Month: June 2015

Run shell command on buffer or region

Emacs has tonnes of features built in, and is infinitely expandable with emacs lisp, but sometimes there is already a shell command that can do the job you want more easily. You can use M-! (wich runs shell-command) to run a shell command with the contents of the current buffer passed to stdin (standard input for the command), or M-| (which runs shell-command-on-region) to do the same for the currently selected text in the buffer.

The output of the shell command is then shown as a new buffer in emacs.

As a trivial example, suppose a buffer contained the following, and we wanted to sort the lines (N.B. this is easy to do in emacs)

bbb
aaa
ddd
ccc

Hitting M-! prompts for a shell command, and we then enter sort to call the standard unix/linux sort command. We now get a buffer called *Shell Command Output* containing

aaa
bbb
ccc
ddd

Since I am not the world’s greatest lisp programmer, I use this quite often for things that could probably be accomplished in emacs. For example, I wanted to pull out all of the xmlUrl addresses from a large file that looked like this

<opml version="1.0">
    <head>
        <title>Ben subscriptions in feedly Cloud</title>
    </head>
    <body>
        <outline text="daily" title="daily">
            <outline type="rss" text="Information Is Beautiful" title="Information Is Beautiful" xmlUrl="http://feeds.feedburner.com/InformationIsBeautiful" htmlUrl="http://www.informationisbeautiful.net"/>
            <outline type="rss" text="Planet Emacsen" title="Planet Emacsen" xmlUrl="http://planet.emacsen.org/atom.xml" htmlUrl="http://planet.emacsen.org/"/>
            <outline type="rss" text="What If?" title="What If?" xmlUrl="http://what-if.xkcd.com/feed.atom"/>
        </outline>
    </body>
</opml>

I couldn’t come up with a way to do this internally in emacs, but it is easy for me in perl, so I just ran M-! and then entered

perl -ne '/xmlUrl=(".+?")/; print "$1\n"' | uniq

to get a buffer containing just

"http://feeds.feedburner.com/InformationIsBeautiful"
"http://planet.emacsen.org/atom.xml"
"http://what-if.xkcd.com/feed.atom"

I’d be curious if anyone has a nice way to do this in emacs alone!

Advertisement

Prettier text replacement with anzu

We recently introduced basic text replacement, but it is easy to make things a bit snazzier. You can preview the replacement by installing the anzu package, and then adding the following to your emacs config file:

