Monthly Archives: May 2015

Using server and clients for instantaneous startup

If you use an advanced emacs configuration like my recommended set up prelude, then the startup time for emacs can be several seconds or longer. To avoid this, and to get other benefits I strongly suggest running emacs with a server and clients.

The way this works is that the first time you start emacs, you start a server, and then any other emacs sessions you start just connect to that server. This means they start instantly, and also have the same buffer list as every other emacs window (frame in emacs terminology) that you have open.

To do this we need to make a simple shell script

#! /bin/tcsh -f

# start emacs server - replace with path to your emacs
/Applications/Emacs.app/Contents/MacOS/Emacs --daemon

# start emacs client - replace with path to your emacsclient
# this is usually in the same place as your emacs executable
/Applications/Emacs.app/Contents/MacOS/bin-x86_64-10_9/emacsclient -c $argv

and save it somewhere sensible like ~/scripts/emacs_daemon.csh

Then set up an alias for your emacs command in your ~/.cshrc or similar:

# alias to start emacs in client mode
# starts server if one is not already started
# replace with path to your emacsclient
alias em '/Applications/Emacs.app/Contents/MacOS/bin-x86_64-10_9/emacsclient --alternate-editor "~/scripts/emacs_daemon.csh" -c'

Now you can use the command em to start emacs every time. The first time it will take as long as usual, but after that it will be instant. Running em file1 file2 or similar will open a new emacs window with the named files as you would expect.

One last point to note is that since your emacs windows are now clients of an emacs server that is running in the background, closing the window will not stop the server. If you want to close the entire emacs session and stop the server (e.g. so you can start a fresh emacs session after changing your config file), you can use M-x save-buffers-kill-emacs, which I have bound to C-x c for convenience. To do this, add the following to your emacs config file

