How to use emacs/elisp to highlight parts of font-locked source code - emacs

I have some log files that contain the directory paths and file names (and line numbers) for C++, C, Java and C# source code files. I have written a regex to search for these file names and line numbers and open the source code file and position the insertion point at the specified line number (kinda like the next-error function when used with the compile command).
Given a file name that appears in the log file multiple times I want to add highlighting (and selectively remove highlighting) to the source code file display window/buffer.
I can do this with functions like add-text-properties, remove-text-properties and add-face-text-property (where is remove-face-text-property?) if there is no font-lock (keyword color coding). These functions don't work if font-lock is turned on!
How do I do this if the font-lock is turned on? I see that the incremental search feature does it so it is possible to add and remove highlighting with out messing up the font-lock coding.
Thanks
Siegfried

Use overlays instead of text-properties. E.g. to highlight with face bold the text between BEG and END, do something like:
(let ((ol (make-overlay BEG END)))
(overlay-put ol 'face 'bold))

Any highlighting that uses text property face is overruled by font-lock highlighting -- font-lock wants to win. In many cases you can still highlight text, but sooner or later font-lock erases that highlighting when it refontifies the buffer.
This does not apply to highlighting that uses overlays –- font-lock has no effect on overlays. So one answer is to just use overlays. However, if that does not work for your use case (there are some downsides to using overlays) there is still hope.
To prevent the interference of font-lock with other highlighting, the typical Emacs approach is to fool font-lock into thinking that it is font-lock highlighting, even when it does not involve font-lock-keywords.
But this has the effect that such highlighting is turned off when font-lock-mode is turned off. Whether this is a good thing or bad depends on your use case.
In vanilla Emacs you have no choice about this. Either the highlighting is not recognized by font-lock, which overrules it, or it is recognized as “one of its own”, in which case it is turned off when font-lock highlighting is turned off.
If you don't need your special highlighting when font-lock-mode is turned off, then you can just use text property font-lock-face instead of property face.
If you use library highlight.el to implement your highlighting then you can do that just by leaving option hlt-face-prop at its default value of font-lock-face. (Value font-lock-face means that the highlighting is controlled by font-lock. Value face means that font-lock does not recognize the highlighting.)
For the case where the option value is face, if you also use library font-lock+.el then there is no interference by font-lock –- the highlighting is independent of font-lock.
Library font-lock+.el is loaded automatically by highlight.el, if it is in your load-path. It prevents font-locking from removing any highlighting face properties that you apply using the commands defined here.
See Highlight Library for more information.

Related

Is there a way to disable indentation for one specific org-mode src block at a time?

