2010-04-27

navigating the kill-ring

The kill-ring is emacs' implementation of a copy-paste-clipboard. As expected, it's more powerful than what most other editors offer - but at the same time, it may be a bit hard to use. We already discussed the kill-ring in the Emacs-Fu prehistory.

One of the more powerful features of the emacs kill-ring is that is allows for multiple entries to be saved there. You can then retrieve those older entries by using prefix arguments, that is: C-y will retrieve the last item from the kill-ring, while M- n C-y will retrieve the n th last stretch of 'killed' (cut/copied) text. For example, M-2 C-y will retrieve the second last one.

Unfortunately, for most people it's quite hard to remember what was 'killed' and when and in what order… Those people can of course use the menu (Edit/Paste from kill menu), but that is not always so convenient, requires mousing around etc.

Edit: As Anynomous mentions in the comments, one can of course use M-y to circle through the candidates. This is quite useful, esp. when you have only a few items in the ring. Note, this command only works just after a 'yank' (C-y).

browse-kill-ring

Instead, using the handy browse-kill-ring extension, you can open a buffer which lists the contents of the kill ring, and you can move your cursor to the desired item and insert it.

Installation in simple; first get the browse-kill-ring package from EmacsWiki, or, alternatively, Debian/Ubuntu users can install the emacs-goodies-el-package.

Then, add to your .emacs something like:

(when (require 'browse-kill-ring nil 'noerror)
  (browse-kill-ring-default-keybindings))

Now, the M-y key binding will activate browse-kill-ring iff the normal behavior (see above) is not available, i.e., when the last command was not a 'yank'. You can also edit the kill-ring (press C-h m when in the browse-kill-ring-buffer to see the available bindings).

a little pop-up menu

While browsing EmacsWiki, I found another trick:

