aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTino Calancha2016-08-16 18:18:44 +0900
committerTino Calancha2016-08-16 18:18:44 +0900
commitc7119916dc958eeb8e6e2ef50d4a9f262db5be32 (patch)
tree78e4ed4d9924bc535b7e4af149218f73e873c348
parent5783984787998f8222d66338efa61f0741466a54 (diff)
downloademacs-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.texi8
-rw-r--r--etc/NEWS10
-rw-r--r--lisp/simple.el107
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
772inserted into a buffer of that name. 772inserted 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.
776If you change the value of the variable
777@code{shell-command-not-erase-buffer} to a non-@code{nil} value,
778the output buffer is not erased. This variable also controls where to
779set the point in the output buffer after the command completes; see the
780documentation of the variable for details.
781
774@node Interactive Shell 782@node Interactive Shell
775@subsection Interactive Subshell 783@subsection Interactive Subshell
776 784
diff --git a/etc/NEWS b/etc/NEWS
index d62dcacbe98..8a13d525450 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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
60if the output buffer is erased between shell commands; if non-nil,
61the output buffer is not erased; this variable also controls where
62to set the point in the output buffer: beginning of the output,
63end of the buffer or save the point.
64When 'shell-command-not-erase-buffer' is nil, the default value,
65the 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'
60controls the position of point when double-clicking mouse-1 on the end 70controls the position of point when double-clicking mouse-1 on the end
61of a parenthetical grouping or string-delimiter: the default value nil 71of 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.
42Also, a non-nil value set the point in the output buffer
43once the command complete.
44The 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'
46restore 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.
57It is an alist (BUFFER . POS), where BUFFER is the output
58buffer, and POS is the point position in BUFFER once the command finish.
59This 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.
42Various Emacs features that update auxiliary information when point moves 63Various 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.
3236See `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.
3256BUFFER is the output buffer of the command; if nil, then defaults
3257to the current BUFFER.
3258Set point to the `cdr' of the element in `shell-command-saved-pos'
3259whose `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
3271The optional second argument OUTPUT-BUFFER, if non-nil, 3339The optional second argument OUTPUT-BUFFER, if non-nil,
3272says to put the output in some other buffer. 3340says to put the output in some other buffer.
3273If OUTPUT-BUFFER is a buffer or buffer name, erase that buffer 3341If OUTPUT-BUFFER is a buffer or buffer name, erase that buffer
3274and insert the output there. 3342and insert the output there; a non-nil value of
3343`shell-command-not-erase-buffer' prevent to erase the buffer.
3275If OUTPUT-BUFFER is not a buffer and not nil, insert the output 3344If OUTPUT-BUFFER is not a buffer and not nil, insert the output
3276in current buffer after point leaving mark after it. 3345in current buffer after point leaving mark after it.
3277This cannot be done asynchronously. 3346This 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
3537Optional fourth arg OUTPUT-BUFFER specifies where to put the 3603Optional fourth arg OUTPUT-BUFFER specifies where to put the
3538command's output. If the value is a buffer or buffer name, 3604command's output. If the value is a buffer or buffer name,
3539erase that buffer and insert the output there. 3605erase that buffer and insert the output there; a non-nil value of
3606`shell-command-not-erase-buffer' prevent to erase the buffer.
3540If the value is nil, use the buffer `*Shell Command Output*'. 3607If the value is nil, use the buffer `*Shell Command Output*'.
3541Any other non-nil value means to insert the output in the 3608Any other non-nil value means to insert the output in the
3542current buffer after START. 3609current 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))))