Skip to main content
4 of 4
deleted 32 characters in body
Tobias
  • 33.7k
  • 1
  • 38
  • 78

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))))
Tobias
  • 33.7k
  • 1
  • 38
  • 78