Showing posts with label emacs. Show all posts
Showing posts with label emacs. Show all posts

wdired and renaming into nonexistent directories

(For the uninitiated, wdired is an indispensable emacs mode that lets you rename files in a directory just by editing their filenames in a buffer.)

Joakim Verona wrote a nifty patch against wdired that allows you to rename even to paths in directories that don't exist yet (emacs creates them for you when you finalize the operation). As an example of where this might be useful, suppose you have a directory like this:

  /home/phil/tempfiles:
  total used in directory 60K available 413675080
  -rw-r--r--  1 phil phil 318K 2009-12-31 19:00 20091231.jpg
  -rw-r--r--  1 phil phil 320K 2010-01-01 19:00 20100101.jpg
  -rw-r--r--  1 phil phil 305K 2010-01-02 19:00 20100102.jpg
  [...]

Say you change that to the following (for instance, using M-x string-rectangle, among other alternatives):

  /home/phil/tempfiles:
  total used in directory 60K available 413675080
  -rw-r--r--  1 phil phil 318K 2009-12-31 19:00 2009/12/31.jpg
  -rw-r--r--  1 phil phil 320K 2010-01-01 19:00 2010/01/01.jpg
  -rw-r--r--  1 phil phil 305K 2010-01-02 19:00 2010/01/02.jpg
  [...]

When you save, your files are now neatly organized in a year/month/day directory structure. This is the closest thing to magic I've done on my computer this month.

I've made some minor updates to Joakim's patch to fix bit-rot and conditionalize this behavior on a variable.

wdired-rename-to-nonexistent-directories.patch (1.6kb)

As an aside, I think learning about wdired turned on a lightbulb in my head that changed my understanding of Emacs. Yes, emacs is a text editor. But its power comes, in part, from the scores of major modes that let you interact with many different kinds of resources (e.g. your filesystem, as with wdired) under the guise of editing text (which you can think of as supplying a common abstraction over all those resources). Once you learn how to use, say, regexp search and replace, you can take advantage of that power when editing text files, but also when renaming/reorganizing files or composing mail or whatnot. Emacs is a text editor, but text doesn't just mean files.

Resolving conflicts (in version control)

When Git (or another VCS) attempts to apply a patch that doesn't apply cleanly, it will defer to you, the user, to figure out the right thing to do. Usually you get, dumped in your lap, a file that has all these funny conflict markers in it, showing alternative versions of the content:

    <action name="Execute"><execute>google-chrome</execute></action>
  </keybind>
  <keybind key="W-s-b">
<<<<<<< HEAD
    <action name="Execute"><execute>firefox-3.6</execute></action>
=======
    <action name="Execute"><execute>firefox-3.7</execute></action>
>>>>>>> f50523b...
  </keybind>
  <keybind key="W-a">
    <action name="Execute"><execute>rhythmbox</execute></action>

You can edit that file by hand to get the state you want, but Emacs has a specialized mode for resolving conflicts. Type M‑x vc‑resolve‑conflicts and you get a three-paned frame like the following:

  • Press n and p to move between diff hunks.
  • For each hunk you can press a or b to transfer the version from the left or right side, respectively, to the output. You can leave the conflicted versions if there's something you really need to fix up by hand.
  • Press q when you're done. Emacs returns you to your fixed-up file. Save it.

Some Emacs macro tricks

Keyboard macros are the Emacs feature that I wish every program had. Especially web browsers: having to carry out repetitive tasks in web apps always feels to me like a throwback to a less civilized era.

