Monthly Archives: June 2015

Look up help for keys and functions

Emacs has extensive documentation built in. To look up help for a certain keyboard command, use C-h k and then the keyboard shortcut. For example to look up the help for C-x C-s you would use C-h k C-x C-s and you will see a help buffer open which documents the command and has a link to the section of code where the command is defined.

Similarly if you want to look up the help for a specific function, use C-h f function-name.

Paste history

Any time you copy (M-w) or cut (C-w) anything in emacs, it is added to the kill-ring (emacs’ version of a clipboard). This keeps a history of all the stuff you have previously copied or cut. After you have pasted (yanked in emacs-speak) text with C-y, you can use M-y as the next key to cycle through the history of all previous text that was cut or copied.

M-y runs the command yank-pop, but this can be substituted with fancier ways of using the kill-ring that we may come back to in due course.

Dired: redirect symbolic links

We have previously looked at using dired for managing files and switching dired into writeable mode for renaming multiple files. Here is a related tip to redirect symbolic links in dired.

Suppose you moved some data from one location to another and ended up with a bunch of broken symbolic links, you can easily edit those links to point to the new path. In the example below, I have links pointing to files in /old/path and I want the to point to files in /new/dir instead, so I do the following

  • Use C-x d to enter dired and choose the directory with the files in
  • Use C-x C-q to turn dired into editing mode. You can then edit the file names by hand or
  • Use multiple cursors to edit the links in one go (you could also use e.g. M-% to do a query-replace). This changes the path of the links.
  • Use C-c C-c so apply the changes, or C-c C-k to cancel

This is illustrated in the following animation.

dired-links.gif

This is just great – it feels like magic every time!

Searching multiple files with rgrep

Use M-x rgrep to search for a string in multiple files. You will be prompted for a string, the files to search and the directory to start the search. So, for example, to search for the word “emacs” in all .txt files in my documents directory, I might use M-x rgrep and then answer emacs, *.txt, and ~/docs/.

rgrep will open a new buffer containing the results. The nice thing is that clicking on one of the matches will open that file in emacs and take you right to the matching line.

Note that rgrep is recursive and so will also search all directories below the one specified. For more control, try M-x grep and M-x grep-find.

Multiple cursors

