Search-forward typo aborts macros - emacs

Search-forward seems to not work well inside emacs macros. For example, say I want to use a macro to help replace FOO with BAR in the following string:
aoeuFOOsnutehaFOOsanotehuFOO
I might begin recording a macro, search-forward for FOO, and then hit backspace a few times and type BAR. Then I can replay this macro to replace the rest of the occurrences. Pretty simple.
Suppose I hit the wrong key and search-forward for FOOO. I hit Backspace to remove the extra O, and finish recording the macro. But when I replay it, nothing happens. FOOO is not in the document, so the macro replay is immediately aborted when the search fails.
This gets annoying in longer macros. As it is, whenever I record a macro, I have to make sure I type in the search text for my search-forwards perfectly. If I make even one mistake, I have to cancel recording my macro and start over; otherwise, the macro will just abort when I replay it.
To sum up, if you use search-forward and commit a typo while recording a macro, the macro will not replay properly because it will abort as soon as it replays your typo.
Any workarounds or solutions to this problem?

You don't have to abort the macro: The easiest thing to do is to simply finish recording the macro (typos and all) and then edit it via C-x C-k C-e (kmacro-edit-macro-repeat) to remove the typo(s).
For instance, when you call this command after defining a macro that is supposed to simply search for occurrences of foo in the current buffer but contains a typo in the search (you typed fooo instead of foo before fixing the typo), the buffer for editing it would look like this:
C-s ;; isearch-forward
f ;; self-insert-command
ooo ;; self-insert-command * 3
DEL ;; delete-backward-char
RET ;; newline
To fix the macro, delete one of the os from the third line and remove the fourth line:
C-s ;; isearch-forward
f ;; self-insert-command
oo ;; self-insert-command * 2
RET ;; newline
Note that you don't have to change self-insert-command * 3 to self-insert-command * 2, I just did that to avoid confusion.
When you're done, hit C-c C-c to recompile the macro and close the *Edit macro* buffer.

