Category Archives: movement

Whizz between windows with windmove

First up, a reminder: in Emacs’ terminology the thing we usually call a window in other apps (the main display of an app with the menus etc at the top) is called a frame, and the individual panes within that (usually displaying different buffers side by side) are called windows.

Once you have been using Emacs for a while, you might find it more efficient to have a single large frame with several windows open inside displaying different buffers. It is then really easy to move between them using the built-in library windmove.

Activate windmove by adding the following to your emacs config file:

(use-package windmove
  ;; :defer 4
  :ensure t
  :config
  ;; use command key on Mac
  (windmove-default-keybindings 'super)
  ;; wrap around at edges
  (setq windmove-wrap-around t))

Now you can hold down the super key (Command on a Mac) and press arrow keys to move to windows in any direction. Note that the default key is shift plus arrow, but this conflicts rather painfully with org-mode, so I prefer super.

Use visible bookmarks to quickly jump around a file

The visible bookmarks package lets you bookmark positions in the current buffer and then jump between them. This is really useful if you are working on large files and have a few common locations you want to keep returning to. It is more efficient than jumping around the mark ring or moving through edit points.

Here is my code to install and configure visible bookmarks with the recommended key bindings:

(use-package bm
  :bind (("<C-f2>" . bm-toggle)
         ("<f2>" . bm-next)
         ("<S-f2>" . bm-previous)))

Here is a trivial illustration where I use <C-f2> to place three bookmarks (causing those lines to be highlighted) and then <f2> and <S-f2> to move up and down through them, before using <C-f2> again to toggle the bookmarks off.

visible-bookmarks.gif

The package will also let you cycle through bookmarks in multiple buffers, and move in order of “last in first out”. See the documentation for more information.

Move to the beginning of a line the smart way

I’ve moved away from using my recommended setup, prelude in favour of completely writing my own customisation file. I would still recommend prelude for beginner and intermediate Emacs users, but I wanted full control for myself. I have missed a few things from prelude, but happily the author provides some of his useful functions in a stand alone package called crux.

One of my favourite tools from crux is crux-move-beginning-of-line, which I use in place of the normal C-a to move to the start of the line. The crux version has the extra benefit that the first time you use it, it moves the point to the first non-whitespace character on the line. Repeating it moves to the start of the line, and more repeats toggle back and forth.

Here’s how I install and configure crux to do this.

(use-package crux
  :bind (("C-a" . crux-move-beginning-of-line)))

Crux has lots of other useful tools, so go and check them out.

Cycle through windows across all frames

There are lots of ways to switch between windows in Emacs. I recently discovered that s-' (i.e. super and ' where super is the command key on a Mac) runs the command next-multiframe-window which cycles you through all the current windows regardless of which frame they are in. This is a nice quick way to switch to another window.

Aside: in Emacs terminology a frame is what most programmes call a window – the floating box containing the programme. In Emacs a frame can be split into several windows such as when you have several buffers open at the same time.

Super-efficient movement using avy

One of the revelations I came to after a while of using emacs is that you can use searching (or swiping) to efficiently move to another place in the visible buffer. In other words, you can see the place that you want the cursor to be so you do a search for a word close to that position to move the cursor there – not because you want to find that word.

The package avy gives an even more efficient way to do this. There are a few options, but with the configuration below, I look at the place I want the cursor to be, hit M-s and type the first character of a word close to that position, and then the short string that appears in order to select the word that I want and the cursor jumps there. Once you get used to it, it almost feels like you can move the cursor just by looking where you want it to go!

In the animation below I want to move the cursor to the start of the word “formed” near the bottom of the window, so I hit M-s and then f. avy then overlays letter combinations on all words starting f and I type “la” to move to the word I want.

avy.gif

Here is my configuration code for avy

(use-package avy
  :ensure t
  :bind (("M-s" . avy-goto-word-1)))

Move through edit points

We’ve looked before at how emacs leaves a trail of breadcrumbs (the mark ring) through which you can navigate to hop around to places you’ve been in the buffer.

A nice alternative is to move round through points at which you made edits in a buffer. You can do this by installing the package goto-chg. Set it up by adding the following to your emacs config file:

(require 'goto-chg)
(global-set-key (kbd "C-c b ,") 'goto-last-change)
(global-set-key (kbd "C-c b .") 'goto-last-change-reverse)

Now you can use C-c b , and C-c b . to go back and forth through the edit points in your buffer. It takes you through your undo history without actually undoing anything.

For bonus points you can use C-u 0 C-c b , to give a description of the change you made at a particular stop on your tour.

Don’t search, swipe

We looked before at basic searches using isearch. However, for some time now I have been using a very nice alternative called swiper. The project page has some good information and a link to a video, so I’ll just summarise what I like about it here.

Swiper acts like isearch, in that you type a string and you get an updating list of matches, but the matching lines are shown in a list in an expanded minibuffer, which you can move through with arrows or C-n and C-p.

One of the best things is that swiper supports regular expressions in a simple way. The main thing you need to know is that spaces are interpreted as a wildcard .* so the query "don swi" would match the title of this post, for example.

The best way to understand it is to try it out yourself. Install swiper and then run it with M-x swiper. I like it so much I have bound it to C-s to replace isearch altogether:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; swiper                                                                 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(global-set-key (kbd "C-s") 'swiper)
(setq ivy-display-style 'fancy)

The second line in the above code sets the colours of the swiper results display to be a bit more, well, fancy! Apparently this option only works well for emacs versions 24.5 and higher, so get updated.

The other tweak I have made is to get swiper to recenter the display when it exits – I found it a little unpredictable where the point was going to be after I finished swiper. This is done with a little bit of advice:

;;advise swiper to recenter on exit
(defun bjm-swiper-recenter (&rest args)
  "recenter display after swiper"
  (recenter)
  )
(advice-add 'swiper :after #'bjm-swiper-recenter)

Scrolling and moving by line

There are (of course) lots of ways to scroll the window and move the cursor in emacs. To move the cursor up or down by a line you can use the arrow keys, or C-n and C-p.

To scroll the window, you can use C-v and M-v to scroll down or up respectively by nearly one full screen. This is equivalent to page up/down.

Normally when you scroll the window, the cursor stays with its current line until it hits the edge of the window and then it moves to the next line. In other words the cursor follows the text as the text scrolls. I prefer the cursor to stay at the same position in the window when I scroll it, so the text moves under the cursor. I also like to add the following simple commands which scroll the window up or down by one line. Putting these two tweaks together, the window moves by one line while the cursor stays still.

;;keep cursor at same position when scrolling
(setq scroll-preserve-screen-position 1)
;;scroll window up/down by one line
(global-set-key (kbd "M-n") (kbd "C-u 1 C-v"))
(global-set-key (kbd "M-p") (kbd "C-u 1 M-v"))

Note how these commands work by passing a prefix argument to the normal scroll commands – this is described in the help for those functions which you can see by using e.g. C-h k C-v.

I used the keybindings M-n and M=p by analogy with C-n and C-p.

Here is a little animation to illustrate how this works.

scrolling-moving-line.gif