I'd like to replace my selection with the output of a program, an annoyance is - when there is an error, the error replaces my text.
Is there a way to check the exit code and only replace the text if it's zero.
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityI would suggest considering to report a bug. Personally I'm fine with it, since it's easy to fix via C-/ (undo
).
To do what you want right now, my first thought is to advice shell-command-on-region
, something like:
(define-advice shell-command-on-region (:filter-return (exit-status) failture)
(prog1 exit-status
(unless (zerop exit-status)
(let ((msg (buffer-substring (region-beginning) (region-end))))
(undo)
(message "%s" msg)))))
but it's not a clean way, and defining a new command is straightforward:
(defun my-shell-command-on-region (beg end command)
"Alternative to C-u M-| (`shell-command-on-region')."
(interactive
(let ((s (read-shell-command "Shell command on region: ")))
(list (region-beginning)
(region-end)
s)))
(let* ((temp-buffer (generate-new-buffer " *temp*"))
(exit-status (call-shell-region beg end command nil temp-buffer))
(output (with-current-buffer temp-buffer
(buffer-string))))
(if (zerop exit-status)
(progn (delete-region beg end)
(insert output))
(message "%s" output))))
shell-command-on-region
, but a quick glance at the code reveals that it usesexit-status
throughout the function to decide what to do. One idea would be to take the function and modify it (creating a new custom function) to suit your needs -- if exit-status is successful, then do x/y/z, else, do something else. I realize 99.9 percent of Emacs users want things likedefadvice
and other tweaks that don't directly modify the code of existing function, but I am that 0.1 percent who modifies anything and everything.