The documentation of the ding function says (emphasis mine):
(ding &optional ARG)
Beep, or flash the screen.
Also, unless an argument is given, terminate any keyboard macro currently executing.
Digging into the source we can see that all isearch-* functions that call ding do so without passing a non-nil ARG. You could redefine these functions to change the way they call ding (not sure if it would be good idea to remove the calls to ding entirely), but there is an easier way to achieve what you want:
You can make sure ding is always called with a non-nil ARG by advising it as follows:
(defadvice ding (before be-nice activate compile)
(ad-set-arg 0 t))
As documented here, the ad-set-arg macro
sets the value of the actual argument at position to value.
So what the advice does is tell Emacs to set ARG to t before running the body of the original ding function, causing ding to be nice and not terminate keyboard macros anymore.
With the advice in place, you can now transform
aoeuFOOsnutehaFOOsanotehuFOO
into
aoeuBARsnutehaBARsanotehuBAR
with a "faulty" macro that contains a corrected typo:
C-s ;; isearch-forward
F ;; self-insert-command
OOO ;; self-insert-command * 3
DEL ;; delete-backward-char
RET ;; newline
3*DEL ;; delete-backward-char
BAR ;; self-insert-command * 3
EDIT
As #phils mentions in the comments below, allowing macro execution to continue regardless of errors can lead to unwanted consequences, so use this solution with care. If you want to be able to quickly enable or disable the advice so that you can use it selectively (i.e., in situations where you are sure it won't mess things up), define it like this:
(defadvice ding (before be-nice) ; advice not activated by default
(ad-set-arg 0 t))
and add a command for turning it on and off to your .emacs:
(defun toggle-ding-advice ()
(interactive)
(if (ad-is-active 'ding)
(ad-disable-advice 'ding 'before 'be-nice)
(ad-enable-advice 'ding 'before 'be-nice))
(ad-activate 'ding))
(global-set-key (kbd "C-c a") 'toggle-ding-advice)
You can then toggle the advice by simply pressing C-c a.

Related

repeat macro after error stops execution

My objective is to remove duplicated stanzas in xml files. I am sure I have a duplicated stanza if the first line of the stanza is found multiple times in the file.
I have created a macro that finds the first line of my stanzas through interactive search, then Ctrl-S again to go to the next occurrence. If found, I then mark the section I want to delete and delete it. My macro terminates here.
If my Ctrl-s does not find the next occurrence, my macro stops, which is exacly what I want it to do. However, when I Esc 1000 Ctrl-x e to execute my macro multiple times, when the error is found also the 1000 cycle stops. I am happy for the macro to stop, but I want to execute it again after the error. Is this possible? Or is there already a macro somewhere to remove duplicates stanzas or groups of lines from a file?
My macro:
C-s ;; isearch-forward
<Conduit ;; self-insert-command * 8
SPC ;; self-insert-command
6*C-w ;; kill-region
C-s ;; isearch-forward
C-a ;; beginning-of-line
C-SPC ;; set-mark-command
C-s ;; isearch-forward
< ;; self-insert-command
/ ;; nxml-electric-slash
Conduit> ;; self-insert-command * 8
<right> ;; forward-char
C-w ;; kill-region
Thanks
Joe
Hmm. It would be nice if Emacs provided a convenient interactive way to handle error conditions inside keyboard macros, but I suspect juanleon's answer might be your best bet at present.
A workaround in general is to not use C-s, but instead use something like M-: (search-forward "foo" nil t) RET to search for "foo" without triggering an error if it's not there. In this example there would be more to it, though.
For one-off processing, what I tend to do in these kinds of situation is generate a buffer of the results I'm interested in, and then process that with the keyboard macro.
This example is actually a bit tricky, but you could occur all the lines matching the pattern, pipe through sort | uniq --all-repeated=separate, and then eliminate the first line of each group. That leaves you with a the exact number of instances you wish to remove for each duplicate, so your keyboard macro could grab a line from that list, find the last instance of it in the original buffer, delete it, and move to the next line in the list.
If this is a common activity, a custom elisp function would seem like the way to go.
If what you want to achieve is to run a macro repeatedly regardless of errors, this would be a way to do it:
(defun repeat-macro-until-abort ()
(interactive)
(while t
(ignore-errors
(kmacro-call-macro 0))))
It will run your last macro until you hit C-g. Please notice that it won't be stopped even by reaching end-of-buffer.
There is a easy way to remove lines that match a regexp: M-x flush-lines
If you know the regexp for the stanza you want to remove, you can type C-M-% <your-regexp> RET RET and you witll iterate over the occurences chosing what to remove (type ! for removing every of them). C-M-% is the default keybinding for query-replace-regexp.

A quick way to repeatedly enter a variable name in Emacs?

I was just typing in this sort of code for Nth time:
menu.add_item(spamspamspam, "spamspamspam");
And I'm wondering if there's a faster way to do it.
I'd like a behavior similar to yasnippet's mirrors, except
I don't want to create a snippet: the argument order varies from
project to project and from language to language.
The only thing that's constant is the variable name that needs to be
repeated several times on the same line.
I'd like to type in
menu.add_item($,"")
and with the point between the quotes, call the shortcut and start typing,
and finally exit with C-e.
This seems advantageous to me, since there's zero extra cursor movement.
I have an idea of how to do this, but I'm wondering if it's already done,
or if something better/faster can be done.
UPD The yasnippet way after all.
Thanks to thisirs for the answer. This is indeed the yasnippet code I had initially in mind:
(defun yas-one-line ()
(interactive)
(insert "$")
(let ((snippet
(replace-regexp-in-string
"\\$" "$1"
(substring-no-properties
(delete-and-extract-region
(line-beginning-position)
(line-end-position))))))
(yas/expand-snippet snippet)))
But I'm still hoping to see something better/faster.
yasnippet can actually be used to create a snippet on-the-fly:
(defun yas-one-line ()
(interactive)
(let ((snippet (delete-and-extract-region
(line-beginning-position)
(line-end-position))))
(yas-expand-snippet snippet)))
Now just type:
menu.add_item($1,"$1")
and call yas-one-line. The above snippet is expanded by yasnippet!
You could try
(defvar sm-push-id-last nil)
(defun sm-push-id ()
(interactive)
(if (not sm-push-id-last)
(setq sm-push-id-last (point))
(text-clone-create sm-push-id-last sm-push-id-last
t "\\(?:\\sw\\|\\s_\\)*")
(setq sm-push-id-last nil)))
after which you can do M-x sm-push-id RET , SPC M-x sm-push-id RET toto and that will insert toto, toto. Obviously, this would make more sense if you bind sm-push-id to a convenient key-combo. Also this only works to insert a duplicate pair of identifiers. If you need to insert something else, you'll have to adjust the regexp. Using too lax a regexp means that the clones will tend to overgrow their intended use, so they may become annoying (e.g. you type foo") and not only foo but also ") gets mirrored on the previous copy).
Record a macro. Hit F3 (or possibly C-x (, it depends) to begin recording. Type whatever you want and run whatever commands you need, then hit F4 (or C-x )) to finish. Then hit F4 again the next time you want to run the macro. See chapter 17 of the Emacs manual for more information (C-h i opens the info browser, the Emacs manual is right at the top of the list).
So, for example, you could type the beginning of the line:
menu.add_item(spamspamspam
Then, with point at the end of that line, record this macro:
F3 C-SPC C-left M-w C-e , SPC " C-y " ) ; RET F4
This copies the last word on the line and pastes it back in, but inside of the quotes.

Emacs close paren jumps to already existing close-paren when editing clojure code

If having this piece of code in an emacs buffer:
(if (> x 5
true
false))
When I try to edit it in order to fix the parenthesis, something very annoying is happening! When I try to add a closing parenthesis to the if condition, emacs is making the cursor jump to the closing parenthesis after 'false' instead of adding a new parenthesis after 5.
Is this part of some mode, maybe clojure-mode? Do you know how may I fix this? What is this useful for?
It sounds like you're using paredit. Did you install it like recommended on the project page?
As to what it's good for? It's good for editing lists. But you have to buy
into whe whole system, or you'll end up really confused. See the wiki
page.
Do you have this section in your ~/.emacs.el? Just remove it.
;; (require 'paredit) if you didn't install via package.el
(defun turn-on-paredit () (paredit-mode 1))
(add-hook 'clojure-mode-hook 'turn-on-paredit)
Yes, paredit is "different". It will always make sure your parenthesis balance. See http://www.emacswiki.org/emacs/PareditCheatsheet .
For your code, place the cursor beneath the first closing parenthesis and press C-left. Repeat the exercise and it will have moved to where you want it.
Cut&paste (kill & yank in emacs lingo) also allow you to manually screw with the balanced parenthesis, so until you get used to paredit it may be easier to use. Good luck!
how to verify that paredit is the offender
You can type C-h k ) while in your Lisp buffer to see what ) is bound to. If it is bound to paredit-close-round then yes paredit is the offender.
how to disable paredit when you don't know what's triggering it
Try auramo's answer in another thread
or if that doesn't work, try this:
(eval-after-load 'paredit
'(defalias 'paredit-mode 'ignore))
If you are curious about what is triggering paredit-mode in your Emacs, use M-x debug-on-entry RET paredit-mode RET
learning to live with paredit
But still I must encourage you to continue using paredit. Let's keep using paredit and let's see solutions for problems you posed. You asked "Do you know how may I fix this?" I'll just assume you are asking how to fix that if form. Marius Kjeldahl gave you solution which uses paredit-forward-barf-sexp, now in general, if you have some Lisp code where you see that some parens are in wrong places and you want to fix that, you can simply temporarily disable paredit-mode in that buffer (by typing M-x paredit-mode) and then fix your code and then enable paredit-mode again (by typing M-x paredit-mode again). Another thing to consider is that Emacs has undo, so if you arrive at (if (> x 5 true false)) through some action, you can undo that action and start over. Undo is bound to C-z if you use CUA mode.
Still you might find bindings of C-left, C-right to be weird, so you might want to use the following setup:
(eval-after-load 'paredit
'(progn
;; paredit-forward-barf-sexp is usually bound to <C-left>, C-}.
;; here we unbind it from <C-left>
;; so that one can continue to use <C-left> for movement.
(define-key paredit-mode-map (kbd "<C-left>") nil)
;; paredit-forward-slurp-sexp is usually bound to <C-right>, C-).
;; here we unbind it from <C-right>
;; so that one can continue to use <C-right> for movement.
(define-key paredit-mode-map (kbd "<C-right>") nil)
;; paredit-backward-kill-word is bound to M-DEL but not to <C-backspace>.
;; here we bind it to <C-backspace> as well
;; because most people prefer <C-backspace> to M-DEL.
(define-key paredit-mode-map (kbd "<C-backspace>") 'paredit-backward-kill-word)))
You asked "What is this useful for?" by which you may be asking two things:
Why is paredit-close-round useful?
Why does paredit have to bind paredit-close-round to ) when it could have bound it to better keys?
Best way to think of paredit-close-round is to think of it as a counterpart to C-M-u. Move point to | in the following code and try press C-M-u several times to see what happens, and then move point to | again and try press C-M-- C-M-u (i.e. type -u while Control and Alt are on) several times to see what happens.
(when t
(when t
(blah)
(blah))
(when t
(blah | blah)
(blah))
(when t
(blah)
(blah)))
C-M-u is useful for selecting expressions; in order to select an enclosing form or forms, you press C-M-u several times and then C-M-SPC several times. C-M-- C-M-u is useful for evaluating an enclosing form; you press C-M-- C-M-u several times and then C-x C-e to eval the enclosing form.
paredit-close-round basically does what C-M-- C-M-u does.
Why is it an OK thing that paredit binds ) to a command that does something other than simply inserting a close paren? Because you are not supposed to insert a closing parenthesis by yourself. Whenever you insert an open paren, a close paren is also inserted automatically. Whenever you want to change (blah) (blah) to ((blah) (blah)), you simply select the two blah forms and press (.

How do I bind a key to "the function represented by the following key sequence"?

I'm just starting to learn emacs (woohoo!) and I've been mucking around in my .emacs quite happily. Unfortunately, I don't know Lisp yet, so I'm having issues with the basics.
I've already remapped a few keys until I fix my muscle memory:
(global-set-key (kbd "<f9>") 'recompile)
That's fine. But how can I tell a key to 'simulate pressing several keys'? For instance, I don't know, make <f1> do the same as C-u 2 C-x } (widen buffer by two chars).
One way is to look up that C-x } calls shrink-window-horizontally, and do some sort of lambda thing. This is of course the neat and elegant way (how do you do this?). But surely there's a way to define <f1> to send the keystrokes C-u 2 C-x }?
Sure there is, and it's the obvious way:
(global-set-key (kbd "<f1>") (kbd "C-u 2 C-x }"))
For anything long-term, I would recommend the approach shown by seh, as that will naturally be more robust in most situations. It requires a little more work and know-how, of course, but it's all worthwhile :)
angus' approach is like a cut-down version of the keyboard macros feature that gives Emacs its name (and slightly simpler to use than macros for the example in question). You should definitely be aware of macros, however -- they can be exceedingly useful, and for anything more complicated it quickly becomes far easier to record one dynamically than to write out all the individual keys manually.
Here's the summary I wrote myself of the most important bits:
;;;; * Keyboard macros
;; C-x ( or F3 Begin recording.
;; F3 Insert counter (if recording has already commenced).
;; C-u <n> C-x ( or F3 Begin recording with an initial counter value <n>.
;; C-x ) or F4 End recording.
;; C-u <n> C-x ) or F4 End recording, then execute the macro <n>-1 times.
;; C-x e or F4 Execute the last recorded keyboard macro.
;; e or F4 Additional e or F4 presses repeat the macro.
;; C-u <n> C-x e or F4 Execute the last recorded keyboard macro <n> times.
;; C-x C-k r Apply the last macro to each line of the region.
;; C-x C-k e Edit a keyboard macro (RET for most recent).
;; C-x C-k b Set a key-binding.
;;
;; If you find yourself using lots of macros, you can even name them
;; for later use, and save them to your init file.
;; M-x name-last-kbd-macro RET (name) RET
;; M-x insert-kbd-macro RET (name) RET
;;
;; For more documentation:
;; C-h k C-x (
;; M-: (info "(emacs) Keyboard Macros") RET
If we play with the example from the question, you'll see how some of these things tie together...
To begin with, you can define the macro with F3C-u2C-x}F4
You could then bind it temporarily to F1 with C-xC-kbF1 (actually that's not true if F1 is currently a prefix key for an existing keymap, as typing it interactively will simply prompt for the remainder. You can circumvent this in code with (global-set-key (kbd "<f1>") ...), but I would suggest sticking to the reserved bindings).
If you then use describe-key (C-hk) to examine what is bound to that key, Emacs will show you a (lambda) expression which you could copy to your init file if you so wished.
Alternatively, you could name the macro and ask Emacs to insert the code into the current buffer:
M-x name-last-kbd-macro RET (name) RET
M-x insert-kbd-macro RETRET
This code will look different to the lambda expression shown by describe-key, but if you evaluate the inserted macro, you'll see the equivalence. You can likewise show that the (kbd "...") expression also evaluates to the same value, and therefore these are all just alternative ways of doing the same thing.
(You can use the *scratch* buffer to evaluate the code by moving point after the end of the expression, and either typing C-xC-e to show the value in the minibuffer, or C-j to insert the value into the buffer).
Note that the 'inserted' code uses fset to assign the macro to a symbol. You could bind the macro to a key either by executing the (fset) and then assigning that symbol to a key with (global-set-key), or you could ignore the (fset) and simply assign the macro value directly. This, of course, is directly equivalent to angus' answer.
Edit: I've just noticed that there's a kmacro-name-last-macro function bound to C-xC-kn which is nearly identical in form to name-last-kbd-macro, but which generates the lambda expression form seen when using kmacro-bind-to-key (C-xC-kb) and describe-key.
I'll use shrink-window-horizontally as the example function, but you can generalize the idea to any bindings you'd like to define.
If you want to use two as the default amount to shrink the window, rather than one, try the following:
(global-set-key [f9]
(lambda (&optional n)
(interactive "P")
(shrink-window-horizontally (or n 2))))
That binds the F9 key to an interactive function accepting a prefix argument. If you just press F9, you'll pass no argument, which summons the default value of 2, as the parameter n will receive nil as an argument. However, if you press, say, C-u 10 F9, you'll pass ten as the argument for n. This allows you to use your binding more flexibly.
general-simulate-key from general.el works better (in my case a sequence with popups and changing keymaps that I couldn't get to work with macros): https://github.com/noctuid/general.el#simulating-keypresses

Convert Emacs macro into Elisp

Is there a way to convert an emacs macro into elisp, not like what M-x insert-kbd-macro does, the actual activity becoming elisp statements.
Thanks for your help.
Nope, sorry. There is no trivial way to convert an emacs macro into elisp.
Update: There's been some work on Emacs to start down this path. See this thread as a starting point. It's still not possible (June 2010), but there's activity.
The first reason I can think of is dealing with interactive commands and translating keystrokes into proper arguments for functions.
Think of the following sequence:
C-x b .em TAB RET
This begins the command to switch to a buffer, types three characters, uses TAB completion to complete it and RET to accept. The equivalent lisp for the end result (in an emacs session where the TAB completion is unique) is:
(switch-to-buffer ".emacs")
Thinking of completion, there are also interactions with expansion of all types (dabbrev, hippie-expand, etc.).
A starting point can be M-x edit-last-kbd-macro which (in my case) shows this:
;; Keyboard Macro Editor. Press C-c C-c to finish; press C-x k RET to cancel.
;; Original keys: C-x b .em <tab> RET
Command: last-kbd-macro
Key: none
Macro:
C-x b ;; switch-to-buffer
.em ;; self-insert-command * 3
<tab> ;; pabbrev-expand-maybe
RET ;; newline-and-indent
Which at least gives you some of the function names. But you'll see that RET is labeled as 'newline-and-indent which is incorrect because at the time of the macro execution, the minibuffer is active and the binding is in fact 'minibuffer-complete-and-exit. Similarly, the proper binding for TAB is 'minibuffer-complete.
I made a package that allows pretty much exactly this at https://github.com/Silex/elmacro
It has some quirks but it works pretty well... for example, the following macro:
F3 C-e M-b M-u C-a C-n F4
Generates the following elisp:
(defun upcase-last-word ()
"Change me!"
(interactive)
(move-end-of-line 1)
(backward-word 1)
(upcase-word 1)
(move-beginning-of-line 1)
(next-line 1 1))