4

When I reposition the cursor in term-mode or ansi-term with M-left or M-right, it always returns to its original position (see animation below). Is this behavior standard? Is there a way to change it so that it behaves as it would in other buffers?

enter image description here

  • I know that you already accepted an answer for this question, but I am wondering if you had `multi-term` installed? I had the same problem as you, and after uninstalling the `multi-term` package, both `term` and `ansi-term` worked fine for me. – elethan Dec 05 '15 at 03:04
  • @elethan No--I don't believe I'd discovered `multi-term` when I first encountered this issue. But I've removed that package now and commented out phils' answer in my `.emacs` and the problem still remains in both `term` and `ansi-term`. Actually, it happens even when launched as `emacs -q`! Thanks for the suggestion though. –  Dec 08 '15 at 01:22

1 Answers1

3

The problem here is that Emacs is moving the cursor position in the buffer, but no input is being sent to the process running in the terminal, meaning that the apparent state does not match the actual state.

This should be reported as a term-char-mode bug, but you can fix it by binding the Ctrl- and Meta-modified left and right cursor keys in term-raw-map to send the same escape codes that are sent when you type M-b and M-f, which is pretty analogous to the behaviour you'd expect from those bindings.

Tangentially I also have some safety net code to try to prevent any scenario where one of the kill or yank commands is executed in term-char-mode, because that would cause a similarly broken/confusing state; so I've included that code here for good measure.

(eval-after-load "term"
  '(progn
     ;; Fix forward/backward word when (term-in-char-mode).
     (define-key term-raw-map (kbd "<C-left>")
       (lambda () (interactive) (term-send-raw-string "\eb")))
     (define-key term-raw-map (kbd "<M-left>")
       (lambda () (interactive) (term-send-raw-string "\eb")))
     (define-key term-raw-map (kbd "<C-right>")
       (lambda () (interactive) (term-send-raw-string "\ef")))
     (define-key term-raw-map (kbd "<M-right>")
       (lambda () (interactive) (term-send-raw-string "\ef")))
     ;; Disable killing and yanking in char mode (term-raw-map).
     (mapc
      (lambda (func)
        (eval `(define-key term-raw-map [remap ,func]
                 (lambda () (interactive) (ding)))))
      '(backward-kill-paragraph
        backward-kill-sentence backward-kill-sexp backward-kill-word
        bookmark-kill-line kill-backward-chars kill-backward-up-list
        kill-forward-chars kill-line kill-paragraph kill-rectangle
        kill-region kill-sentence kill-sexp kill-visual-line
        kill-whole-line kill-word subword-backward-kill subword-kill
        yank yank-pop yank-rectangle))))
phils
  • 48,657
  • 3
  • 76
  • 115
  • 1
    Thank you, phils. I didn't even think about using M-f and M-b! I appreciate your code--it works just as described. I've [reported](http://www.emacswiki.org/emacs/EmacsBugs) this behavior as a bug (using M-x report-emacs-bug). –  Oct 03 '15 at 01:29