C-u M-! inserts the output of a shell command in the current buffer. That's great, but this output includes the terminating newline that almost all shell commands produce, and I almost never want that newline, or any other whitespace. How about this patch, which makes shell-command strip whitespace by default when called interactively? diff --git a/lisp/simple.el b/lisp/simple.el index 25293ed..918b9bd 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -2973,7 +2973,8 @@ shell (with its need to quote arguments)." (defun shell-command (command &optional output-buffer error-buffer) "Execute string COMMAND in inferior shell; display output, if any. -With prefix argument, insert the COMMAND's output at point. +With prefix argument, insert the COMMAND's output at point as if with +`:strip'. If COMMAND ends in `&', execute it asynchronously. The output appears in the buffer `*Async Shell Command*'. @@ -2997,11 +2998,16 @@ Noninteractive callers can specify coding systems by binding The optional second argument OUTPUT-BUFFER, if non-nil, says to put the output in some other buffer. If OUTPUT-BUFFER is a buffer or buffer name, put the output there. -If OUTPUT-BUFFER is not a buffer and not nil, -insert output in current buffer. (This cannot be done asynchronously.) In either case, the buffer is first erased, and the output is inserted after point (leaving mark after it). +If OUTPUT-BUFFER is not a buffer and not nil, insert output in +current buffer. (This cannot be done asynchronously.) In this +case, the output buffer is not erased. Additionally, if +OUTPUT-BUFFER is `:strip', leading and trailing whitespace is +removed before inserting the shell command output in the current +buffer. + If the command terminates without error, but generates output, and you did not specify \"insert it in the current buffer\", the output can be displayed in the echo area or in its buffer. @@ -3036,7 +3042,7 @@ the use of a shell (with its need to quote arguments)." ((eq major-mode 'dired-mode) (dired-get-filename nil t))))) (and filename (file-relative-name filename)))) - current-prefix-arg + (if current-prefix-arg :strip) shell-command-default-error-buffer)) ;; Look for a handler in case default-directory is a remote file name. (let ((handler @@ -3083,10 +3089,21 @@ the use of a shell (with its need to quote arguments)." ;; This is like exchange-point-and-mark, but doesn't ;; activate the mark. It is cleaner to avoid activation, ;; even though the command loop would deactivate the mark - ;; because we inserted text. + ;; because we inserted text. (goto-char (prog1 (mark t) (set-marker (mark-marker) (point) - (current-buffer))))) + (current-buffer)))) + (when (eq output-buffer :strip) + (save-excursion + (save-restriction + (narrow-to-region (min (point) (mark t)) + (max (point) (mark t))) + (goto-char (point-min)) + (skip-chars-forward " \v\t\n\r") + (delete-region (point-min) (point)) + (goto-char (point-max)) + (skip-chars-backward " \v\t\n\r") + (delete-region (point) (point-max)))))) ;; Output goes in a separate buffer. ;; Preserve the match data in case called from a program. (save-match-data