;; set shortcut to kill whole emacs session
(global-set-key (kbd "C-x c") 'save-buffers-kill-emacs)

Jump around previous locations in a buffer

When you mark text using C-SPACE as described previously, emacs adds that location to the “mark ring”. This is just a list of places you have marked previously in a buffer. You can jump to the last place in the mark ring using C-u C-SPACE, then use C-u C-SPACE to keep going to previous places.

The neat thing is that emacs automatically adds marks for you when you do different things that jump you to a different place in a buffer (e.g. when you start a search or move to the start or end of the buffer) so C-u C-SPACE will often magically take you back to where you want to go. Try it – you’ll be surprised how often just does what you want.

If you know you will want to come back to a particular spot, just hit C-SPACE twice to mark that point.

Update

Reader ClĂ©ment pointed out that my previous advice to use C-SPACE to continue cycling through the mark ring doesn’t work with default settings. Instead you should use C-u C-SPACE to keep moving back through the mark ring. If you want to be able to just use C-SPACE then you need to customise the variable set-mark-command-repeat-pop to be non-nil. See the emacs manual.

Show file in Finder

This is a tip for Mac users. Use M-x reveal-in-finder to show the current file in a new finder window. If you use this in dired, it will show the file at the cursor in a new finder window.

The reveal-in-finder package may be installed by default with your emacs, but if not, you can install it through the package manager using package-list-packages.

I find this useful for example to quickly attach files to emails in thunderbird. I just reveal the file in finder and then drag it onto my compose window in thunderbird.

Cycle spacing

In the comments on my post on deleting whitespace, Vargonaut pointed out the useful function cycle-spacing. This function, when called multiple times, cycles through

  1. replacing all spaces with a single space
  2. removing all spaces
  3. restoring the original spacing

As Vargonaut recommends, it is convenient to bind this to M-SPACE in place of the just-one-space function. Do this with

;; cycle through amounts of spacing
(global-set-key (kbd "M-SPC") 'cycle-spacing)

Here is an animation of this in action

cycle-spacing.gif

Move to start/end of line or sentence

To move to the start of a line use C-a and to move to the end of a line, use C-e.

To move to the start or end of a sentence, use M-a and M-e respectively. Note that by default, emacs assumes sentences are broken up by a full stop and then two spaces. If you want it to recognise full stop followed by a single space as the end of a sentence then add the following to your emacs config file:

;; sentences end with single space
(setq sentence-end-double-space nil)

Note that this will lead emacs to get a bit confused about abbreviations e.g. that one just there.

Comment Boxes

Sometimes it is useful to break up blocks of your writing visually with comment boxes. I use these to separate out major sections of e.g. a piece of code. To do this, highlight the lines of text that you want to enclose in a comment box, and then use M-x comment-box.

The example below illustrates this, with the first comment box showing the default behaviour. I prefer a wider comment box, as in the second box below.

comment-boxes.gif

To get the boxes in the second example, add the flowing code to your emacs config file (copied from irreal). This defines a function that you can run with M-x bjm-comment-box and sets up a keyboard short-cut C-c b b.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Full width comment box                                                 ;;
;; from http://irreal.org/blog/?p=374                                     ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun bjm-comment-box (b e)
"Draw a box comment around the region but arrange for the region to extend to at least the fill column. Place the point after the comment box."

(interactive "r")

(let ((e (copy-marker e t)))
  (goto-char b)
  (end-of-line)
  (insert-char ?  (- fill-column (current-column)))
  (comment-box b e 1)
  (goto-char e)
  (set-marker e nil)))

(global-set-key (kbd "C-c b b") 'bjm-comment-box)

Cut whole line

You can use C-k to cut (kill in emacs terminology) the text up to the end of the current line from the current cursor position, but this does not include the newline character at the end of the line.

I find it more useful to use C-S-backspace which cuts the whole line including the newline, regardless of where the cursor is.

In either case, the line(s) that you deleted are in your clipboard (kill-ring in emacs terminology) and can be pasted elsewhere (yanked in emacs terminology).

Even more useful, if you add the following code (taken from emacs-fu) to your emacs config file, then pressing C-w (which usually cuts a highlighted region) when no region is highlighted, will cut the current line instead.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; kill line if no region active                                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; http://emacs-fu.blogspot.co.uk/2009/11/copying-lines-without-selecting-them.html
(defadvice kill-region (before slick-cut activate compile)
  "When called interactively with no active region, kill a single line instead."
  (interactive
   (if mark-active (list (region-beginning) (region-end))
     (list (line-beginning-position)
           (line-beginning-position 2)))))

Dired: marking, copying, moving and deleting files

Following from our introduction to dired, here is an example of how to use dired for simple file operations. You can do much more with dired, and we will return to it in the future.

Open dired for a directory containing files you want to work with. Then use C, R, or D when the cursor is on the line of a file to copy, rename/move or delete the file, respectively. This can also be done for multiple files by marking them.

You can mark files in dired by pressing m on the line of a file, and unmark it by pressing u. You can mark several files individually using m or mark all files whose names match a search string by using % m string <RET>. Use U to unmark all files.

The strings used for matching are regular expressions, so are very powerful. For example:

  • % m test <RET> will mark all files with names containing the string “test” (equivalent to *test* on the command line.
  • % m ^test <RET> will mark all files with names starting with the string “test” (equivalent to test* on the command line).
  • % m txt$ <RET> will mark all files with names ending with the string “txt” (equivalent to *txt on the command line).
  • % m ^test.*org$ <RET> will mark all files with names starting with the string “test” and ending with “org” (equivalent to test*org on the command line).
  • % m [kxj] <RET> will mark all files with names containing the letters k, x, or j
  • % m [kxj] <RET> will mark all files with names containing the letters k, x, or j
  • % m [6-9] <RET> will mark all files with names containing the digits 6,7,8,9

Read more about emacs’ regular expressions here.

Once you have marked files, use C, R, or D as before to copy, move or delete them.

You can invert the marking of files using * t, and mark all files (or directories) using * s.

You can hide marked files from the current dired view using k. Note that these are not deleted, use g to see them again.

So, supposing you wanted to delete a bunch of files, but wanted to see them first to visually check you are deleting the right ones, you might do the following

  1. mark the files manually, or using a regular expression
  2. * t invert the selection
  3. k hide the selected files so now you see the ones you originally selected for deletion so you can check you got the right ones
  4. * s to select those visible files
  5. D to delete them

This animation illustrates me going through these steps when I have selected all files ending “txt”.

dired-files.gif