(global-set-key "\C-cy" '(lambda ()
   (interactive)
   (popup-menu 'yank-menu)))

After which C-c y will show a little pop-up menu with the your kill-menu entries. It does not seem to fully synchronize with the (possibly edited) entries you get from browse-kill-ring, but it's a pretty neat way to navigate through your kill-ring-buffers – if you don't have too many of them (if so, you could customize the kill-ring-max variable).

2010-04-18

creating custom modes the easy way with generic-mode

Syntax highlighting is useful when editing configuration files, programs and so on, as it helps to prevent errors and makes it easier to quickly scan documents.

Emacs supports syntax highlighting (font locking in emacs lingo) for many different file types. For many common cases (e.g. editing for many programming languages, org-mode), emacs' support goes much further than merely colorizing keywords, and offers all kinds of 'magic' (auto-completion, 'electricity', special key bindings, …). For some other file types, at least keywords are given some different color.

Still, there are files that are not recognized by emacs as having some special format; these are displayed as plain text. This may be the case for less-common configuration files, or your own specific formats.

Defining a full 'mode' for such file types can be a lot of work. Fortunately, emacs offers a easier way: generic-mode. generic-mode defines a whole lot of mode of modes for common formats, but also defines the define-generic-mode macro to create your own modes.

Suppose we have a little language called foo; a typical foo-file might look something like:

!! this is a comment
account=foo; !! another comment
user=jimmy;
password=$3cre7;

Using define-generic-mode, we can easily define a mode for this:

(require 'generic-x) ;; we need this

(define-generic-mode 
  'foo-mode                         ;; name of the mode to create
  '("!!")                           ;; comments start with '!!'
  '("account" "user" 
    "password")                     ;; some keywords
  '(("=" . 'font-lock-operator)     ;; '=' is an operator
    (";" . 'font-lock-builtin))     ;; ';' is a a built-in 
  '("\\.foo$")                      ;; files for which to activate this mode 
   nil                              ;; other functions to call
  "A mode for foo files"            ;; doc string for this mode
)

Now, this will look something like this (if necessary, see the colorized version):

!! this is a comment
account = foo; !! another comment
user = jimmy;
password = $3cre7;

2010-04-04

the zenburn color theme

A popular way to customize emacs is changing its color scheme, as already discussed color theming. Until recently, I was using an evolved version of the color theme presented there, 'djcb-dark'. It works for me but, admittedly, it's a bit ugly.

But recently, in a post to the Wanderlust mailing list, someone mentioned a color theme called Zenburn. Zenburn started its life as a color scheme for vim, around 2002. The explicit goal was to have a pleasant theme that is light on the eyes, and allows you to stay 'in the zone' for long stretches of time. People liked it, and version for many other programs were made, including emacs.

I've been using Zenburn for the last few weeks, and I really like it. I used to think that 'low-contrast' would mean that things are not really clear; but the opposite seems true. Anyway, the screen shot says more than a thousand words I suppose…

Zenburn-for-emacs (written by Daniel Brockman) can be found at the link above. I've sent my updates to him of course, but as it may take a while for the 'official' version to be updated, I've put my version on Emacswiki: ZenburnColorTheme. The changes are the support for Wanderlust, hi-line (for highlighting the current line) , magit and elscreen; also, I made selected (eh, transiently marked regions) not loose their foreground color.

Note, the theme is not yet part of the color-theme package, but does require it.

2010-03-20

showing the buffer position in the mode-line

I do quite a bit of scrolling in emacs, but I hardly ever use the scroll bar for that. The main reason for still having the scroll bar is that it gives me some indication where I am in the buffer. Of course, there is some information in the mode-line, and you can get some more with size-indication-mode, but it's not as immediately obvious as the scroll bar.
But recently, I discovered Lennart Borgman's sml-modeline, which combines all of the scroll bar information into a nice visual indication on the modeline, and I have been happily using it, and got rid of my scroll bar.
Put you sml-modeline in your load-path, and the following fragment in your .emacs should do the trick:
(if (require 'sml-modeline nil 'noerror)    ;; use sml-modeline if available
  (progn 
    (sml-modeline-mode 1)                   ;; show buffer pos in the mode line
    (scroll-bar-mode -1))                   ;; turn off the scrollbar
  (scroll-bar-mode 1)                       ;; otherwise, show a scrollbar...
  (set-scroll-bar-mode 'right))             ;; ... on the right

Note, there is a older version available in Emacswiki which has some problems (such as conflicting with the Standard ML editing mode for emacs); thus, for now it's better to us the Launchpad version; the instructions above apply to that version.

2010-03-08

cleaning up buffers automatically

Recently, I discussed some ways to deal with large numbers of buffers. Maybe we can also take a step back and ask why we have so many buffers in the first place - do we really need all of them?

Well, the obvious answer is: probably not. After a few days of (emacs-uptime) there are all kinds of temporary output buffers, man pages and unchanged buffers you haven't touched in a long time. Let's get rid of those!

midnight

For this very purpose, emacs provides midnight-mode (as has done so for more than a decade). At midnight, it looks at all the buffers, and determines which of the buffers are no longer in use, and closes ('kills') them. Regardless of its name, this cleanup does not necessarily have to take place at midnight, but could be invoked at any time.

Setup is easy, just put the following in your .emacs:

(require 'midnight)

Clearly, the package was designed for emacs instances that are running for long times – for example, by default it clears buffers after having been inactive for 3 days. I'm not sure if that use case is very common today. Anyway, you can change it by setting clean-buffer-list-delay-general (which takes the number of days before a buffer becomes eligible for killing).

You can ask midnight-mode to clean-up unused buffers right now with M-x clean-buffer-list. Also, you can use some variables to control which buffers are to be killed, and which ones specifically not:

clean-buffer-list-kill-buffer-names
clean-buffer-list-kill-never-buffer-names
clean-buffer-list-kill-regexps
clean-buffer-list-kill-never-regexps

To run clean-buffer-list every n minutes or so, you could use run-at-time, left as an exercise to the reader.

tempbuf

Another way to accomplish roughly the same is TempbufMode.

It seems a bit better equipped for shorter cleanup interval, and you have some killed. However, that requires you to add it to the modes where you'd like to more influence on the algorithm it uses to decide whether a buffer may be use it, something like:

;; download tempbuf: http://www.emacswiki.org/emacs/tempbuf.el
(when (require 'tempbuf nil 'noerror) 
  (add-hook 'custom-mode-hook 'turn-on-tempbuf-mode)
  (add-hook 'w3-mode-hook 'turn-on-tempbuf-mode)
  (add-hook 'Man-mode-hook 'turn-on-tempbuf-mode)
  (add-hook 'view-mode-hook 'turn-on-tempbuf-mode))

Side-note: I'm using the (when (require 'tempbuf nil 'noerror) ... ) pattern here to make sure that my .emacs also works when tempbuf is not available.

Added: for cleaning-up your buffer list non-automatically, you can simply use M-x kill-some-buffers. (Thanks Susan!). Or you can use C-x C-b.

2010-02-23

wanderlust iii

Wanderlust

I have been using the Wanderlust E-mail client for almost a year now, and I am very happy with it. In previous postings I already discussed setup and some tips and tricks; and I also had somewhat related posts on bbdb (the address book) and warning you about new mail. But I think it's time for an update.

maintenance

One question that I have received quite a few times was about the maintenance of Wanderlust; it's may be a nice e-mail client, but little seems to have happened in the last few years. It's reasonable concern.

Fortunately, it seems the situation has improved significantly. There's more traffic on the mailing lists, both from old and new users. Various improvements are circulating; the place to get the latest stuff is in David Abrahams' git-repository: semi, flim, apel and wanderlust. The plan is to gradually apply the changes to the upstream (CVS) repository.

bugs

Although I have been quite happy with Wanderlust, there was one bug #5534 that has bitten me a few times, causing occasional hangs when saving (draft) messages with non-ascii characters. It seemed finally to be a bug in emacs itself, which is triggered by something in Wanderlust. A fix will probably be available for the next emacs version; until then, you can work around this by using an external MIME-encoder. To do this, add the following to your WL initialization code (thanks to various helpful people on the WL mailing list):

(setq mel-b-ccl-module nil)
(setq mel-q-ccl-module nil)
(setq base64-external-encoder '("mimencode"))
(setq base64-external-decoder '("mimencode" "-u"))
(setq base64-external-decoder-option-to-specify-file '("-o"))
(setq quoted-printable-external-encoder '("mimencode" "-q"))
(setq quoted-printable-external-decoder '("mimencode" "-q" "-u"))
(setq quoted-printable-external-decoder-option-to-specify-file '("-o"))
(setq base64-internal-decoding-limit 0)
(setq base64-internal-encoding-limit 0)
(setq quoted-printable-internal-decoding-limit 0)
(setq quoted-printable-internal-encoding-limit 0)

(setq-default mime-transfer-level 8)
(setq mime-header-accept-quoted-encoded-words t)

This requires the mimencode-program, which is part of the metamail-package. For the time being, this seems to be the best solution when using Wanderlust with Emacs 23.

one more trick: reformatting

Let's finish with one more trick. Sometimes, incoming mail is formatted quite badly; in particular, the new lines are too long for comfortable reading. From the WL-mailing list, here's a trick to deal with that:

(require 'filladapt)

;; from a WL mailing list post by Per b. Sederber
;; Re-fill messages that arrive poorly formatted
(defun wl-summary-refill-message (all)
  (interactive "P")
  (if (and wl-message-buffer (get-buffer-window wl-message-buffer))
      (progn
        (wl-summary-toggle-disp-msg 'on)
        (save-excursion
          (set-buffer wl-message-buffer)
          (goto-char (point-min))
          (re-search-forward "^$")
          (while (or (looking-at "^\\[[1-9]") (looking-at "^$"))
            (forward-line 1))
          (let* ((buffer-read-only nil)
                 (find (lambda (regexp)
                         (save-excursion
                           (if (re-search-forward regexp nil t)
                               (match-beginning 0)
                             (point-max)))))
                 (start (point))
                 (end (if all
                          (point-max)
                        (min (funcall find "^[^>\n]* wrote:[ \n]+")
                             (funcall find "^>>>>>")
                             (funcall find "^ *>.*\n *>")
                             (funcall find "^-----Original Message-----")))))
            (save-restriction
              (narrow-to-region start end)
              (filladapt-mode 1)
              (fill-region (point-min) (point-max)))))
        (message "Message re-filled"))
    (message "No message to re-fill")))

(define-key wl-summary-mode-map "\M-q" 'wl-summary-refill-message)

Now, you can refill your messages with M-q when in the Summary.

If you have any other nifty WL-tricks that could be useful for others, please share them in the comments, thanks!

2010-02-19

dealing with many buffers: ibuffer


If you are like me, you'll open a lot of buffers in emacs. There may be a couple of buffers with source code, a few for e-mail. org-mode will open buffers for all your agenda files. Then, maybe an info page, a few ERC-channels, a couple of special emacs buffers such as **Messages** and **scratch**. So, in a moderately busy emacs session there may 30-40 buffers open, and after a day or so there can be many more.

With so many buffers, it can be hard to quickly find the one you are looking for - and clearly a one-tab-per-buffer (like Firefox uses) would not work very well either.

So, what can we do instead? Here, on emacs-fu, we discussed this a couple of
times already:

  • using ido-mode, you can quickly switch to buffers by typing a subset of
    their name
  • using elscreen to step through buffer configurations (this comes close to a
    workable tab-like solution)

These are really useful tools. What's still missing though, is a way to get an overview of all buffers. For that, emacs provide buffer-menu, normally bound to C-x C-b. It lists all your buffers, and you can interact with them in a way similar to dired, e.g. you can switch to a buffer by moving the point (cursor) to the buffer and pressing Return. Or you mark buffers for deletion by pressing d when point is on the buffer, and then press x to kill them all.

Very useful. But if you really have a lot of buffers, just having a long list of them may still be a bit hard to deal with. For that, there is ibuffer, which allows you to put your buffers in different categories -- which can even overlap. Emacs ships ibuffer since version 22, so you'll probably already have it.

Using a setup like the following, you can put your buffers in categories; each buffer is shown only once (apparently, the first match), and you can match on mode (the Emacs-mode of the buffer), name (the buffer name), filename (the full path to the file being visited, if any), and a couple of others (see EmacsWiki).

(require 'ibuffer) 
(setq ibuffer-saved-filter-groups
  (quote (("default"      
            ("Org" ;; all org-related buffers
              (mode . org-mode))  
            ("Mail"
              (or  ;; mail-related buffers
               (mode . message-mode)
               (mode . mail-mode)
               ;; etc.; all your mail related modes
               ))
            ("MyProject1"
              (filename . "src/myproject1/"))
            ("MyProject2"
              (filename . "src/myproject2/"))
            ("Programming" ;; prog stuff not already in MyProjectX
              (or
                (mode . c-mode)
                (mode . perl-mode)
                (mode . python-mode)
                (mode . emacs-lisp-mode)
                ;; etc
                )) 
            ("ERC"   (mode . erc-mode))))))

(add-hook 'ibuffer-mode-hook
  (lambda ()
    (ibuffer-switch-to-saved-filter-groups "default")))
If you like ibuffer, you can even override the buffer-menu key binding for
it:
(global-set-key (kbd "C-x C-b") 'ibuffer)
As with buffer-menu, you can do various funky things with those buffers, and also filter them further; see the documentation. I am mostly using it for its buffer-navigational qualities, and it's good at that.