Hacker News new | past | comments | ask | show | jobs | submit login
Elisp in Replacement String (susam.net)
89 points by todsacerdoti on Jan 12, 2024 | hide | past | favorite | 17 comments



This all works in evil-mode as well, and by default you get the cool live-preview (not sure how to enable that for the vanilla C-M-%)

    :%s/\([0-9]+\))/\,(1- \#1))/
will turn

    1) one
    2) two
    3) three
into

    0) one
    1) two
    2) three


  :%s/\([0-9]\+\))/\=submatch(1)-1.')'    " vim

  perl -pe 's/([0-9]+)\)/$1-1 .")"/e'

  ruby -pe 'sub(/([0-9]+)\)/){"#{$1.to_i-1})"}'


What do you mean by live preview? My non-evil Emacs shows you the matches in the current buffer as you type. I don't think I did anything to enable it, but think it's a fairly recent thing (maybe Emacs 29).


For those wondering about why the \, is used to indicate the start a lisp expression, the backslash is used to escape all replacements and the comma recalls the lisp backquote (`) function (operator) which is like quote (‘), but allows interpolation of evaluated lisp expressions when preceded by a comma[0].

[0] https://www.gnu.org/software/emacs/manual/html_node/elisp/Ba...


I would have said that the comma recalls the way that comma is used inside backquoted expressions.


Thanks, that's a great way to remember it!


Somehow, I was unaware of C-M-% for replacements, though I use M-% all the time for a (naive) string search then replace all instances by pressing the ! key.

This is a very neat trick, and little things like this are why I keep using Emacs. Part of me wishes there were some "universal" version of the M-: keybind for evaluating elisp expressions in any interactive command.


It's not exactly what you want, but "C-x ESC ESC" will bring up the last run command in lisp form and let you edit it before running it again. That's how I used to repeat M-% replacements before they added the nice history to it.


Wow! and you can C-p back to see earlier ones too! Thank you for sharing this ... to me it's similar in impact to q: in vim.


I'm not clear what you mean there, but it seems that C-u C-x C-e, gets a lot of the way there?


just to be sure: you don't look for recursive edit do you?

https://www.gnu.org/software/emacs/manual/html_node/emacs/Re...


Another way to insert counters is the keyboard macro counter (info "(emacs) Keyboard Macro Counter")

kmacro-set-counter (C-x C-k C-i)

Then <F3> to start recording the macro and <F3> again to insert the counter. <F4> to end the macro and <F4> to run it. So <F3><F3><space><F4><F4><F4><F4><...> will insert the integers starting from zero separated by a space.

This can be more useful in certain cases, for example when you need to do "structural editing" like editing a certain field in JSON where it can be easier to locate the edit point using keyboard shortcuts or search.


I didn't know about using elisp in the replacement! Can't wait to need to use it.

You can also do this replacement across an entire project and emacs also uses "smart" caps by default so that case is preserved from match to replacement. I wrote about it here: https://blog.gpkb.org/posts/emacs-regexp-replace/



> It's so good to be an Emacs user.

I wholeheartedly agree. While Elisp may not be the best Lisp, it's still very much good enough to give you superpowers when you need them.


Nice!


cute trick I always forget




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: