How to switch to a different buffer from a terminal buffer

EmacsEmacs23

Emacs Problem Overview


I've been using emacs for few weeks and it's been great so far - coming from vim was easier than I expected (actually - emacs' keyboard shortcuts feel more... natural).

I have added few customizations like moving between buffers using M-Left/Right/Up/Down because C-x o felt a little bit too slow when I had four files opened at once.

So far - so good :-)

One thing bugs me though:

  1. I open some splits using C-x 3 and C-x 2
  2. I open the terminal in one of them using M-x term ENT
  3. How do I switch to different split using keyboard?

Usual shortcuts obviously don't work - terminal is intercepting every emacs command, and I have to click on different buffer to activate it.

Emacs Solutions


Solution 1 - Emacs

In term-mode, any regular C-x whatever keybinding becomes C-c whatever instead.

Solution 2 - Emacs

I'm not sure I understand your question. If you run M-x terminal, most of the key events are sent to the underlying terminal, so the standard C-x o binding and your M-Left are not available in the terminal.

Try using M-x shell to get a shell in one of the windows, and the navigation bindings you set up should still work.

Solution 3 - Emacs

In term-mode, type C-c b RET to switch to some other buffer.

That does what C-x b RET normally does.

Solution 4 - Emacs

This should do the trick to get C-x b working. You may have to add bindings for any custom move commands.

(add-hook 'term-mode-hook
   (lambda ()
     ;; C-x is the prefix command, rather than C-c
     (term-set-escape-char ?\C-x)
     (define-key term-raw-map "\M-y" 'yank-pop)
     (define-key term-raw-map "\M-w" 'kill-ring-save)))

BTW, there is a big difference between shell-mode and term-mode. The former integrates better with emacs (e.g. cd command). The latter is a full terminal emulation and can handle curses programs. They both have their place.

Solution 5 - Emacs

For a more generic answer dealing with emacs' windows, you can look at windmove, which started shipping with Emacs circa Emacs 22, I believe:

;;; Commentary:
;;
;; This package defines a set of routines, windmove-{left,up,right,
;; down}, for selection of windows in a frame geometrically.  For
;; example, `windmove-right' selects the window immediately to the
;; right of the currently-selected one.  This functionality is similar
;; to the window-selection controls of the BRIEF editor of yore.
;;
;; One subtle point is what happens when the window to the right has
;; been split vertically; for example, consider a call to
;; `windmove-right' in this setup:
;;
;;                    -------------
;;                    |      | A  |
;;                    |      |    |
;;                    |      |-----
;;                    | *    |    |    (* is point in the currently
;;                    |      | B  |     selected window)
;;                    |      |    |
;;                    -------------
;;
;; There are (at least) three reasonable things to do:
;; (1) Always move to the window to the right of the top edge of the
;;     selected window; in this case, this policy selects A.
;; (2) Always move to the window to the right of the bottom edge of
;;     the selected window; in this case, this policy selects B.
;; (3) Move to the window to the right of point in the selected
;;     window.  This may select either A or B, depending on the
;;     position of point; in the illustrated example, it would select
;;     B.
;;
;; Similar issues arise for all the movement functions.  Windmove
;; resolves this problem by allowing the user to specify behavior
;; through a prefix argument.  The cases are thus:
;; * if no argument is given to the movement functions, or the
;;   argument given is zero, movement is relative to point;
;; * if a positive argument is given, movement is relative to the top
;;   or left edge of the selected window, depending on whether the
;;   movement is to be horizontal or vertical;
;; * if a negative argument is given, movement is relative to the
;;   bottom or right edge of the selected window, depending on whether
;;   the movement is to be horizontal or vertical.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlukaszkoreckiView Question on Stackoverflow
Solution 1 - EmacsJosh MatthewsView Answer on Stackoverflow
Solution 2 - EmacsTrey JacksonView Answer on Stackoverflow
Solution 3 - Emacsoffby1View Answer on Stackoverflow
Solution 4 - EmacsharpoView Answer on Stackoverflow
Solution 5 - EmacsJoe CasadonteView Answer on Stackoverflow