When using ansi-term in line mode emacs lets you edit the buffer arbitrarily, not just after the last prompt. I'm trying to make it read only so I stop fudging with command output. The problem is all the solutions I've come up with also prevent me from entering any commands while in line mode. Here's my attempt:
(defvar-local etc-last-read-only 0)
(defun etc-make-term-output-read-only (&rest args)
(interactive)
(let ((inhibit-modification-hooks t))
(when (= 0 etc-last-read-only)
(setq etc-last-read-only (point-min)))
(let ((end-prompt (ignore-errors (save-excursion
(goto-char (point-max))
(term-previous-prompt 1)
;; (backward-char)
(point)))))
(when (and end-prompt (> end-prompt etc-last-read-only))
(add-text-properties etc-last-read-only end-prompt
'(read-only t rear-sticky t
front-sticky nil))
(setq etc-last-read-only end-prompt)))))
(add-hook 'term-mode-hook
(lambda () (add-hook 'after-change-functions #'etc-make-term-output-read-only nil t))
The idea is that whenever the buffer changes we try to make everything before the most recent prompt read only. I have term-prompt-regexp set to match my PS1 and I can tell that the regexp works correctly because C-c C-p and C-c C-n correctly jump between prompt instances, and I've manually verified with string-match that I get the right result, matching the prompt and one following space. To make the hook more efficient we track how much of the buffer we've made read only so far so we don't have to apply the read only property to the whole buffer every time.
If the backward-char call is included, then I can enter commands as long as I never hit backspace at the beginning of the prompt. If I do then I get a text is read only error from then on and can never enter commands again. If I don't include it, then I never get to enter commands in the first place because it thinks everything is read only. I thought maybe this was an issue with stickiness from the earlier characters, so I tried disabling the stickiness as you can see but it made no difference.
There are some more changes that are needed to make this more robust (I put advice on term-emulate-terminal to inhibit read only and probably need it elsewhere) but first I just want this proof of concept working. What am I doing wrong? How do I get everything up to term-bol marked read only without preventing typing commands there?