I have written a small function to reverse the items in the marked region using the comma as item separator. The function code is:
(defun reverse-list (beg end)
"Reverses a list in-place, where comma ',' is the list item separator."
(interactive "r")
(if (region-active-p)
(let ((region-list (reverse (split-string (region-as-string) ","))))
(kill-region beg end)
(loop for s in region-list do (progn
(insert (chomp s))
(insert ", ")))
(delete-char -2))
(message "Error: No region selected!")))
where chomp strips leading/trailing whitespace from a string and region-as-string yields the region as a string.
The function is very useful, however it would be great to be able to select the separator on the fly. The behaviour I’m looking for is:
- if called without universal argument use the comma as item separator
- if called with universal argument (
C-u) ask the user to input a (possibly multi-char) separator string
I tried to achieve this, but haven’t been successful in doing so. It would be great if you could provide help!
Thanks in advance,
elemakil
You can use the interactive code
Pto read the "raw" prefix argument. This isnilif there was no prefix argument, and non-nilif there was a prefix argument, so you can test this and decide whether to set the separator to","or to useread-stringto prompt the user to enter it.Also, I’d make the following comments on your code:
Your function only works if called interactively, so that
begandendare really the beginning and end of the region. If called non-interactively, these might not match (or there might not even be a region) and in that case your function will go wrong (because it deletes the buffer betweenbegandendbut inserts the reversal of the region). So you need to call(buffer-substring beg end), not(region-as-string).[Edited, see comments] It’s not a good idea to raise an error in the case where the region is inactive. In Emacs, the region continues to exist even when it’s inactive (that is, no longer highlighted). Or the user might have turned off
transient-mark-modeand so never have an active region at all. In both cases, the user might still want to run your command.At most, you might change the behavior of the command when the region is active (see for example,
comment-dwim).You delete the region by calling
kill-region, which copies the removed text to the kill-ring. Is this really what you want to do? It might surprise the user. It’s better to calldelete-regionunless you actually mean to save the deleted text.You don’t ensure that point is in the right place before you start calling
insert. In interactive use, you’ll get away with it, but for non-interactive use point could be anywhere, so you ought to move it explicitly. And also usesave-excursion, of course.It seems very inelegant to insert an extra
", "and then have to delete it afterwards. Better not to insert it in the first place.Here’s some revised code that fixes all of the above: