summaryrefslogtreecommitdiff
path: root/lisp/comint.el
diff options
context:
space:
mode:
authorMiha Rihtaršič <miha@kamnitnik.top>2021-12-07 21:16:23 +0100
committerLars Ingebrigtsen <larsi@gnus.org>2021-12-07 21:16:23 +0100
commit5364c571988b2bfba05870450a66767f7c134ebd (patch)
tree4d1957e818f81219c0b6ef8a30e206d89976ed77 /lisp/comint.el
parentbeed398eb5e49680b731aeacd553d357759043c1 (diff)
downloademacs-5364c571988b2bfba05870450a66767f7c134ebd.tar.gz
emacs-5364c571988b2bfba05870450a66767f7c134ebd.tar.bz2
emacs-5364c571988b2bfba05870450a66767f7c134ebd.zip
Improve yanking in the middle of comint process output
* lisp/comint.el (comint--unmark-string-as-output): New function to remove unwanted properties from text yanked from comint buffers. (comint-mode): Use it as a 'filter-buffer-substring-function'. (comint-output-filter): Set 'insert-in-front-hooks' text property on process output such that text yanked by the user in the middle of process output is marked as process output (Bug#3735). (comint--mark-as-output): New function. (comint--mark-yanked-as-output): New function.
Diffstat (limited to 'lisp/comint.el')
-rw-r--r--lisp/comint.el54
1 files changed, 45 insertions, 9 deletions
diff --git a/lisp/comint.el b/lisp/comint.el
index 544f0b8b820..5f99f560cf3 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -730,6 +730,8 @@ Entry to this mode runs the hooks on `comint-mode-hook'."
(or (file-remote-p default-directory) ""))
(setq-local comint-accum-marker (make-marker))
(setq-local font-lock-defaults '(nil t))
+ (add-function :filter-return (local 'filter-buffer-substring-function)
+ #'comint--unmark-string-as-output)
(add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
(add-hook 'isearch-mode-hook 'comint-history-isearch-setup nil t)
(add-hook 'completion-at-point-functions 'comint-completion-at-point nil t)
@@ -1815,7 +1817,8 @@ Ignore duplicates if `comint-input-ignoredups' is non-nil."
(ring-insert comint-input-ring cmd)))
(defconst comint--prompt-rear-nonsticky
- '(field inhibit-line-move-field-capture read-only font-lock-face)
+ '( field inhibit-line-move-field-capture read-only font-lock-face
+ insert-in-front-hooks)
"Text properties we set on the prompt and don't want to leak past it.")
(defun comint-send-input (&optional no-newline artificial)
@@ -2152,14 +2155,7 @@ Make backspaces delete the previous character."
(goto-char (process-mark process)) ; In case a filter moved it.
(unless comint-use-prompt-regexp
- (with-silent-modifications
- (add-text-properties comint-last-output-start (point)
- `(rear-nonsticky
- ,comint--prompt-rear-nonsticky
- front-sticky
- (field inhibit-line-move-field-capture)
- field output
- inhibit-line-move-field-capture t))))
+ (comint--mark-as-output comint-last-output-start (point)))
;; Highlight the prompt, where we define `prompt' to mean
;; the most recent output that doesn't end with a newline.
@@ -2191,6 +2187,46 @@ Make backspaces delete the previous character."
,comint--prompt-rear-nonsticky)))
(goto-char saved-point)))))))
+(defun comint--mark-as-output (beg end)
+ (with-silent-modifications
+ (add-text-properties
+ beg end
+ `(rear-nonsticky
+ ,comint--prompt-rear-nonsticky
+ front-sticky
+ (field inhibit-line-move-field-capture)
+ field output
+ inhibit-line-move-field-capture t
+ ;; Text inserted by a user in the middle of process output
+ ;; should be marked as output. This is needed for commands
+ ;; such as `yank' or `just-one-space' which don't use
+ ;; `insert-and-inherit' and thus bypass default text property
+ ;; inheritance.
+ insert-in-front-hooks
+ (,#'comint--mark-as-output ,#'comint--mark-yanked-as-output)))))
+
+(defun comint--mark-yanked-as-output (beg end)
+ ;; `yank' removes the field text property from the text it inserts
+ ;; due to `yank-excluded-properties', so arrange for this text
+ ;; property to be reapplied in the `after-change-functions'.
+ (let (fun)
+ (setq
+ fun
+ (lambda (beg1 end1 _len1)
+ (remove-hook 'after-change-functions fun t)
+ (when (and (= beg beg1)
+ (= end end1))
+ (comint--mark-as-output beg1 end1))))
+ (add-hook 'after-change-functions fun nil t)))
+
+(defun comint--unmark-string-as-output (string)
+ (remove-list-of-text-properties
+ 0 (length string)
+ '( rear-nonsticky front-sticky field
+ inhibit-line-move-field-capture insert-in-front-hooks)
+ string)
+ string)
+
(defun comint-preinput-scroll-to-bottom ()
"Go to the end of buffer in all windows showing it.
Movement occurs if point in the selected window is not after the process mark,