Emacs: swapping replace queries - emacs

Using query-replace, the minibuffer says this (having saved the previous arguments):
Query replace (default FROM -> TO)
is there a command to swap the args? To get this:
Query replace (default TO -> FROM)

AFAIK, nothing out of the box does that for you. But IMHO you don't need that.
All you need to do is use M-p. Use it once to get the last TO you used. Then repeat M-p a couple times to get the last FROM you used. Very quick.
After that, you can use C-x ESC ESC (or C-x M-: or C-x M-ESC), possibly followed by M-p, to repeat either combination (TO -> FROM or FROM -> TO).

(defun swap-query-replace-defaults ()
"Swap the initial expressions offered by `query-replace'. "
(interactive)
(let* ((erg query-replace-defaults)
(first (car erg))
(second (cdr erg)))
(setq query-replace-defaults (cons second first))
(when (interactive-p) (message "%s" query-replace-defaults))
query-replace-defaults))
Made a feature-request:
http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00102.html

There's a shortcut to swap the args: M-p RET M-p M-p RET

I use this:
;; Redefine `query-replace-read-from' to add a custom keymap when
;; replacing strings. Now, C-u ENTER does the reverse suggested
;; replacement.
(defvar query-replace-keymap
(let ((map (make-sparse-keymap)))
(set-keymap-parent map minibuffer-local-map)
(define-key map [remap exit-minibuffer]
(lambda ()
(interactive)
(if (and current-prefix-arg query-replace-defaults)
(setq query-replace-defaults
(cons
(cdr query-replace-defaults)
(car query-replace-defaults))))
(exit-minibuffer)))
map))
(defun query-replace-read-from (prompt regexp-flag)
"Query and return the `from' argument of a query-replace operation.
The return value can also be a pair (FROM . TO) indicating that the user
wants to replace FROM with TO."
(if query-replace-interactive
(car (if regexp-flag regexp-search-ring search-ring))
(let* ((history-add-new-input nil)
(query-replace-defaults query-replace-defaults)
(prompt
(if query-replace-defaults
(format "%s (default %s -> %s): " prompt
(query-replace-descr (car query-replace-defaults))
(query-replace-descr (cdr query-replace-defaults)))
(format "%s: " prompt)))
(from
;; The save-excursion here is in case the user marks and copies
;; a region in order to specify the minibuffer input.
;; That should not clobber the region for the query-replace itself.
(save-excursion
(if regexp-flag
(read-regexp prompt nil query-replace-from-history-variable)
(read-from-minibuffer
prompt nil query-replace-keymap nil query-replace-from-history-variable
(car (if regexp-flag regexp-search-ring search-ring)) t)))))
(if (and (zerop (length from)) query-replace-defaults)
(cons (car query-replace-defaults)
(query-replace-compile-replacement
(cdr query-replace-defaults) regexp-flag))
(add-to-history query-replace-from-history-variable from nil t)
;; Warn if user types \n or \t, but don't reject the input.
(and regexp-flag
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from)
(let ((match (match-string 3 from)))
(cond
((string= match "\\n")
(message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead"))
((string= match "\\t")
(message "Note: `\\t' here doesn't match a tab; to do that, just type TAB")))
(sit-for 2)))
from))))

Related

Emacs jump to next annotated words or phrases

