emacscomint-mode

Emacs shell-mode: Prevent RET sending input from anywhere


As the documentation says that RET will comint-send-input anywhere in a shell mode. The issue is that if you by mistake hit enter on any line and you are not at a prompt it will execute the whole random text until the next prompt. How can I prevent this from happening? It would be nice if hitting Enter anywhere out of the prompt will send you to a new prompt at the bottom.


Solution

  • Something like this?

    (defun my-comint-send-input-maybe ()
      "Only `comint-send-input' when point is after the latest prompt.
    
    Otherwise move to the end of the buffer."
      (interactive)
      (let ((proc (get-buffer-process (current-buffer))))
        (if (and proc (>= (point) (marker-position (process-mark proc))))
            (comint-send-input)
          (goto-char (point-max)))))
    
    (with-eval-after-load "comint"
      (define-key shell-mode-map [remap comint-send-input] 'my-comint-send-input-maybe))
    

    You could replace (goto-char (point-max)) with (comint-copy-old-input) to insert but not send the old input at the new prompt; but that's still liable to cause problems when the inserted input looks like output.

    However, also note the comments and link in C-hf comint-send-input regarding comint-get-old-input -- this can be used to implement custom logic for establishing what the "old input" should be when comint-send-input is invoked with point before the process mark.