Modes that communicate with external shells should inherit from comint
mode. eshell
is an exception w.r.t this principle since it emulates almost all commands on elisp-base. First, setting output read-only is described for eshell
afterwards for comint
-based modes.
eshell
The following lisp snippet demonstrates the usage of eshell-output-filter-functions
for setting the output read-only.
It is not very sophisticated and not thoroughly tested.
(defun eshell-interactive-output-readonly ()
"Make output of interactive commands in eshell read-only.
This should be the last entry in eshell-output-filter-functions!"
(let ((end eshell-last-output-end))
(save-excursion
(goto-char end)
(end-of-line 0)
(setq end (point)))
(when (< eshell-last-output-block-begin end)
(put-text-property eshell-last-output-block-begin end 'read-only "Read-only interactive eshell output"))))
(defun eshell-make-interactive-output-readonly ()
(add-hook 'eshell-output-filter-functions 'eshell-interactive-output-readonly 'append))
(add-hook 'eshell-mode-hook 'eshell-make-interactive-output-readonly)
comint
based modes:
It looks like one cannot use comint-output-filter-functions
for setting the command output read-only in comint
-based modes.
The reason is that comint-output-filter
sets unconditionally the rear-nonsticky
text property to t
. Therefore you can insert text into the output despite of the read-only
-property even if already existing output characters cannot be modified.
The only chance to protect the output is an after
-advice for comint-output-filter
. The following code-snippet demonstrates the principle.
(defadvice comint-output-filter (after output-readonly activate)
"Set last process output read-only."
(add-text-properties comint-last-output-start (line-end-position 0)
'(read-only "Process output is read-only."
rear-nonsticky (inhibit-line-move-field-capture))))