I would like to have a emacs function which selects (marks) a region given by start and end.
I tried it with
(defun mark-range (start end)
"Mark buffer content from start to end"
(message (concat "Select " (number-to-string start) " " (number-to-string end)))
(setq bufmax (max start end))
(setq bufmin (min start end))
(goto-char bufmax)
(set-mark bufmin) ;actually the comment on set-mark says: Do not use!
;(set-mark-command bufmin) did not work for this
)
It works when called in simple functions, but sometimes this function just does not work even when the message shows the right content of start and end. The selection is then just not there.
Any Ideas, how I can achieve a reliable function?
(I am using spacemacs dev branch)
EDIT:
Ok here is the use case, I actually want to move text up and down with Alt-Up Alt-Down like it is in eclipse
I found there is a block move text, but it does not what I want: Select the full lines the region touches and moves it up afterwards staying selected to be used again.
So I first check how many lines I must move the line before the first down, and then use this also to select the lines again. But then the selection does not work. It is simply not there.
I now tried to integrate Drews answer but did not really help, mark does not appear, (added deactivate-mark as there is one before, also no luck).
Tried it with my approach including (activate, deactivate) before, also does not work.
(defun rl-move-up-block(start end)
(let (last first dist m-start)
(goto-char (max start end))
(setq last (line-number-at-pos))
(goto-char (min start end))
(setq first (line-number-at-pos))
(goto-char (min start end))
(forward-line -1)
(setq dist (+ (- last first) 1))
(dotimes (i dist)
(move-text-line-down))
(forward-line (- 0 dist))
(set-mark (line-beginning-position))
(forward-line (- dist 1))
(end-of-line)
(activate-mark)
)
)
(defun rl-move-up (start end)
"Move text up like in eclipse"
(interactive "r")
(if (use-region-p)
(rl-move-up-block start end)
(move-text-line-up)
)
)
(global-set-key (kbd "M-<up>") 'rl-move-up)
EDIT 2:
Well I just found out if I remove the moving of the lines, replacing it with just moving the cursor, marking works just fine.
;(dotimes (i dist)
; (move-text-line-down))
(forward-line dist)
So the issue is changing text and then marking again.
I once tried to have a view what it does in slow mo, by putting a sleep between each line.
Did not work, just made the whole function take longer - maybe it needs a refresh view call for something. Is there something to refresh or finalize a change? Maybe that helps to make mark work again after moving lines.
You were just missing function activate-mark.
The doc says that set-mark sets the mark, and that sometimes people do that unnecessarily. Here you explicitly want to set the mark at an arbitrary position (the least of START or END).
You also want to call message last.
(defun mark-range (start end)
"..."
(set-mark (min start end))
(goto-char (max start end))
(activate-mark)
(message "Select %d to %d" start end))
Well turns out there is a variable.
I checked the code of move-text-down a existing command
and found there is a variable set to nil
If I do that after moving text it works
(dotimes (i dist)
(move-text-line-down))
(setq deactivate-mark nil) ; <<<<<<
(forward-line (- 0 dist))
Related
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.
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.
I want an emacs binding (in evil mode) to take the selection and move it over one space at a time to the right, or to the left. For example, highlight five line, hit [some-key] and all five lines slide one space to the right, and hit [shift some-key] and all lines slide one space to the left.
This might be a better approach than the one I had originally posted.
(defun jg-indent (start end count)
(interactive "r\np")
(save-excursion
(let ((start (if (use-region-p)
start
(beginning-of-line)
(point)))
(end (if (use-region-p)
end
(end-of-line)
(point))))
(indent-rigidly start end count))))
(defun jg-unindent (start end)
(interactive "r")
(jg-indent start end -1))
(global-set-key "\C-c=" 'jg-indent)
(global-set-key "\C-c+" 'jg-unindent)
In Emacs, I sometimes want to kill or copy a rectangle of text such as this one:
XX first line
XX second line is longer
XX 3rd line short
I want to copy the three lines without the leading "XX" on every line. However, it is impossible to mark both corners of the required rectangle, because the first and third lines do not reach to the right edge of the rectangle that I'm after. So how would I copy the three lines above without the leading "XX" in emacs?
Start marking the rectangle from the first line and when you are at the end of the 3d line then just type spaces until the line is long enough. That's what I usually do.
After copying you can type M-\ (delete-horizontal-space) to remove the added spaces.
I see two options that jump out.
The first is to use M-x artist-mode,
this will let you move to the position on the first/last line you want.
At which point you cut the rectangle C-x r k, and then paste
it wherever you want. Don't forget to type C-c C-c to exit artist mode.
The second is to just cut all three lines using the regular C-w
and then when you paste, delete the rectangle of XXs at the beginning of the lines.
You can have a look at the cua-selection-mode (M-x cua-selection-mode).
It allows you to do what you want, but only in the graphical emacs (not in the Terminal). The key bindings are a bit different: you start the region with C-RET (instead of C-SPC) and cut/yank the rectangle simply with C-w/C-y (not using the rectangle commands).
You can find an example in this blog.
To permanently enable the mode just add
(cua-selection-mode t)
to your .emacs.
P.S. the full cua-mode will also change further key bindings. It is not necessary to use it.
simple modifications of inbulit defuns. kill-right-rectangle function does what you want.
I am sure there would much better way to do it. Nonetheless it works.
Two points about the following code.
- Since the idea is to get the text upto end of the line, you don't even need to specify the last column. simply mark at first line (in you example point at "f") and go down to third line to "3" call the function. (we only need one column, so don't need to move cursor to any right)
- this doesn't work if the buffer is read only. its just not implemented.
(defun end-column (POINT)
"returns end column"
(save-excursion
(goto-char POINT)
(move-end-of-line 1)
(current-column)))
(defun apply-on-right-rectangle (function start end &rest args)
(let (startcol startpt endcol endpt final-point)
(save-excursion
(goto-char start)
(setq startcol (current-column))
(beginning-of-line)
(setq startpt (point))
(goto-char end)
(setq endcol (current-column))
(forward-line 1)
(setq endpt (point-marker))
;; ensure the start column is the left one.
(if (< endcol startcol)
(let ((col startcol))
(setq startcol endcol endcol col)))
;; start looping over lines
(goto-char startpt)
(while (< (point) endpt)
(setq endcol (end-column (point)))
(apply function startcol endcol args)
(setq final-point (point))
(forward-line 1)))
final-point))
(defun delete-extract-right-rectangle (start end &optional fill)
(let ((lines (list nil)))
(apply-on-right-rectangle 'delete-extract-rectangle-line start end lines fill)
(nreverse (cdr lines))))
(defun kill-right-rectangle (start end &optional fill)
(interactive "r\nP")
(condition-case nil
(setq killed-rectangle (delete-extract-right-rectangle start end fill))
((buffer-read-only text-read-only)
(setq killed-rectangle (extract-rectangle start end))
(if kill-read-only-ok
(progn (message "Read only text copied to kill ring") nil)
(barf-if-buffer-read-only)
(signal 'text-read-only (list (current-buffer)))))))
After upgrading to emacs 23.2.1 with Fedora 15 one of my emacs functions is broken and I just can't seem to find the problem. Something has to have changed, but I sure can't find it in the elisp documentation.
I'd really appreciate any suggestions!
What it should do: Pressing Ctl-hyphen should copy the character above the cursor and move the point ahead by 1.
What it does: Keeps copying the character above without advancing the point. HOWEVER, calling it with "M-x insert-char-from-previous-line" or pressing RightArrow between Ctl-hypens works as it should. Adding (forward-char 1) to the end of the script doesn't help.
(defun insert-char-from-previous-line ()
"Copy previous line character by character"
(interactive)
(previous-line 1)
(let ((char-above (following-char) ))
(next-line 1)
(if (not (char-equal char-above ?\n ))
(insert char-above))))
(global-set-key [?\C--] 'insert-char-from-previous-line) ;copy char above
I think your getting caught in a goal column issue. You probably should not use next-line/previous-line for this, rather try this:
(defun insert-char-from-previous-line ()
"Copy previous line character by character"
(interactive)
(let ((curpoint (point))
(curcolumn (current-column)))
(forward-line -1)
(forward-char curcolumn)
(let ((char-above (following-char) ))
(goto-char curpoint)
(if (not (char-equal char-above ?\n ))
(insert char-above)))))
From the docs on pervious-line:
If you are thinking of using this in a Lisp program, consider using
`forward-line' with a negative argument instead. It is usually easier
to use and more reliable (no dependence on goal column, etc.).
(describe-function 'previous-line)
don't move the point for something like this:
(defun i-char (arg)
(interactive "*p")
(let ((start (+ (point-at-bol 0)
(current-column)))))
(insert (buffer-substring-no-properties start (+ start arg))))