When using Emacs, I notice that words or phrases in a buffer can be annotated or highlighted by many minor modes like hi-lock-mode, flyspell-mode, flycheck-mode...
Is there any uniform way to jump to the highlighted words or phrases created by all these minor modes? Specifically, is there any package or function support jumping to the next and previous highlighted phrases?
When using Eclipse, I can do it by pressing Ctrl-. and Ctrl-,. However, when switching to Emacs, so far, I haven't found an equivalent feature.
Developing a mode which aims to tackle that kind of tasks
https://github.com/andreas-roehler/werkstatt/tree/master/general-key
Facilitates the setting of a general command.
Than this command gets different bindings according to modes - which needs to be edited by hand once. Afterwards it allows to set/change a key at one place for all related/bound commands.
See for example inside
https://github.com/andreas-roehler/werkstatt/blob/master/general-key/general-key-python-mode.el
It's alpha still notably for the install process. Bug reports resp. feature requests welcome.
Not surprisingly, #Drew has answered something related to this.
You can programmatically use isearch with something like:
(defun foo (regexp)
(interactive (list (read-regexp "Regexp: ")))
(isearch-mode t t)
(let ((isearch-regexp nil))
(isearch-yank-string regexp)))
This will pull your previous regexp history, including those from hi-lock. I imagine it would be a fun exercise to modify this to use hi-lock-regexp-history.
If you use swiper, you can restrict the search candidates to lines with highlighted patterns by hi-lock-mode.
Here is a simple wrapper of swiper:
(require 'cl-lib)
(defun swiper-over-highlights-simple ()
(interactive)
(let ((original-swiper--candidates (symbol-function 'swiper--candidates)))
(cl-letf (((symbol-function 'swiper--candidates)
(lambda ()
(let ((pattern (mapconcat #'car hi-lock-interactive-patterns "\\|")))
(cl-remove-if-not (lambda (x) (string-match-p pattern x))
(funcall original-swiper--candidates))))))
(swiper))))
In addition, you can change ivy-read's preselect argument, which initializes the first matched line inside swiper.
The following fuction, modified from swiper, finds the closest next line with a highlighted pattern:
(defun swiper-over-highlights (&optional initial-input)
(interactive)
(let ((original-swiper--candidates (symbol-function 'swiper--candidates))
(pattern (mapconcat #'car hi-lock-interactive-patterns "\\|")))
(cl-letf (((symbol-function 'swiper--candidates)
(lambda ()
(cl-remove-if-not (lambda (x) (string-match-p pattern x))
(funcall original-swiper--candidates)))))
(let ((candidates (swiper--candidates)))
(swiper--init)
(setq swiper-invocation-face
(plist-get (text-properties-at (point)) 'face))
(let ((preselect
(save-excursion
(search-forward-regexp pattern nil t)
(let* ((current-line-value (current-line))
(candidate-line-numbers (mapcar (lambda (x) (cadr (text-properties-at 0 x)))
candidates))
(preselect-line-num (cl-find-if (lambda (x) (<= current-line-value x))
candidate-line-numbers)))
(- (length candidate-line-numbers)
(length (member preselect-line-num candidate-line-numbers))))))
(minibuffer-allow-text-properties t)
res)
(unwind-protect
(and
(setq res
(ivy-read
"Swiper: "
candidates
:initial-input initial-input
:keymap swiper-map
:preselect preselect
:require-match t
:action #'swiper--action
:re-builder #'swiper--re-builder
:history 'swiper-history
:extra-props (list :fname (buffer-file-name))
:caller 'swiper))
(point))
(unless (or res swiper-stay-on-quit)
(goto-char swiper--opoint))
(isearch-clean-overlays)
(unless (or res (string= ivy-text ""))
(cl-pushnew ivy-text swiper-history))
(setq swiper--current-window-start nil)
(when swiper--reveal-mode
(reveal-mode 1))))))))

How to make describe-function "C-h f" case-insensitive by default

When searching for a function whose name I partly remember, I use C-h f to call describe-function, enter *part-of-function-name, and hit TAB. But I now realize that this search is not case-insensitive.
For example:
C-h f info TAB
lists all functions starting with info, but doesn't include those starting with Info, whereas
C-h f Info TAB
lists all functions starting with Info, but doesn't include those starting with info.
Another example:
C-h f *nfc TAB
gives me *nfc [No match], whereas
C-h f *NFC TAB
gives me ucs-normalize-HFS-NFC-region.
How can I make describe-function case-insensitive by default, using some configuration in my init.el file?
Add a binding of completion-ignore-case to t in the interactive spec of the command. This has the advantages that (a) it affects only describe-function (C-h f) and (b) you can easily toggle it on/off (as with any Emacs advice).
(defadvice describe-function (before ignore-case activate)
"Make it case-insensitive."
(interactive
(let ((completion-ignore-case t) ; <============= ADDED BINDING
(fn (function-called-at-point))
(enable-recursive-minibuffers t)
val)
(setq val (completing-read
(if fn
(format "Describe function (default %s): " fn)
"Describe function: ")
obarray 'fboundp t nil nil (and fn (symbol-name fn))))
(list (if (equal val "") fn (intern val))))))
(setq completion-ignore-case t) should do what you want, tho globally rather than only for C-h f.
Here's a custom function that I use in place of describe-function.
It uses ido completion.
(defvar functions-cache nil)
;;;###autoload
(defun refresh-functions-cache ()
(interactive)
(setq functions-cache nil)
(mapatoms (lambda (symbol)
(when (fboundp symbol)
(push (symbol-name symbol) functions-cache))))
(setq functions-cache (sort functions-cache #'string<)))
;;;###autoload
(defun describe-function-ex (function)
"Display the full documentation of FUNCTION (a symbol)."
(interactive
(let ((fn (function-called-at-point))
(enable-recursive-minibuffers t)
val)
(unless functions-cache
(refresh-functions-cache))
(setq val (ido-completing-read
(if fn
(format "Describe function (default %s): " fn)
"Describe function: ")
functions-cache
nil t nil nil
(and fn (symbol-name fn))))
(list (if (equal val "")
fn (intern val)))))
(if (null function)
(message "You didn't specify a function")
(help-setup-xref (list #'describe-function function)
(called-interactively-p 'interactive))
(save-excursion
(with-help-window (help-buffer)
(prin1 function)
(princ " is ")
(describe-function-1 function)
(with-current-buffer standard-output
;; Return the text we displayed.
(buffer-string))))))

Shortcut for inserting environments in `org-mode`

I'm using org-mode for organizing myself (very useful so far!). However, it is kind of annoying writting
#+begin_comment
...
#+end_comment
each time I'd like to insert an environment.
Question
Is there a shortcut to insert the #+begin_ and #+end_ for a given environment?
In the same way C-c C-o comment RET would insert
\begin{comment}
\end{comment}
in latex-mode.
Org has a facility called "Easy templates": http://orgmode.org/manual/Easy-Templates.html
A template for comment is missing but you can add it with:
(add-to-list 'org-structure-template-alist '("C" "#+begin_comment\n?\n#+end_comment"))
And use it by typing <C followed by TAB.
Alternatively, you could use yasnippet.
Now the corresponding template section is called Structure Template and the insertion sequence is invoked by C-c C-,. I didn't (require 'org-tempo) which is described to support insertion keys like <s TAB.
The comment environment is already defined in org-structure-template-alist. So the comment would be inserted by
C-c C-, C
It's still possible to add a user defined sequence by, for example,
C-c C-, [TAB|RET|SPC] src python :results output :session
delivering
#+begin_src python :results output :session
#+end_src
(emacs 25.2.2, org-mode 9.2)
You could have a look at "org-auctex-keys.el", a minor mode which I created to offer AUCTeX key bindings within Org documents.
In this case, you'd use C-c C-e to insert an environment (prompt to enter the environment name), as what AUCTeX does.
If you're interested, check it out at https://github.com/fniessen/org-auctex-key-bindings.
Not as elegant as the answer of Michael Markert but maybe more expandable.
1) You can select a region and put the block around it or you can just put the block at point.
2) Keyword expansion and history.
3) Keystrokes: C-c b
The command could be further expanded. E.g., for the src block the various switches like -n -r and export to files could be supported.
(defun list-major-modes ()
"Returns list of potential major mode names (without the final -mode).
Note, that this is guess work."
(interactive)
(let (l)
(mapatoms #'(lambda (f) (and
(commandp f)
(string-match "-mode$" (symbol-name f))
;; auto-loaded
(or (and (autoloadp (symbol-function f))
(let ((doc (documentation f)))
(when doc
(and
(let ((docSplit (help-split-fundoc doc f)))
(and docSplit ;; car is argument list
(null (cdr (read (car docSplit)))))) ;; major mode starters have no arguments
(if (string-match "[mM]inor" doc) ;; If the doc contains "minor"...
(string-match "[mM]ajor" doc) ;; it should also contain "major".
t) ;; else we cannot decide therefrom
))))
(null (help-function-arglist f)))
(setq l (cons (substring (symbol-name f) 0 -5) l)))))
(when (called-interactively-p 'any)
(with-current-buffer (get-buffer-create "*Major Modes*")
(clear-buffer-delete)
(let ((standard-output (current-buffer)))
(display-completion-list l)
(display-buffer (current-buffer)))))
l))
(defvar org-insert-block-hist nil
"History for command `org-insert-block'")
(defvar org-insert-block-hist/src:major nil
"History for major mode in org src blocks.")
(defvar org-insert-block-list (append org-protecting-blocks
'("comment" ""))
"List of block types offered as completion for command `org-insert-block'")
;; block_src switches: -n () -r (references) -l "((%s))" (label format) -k (keep labels)
(defvar org-insert-block-list-specials
"Assoc list of Commands for reading additional specification of org-blocks.")
(setq org-insert-block-list-specials
'(("src" . (concat " " (completing-read "Major mode:"
(list-major-modes)
nil nil
(car org-insert-block-hist/src:major)
'(org-insert-block-hist/src:major . 1)
)))))
(defun org-insert-block (bl &optional b e attributes)
"Put region between b and e into org-block of kind bl.
If b or e is nil then put org-block limiters around point.
The string attributes is inserted behind the string #+begin_... "
(interactive
(let ((usereg (use-region-p))
(blKind (completing-read "Input block kind (tab: completion, uparrow: history):"
org-insert-block-list nil nil (car org-insert-block-hist) '(org-insert-block-hist . 1))))
(list
blKind
(when usereg (region-beginning))
(when usereg (region-end))
(let ((spec (assoc blKind org-insert-block-list-specials)))
(when spec (eval (cdr spec)))
))))
(let ((begBlock (concat "\n#+begin_" bl attributes "\n"))
(endBlock (concat "\n#+end_" bl "\n")))
(if (and b e)
(save-restriction
(narrow-to-region b e)
(goto-char (point-min))
(insert begBlock)
(goto-char (point-max))
(insert endBlock)
(indent-region (point-min) (point-max)))
(let ((p (point)))
(insert endBlock)
(goto-char p)
(insert begBlock))
)))
(add-hook 'org-mode-hook '(lambda ()
(local-set-key (kbd "C-c b") 'org-insert-block)))

Swap parentheses and square brackets in Emacs Paredit

How can I define a command in paredit mode that swaps parentheses and square brackets?
So the task is to turn this, for example:
(blah
(a (b)
c))
into this:
(blah
[a (b)
c])
With paredit mode, move to start of the expression (a ..) and then:
C-M-SPC [ <right> M-s
Without paredit, but still wanting to maintain balanced parens during transitions, move to a and then press C-M-SPC multiple times until error and then (assuming that CUA mode is on):
C-x <timeout> <right> <backspace> <backspace> [ ] <left> C-v
Well that is complex, so let's stick with paredit mode version, and try to make a command out of it. Keyboard Macro Editor tells you the names of commands being used, so you would be able to come up with at least the following code:
(defun my-switch-to-square ()
"Change (..) to [..]."
(interactive)
(mark-sexp --)
(paredit-open-square --)
(right-char --)
(paredit-splice-sexp --))
-- indicates part of code we have not yet decided. After you read documentation of each function in the code, you learn what arguments to pass, and that there is no need to call mark-sexp. After rewriting docstring and adding a call to left-char, the code you end up with would be:
(defun my-switch-to-square ()
"Change |(..) to |[..]. | is point position."
(interactive)
(paredit-open-square 1)
(right-char 1)
(paredit-splice-sexp)
(left-char 1))
The following code does what you request. You can bind swap-parens to whatever key binding you want.
(defvar swap-paren-pairs '("()" "[]"))
(defun swap-parens-at-points (b e)
(let ((open-char (buffer-substring b (+ b 1)))
(paren-pair-list (append swap-paren-pairs swap-paren-pairs)))
(while paren-pair-list
(if (eq (aref open-char 0) (aref (car paren-pair-list) 0))
(save-excursion
(setq to-replace (cadr paren-pair-list))
(goto-char b)
(delete-char 1)
(insert (aref to-replace 0))
(goto-char (- e 1))
(delete-char 1)
(insert (aref to-replace 1))
(setq paren-pair-list nil))
(setq paren-pair-list (cdr paren-pair-list))))))
(defun swap-parens ()
(interactive)
(cond ((looking-at "\\s(")
(swap-parens-at-points (point) (save-excursion (forward-sexp) (point))))
((and (> (point) 1) (save-excursion (forward-char -1) (looking-at "\\s)")))
(swap-parens-at-points (save-excursion (forward-sexp -1) (point)) (point)))
((message "Not at a paren"))))
I'm not sure what you mean by "define command"? You can do it like this:
|(foo bar)
"|" is point.
;; Keyboard Macro Editor. Press C-c C-c to finish; press C-x k RET to cancel.
;; Original keys: C-u [ C-f <M-up> C-b
Command: last-kbd-macro
Key: none
Macro:
C-u [ ;; paredit-open-square
C-f ;; forward-char
<M-up> ;; paredit-splice-sexp-killing-backward
C-b ;; backward-char
Although to be honest, this type of usage scenario is more common for VIM trickery. I've never actually used this IRL.
bzr branch lp:s-x-emacs-werkstatt
will deliver a library inspired by paredit, but delivering more detailed commands
M-x ar-bracket-parentized-atpt RET
puts brackets around parenteses at point
look inside thing-at-point-utils.el and the other files what else is provided

The mechanism iswtichb used to show completions

all.
I decided to hack iswitchb this morning, and found a confusing thing.
Usually,when we command iswitchb,we got someting in minibuffer like:
iswitch {buffer1,buffer2 ...}
What in braces is the completions, as we typing its number
is shrinking.
And I didn't find how iswitchb achieved this when hacking on
its code (sorry for my dullness ).
This is original iswitchb-read-buffer with doc-string ripped
off:
(defun iswitchb-read-buffer (prompt &optional default require-match
start matches-set)
(let
(
buf-sel
iswitchb-final-text
(icomplete-mode nil) ;; prevent icomplete starting up
)
(iswitchb-define-mode-map)
(setq iswitchb-exit nil)
(setq iswitchb-default
(if (bufferp default)
(buffer-name default)
default))
(setq iswitchb-text (or start ""))
(unless matches-set
(setq iswitchb-rescan t)
(iswitchb-make-buflist iswitchb-default)
(iswitchb-set-matches))
(let
((minibuffer-local-completion-map iswitchb-mode-map)
;; Record the minibuffer depth that we expect to find once
;; the minibuffer is set up and iswitchb-entryfn-p is called.
(iswitchb-minibuf-depth (1+ (minibuffer-depth)))
(iswitchb-require-match require-match))
;; prompt the user for the buffer name
(setq iswitchb-final-text (completing-read
prompt ;the prompt
'(("dummy" . 1)) ;table
nil ;predicate
nil ;require-match [handled elsewhere]
start ;initial-contents
'iswitchb-history)))
(if (and (not (eq iswitchb-exit 'usefirst))
(get-buffer iswitchb-final-text))
;; This happens for example if the buffer was chosen with the mouse.
(setq iswitchb-matches (list iswitchb-final-text)
iswitchb-virtual-buffers nil))
;; If no buffer matched, but a virtual buffer was selected, visit
;; that file now and act as though that buffer had been selected.
(if (and iswitchb-virtual-buffers
(not (iswitchb-existing-buffer-p)))
(let ((virt (car iswitchb-virtual-buffers))
(new-buf))
;; Keep the name of the buffer returned by find-file-noselect, as
;; the buffer 'virt' could be a symlink to a file of a different name.
(setq new-buf (buffer-name (find-file-noselect (cdr virt))))
(setq iswitchb-matches (list new-buf)
iswitchb-virtual-buffers nil)))
;; Handling the require-match must be done in a better way.
(if (and require-match
(not (iswitchb-existing-buffer-p)))
(error "Must specify valid buffer"))
(if (or (eq iswitchb-exit 'takeprompt)
(null iswitchb-matches))
(setq buf-sel iswitchb-final-text)
;; else take head of list
(setq buf-sel (car iswitchb-matches)))
;; Or possibly choose the default buffer
(if (equal iswitchb-final-text "")
(setq buf-sel (car iswitchb-matches)))
buf-sel))
And this is the part of iswitchb-read buffer,which I thought
is responsible for functioning completion mechanism.
(defun iswitchb-read-buffer (prompt &optional default require-match
start matches-set)
(let
(
(iswitchb-minibuf-depth (1+ (minibuffer-depth)))
)
;; prompt the user for the buffer name
(completing-read
prompt ;the prompt
'(("dummy" . 1)) ;table
nil ;predicate
nil ;require-match [handled elsewhere]
start ;initial-contents
'iswitchb-history)))
Eval
(iswitchb-read-buffer "Test: ")
resulting
Test: {buffer1,buffer2,...}
So, I think I'm right.
So,what confused me is how can sexp:
(iswitchb-minibuf-depth (1+ (minibuffer-depth)))
has effect on what echos in minibuffer. Comment this
sexp,or replace iswitchb-minibuffer-depth with another
variable, the completions will disappear.
Any advice?
This variable is used in iswitchb-entryfn-p which is called from iswitchb-minibuffer-setup
(defun iswitchb-minibuffer-setup ()
"Set up minibuffer for `iswitchb-buffer'.
Copied from `icomplete-minibuffer-setup-hook'."
(when (iswitchb-entryfn-p)
(set (make-local-variable 'iswitchb-use-mycompletion) t)
(add-hook 'pre-command-hook 'iswitchb-pre-command nil t)
(add-hook 'post-command-hook 'iswitchb-post-command nil t)
(run-hooks 'iswitchb-minibuffer-setup-hook)))
When iswitchb-minibuf-depth is null then iswitchb-entryfn-p is null and the setup is not done.
The iswitchb-minibuffer-setup is a hook which is added to the iswitchb-mode.
BTW, while this may not directly answer your question, this part of iswitchb's behavior is also provided by icomplete-mode (for the normal completion code).