<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc=" http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>briancarper.net (λ) (Tag: Vim)</title><link>http://briancarper.net/tag/80/vim</link><description>Some guy's blog about programming and Linux and cows.</description><item><title>Shuffle lines in Vim</title><link>http://briancarper.net/blog/580/shuffle-lines-in-vim</link><guid>http://briancarper.net/blog/580/shuffle-lines-in-vim</guid><pubDate>Thu, 07 Jul 2011 14:07:41 -0700</pubDate><description>&lt;p&gt;In a pinch, I needed to randomize the order of a few thousand lines of plain text.  In Linux you can just pipe the file through &lt;code&gt;sort&lt;/code&gt;, even right inside Vim:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%!sort -R
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But I was stuck on Windows.  And I don't know how to randomize a file in native Vim script.  But doing it in Ruby is pretty easy, and luckily, Vim has awesome Ruby support.  Tne minutes' work and a few peeks at &lt;code&gt;:h ruby&lt;/code&gt; and we have a successful, working kludge:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function! ShuffleLines()
ruby &amp;lt;&amp;lt; EOF
    buf = VIM::Buffer.current
    firstnum =  VIM::evaluate('a:firstline')
    lastnum = VIM::evaluate('a:lastline')
    lines = []
    firstnum.upto(lastnum) do |lnum|
      lines &amp;lt;&amp;lt; buf[lnum]
    end
    lines.shuffle!
    firstnum.upto(lastnum) do |lnum|
      buf[lnum] = lines[lnum-firstnum]
    end
EOF
endfunction
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;2011-07-07 23:32 - Edited to remove a superfluous line.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2011-07-09 21:33 - Wrong parameter for &lt;code&gt;sort&lt;/code&gt;, oops.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>org-mode is awesome</title><link>http://briancarper.net/blog/577/org-mode-is-awesome</link><guid>http://briancarper.net/blog/577/org-mode-is-awesome</guid><pubDate>Thu, 20 Jan 2011 16:14:44 -0800</pubDate><description>&lt;p&gt;I've seen &lt;a href=&quot;http://orgmode.org/&quot;&gt;org-mode&lt;/a&gt; for Emacs mentioned very frequently around the interwebs, so it went into my mental queue of topics to learn.  It finally bubbled to the top this week, so I took a look.&lt;/p&gt;

&lt;h1&gt;Organizer?  Nah.&lt;/h1&gt;

&lt;p&gt;As an organizer/calendar, well, I doubt I'll need it.  Enforced use of MS Outlook is mandated by work.  My Post-it-notes-all-over-my-desk method of organization will also continue to serve me well.&lt;/p&gt;

&lt;p&gt;There are some nice agenda-related shortcuts that are probably worth using though, like typing &lt;code&gt;C-c .&lt;/code&gt; to enter a datestamp, like &lt;code&gt;&amp;lt;2011-01-20 Thu&amp;gt;&lt;/code&gt;.  Then you can increment or decrement it one year/month/day at a time via &lt;code&gt;S-up&lt;/code&gt; and &lt;code&gt;S-down&lt;/code&gt;.  I like this.&lt;/p&gt;

&lt;h1&gt;Plaintext editor?  Yes!&lt;/h1&gt;

&lt;p&gt;As a plaintext outline and table editor... wow.  org-mode rocks.  Do you know how many hours of my life could have been saved by having a good ASCII table/bullet-list editor?  org-mode lines everything up and keeps it all nice and neat for you.&lt;/p&gt;

&lt;p&gt;You can also make plaintext check boxes and check/uncheck them.  And you can insert hyperlinks and footnotes, and click them to open web pages or jump back and forth between footnote and reference.&lt;/p&gt;

&lt;p&gt;There are ways to collapse and expand outlines, search for items and only display those items, and so on.  The &lt;a href=&quot;http://orgmode.org/guide/index.html&quot;&gt;documentation&lt;/a&gt; for org-mode is very clear and took me less than an hour to read through.  All-in-all a pleasant experience.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;* Agenda
** Things to learn
1. [X] Clojure
2. [X] org-mode (see [fn:diagram1])
3. [ ] Haskell
4. [ ] Japanese
   1. [X] Hiragana
   2. [X] Katakana
   3. [ ] Kanji
5. [ ] The true meaning of friendship

* Footnotes
[fn:diagram1]

| Task                              | Annoyance (1-10) |
|-----------------------------------+------------------|
| Making ASCII tables by hand       |              9.5 |
| Making ASCII bullet lists by hand |              7.2 |
| Using org-mode                    |              0.4 |
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It looks nice plastered into my blog, but you don't get a real idea of how many cool things you can do with it until you open it in Emacs and start shuffling items around, bumping them up/down a level in headlines, creating properly-numbered bullet items with one key, and seeing the columns in the table auto-resize as you type.&lt;/p&gt;

&lt;p&gt;I also highly recommend putting &lt;code&gt;(setq org-startup-indented t)&lt;/code&gt; into &lt;code&gt;.emacs&lt;/code&gt; to make everything look pretty on-screen.  It still saves as the simple plaintext above, but it looks like this in Emacs:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/emacs/org-mode.png&quot; alt=&quot;org-mode&quot; title=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I can definitely see using org-mode for TODO files in some of my projects.  (You can mark entries as TODO (just by typing &lt;code&gt;TODO&lt;/code&gt; in front), and then toggle between TODO/DONE via &lt;code&gt;C-c C-t&lt;/code&gt;.)   I can also see using it as a general-purpose note-taker.&lt;/p&gt;

&lt;p&gt;org-mode also has a &lt;a href=&quot;http://mobileorg.ncogni.to/doc/&quot;&gt;mobile version&lt;/a&gt; for iPhone and Android, synced via WebDAV or Dropbox, so you can org-mode on your phone while you're driving to the grocery store&lt;sup id=&quot;fnref:dontdothis&quot;&gt;&lt;a href=&quot;#fn:dontdothis&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Again I don't really need this, but there it is.&lt;/p&gt;

&lt;h1&gt;The joy of plaintext&lt;/h1&gt;

&lt;p&gt;Plaintext is awesome.&lt;/p&gt;

&lt;p&gt;It's the universal file format.  It's readable and writeable by scripting langauges, terminals, text editors, IDEs, word processors, web browsers, even lowly humans.&lt;/p&gt;

&lt;p&gt;Plaintext's one shortcoming is its lack of structure.  It's just a bunch of letters.  It doesn't have a color, it doesn't have a style, it doesn't line up into columns without a lot of effort.  There's nothing stopping you from opening a parenthesized list and forgetting the closing paren.&lt;/p&gt;

&lt;p&gt;Computers don't care about these problems, but humans are bad at producting plaintext by hand, and bad at editing it once it's produced.  Our clumsy, stumpy fingers and inconsistent, chaotic brains can't handle the freedom.&lt;/p&gt;

&lt;p&gt;Emacs (and Vim) are awesome because they let you do magical things to plaintext.  They enforce structure.  They provide shortcuts so you can get your plainext right the first time.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;[ ]&lt;/code&gt; is just two braces and a space, but org-mode lets me hit &lt;code&gt;C-c C-c&lt;/code&gt; and turn the space into an &lt;code&gt;X&lt;/code&gt;.  This may seem banal, hardly worth caring about, but add to this shortcut thousands upon thousands of others.  Things like org-mode, or &lt;a href=&quot;http://www.emacswiki.org/emacs/ParEdit&quot;&gt;paredit&lt;/a&gt;, or all of Vim's built-in magic... it all adds up to something wonderful.&lt;/p&gt;

&lt;p&gt;And best of all, you always still have the option of manually keyboarding over and typing that &lt;code&gt;X&lt;/code&gt; between the braces yourself.  It's still just plaintext underneath.  So you end up with the best of both worlds.&lt;/p&gt;&lt;div class=&quot;footnotes&quot;&gt;&lt;ol&gt;&lt;li id=&quot;fn:dontdothis&quot;&gt;&lt;p&gt;I do not recommend using org-mode while driving, for public safety reasons. &lt;a rev=&quot;footnote&quot; href=&quot;#fnref:dontdothis&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</description></item><item><title>Vim undo tree visualization</title><link>http://briancarper.net/blog/573/vim-undo-tree-visualization</link><guid>http://briancarper.net/blog/573/vim-undo-tree-visualization</guid><pubDate>Mon, 18 Oct 2010 15:21:16 -0700</pubDate><description>&lt;p&gt;I wrote &lt;a href=&quot;http://briancarper.net/blog/568/emacs-undo-trees&quot;&gt;previously&lt;/a&gt; about an awsome plugin to give Emacs Vim-style undo trees.&lt;/p&gt;

&lt;p&gt;Vim's undo trees are the best thing since sliced bread, but the interface for browsing through the tree is not pleasant.  The &lt;a href=&quot;http://www.dr-qubit.org/undo-tree/undo-tree.el&quot;&gt;Emacs undo-tree library&lt;/a&gt; has a way to visualize the tree and move through it with your keyboard, which solves this problem.&lt;/p&gt;

&lt;p&gt;But now, thanks to Steve Losh, &lt;a href=&quot;http://bitbucket.org/sjl/gundo.vim/src&quot;&gt;Vim has an undo-tree visualizer too&lt;/a&gt;.  Delicious.  Though it's still beta and promises to eat your babies, it seems to work pretty well.  I think the diff view of the changes for the undo is a really good idea.&lt;/p&gt;

