diff options
| author | Tino Calancha | 2016-08-16 18:18:44 +0900 |
|---|---|---|
| committer | Tino Calancha | 2016-08-16 18:18:44 +0900 |
| commit | c7119916dc958eeb8e6e2ef50d4a9f262db5be32 (patch) | |
| tree | 78e4ed4d9924bc535b7e4af149218f73e873c348 | |
| parent | 5783984787998f8222d66338efa61f0741466a54 (diff) | |
| download | emacs-c7119916dc958eeb8e6e2ef50d4a9f262db5be32.tar.gz emacs-c7119916dc958eeb8e6e2ef50d4a9f262db5be32.zip | |
Allow not erase output buffer in shell commands
* lisp/simple.el (shell-command-not-erase-buffer): New option to allow
not erasing the output buffer between shell commands. Defaults to nil.
(shell-command-on-region): Use it.
(shell-command--save-pos-or-erase): New defun; store a buffer position
if 'shell-command-not-erase-buffer' is non-nil; otherwise
erase the output buffer of the shell command.
(shell-command, shell-command-on-region): Use it.
(shell-command--set-point-after-cmd): New defun;
if 'shell-command-not-erase-buffer' is non-nil, set point
in the output buffer to the position in 'shell-command-saved-pos'.
(shell-command-sentinel, shell-command-on-region): Use it.
* doc/emacs/misc.texi (shell-command-not-erase-buffer):
Document this feature in the manual.
; * etc/NEWS: Add entry for this new feature.
See discussion on:
http://lists.gnu.org/archive/html/emacs-devel/2016-07/msg00610.html
| -rw-r--r-- | doc/emacs/misc.texi | 8 | ||||
| -rw-r--r-- | etc/NEWS | 10 | ||||
| -rw-r--r-- | lisp/simple.el | 107 |
3 files changed, 107 insertions, 18 deletions
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 94e1f198f2b..acddb7a8f70 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi | |||
| @@ -771,6 +771,14 @@ the output buffer. But if you change the value of the variable | |||
| 771 | @code{shell-command-default-error-buffer} to a string, error output is | 771 | @code{shell-command-default-error-buffer} to a string, error output is |
| 772 | inserted into a buffer of that name. | 772 | inserted into a buffer of that name. |
| 773 | 773 | ||
| 774 | @vindex shell-command-not-erase-buffer | ||
| 775 | By default, the output buffer is erased between shell commands. | ||
| 776 | If you change the value of the variable | ||
| 777 | @code{shell-command-not-erase-buffer} to a non-@code{nil} value, | ||
| 778 | the output buffer is not erased. This variable also controls where to | ||
| 779 | set the point in the output buffer after the command completes; see the | ||
| 780 | documentation of the variable for details. | ||
| 781 | |||
| 774 | @node Interactive Shell | 782 | @node Interactive Shell |
| 775 | @subsection Interactive Subshell | 783 | @subsection Interactive Subshell |
| 776 | 784 | ||
| @@ -56,6 +56,16 @@ affected by this, as SGI stopped supporting IRIX in December 2013. | |||
| 56 | * Changes in Emacs 25.2 | 56 | * Changes in Emacs 25.2 |
| 57 | 57 | ||
| 58 | +++ | 58 | +++ |
| 59 | ** The new user option 'shell-command-not-erase-buffer' controls | ||
| 60 | if the output buffer is erased between shell commands; if non-nil, | ||
| 61 | the output buffer is not erased; this variable also controls where | ||
| 62 | to set the point in the output buffer: beginning of the output, | ||
| 63 | end of the buffer or save the point. | ||
| 64 | When 'shell-command-not-erase-buffer' is nil, the default value, | ||
| 65 | the behaviour of 'shell-command', 'shell-command-on-region' and | ||
| 66 | 'async-shell-command' is as usual. | ||
| 67 | |||
| 68 | +++ | ||
| 59 | ** The new user option 'mouse-select-region-move-to-beginning' | 69 | ** The new user option 'mouse-select-region-move-to-beginning' |
| 60 | controls the position of point when double-clicking mouse-1 on the end | 70 | controls the position of point when double-clicking mouse-1 on the end |
| 61 | of a parenthetical grouping or string-delimiter: the default value nil | 71 | of a parenthetical grouping or string-delimiter: the default value nil |
diff --git a/lisp/simple.el b/lisp/simple.el index e91b6e02a9c..f77c9f88557 100644 --- a/lisp/simple.el +++ b/lisp/simple.el | |||
| @@ -37,6 +37,27 @@ | |||
| 37 | (defvar compilation-current-error) | 37 | (defvar compilation-current-error) |
| 38 | (defvar compilation-context-lines) | 38 | (defvar compilation-context-lines) |
| 39 | 39 | ||
| 40 | (defcustom shell-command-not-erase-buffer nil | ||
| 41 | "If non-nil, output buffer is not erased between shell commands. | ||
| 42 | Also, a non-nil value set the point in the output buffer | ||
| 43 | once the command complete. | ||
| 44 | The value `beg-last-out' set point at the beginning of the output, | ||
| 45 | `end-last-out' set point at the end of the buffer, `save-point' | ||
| 46 | restore the buffer position before the command." | ||
| 47 | :type '(choice | ||
| 48 | (const :tag "Erase buffer" nil) | ||
| 49 | (const :tag "Set point to beginning of last output" beg-last-out) | ||
| 50 | (const :tag "Set point to end of last output" end-last-out) | ||
| 51 | (const :tag "Save point" save-point)) | ||
| 52 | :group 'shell | ||
| 53 | :version "25.2") | ||
| 54 | |||
| 55 | (defvar shell-command-saved-pos nil | ||
| 56 | "Point position in the output buffer after command complete. | ||
| 57 | It is an alist (BUFFER . POS), where BUFFER is the output | ||
| 58 | buffer, and POS is the point position in BUFFER once the command finish. | ||
| 59 | This variable is used when `shell-command-not-erase-buffer' is non-nil.") | ||
| 60 | |||
| 40 | (defcustom idle-update-delay 0.5 | 61 | (defcustom idle-update-delay 0.5 |
| 41 | "Idle time delay before updating various things on the screen. | 62 | "Idle time delay before updating various things on the screen. |
| 42 | Various Emacs features that update auxiliary information when point moves | 63 | Various Emacs features that update auxiliary information when point moves |
| @@ -3210,6 +3231,53 @@ output buffer and running a new command in the default buffer, | |||
| 3210 | :group 'shell | 3231 | :group 'shell |
| 3211 | :version "24.3") | 3232 | :version "24.3") |
| 3212 | 3233 | ||
| 3234 | (defun shell-command--save-pos-or-erase () | ||
| 3235 | "Store a buffer position or erase the buffer. | ||
| 3236 | See `shell-command-not-erase-buffer'." | ||
| 3237 | (let ((sym shell-command-not-erase-buffer) | ||
| 3238 | pos) | ||
| 3239 | (setq buffer-read-only nil) | ||
| 3240 | ;; Setting buffer-read-only to nil doesn't suffice | ||
| 3241 | ;; if some text has a non-nil read-only property, | ||
| 3242 | ;; which comint sometimes adds for prompts. | ||
| 3243 | (setq pos | ||
| 3244 | (cond ((eq sym 'save-point) (point)) | ||
| 3245 | ((eq sym 'beg-last-out) (point-max)) | ||
| 3246 | ((not sym) | ||
| 3247 | (let ((inhibit-read-only t)) | ||
| 3248 | (erase-buffer) nil)))) | ||
| 3249 | (when pos | ||
| 3250 | (goto-char (point-max)) | ||
| 3251 | (push (cons (current-buffer) pos) | ||
| 3252 | shell-command-saved-pos)))) | ||
| 3253 | |||
| 3254 | (defun shell-command--set-point-after-cmd (&optional buffer) | ||
| 3255 | "Set point in BUFFER after command complete. | ||
| 3256 | BUFFER is the output buffer of the command; if nil, then defaults | ||
| 3257 | to the current BUFFER. | ||
| 3258 | Set point to the `cdr' of the element in `shell-command-saved-pos' | ||
| 3259 | whose `car' is BUFFER." | ||
| 3260 | (when shell-command-not-erase-buffer | ||
| 3261 | (let* ((sym shell-command-not-erase-buffer) | ||
| 3262 | (buf (or buffer (current-buffer))) | ||
| 3263 | (pos (alist-get buf shell-command-saved-pos))) | ||
| 3264 | (setq shell-command-saved-pos | ||
| 3265 | (assq-delete-all buf shell-command-saved-pos)) | ||
| 3266 | (when (buffer-live-p buf) | ||
| 3267 | (let ((win (car (get-buffer-window-list buf))) | ||
| 3268 | (pmax (with-current-buffer buf (point-max)))) | ||
| 3269 | (unless (and pos (memq sym '(save-point beg-last-out))) | ||
| 3270 | (setq pos pmax)) | ||
| 3271 | ;; Set point in the window displaying buf, if any; otherwise | ||
| 3272 | ;; display buf temporary in selected frame and set the point. | ||
| 3273 | (if win | ||
| 3274 | (set-window-point win pos) | ||
| 3275 | (save-window-excursion | ||
| 3276 | (let ((win (display-buffer | ||
| 3277 | buf | ||
| 3278 | '(nil (inhibit-switch-frame . t))))) | ||
| 3279 | (set-window-point win pos))))))))) | ||
| 3280 | |||
| 3213 | (defun async-shell-command (command &optional output-buffer error-buffer) | 3281 | (defun async-shell-command (command &optional output-buffer error-buffer) |
| 3214 | "Execute string COMMAND asynchronously in background. | 3282 | "Execute string COMMAND asynchronously in background. |
| 3215 | 3283 | ||
| @@ -3271,7 +3339,8 @@ Noninteractive callers can specify coding systems by binding | |||
| 3271 | The optional second argument OUTPUT-BUFFER, if non-nil, | 3339 | The optional second argument OUTPUT-BUFFER, if non-nil, |
| 3272 | says to put the output in some other buffer. | 3340 | says to put the output in some other buffer. |
| 3273 | If OUTPUT-BUFFER is a buffer or buffer name, erase that buffer | 3341 | If OUTPUT-BUFFER is a buffer or buffer name, erase that buffer |
| 3274 | and insert the output there. | 3342 | and insert the output there; a non-nil value of |
| 3343 | `shell-command-not-erase-buffer' prevent to erase the buffer. | ||
| 3275 | If OUTPUT-BUFFER is not a buffer and not nil, insert the output | 3344 | If OUTPUT-BUFFER is not a buffer and not nil, insert the output |
| 3276 | in current buffer after point leaving mark after it. | 3345 | in current buffer after point leaving mark after it. |
| 3277 | This cannot be done asynchronously. | 3346 | This cannot be done asynchronously. |
| @@ -3408,13 +3477,8 @@ the use of a shell (with its need to quote arguments)." | |||
| 3408 | (setq buffer (get-buffer-create | 3477 | (setq buffer (get-buffer-create |
| 3409 | (or output-buffer "*Async Shell Command*")))))) | 3478 | (or output-buffer "*Async Shell Command*")))))) |
| 3410 | (with-current-buffer buffer | 3479 | (with-current-buffer buffer |
| 3411 | (setq buffer-read-only nil) | ||
| 3412 | ;; Setting buffer-read-only to nil doesn't suffice | ||
| 3413 | ;; if some text has a non-nil read-only property, | ||
| 3414 | ;; which comint sometimes adds for prompts. | ||
| 3415 | (let ((inhibit-read-only t)) | ||
| 3416 | (erase-buffer)) | ||
| 3417 | (display-buffer buffer '(nil (allow-no-window . t))) | 3480 | (display-buffer buffer '(nil (allow-no-window . t))) |
| 3481 | (shell-command--save-pos-or-erase) | ||
| 3418 | (setq default-directory directory) | 3482 | (setq default-directory directory) |
| 3419 | (setq proc (start-process "Shell" buffer shell-file-name | 3483 | (setq proc (start-process "Shell" buffer shell-file-name |
| 3420 | shell-command-switch command)) | 3484 | shell-command-switch command)) |
| @@ -3497,12 +3561,14 @@ and are only used if a pop-up buffer is displayed." | |||
| 3497 | 3561 | ||
| 3498 | 3562 | ||
| 3499 | ;; We have a sentinel to prevent insertion of a termination message | 3563 | ;; We have a sentinel to prevent insertion of a termination message |
| 3500 | ;; in the buffer itself. | 3564 | ;; in the buffer itself, and to set the point in the buffer when |
| 3565 | ;; `shell-command-not-erase-buffer' is non-nil. | ||
| 3501 | (defun shell-command-sentinel (process signal) | 3566 | (defun shell-command-sentinel (process signal) |
| 3502 | (if (memq (process-status process) '(exit signal)) | 3567 | (when (memq (process-status process) '(exit signal)) |
| 3503 | (message "%s: %s." | 3568 | (shell-command--set-point-after-cmd (process-buffer process)) |
| 3504 | (car (cdr (cdr (process-command process)))) | 3569 | (message "%s: %s." |
| 3505 | (substring signal 0 -1)))) | 3570 | (car (cdr (cdr (process-command process)))) |
| 3571 | (substring signal 0 -1)))) | ||
| 3506 | 3572 | ||
| 3507 | (defun shell-command-on-region (start end command | 3573 | (defun shell-command-on-region (start end command |
| 3508 | &optional output-buffer replace | 3574 | &optional output-buffer replace |
| @@ -3536,7 +3602,8 @@ appears at the end of the output. | |||
| 3536 | 3602 | ||
| 3537 | Optional fourth arg OUTPUT-BUFFER specifies where to put the | 3603 | Optional fourth arg OUTPUT-BUFFER specifies where to put the |
| 3538 | command's output. If the value is a buffer or buffer name, | 3604 | command's output. If the value is a buffer or buffer name, |
| 3539 | erase that buffer and insert the output there. | 3605 | erase that buffer and insert the output there; a non-nil value of |
| 3606 | `shell-command-not-erase-buffer' prevent to erase the buffer. | ||
| 3540 | If the value is nil, use the buffer `*Shell Command Output*'. | 3607 | If the value is nil, use the buffer `*Shell Command Output*'. |
| 3541 | Any other non-nil value means to insert the output in the | 3608 | Any other non-nil value means to insert the output in the |
| 3542 | current buffer after START. | 3609 | current buffer after START. |
| @@ -3616,7 +3683,10 @@ interactively, this is t." | |||
| 3616 | (let ((buffer (get-buffer-create | 3683 | (let ((buffer (get-buffer-create |
| 3617 | (or output-buffer "*Shell Command Output*")))) | 3684 | (or output-buffer "*Shell Command Output*")))) |
| 3618 | (unwind-protect | 3685 | (unwind-protect |
| 3619 | (if (eq buffer (current-buffer)) | 3686 | (if (and (eq buffer (current-buffer)) |
| 3687 | (or (not shell-command-not-erase-buffer) | ||
| 3688 | (and (not (eq buffer (get-buffer "*Shell Command Output*"))) | ||
| 3689 | (not (region-active-p))))) | ||
| 3620 | ;; If the input is the same buffer as the output, | 3690 | ;; If the input is the same buffer as the output, |
| 3621 | ;; delete everything but the specified region, | 3691 | ;; delete everything but the specified region, |
| 3622 | ;; then replace that region with the output. | 3692 | ;; then replace that region with the output. |
| @@ -3635,10 +3705,9 @@ interactively, this is t." | |||
| 3635 | ;; output there. | 3705 | ;; output there. |
| 3636 | (let ((directory default-directory)) | 3706 | (let ((directory default-directory)) |
| 3637 | (with-current-buffer buffer | 3707 | (with-current-buffer buffer |
| 3638 | (setq buffer-read-only nil) | ||
| 3639 | (if (not output-buffer) | 3708 | (if (not output-buffer) |
| 3640 | (setq default-directory directory)) | 3709 | (setq default-directory directory)) |
| 3641 | (erase-buffer))) | 3710 | (shell-command--save-pos-or-erase))) |
| 3642 | (setq exit-status | 3711 | (setq exit-status |
| 3643 | (call-process-region start end shell-file-name nil | 3712 | (call-process-region start end shell-file-name nil |
| 3644 | (if error-file | 3713 | (if error-file |
| @@ -3656,8 +3725,10 @@ interactively, this is t." | |||
| 3656 | (format " - Exit [%d]" exit-status))))) | 3725 | (format " - Exit [%d]" exit-status))))) |
| 3657 | (if (with-current-buffer buffer (> (point-max) (point-min))) | 3726 | (if (with-current-buffer buffer (> (point-max) (point-min))) |
| 3658 | ;; There's some output, display it | 3727 | ;; There's some output, display it |
| 3659 | (display-message-or-buffer buffer) | 3728 | (progn |
| 3660 | ;; No output; error? | 3729 | (display-message-or-buffer buffer) |
| 3730 | (shell-command--set-point-after-cmd buffer)) | ||
| 3731 | ;; No output; error? | ||
| 3661 | (let ((output | 3732 | (let ((output |
| 3662 | (if (and error-file | 3733 | (if (and error-file |
| 3663 | (< 0 (nth 7 (file-attributes error-file)))) | 3734 | (< 0 (nth 7 (file-attributes error-file)))) |