emacs how to refresh buffer and preserve highlighting - especially for logs - regex

I am often parsing log files, which I help visualize by highlighting specific char sequences via M-s h r + regex, aka the command highlight-regexp or hi-lock-face-buffer. Sometimes I will need to regenerate the log file, which is done via the C-x C-v or find-alternate-file command. Unfortunately, the regeneration also loses all of my highlighting.
TLDR
Is there a way to regenerate my buffer file while maintaining all of the highlighting?
Update
I am using text-mode, and the regexes vary widely depending on my task and the log file. I would like something that carries over all of my highlighting to the refreshed buffer. Does something already exist?
Answer:
Even better than maintaining highlights after a refresh, the selected answer uses an add-hook to create a highlighting scheme for a particular log. Additionally, each log can have different highlight schemes. The result is an automated highlighting scheme that matches a particular log file's name, with the ability to toggle the schemes of various highlights.

You can add-hook that:
(add-hook 'text-mode-hook
(lambda ()
(font-lock-add-keywords nil '(("^\\([^,]*\\)," 1 'font-lock-function-name-face)))))
What regexp you'd like to highlight? If You are using several regexps depending on the log, it might be possible to hook them all. Or you might program the condition: which regexp to hightlight:
(add-hook 'text-mode-hook
(lambda ()
(if (condition)
;; condition true:
(font-lock-add-keywords nil '((regexp1 1 'font-lock-function-name-face)))
;; condition false:
(font-lock-add-keywords nil '((regexp2 1 'font-lock-function-name-face)))
)
))
Also if you control the generation of logs you can generate the hightlight rules in the first line:
# -*- eval: (highlight-regexp REGEXP) -*-
(assuming # is the comment char in your log).
Edit:
Here's defun which toggles hightlighting for TestQueryLogic or invoking fork-join and testGudermann:
(defun testing-MapAppLog.txt ()
"Toggle highlighting `TestQueryLogic' or `invoking fork-join' and `testGudermann'."
(interactive)
(cond
((get this-command 'state)
(highlight-regexp "TestQueryLogic" font-lock-variable-name-face)
(highlight-regexp "invoking fork-join" font-lock-type-face)
(unhighlight-regexp "testGudermann")
(message "Highlighting: TestQueryLogic, invoking fork-join")
(put this-command 'state nil))
(t
(unhighlight-regexp "TestQueryLogic")
(unhighlight-regexp "invoking fork-join")
(highlight-regexp "testGudermann" font-lock-preprocessor-face)
(message "Highlighting: testGudermann")
(put this-command 'state t))))
So call it once to hightlight TestQueryLogic, invoking fork-join, call it again to hightlight testGudermann instead. You can bind to a key:
(define-key text-mode-map (kbd "M-s t") 'testing-MapAppLog.txt)
and press that once or twice depending on what you'd like to highlight.

Rather than C-x C-v which basically says "throw away current buffer and use thise other file instead" an has hence no hope of preserving transient info such as your highlighting patterns, you want to use revert-buffer, or maybe even auto-revert-mode or auto-revert-tail-mode.

Related

manipulate regexp-search matches using `query-regexp-replace` in a defun

Since version 22 of Emacs, we can use \,(function) for manipualting (parts of) the regex-search result before replacing it. But – this is mentioned often, but nonetheless still the truth – we can use this construct only in the standard interactive way. (Interactive like: By pressing C-M-% or calling query-replace-regexp with M-x.)
As an example:
If we have
[Foo Bar 1900]
and want to get
[Foo Bar \function{foo1900}{1900}]
we can use:
M-x query-replace-regexp <return>
\[\([A-Za-z-]+\)\([^0-9]*\) \([0-9]\{4\}\)\]
[\1\2 \\function{\,(downcase \1)\3}{\3}]
to get it done. So this can be done pretty easy.
In my own defun, I can use query only by replacing without freely modifying the match, or modify the prepared replaced string without any querying. The only way I see, is to serialize it in such a way:
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(while (query-replace-regexp
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
"[\\1\\2 \\\\function{\\1\\3}{\\3}]" ))
(goto-char (point-min))
(while (search-forward-regexp "\\([a-z0-9]\\)" nil t)
(replace-match (downcase (match-string 1)) t nil)
)
)
For me the query is important, because I can't be sure, what the buffer offers me (= I can't be sure, the author used this kind of string always in the same manner).
I want to use an elisp function, because it is not the only recurring replacement (and also not only one buffer (I know about dired-do-query-replace-regexp but I prefer working buffer-by-buffer with replace-defuns)).
At first I thought I only miss something like a query-replace-match to use instead of replace-match. But I fear, I am also missing the easy and flexible way of rearrange the string the the query-replace-regexp.
So I think, I need a \, for use in an defun. And I really wonder, if I am the only one, who is missing this feature.
If you want your rsearch&replace to prompt the user, that means you want it to be interactive, so it's perfectly OK to call query-replace-regexp (even if the byte-compiler will tell you that this is meant for interactive use only). If the warning bothers you, you can either wrap the call in with-no-warnings or call perform-replace instead.
The docstring of perform-replace sadly doesn't (or rather "didn't" until today) say what is the format of the replacements argument, but you can see it in the function's code:
;; REPLACEMENTS is either a string, a list of strings, or a cons cell
;; containing a function and its first argument. The function is
;; called to generate each replacement like this:
;; (funcall (car replacements) (cdr replacements) replace-count)
;; It must return a string.
The query-replace-function can handle replacement not only as a string, but as a list including the manipulating elements. The use of concat archives building an string from various elements.
So one who wants to manipulate the search match by a function before inserting the replacement can use query-replace-regexp also in a defun.
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(query-replace-regexp
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
(quote (replace-eval-replacement concat "[\\1\\2 \\\\function{"
(replace-quote (downcase (match-string 1))) "\\3}{\\3}]")) nil ))
match-string 1 returns the first expression of our regexp-search.
`replace-quote' helps us doublequoting the following expression.
concat forms a string from the following elements.
and
replace-eval-replacement is not documented.
Why it is in use here nevertheless, is because of emacs seems to use it internally, while performing the first »interactive« query-replace-regexp call. At least is it given by asking emacs with repeat-complex-command.
I came across repeat-complex-command (bound to [C-x M-:].) while searching for an answer in the source code of query-replace-regexp.
So an easy to create defun could be archieved by performing the standard search and replace way as told in the question and after first sucess pressing [C-x M-:] results in an already Lisp formed command, which can be copied and pasted in a defun.
Edit (perform-replace)
As Stefan mentioned, one can use perform-replace to avoid using query-replace-regexp.
Such a function could be:
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(while (perform-replace
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
(quote (replace-eval-replacement concat "[\\1\\2 \\\\function{"
(replace-quote (downcase (match-string 1))) "\\3}{\\3}]"))
t t nil)))
The first boolean (t) is a query flag, the second is the regexp switch. So it works also perfectly, but it didn't help finding the replacement expression as easy as in using \,.

How do you create (automatically inserted) LaTeX template with Emacs+AUCTeX?

I use Emacs+AUCTex for writing LaTeX documents. I have specific needs so my typical preamble is quite long. Today, I have a .tex file with only this preamble (a template so) and I use C-x C-w to write a new file from this template. It isn't the best solution because my template localization could be far away from the new file.
So is there a way to call LaTeX templates in Emacs in another (shorter) way?
EDIT : auto-insert-mode offers a way to achieve what I want but it doesn't put automatically my template (LaTeX preamble) when I create a .tex file. I have to launch M-x auto-insert. How can I automatize this based on the file extension?
At the end of VirTeX-common-initialization (essentially) TeX-master-file is added to find-file-hooks. This is the source for the %%% Local Variables: %%% mode: latex %%% TeX-master: t %%% End: stuff. (Note, that VirTeX-common-initialization is the first thing in LaTeX-common-initialization which is called in TeX-latex-mode being an alias for latex-mode.)
To get ride of the automagically added comments you can remove the hook:
(add-hook 'TeX-mode-hook '(lambda ()
(remove-hook 'find-file-hooks (car find-file-hooks) 'local)))
That looks like a hack. But adding TeX-master-file is quite hard-coded without user-options. So, it seems to me that you have no other chance.
After that correction the auto-insert stuff works automagically.
(At least for me.)
But, I have replaced the entries in auto-insert-alist. Meaning, instead of
(define-auto-insert "\\.tex$" "my-latex-template.tex")
I have something like that:
(let ((el (assoc 'latex-mode auto-insert-alist)))
(if el
(setcdr el "/c/temp/autoinsert.tex")
(define-auto-insert "\\.tex$" "/c/temp/autoinsert.tex")))
Maybe, that is important, maybe not. I've got to get home now and I cannot further investigate that.
You're probably looking for auto-insert-mode. This is orthogonal to AUCTeX - for instance, I use it to insert a class-template for .java files.
Put the following in your .emacs file:
(auto-insert-mode)
;; *NOTE* Trailing slash important
(setq auto-insert-directory "/path/to/template/directory/")
(setq auto-insert-query nil)
(define-auto-insert "\\.tex$" "my-latex-template.tex")
Of course, you could make the regular expression used as the first argument to define-auto-insert more complex e.g. to insert different preambles depending on the working directory.
I adapted this code from an example from the EmacsWiki where you can also find additional information.
This is the simplest solution I can think of:
(defun insert-latex-template()
(when (= (point-max) (point-min))
(insert-file "/path/to/your/template/file")))
(add-hook 'latex-mode-hook 'insert-latex-template)

How do I beautify lisp source code?

My code is a mess many long lines in this language like the following
(defn check-if-installed[x] (:exit(sh "sh" "-c" (str "command -v " x " >/dev/null 2>&1 || { echo >&2 \"\"; exit 1; }"))))
or
(def Open-Action (action :handler (fn [e] (choose-file :type :open :selection-mode :files-only :dir ListDir :success-fn (fn [fc file](setup-list file)))) :name "Open" :key "menu O" :tip "Open spelling list"))
which is terrible. I would like to format it like so
(if (= a something)
(if (= b otherthing)
(foo)))
How can I beautify the source code in a better way?
The real answer hinges on whether you're willing to insert the newlines yourself. Many systems
can indent the lines for you in an idiomatic way, once you've broken it up into lines.
If you don't want to insert them manually, Racket provides a "pretty-print" that does some of what you want:
#lang racket
(require racket/pretty)
(parameterize ([pretty-print-columns 20])
(pretty-print '(b aosentuh onethunoteh (nte huna) oehnatoe unathoe)))
==>
'(b
aosentuh
onethunoteh
(nte huna)
oehnatoe
unathoe)
... but I'd be the first to admit that inserting newlines in the right places is hard, because
the choice of line breaks has a lot to do with how you want people to read your code.
I use Clojure.pprint often for making generated code more palatable to humans.
it works well for reporting thought it is targeted at producing text. The formatting built into the clojure-mode emacs package produces very nicely formatted Clojure if you put the newlines in your self.
Now you can do it with Srefactor package.
Some demos:
Formatting whole buffer demo in Emacs Lisp (applicable in Common Lisp as well).
Transform between one line <--> Multiline demo
Available Commands:
srefactor-lisp-format-buffer: format whole buffer
srefactor-lisp-format-defun: format current defun cursor is in
srefactor-lisp-format-sexp: format the current sexp cursor is in.
srefactor-lisp-one-line: turn the current sexp of the same level into one line; with prefix argument, recursively turn all inner sexps into one line.
Scheme variants are not as polished as Emacs Lisp and Common Lisp yet but work for simple and small sexp. If there is any problem, please submit an issue report and I will be happy to fix it.

emacs: highlighting balanced expressions (eg. LaTeX tags)

What would be a good way to get Emacs to highlight an expression that may include things like balanced brackets -- e.g. something like
\highlightthis{some \textit{text} here
some more text
done now}
highlight-regex works nicely for simple things, but I had real trouble writing an emacs regex to recognize line breaks, and of course it matches till the first closing bracket.
(as a secondary question: pointers to any packages that extend emacs regex syntax would be much appreciated -- I am having pretty hard time with it, and I'm fairly familiar with regexes in perl.)
Edit: For my specific purpose (LaTeX tags highlighting in an AUCTeX buffer), I was able to get this to work by customizing an AUCTeX specific variable font-latex-user-keyword-classes, that adds something like this to custom-set-variables in .emacs:
'(font-latex-user-keyword-classes (quote (("mycommands" (("highlightthis" "{")) (:slant italic :foreground "red") command))))
A more generic solution would still be nice to have though!
You could use functions acting on s-expressions to work with the region you want to highlight, and use one of the solutions mentionned on this question to actually highlight it.
Here is an example :
(defun my/highlight-function ()
(interactive)
(save-excursion
(goto-char (point-min))
(search-forward "\highlightthis")
(let ((end (scan-sexps (point) 1)))
(add-text-properties (point) end '(comment t face highlight)))))
EDIT : Here is an example using a similar function with Emacs' standard font locking system, as explained in the search-based fontification section of the emacs-lisp manual :
(defun my/highlight-function (bound)
(if (search-forward "\highlightthis" bound 'noerror)
(let ((begin (match-end 0))
(end (scan-sexps (point) 1)))
(set-match-data (list begin end))
t)
nil))
(add-hook 'LaTeX-mode-hook
(lambda ()
(font-lock-add-keywords nil '(my/highlight-function))))

Emacs Brace and Bracket Highlighting?

When entering code Emacs transiently highlights the matching brace or bracket. With existing code however is there a way to ask it to highlight a matching brace or bracket if I highlight its twin?
I am often trying to do a sanity check when dealing with compiler errors and warnings. I do enter both braces usually when coding before inserting the code in between, but have on occasion unintentionally commented out one brace when commenting out code while debugging.
Any advice with dealing with brace and bracket matching with Emacs?
OS is mostly Linux/Unix, but I do use it also on OS X and Windows.
If you're dealing with a language that supports it, give ParEdit a serious look. If you're not using with a Lisp dialect, it's not nearly as useful though.
For general brace/bracket/paren highlighting, look into highlight-parentheses mode (which color codes multiple levels of braces whenever point is inside them). You can also turn on show-paren-mode through customizations (that is M-x customize-variable show-paren-mode); that one strongly highlights the brace/bracket/paren matching one at point (if the one at point doesn't match anything, you get a different color).
my .emacs currently contains (among other things)
(require 'highlight-parentheses)
(define-globalized-minor-mode global-highlight-parentheses-mode highlight-parentheses-mode
(lambda nil (highlight-parentheses-mode t)))
(global-highlight-parentheses-mode t)
as well as that show-paren-mode customization, which serves me well (of course, I also use paredit when lisping, but these are still marginally useful).
Apart from the answer straight from the manual or wiki, also have a look at autopair.
tried on emacs 26
(show-paren-mode 1)
(setq show-paren-style 'mixed)
enable showing parentheses
set the showing in such as highlit the braces char., or if either one invisible higlight what they enclose
for toggling the cursor position / point between both, put this script in .emacs
(defun swcbrace ()(interactive)
(if (looking-at "(")(forward-list)
(backward-char)
(cond
((looking-at ")")(forward-char)(backward-list))
((looking-at ".)")(forward-char 2)(backward-list))
)))
(global-set-key (kbd "<C-next>") 'swcbrace)
it works toggling by press Control-Pgdn
BTW, for the immediate question: M-x blink-matching-open will "re-blink" for an existing close paren, as if you had just inserted it. Another way to see the matching paren is to use M-C-b and M-C-f (which jump over matched pairs of parens), which are also very useful navigation commands.
I second ParEdit. it is very good atleast for lisp development.
FWIW I use this function often to go to matching paren (back and forth).
;; goto-matching-paren
;; -------------------
;; If point is sitting on a parenthetic character, jump to its match.
;; This matches the standard parenthesis highlighting for determining which
;; one it is sitting on.
;;
(defun goto-matching-paren ()
"If point is sitting on a parenthetic character, jump to its match."
(interactive)
(cond ((looking-at "\\s\(") (forward-list 1))
((progn
(backward-char 1)
(looking-at "\\s\)")) (forward-char 1) (backward-list 1))))
(define-key global-map [(control ?c) ?p] 'goto-matching-paren) ; Bind to C-c p
Declaimer: I am NOT the author of this function, copied from internet.
If you just want to check the balanced delimiters, be them parentheses, square brackets or curly braces, you can use backward-sexp (bound to CtrlAltB) and forward-sexp (bound to CtrlAltF) to skip backward and forward to the corresponding delimiter. These commands are very handy to navigate through source files, skipping structures and function definitions, without any buffer modifications.
You can set the below in your init.el:
(setq show-paren-delay 0)
(show-paren-mode 1)
to ensure matching parenthesis are highlighted.
Note that (setq show-paren-delay 0) needs to be set before (show-paren-mode 1) so that there's no delay in highlighting, as per the wiki.
If you want to do a quick check to see whether brackets in the current file are balanced:
M-x check-parens
Both options tested on Emacs 27.1