&lt;p&gt;Thus continues the eternal Vim/Emacs arms race.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/vim/vim-undo-tree.png&quot; alt=&quot;Vim undo tree&quot; title=&quot;&quot; /&gt;&lt;/p&gt;</description></item><item><title>Vim :ruby and :rubydo scope</title><link>http://briancarper.net/blog/569/vim-ruby-and-rubydo-scope</link><guid>http://briancarper.net/blog/569/vim-ruby-and-rubydo-scope</guid><pubDate>Tue, 31 Aug 2010 10:40:51 -0700</pubDate><description>&lt;p&gt;Note to self.  In old Vim (tested in 7.2.320), I could do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:ruby x='foo'
:rubydo $_=x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now every line in the file says &lt;code&gt;foo&lt;/code&gt;.  But in Vim 7.3 I get an error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NameError: undefined local variable or method `x' for main:Object
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The scoping rules for Ruby in Vim must have changed somewhere along the line.  I was abusing this feature to do some handy things, so this is sad.&lt;/p&gt;

&lt;p&gt;A workaround is to use global variables in Ruby instead.  So this still works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:ruby $x='foo'
:rubydo $_=$x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Phew.&lt;/p&gt;</description></item><item><title>Emacs undo trees</title><link>http://briancarper.net/blog/568/emacs-undo-trees</link><guid>http://briancarper.net/blog/568/emacs-undo-trees</guid><pubDate>Tue, 17 Aug 2010 14:06:33 -0700</pubDate><description>&lt;p&gt;I've said it before: &lt;a href=&quot;/blog/361/emacs-undo-is-horrible&quot;&gt;undo in Emacs is horrible&lt;/a&gt;.  On the other hand, &lt;a href=&quot;http://stackoverflow.com/questions/1088864/how-is-vims-undo-tree-used&quot;&gt;undo in Vim is awesome&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But this is true no longer.  Now there are &lt;strong&gt;&lt;em&gt;&lt;a href=&quot;http://www.dr-qubit.org/undo-tree/undo-tree.el&quot;&gt;undo trees for Emacs!&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;  Yes, this news is so important I had to italicize and bold it.  It's like Emacs has been punching me in the face for years, and today I got it to stop.  I never thought I'd see the day.&lt;/p&gt;

&lt;p&gt;And it works great too.  You can even view the tree visually and navigate it with the cursor keys, which is a step up on what Vim offers out of the box.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/emacs/emacs-undo-trees.png&quot; alt=&quot;Emacs undo trees&quot; title=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In other news, Vim 7.3 is out and it now has &lt;a href=&quot;https://groups.google.com/group/vim_announce/browse_thread/thread/66c02efd1523554b&quot;&gt;persistent undo&lt;/a&gt; across reloads.  It's like an arms race, and gleeful hackers reap the benefits.&lt;/p&gt;</description></item><item><title>Vim and plaintext data files</title><link>http://briancarper.net/blog/552/vim-and-plaintext-data-files</link><guid>http://briancarper.net/blog/552/vim-and-plaintext-data-files</guid><pubDate>Mon, 12 Jul 2010 10:42:48 -0700</pubDate><description>&lt;p&gt;I use Vim to work with plaintext datasets.  Here are some habits and code snippets I've picked up which make data files a bit easier to deal with.&lt;/p&gt;

&lt;!--more Read on for Vim trickery...--&gt;

&lt;h1&gt;Tab-delimited files&lt;/h1&gt;

&lt;p&gt;If you have a file full of tab-separated values, the columns may not line up very well due to the variable display-length of tabs.  You'll often end up with something that looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo bar
longvaluehere    quux
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But things will line up if you set tabstop to a value greater than the longest column.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:setlocal tabstop=16
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then it'll look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo             bar
longvaluehere   quux
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can use visual-block mode to add and remove columns easily.&lt;/p&gt;

&lt;p&gt;If you're working with TSV files, you'll want to set the &lt;code&gt;listchars&lt;/code&gt; option in such a way that tabs are displayed specially.  I use this, stolen/adapted from &lt;a href=&quot;http://github.com/ciaranm/dotfiles-ciaranm/blob/master/vimrc&quot;&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:set listchars=eol:\ ,tab:»-,trail:·,precedes:…,extends:…,nbsp:‗
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Remember also that you can insert a literal tab into your file no matter what you have &lt;code&gt;expandtab&lt;/code&gt; set to, by hitting &lt;code&gt;CTRL-v&lt;/code&gt; first.  &lt;/p&gt;

&lt;p&gt;Those things are just about all I need to work with TSV files comfortably.&lt;/p&gt;

&lt;h1&gt;Dealing with long lines&lt;/h1&gt;

&lt;p&gt;Sometimes I'll run some data through a statistics program and it'll tell me &quot;Invalid character at line 576, column 9438&quot;.  How do you jump to that location in your data?  Easily enough in normal mode:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;576G9438|
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;G&lt;/code&gt; jumps you to a line, &lt;code&gt;|&lt;/code&gt; jumps you to a column.  A good mnemonic to remember these: &quot;g = goto line&quot; and &quot;| looks like a column&quot;.&lt;/p&gt;

&lt;p&gt;Suppose (like me) you turn scrollbars off in your GVim window, or you work from a terminal.  How do you scroll horizontally?  With &lt;code&gt;zL&lt;/code&gt; and &lt;code&gt;zH&lt;/code&gt;.  But those are hard to type and harder to remember, so I map them to CTRL+Shift+Right and Left.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nnoremap &amp;lt;C-S-Right&amp;gt; zL
nnoremap &amp;lt;C-S-Left&amp;gt; zH
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you have a lot of long lines, it behooves you to set up a mapping to turn soft line-wrapping on and off quickly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nnoremap &amp;lt;Leader&amp;gt;w :setlocal nowrap!&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can jump back and forth between wrapped and unwrapped views of your data via &lt;code&gt;\w&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;Diffs on long lines&lt;/h1&gt;

&lt;p&gt;When using vimdiff, &lt;code&gt;]c&lt;/code&gt; and &lt;code&gt;[c&lt;/code&gt; will jump you to lines that contain differences.  But if your lines are thousands of characters long, it doesn't always help to know that two lines are different: you want to know where they differ.  &lt;code&gt;]c&lt;/code&gt; puts you at the first column in the line, which isn't helpful.&lt;/p&gt;

&lt;p&gt;This function will jump you to the column where the difference between two lines starts:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function! IsDiff(col)
    let hlID = diff_hlID(&quot;.&quot;, a:col)
    return hlID == 24
endfunction

function! FindDiffOnLine()
    let c = 1
    while c &amp;lt; col(&quot;$&quot;)
        if IsDiff(c)
            call cursor(&quot;.&quot;, c)
            return
        endif
        let c += 1
    endwhile
endfunction
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This seems fragile, so if you know a better way please leave a comment and let me know.&lt;/p&gt;

&lt;h1&gt;Diff a buffer against itself&lt;/h1&gt;

&lt;p&gt;Sometimes I have files with lots of lines of data, and some lines might be duplicate.  It's really easy to get rid of the duplicate lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:sort u
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But what if I want to see what lines were just removed?  I don't know of a built-in way to do it, so I use this simple function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function! MarkDuplicateLines()
    let x = {}
    let count_dupes = 0
    for lnum in range(1, line('$'))
        let line = getline(lnum)
        if has_key(x, line)
            exe lnum . 'norm I *****'
            let count_dupes += 1
        else
            let x[line] = 1
        endif
    endfor
    echomsg count_dupes . &quot; dupe(s) found&quot;
endfunction
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That'll put a bunch of asterisks at the beginning of every line that's a duplicate of a previous line.&lt;/p&gt;

&lt;h1&gt;Fix broken punctuation&lt;/h1&gt;

&lt;p&gt;Ever had to work with textual data that someone else sent you in MS Word or Excel?  I have.  It hurts.  If you copy/paste from an MS document into a plaintext file, you'll probably end up with a bunch of funky unreadable or undisplayable characters.&lt;/p&gt;

&lt;p&gt;This function fixes the most common Word-spawned &quot;smart&quot; punctuation characters that you're likely to run across:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function! FixInvisiblePunctuation()
    silent! %s/\%u2018/'/g
    silent! %s/\%u2019/'/g
    silent! %s/\%u2026/.../g
    silent! %s/\%uf0e0/-&amp;gt;/g
    silent! %s/\%u0092/'/g
    silent! %s/\%u2013/--/g
    silent! %s/\%u2014/--/g
    silent! %s/\%u201C/&quot;/g
    silent! %s/\%u201D/&quot;/g
    silent! %s/\%u0052\%u20ac\%u2122/'/g
    silent! %s/\%ua0/ /g
    retab
endfunction
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This function was built up during years of choking on special characters that crept up in my data, so I'm sure I'll be adding more to it in the future.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;\%u####&lt;/code&gt; here is a regex escape to represent a character as a hexidecimal Unicode codepoint.&lt;/p&gt;

&lt;p&gt;Many of these characters show up as blank (whitespace) if you lack the font to display them.  If you ever run across a character you can't see and you want to inspect it, put the cursor on it and do&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:ascii
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's a bad name for the command, since it works on Unicode characters too.  That'll give you the numeric code you can use in a regex to replace them all with something sane.&lt;/p&gt;</description></item><item><title>Vim regex - remove kind-of-matching lines</title><link>http://briancarper.net/blog/vim-regex---remove-kind-of-matching-lines</link><guid>http://briancarper.net/blog/vim-regex---remove-kind-of-matching-lines</guid><pubDate>Sun, 20 Jun 2010 22:49:19 -0700</pubDate><description>&lt;p&gt;I have a file where every line starts with a number (followed by whitespace and a bunch of other stuff).  Every number appears on either one or two lines, and if two, the second line always has a &lt;code&gt;b&lt;/code&gt; after the number.&lt;/p&gt;

&lt;p&gt;I need to delete every line for which there's a corresponding &lt;code&gt;b&lt;/code&gt; line.  But if there's no corresponding &lt;code&gt;b&lt;/code&gt; line I want to leave the original line there.&lt;/p&gt;

&lt;p&gt;Before:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;123 foo bar
456 blarg
789 quux
123b foo baz
789b quux blurble
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;123b foo baz
456 blarg
789b quux blurble
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Except in my real file, I have a thousand lines and it'd take a year to do by hand.  Vim to the rescue:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:sort
:%s/^\v((\d+).*\n)(\2b.*)/\3/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that is why Vim is awesome.  Can you think of a shorter way to do this, in Vim or Emacs?&lt;/p&gt;</description></item><item><title>Emacs: Yank lines as lines</title><link>http://briancarper.net/blog/emacs-yank-lines-as-lines</link><guid>http://briancarper.net/blog/emacs-yank-lines-as-lines</guid><pubDate>Fri, 21 May 2010 12:07:13 -0700</pubDate><description>&lt;p&gt;One thing nice about Vim is manipulating whole lines at a time.  &lt;code&gt;dd&lt;/code&gt; deletes a line (including trailing newline), regardless of where the cursor is on the line.  Then, &lt;code&gt;p&lt;/code&gt; puts that line (with its newline) as a new line after the current line, and &lt;code&gt;P&lt;/code&gt; puts it above the current line, again regardless of where your cursor is at the moment.  (It also jumps the cursor to the beginning of the text you just inserted, which is nice.)&lt;/p&gt;

&lt;p&gt;Emacs has &lt;code&gt;kill-whole-line&lt;/code&gt; (&lt;code&gt;C-S-Backspace&lt;/code&gt;) which is like Vim's &lt;code&gt;dd&lt;/code&gt;.  But I didn't find an equivalent of &lt;code&gt;p&lt;/code&gt; and &lt;code&gt;P&lt;/code&gt;.  So here's my version:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun yank-with-newline ()
  &quot;Yank, appending a newline if the yanked text doesn't end with one.&quot;
  (yank)
  (when (not (string-match &quot;\n$&quot; (current-kill 0)))
    (newline-and-indent)))

(defun yank-as-line-above ()
  &quot;Yank text as a new line above the current line.

Also moves point to the beginning of the text you just yanked.&quot;
  (interactive)
  (let ((lnum (line-number-at-pos (point))))
    (beginning-of-line)
    (yank-with-newline)
    (goto-line lnum)))

(defun yank-as-line-below ()
  &quot;Yank text as a new line below the current line.

Also moves point to the beginning of the text you just yanked.&quot;
  (interactive)
  (let* ((lnum (line-number-at-pos (point)))
         (lnum (if (eobp) lnum (1+ lnum))))
    (if (and (eobp) (not (bolp)))
        (newline-and-indent)
      (forward-line 1))
    (yank-with-newline)
    (goto-line lnum)))

(global-set-key &quot;\M-P&quot; 'yank-as-line-above)
(global-set-key &quot;\M-p&quot; 'yank-as-line-below)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just one more step along the path to Vimmify my Emacs setup.  Emacs has some weird edge cases because you can move the cursor one &quot;line&quot; past the last real line in the file.  But I think I worked out something comfortable for myself.&lt;/p&gt;

&lt;p&gt;PS: I've written about this before, but if you use &lt;code&gt;C-S-Backspace&lt;/code&gt; a lot in Emacs on Linux, I highly recommend putting this into your X11 config:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Option &quot;DontZap&quot; &quot;True&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's really easy to mix up &lt;code&gt;C-S-Backspace&lt;/code&gt; and &lt;code&gt;C-M-Backspace&lt;/code&gt; (the latter of which kills your X server).  It's not fun to mix those up.  Not fun at all.&lt;/p&gt;

&lt;p&gt;PPS: &lt;a href=&quot;http://stackoverflow.com/questions/2173324/emacs-equivalents-of-vims-dd-o-o&quot;&gt;This thread on Stack Overflow&lt;/a&gt; has some Emacs equivalents of Vim's &lt;code&gt;o&lt;/code&gt; and &lt;code&gt;O&lt;/code&gt; which are pretty nice too.&lt;/p&gt;</description></item><item><title>Vim vs. Emacs: Indenting text before copying</title><link>http://briancarper.net/blog/vim-vs-emacs-indenting-text-before-copying</link><guid>http://briancarper.net/blog/vim-vs-emacs-indenting-text-before-copying</guid><pubDate>Thu, 13 May 2010 16:21:27 -0700</pubDate><description>&lt;p&gt;I use Markdown on my blog for posts and comments, and I post at other sites that use Markdown (e.g. &lt;a href=&quot;http://stackoverflow.com&quot;&gt;Stack Overflow&lt;/a&gt;).  In Markdown, text indented four spaces is displayed as code, in &lt;code&gt;pre&lt;/code&gt; tags.  &lt;/p&gt;

&lt;p&gt;I find myself often writing code in Vim or Emacs and needing to copy/paste it into a browser in a Markdown-suitable way.it back.  This is easy to do in Vim and Emacs, only a few keystrokes.  But &quot;a few&quot; is still greater than &quot;one&quot;, so the heck with that.  Let's script it.&lt;/p&gt;

&lt;h1&gt;Vim version&lt;/h1&gt;

&lt;p&gt;This keymapping in Vim will do it all for me:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;vmap &amp;lt;Leader&amp;gt;y :s/^/    /&amp;lt;CR&amp;gt;gv&quot;+ygv:s/^    //&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One clumsy thing about Vim is needing to restore the previous visual selection after each regex-replacement.  I could use the marks &lt;code&gt;'&amp;lt;&lt;/code&gt; and &lt;code&gt;'&amp;gt;&lt;/code&gt; as ranges to &lt;code&gt;:s&lt;/code&gt; instead, but that's more typing than simply doing &lt;code&gt;gv&lt;/code&gt; in the mapping.  Copying to the system clipboard is easy because Vim has a register &lt;code&gt;&quot;+&lt;/code&gt; for that purpose.&lt;/p&gt;

&lt;p&gt;This took me maybe 45 seconds to write, probably due to being pretty familiar with Vim already.  But in Vim, mappings are easy.  You just type the characters that you'd type if you were doing it manually.&lt;/p&gt;

&lt;h1&gt;Emacs version&lt;/h1&gt;

&lt;p&gt;Trying to do the same in Emacs was painful.  My &lt;em&gt;Emacs-fu&lt;/em&gt; is sorely inadequate, compared to my &lt;em&gt;Vim-jitsu&lt;/em&gt;.  This seems to work, but ugh:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;;; adapted from http://www.emacswiki.org/emacs/.emacs-ChristianRovner.el
(defun expand-region-linewise ()
  (interactive)
  (let ((start (region-beginning))
        (end (region-end)))
   (goto-char start)
   (beginning-of-line)
   (set-mark (point))
   (goto-char end)
   (unless (bolp) (end-of-line))))

(defun markdown-copy ()
  (interactive)
  (save-window-excursion
   (save-excursion
     (save-restriction
       (expand-region-linewise)
       (narrow-to-region (region-beginning) (region-end))
       (goto-char (point-min))
       (replace-regexp &quot;^&quot; &quot;    &quot;)
       (clipboard-kill-ring-save (point-min) (point-max))
       (goto-char (point-min))
       (replace-regexp &quot;^    &quot; &quot;&quot;)))))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Writing this involved a long journey through the Emacs documentation.&lt;/p&gt;

&lt;p&gt;One difficulty was getting Emacs to play friendly with my fat-fingered region-marking.  I don't always highlight from the beginning of the first line to the end of the last.  That's why Vim's visual-line mode is awesome; the cursor can be anywhere on the line, it still selects the whole line.  The handy function above (found on the Emacs wiki) takes care of that.  I don't know how long it would've taken me to come up with that on my own.&lt;/p&gt;

&lt;p&gt;Then it was a matter of rooting through millions of Emacs functions until I found the ones that move the point around and copy text to the clipboard.  Along the way I discovered the wonders of &quot;narrowing&quot;, which limits Emacs to work on some region of text, and all those macros to undo the messes I make while moving around.&lt;/p&gt;

&lt;p&gt;Maybe I could've done this with an Emacs keyboard macro, and then called &lt;code&gt;apply-macro-to-region-lines&lt;/code&gt;.  And maybe I could use &lt;code&gt;append-next-kill&lt;/code&gt; to build up the indented text one line at a time.  But my efforts to do this or anything like it failed horribly.&lt;/p&gt;

&lt;p&gt;In any case I thought it was an interesting comparison.  Improvements to either version are welcome.&lt;/p&gt;

&lt;p&gt;EDIT: This works too (thanks Holger Durer):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defun markdown-copy ()
  (interactive)
  (save-excursion
    (expand-region-linewise)
    (indent-rigidly (region-beginning) (region-end) 4)
    (clipboard-kill-ring-save (region-beginning) (region-end))
    (indent-rigidly (region-beginning) (region-end) -4)))
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Review: Hacking Vim 7.2</title><link>http://briancarper.net/blog/review-hacking-vim-72</link><guid>http://briancarper.net/blog/review-hacking-vim-72</guid><pubDate>Fri, 07 May 2010 16:30:44 -0700</pubDate><description>&lt;p&gt;Vim is an open-source text editor with a power and flexibility matched only by the steepness of its learning curve. As the author of this book states, &quot;Vim Can Do Everything&quot;; but configuring it to do so is sometimes daunting. &lt;a href=&quot;https://www.packtpub.com/hacking-vim-7-2/book&quot;&gt;Hacking Vim 7.2&lt;/a&gt; aims to help the average Vimmer get the most out of customizing Vim, for fun and productivity.&lt;/p&gt;

&lt;!--more Read the full review--&gt;

&lt;p&gt;Vim has an overwhelming number of features. Its built-in help system and documentation are comprehensive and easy to navigate once you know what you're looking for, but knowing where to start is sometimes very difficult. The best you can hope for in a book is a broad outline to point the way toward features that you didn't know much about. Hacking Vim 7.2 achieves this goal.&lt;/p&gt;

&lt;p&gt;No topic is covered in nearly the depth you'll find in the official documentation (or even on the &lt;a href=&quot;https://www.packtpub.com/hacking-vim-7-2/book&quot;&gt;Vim Wiki&lt;/a&gt;), but every topic is covered in enough detail to let you know that a feature exists and to point you in the right direction to begin using it. Most helpfully, throughout the book are references to things to look up in Vim's help system, as well as links to various relevant scripts on &lt;a href=&quot;http://www.vim.org/scripts/&quot;&gt;http://www.vim.org/scripts/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is not a book for an absolute Vim beginner; some familiarity with Vim is assumed. And for a Vim fanatic, much of the material may be common knowledge for you already. But any seasoned Vimmer will tell you that there are always things to learn about this editor, and I think nearly everyone will learn something from this book. For someone who uses Vim and is looking to master it, this book is a great starting point, though you'll still need to dive into the official reference material to really cement your knowledge.&lt;/p&gt;

&lt;p&gt;The book starts on an odd note. Chapter 1 is a history of vi and the various vi clones released over the past couple decades. This information is interesting trivia and serves to give credit to programmers who paved the road to Vim, but it doesn't really help anyone &quot;hack Vim&quot; in any way. The book probably could've done without this chapter.&lt;/p&gt;

&lt;p&gt;Chapter 2 deals with customizing the overall look and feel of Vim. How and where to edit vimrc is covered, with brief attention given to cross-platform issues. It covers the basics (changing font faces and colors, customizing menus and toolbars), as well as pointing out some more obscure settings, like highlighting the cursor row and column (creating a kind of &quot;cursor crosshair&quot;), and using the match feature to highlight multiple search terms at once. This chapter is a good foundation for later chapters and a good introduction for anyone who has never edited their own vimrc.&lt;/p&gt;

&lt;p&gt;Chapter 3 is about text navigation. Sadly, the book doesn't go into as much detail on movement commands as I would've liked. The ability to move around and manipulate text quickly in Normal Mode by combining counts and motions/operators is one of Vim's most unique and powerful features, but it only gets a few paragraphs here.&lt;/p&gt;

&lt;p&gt;There are some interesting key mappings provided, for example how to move up and down between &quot;virtual&quot; lines when lines are soft-wrapped. Search is covered briefly, both plain text search and multi-file search via vimgrep, but there's little information about Vim's powerful regular expressions, which I thought was a shame. Marks are discussed, both normal &quot;hidden&quot; marks as well as visible &quot;signs&quot;, the latter being a feature I've never used.&lt;/p&gt;

&lt;p&gt;Chapter 4 is about &quot;production boosters&quot; and covers a wide variety of topics. Much of the chapter is devoted to &quot;templates&quot; and &quot;snippets&quot;, which allow you to build skeletons of commonly-used source code (with fill-in-the-blanks markers) that can be re-used when editing new files. A system for using these templates is built from scratch using Vim script, providing a clever and useful example of scripting in action.&lt;/p&gt;

&lt;p&gt;Auto-completion is covered in a lot of detail. Some custom key mappings are provided to help make &quot;omni-completion&quot; in Vim a bit easier to invoke. This chapter also very thoroughly covers Vim's multiple copy/paste registers and how they work. Recording and using macros, pointed out as one of Vim's more overlooked features, gets a good, lengthy example.&lt;/p&gt;

&lt;p&gt;&quot;Undo branching&quot; in Vim is wonderful, but difficult to understand. Chapter 4 gives a simple, step-by-step example of why it's useful and how it works. This chapter also briefly discusses folding, vimdiff, netrw (editing files remotely via SSH and other protocols), and ctags. There's lots of good stuff in this chapter and you're almost certain to learn something useful.&lt;/p&gt;

&lt;p&gt;Chapter 5 covers text formatting, both using built-in Vim commands and by piping text through external tools like par and tidy. A lot of space is devoted to using Vim to prettify plaintext, for example by centering titles on a line, adding ASCII-art dashes for headers and making bulleted lists. If you edit plaintext in Vim often, this is probably a great chapter, but I didn't find much use for most of it.&lt;/p&gt;

&lt;p&gt;For programmers, the book discusses the different indentation styles available in Vim and very briefly shows how to write your own indentation functions, and how to indent and reformat blocks or whole files of code all at once. &quot;Paste mode&quot; also gets a passing mention. Personally I think a programmer reading this book would've benefited from much more detail about Vim's myriad indentation and text-wrapping options and how they work together, as this can be one of the most frustrating parts of Vim to configure correctly.&lt;/p&gt;

&lt;p&gt;I had high hopes for Chapter 6 and 7, which deal with Vim scripting, but I was largely disappointed. Chapter 6 deals with scripting basics, and is essentially a beginner's language tutorial. It explains which variable types exist in Vim script, how if/then/else works, how for- and while-loops work, how function parameters operate, and so on, but anyone who knows a modern scripting language will learn these things quickly without much effort. There's also some basic information about how to write a syntax-highlighting script from scratch, but there's not really enough information to allow you write one for a real programming language.&lt;/p&gt;

&lt;p&gt;Chapter 7 is supposed to be about &quot;extended scripting&quot; topics, but serves largely as a style guide. It details how to structure a script to check for compiled-in features and Vim version number. This chapter touches briefly on using SID and PLUG to namespace functions, but the explanation and example left me puzzled. How to use the debugger and how to make Vimballs are both explored, and the book points out that you can use Perl, Python and Ruby to script Vim without going into much detail or giving solid examples.&lt;/p&gt;

&lt;p&gt;If you're looking for any advancing information on writing your own functions in Vim script, you're mostly out of luck here. Previous chapters in the book do include some useful and practical functions, but those functions are never really taken apart or explained in detail.&lt;/p&gt;

&lt;p&gt;Finally there are two appendices, one of which lists a bunch of games you can play in Vim (again this could've been left out of the book and I wouldn't have missed it), as well as examples of using Vim as a mail, chat, and Twitter client. There's also a feature-by-feature comparison of Vim to MS Visual Studio, showing that many of Visual Studio's abilities can be provided in Vim given the proper scripts. I thought it was an interesting demonstration that Vim really can do everything, just in case the reader had any doubts at this point. The last appendix is a style guide for keeping your vimrc clean, mostly via common sense and splitting your configuration into multiple files.&lt;/p&gt;

&lt;p&gt;Overall, stylistically the book is a bit dry and humorless, but it's easy enough to read and it gets its information across clearly. There were a few typos and editing errors, including a few rather glaring typos in some code examples, but overall the author seems extremely knowledgeable about Vim. The best parts of the book are where the author says &quot;this was useful to me personally, so here's how I do X&quot;. This book is clearly written by someone who uses Vim all the time, and most of the information provided is practical and immediately usable.&lt;/p&gt;

&lt;p&gt;I do feel the book should've gone into more detail in many areas. At 244 pages, the book is short and gives a rather shallow view of many of Vim's features. But the book hits all the right notes and leaves few features entirely unexplored.&lt;/p&gt;

&lt;p&gt;I'd recommend this book to any person who uses Vim and wants to explore features they may have been missing. There's nothing in this book you won't find in Vim's built-in documentation, but this book lays everything out in an easy-to-read format, and should serve as a good starting point to customizing and mastering Vim.&lt;/p&gt;</description></item><item><title>searchpairpos</title><link>http://briancarper.net/blog/searchpairpos</link><guid>http://briancarper.net/blog/searchpairpos</guid><pubDate>Thu, 20 Aug 2009 14:39:03 -0700</pubDate><description>&lt;p&gt;How did I live this long without knowing about &lt;code&gt;searchpairpos()&lt;/code&gt; in Vim?  I hate when I write a clumsy, slow reimplementation of something that already exists as a standard function. &lt;/p&gt;

&lt;p&gt;The only bad thing about Vim and Emacs both is that the feature list is about a mile and a half long (and that's a bad thing only in the sense of being an overwhelming amount of good things).  &lt;/p&gt;

&lt;p&gt;I have read almost the entire Vim manual at this point but there are corners that remain unexplored, and sometimes they contain treasure.  One thing I love doing is answering Vim questions on &lt;a href=&quot;http://stackoverflow.com/questions/tagged/vim&quot;&gt;Stack Overflow&lt;/a&gt; because most of the time I don't know the answer right off the bat, and so looking it up or figuring it out teaches me something new.&lt;/p&gt;

&lt;p&gt;Emacs is another story... Emacs remains a mystery to me in many ways, in spite of having used it for about a year now.  I very much plan to read the whole Emacs manual.  I've already read parts of it but I seem to have barely made a dent.  There are things I know should be simple to do or that there are already built-in options for, but I don't know how to do them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do I kill a word and also kill the whitespace immediately after it so it yanks properly later?  &lt;/li&gt;
&lt;li&gt;When I &lt;code&gt;kill-whole-line&lt;/code&gt; and paste that line elesewhere, I lose a newline and screw up indenting.  Sometimes it works how I expect and sometimes it doesn't.&lt;/li&gt;
&lt;li&gt;There are so many things I can do in Vim but can't in Emacs... marks, multiple registers, abbreviations, sensibly configured per-filetype indentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;etc. etc.  I know there are ways to do these things once I have time to just sit down and read the darned manual.  And learn elisp's syntax and semantics (which can't be harder than learning Vim script).  My &lt;code&gt;~/.vimrc&lt;/code&gt; is currently twice as long as my &lt;code&gt;~/.emacs&lt;/code&gt;, which says a lot.&lt;/p&gt;

&lt;p&gt;On a related note, I'm in the process of putting my Vim and Emacs configs on &lt;a href=&quot;http://github.com/briancarper/dotfiles/tree/master&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Vim and Emacs modelines</title><link>http://briancarper.net/blog/vim-and-emacs-modelines</link><guid>http://briancarper.net/blog/vim-and-emacs-modelines</guid><pubDate>Tue, 05 May 2009 18:22:47 -0700</pubDate><description>&lt;p&gt;Both Vim and Emacs have &quot;windows&quot;, resizeable panes inside the main app &quot;frame&quot;.  Windows are a very useful feature (aside from the ill-chosen name; should've been &quot;panes&quot; or something).  I find windows superior to tabs in my opinion; you can easily view more than one file at a time, view two files side-by-side for comparison, and such.  Both Vim and Emacs use the border under the window to show helpful information like the filename and editing mode such; this is called the &quot;status line&quot; or &quot;modeline&quot;.  Again, very handy.&lt;/p&gt;

&lt;p&gt;How do you set a nice custom modeline in Vim?  Here's my config from my .vimrc:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set statusline=%f\ %2*%m\ %1*%h%r%=[%{&amp;amp;encoding}\ %{&amp;amp;fileformat}\ %{strlen(&amp;amp;ft)?&amp;amp;ft:'none'}\ %{getfperm(@%)}]\ 0x%B\ %12.(%c:%l/%L%)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yikes!  What a mess.  It's just a big string with a bunch of special codes and literal characters all mixed up.  If you do &lt;code&gt;:h 'statusline'&lt;/code&gt; you can read about all the options.  That string is ugly though.&lt;/p&gt;

&lt;p&gt;Or so I thought, until I witnessed the trainwreck that is Emacs.  The documentation for Emacs' modeline comprises a &lt;a href=&quot;http://www.gnu.org/software/emacs/elisp/html_node/Mode-Line-Format.html&quot;&gt;small encyclopedia&lt;/a&gt;.  The configuration itself is spread across a couple dozen configuration variables.  This is the default value for &lt;strong&gt;just one&lt;/strong&gt; of them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(#(&quot;%[&quot; 0 2
   (help-echo &quot;Recursive edit, type C-M-c to get out&quot;))
 #(&quot;(&quot; 0 1
   (help-echo &quot;mouse-1: Select (drag to resize)\nmouse-2: Make current window occupy the whole frame\nmouse-3: Remove current window from display&quot;))
 (:propertize
  (&quot;&quot; mode-name)
  help-echo &quot;Major mode\nmouse-1: Display major mode menu\nmouse-2: Show help for major mode\nmouse-3: Toggle minor modes&quot; mouse-face mode-line-highlight local-map
  (keymap
   (mode-line keymap
          (down-mouse-3 keymap
                (abbrev-mode menu-item &quot;Abbrev (Abbrev)&quot; abbrev-mode :help &quot;Automatically expand abbreviations&quot; :button
                     (:toggle . abbrev-mode))
                (auto-fill-mode menu-item &quot;Auto fill (Fill)&quot; auto-fill-mode :help &quot;Automatically insert new lines&quot; :button
                        (:toggle . auto-fill-function))
                (auto-revert-mode menu-item &quot;Auto revert (ARev)&quot; auto-revert-mode :help &quot;Revert the buffer when the file on disk changes&quot; :button
                          (:toggle bound-and-true-p auto-revert-mode))
                (auto-revert-tail-mode menu-item &quot;Auto revert tail (Tail)&quot; auto-revert-tail-mode :help &quot;Revert the tail of the buffer when buffer grows&quot; :enable
                           (buffer-file-name)
                           :button
                           (:toggle bound-and-true-p auto-revert-tail-mode))
                (flyspell-mode menu-item &quot;Flyspell (Fly)&quot; flyspell-mode :help &quot;Spell checking on the fly&quot; :button
                       (:toggle bound-and-true-p flyspell-mode))
                (font-lock-mode menu-item &quot;Font Lock&quot; font-lock-mode :help &quot;Syntax coloring&quot; :button
                        (:toggle . font-lock-mode))
                (glasses-mode menu-item &quot;Glasses (o^o)&quot; glasses-mode :help &quot;Insert virtual separators to make long identifiers easy to read&quot; :button
                      (:toggle bound-and-true-p glasses-mode))
                (hide-ifdef-mode menu-item &quot;Hide ifdef (Ifdef)&quot; hide-ifdef-mode :help &quot;Show/Hide code within #ifdef constructs&quot; :button
                         (:toggle bound-and-true-p hide-ifdef-mode))
                (highlight-changes-mode menu-item &quot;Highlight changes (Chg)&quot; highlight-changes-mode :help &quot;Show changes in the buffer in a distinctive color&quot; :button
                            (:toggle bound-and-true-p highlight-changes-mode))
                (outline-minor-mode menu-item &quot;Outline (Outl)&quot; outline-minor-mode :help &quot;&quot; :button
                        (:toggle bound-and-true-p outline-minor-mode))
                (overwrite-mode menu-item &quot;Overwrite (Ovwrt)&quot; overwrite-mode :help &quot;Overwrite mode: typed characters replace existing text&quot; :button
                        (:toggle . overwrite-mode))
                &quot;Minor Modes&quot;)
          (mouse-2 . describe-mode)
          (down-mouse-1 menu-item &quot;Menu Bar&quot; ignore :filter
                (lambda
                  (_)
                  (mouse-menu-major-mode-map))))))
 (&quot;&quot; mode-line-process)
 (:propertize
  (&quot;&quot; minor-mode-alist)
  mouse-face mode-line-highlight help-echo &quot;Minor mode\nmouse-1: Display minor mode menu\nmouse-2: Show help for minor mode\nmouse-3: Toggle minor modes&quot; local-map
  (keymap
   (header-line keymap
        (down-mouse-3 keymap
                  (abbrev-mode menu-item &quot;Abbrev (Abbrev)&quot; abbrev-mode :help &quot;Automatically expand abbreviations&quot; :button
                       (:toggle . abbrev-mode))
                  (auto-fill-mode menu-item &quot;Auto fill (Fill)&quot; auto-fill-mode :help &quot;Automatically insert new lines&quot; :button
                          (:toggle . auto-fill-function))
                  (auto-revert-mode menu-item &quot;Auto revert (ARev)&quot; auto-revert-mode :help &quot;Revert the buffer when the file on disk changes&quot; :button
                        (:toggle bound-and-true-p auto-revert-mode))
                  (auto-revert-tail-mode menu-item &quot;Auto revert tail (Tail)&quot; auto-revert-tail-mode :help &quot;Revert the tail of the buffer when buffer grows&quot; :enable
                             (buffer-file-name)
                             :button
                             (:toggle bound-and-true-p auto-revert-tail-mode))
                  (flyspell-mode menu-item &quot;Flyspell (Fly)&quot; flyspell-mode :help &quot;Spell checking on the fly&quot; :button
                         (:toggle bound-and-true-p flyspell-mode))
                  (font-lock-mode menu-item &quot;Font Lock&quot; font-lock-mode :help &quot;Syntax coloring&quot; :button
                          (:toggle . font-lock-mode))
                  (glasses-mode menu-item &quot;Glasses (o^o)&quot; glasses-mode :help &quot;Insert virtual separators to make long identifiers easy to read&quot; :button
                        (:toggle bound-and-true-p glasses-mode))
                  (hide-ifdef-mode menu-item &quot;Hide ifdef (Ifdef)&quot; hide-ifdef-mode :help &quot;Show/Hide code within #ifdef constructs&quot; :button
                           (:toggle bound-and-true-p hide-ifdef-mode))
                  (highlight-changes-mode menu-item &quot;Highlight changes (Chg)&quot; highlight-changes-mode :help &quot;Show changes in the buffer in a distinctive color&quot; :button
                              (:toggle bound-and-true-p highlight-changes-mode))
                  (outline-minor-mode menu-item &quot;Outline (Outl)&quot; outline-minor-mode :help &quot;&quot; :button
                          (:toggle bound-and-true-p outline-minor-mode))
                  (overwrite-mode menu-item &quot;Overwrite (Ovwrt)&quot; overwrite-mode :help &quot;Overwrite mode: typed characters replace existing text&quot; :button
                          (:toggle . overwrite-mode))
                  &quot;Minor Modes&quot;))
   (mode-line keymap
          (down-mouse-3 keymap
                (abbrev-mode menu-item &quot;Abbrev (Abbrev)&quot; abbrev-mode :help &quot;Automatically expand abbreviations&quot; :button
                     (:toggle . abbrev-mode))
                (auto-fill-mode menu-item &quot;Auto fill (Fill)&quot; auto-fill-mode :help &quot;Automatically insert new lines&quot; :button
                        (:toggle . auto-fill-function))
                (auto-revert-mode menu-item &quot;Auto revert (ARev)&quot; auto-revert-mode :help &quot;Revert the buffer when the file on disk changes&quot; :button
                          (:toggle bound-and-true-p auto-revert-mode))
                (auto-revert-tail-mode menu-item &quot;Auto revert tail (Tail)&quot; auto-revert-tail-mode :help &quot;Revert the tail of the buffer when buffer grows&quot; :enable
                           (buffer-file-name)
                           :button
                           (:toggle bound-and-true-p auto-revert-tail-mode))
                (flyspell-mode menu-item &quot;Flyspell (Fly)&quot; flyspell-mode :help &quot;Spell checking on the fly&quot; :button
                       (:toggle bound-and-true-p flyspell-mode))
                (font-lock-mode menu-item &quot;Font Lock&quot; font-lock-mode :help &quot;Syntax coloring&quot; :button
                        (:toggle . font-lock-mode))
                (glasses-mode menu-item &quot;Glasses (o^o)&quot; glasses-mode :help &quot;Insert virtual separators to make long identifiers easy to read&quot; :button
                      (:toggle bound-and-true-p glasses-mode))
                (hide-ifdef-mode menu-item &quot;Hide ifdef (Ifdef)&quot; hide-ifdef-mode :help &quot;Show/Hide code within #ifdef constructs&quot; :button
                         (:toggle bound-and-true-p hide-ifdef-mode))
                (highlight-changes-mode menu-item &quot;Highlight changes (Chg)&quot; highlight-changes-mode :help &quot;Show changes in the buffer in a distinctive color&quot; :button
                            (:toggle bound-and-true-p highlight-changes-mode))
                (outline-minor-mode menu-item &quot;Outline (Outl)&quot; outline-minor-mode :help &quot;&quot; :button
                        (:toggle bound-and-true-p outline-minor-mode))
                (overwrite-mode menu-item &quot;Overwrite (Ovwrt)&quot; overwrite-mode :help &quot;Overwrite mode: typed characters replace existing text&quot; :button
                        (:toggle . overwrite-mode))
                &quot;Minor Modes&quot;)
          (mouse-2 . mode-line-minor-mode-help)
          (down-mouse-1 . mouse-minor-mode-menu))))
 #(&quot;%n&quot; 0 2
   (local-map
    (keymap
     (mode-line keymap
        (mouse-2 . mode-line-widen)))
    mouse-face mode-line-highlight help-echo &quot;mouse-2: Remove narrowing from the current buffer&quot;))
 #(&quot;)&quot; 0 1
   (help-echo &quot;mouse-1: Select (drag to resize)\nmouse-2: Make current window occupy the whole frame\nmouse-3: Remove current window from display&quot;))
 #(&quot;%]&quot; 0 2
   (help-echo &quot;Recursive edit, type C-M-c to get out&quot;))
 #(&quot;--&quot; 0 2
   (help-echo &quot;mouse-1: Select (drag to resize)\nmouse-2: Make current window occupy the whole frame\nmouse-3: Remove current window from display&quot;)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What the hell?&lt;/p&gt;

&lt;p&gt;Instead of a string, it's an s-expression, which is better, right?  Well no, it's still just a big construct with &lt;a href=&quot;http://www.gnu.org/software/emacs/elisp/html_node/Mode-Line-Data.html#Mode-Line-Data&quot;&gt;arbitrary meanings assigned to its contents&lt;/a&gt;.  Lists mean one thing, strings mean another thing (and those strings, like Vim's, can contain special escape sequences).  Symbols mean something else, symbols that are keywords mean something else, numbers mean something else, and so on.&lt;/p&gt;

&lt;p&gt;To decipher this I had to learn this mini-language.  And also learn about &quot;text properties&quot; and a bunch of elisp stuff.  It also required knowledge about a bunch of minor modes and how they tie into the modeline, all of which is essentially a bowl of spaghetti code.  And keymaps, and maps to control mouse click events and such.  Eventually I figured out that most of that crap is controlling tooltip text.&lt;/p&gt;

&lt;p&gt;If you do &lt;code&gt;M-x customize-apropos&lt;/code&gt; in Emacs and search for &quot;mode-line&quot;, you'll get a helpful list of all of the configuration values and their values.  (The default values contain literal tab characters, which you can't even type into the customize text fields without &lt;code&gt;C-q&lt;/code&gt;ing, because tab jumps you between fields.  Ughhhhhhh.)&lt;/p&gt;

&lt;p&gt;I gave up even trying to get Emacs to have all the helpful information my Vim modeline has.  Even deleting the default crap to pare this down to something readable took some effort.  This what I ended up with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(mode-line-format (quote (&quot;%e--[&quot; mode-line-buffer-identification &quot;]&quot; (vc-mode vc-mode) &quot;  &quot; mode-line-modes global-mode-string &quot; %-&quot;)))
(mode-line-in-non-selected-windows t)
(mode-line-modes (quote (&quot;%[&quot; &quot;(&quot; (:propertize (&quot;&quot; mode-name)) (&quot;&quot; mode-line-process) (:propertize (&quot;&quot; minor-mode-alist)) &quot;%n&quot; &quot;)&quot; &quot;%]&quot;)))
(mode-line ((((class color) (min-colors 88)) (:background &quot;#333333&quot; :foreground &quot;#bcbcbc&quot; :box (:line-width -1 :color &quot;#333333&quot;)))))
(mode-line-highlight ((((class color) (min-colors 88)) nil)))
(mode-line-inactive ((default (:inherit mode-line)) (((class color) (min-colors 88) (background dark)) (:foreground &quot;#8b8b8b&quot; :weight light))))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What does that mean?  Don't ask me, I can no longer read it.  If &lt;code&gt;customize&lt;/code&gt; hadn't produced a lot of that for me, I probably wouldn't have managed.  My favorite part is the four-deep nested list of lists of lists of lists for the colors.&lt;/p&gt;

&lt;p&gt;Verdict?  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Vim's modeline is less powerful than Emacs.  But who cares if you can't even read it to edit it?  Most of Emacs' modeline features are annoying.  (My motivation for editing this to begin with was to turn off all the mouse buttons and mini-menus and crap.)  &lt;/p&gt;

&lt;p&gt;Vim's status line is exactly configurable enough.  I don't want to build a small GUI app in my modeline.  I want it to show certain bits of information about the buffer, that's it.  Vim does this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Vim script is less elegant than elisp.   Or is it?  Vim's modeline is a custom DSL for formatting modelines.  It's hard to think of anything more concise.  Concision is a very good thing.  Emacs' version is more general, at the expense of horrid verbosity and unreadability.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vim's modeline is a string, which means you either write it literally, or you construct it by concatenating lots of other strings.  This is a faux pas, right?  It's like using &lt;code&gt;eval&lt;/code&gt; in Ruby or Perl.  It's fragile and error-prone.  Emacs uses a Lisp, with its macros and quoted lists and &lt;em&gt;code is data&lt;/em&gt; and so on.  &lt;/p&gt;

&lt;p&gt;But who cares?  In this case, a simple string is powerful enough.  I don't need a whole Turing-complete programming language to configure a modeline.  It's massive overkill and you pay a price for it.  The minute a human being is supposed to be keeping track that the second element in the 5-deep nested list means &quot;x&quot;, something has gone horribly wrong.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vim wins this round.&lt;/p&gt;</description></item><item><title>Vim regexes are awesome</title><link>http://briancarper.net/blog/vim-regexes-are-awesome</link><guid>http://briancarper.net/blog/vim-regexes-are-awesome</guid><pubDate>Sat, 18 Apr 2009 14:47:54 -0700</pubDate><description>&lt;p&gt;Two years ago I wrote about how &lt;a href=&quot;http://briancarper.net/blog/vim-regexes&quot;&gt;Vim's regexes were no fun&lt;/a&gt; compared to &lt;code&gt;:perldo&lt;/code&gt; and &lt;code&gt;:rubydo&lt;/code&gt;.  Turns out I was wrong, it was just a matter of &lt;a href=&quot;http://briancarper.net/blog/lisp-syntax-doesnt-suck&quot;&gt;not being used to them&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Vim's regexes are very good.  They have all of the good features of Perl/Ruby regexes, plus some extra features that don't make sense outside of a text editor, but are nonetheless very helpful in Vim.&lt;/p&gt;

&lt;p&gt;Here are a few of the neat things you can do.&lt;/p&gt;

&lt;h1&gt;Very magic&lt;/h1&gt;

&lt;p&gt;Vim regexes are inconsistent when it comes to what needs to be backslash-escaped and what doesn't, which is the one bad thing.  But Vim lets you put &lt;code&gt;\v&lt;/code&gt; to make everything suddenly consistent: everything except letters, numbers and underscores becomes &quot;special&quot; unless backslash-escaped.&lt;/p&gt;

&lt;p&gt;Without &lt;code&gt;\v&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%s/^\%(foo\)\{1,3}\(.\+\)bar$/\1/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With &lt;code&gt;\v&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%s/\v^%(foo){1,3}(.+)bar$/\1/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Far easier to read.  Along with &lt;code&gt;\c&lt;/code&gt; to turn on and off case sensitivity, these are good options to make a habit of prepending to regexes when needed.  It eventually becomes second-nature.  See also &lt;code&gt;:h /\v&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;Spanning newlines&lt;/h1&gt;

&lt;p&gt;One thing that &lt;code&gt;:perldo&lt;/code&gt; and &lt;code&gt;:rubydo&lt;/code&gt; can't do is span newlines; you can't combine two lines and you can't break one line into two.&lt;/p&gt;

&lt;p&gt;But Vim's regexes can span newlines if you use &lt;code&gt;\_.&lt;/code&gt; instead of &lt;code&gt;.&lt;/code&gt;.  I find this to be a lot more aesthetically pleasing than Perl's horrible &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;m&lt;/code&gt; modifiers tacked onto the end of a regex.  e.g. this strips &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags from a text document.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%s@&amp;lt;body&amp;gt;\v(\_.+)\V&amp;lt;/body&amp;gt;@\1@
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Note: in real life, never use a regex to parse HTML or XML.  Down that path lies madness.  The above is OK because I'd expect only one &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag to appear in any document.)&lt;/p&gt;

&lt;p&gt;(Note^2: being able to turn on and off magic in the middle of a regex is awfully helpful.)&lt;/p&gt;

&lt;p&gt;(Note^4: You can use arbitrary delimiters like &lt;code&gt;@&lt;/code&gt; for the regex, which is useful if your pattern includes literal &lt;code&gt;/&lt;/code&gt;'s.)&lt;/p&gt;

&lt;p&gt;See also &lt;code&gt;:h \_.&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;&lt;code&gt;\zs&lt;/code&gt;&lt;/h1&gt;

&lt;p&gt;Vim lets you demand that some text match, but ignore that text when it comes to the substitution part.  This is handy for certain specific kinds of regexes.  Normally if you want to match some text and then leave it alone in the substitution, you have to capture it and then put it back manually; &lt;code&gt;\zs&lt;/code&gt; lets you avoid this. &lt;/p&gt;

&lt;p&gt;Say you want to chop some text off the end of a line, but leave the rest of the line alone.  Normally you'd have to do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%s/\v^(foobar)(baz)/\1/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to put the &lt;code&gt;foobar&lt;/code&gt; back.  Of course you can also use a zero-width lookbehind assertion:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%s/\v(^foobar)@&amp;lt;=baz//
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But that's even more line-noise.  This is the easiest way:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%s/^foobar\zsbaz//
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See &lt;code&gt;:h /\zs&lt;/code&gt;.  (And &lt;code&gt;:h /\@&amp;lt;=&lt;/code&gt; if you're so inclined.)&lt;/p&gt;

&lt;h1&gt;Expressions&lt;/h1&gt;

&lt;p&gt;Using &lt;code&gt;\=&lt;/code&gt;, you can put arbitrary expressions on the right side of a regex substitution.  For example say you have this text:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;~/foo ~/bar
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:%s/\v(\S+)/\=expand(submatch(1))/g
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You end up with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/home/user/foo /home/user/bar
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because you can also call your own user-defined functions in the expression part, this can end up being pretty powerful.  For example it can be used to &lt;a href=&quot;http://vim.wikia.com/wiki/Substitute_with_incrementing_numbers&quot;&gt;insert incrementing numbers&lt;/a&gt; into arbitrary places in your text.  See &lt;code&gt;:h sub-replace-\=&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;And so on&lt;/h1&gt;

&lt;p&gt;Read &lt;code&gt;:h regexp&lt;/code&gt; if you haven't already. Tons of other features in there that can make your life easy if you manage to internalize them.  It is difficult to get used to Vim's funky syntax if you're very familiar with Perl/Ruby-style regexes, but I think it's worth it.  Only took me two years!  (OK, more like a couple days of concerted effort after a year-and-a-half delay.)&lt;/p&gt;</description></item><item><title>A Sad, Dark Day</title><link>http://briancarper.net/blog/a-sad-dark-day</link><guid>http://briancarper.net/blog/a-sad-dark-day</guid><pubDate>Mon, 13 Apr 2009 01:27:12 -0700</pubDate><description>&lt;p&gt;Today was a terrible day.  I found myself subconsciously trying to use Emacs keystrokes in Vim.  I feel dirty.  I took a bath but it won't come clean.  : (&lt;/p&gt;

&lt;p&gt;It just goes to show that &lt;a href=&quot;/blog/lisp-syntax-doesnt-suck&quot;&gt;you can get used to anything&lt;/a&gt; if you do it often enough.  Emacs still drives me up the wall but maybe I've achieved a critical mass of enough custom keybindings to let me tolerate it.&lt;/p&gt;

&lt;p&gt;Aside from &lt;code&gt;paredit&lt;/code&gt;, which has no equal even in Vim, Emacs does have some vaguely non-sucky features.  &lt;code&gt;hi-lock&lt;/code&gt; is pretty nice (Vim has an equivalent of course).  Once I learned a few of the shortcuts for &lt;a href=&quot;http://github.com/tsgates/git-emacs/tree/master&quot;&gt;git-emacs&lt;/a&gt; I actually found myself using Git much more effectively.  Having to drop into a shell to type Git commands is just enough of a disruption to prevent me from doing it often enough.  I never got the hang of any version control library in Vim.&lt;/p&gt;

&lt;p&gt;I'm almost even getting used to the Emacs buffer model.  I find myself &lt;code&gt;C-x b&lt;/code&gt;ing and flipping back and forth between buffers by name, rather than my Vim practice of opening buffers in certain carefully-placed windows and leaving them there.&lt;/p&gt;

&lt;p&gt;On the subject of typing, I broke down finally and ordered a &lt;a href=&quot;http://pckeyboards.stores.yahoo.net/customizer.html&quot;&gt;Unicomp Customizer 104 keyboard&lt;/a&gt;.  I've heard too many hackers say that the old IBM clicky keyboards are good for typing.  It should arrive Tuesday, and I'm a lot more excited than anyone should be over a keyboard.  &lt;/p&gt;

&lt;p&gt;Expect a keyboard review.  Try to contain your excitement until then.  I know it'll be hard.&lt;/p&gt;</description></item><item><title>Vim cterm colors</title><link>http://briancarper.net/blog/vim-256-cterm</link><guid>http://briancarper.net/blog/vim-256-cterm</guid><pubDate>Sat, 04 Apr 2009 12:48:06 -0700</pubDate><description>&lt;p&gt;Note to self.  Vim color schemes that only set &lt;code&gt;cterm&lt;/code&gt; colors don't work unless you &lt;code&gt;export TERM=xterm-256color&lt;/code&gt; in your terminal emulator.  Konsole in KDE4 seems to default to plain &lt;code&gt;xterm&lt;/code&gt;.  Took me a half hour to figure out why my color scheme wasn't working in Konsole.&lt;/p&gt;</description></item><item><title>Wordpress DB migration - encoding fun</title><link>http://briancarper.net/blog/wordpress-db-migration-encoding-fun</link><guid>http://briancarper.net/blog/wordpress-db-migration-encoding-fun</guid><pubDate>Sat, 07 Mar 2009 14:28:34 -0800</pubDate><description>&lt;p&gt;Note to self.  Using &lt;code&gt;mysqldump&lt;/code&gt; to dump a table with &lt;code&gt;latin1&lt;/code&gt; encoding and then editing it and importing it into a second DB with &lt;code&gt;utf8&lt;/code&gt; encoding isn't a lot of fun.&lt;/p&gt;

&lt;p&gt;I found some &lt;a href=&quot;http://hexmen.com/blog/2008/07/fixing-mysqldump-character-encoding-in-vim/&quot;&gt;instructions for properly opening mysqldump files in Vim&lt;/a&gt; with the proper encoding.  I'm still somewhat confused what the difference between &lt;code&gt;enc&lt;/code&gt; and &lt;code&gt;fenc&lt;/code&gt; is in Vim but this worked.  Eventually.&lt;/p&gt;

&lt;p&gt;Also during the hour of banging my head on my keyboard, somewhere I read that using shell redirects to dump the &lt;code&gt;mysqldump&lt;/code&gt; output to a file is sometimes a bad idea if there are multibyte characters in it, and instead you should use the &lt;code&gt;-r&lt;/code&gt; flag to specify an output file.  Could be true, I don't remember.&lt;/p&gt;</description></item><item><title>Juvenile?</title><link>http://briancarper.net/blog/juvenile</link><guid>http://briancarper.net/blog/juvenile</guid><pubDate>Wed, 25 Feb 2009 17:27:44 -0800</pubDate><description>&lt;p&gt;I get a cheap thrill out of editing my ~/.emacs file in Vim.&lt;/p&gt;</description></item><item><title>Vim - escaping quotes</title><link>http://briancarper.net/blog/vim-escaping-quotes</link><guid>http://briancarper.net/blog/vim-escaping-quotes</guid><pubDate>Thu, 16 Oct 2008 16:52:25 -0700</pubDate><description>&lt;p&gt;This Vim regex escapes (by doubling) every double-quote on a line except the first one, last one, or any that are already doubled:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:s/\v(^[^&quot;]*)@&amp;lt;!&quot;@&amp;lt;!&quot;&quot;@!([^&quot;]*$)@!/&quot;&quot;/g
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sometimes I kind of understand that old humorous quote: &lt;em&gt;Some people, when confronted with a problem, think &quot;I know, I'll use regular expressions.&quot; Now they have two problems.&lt;/em&gt;  But regexes are still pretty darn useful.  I can't imagine a good replacement for them that wouldn't have all the same problems with escaping and magic characters and whatnot, without the replacement being so verbose that no one would ever use them.&lt;/p&gt;</description></item><item><title>Vim "Align" plugin</title><link>http://briancarper.net/blog/vim-align-plugin</link><guid>http://briancarper.net/blog/vim-align-plugin</guid><pubDate>Mon, 13 Oct 2008 10:22:15 -0700</pubDate><description>&lt;p&gt;There are some Vim plugins I don't know how I lived without before I found them.  One I found just last week is &lt;a href=&quot;http://www.vim.org/scripts/script.php?script_id=294&quot;&gt;Align&lt;/a&gt;, which turns this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@label = Label.new(@frame, -1, &quot;Choose an option:&quot;, DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER)
@selector = ListBox.new(@panel, -1, DEFAULT_POSITION, DEFAULT_SIZE, [], LB_SINGLE)
@button = Button.new(@frame, -1, 'OK')
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;into this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@label    = Label.new  (@frame, -1, &quot;Choose an option:&quot;, DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER)
@selector = ListBox.new(@panel, -1, DEFAULT_POSITION   , DEFAULT_SIZE    , []          , LB_SINGLE)
@button   = Button.new (@frame, -1, &quot;OK&quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These mappings are helpful to quickly align some visually-selected lines of code by comma, left paren or equal sign:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;vmap &amp;lt;silent&amp;gt; &amp;lt;Leader&amp;gt;i= &amp;lt;ESC&amp;gt;:AlignPush&amp;lt;CR&amp;gt;:AlignCtrl lp1P1&amp;lt;CR&amp;gt;:'&amp;lt;,'&amp;gt;Align =&amp;lt;CR&amp;gt;:AlignPop&amp;lt;CR&amp;gt;
vmap &amp;lt;silent&amp;gt; &amp;lt;Leader&amp;gt;i, &amp;lt;ESC&amp;gt;:AlignPush&amp;lt;CR&amp;gt;:AlignCtrl lp0P1&amp;lt;CR&amp;gt;:'&amp;lt;,'&amp;gt;Align ,&amp;lt;CR&amp;gt;:AlignPop&amp;lt;CR&amp;gt;
vmap &amp;lt;silent&amp;gt; &amp;lt;Leader&amp;gt;i( &amp;lt;ESC&amp;gt;:AlignPush&amp;lt;CR&amp;gt;:AlignCtrl lp0P0&amp;lt;CR&amp;gt;:'&amp;lt;,'&amp;gt;Align (&amp;lt;CR&amp;gt;:AlignPop&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Emacs annoyance #448,546</title><link>http://briancarper.net/blog/emacs-annoyance-448546</link><guid>http://briancarper.net/blog/emacs-annoyance-448546</guid><pubDate>Sun, 12 Oct 2008 15:04:12 -0700</pubDate><description>&lt;p&gt;From the &lt;a href=&quot;http://www.gnu.org/software/emacs/manual/html_node/emacs/File-Names.html&quot;&gt;Emacs docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Each buffer has a default directory which is normally the same as the directory of the file visited in that buffer. When you enter a file name without a directory, the default directory is used. If you specify a directory in a relative fashion, with a name that does not start with a slash, it is interpreted with respect to the default directory. The default directory is kept in the variable default-directory, which has a separate value in every buffer. &lt;/p&gt;
  
  &lt;p&gt;The command M-x pwd displays the current buffer's default directory, and the command M-x cd sets it (to a value read using the minibuffer). A buffer's default directory changes only when the cd command is used. A file-visiting buffer's default directory is initialized to the directory of the file it visits.  If you create a buffer with C-x b, its default directory is copied from that of the buffer that was current at the time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is extremely annoying.  Vim leaves my working directory the hell alone, why doesn't Emacs?  Vim lets you set a global working directory, and selectively (and explicitly) change it on a per-buffer basis.  This is what I want.&lt;/p&gt;

&lt;p&gt;But in Emacs, every time you open a file, the working directory automatically changes to the directory of that file.  If you have multiple files open in Emacs (which of course you do), every time you move the cursor between windows, or look at a new file in your current window, your working directory just changed out from under you.&lt;/p&gt;

&lt;p&gt;So say you open some files.  Then you want to start SLIME.  So you &lt;code&gt;C-x 2&lt;/code&gt; to split and open a new window, in which to start SLIME.  Except (annoyance #448,547) Emacs doesn't open a window with a new BLANK file, as Vim sanely does via &lt;code&gt;CTRL-W n&lt;/code&gt;; instead it puts the file you're looking at into BOTH windows, which is absolutely never what you want.  As a result, the working directory of BOTH windows is the directory of whatever file you were looking at.   So every time you start SLIME, you have to make sure you &lt;code&gt;M-x cd&lt;/code&gt; back to the proper working directory first, because otherwise your Lisp process is randomly going to start in the wrong directory.&lt;/p&gt;

&lt;p&gt;But you can change the directory of the SLIME buffer after you start SLIME.  Just &lt;code&gt;M-x cd&lt;/code&gt; or &lt;code&gt;,cd&lt;/code&gt;.  Except if you're unlucky enough to be using SLIME for Clojure, which may have set its classpath based on its working directory when you started it.  In that case you have to restart SLIME.  &lt;/p&gt;

&lt;p&gt;But if you kill SLIME, Emacs (annoyance #448,548) jams another random file into the window where SLIME just was.  So your working directory just changed again!  Or did it?  Depends what Emacs decided to put into your window.  You may think that, while SLIME is running, &lt;code&gt;M-x cd&lt;/code&gt; and/or &lt;code&gt;,cd&lt;/code&gt; and then &lt;code&gt;,restart-inferior-lisp&lt;/code&gt; may do what you want, but you would be wrong; it always reverts back to the original working directory from when SLIME was first started.&lt;/p&gt;

&lt;p&gt;Lost?  Confused?  tl;dr?  Welcome to Emacs.  So now I'm looking through the encyclopedic tangled mess of Emacs documentation to try to figure out how to get Emacs not to change my working directory, ever, unless I say so.  This is hindered as always by (annoyance #448,549) Emacs' arcane and non-standard terminology.  So far, I have committed to memory that &quot;current directory&quot;/&quot;working directory&quot; in Emacs is instead called &quot;default directory&quot;.  And you don't open files, you &quot;visit&quot; them.  Command line?  No, &quot;minibuffer&quot;.&lt;/p&gt;</description></item><item><title>Copy/paste in Linux: Eureka</title><link>http://briancarper.net/blog/copypaste-in-linux-eureka</link><guid>http://briancarper.net/blog/copypaste-in-linux-eureka</guid><pubDate>Tue, 16 Sep 2008 17:42:53 -0700</pubDate><description>&lt;p&gt;It's been a few years since I officially grasped Linux's (well, X Windows') weird concept of copying and pasting, with its multiple discrete copy/paste methods: the highlight + middle click version, and &quot;clipboard&quot; Edit-&gt;Copy&quot; + &quot;Edit-&gt;Paste version.&lt;/p&gt;

&lt;p&gt;But once in a blue moon, copying and pasting in X still surprises me.  Try this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Firefox and a text editor.  I'm trying with Vim.&lt;/li&gt;
&lt;li&gt;Highlight some text in Firefox.&lt;/li&gt;
&lt;li&gt;Middle-click paste it into the editor.  The highlighted text is pasted, as expected.&lt;/li&gt;
&lt;li&gt;Close Firefox.&lt;/li&gt;
&lt;li&gt;Middle-click into the editor again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Can you guess what happens at the end?  If you said &quot;Some random text from another application and/or nothing at all is pasted rather than the stuff from Firefox&quot;, you're right!&lt;/p&gt;

&lt;p&gt;But today I read &lt;a href=&quot;http://www.jwz.org/doc/x-cut-and-paste.html&quot;&gt;this article&lt;/a&gt; on jwz.org and finally understood how copy/paste works in X.  Highlighting text doesn't copy anything, it just announces to the world &quot;If any applications want to middle-click paste something, come ask me for it&quot;.  So if you close the application you wanted to paste text from before you actually do the pasting, the application isn't around to give you the text you wanted any more, so you can't get it.  The Edit-&gt;Copy / Edit-&gt;Paste version of copy/paste behaves the same way.  You can't &quot;Copy&quot;, close app, &quot;Paste&quot;.&lt;/p&gt;

&lt;p&gt;Note, this is different from how MS Windows works.  When you copy some text in Windows it really copies to another location.  You can close the app and still paste away.  But Windows has a different (inconsistent) behavior when copy/pasting files in Explorer.  There, it behaves like X in Linux: if right click a file and &quot;Copy&quot;, it doesn't actually do anything with the data until you paste.  If you right-click, &quot;Copy&quot;, delete the file, &quot;Paste&quot;, you don't get an error until you try to Paste. &lt;/p&gt;

&lt;p&gt;In Vim in Linux, the &lt;code&gt;&quot;*&lt;/code&gt; register lets you access the &quot;primary selection&quot; (highlight / middle click selection), and the &lt;code&gt;&quot;+&lt;/code&gt; register lets you access the clipboard.  &lt;/p&gt;

&lt;p&gt;In Vim in Windows, &lt;code&gt;&quot;*&lt;/code&gt; and &lt;code&gt;&quot;+&lt;/code&gt; do the same thing, and use the clipboard.&lt;/p&gt;</description></item><item><title>Vim + screen + REPL = win</title><link>http://briancarper.net/blog/vim-screen-repl-win</link><guid>http://briancarper.net/blog/vim-screen-repl-win</guid><pubDate>Sat, 06 Sep 2008 00:36:48 -0700</pubDate><description>&lt;p&gt;Via the &lt;a href=&quot;http://en.wikibooks.org/wiki/Clojure_Programming&quot;&gt;Clojure wiki&lt;/a&gt; I found a &lt;a href=&quot;http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/&quot;&gt;great page&lt;/a&gt; describing how you can use GNU screen and some Vim magic to let Vim play nicely with an interactive commandline program like a Common Lisp REPL, Ruby's &lt;code&gt;irb&lt;/code&gt;, or Python's, well, &lt;code&gt;python&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That page is a very stripped-down and simpler version of what &lt;a href=&quot;http://mikael.jansson.be/hacking/limp&quot;&gt;Limp&lt;/a&gt; does for Vim+Lisp.  But Jonathan Palardy's version has the benefit of being so simple that you can set it up yourself manually in a second or two.  I still have never gotten Limp to work quite right and I don't have the time to debug a big mess of Vim script.&lt;/p&gt;

&lt;p&gt;The idea is to start up a named screen session via e.g. &lt;code&gt;screen -S foo -t bar&lt;/code&gt;, then start an irb session (or whatever) in there, and then in Vim you can simply yank some text into a named register and send it off to screen via a system call.  Download &lt;a href=&quot;http://s3.amazonaws.com/mps/slime.vim&quot;&gt;Jonathan's code&lt;/a&gt; and see.&lt;/p&gt;

&lt;p&gt;It's not a full-blown SLIME; it doesn't have tab-completion or weird interactive debugging windows or such bullcrap.  It doesn't capture the output of your command and feed it back into your Vim buffer.  But hey, it's pretty good for something you can throw together in 2 minutes, and it works.&lt;/p&gt;

&lt;p&gt;So there goes my last reason to ever use Emacs.  Good riddance, I must say.  &lt;/p&gt;

&lt;p&gt;Honestly, Emacs just frustrates the living hell out of me.  Oh how I tried to like it.  I really did.  I've used it on and off constantly over the past year.  I have Emacs shortcuts written all over the whiteboard in my office.  But its braindead window management, its terrible broken undo/redo system, its finger-crippling key-chord combos, its lack of features I need (like line numbering), its reliance on broken 3rd-party elisp hack scripts for things Vim has built in (like line numbering!), its ugly fonts and GUI elements, and so on and so forth.  Vim is such a joy in comparison.&lt;/p&gt;</description></item><item><title>Stupid Vim trick (and mental illness)</title><link>http://briancarper.net/blog/stupid-vim-trick-and-mental-illness</link><guid>http://briancarper.net/blog/stupid-vim-trick-and-mental-illness</guid><pubDate>Thu, 10 Jul 2008 16:48:07 -0700</pubDate><description>&lt;p&gt;The OS on my first computer was Windows 3.1, and I lived with Windows 95/98/ME for a long time.  When you live their formative years in this kind of environment, you develop an obsessive need to save your work all the time, because at any moment, the program you were using could crash.  With Vim, a save is just a &lt;code&gt;:w&lt;/code&gt; away.  I hit that combination so often it's a wonder I haven't worn a hole through my w key yet.  It takes no effort or thinking at this point, just a quick reflex flick of the wrist.&lt;/p&gt;

&lt;p&gt;Did you ever wonder just how often you save your work in a given day?  I wondered, so I put this into ~/.vimrc:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cabbrev w &amp;lt;c-r&amp;gt;=(getcmdtype()==':' &amp;amp;&amp;amp; getcmdpos()==1 ? 'W' : 'w')&amp;lt;CR&amp;gt;
command! -nargs=* W :execute(&quot;silent !echo &quot; . strftime(&quot;%Y-%m-%d %H:%M:%S&quot;) . &quot; &amp;gt;&amp;gt; ~/timestamps&quot;)|w &amp;lt;args&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now every time I do &lt;code&gt;:w&lt;/code&gt;, it will append a timestamp to a text file.  It's not quite perfect and :w won't work right in certain cases but it was good enough for a quick hack.&lt;/p&gt;

&lt;p&gt;I let Vim go like this for one whole day at work.  I got in a good six and a half hours of coding on Tuesday (keeping in mind that I was using other programs all day too, messing with our DB, running and debugging the script I was writing, responding to emails, and so on).&lt;/p&gt;

&lt;p&gt;It turns out I hit :w 356 times that day.    Here's a chart of saves per hour.  &lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/random/saves-per-hour.png&quot; alt=&quot;Saves per hour&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Clearly either my productivity or my data-loss paranoia increases as the day progresses.  I think I got up to make a cup of tea at around 2:00 so that may explain the fall-off.  And the last hour isn't quite a full hour of work because I went home.&lt;/p&gt;

&lt;p&gt;So as a rough estimate, it looks like I save my work about once per minute.  Looking at the data, it's not at all uncommon for me to have saved my work twice within a 5-second period of time.  There are even a few cases where I saved twice within two seconds.&lt;/p&gt;</description></item><item><title>Emacs pinky?</title><link>http://briancarper.net/blog/emacs-pinky</link><guid>http://briancarper.net/blog/emacs-pinky</guid><pubDate>Sun, 08 Jun 2008 13:23:44 -0700</pubDate><description>&lt;p&gt;I worry about my hands.  I play with computers for a living, and part of the reason someone would want to hire me is that I get a job done quickly.  And being able to type fast is a necessary (not sufficient) ability for that to happen.&lt;/p&gt;

&lt;p&gt;When I was in high school I started getting horrible pain on my wrists and hands.  I had to wear a wrist brace for weeks at a time.  I don't know what caused it, but too much keyboard time and bad posture and good old repetitive strain injury was and is my best guess.  (This was before I'd even heard of Vim.  Not sure what text editor I used back then.  Probably some Notepad clone, ugh.)&lt;/p&gt;

&lt;p&gt;But then I trained myself to type more comfortably, and I haven't had any pain for years.  I hold my arms at the proper angle, and I don't bend my wrists or stretch or strain my fingers.  My hands bounce over the keys nowadays, on and off the home row constantly.  I don't use my pinky fingers to type at all, in fact.  When I need to type a q or a number or a tilde, I move my whole hand up and hit it with my ring finger.  When I'm vimming, I hit ESC with my middle finger.  With practice this is just as fast as keeping your hands on the home row, but I find it far more comfortable.  I still do it fast enough that people remark that I'm a fast typist (though I know plenty of people who are faster).&lt;/p&gt;

&lt;p&gt;Thus we come to Emacs.  Emacs is the king of key chords.  I'm OK hitting Ctrl.  I pick up my hand and hit Ctrl with the side of my pinky like I'm karate-chopping it with a half-closed fist, or use my pinky and ring finger both.  The Alt key I can usually reach with my thumb.  But anything that requires Ctrl + Shift or to a lesser degree Alt + Shift is a killer on my hands.  I don't know a good way to quickly type Ctrl + Shift + another key in a comfortable way.  Caps lock remapped to another Ctrl is the solution many websites list, but that doesn't cut it for me either, it's just pinky-stretching in another direction (and what do you do when you have to hit Ctrl with your right hand?).&lt;/p&gt;

&lt;p&gt;For some reason I'm highly amused yet slightly horrified that there really is a condition called &lt;a href=&quot;http://en.wikipedia.org/wiki/Emacs#Emacs_Pinky&quot;&gt;Emacs pinky&lt;/a&gt;.  And that Richard Stallman and other Emacs gurus have famously experienced wrist injuries due to years of using Emacs.  How many people in the world can say that their favorite text editor has &lt;em&gt;physically crippled them&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Even if you admit that heavy dependence on the modifier keys is necessary, some of Emacs' keybindings seem ill-chosen to me. See this quote from the Emacs tutorial:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You can use the arrow keys,but it's more efficient to keep your hands in the standard position and use the commands C-p, C-b, C-f, and C-n.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I don't know what kind of creature finds those keys more efficient than the arrow keys or pageup / pagedown, but I don't think it's a human being.  (But admittedly, same goes for hjkl in Vim.)  Sure, you don't have you move your hands from the home row.  You just have to contort them into pretzels.  Try hitting up up up down left left right quickly, then try to do the same using those keys.&lt;/p&gt;

&lt;p&gt;Same is true of other commands.  &lt;code&gt;delete-indentation&lt;/code&gt;, which I find myself doing a lot, is &lt;code&gt;M-^&lt;/code&gt;.  When editing Lisp you may get to experience wonders like &lt;code&gt;C-(&lt;/code&gt; and &lt;code&gt;M-J&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Anything multi-chord is also just a little bit torturous for me.  How do you execute a command more than once in Emacs?  e.g. move down 3 lines?  You can either type &lt;code&gt;M-3 C-n&lt;/code&gt;, which requires me to hit Alt with my right hand and 3 with my left, then hit Ctrl with my left and n with my right.  Or you can do &lt;code&gt;C-u 3 C-n&lt;/code&gt;, which actually requires me to alternate hands on the modifier keys three times instead of two.  This for something so ridiculously simple as moving the cursor, something I do hundreds of times a day.  &lt;/p&gt;

&lt;p&gt;This kind of crap leads you to try to hit M-3 or C-u or C-n with one hand instead of two.  If I can manage to hit M-3 with my left hand, I can hit the down arrow with my right.  M-3 is possible with one hand, but M-8 or M-9 would not be without dislocating a few joints.  Down this path leads permanent disability.&lt;/p&gt;

&lt;p&gt;Sometimes I toy with the idea of remapping every keybinding or nearly every keybinding in Emacs to something sane.  But aside from thoughts such as &quot;Why the heck should it be necessary for me to do this?&quot; or &quot;Why would this possibly be worth my time?&quot;, I'm unsure I could come up with anything better.  I'd still be limited to using lots and lots of modifier keys.  Emacs has had decades of refinement after all, and it's still in this sorry state.&lt;/p&gt;

&lt;p&gt;I have tried the Vi and Vim keybindings in Emacs, and they don't work right.  They don't work in all buffers, for example a SLIME REPL buffer.  Even when Vim mode is working, many of the Vim commands are present, but not all.  These huge, massive Emacs-customization hacks always seem to work well maybe 95% of the time for me, but text editor bindings and behaviors are really something you need to work perfectly 100% of the time.  Every time Emacs does something ridiculous or one of these third-party scripts mangles my buffer, and I have to kill and reload the file, it completely breaks my stride and throws off my concentration.  The text editor needs to get out of your way and let you focus on what you're doing.&lt;/p&gt;</description></item><item><title>Emacs undo is horrible</title><link>http://briancarper.net/blog/emacs-undo-is-horrible</link><guid>http://briancarper.net/blog/emacs-undo-is-horrible</guid><pubDate>Sun, 25 May 2008 22:54:34 -0700</pubDate><description>&lt;p&gt;Emacs has a, well, &quot;unique&quot; undo system.  It only has undo, no redo.  When you undo something, the act of undoing is added as itself onto a stack of undo actions.  When you've un-done enough things, you do &quot;something, like move the cursor, and that breaks the chain.  From there if you undo again, you will traverse back over the undo actions you just did.&lt;/p&gt;

&lt;p&gt;This is supposedly powerful.  It does help with the following situation: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type something. &lt;/li&gt;
&lt;li&gt;Type something #2. &lt;/li&gt;
&lt;li&gt;Type something #3.  &lt;/li&gt;
&lt;li&gt;Undo undo undo.  &lt;/li&gt;
&lt;li&gt;Type something #4.  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most programs once you reach step 4, you can redo to get back to the text you just undid  But once you reach step 5, the first three things you typed are lost forever.  You've gone back in time and changed history, eradicating the old future and replacing it with a new one.  You can never get back to the old future.   Emacs undo, on the other hand, where undo actions are just like any other actions and pushed onto a stack of actions, does let you undo back first three things you typed.&lt;/p&gt;

&lt;p&gt;However in practice this doesn't work so well.  &lt;a href=&quot;http://www.e-texteditor.com/blog/2006/making-undo-usable&quot;&gt;This site&lt;/a&gt; has a nice quote:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;?By [undoing] repeatedly, you can gradually work your way back to a point before your mistake. This is convenient if you?ve made a mistake four or five commands back. It is marginally useful if you?ve made a mistake twenty or thirty characters back. And it is completely useless if your mistake is ancient history.? - Learning GNU Emacs (page 42)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem being, supposing you undo 20 times, and break the chain (by moving the cursor for example), if you then decide to undo one step FURTHER back, you have to undo all 20 of your previous undos, undo 20 more times, then undo once more.  Eventually you end up feeling like you're going up and down a roller coaster of undos.&lt;/p&gt;

&lt;p&gt;If you hate this, which you probably do, you could use &lt;a href=&quot;http://www.emacswiki.org/cgi-bin/wiki/RedoMode&quot;&gt;redo mode&lt;/a&gt;, which gimps up Emacs undo/redo to be like any other program's, i.e. you get the same behavior as Microsoft Notepad.  (Although when I tried it, it was buggy as heck, failing to undo my actions properly, mangling text from different lines together and whatnot.)&lt;/p&gt;

&lt;p&gt;Vim's undo system on the other hand is far better and equally powerful.  You have a standard undo / redo option via &lt;code&gt;u&lt;/code&gt; and &lt;code&gt;CTRL-R&lt;/code&gt;.  You also have a second completely different way to undo: you can &quot;go back in time&quot;.  In the above example, Vim will create two undo &quot;branches&quot; and you can jump from one to the other even if you undo and &quot;break the chain&quot; by typing something new.&lt;/p&gt;

&lt;p&gt;Doing &lt;code&gt;:undol&lt;/code&gt; lists the branches, in a somewhat confusing format.  But you can just pound &lt;code&gt;g-&lt;/code&gt; and &lt;code&gt;g+&lt;/code&gt; to go to older / newer text states, or use &lt;code&gt;:earlier&lt;/code&gt; with a human-readable time (say, 10s or 5m) and it will take you to that point.  These will get you all the power of Emacs' undo stack, with none of the pain or confusion.  See also &lt;code&gt;:h undo-two-ways&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is one of many instances where Vim wins, hands-down.  Vim's undo system isn't as reprogrammable as Emacs, but it's so powerful and so perfectly what you'd want that it doesn't matter.  This is beautifully typical of Vim.  I don't have a year to figure out all the nooks and crannies and edge cases and idiosyncrasies of Emacs undo system, let alone the time it'd take to write a custom, crusty elisp script to buggily re-implement it.&lt;/p&gt;

&lt;p&gt;Being an &quot;extensible text editor&quot; doesn't help much when such basic functionality is so broken.  Unless you want to &lt;a href=&quot;http://www.gnufans.net/~deego/emacspub/lisp-mine/undo-browse/dev/undo-browse.el&quot;&gt;play your undo history back like a movie, in rainbow colors&lt;/a&gt;, which I don't.  I want undo/redo that works.&lt;/p&gt;</description></item></channel></rss>

