ankurdave / color-identifiers-mode Goto Github PK
View Code? Open in Web Editor NEWEmacs minor mode to highlight each source code identifier uniquely based on its name
Emacs minor mode to highlight each source code identifier uniquely based on its name
Hi,
For some reason i'm getting an error when trying to activate (color-identifiers-mode)
in an emacs lisp file with emacs 24.4 compiled over cygwin (shouldn't be an issue i don't think?). The error reported is pcase--app-subst-match(:pcase--succeed sexp car x)
.
I'm not really sure where to start debugging something such as this so let me know what additional information i can provide. The Backtrace buffer in emacs shows something along these lines... i had trouble pasting everything into the issue as it had non-printable chars/etc.
Debugger entered--Lisp error: (wrong-type-argument listp :pcase--succeed)
pcase--app-subst-match(:pcase--succeed sexp car x)
#[257 "\303�@\300\301\302$�AB\207" [sexp car x pcase--app-subst-match] 6 "\n\n(fn BRANCH)"]
((:pcase--succeed #[257 "\302\301\242>\204
pcase--app-subst-rest((((and (match sexp app car (quote let*)) (match sexp app cdr rest)) #[257 "\302\301\242>\204�
pcase--app-subst-rest((((and (match sexp app car (quote let*)) (match sexp app cdr rest)) #[257 "\302\301\242>\204�
pcase--u1(((match sexp app car (quote let)) (match sexp app cdr rest)) #[257 "\302\301\242>\204�
Hi,
First of all thanks a lot for your awesome work! I am using this mode on daily basis and it's like getting grapheme-color synaesthesia super powers!
Do you plan to merge the pending pull-request, especially #35? Are you willing to keep maintaining this project?
Thanks!
If you can please add support for Elixir and Processing languages
I tried as documented:
M-x customize-save-variable RET global-color-identifiers-mode RET y
But it does not take effect. If I open a new file color-identifiers-mode is not enabled automatically
I often get Emacs errors when using color-identifiers. I finally enabled debugging to try to hunt it down, but it's more difficult than I thought, so I'm reporting it here — perhaps it will be obvious to the author:
Debugger entered--Lisp error: (wrong-type-argument listp second)
car(second)
mapcar(car (second [x] (first (next x))))
color-identifiers:clojure-declarations-in-sexp((fn ^:static second [x] (first (next x))))
#[nil "�\304�\211�:\203��\305\n@!\211�\203��\306� \"�)\nA\211�\202��\n\2031�\305\n!\211�\2030�\306� \"�) *\207" [sexp result cons ids nil color-identifiers:clojure-declarations-in-sexp append] 4]()
color-identifiers:clojure-declarations-in-sexp((def ^{:doc "Same as (first (next x))" :arglists (quote ([x])) :added "1.0" :static true} second (fn ^:static second [x] (first (next x)))))
byte-code("\304p!�\305�!�\306\307\310\311 \"\"�\312\n�\"�+\304\207" [sexp ids strs result read color-identifiers:clojure-declarations-in-sexp -filter #[(id) "�\301\235?\205���\207" [id ("&" ":as")] 2] mapcar #[(id) "�9\205��\301�!\207" [id symbol-name] 2] append] 5)
byte-code("\300\301\302\217\210\202��" [nil (byte-code "\304p!�\305�!�\306\307\310\311 \"\"�\312\n�\"�+\304\207" [sexp ids strs result read color-identifiers:clojure-declarations-in-sexp -filter #[(id) "�\301\235?\205���\207" [id ("&" ":as")] 2] mapcar #[(id) "�9\205��\301�!\207" [id symbol-name] 2] append] 5) ((invalid-read-syntax))] 3)
color-identifiers:clojure-get-declarations()
color-identifiers:refresh()
apply(color-identifiers:refresh nil)
timer-event-handler([t 0 5 0 t color-identifiers:refresh nil idle 0])
I believe the Clojure code that caused this error is:
(def
^{:doc "Same as (first (next x))"
:arglists '([x])
:added "1.0"
:static true}
second (fn ^:static second [x] (first (next x))))
I put this in my init.el:
(add-hook 'after-init-hook 'global-color-identifiers-mode)
Restart my Emacs, open a C file, the color-identifiers-mode is already enabled(in mode-line), but the font-face doesn't change.
If I M-x color-identifiers:refresh
once or M-x color-identifiers-mode
twice (first to disable it then enable), the face will change.
Update:
Actually, after more than 5 seconds the face finally changes.
For opening a .c
file the color-identifiers-mode probably tries to parse everything at once, which causes Emacs to hang for at least a minute with 100% CPU load and still cursor.
Steps to reprodice:
(global-color-identifiers-mode)
The commit:
Author: Ankur Dave <[email protected]>
Date: Thu Jun 15 13:38:13 2017 -0700
When using font-lock for detection, ensure whole buffer is fontified
Hello. Do you plan to support highlighting of R variables?
Best regards!
Somehow recently this mode has started to fail due to the color-identifiers:regenerate-colors
function generating a green value with a negative number. Any idea what could be causing this?
Debugger entered--Lisp error: (overflow-error -3.9467358500864416)
format("#%04x%04x%04x" 45874.674699756506 -3.9467358500864416 39321.02887623094)
color-rgb-to-hex(0.7000026657474099 -6.0223328756945775e-05 0.6000004406230403)
apply(color-rgb-to-hex (0.7000026657474099 -6.0223328756945775e-05 0.6000004406230403))
#f(compiled-function (lab) #<bytecode 0x43d7db25>)((40.93880504473374 71.59131282262898 -33.59948996162703))
mapcar(#f(compiled-function (lab) #<bytecode 0x43d7db25>) ((55.969850095011296 -46.000507436863344 19.62744792501374) (37.92861196982004 0.001649772411432826 -0.0023626805090937175) (40.93880504473374 71.59131282262898 -33.59948996162703) (63.951474742506235 -60.79630657802959 64.34808917048707) (35.8910784765621 14.86558451596301 -8.575118569885687) (42.36192063640289 4.958390126570233 -47.41772030495586) (63.59678689625561 -3.1552419727832737 67.26118832479327) (44.52512917499077 -23.365784790247535 24.165666422961053) (36.98022704672353 61.28754873290543 51.3693598087128) (23.463354969597376 61.524269701778486 -78.28325538202843)))
-map(#f(compiled-function (lab) #<bytecode 0x43d7db25>) ((55.969850095011296 -46.000507436863344 19.62744792501374) (37.92861196982004 0.001649772411432826 -0.0023626805090937175) (40.93880504473374 71.59131282262898 -33.59948996162703) (63.951474742506235 -60.79630657802959 64.34808917048707) (35.8910784765621 14.86558451596301 -8.575118569885687) (42.36192063640289 4.958390126570233 -47.41772030495586) (63.59678689625561 -3.1552419727832737 67.26118832479327) (44.52512917499077 -23.365784790247535 24.165666422961053) (36.98022704672353 61.28754873290543 51.3693598087128) (23.463354969597376 61.524269701778486 -78.28325538202843)))
color-identifiers:regenerate-colors()
color-identifiers-mode(toggle)
funcall-interactively(color-identifiers-mode toggle)
call-interactively(color-identifiers-mode record nil)
command-execute(color-identifiers-mode record)
#f(compiled-function (cmd) #<bytecode 0x431f6165>)("color-identifiers-mode")
When byte-compiling color-identifiers-mode.el
, Emacs reports these warnings:
In color-identifiers-mode:
color-identifiers-mode.el:62:11:Warning: reference to free variable
‘color-identifiers:timer’
color-identifiers-mode.el:63:21:Warning: assignment to free variable
‘color-identifiers:timer’
Don't touch :box face rules on highlight identifiers
This is mostly a refactoring task.
There are multiple bugs about wrong text being colorized, such as #40 or #62. Both #40 and #62 can be solved by making "scan-fn" color-identifiers:cc-mode-get-declarations
(like in #93).
cc-mode-get-declarations
and scan-identifiers
are similar in what they do, but the main difference is that scan-identifiers
is called against almost every word, whereas cc-mode-get-declarations
is only called on words that have properties set. In terms of code the difference is that the former mostly uses re-search-forward
to move through buffer, whereas the latter does that only with next-property-change
. (yes, I know next-property-change
is called in scan-identifiers
too, but only if re-search-forward
fails, which I don't think happens too often).
What I can gather from this difference is that these two functions have different usecases:
cc-mode-get-declarations
is used to find out declarations of identifiers, but not their usages in the textscan-identifiers
is used to find and highlight usages of identifiers in the text.With that said, I don't think using scan-identifiers
as the default scan-fn
function is correct. More likely, the cc-mode-get-declarations
should be renamed to sound more generic, and be the default scan-fn
.
I have set up color-identifiers-mode as such.
(use-package color-identifiers-mode
:ensure t
:defer t
:config
(add-hook 'after-init-hook 'global-color-identifiers-mode))
I have even tried the :hook
property with use-package
as such.
:hook ((after-init . global-color-identifiers))
Every time i open a c file or h file. I need to set run M-x global-color-identifiers-mode
in order for color-identifiers to happen on the current buffer.
Any thoughts on what I'm doing incorrectly?
How to add Typescript (+ tsx) support here?
I can't tell which one is the issue here.
When both hideshowvis and color-identifiers-mode are in use, color-identifiers:refresh
becomes very slow on large files. When hideshowvis is not loaded, color-identifiers:refresh
is much faster (like .5 seconds versus 15 seconds).
To reproduce this, first get hideshowvis installed. Save this file into ~/emacs.d/lisp
.
In init.el
add
(use-package hideshowvis
:diminish
:load-path "~/.emacs.d/lisp"
:bind ("M-[" . hs-toggle-hiding)
:init (progn
(add-hook #'prog-mode-hook (lambda () (hideshowvis-enable) (hideshowvis-symbols)))))
That will cause hideshowvis to open when a programming file is opened, like c++.
Now we need to open a large c++ file. Download this file to ~/Downloads/inference_context.cc
.
Now open that file in emacs. Confirm that there are little minus signs in the fringe which can be clicked to shrink and expand code.
Now type M-x color-identifiers:refresh
. It should return in under 0.5 seconds.
Now hold page down on the keyboard until you reach the end of the file. Once again, type M-x color-identifiers:refresh
. It will take noticeably longer, like 4 seconds or so. This will be the case from now on. Now page up all the way to the top and try again. Now it might be even longer, like 12 seconds.
M-x profiler-start
before the slowness and then M-x profiler-report
after the slowness shows 99% of the cpu time in thing-at-point
, called by symbol-at-point
in color-identifiers. It's not clear if that is many more calls to thing-at-point or just more time spent inside the function. I don't know a method to count calls in elisp.
I have the following configuration
(use-package color-identifiers-mode
:diminish color-identifiers-mode
:init (add-hook 'after-init-hook 'global-color-identifiers-mode))
With above configuration tangling functionality from org-mode is taking a lot of time
With
(defun my-test (arg1 arg2 arg3)
`(,arg1 arg2 ,@arg3))
arg1 and arg2 are fontified everywhere but arg3 is fontified only in the first line.
This mode is beautiful, but brings significant performance issue for large files, e.g. 60000+ lines javascript file with js2-mode.
I have to disable it to improve the user experience.
Hello, and thank you for your awesome package!
I found the following issue:
I have an org-mode file with the following fragment:
#+begin_src: elisp
(defun my-rtcite-export-handler (path desc format)
"See http://www-public.imtbs-tsp.eu/~berger_o/weblog/2012/03/23/how-to-manage-and-export-bibliographic-notesrefs-in-org-mode/"
(message "my-rtcite-export-handler is called : path = %s, desc = %s, format = %s" path desc format)
(let* ((search (when (string-match "::#?\\(.+\\)\\'" path)
(match-string 1 path)))
[] (path (substring path 0 (match-beginning 0))))
(cond ((eq format 'latex)
(if (or (not desc)
(equal 0 (search "rtcite:" desc)))
(format "\\cite{%s}" search)
(format "\\cite[%s]{%s}" desc search))))))
#+end_src
The code there is wrong, as the []
is there by mistake. However, color-identifiers-mode
fails, and the global-color-identifiers-mode
fails too.
Cannot find definition of python-nav-forward-defun. Where is this function?
The following works reasonably well for me:
(add-to-list
'color-identifiers:modes-alist
`(ruby-mode . ("[^.][[:space:]]*" "\\_<\\([a-zA-Z_$]\\(?:\\s_\\|\\sw\\)*\\)" (nil))))
But it still leaves a problem: in Ruby, it's often impossible to distinguish a local variable from a method called without arguments. Can we add some parameter that would allow to pass a function, which would look at the first occurrence of an identifier (inside a given defun, or globally), and tell if it's a variable?
For example, in ruby-mode, that function would check whether the identifier is followed by =
, or whether it's in a method arguments list.
CUDA is similar to c/c++ so you can probably just borrow that code.
wget https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/qutebrowser/browser/browsertab.py
1.py
file that is twenty times larger: for i in $(seq 1 20); do cat browsertab.py >> 1.py; done
1.py
file(benchmark-run 1 (color-identifiers:list-identifiers))
0.2 or 0.3 seconds
1.4 seconds
benchmark-report
says that 70% of time is spent in internal Emacs function we call (sexp-at-point)
.
So one solution to this problem could be optimizing this function.
Another good idea might be to modify upstream python-mode
so that they mark args inside defuns with a font-lock-variable-name-face
face, which would allow to get rid of color-identifiers:python-get-declarations
in preference of the generic color-identifiers:get-declarations
(well, maybe not completely, but at least for Emacs versions that will support that feature)
Installing on the latest Emacs gives this warning during byte-compilation:
In color-identifiers-mode:
color-identifiers-mode.el:65:21:Warning: `font-lock-fontify-buffer' is for
interactive use only; use font-lock-ensure or font-lock-flush instead.
In color-identifiers:refresh:
color-identifiers-mode.el:547:74:Warning: `font-lock-fontify-buffer' is for
interactive use only; use font-lock-ensure or font-lock-flush instead.
Looking at the source of font-lock-fontify-buffer
I find this scary comment:
;; When called from Lisp, this function is a big mess.
So I figured it was worth a bug report.
MELPA creates a new release every time a commit is pushed to github. Would it be possible to push a version of this to MELPA stable as well?
https://stable.melpa.org
https://github.com/milkypostman/melpa#stable-packages
The instructions I see in this issue
kai2nenobu/guide-key#28
suggest that it is just a matter of a git tag with a version number and commit and git push
cheers
I would love to see support for clojure-mode, unfortunately I'm not familiar enough with elisp myself to add it. Consider this the request for support should anyone come looking :)
A definition like:
def f((x, y)):
…
trips color-identifiers-mode with:
Error running timer `color-identifiers:refresh': (wrong-type-argument symbolp (x (\, y)))
This is too bad, since it breaks the nice identifier coloring of the whole file!
color-identifiers:refresh
hangs on buffers with circular structures.
Steps to reproduce:
Create an emacs-lisp-mode
buffer.
Add text containing reader syntax for a circular structure:
(-take 5 '#0=(1 . #0#))
Call color-identifiers:refresh
.
The command hangs and does not return.
Backtrace:
Debugger entered--Lisp error: (quit)
#f(compiled-function (sexp) #<bytecode 0x1577820639a9>)((1 . #1))
color-identifiers:elisp-declarations-in-sexp((1 . #1))
#f(compiled-function (sexp) #<bytecode 0x1577820639a9>)('(1 . #2))
color-identifiers:elisp-declarations-in-sexp('(1 . #2))
#f(compiled-function (sexp) #<bytecode 0x1577820639a9>)((-take 5 '(1 . #5)))
color-identifiers:elisp-declarations-in-sexp((-take 5 '(1 . #5)))
color-identifiers:elisp-get-declarations()
color-identifiers:list-identifiers()
color-identifiers:refresh()
funcall-interactively(color-identifiers:refresh)
call-interactively(color-identifiers:refresh record nil)
command-execute(color-identifiers:refresh record)
counsel-M-x-action("color-identifiers:refresh")
Just kind of impressed by the color theme that the screenshots show.
I got this error when installing - color-identifiers-mode.el:42:1:Error: Cannot open load file: dash-functional
I'm using emacs 24.3.1.
Recent commit uses font-lock-ensure
which I believe is new in emacs 25 thus breaking users on emacs 24.
Occasionally, I'm writing some elisp and the buffer contains some invalid code like (something ')
, or #name
. In these situations, I keep getting errors from color-identifiers
because of invalid read syntax.
This is very distracting, and I think it would be preferable to use ignore-errors
in the timer function to avoid this kind of thing.
Thank you for this great package.
Can you add support for C/C++?
Is it correct that comments are also colorized?
Great package by the way, helps me see the variables better.
As the doc string described, the function color-identifiers:color-identifier
should return a hex color. However, when the parameter identifier
not present in color-identifiers:color-index-for-identifier
it would return wrong value.
(let ((entry (assoc-string identifier color-identifiers:color-index-for-identifier)))
(if entry
(nth (cdr entry) color-identifiers:colors)
;; If not present, make a temporary color using the rotating index
(push (cons identifier (% color-identifiers:current-index
(length color-identifiers:colors)))
color-identifiers:color-index-for-identifier)
(setq color-identifiers:current-index
(1+ color-identifiers:current-index))))))
i "implemented" this locally, but rather than creating a PR i thought maybe you might have a better idea of doing this that doesn't involve copy/pasting. thanks.
They reappear shortly due to the idle timer, but it would be nice to avoid the flash entirely.
It would be absolutely fantastic if Typescript would be added.
Just food for thought.
Running it returns:
Symbol's function definition is void: defvar-local
Compilation log returned:
Compiling file c:/Users/Philip/AppData/Roaming/.emacs.d/elpa/color-identifiers-mode-20140517.1145/color-identifiers-mode.el at Sat May 17 13:06:48 2014
color-identifiers-mode.el:405:15:Warning: reference to free variable
`color-identifiers:identifiers'
color-identifiers-mode.el:456:15:Warning: reference to free variable
`color-identifiers:color-index-for-identifier'
color-identifiers-mode.el:460:15:Warning: reference to free variable
`color-identifiers:current-index'
In color-identifiers:refresh:
color-identifiers-mode.el:489:31:Warning: assignment to free variable
`color-identifiers:identifiers'
color-identifiers-mode.el:488:55:Warning: reference to free variable
`color-identifiers:identifiers'
color-identifiers-mode.el:504:19:Warning: assignment to free variable
`color-identifiers:color-index-for-identifier'
In color-identifiers:color-identifier:
color-identifiers-mode.el:512:40:Warning: reference to free variable
`color-identifiers:identifiers'
color-identifiers-mode.el:513:43:Warning: reference to free variable
`color-identifiers:color-index-for-identifier'
color-identifiers-mode.el:517:35:Warning: reference to free variable
`color-identifiers:current-index'
color-identifiers-mode.el:519:15:Warning: assignment to free variable
`color-identifiers:color-index-for-identifier'
color-identifiers-mode.el:521:19:Warning: assignment to free variable
`color-identifiers:current-index'
In end of data:
color-identifiers-mode.el:575:1:Warning: the following functions are not known to be defined:
python-nav-forward-defun, defvar-local
For large files, this mode can significantly slow down opening.
If possible (I'm not familiar enough to say) perhaps defer the colorizing until after the file has loaded?
I noticed that typescript with react ( tsx) files are not supported.
Can we support it? or even better, support all language automatically ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.