How to hide the symbol $ when highlighting LaTeX equations in Emacs Org-mode? - emacs

I know that in Org-mode, the emphasis markers like *, ~, =, +, _ can be hidden by this setting: (setq org-hide-emphasis-markers t).
I wonder if there is any option that enables hiding the markers like $ or \(, \) of LaTeX?
This will be useful when LaTeX math equations can be highlighted by setting:
(setq org-highlight-latex-and-related '(latex script entities))
Update 1
I tried the solution proposed by #Thomas on a fresh emacs -q but somehow the symbol $ is still not hidden, while other markers like *,+ are. \
Not sure if there is something wrong with my Emacs? I'm using Org 9.3 of Emacs 27.1
Update 2
The solution of Thomas does work for Emacs 25.2!
But somehow, there is a major change in Emacs 26.2, 26.3, 27.1 that breaks this feature... :(
Update 3
Since the solution suggested by Thomas doesn't work with recent Emacs (26 or newer), I finally came up with a quick solution by customizing the function org-do-latex-and-related of Org-mode.
(defun org-do-latex-and-related (_limit)
"Highlight LaTeX snippets and environments, entities and sub/superscript.
Stop at first highlighted object, if any. Return t if some
highlighting was done, nil otherwise."
(when (org-string-nw-p org-latex-and-related-regexp)
(catch 'found
(while (re-search-forward org-latex-and-related-regexp
nil t) ;; on purpose, we ignore LIMIT
(unless (cl-some (lambda (f) (memq f '(org-code org-verbatim underline
org-special-keyword)))
(save-excursion
(goto-char (1+ (match-beginning 0)))
(face-at-point nil t)))
(let* ((offset (if (memq (char-after (1+ (match-beginning 0)))
'(?_ ?^))
1
0))
(start (+ offset (match-beginning 0)))
(end (match-end 0)))
(if (memq 'native org-highlight-latex-and-related)
(org-src-font-lock-fontify-block "latex" start end)
(font-lock-prepend-text-property start end
'face 'org-latex-and-related))
;;<<<<<<<<<<<<<<<<<<<<<
;; my code starts here
(when (and org-hide-emphasis-markers (< (+ start 4) end))
(cond ((member (buffer-substring start (+ start 2)) '("$$" "\\("))
(add-text-properties start (+ start 2) '(invisible org-link)))
((string= (buffer-substring (1+ start) (+ start 2)) "$")
(add-text-properties (1+ start) (+ start 2) '(invisible org-link))))
(cond ((member (buffer-substring end (- end 2)) '("$$" "\\)"))
(add-text-properties end (- end 2) '(invisible org-link)))
((string= (buffer-substring (1- end) (- end 2)) "$")
(add-text-properties (1- end) (- end 2) '(invisible org-link)))))
;; my code ends here
;;>>>>>>>>>>>>>>>>>>>>>
(add-text-properties (+ offset (match-beginning 0)) (match-end 0)
'(font-lock-multiline t)))
(throw 'found t)))
nil)))
If anyone interested in this feature, you can place the above function somewhere in your Emacs configuration file, after Org-mode is loaded, so that the new org-do-latex-and-related will override the original one of Org-mode.
Here is what I obtained using the code above:

An alternative approach is to not hide the $ symbol at all and instead use org-fragtog. It automatically toggles org-mode latex fragment previews as the cursor enters and exits them.
However, when you open a file with equations it will only toggle the preview of an equation as the cursor enters and leaves the equation. I also have a keybinding (f5) for org-latex-preview. If I open an org-mode file with many equations I can type C-u C-u f5 to toggle latex preview on all equations in the buffer. If I want to change some equation I can just move the cursor there and org-fragtog-mode will turn-off the preview. Then I can edit the equation and the cursor leaves the equation the preview will be automatically enabled again.
This also works correctly when org-highlight-latex-and-related is set to any of the possible choices as well as when you use prettify-symbols-mode.

Customize the variable org-emphasis-alist and add $ as an additional maker with the default values for all customization options. To do so, type
M-x customize-variable [RET] org-emphasis-alist [RET]
Then go to the bottom of the customization buffer, click on the last INS, and insert a dollar sign under Marker character:.
Finally, click on State to make this change permanent either for the current editing session only or also for all future sessions.
NOTE that you have to restart org-mode by typing M-x org-mode again in order for this change to take effect.

Related

emacs - scroll past top of buffer?

Emacs (and all other text editors) by default show blank space below the bottom lines of a buffer. I want emacs to be able to also scroll above/show blank space like this above the top lines in a buffer as well so that the top lines can be viewed in the center of the screen for small files.
With guidance from Thomas's answer here I have created a minor mode for this which is now available on MELPA:
TopSpace - Recenter line 1 with scrollable upper margin/padding
I've started a small minor-mode to accomplish this. However, as first versions go, it's probably buggy, doesn't handle all edge cases (such as e.g., narrowing), and isn't particularly efficient.
Thus, I'd be happy to accept improvements: feel free to directly edit this answer if you can make this code better or to extend it.
(defvar vertical-center-num-buffers 0
"The number of buffers in which `vertical-center-mode' is activated.")
(define-minor-mode vertical-center-mode
"This minor mode displays the contents of a buffer vertically
centered with respect to the window height. This, of course, only
makes sense for buffers whose content is shorter than the window
height."
nil
" vc"
nil
;; is the mode being turned on or off?
(if vertical-center-mode
;; on
(progn
;; keep track of the number of lines in the buffer
(setq-local vertical-center-num-lines (count-lines (point-min) (point-max)))
;; use an overlay to display empty lines at the beginning of the buffer
(setq-local vertical-center-overlay (make-overlay (point-min) (point-max)))
;; initial call to the function that centers the buffer contents
(vertical-center--lines-changed 0)
;; react to changes to the buffer or the window
(add-hook 'kill-buffer-hook 'vertical-center--kill-buffer)
(add-hook 'window-size-change-functions 'vertical-center--window-size-changed)
(when (= vertical-center-num-buffers 0)
(add-hook 'before-change-functions 'vertical-center--before-change)
(add-hook 'after-change-functions 'vertical-center--after-change))
;; this is just to play nice and remove the above hook
;; functions when they're no longer needed. Let's keep our
;; fingers crossed that we'll always stay in sync.
(setq vertical-center-num-buffers (1+ vertical-center-num-buffers)))
;; off
;; delete/unset data structures when the mode is turned off
(delete-overlay vertical-center-overlay)
(makunbound 'vertical-center-num-lines)
(makunbound 'vertical-center-overlay)
(setq vertical-center-num-buffers (1- vertical-center-num-buffers))
;; remove hook functions when they're no longer needed
(when (= vertical-center-num-buffers 0)
(remove-hook 'kill-buffer-hook 'vertical-center--kill-buffer)
(remove-hook 'window-size-change-functions 'vertical-center--window-size-changed)
(remove-hook 'before-change-functions 'vertical-center--before-change)
(remove-hook 'after-change-functions 'vertical-center--after-change))))
;; handle killing of buffers
(defun vertical-center--kill-buffer ()
(when vertical-center-mode
(setq vertical-center-num-buffers (1- vertical-center-num-buffers))))
;; react to changes in the window height
(defun vertical-center--window-size-changed (arg)
(vertical-center--lines-changed 0))
;; handle deletions of buffer text
(defun vertical-center--before-change (beginning end)
(when (boundp 'vertical-center-num-lines)
(let ((num-lines 0))
(while (< beginning end)
(when (= (char-after beginning) ?\n)
(setq num-lines (1- num-lines)))
(setq beginning (1+ beginning)))
(when (< num-lines 0)
(vertical-center--lines-changed num-lines)))))
;; handle insertions into the buffer
(defun vertical-center--after-change (beginning end previous-length)
(when (boundp 'vertical-center-num-lines)
(let ((num-lines 0))
(while (< beginning end)
(when (= (char-after beginning) ?\n)
(setq num-lines (1+ num-lines)))
(setq beginning (1+ beginning)))
(when (> num-lines 0)
(vertical-center--lines-changed num-lines)))))
;; update the display when either the buffer content or the window
;; height has changed
(defun vertical-center--lines-changed (num-lines)
(setq vertical-center-num-lines (+ vertical-center-num-lines num-lines))
(let ((top-margin (/ (- (window-height) vertical-center-num-lines) 2)))
;; set the top margin
(overlay-put vertical-center-overlay 'before-string
(when (> top-margin 0)
(make-string top-margin ?\n)))))
Save the above code in a file named "vertical-center.el" in a directory of your choice, and then add the following lines to your .emacs file:
(setq load-path (append load-path "<directory>"))
(autoload 'vertical-center-mode "vertical-center")
Here, <directory> should be the path to the directory in which you saved the "vertical-center.el" file.
After restarting Emacs, you can now activate or deactivate the mode by typing M-x vertical-center-mode.

Emacs: highlight 2 or more empty lines

I have entered the following code in my .emacs file to highlight unwanted white spaces.
(require 'whitespace)
(setq whitespace-style '(face empty tabs lines-tail trailing))
(global-whitespace-mode t)
This shows (1) empty lines at the beginning & end of buffer
(2) tabs
(3) lines which go over the 80 character limit
(4) trailing white spaces
I would like emacs to automatically highlight '2 or more empty lines'. Any ideas on how to implement this? I did find a blog post explaining a way to do this with the help of regexp, but I am not sure how to implement this in .emacs file.
Edit 1: Found a way to delete extra blank lines but this still doesn't help me with highlighting multiple blank lines automatically. delete extra blank lines in emacs
Edit 2: Adding the following to .emacs seems to work, but only after I save and reopen file in a buffer.
(add-hook 'change-major-mode-hook '(lambda () (highlight-regexp "\\(^\\s-*$\\)\n" 'hi-yellow)))
Edit 3: After adding (global-hi-lock-mode 1) to .emacs file just before the line in Edit 2, it seems to highlight 1 or more empty lines within the buffer. I am not sure how to modify the regexp so that it will only accept 2 or more empty lines.
Just use library Highlight (highlight.el). That's what it's for.
Use command hlt-highlight-regexp-region (C-x X h x) or hlt-highlight-regexp-to-end (C-x X h e). (To unhighlight a regexp, use C-x X u x or C-x X u e.)
Interactively, you input the regexp to use as usual in Emacs (with C-q C-j to match a newline character, and no need for double backslashes), so you type \(^\s-*$\) C-q C-j.
Your highlight-regexp-solution can be made into a minor-mode with the following elisp (e.g., in your .emacs file).
You can activate the minor mode by right-clicking onto one of the mode-names in the mode-line and then selecting nl2-mode. You can deactivate the minor mode by clicking on nl2 in the mode line and selecting Turn off minor mode.
To understand the code see the help for define-minor-mode and define-key (e.g., C-h f define-minor-mode RET). Note, that in emacs also mouse clicks in menus count as key strokes.
(define-minor-mode nl2-mode
"Highlight two successive newlines."
:global t
:lighter " nl2"
(if nl2-mode
(highlight-regexp "\\(^\\s-*$\\)\n" 'hi-yellow)
(unhighlight-regexp "\\(^\\s-*$\\)\n")))
(define-key mode-line-mode-menu [nl2-mode]
`(menu-item ,(purecopy "nl2-mode") nl2-mode
:help "Highlight two succesive newlines."
:button (:toggle . (bound-and-true-p nl2-mode))))
There are several facts that make highlighting two consecutive empty lines more complicated (font-lock tends to only highlight non-empty regions, linebreaks are limits for the region to re-fontify, re-fontification after buffer changes are required).
The following code shows one way. Maybe, there are easier ways.
(require 'font-lock)
(global-font-lock-mode)
(defface jit-lock-nl2-face '((default :background "yellow"))
"Face to indicate two or more successive newlines."
:group 'jit-lock)
(defun jit-nl2-extend (start end &optional old)
"Extend region to be re-fontified"
(save-excursion
(save-match-data
;; trailing:
(goto-char end)
(skip-chars-forward "[[:blank:]]\n")
(setq jit-lock-end (point))
;; leading:
(goto-char start)
(beginning-of-line)
(skip-chars-backward "[[:blank:]]\n")
(unless (bolp) (forward-line))
(setq jit-lock-start (point)))))
(defun jit-nl2 (jit-lock-start jit-lock-end)
"Highlight two or more successive newlines."
(save-excursion
(save-match-data
(jit-nl2-extend jit-lock-start jit-lock-end)
;; cleanup
(remove-text-properties jit-lock-start jit-lock-end '(font-lock-face jit-lock-nl2-face))
;; highlight
(while (< (point) jit-lock-end)
(if (looking-at "[[:blank:]]*\n\\([[:blank:]]*\n\\)+")
(progn (put-text-property (match-beginning 0) (match-end 0) 'font-lock-face 'jit-lock-nl2-face)
(goto-char (match-end 0)))
(forward-line))))))
(add-hook 'after-change-major-mode-hook (lambda ()
(add-hook 'jit-lock-after-change-extend-region-functions 'jit-nl2-extend)
(jit-lock-register 'jit-nl2)
(jit-lock-mode 1)
))

Select to beginning / ending of word-wrapped visual line

The default behavior of the latest nightly builds of Aquamacs24 and Emacs-Trunk both appear to function differently than I'm accustomed -- i.e., command+shift+right or command+shift+left jumps to the beginning or end of the visual line without selecting the region. Instead, it is necessary to set the mark by moving the shift+left or shift+right or Ctrl+SPC to activate the mark and then go to the end or beginning of the visual line. In other words, it is a two step approach that needs to be combined into one-fell-swoop.
The following code almost does what I'm looking for, except that I'd like the selection to automatically cancel if I change my mind and release the shift key and move the arrow key. The way the code is presently written keeps the selection mode active and does not cancel unless I use a Ctrl+g.
Can anyone please suggest a modification to my code or an alternative way to achieve the desired behavior?
(defun beginning-of-visual-line (&optional n)
"Move point to the beginning of the current line.
If `word-wrap' is nil, we move to the beginning of the buffer
line (as in `beginning-of-line'); otherwise, point is moved to
the beginning of the visual line."
(interactive)
(if word-wrap
(progn
(if (and n (/= n 1))
(vertical-motion (1- n))
(vertical-motion 0))
(skip-read-only-prompt))
(beginning-of-line n)))
(defun end-of-visual-line (&optional n)
"Move point to the end of the current line.
If `word-wrap' is nil, we move to the end of the line (as in
`beginning-of-line'); otherwise, point is moved to the end of the
visual line."
(interactive)
(if word-wrap
(unless (eobp)
(progn
(if (and n (/= n 1))
(vertical-motion (1- n))
(vertical-motion 1))
(skip-chars-backward " \r\n" (- (point) 1))))
(end-of-line n)))
(defun command-shift-right ()
""
(interactive) ;; this is a command (i.e. can be interactively used)
(when (not (region-active-p)) ;; if the region is not active...
(push-mark (point) t t)) ;; ... set the mark and activate it
(end-of-visual-line)) ;; move point defined
(defun command-shift-left ()
""
(interactive) ;; this is a command (i.e. can be interactively used)
(when (not (region-active-p)) ;; if the region is not active...
(push-mark (point) t t)) ;; ... set the mark and activate it
(beginning-of-visual-line)) ;; move point defined
Emacs has built-in support for shift-select-mode: just use (interactive "^") in your functions and they'll select when triggered with a shift.

Why does re-search-backward give different result in python-mode?

I have been using python-mode for a long time. And I always use subword-mode. But subword-mode behave strangely in python-mode. For example, the M-b movement. If there is a variable named test_varialbe and I put the cursor at the end of this variable, in python-mode M-b will make the cursor point to t while in other modes it will go to v.
So I looked into the source of subword-mode and found the following function:
(defun subword-backward-internal ()
(if (save-excursion
(let ((case-fold-search nil))
(re-search-backward
(concat
"\\(\\(\\W\\|[[:lower:][:digit:]]\\)\\([[:upper:]]+\\W*\\)"
"\\|\\W\\w+\\)")
nil t)))
(goto-char
(cond
((and (match-end 3)
(< 1 (- (match-end 3) (match-beginning 3)))
(not (eq (point) (match-end 3))))
(1- (match-end 3)))
(t
(1+ (match-beginning 0)))))
(backward-word 1)))
After making some tests, I found re-search-backward is giving different result in different modes. If I eval-expression the (let ...) expression in python-mode, the cursor will jump to the space before test_varialbe, and in other modes it will jump to -.
Why is this? What has caused re-search-backward to behave differently?
The reason is that there are differences in the Syntax table definition of '_'.
In Python mode '_' has a syntax definition of "word" whereas in other cases it is defined as "symbol". Look at Elisp manual: Syntax tables
in addition:
Grasping identifiers, basic commands like `forward-word' make more sense with "_" on word syntax. AFAIK Emacs doesn't provide the respective commands WRT with symbols.

Shift a region or line in emacs

I'm looking for a way in emacs to shift text to the right or to the left by n spaces. A similar functionality that it in vim << or >>. It should work on a region or if no region is selected on a current line and not move the cursor from its current location.
The solution from EmacsWiki does not work very well as the M-x indent-rigidly since it somewhat remembers the last region used and shifts that one instead. The closest seems to be the one here but I did not managed to make it work. I'm not a lisp developer so it's difficult to modify the code. I will appreciate any help.
Thanks!
You could select the region then C-u C-x <tab> will shift 4 spaces. You can type a number after C-u to change 4 to anything else.
Maybe this works the way you want.
(defun shift-text (distance)
(if (use-region-p)
(let ((mark (mark)))
(save-excursion
(indent-rigidly (region-beginning)
(region-end)
distance)
(push-mark mark t t)
(setq deactivate-mark nil)))
(indent-rigidly (line-beginning-position)
(line-end-position)
distance)))
(defun shift-right (count)
(interactive "p")
(shift-text count))
(defun shift-left (count)
(interactive "p")
(shift-text (- count)))
To achieve this I usually do a trick:
activate CUA mode
go to the beginning of line
C-RET, now if you move the cursor you should see a rectangular red region
Move the cursor down the lines and type space until you've obtained the correct shifting.
This can be done also programmatically in some way (in the same way).
EDIT:
I've just read the article in emacs wiki, it's the same solution except for the CUA mode that is infinitely more powerful than the "common" rectanguar selection (since it's visual).
As I use Evil (with Spacemacs), the Vim-like region shifting is already implemented in visual mode with S-v and </> properly.
I'm mostly using hybrid-mode though, and when it's active I also want to be able to shift the region, preferrably by the current language's shift-width.
To achieve this, here's an implementation that re-uses evil's shifting, but does it "properly" in hybrid-mode.
(defun jj/shift-text (beg end shift-block-fun shift-line-fun)
"shift text in region or line using evil like S-v with < and > do in Vim.
It takes special care of preserving or even extending the region to the moved text lines."
(if (use-region-p)
(progn
(let ((point-at-end (< (mark) (point))))
;; fix up current region end to grab the whole line
(if point-at-end
(end-of-line)
(beginning-of-line))
;; then fix up the other region end
(exchange-point-and-mark)
(if point-at-end
(beginning-of-line)
(end-of-line))
;; restore mark-point order
(exchange-point-and-mark)
(let ((linebeg (if point-at-end (mark) (point)))
(lineend (if point-at-end (point) (mark))))
;; shift the text
(save-mark-and-excursion
(funcall shift-block-fun linebeg lineend)
;; "In Transient Mark mode, every buffer-modifying primitive sets deactivate-mark"
;; but we wanna keep it active :)
(setq deactivate-mark nil)))))
(funcall shift-line-fun 1)))
(defun jj/shift-left (beg end)
(interactive "r")
(jj/shift-text beg end #'evil-shift-left #'evil-shift-left-line))
(defun jj/shift-right (beg end)
(interactive "r")
(jj/shift-text beg end #'evil-shift-right #'evil-shift-right-line))
and where your keybindings are defined:
;; text shifting. evil-normal-state-map has these anyway.
(define-key evil-hybrid-state-map (kbd "M-<") #'jj/shift-left)
(define-key evil-hybrid-state-map (kbd "M->") #'jj/shift-right)