Since command outputs are easily mutable, I have to be careful when I work with eshell and REPL buffers.

Is there a way to protect them?

  • could you let know if Tobias' answer statisied you? – ReneFroger Jan 2 '16 at 0:16
  • 1
    I was waiting for a more complete answer, but his answer works for eshell. Since no other answer was coming, I chose his answer. – crocket Jan 2 '16 at 0:32
  • Do you mean the lisp-scratch buffer by repl buffer? – Tobias Jan 2 '16 at 0:54
  • @Tobias In my case, it is REPL buffers launched by cider-jack-in and nodejs-repl. But, I want everything except the current input line on all REPL buffers and all shell buffers to be immutable against keyboard inputs. – crocket Jan 2 '16 at 1:53
  • nodejs-repl is derived from comint-mode -- as it should be. Therefore, the added section on comint in the already existing answer should work. It looks like this is not the case for cider because cider is not based on comint but they do their own stuff for process communication. – Tobias Jan 2 '16 at 11:25

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.


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))
      (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))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.