I'm using most of the standard features of org-mode that come with the spacemacs develop branch, but I haven't been able to find a way to disable the automatic indentation for source code blocks on a case by case basis. I use tangle and I'm writing Dockerfile's in the same file that I'm writing groovy code or javascript for example. The Dockerfile's are the only ones I want not to be indented so I can get syntax highlighting. Here's what it looks like without the indentation:
And here's what it looks like with the indentation that automatically happens if I edit the text:
The automatic indentation is fine for groovy for example, so I have no issue with the automatic indentation here. (in fact, if I still got the syntax highlighting for Dockerfile's I probably wouldn't mind too much except the weird word wrapping not respecting the background face). Here's the example with groovy:
As you can see, I tried a :noindent property I found in the org-mode docs that's usually in a #+STARTUP directive. I also searched stack overflow, but I didn't find anything fruitful that didn't disable indenting for all source blocks or for the entire file.
In my practice (I'm not sure it is a good practice or not, just share it to you):
I setup org-src-tab-acts-natively to true for using the language’s major-mode indentation. In your case, it will format the src block with the formatting rules of dockerfile-mode.
I created a new major-mode plain-mode for the content which should not be indented automatically. Personally, I use this mode for something like:
shell outputs
ASCII diagrams
...
#+begin_src plain
this will not
be
auto
indented
#+end_src
Above src block will not be indented when you select them as region, and TAB on them.
In this way, the src blocks will always behavior as expected when formatting them.
Aside, the example code of plain-mode:
(define-derived-mode plain-mode
clean-mode "Plain"
"Major mode for plain text."
;; preserve the auto indentation on line
(setq-local indent-line-function 'indent-relative)
;; disable auto indentation on region
(setq-local indent-region-function (lambda (start end))))

Emacs abbrev-mode in natural languages

I frequently use abbrev-mode in Emacs when writing prose or just taking notes. It would be nice if there was any way to define language-specific abbreviations, e.g. if I write "proj" in an English text, it would expand to "project", whereas if I write it in a Swedish text, it would expand to "projekt". Likewise, "riskfac" would expand to "risk factor" in English but "riskfaktor" in Swedish. How to accomplish this?
It would be especially nice if this could be coupled to the ispell-dictionary that is currently used. I know there are different abbrev-tables, but these are specific to modes, not languages.
Any ideas here?
For free text, I tend to use pabbrev.el (which I wrote!) but there are several other packages which now do the same thing -- a dynamic abbreviation expansion depending on what you have already written. This tends to give a degree of language specificity in practice.
Otherwise, I think you need something to switch the abbrev tables in different buffers. Perhaps you could hook this into input methods if you are using them, then Emacs would know which language you were using.
Consider trying dynamic-completion-mode (standard library completion.el).
You can change between different dynamic-completion files, one for each language. Option save-completions-file-name holds the file name, but nothing says that you cannot change its value dynamically, e.g. using a command, in order to switch among several sets of completions. (Naturally, such a command should save to one file before switching to another.)
The "doc" for dynamic-completion-mode is in the Commentary of library completion.el. The library is old, but still quite useful, IMHO. Excerpts from the Commentary:
This watches all the words that you type and remembers them. When
typing a new word, pressing "complete" (meta-return) "completes" the
word by inserting the most recently used word that begins with the
same characters. If you press meta-return repeatedly, it cycles
through all the words it knows about.
If you like the completion then just continue typing, it is as if you
entered the text by hand. If you want the inserted extra characters
to go away, type control-w or delete. More options are described below.
The guesses are made in the order of the most recently "used". Typing
in a word and then typing a separator character (such as a space) "uses"
the word. So does moving a cursor over the word. If no words are found,
it uses an extended version of the dabbrev style completion.
(See also Icicles completion for dynamic-completion-mode.)
I had the same requirement (and am also switching between writing
English and Swedish in Emacs) and solved it by defining two modes, one
for English and one for Swedish. Both derive from a special "writer
mode" that has some useful features when I am just writing text. I have
some convenient keybindings (and even abbrevs that run code) to switch
modes/languages. Since each language has its own mode, I can keep
different abbrevs for the two languages.
Here is part of my setup:
(define-derived-mode writer-mode text-mode "W-EN"
"Writer mode."
(abbrev-mode 1))
(define-derived-mode writer-english-mode writer-mode "W-EN"
"Writer mode - English.")
(define-derived-mode writer-swedish-mode writer-mode "W-SV"
"Writer mode - Swedish.")
...
(defun writer-swedish ()
(interactive)
(writer-swedish-mode)
(set-input-method 'swedish-postfix)
(setq header-line-format " SV> ")
(setq mode-line-format nil)
(flyspell-mode -1)
(writer-setup-bindings))
(defun writer-english ()
(interactive)
(writer-english-mode)
(deactivate-input-method)
(setq header-line-format " EN> ")
(setq mode-line-format nil)
(flyspell-mode 1)
(writer-setup-bindings))
As you can see I also use an input method when writing Swedish. I have a
keyboard with Swedish letters but try to stay with English keyboard
layout since it is generally better when writing code.

Scheme editing in Emacs - modes and keyboard layout

Recently I started using Emacs as my Scheme (Lisp) editor. I'm thinking what extensions should I use in order to achieve the best performance. Currently I'm using Paredit and it helps a lot. I know that there are numerous Scheme extensions for Emacs: Geiser, Quack to name the two that seem very popular, and EmacsWiki lists many more. Which of these have you guys used and which ones do you find the best? At the moment my biggest problem is lack of parentheses colouring, which makes it vary hard to pair them visually - indentations are not enough when you have a line of code ending with ))))))))
I'm also thinking how could I improve the keyboard layout of Emacs in order to do better in Scheme editing? I've found some good advice on CLiki. I swapped [] with () on the keyboard and that's helpful. I'm also considering swapping Alt and Ctrl keys.
Do you have any other tips and suggestions that make it easier to edit Scheme in Emacs?
I've found rainbow delimiters mode really helpful for highlighting different levels of parentheses.
Among other modes that help me write lisp are hideshow mode for folding of sexps, slime which is primarily for Common Lisp but I use it's indentation capabilities in scheme too, low-contrast color theme called solarized with which my eyes don't fatigue any more and heavily mutated vim mode which permits me to keep my keybindings manageable through editing modes.
I use show-paren-mode, a minor mode, with these in my .emacs:
(show-paren-mode t)
(setq show-paren-delay 0)
(setq show-paren-style 'expression) ; alternatives are 'parenthesis' and 'mixed'
Relevant faces to modify are show-paren-match and show-paren-mismatch.
It only highlights a sexp when point is immediately before or after it, but I like that it's not so in-your-face.
I use autopair to get parenthesis right, show-paren-mode to see the end and beginning of s-expressions and expand-region to mark s-expression (It works on a lot more than that).
I think as you keep playing with paredit you may see less and less need for parenthesis coloring. For example, type ')' within any sexp, and the opening and closing parens will be momentarily highlighted; then point will move to the end of the sexp. Being able to navigate the nested sexp structure easily - for example, C-M-u and C-M-d to navigate up and down one paren level - also takes away some of the need to visually pair parenthesis.

Turn off Emacs Whitespace-mode "Long Line" Visualization

I personally keep all lines under 80 characters, but I also work on projects in teams where other programmers don't care about line length.
I love using whitespace-mode, but the long line visualization is really annoying when I'm working on projects where I shouldn't interfere with the long lines. It seems like it should be easy to turn off the long line visualization---I hit m-x global-whitespace-toggle-options l, and then can hit m-x global-whitespace-toggel-options ? to confirm that the "long-line visualization" is turned off. But long lines are still highlighted. I kill buffers and reload them, and highlighting is still there. I'm definitely using global, not local, whitespace-mode.
Why can't I turn off the long line visualization?
The last time I customized whitespace-mode, I noticed that my changes to the settings didn't have any effect in buffers that already existed; try recreating the buffer, or leaving and reentering whitespace-mode. In case you don't already know, you can use M-x customize-group whitespace to turn off that particular option entirely, rather than doing it manually.
Edit: Specifically you want to customize the whitespace-style variable. This lets you turn on and off individual styles. In this case you should turn off the ones labelled "(Face) Lines" and "(Face) Lines, only overlong part". The former changes the face of the whole line when it is overly long, while the latter only changes the face of the part that extends past the threshold.
(Other options in this group define the faces that whitespace-mode will use to highlight the styles you've turned on, the regexes it uses to identify certain situations, etc, but usually you only care about whitespace-style).
Set whitespace-line-column to a higher value (default is 80), so the highlighting of long lines doesn't kick in:
(setq whitespace-line-column 250)
I'm assuming that you already have whitespace-mode activated somewhere in your init.el or similar. If so, you can adapt duma's comment above, and either
Edit the elisp that sets whitespace-style to remove lines-tail. E.g., Emacs Prelude sets
(setq whitespace-style '(face tabs empty trailing lines-tail))
Simply change that to
(setq whitespace-style '(face tabs empty trailing))
If you don't want to directly edit that elisp, but rather override it later with your own code, do something like
(setq whitespace-style (delete 'lines-tail whitespace-style))
Unfortunately, if running Prelude with auto-loaded buffers (using something like Emacs Desktop), the initial setting will take precedence: for each buffer on which you want to see whitespace-style displayed as directed, you must [1]
kill the buffer
re-open the buffer
[1]: Note to OP: if there's another way to reload a buffer, please edit or comment this answer. I was hoping to find something like M-x reload-buffer but am not seeing anything like that with C-h a buffer.

How to highlight all occurrences of a word in an Emacs buffer?

Notepad++ has a convenient feature: if you select a word in your text (not necessarily a keyword), the word is highlighted throughout the text. Can this be done in Emacs as well? And if so, how?
It doesn't necessarily have to work exactly like Notepad++ (i.e., via selection); ideally, I would like to set up a key binding that causes all occurrences of the word under cursor to be highlighted.
It would be great if the highlights were permanent, i.e., moving point away from a highlighted word should not cause the highlight to be removed.
Also, it would be useful if there was a solution that made it possible to navigate between highlights (using custom key bindings).
The hi-lock suggestions are good. I think it's easier to use the M-x versions, though:
M-x highlight-regexp RET <REGEXP>
M-x highlight-phrase RET <REGEXP>
highlight-phrase is just a bit of sugar around highlight-regexp that ignores case and translates a space in the regex to match arbitrary whitespace. Handy.
Maybe highlight-symbol.el at http://nschum.de/src/emacs/highlight-symbol/ is what you are looking for:
Type C-s, then type the current word or type C-w. As a bonus, you can now hit C-s again to search for the word.
This is called incremental search.
What I use is idle-highlight
http://www.emacswiki.org/emacs/IdleHighlight
M-x idle-highlight sets an idle timer that highlights all occurences in the buffer of the word under the point.
To enable it for all programming modes, in ~/.emacs.d/init.el:
;; highlight words
(add-hook 'prog-mode-hook (lambda () (idle-highlight-mode t)))
Light-symbol will highlight whatever symbol point is over.
Alternately, you can use occur, which lists all lines matching a regexp. It's useful to quickly see all functions in a class.
Nobody mentioned symbol-overlay mode. It's basically a better rewrite of highlight-symbol-mode. "Better" as in, lacks bugs of original highlight-symbol (such as, temporary highlight getting stuck, or the temporary highlight disappearing for moving inside the highlighted word; or not being able to highlight symbols like *), better integrated, and maintained. See "Advantages" paragraph of its README.
You can install it as usual, with M-xpackage-install (make sure to update package list beforehand with package-list-packages). For reference, at the bottom I attached code I use to enable the mode and disable a few of the more advanced features which you may or may not want.
Notepad++ has a convenient feature: if you select a word in your text (not necessarily a keyword), the word is highlighted throughout the text. Can this be done in Emacs as well? And if so, how?
Once you enable overlay-symbol, occurrences on the screen will be shown for every word that you put cursor upon after a timeout (timeout by default is 0.5s, can be configured with symbol-overlay-idle-time variable). If a word don't get highlighted, this means there's just one match on the screen (the one you put cursor upon), hence there's no need to highlight it.
It would be great if the highlights were permanent, i.e., moving point away from a highlighted word should not cause the highlight to be removed.
To highlight the word under cursor permanently there's a function symbol-overlay-put. To unhighlight call it once again.
In my config example it's bound to Logo+` key.
(require 'symbol-overlay)
(defun enable-symbol-overlay-mode ()
(unless (or (minibufferp)
(derived-mode-p 'magit-mode)
(derived-mode-p 'xref--xref-buffer-mode))
(symbol-overlay-mode t)))
(define-global-minor-mode global-symbol-overlay-mode ;; name of the new global mode
symbol-overlay-mode ;; name of the minor mode
enable-symbol-overlay-mode)
(global-symbol-overlay-mode) ;; enable it
(global-set-key (kbd "s-`") 'symbol-overlay-put)
(setq symbol-overlay-ignore-functions nil) ;; don't ignore keywords in various languages
(setq symbol-overlay-map (make-sparse-keymap)) ;; disable special cmds on overlays
This may not be as nice as what you were hoping but if you put
(global-hi-lock-mode 1)
in your .emacs file then you can type C-x w h REGEX <RET> <RET> to highlight all occurances of REGEX, and C-x w r REGEX <RET> to unhighlight them again. Again, not as elegant as you'd probably like, but it'll work.
Try http://www.emacswiki.org/emacs/msearch.el
All occurences of the text selected with the cursor are highlighted.
You have to drag over the string which you want to highlight. That enables you to easily change the selection without changing the highlight.
If you want to preserve the highlighting of a string you can freeze it.
You can enslave a buffer to another buffer. Text selected in the master buffer will also be highlighted in the slave buffer. That is useful for comparing buffers.
It is also useful for taking notes in one buffer while you investigate the text in another one. You can have a collection of keywords in the notes buffer. Drag over such a keyword and its occurences in the investigated text will be highlighted.
I am using this stuff for years now. I added the freezing quite recently. So, maybe something is broken. If this is the case leave me a note on http://www.emacswiki.org/emacs/msearch or here.
Check Interactive Highlighting
Should be:
C-x w h word <RET> <RET>
Try iedit. It highlights the word at point and lets you edit all occurrences of it easily. With an additional keystroke (C-'), it hides all the lines without that word in it. Very handy!
Commands in library highlight.el
let you (un)highlight text matching a regexp (in this case a symbol), using overlays or text properties. You can cycle among the occurrences. Highlighting can be temporary or persistent. (more info).
This maybe won't highlight but will search for a word without you needing to type it...
when you've reached the word you wanted to search, C-S, then read the full word with C-W then you can C-S and it will search for it. In my Emacs it also highlights all instances in the document.
This package available in Melpa works, you can customize the highlight style as well.
https://github.com/ignacy/idle-highlight-in-visible-buffers-mode