Multiple cursors is a very nice package that lets you create several cursors that all do the same thing as you type (see the example below). You can add it to emacs using the steps described here Once you have installed it, it is useful to set up a keybinding (a keyboard short-cut) for it. You can do this by adding the following to your emacs config file to set C-c m c as the binding for multiple cursors.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; multiple cursors                                                       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(global-set-key (kbd "C-c m c") 'mc/edit-lines)

Once you have done this and restarted emacs, you can use multiple cursors.

To use it, highlight the lines on which you wish to have cursors and use C-c m c. Now you can edit away and press enter when you are done to exit multiple cursors. In the following example, I create cursors on 4 lines and then use them to edit the four lines simultaneously.

emacs-mc1.gif

For a more complex example, I use multiple cursors to reformat a latex style table into plain text. In this clip I do the following

  1. First make the column headings that I want
  2. highlight the lines of the table and start multiple-cursors
  3. edit the line, making use of M-f and M-b to move the cursors forward and back by word, which is useful when the text is not aligned
  4. exit multiple cursors and highlight the table again
  5. use C-u M-x align to align the columns of the table (more tips on aligning text to follow)

emacs-mc2.gif

Of course, there are lots of other ways to accomplish tasks like the above (e.g. using macros or regular expressions in query-replace, or using iedit), many of which we will look at in the future, but I like multiple cursors as a nice visual way of making these sorts of edits.

Note that sometimes when you type a command with multiple cursors running it will ask you if you want to apply this command to all cursors – you can answer yes or no to this and it will remember your choice.

For more examples, see this video.

Basic searching

This is a very basic tip, but is something we’ll come back to and build on.

To search for text in the buffer, use C-s and start typing a string to search forwards and C-r to search backwards. Repeatedly pressing C-s or C-r will move to the next/previous match.

A useful extra tip is that pressing C-s or C-r for a second time before entering your search string will reuse the previous search string.

In emacs, searching is useful finding occurrences of a string in a buffer, but also moving the cursor to a different place in the buffer to continue editing. For example, I might decide I wanted to move the cursor to the end of the word “repeatedly” in the first paragraph to make an edit. I can get their using e.g. C-r edly and hitting C-r a couple of times to move to that point. I then hit RET to end the search and the cursor is where I want it to be.

Remember that you can always use C-u C-SPACE to jump back to where you started you search after you are finished.

There are a lot of more advanced packages for searching and jumping around the buffer, and we’ll come to those in due course…

Count words in region or buffer

Highlight (mark) a region and use M-= to count the number of lines, words and characters in the region. Results are reported in the mini buffer at the bottom of the window.

As pointed out over at irreal, this default command (count-words-region) has the undesirable behaviour that it counts words in a region even when there is no region highlighted (it basically uses the last region you selected). Really, if there is no region highlighted, we would like it to count the words in the whole buffer. To do this, we can set M-= to a slightly different built-in function (count-words) by adding the following to your emacs config file:

;; use count-words instead of count-words-region as it works on buffer
;; if no region is selected
(global-set-key (kbd "M-=") 'count-words)

Use emacs for thunderbird emails

Some people use emacs as their email client with e.g. gnus, wanderlust or mu4e. I am not quite hardcore enough for that, and do my emailing in Thunderbird. I don’t have to give up on emacs completely when sending emails though. Using the external editor extension for Thunderbird, I can quickly compose your email in emacs and then send it in Thunderbird.

To use it, install the extension in Thunderbird, and then in its preferences, set the text editor path to your emacsclient with a -c option. For example, on my Mac, this is

/Applications/Emacs.app/Contents/MacOS/bin-x86_64-10_9/emacsclient -c

See this post about using emacsclient if you are not sure about that.

Now, when composing a mail in Thunderbird, I can click the emacs button that has appeared on the tool bar of the compose window (if it is not there, right click and add it from the list), or just hit Command-E. This launches an emacs window with the email text ready to go. Type in your text and when you are done, hit C-x C-c to save and close the window. Your emacs text should now be in your Thunderbird compose window.

One last point is that I like to use org-mode style structures in my emails, so I add the following to my emacs config file to tell emacs to open .eml files in org-mode.

;;use org mode for eml files (useful for thunderbird plugin)
(add-to-list 'auto-mode-alist '("\\.eml\\'" . org-mode))

Tweaking deft: no spaces in file names

Building on my earlier posts on deft, I have another minor improvement I wanted to make. I really like the way deft creates files from the search string, generating the file name from the string. The only problem is that I don’t want spaces in my file names, which I may well have in my deft search string.

My solution was to add the following advice to the function in deft that creates new files, telling it to replace spaces in the search string with hyphens before creating the file.

;;advise deft-new-file-named to replace spaces in file names with -
(defun bjm-deft-strip-spaces (orig-fun &rest file)
  ;;this probably doesn't need to be done in three steps!
  (setq name (pop file))
  (setq name (replace-regexp-in-string " " "-" name))
  (push name file)
  (apply orig-fun file)
  )

(advice-add 'deft-new-file-named :around #'bjm-deft-strip-spaces)

Maybe someone can help me improve my novice lisp programming here, as I am sure there must be a more direct way to use replace-regexp-in-string here!

I think this is a nice illustration of how the user can relatively easily adjust the behaviour of a function which is quite buried inside a package. You have to be a bit careful when advising functions that you don’t introduce unwanted behaviour if that function is called in a different context, but in this case it should be safe as the function deft-new-file-named is not used elsewhere.

In a comment on my earlier post Kaushal Modi linked to his solution to this, which also removes any upper cases.

Update

The wise commenters below pointed out that my function above is a bit dangerous, since the variable name that I use has global scope so could modify another variable called name elsewhere. This can be solved by using (let ...) to give the variable local scope, as Kaushal Modi points out, but I ended up going with the compact version suggested by Noam Postavsky:

;;advise deft-new-file-named to replace spaces in file names with -
(defun bjm-deft-strip-spaces (args)
  "Replace spaces with - in the string contained in the first element of the list args. Used to advise deft's file naming function."
  (list (replace-regexp-in-string " " "-" (car args)))
  )
(advice-add 'deft-new-file-named :filter-args #'bjm-deft-strip-spaces)

Which uses filter-args in the advice function to specify that my bjm-quit-strip-spaces function is applied to the arguments to deft-new-file-named before they are passed to the latter function.

Tweaking deft: improving navigation

Following up on my earlier posts on deft, I had another small tweak I wanted to make, that also illustrates a useful technique for customised Emacs.

In the deft buffer, each entry takes two lines so I have to hit the up/down arrow key twice to move between them. To simplify this, I tweaked the keybindings in deft-mode to make the arrow keys jump 2 lines instead of 1, but only when deft-mode is active:

;;override normal settings to jump 2 lines as deft has time stamps on second line
(define-key deft-mode-map (kbd "<down>")
  (lambda () (interactive) (next-line 2)))
(define-key deft-mode-map (kbd "<up>")
  (lambda () (interactive) (next-line -2)))

Here, lambda is the name used for anonymous functions in emacs lisp, which are useful in cases like this where I want to make a simple function that I won’t need to use anywhere else. The function is very simple, it just calls the normal line movement command next-line with an argument of 2 or -2 to skip up or down by 2 lines. We then define the arrow keys to call this function, but only in deft-mode-map, which contains the keybindings for deft-mode.

Touch-typists (which, to my shame I am not) generally prefer to use C-n and C-p to move up and down lines, so those could be used instead here.

Update

Commenter Kaushal Modi pointed out that I should not have been seeing the entries in the deft buffer taking up more than one line. It turns out the problem was that I had global-visual-line-mode switched on on my emacs config file which caused the problem.

This means the above changes are redundant, but I’ll leave them up as an example of adding keybindings to a specific mode.