A bit of Terminology

Emacs has its own terminology for what’s commonly known as copying, pasting and cutting - namely “saving”, “yanking” and “killing”.

On top of this, Emacs has its own internal clipboard called the kill-ring . Items that you save or kill end up there and yanking pulls items out of there.

The kill-ring is much more than a typical clipboard, but that’s a subject for an entire post itself.

The Typical Workflow

Normally you’d mark some region and then you’d use M-w to save the region to the kill-ring or C-w to kill the region (which would also add it to the kill-ring). You’d also use C-y to yank items out of the kill-ring. Nothing special here - it’s basically C-c , C-x and C-v from so many apps.

Of course, that’s Emacs we’re talking about and we can certainly do way better than other apps. Enter the hero of today’s episode.

easy-kill

easy-kill is an awesome package that allows you to save up on the steps you’d normally have to take when saving and killing stuff. It’s called easy-kill , but could have just as easily been named easy-save or fast-kill . Setting up the package is very easy:

( use-package easy-kill :ensure t :config ( global-set-key [remap kill-ring-save] #' easy-kill ) ( global-set-key [remap mark-sexp] #' easy-mark ))

Note: The package comes bundled with Prelude.

This basically installs it and rebinds M-w ( kill-ring-save ) to easy-kill and C-M-@ / C-M-SPC ( mark-sexp ) to easy-mark . If you apply M-w on a region, it will behave just as it always did. The real fun begins when you don’t have a region.

M-w saves in this order:

active region (if present)

url at point

email at point

current line

That’s already an improvement over the standard M-w behavior, but we’re just getting started. easy-kill ’s real power requires you to use M-w as a prefix in a more complex interaction. Assume you’re working with the following Lisp code:

( foo b | ar baz )

Note: | denotes the position of the cursor.

At this point pressing M-w will mark and save the entire line, but if you follow up with w it will just save the word (symbol) foo . Pressing w a second time will expand the selection to include the following word as well. If you want to save the entire enclosing list ( (foo bar baz) ) you can do so with M-w l .

The full list of save to kill-ring commands is the following:

M-w w : save word at point

: save word at point M-w s : save sexp at point

: save sexp at point M-w l : save list at point (enclosing sexp)

: save list at point (enclosing sexp) M-w d : save defun at point

: save defun at point M-w D : save current defun’s name

: save current defun’s name M-w f : save filename at point

: save filename at point M-w b : save buffer-file-name (the name of the file a buffer is currently visiting) or default-directory (the current directory of a buffer, in case it’s not visiting a file).

There are also a bunch of keybindings that modify the current selection:

@ : append selection to previous kill and exit. For example, M-w d @ will append the current function to the last kill. Useful for creating compound entries in the kill-ring.

: append selection to previous kill and exit. For example, will append the current function to the last kill. Useful for creating compound entries in the kill-ring. C-w : kill selection and exit.

: kill selection and exit. + , - and 1-9 : expand/shrink selection by 1 or n elements.

, and : expand/shrink selection by 1 or n elements. 0 : shrink the selection to the initial size i.e. before any expansion.

: shrink the selection to the initial size i.e. before any expansion. SPC : cycle through things in easy-kill-alist (word at point, sexp at point, etc)

: cycle through things in (word at point, sexp at point, etc) C-SPC : turn selection into an active region, so you can apply some other operation on the region (e.g. indent-region )

: turn selection into an active region, so you can apply some other operation on the region (e.g. ) C-g : abort.

Those are a lot of keybindings, so it might take you a while to memorize them. You can press ? at any time while using easy-kill to get a nice help screen with all of its keybindings.

Let’s go over the expansion commands in a bit more detail. Pressing M-w w saves the current word, and repeated presses of w will expand the saving to include the following words.

|This is some text.

Here you can press M-w w w w w to select the text This is some text , or you can alternatively do M-w w 3 . All commands that operate some expandable selection operate in this fashion.

+/- does expanding/shrinking according to the thing that was first selected. So for words the expansion is word-wise, for lines - line-wise, for lists or sexps, list-wise. Here’s an example - if you want to select several consecutive lines you can do it by pressing M-w + + + + .

Note: List-wise expanding/shrinking works well in lispy modes (Emacs Lisp, Common Lisp, Scheme, Clojure, etc), and SMIE-based modes (Prolog, SML, Modula2, Shell, Ruby, Octave, CSS, SQL etc), org-mode, nxml-mode and js2-mode. In other types of modes you can get some pretty weird results.

While, I normally use easy-kill for saving/killing buffer contents, some of its other commands are also super useful. Back in the day I wrote a post on saving the current buffer’s file and with easy-kill you can achieve the same thing using M-w b .

easy-mark

easy-mark is similar to easy-kill but marks the region immediately. It can be a handy replacement for mark-sexp allowing +/- to do list-wise expanding/shrinking and marks the whole sexp even when in the middle of one.

Mark my words - that’s a massive improvement over the default behavior!

Epilogue

I’ve been using easy-kill for a few years now and it was a game changer for me. I can never imagine going back to the way I was doing saving and killing before. easy-kill also reduced a lot my usage of expand-region, which I was historically using to quickly expand a selection to what I need and then save/kill it.

For some reason easy-kill never got much attention and I hope that this post is going to change this.

That’s all for today, folks! Until next time!