(More information about keyboard macros, for the uninitiated: see #2.)

Here are some useful macro-related commands that I recently learned to use:

Extending a macro. If you record a macro, then realize you forgot to add an important step at the end, you don't have to re-record it. C-u F3 replays the last macro and then lets you tack on more commands to the end of it.

For example, C-u F3 RET F4 replays the last macro and then appends RET to the end of it. (You can also use C-u C-u F3 ... F4 to extend a macro without replaying it again first.)

Editing a macro. For more intensive fixes or changes to macros, you can edit your most recent macro with C-x C-k C-e (kmacro-edit-macro-repeat). You get a buffer like the following, and you can remove keystrokes or add new ones:

;; Keyboard Macro Editor.
;; Press C-c C-c to finish; press C-x k RET to cancel.
;; Original keys: ESC c ESC f ESC f ESC f C-d RET<

Command: last-kbd-macro
Key: none

Macro:

ESC c   ;; capitalize-word
ESC f   ;; forward-word
ESC f   ;; forward-word
ESC f   ;; forward-word
C-d   ;; delete-char
RET   ;; newline

Creating a macro from your keyboard history. If you just performed some task that you'd like to repeat, but didn't have the foresight to start recording a macro before you started, all is not lost. C-x C-k l (kmacro-edit-lossage) brings up a buffer (like the edit buffer above) containing your most recent 300 keystrokes, which you can pare down to create a new macro.

"Edit with Emacs" Chrome extension

Alex Bennée has written an Edit with Emacs extension for Google Chrome. It's Chrome's answer to Firefox's "It's all text" extension, which makes composing emails, blog posts, and other long-form text in a browser a lot more tolerable. (Hooray!)

Since Chrome extensions can't spawn arbitrary processes, the Edit with Emacs extension requires the cooperation of an additional edit server that can. The edit server is implemented in elisp and is bundled with the extension.

Installation instructions:

  1. Visit the extension gallery page and click "Install".
  2. In Chrome, click on the wrench menu, Extensions, "Options" under "Edit with Emacs", and follow the instructions there for setting up the edit server.
  3. After configuring the edit server, click "Test Edit Server" to make sure everything is working.
  4. Henceforth, in any new tabs you open, you'll see a little "edit" button next to any textarea elements, which you can click on to pop up a new editor frame. (You can also double-click on the textarea.)

Subtleties of search-and-replace in Emacs

The search/replace mechanism in Emacs is a beautiful thing, full of subtleties.

It is pretty clear that its design has been honed to an edge by about 20 years of heavy use. You might not think there could be much to it, but a lot of apps that have come along since then could learn something from some of its features:

Incremental search. (isearch, or "find as you type") This has gained traction elsewhere in recent years. To search, press C-s and start typing; C-s again takes you to successive matches. Emacs highlights all the matches that are visible:

You can save quite a bit of typing this way because you can stop as soon as you've typed a prefix that uniquely identifies the text you're looking for.

In addition, the search UI is in the minibuffer, instead of in a separate dialog that covers part of your document.

Firefox, Chrome, and gedit all have fairly similar features; however, they only expose bare-bones search functionality through them. OpenOffice and most word processors bring up a big and jarring dialog.

Yanking from the document. This is like auto-completion for your searches. Suppose you're looking for all instances of "tag.artist" in your document. Press C-s and start typing...

Now you notice that the word following the highlighted match is exactly what you were looking for. Just press C-w to pull the next word into your query:

Then pressing C-s searches for subsequent occurrences of tag.artist. If you think this is useful, just think about how awesome it is when you need to search for superLongIdentifierNames in Java code.

You can also yank just the next character from the document, or everything up to the end of the line. Type C-h k C-s in Emacs to learn more.

Case replacement. If you have the text

Eat foo for breakfast!
Foo is the best medicine.
VOTE FOO FOR PRESIDENT

and replace (M-x query-replace or M-%) "foo" with "bar", what do you get? Exactly what you expect:

Eat bar for breakfast!
Bar is the best medicine.
VOTE BAR FOR PRESIDENT

This is clearly what you want most of the time, at least when you're editing prose. Gedit and OpenOffice don't do this (and Chrome and Firefox don't have a "replace" feature).

(What happens, you ask, if you're editing code, or anything else where case sensitivity is critical? Emacs's heuristic is to only turn on these smart replacements when your query and replacement text are both all lowercase. You can also manually toggle case-sensitivity in searching with M-c. For what it's worth, I've never noticed a false positive when editing code.)

Cycling behavior. Many programs do a poor job of letting you know when your search has wrapped around to the beginning of the document. In Firefox, I often find that I can inadvertently cycle through looking at all the search results two or three times before I realize what I've done.

After the last match in a document, Gedit and Chrome wrap around to the beginning silently. Firefox wraps around and concurrently displays a notification in the search UI. The problem is that if your attention is focused on the document content—as it probably is if you're scanning the individual matches—it's easy to miss the cues that tell you the search has wrapped around (e.g. Firefox's notification, or the scroll bar jumping back). You can end up back at the beginning of the document without realizing it.

At the other end of the spectrum, OpenOffice brings up a big and jarring dialog asking you "Yes/No" whether you want to continue searching at the beginning. Not so great, either.

How does Emacs deal with this? When you've reached the last match for a query in the buffer, pressing C-s does nothing, except raising a quiet notification that there are no remaining matches:

If you press C-s again, however, the search wraps back around to the beginning of the buffer.

That is, at the last match, C-s is not initially met with an immediate jump to a new match (as it usually is); Emacs gives just enough "pushback" to ensure that the user is aware when the search has wrapped, even if they're not paying any attention to the application chrome (minibuffer and scroll bars)! Very cool.

Displaying failed searches. When you type something that doesn't have a match, Emacs brings you to the maximal matching prefix of whatever you typed, and highlights the part of your query that wasn't found:

This kind of feedback gives you a good idea of whether or not you made a typo/error in your search: if you did, it often appears near the point where the text stopped matching.

If you only get all-or-nothing feedback telling you "no matches were found," then you are sort of groping around in the dark as you try to figure out what went wrong.

Search as a method for navigation. Perhaps the killer feature of isearch in Emacs is that you can use it as the primary method for moving around in a document, essentially replacing most of the functions of the PgUp/PgDn keys and the scroll bar in other applications.

Part of this has to do with the fact that the search UI is so lightweight (no dialog boxes!). However, isearch in Emacs is also cool because it facilitates many use cases:

  • During a search, you can press C-g to cancel and return to where you started. This is handy if you just wanted to search for something in order to get a quick glance at it.
  • …However, if you do indeed want to stop at the current match, press RET. Perhaps you want to make some quick edits or do some more extensive reading at that spot. But when you're done with that, you can press C-x C-x to return to where you originally were, because Emacs has set the mark to the place where you started.
  • …Or, you can just continue editing there with no intention of returning to your original position.

Gedit and OpenOffice really only support that very last use case. You can hold your existing spot in a document with the cursor, but then you're limited to looking around with the scrollbars, which is cumbersome. Or you can use the Find feature or otherwise move the cursor, but then you've lost your original position.

Emacs is like your very own personal assistant: it remembers things so you don't have to.

Conclusion

I haven't mentioned many of the miscellaneous keyboard-accessible commands and options available from within isearch and query-replace. These are well worth your time to learn, although they are quite self-explanatory if you read the integrated help:

  • For options available in isearch, type C-h k C-s.
  • For options available in query-replace, type C-h at a query-replace prompt.

I'd sum up some of the more generalizable design principles behind search-and-replace in Emacs as follows:

  • Reduce extraneous typing.
  • Stay out of the user's way whenever possible.
  • However, alert the user with immediate and useful feedback whenever necessary.

AUCTeX and preview-latex

AUCTeX is a TeX mode for Emacs that adds various conveniences for editing LaTeX (and other macro packages). One of its killer features is inline previews of math and graphics, using preview-latex:

With AUCTeX and preview-latex, you can properly edit your document and equations in their high-level (TeX source) representation, while getting near-instant confirmation that your equations will turn out the way you want. It's pretty much the best of both worlds.

AUCTeX is easy to set up on Ubuntu, although it takes slightly more work than the usual apt-get invocation. Here is a HOWTO for my future reference (and yours). This has been tested on Ubuntu 9.04 with a post-v23-release emacs-snapshot:

Install AUCTeX.

$ sudo aptitude install auctex

Add the following init code to your .emacs file.

(load "auctex.el" nil t t)
(load "preview-latex.el" nil t t)

Open a LaTeX file in Emacs and press C-c C-p C-b (M-x preview-buffer) to generate math/graphics previews for the entire buffer. After you update an equation, press C-c C-p C-p (M-x preview-at-point) to refresh the preview.

Further reading: AUCTeX, AUCTeX manual

Emacs 23

Emacs 23 has been released. You can download it from GNU's FTP server.

The most notable new features or changes that I noticed or have been using:

  • A single Emacs process can generate frames on any number of TTYs and on X simultaneously. Run M-x server-start and then emacsclient -t or emacsclient -c to create a new TTY or X frame, respectively.
  • C-p and C-n now move by screen/visual lines instead of by logical lines. While this makes Emacs more consistent with most modern apps, it has the potential to break keyboard macros. If you use macros frequently, consider setting (setq line-move-visual nil) to disable this behavior.
  • Transient Mark mode is enabled by default. I find t-m-m is occasionally really handy, especially after the mark-* commands, and for restricting the region for query-replace. However, I think t-m-m highlights a little too aggressively. To disable t-m-m except after the mark-* commands, I use the following:
  • (transient-mark-mode 0)
    
    ;; Activate t-m-m only after mark-* commands (you can also enable it manually
    ;; at any time with C-u C-x C-x).
    (require 'cl)
    (macrolet
        ((advise (&rest commands)
                 `(progn
                    ,@(mapcar (lambda (command)
                                `(defadvice ,command (after transient-mark activate)
                                   "Activate Transient Mark mode temporarily."
                                   (setq transient-mark-mode '(only))))
                              commands))))
      (advise mark-sexp
              mark-word
              mark-paragraph
              mark-defun
              mark-end-of-sentence
              mark-page
              mark-whole-buffer
              LaTeX-mark-environment
              LaTeX-mark-section))
  • C-l is bound to recenter-top-bottom, which moves the viewable area so that the current line is at the center, top, or bottom on successive presses. Useful for surveying the area around point.
  • DocView mode, new, is a PDF/PostScript/DVI viewer.
  • Emacs is smarter about splitting windows (e.g. after C-x 4 C-f), splitting vertically if your frame is sufficiently wide.
  • Beautiful anti-aliased fonts.

There are many, many, more changes. See etc/NEWS for the gory details.

On emacs-devel, I recently got a pointer to Richard Stallman's 1981 paper on the design of Emacs, presented at the ACM Conference on Text Processing:

Extensibility means that the user can add new editing commands or change old ones to fit his editing needs, while he is editing. EMACS is written in a modular fashion, composed of many separate and independent functions. The user extends EMACS by adding or replacing functions, writing their definitions in the same language that was used to write the original EMACS system. We will explain below why this is the only method of extension which is practical in use: others are theoretically equally good but discourage use, or discourage nontrivial use.

Extensibility makes EMACS more flexible than any other editor. Users are not limited by the decisions made by the EMACS implementors. What we decide is not worth while to add, the user can provide for himself. He can just as easily provide his own alternative to a feature if he does not like the way it works in the standard system.

It is striking how so little software today, even "professional" software that users are apt to use 8 hours a day, is actually designed to facilitate extensibility and automation by users.

Using itsalltext with emacs/emacsclient

I finally started using It's All Text!— this is something I should done long ago. (It's All Text! is a Firefox extension that lets you invoke an external editor to edit the contents of any textarea element, like this blog post I'm writing right now in Blogger.)

There's such a stark contrast between using Emacs, where I feel at one with the document, and typing in the browser textarea, which always makes me feel kind of claustrophobic now (the problem is not that the textbox is too small, but that it doesn't provide enough degrees of freedom for editing).

If you are using an Emacs with multi-TTY support (a v23 snapshot), you can leave one long-lived Emacs server instance running and quickly pop up a new frame from it for each editing buffer:

  1. From your main Emacs frame, run M-x server-start.
  2. Save the following wrapper script (I called mine ecw) and configure it to be your editor in It's All Text!:
    #!/bin/sh
    /usr/bin/emacsclient -c $@
  3. In the It's All Text! options you can configure your favorite hotkey to launch a new Emacs frame for editing.
  4. When you're done with a buffer, save and press C-x # to return to Firefox.

Update: another tip. To automatically fire up html-mode when editing text from, say, blogger.com, you can add something like this to your .emacs:

(add-to-list 'auto-mode-alist '("/www\\.blogger\\.com\\.[^/]+\\.txt\\'" . html-mode))

This works because the temp file that It's All Text! creates has a name like www.blogger.com.2a2q1e2r32.txt.

"Being Productive With Emacs" Redux

This past IAP I taught a short class on Emacs ("Being Productive With Emacs") at MIT. It was similar in content to the class that I taught in 2007, although I pared down the material a bit.

I've posted the slides online. You may use the slides under the terms of the GFDLv1.3+ or the GPLv3+.

(I made the slides using S5, which is pretty sweet. It lets you make moderately professional looking DHTML slides in a text editor without much pain.)

Magit

Magit is a spectacular Emacs add-on for interacting with git. Magit was designed with git in mind (unlike VC mode, which is a more generic utility), so git commands map quite straightforwardly onto Magit commands. M-x magit-status tells you about the current state of your repo and gives you one-key access to many common git commands. However, what really sold me on Magit was its patch editor, which completely obsoletes my use of git add, git add --interactive, and git add --patch. If Magit had this patch editor and nothing else, I would still use it. That's how great this is.

M-x magit-status (which I've bound to C-c i) tells you about your working tree and the index, kind of like a combination of git diff, git diff --cached, and git status. It shows some number of sections (e.g. Staged changes, Unstaged changes, etc.); within each section you can see what files have been modified; within each file you can view the individual hunks. Within any of these containers you can press TAB to expand or collapse the heading. Moving your cursor into a file header or a diff hunk header selects the changes in that file or hunk, respectively. You can then press s to stage those changes, as shown in these before-and-after pictures:

Once you're satisfied with your staged changes, you can press c to commit, which prompts you for a log message. After you've typed a message, C-c C-c performs the actual commit.

This is already much faster than using git add --interactive or git add --patch to stage parts of a file. You just find the hunk you want rather than having git ask you yes/no about every hunk.

However, Magit also allows staging changes at an even finer granularity. If you highlight some lines in a hunk and then press s, Magit only stages the selected lines, as shown in these before-and-after pictures:

When in doubt, it's a good idea to make small commits rather than large commits. It's easy to revert (cherry-pick, explain, etc.) more than one commit, but hard to revert half a commit. Kudos to Magit for making small commits easier to create.

Finally, Magit comes with a fine manual, which you can read online.

Installing Magit

It doesn't get too much easier than this for external Emacs packages.

Check out Magit:

git clone git://gitorious.org/magit/mainline.git

Make sure that magit.el from that checkout, or a copy, is on your load path. For example:

(add-to-list 'load-path (expand-file-name "~/.emacs.d/lisp"))

Autoload Magit and bind magit-status:

(autoload 'magit-status "magit" nil t)
(global-set-key "\C-ci" 'magit-status)

Emacs 22.3 released; emacs-snapshot packages for Ubuntu

Emacs 22.3 was released on 5 September 2008.

You may know that Romain Francoise maintains a repository with emacs-snapshot packages for Debian updated weekly. Well, what about Ubuntu users? Since earlier this summer-ish, the ubuntu-elisp PPA has also been receiving emacs-snapshot packages regularly! Great news for those of us who always want to try out the features that the awesome hackers on emacs-devel are writing about.

Reading your mail in Emacs with VM

I posted an article on reading your mail with VM in Emacs, which contains a minimal VM orientation, information about how I read mail in VM, and the elisp configuration I used to set that up.

I attempted the switch a couple of months back after realizing that the volume of email I was dealing with was seriously impairing my work ability. Gmail does have some tools for managing lots of email (labels), but with VM I can be much more fine-grained about what messages I look at at any particular time. Scanning and reading mail is also much faster, if only because I don't have to wait for the RTT to a Google server and the browser render time every time I want to do something.

And, of course, the best part of VM is that it comes with a great e-mail editor.

Why VM? The big choices are Gnus, VM, and MH-E. I had tried Gnus and couldn't really wrap my head around its model of doing things. MH-E sounded acceptable but I assumed that VM, which had more Lisp implementation, would probably be more flexible. I am pretty happy with VM, but I suspect that changing mail clients is really just a matter of performing a conversion process on the mail folder files. Some operations (such as writing an entire mailbox to disk) are probably slower than they could be, but in general it is blazing fast.

I also wrote about setting up BBDB (the Insidious Big Brother Database), an address book program which is strangely satisfying to use.

Read about my VM configuration and workflow.

Coloring email in Emacs VM

I do like Gmail, but (1) it feels sluggish, (2) writing anything nontrivial in a browser text box is just too awkward, and (3) I occasionally wish I had a copy of my mail accessible offline. So I've been trying to switch over to retrieving and reading my mail in Emacs. After a failed experiment in using Gnus to read my mail last year, I recently mustered the energy to try VM.

It seems to be working well, and I'll write more about my configuration and workflow later, but I wanted to mention one package that I just found.

One of the (few) things I liked about Gnus was that it color-coded the blurbs in each message by author, which it inferred from the line prefixes (">", ">>", etc.), like so:

VM doesn't support such functionality out of the box, but the package u-vm-color.el mimics it. The package is fairly straightforward to install and works as advertised.

One thing I discovered that when you run a TTY Emacs it assumes that it is working with light text on a dark background. If you are running Emacs in an xterm with dark text on a light background, you'll need to supply the -rv (reverse video) option to Emacs. Otherwise, Emacs may choose unreadable, or at least, suboptimal, colors for all its faces.

A million lines of Lisp

People rave about Lisp, and one reason why is because you can use macros to make new kinds of abstractions. Sure, in other languages you can write functions to define new procedures, but in Lisp you can write macros to define new control flow constructs (for starters). You can write functions that write functions and programs that write programs, a power which is pretty much unimaginable in most other languages. In other languages you can only stack your abstractions so high, but in Lisp, the sky's the limit. Because of macros, and others of its features, Lisp is sometimes called the programmable programming language.

I suspect that because of macros, Lisp programs grow in a way that is qualitatively different from programs in other languages. With every line of additional code in Lisp, you can do more, more quickly; in ordinary languages, the return on additional lines of code is constant if not decreasing. Various people have tried to estimate the advantage that Lisp has over C++ (in the ratio of the number of lines needed to do a particular task). Whatever the figure, I believe that Lisp's advantage should increase for larger and larger programs.

In pretty much any language, a program with a million lines of code is regarded with considerable respect. So if Lisp can do so much more with so much less, what would a million line Lisp program look like? Could we even imagine it? (Would it be sentient, or what?)

It turns that such a program exists, and is widely available.

As of right now (23 June 2008), a checkout of GNU Emacs has 1,112,341 lines of Lisp as well as 346,822 lines of C.

It is somewhat astonishing that Emacs, a program with more than 30,000 built-in functions— in a single namespace&mdash can keep from falling apart under its own weight! In Emacs, activating minor or major modes, or setting variables, can have effects on how particular buffers look, what is done when Emacs saves a file, and how different keys (or other events) are interpreted, among other things. Unlike operating systems, which are broken down into programs (which only talk to each other in limited ways), Emacs has many parts which all have the potential to interact with each other.

In some cases it is necessary to add special-case code to say what should happen for particular pairs of interacting features, but a robust system should be able to make the right thing happen most of the time even for features which are totally oblivious of each other. One way that Emacs tames this complexity is with the use of hooks.

Hooks (sometimes referred to elsewhere as listeners) are a way of telling Emacs to run a particular piece of code whenever a certain situation happens (e.g. when a file is opened). Many Emacs modules add hooks in order to do their thing. For example, VC checks every time I open a file whether it is in a version-controlled directory, so that it can report the file's version and status. Another example: Emacs activates follow-mode— if I have set a particular option— whenever I open a file. The variable find-file-hook is a list containing, among others, two functions responsible for performing the tasks described above; each function in that list is executed whenever Emacs opens a new file. I were to add a function of my own to one of these hooks, then Emacs would happily run it, too.

As an alternative, you might consider implementing such an extensible system using polymorphism and inheritance: e.g. to add behaviors, you would create a subclass of a particular class which implemented some method differently. The chief advantage of using hooks over that approach is that with hooks, changing behavior is very obviously additive: if you can call for either A, B, or C to happen in a particular situation, you can also easily call for any combination of those things, but A, B, and C can very well be implemented completely independently— a key requirement for systems of a million lines or more.

From dabbrev-expand to hippie-expand

I've "graduated" from using dabbrev-expand and switched to hippie-expand. hippie-expand does much the same thing has dabbrev-expand (completes words you are typing) but supports adding new completion heuristics rather than only looking at text in other buffers for potential completions. I switched when I found myself pressing M-/ and hoping to get completions corresponding to the names of other files I had open. hippie-expand does this out of the box.

To set it up, all you need to do is bind M-/ to hippie-expand (which comes with Emacs):

(global-set-key "\M-/" 'hippie-expand)

By default, hippie-expand uses the following set of completion techniques (customizable in hippie-expand-try-functions-list):

  '(try-complete-file-name-partially
    try-complete-file-name
    try-expand-all-abbrevs
    try-expand-list
    try-expand-line
    try-expand-dabbrev
    try-expand-dabbrev-all-buffers
    try-expand-dabbrev-from-kill
    try-complete-lisp-symbol-partially
    try-complete-lisp-symbol)

Because hippie-expand uses try-expand-dabbrev-* as one of its completion techniques, its completions are a strict superset of the completions that dabbrev would have suggested. So it is a pretty good drop-in replacement for dabbrev. In addition to looking for words in other buffers, it will also fill in filenames, entire lines of files, lisp symbols, and words in the kill ring.

Improving rename order in wdired

After using Emacs' wdired for some heavy-duty work, I noticed a flaw in how it does renaming.

Some background for those who do not know what wdired is (I find it indispensable!): wdired gives you a view of a directory that looks like the output of ls -l. However, you are allowed to edit the filenames. When you "save" the buffer, wdired renames all the files whose names you have changed. (More information: a blog post about wdired; Emacs manual node for wdired)

Here's the problem:

wdired always performs renames in a fixed order, starting from from the bottom of the buffer and going up. You can easily construct sets of renames where wdired unnecessarily thinks it has to clobber a file because it is doing the renames in the wrong order.

I improved wdired-finish-edit so that it does renames in the "right" order. I've posted the improved version on my web site.

While this does complicate the implementation a bit, the apparent model that wdired presents is that all the renames you ask for happen simultaneously, so I believe there is no reason when this new behavior would be inappropriate, assuming the code is not buggy.

Emacs in Ubuntu Hardy now has anti-aliased fonts

Update, 7 August 2009: the most recent major release of Emacs (v. 23.1) now has the anti-aliased font support. See the Ubuntu elisp PPA, which contains packages for any recent Ubuntu release, or see installation instructions for various other platforms.

The latest emacs-snapshot-gtk packages in Ubuntu Hardy (1:20080228-1) have the Unicode/font changes merged, and now support anti-aliased fonts for the first time.

While I didn't really mind the old bitmap fonts, I have to say that anti-aliasing is gorgeous.

To activate the new fonts, I added the following line to my ~/.Xdefaults:

Emacs.font: Monospace-8

Then, I ensured that the settings in .Xdefaults are being loaded by adding the following to my ~/.xsession:

if [ -f $HOME/.Xdefaults ]; then
  xrdb -merge $HOME/.Xdefaults
fi

Comparison of regexp syntax

To help myself learn Emacs regular expressions, I've put together this cheat sheet comparing regular expression syntax in Emacs, Python, and egrep.

Note that in Emacs, the syntax described below is for regular expressions that are entered directly (e.g. in isearch-forward-regexp and occur). When you provide a regexp in a string (e.g. in Lisp code or in re-builder) you need to double all backslashes.

Emacs Python egrep
Any character . . .
Beginning of line ^ ^ ^
End of line $ $ $
0 or more repetitions * * *
1 or more repetitions + + +
3-5 repetitions \{3,5\} {3,5} {3,5}
Optional ? ? ?
Character set [...] [...] [...]
Alternatives \| | |
Group \(...\) (...) (...)
Named group (?P<name>...)
Non-capturing group1\(?:...\)(?:...)
Word boundary \b \b \b
Digit [[:digit:]]\d [[:digit:]]
Whitespace char \s- \s
Alphanumeric char \w \w \w
Back reference \1 \1
Named back reference (?P=name)

1 Also referred to as "shy groups".

Coming soon to Emacs...

I've recently read about these new features that are making their way into Emacs CVS. (You can check out many of these by compiling from CVS or using a recent snapshot.) It may be a while before Emacs 23 is released, but never let it be said that Emacs is stagnant:

  • Emacs is now a viewer for PDF, PS and DVI files (screencast). The new doc-view mode is automatically activated when you visit any of those file types.
  • Emacs is getting D-Bus support. D-Bus provides a channel for Emacs to talk to other desktop and system applications that support it.
  • Tramp (remote file access) is now faster than ever because it caches all the diagnostics it performs on each host.
  • As I've previously mentioned, VC-mode is being reworked to better deal with changeset-oriented and distributed VCS.
  • With the merging of the Unicode branch, Emacs will get, among other things, gorgeous anti-aliased font rendering.
  • The multi-TTY branch allows a currently running Emacs to open frames on other displays and TTYs. This means emacsclient is now a fast and proper editor for terminal programs that invoke an editor.

Update: Emacs is also getting support for status area icons and notifications. Hopefully this will lead to better integration with the rest of the desktop for Emacs-based applications.

Manipulating changeset-based VCS from within Emacs

VC mode in Emacs is currently getting a facelist to better support changeset-oriented version control systems, including distributed VCS. I told myself I would attempt to start using these new features rather than continuing to use Git from the command line. Here's what I've learned so far (just enough to get started):

The new VC mode was committed to Emacs CVS after the 22.1 release; you can get it by building Emacs (from CVS or from the Git mirror) or getting a precompiled snapshot (Ubuntu, Debian).

Previously, VC operations in Emacs operated on a single file (whatever file was in the current buffer). Now, you can select multiple files to operate on, as well as get an overview of your project's status, by using VC-Dired mode:

  • Open a directory with C-x v d. It looks a lot like a regular Dired listing, but has space to show some VC-specific information.
  • By default, VC-Dired only shows changed files. Type v t to toggle between displaying only changed files and displaying all files.
  • In VC-Dired, v is the VC prefix key, which does what C-x v does in file buffers. For example, you can diff the file at point with v = or annotate the file at point with v g.
  • Hack a bit. When you're ready to commit, mark one or more files you want to commit in VC-Dired with m.
  • Commit the files with v v. As with single-file commits, VC prompts you for a log message (type C-c C-c to finish the commit.