(require 'anzu)
(global-anzu-mode)
(global-set-key (kbd "M-%") 'anzu-query-replace)
(global-set-key (kbd "C-M-%") 'anzu-query-replace-regexp)

This is illustrated in the example below from my post on renaming multiple files in dired – note how when I replace “foo” with “bar” you see the replacement text previewed next to the original text

dired-rename.gif

If you use my recommended setup, prelude, this behaviour is the default,so you shouldn’t need to do anything.

Instant scratch buffer for current mode

When emacs launches it will typically show the *scratch* buffer, which is in lisp mode by default, and is useful for making rough notes and evaluating bits of lisp code.

You can chose the default mode of the scratch buffer by setting the variable initial-major-mode as described on emacs redux. So if you want it to be in text mode, use

(setq initial-major-mode 'text-mode)

Today I wanted a scratch buffer in org-mode for some rough work with a table. I could have switched to the scratch buffer and used M-x org-mode to switch the major mode of the scratch buffer, but I found a nicer solution. I installed the package scratch and added the following to my emacs config file:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; multiple scratch buffers                                               ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; uses package "scratch"
(autoload 'scratch "scratch" nil t)

With this package, if you use M-x scratch it will launch a scratch buffer for the current mode. So in my org-mode buffer, using this command gave me a scratch buffer called *org* where I could put my temporary org scribblings.

Basic text replacement

You can replace text using M-% (which runs the command query-replace). For example, to replace “foo” with “bar”, use M-x RET foo RET bar and then emacs will step through all the occurrences of “foo” asking if you want to replace them. You can hit y, n, to say yes or no to each, or ! to say yes to all.

Replacement runs from the current cursor position, so to run it everywhere in the buffer, you can jump to the start of the buffer first. Also, remember that when you have finished with your search and/or replace, you can jump back to where you started with C-u SPACE.

Note also, that if you highlight a region, then query-replace will only run on the selected region.

Later on we’ll come back to this topic to look at more advanced text replacement using regular expressions and other neat additions.

Regions, marks, and visible-mark

In my post on sorting lines, a commenter pointed out that a command would work on a region even when it was not active (highlighted). This prompted me to pay a bit more attention to how regions behave in emacs. I found this page of Xah Lee’s useful.

The key concept is that a region almost always exists in your buffer, even if it is not highlighted. The region is defined as the space between the mark and the point. The mark is the last place you placed a mark (e.g. when you use C-SPACE to start marking text), and the point is the location of the cursor. The region is highlighted if it is active, but it always exists even if it is not active and highlighted, even though you can’t see it. Some commands can still act on the region even if it is not active.

It can be confusing at first, as you can’t see the region if it is not active, and can’t generally see the mark. One way to see the current inactive region is to use C-x C-x which runs the command exchange-point-and-mark. From the emacs manual, this does the following:

Set the mark at point, and activate it; then move point where the mark used to be.

So the cursor moves to where the mark was and the region is highlighted for you to see. Using C-x C-x again puts you back where you were.

An alternative is to install the package visible-mark which highlights the position of the current mark, and an optional number of previous marks. I’m not sure I would want to use it all the time, but it is great for getting a sense of where the mark is, and also when the mark changes location, such as when you do a search, or paste text.

You can customise this by adding something like the following (taken from the package documentation) to your emacs config file:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; visible mark - show where mark is                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defface visible-mark-active ;; put this before (require 'visible-mark)
  '((((type tty) (class mono)))
    (t (:background "magenta"))) "")
(require 'visible-mark)
(global-visible-mark-mode 1) ;; or add (visible-mark-mode) to specific hooks
(setq visible-mark-max 2)
(setq visible-mark-faces `(visible-mark-face1 visible-mark-face2))

This shows the two most recent marks with different colour highlights (pink for the most recent and gold for the next most recent). Quite instructive!

Finally, remember that you can use C-u C-SPACE to jump around the previous marks in the buffer, which is great for quickly getting back somewhere useful.

Sort lines in a region

Select a region of text and then use M-x sort-lines to sort the lines into alphabetical order (really ascii-betical order). To reverse the sort, we give the command a prefix argument by using C-u M-x sort-lines. The keybinding C-u provides a prefix argument to the command that follows. In the case of sort-lines, the documentation (C-h f sort-lines) tells us that giving an argument will reverse the sort, hence using C-u.

To sort numerically, use M-x sort-numeric-fields. This sorts the lines into ascending numerical order. For simple tabular data, this command can sort by a particular field, if each line contains the same number of fields separated by whitespace. To do this we need to provide a numeric argument, which we do with e.g. C-u 3 M-x sort-numeric-fields to sort by the 3rd field on each line.

To reverse the numeric sort, simply perform the normal sort, and then select the region again and reverse the order of the lines with M-x reverse-region.

As a final tip, after you run the sort command, you will find that the region you originally selected is no longer highlighted, but you need it to be to run reverse-region. Don’t touch the mouse, just hit C-x C-x (which runs the command exchange-point-and-mark) which exchanges the point (the cursor) and the mark (the beginning of the region you previously selected) and activates (highlights) the region between them. The net effect is that the region you previously selected is now selected again.

Update

As pointed out below by commenter Noam Postavsky, you do not need to use C-x C-x to reactivate the region before using reverse-region. This is because the region still exists even though it is not highlighted, so the reverse-region command works just fine. I’ve written a short post about emacs regions to clarify this behaviour for myself.

Advanced undo/redo with undo-tree

In emacs, by default C-/ runs the command undo, which does what you would expect and undoes your changes to the current buffer. However, there is a really great upgrade to this called undo-tree which records and visualises your undo history as a branching tree. Install this package, and then add the following to your emacs config file

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; undo tree mode                                                         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;turn on everywhere
(global-undo-tree-mode 1)
;; make ctrl-z undo
(global-set-key (kbd "C-z") 'undo)
;; make ctrl-Z redo
(defalias 'redo 'undo-tree-redo)
(global-set-key (kbd "C-S-z") 'redo)

Now you can use C-z for undo and C-Z for redo. Even better though is using C-x u to run undo-tree-visualize which opens a second buffer displaying a tree view of your undo history in a buffer. You can navigate this with the arrow keys and watch the main buffer change through its previous states, and hit q to exit when you have the buffer the way you wanted it, or C-q to quit without making any changes.

In this simple illustration, I do the following:

  • type some text and then undo some of that typing
  • type some new text
  • use undo-tree to undo the new text and then switch branches to redo the old text

undo-tree.gif

Undo-tree can do other neat things too – see the web page for details.

Visualise and copy differences between files

To compare the contents of two text files, use M-x ediff-files and open the two files you want to compare. Emacs will then open one above the other in your main emacs window (N.B. a window is called a frame in emacs terminology), and also open a smaller window which says Type ? for help.

Press | to put the two files side by side in your main emacs frame, and then stretch your window nice and wide so you can see both files side by side clearly. Now click back on the small emacs window with the help text.

In your main window, you should see blocks of text that differ between the two buffers highlighted. Press n to move to the next difference and p to move to the previous difference. Press a to copy the text from the left-hand file to the right-hand file, or press b to copy text from the right-hand file to the left-hand file.

Press q to exit ediff and then save your files if you have modified them.

To make the experience a little smoother I add the following to my emacs config file:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ediff                                                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'ediff)
;; don't start another frame
;; this is done by default in preluse
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
;; put windows side by side
(setq ediff-split-window-function (quote split-window-horizontally))
;;revert windows on exit - needs winner mode
(winner-mode)
(add-hook 'ediff-after-quit-hook-internal 'winner-undo)

Ediff can do more than this, but this is my main use case – see the manual for more.

Join line to previous line

Emacs has a slightly obscurely named command delete-indentation which is bound to M-^ which can be rather useful. From the help for the function (which you can always look up using C-h k M-^ or C-h f delete-indentation):

Join this line to previous and fix up whitespace at join.

You can use this multiple times to “gather up” lines, joining them together. The easiest way to explain is with an example:

join-lines.gif

N.B. after I have joined the lines in the example above, I used M-q to wrap (fill) the lines tidily.