23

In Terminal Emacs (no mouse), I'm using split windows to work with multiple buffers at the same time. I'm finding moving between the split windows much more painful than how I do it in Vim. Reading the documentation it looks like I'm doing it correctly (C-x o), but that just cycles around the windows in a clockwise direction. If I move to an adjacent window to make a quick edit, I need to hit C-x o a few times before I'm back where I was. Sometimes I accidentally press it too many times in a hurry and have to cycle all the way back through the windows again.

Far from install yet-another-external-package, is there any way I can just either move directly to a window (by, say, a number), or at least cycle around the windows in the opposite direction?

In Vim C-w C-w is like C-x o in Emacs, but there's also C-w ARROW to move in a specified direction... something like that? :)

d11wtq
  • 34,788
  • 19
  • 120
  • 195
  • 2
    I know you said you don't want packages, but Evil uses the C-w bindings you know and love. :) – Chris Barrett May 17 '13 at 13:49
  • Have installed Evil, thanks. I'm enjoying it so far, because it doesn't interfere with Emacs commands as much as I thought it would. – d11wtq May 18 '13 at 16:02
  • 1
    @ChrisBarrett interestingly evil-mode seems to implement `C-w h/j/k/l`, but not the arrow-key variants of those. I guess I can easily map them myself. – d11wtq Jun 10 '13 at 07:49

7 Answers7

34

Add this to your init file:

(windmove-default-keybindings)

Then you can use SHIFT+arrow to move to the next adjacent window in the specified direction.

You can specify a different modifier if you prefer, by passing an argument (defaults to 'shift).

Or just bind whatever you like to these functions:

  • windmove-up
  • windmove-down
  • windmove-left
  • windmove-right

You can also add FrameMove to the mix, to make this work transparently across multiple frames.

For numbered window navigation, there's switch-window.el.

phils
  • 71,335
  • 11
  • 153
  • 198
  • 2
    As OP states explicitly that Emacs is run in terminal, it's worth noting that `Shift+UP` doesn't work in xterm-based emulators, including gnome-terminal & terminator. See [related question](http://stackoverflow.com/questions/10871745/shift-up-arrow-doesnt-highlight-text-emacs-iterm2) for more info. – immerrr May 17 '13 at 13:55
  • Very good point; they'll likely need to specify their own bindings in that case. (Although xterm is one of the terminal emulators which *does* also facilitate extended key sequences, and I don't think the other two you mentioned are actually based on it :) – phils May 17 '13 at 14:41
  • @phils, I should've picked words more accurately, I meant xterm-terminfo rather than xterm-the-emulator itself. – immerrr May 17 '13 at 18:17
  • Bound to keys that work for my brain, this is totally awesome! Thanks! –  Aug 14 '22 at 05:38
4

Add this to your init file (e.g. ~/.emacs):

(windmove-default-keybindings)

Then do SHIFT+arrow to move to the window in that direction.

jameshfisher
  • 34,029
  • 31
  • 121
  • 167
3

You can give a prefix argument to C-x o like this C-u -1 C-x o. This way you can go any number of windows forward or backward. Personally I think it's easier to create a special key for moving back one window. I have this in my .emacs:

(defun other-window-backward ()
  "Goto previous window"
  (interactive)
  (other-window -1))
(global-set-key (kbd "\C-x p") 'other-window-backward)
snowape
  • 1,274
  • 10
  • 23
  • Ah, I didn't realize that `other-window` accepts an argument like that, thanks. Nice and simple to customize with a mapping then :) – d11wtq May 17 '13 at 12:12
1

I use the following to navigate to the next (same as C-x o), previous, first, and last window:

(defun my-previous-window ()
  "Previous window"
  (interactive)
  (other-window -1))
(global-set-key "\C-xp" 'my-previous-window)

(global-set-key "\C-xn" 'other-window)

(defun my-select-first-window ()
  (interactive)
  (select-window (frame-first-window)))

(defun my-select-last-window ()
  (interactive)
  (select-window (previous-window (frame-first-window))))

(global-set-key "\C-x<" 'my-select-first-window)
(global-set-key "\C-x>" 'my-select-last-window)
Lindydancer
  • 25,428
  • 4
  • 49
  • 68
1

Use window-jump, e.g.:

;; C-x <direction> to switch windows
(use-package window-jump
             :bind (("C-x <up>" . window-jump-up)
                    ("C-x <down>" . window-jump-down)
                    ("C-x <left>" . window-jump-left)
                    ("C-x <right>" . window-jump-right)))

For help with use-package, see https://github.com/jwiegley/use-package/blob/master/README.md.

mcandre
  • 22,868
  • 20
  • 88
  • 147
1

For the sake of completion, there is window-numbering and ace-window too

csantosb
  • 306
  • 3
  • 9
  • I added this line to my .emacs but still can not move as expected. Something wrong? my version is 24.5 – 4t8dds Jan 20 '16 at 03:25
-1

I wrote an elisp module a while back to expand on windmove to make it a bit more useful: http://samograd.ca/stumpwm.el. You can bind stumpwm-move-window-[left/right/up/down] to whatever keys you want and the windows will move in the correct direction, even into another another frame (tested with 2 frames). There's also an stumpwm-interactive-resize-window for handy interactive window resizing using C-n/C-p/C-f/C-b with Return to end resizing.

Burton Samograd
  • 3,652
  • 19
  • 21