A New Trick For Marking Up Key Sequences in Emacs

Frozenlock left a comment to an old post of mine about Marking Up Key Sequences For HTML. He said he liked the way Xah Lee and I mark up Emacs keys sequences but that he didn’t like having to write ctrl+x b to get 【Ctrl+x b】 so he wrote a little hack that allows him to enter the actual key strokes and have the appropriate markup inserted at the point.

It turns out to be pretty easy to do. If I were starting from scratch (or weren’t so lazy) I’d modify my prettify-key-sequence function to accept the actual keystrokes and output the markup. Frozenlock uses the macro method that I used before I wrote prettify-key-sequence so there isn’t quite as much control over the final output but it works well for most cases. If you want to use markedup key sequences, I’d look at Frozenlock’s method and consider integrating it into something like prettify-key-sequence.

Posted in Blogging | Tagged , | 5 Comments

Using The Emacs save-restriction Special Form

Emacs has the ability to “narrow” a buffer to a region thereby making the parts of the buffer outside the region invisible. The invisible part of the buffer is completely inaccessible: you can’t move into it, you can’t change it, and, of course, you can’t see it. The table below shows the commands to narrow and widen (cancel the narrowing) buffers1.

Key Sequence Function Action
Ctrl+x n n narrow-to-region Narrow to region between point and mark
Ctrl+x n w widen Widen the buffer
Ctrl+x n p narrow-to-page Narrow to current page
Ctrl+x n d narrow-to-defun Narrow to current function

These functions are sometimes useful during interactive editing. For example, you might want to narrow to the function you’re working on so you won’t be distracted by the other code. I find, however, that they’re mostly useful in Emacs Lisp code. That brings me to the point of this post.

Xah Lee has an excellent—and, if you’re an Elisp programmer, important—post on using narrowing to avoid changing the boundaries of a region while you work in it. If you haven’t read his post, go do that now before continuing with this one.

Lee’s post is an excellent example of using narrowing in Elisp code but what I really want to talk about is the special form save-restriction. This form merely saves the current narrowing, if any, executes its body, and then restores the saved narrowing. The template is

(save-restriction
  (narrow-to-region beg end)
  (do stuff)
  (do-more stuff))

so that you can temporarily narrow to some region without affecting any narrowing already in effect. You might wonder why you would want to narrow in Elisp. Lee gives an excellent example of its usefulness but I most often use it as a sort of “set it and forget it” device when I’m writing code that can operate on a region or the entire buffer.

For example, consider the following function that counts lines in a Scheme source code file:

(defun jcs-count-scheme-lines ()
  "Count non-comment, non-blank lines in a Scheme program"
  (interactive)
  (with-region-or-buffer (b e)
    (let ((cnt 0))
      (save-excursion
        (save-restriction
          (narrow-to-region b e)
          (goto-char (point-min))
          (while (not (eobp))
            (unless (looking-at "^\\s-*$\\|\\s-*;")
              (setq cnt (1+ cnt)))
            (forward-line 1))
          (message "%d code lines" cnt))))))

The with-region-or-buffer macro binds the beginning and end of the current region if there is one or the beginning and end of buffer if there isn’t to its first and second arguments. I wrote about it here and here. I narrow to the region defined by b and e so that I don’t have to worry about whether I’m working in the whole buffer or a smaller region. In effect, I set the area I’m working in and then just pretend I’m working in the whole buffer so that I don’t have to write a lot of code worrying about whether I’m acting on a buffer or smaller region.

This is a really handy technique that can save a lot of code and effort. I use it all the time because I try to make most of my Elisp functions work on either regions or the entire buffer.

The code above illustrates another point. The save-excursion special form is similar to save-restriction except that it saves and restores the point, mark, state of mark activation, and current buffer. When you use them together, as I did here, you should put the save-excursion in the outermost position.

Footnotes:

1 Narrowing is disabled by default. When you first use it, Emacs will ask you if you want to enable it temporarily or permanently. You can enable it yourself by putting (put 'narrow-to-region 'disabled nil) in your .emacs or init.el file.

Posted in Programming | Tagged , | 2 Comments

More Amazon Disruption

Back in September while everyone was waiting for Amazon to announce the Kindle Fire, Sebastian Anthony over at ExtremeTech speculated that Amazon would also roll out a digital library that would let Kindle/Amazon Prime users check out books for free. He went on to discuss what this would mean for public libraries and concluded that it could easily mean their death.

The announcement for the Fire came and went and there was nothing about the digital library so I forgot about the post. Just recently, however, Amazon announced the Kindle Owners’ Lending Library that does pretty much what Anthony had predicted. You can borrow one book at a time and can keep it as long as you like but you can borrow a new book only once a month. Not ideal for the voracious reader but still a pretty good deal and who knows how the details of the plan will evolve in the future.

What interests me about this is not so much what it will mean for libraries—I’m pretty sure they will evolve to deal with the digitization of media—but what it means for publishers. The publishers, of course, hate the plan and none of the big six are participating according to an article by Jeffrey Trachtenberg and Stu Woo at the Wall Street Journal. Those that are participating are typically paid a flat fee by Amazon.

Doubtless the big publishing houses will resist as long as they can but in the end they will be dragged kicking and screaming into the program. Sadly, this is another missed opportunity for them. Rather than accept the inevitable and find a new business model that leverages what Amazon and others are doing, they continue to try to fend off the forces of change.

As I wrote a couple of weeks ago, Amazon is already storming the ramparts of the publishing industry and if the big houses can’t find a place in the new ecology they will surely wither and die. I’ve said before that I hope that doesn’t happen but, really, time is running short.

Update: Mathew Ingram has a nice analysis on this over at Gigaom that’s well worth a read.

Posted in General | Leave a comment

Emacs Rocks

Tim Visher has started a growth industry with his VimGolf in Emacs videos. First, some of us starting writing about the videos, then people started issuing their own challenges, and now he has a direct competitor with Emacs Rocks. I don’t know how Visher feels about that but I’m delighted. It’s more fun and more opportunities to learn some nifty Emacs tricks.

For example, the second and third episodes reconsider the problem explored in VimGolf in Emacs e006. The final solution solves the problem in an incredible 10 keystrokes, beating the best Vim score by 7 strokes.

Not all the Emacs Rocks episodes discuss VimGolf problems through. Episode 1 deals with a small refactoring of some JavaScript code. In that video he needs to mark a rectangle and uses a nice trick that could be brought to bear on yesterday’s post. Recall that the problem was to sort

California             423,970 km²
Taiwan                  36,008 km²
Japan                  377,944 km²
Germany                357,021 km²
Iraq                   438,317 km²
Iran                 1,648,195 km²
Korea (North+South)    219,140 km²
Mexico               1,964,375 km²

by the number of square kilometers. I did that by marking the rectangle containing the numbers and calling sort-columns. I wasn’t really thinking about VimGolf so I didn’t mark the rectangle in an optimum way; I just said put the point here, set the mark, put the point there and call sort-columns. Here’s how the trick from Emacs Rocks can be used to mark the rectangle.

Let’s assume that after the first part of the problem, the point is left at the end of the last line. If we do a 【Ctrl+r␣␣42Return】 (where ␣ is a space), we end up two spaces in front of the the 423,970 in the first line, which is just where we want to be. Furthermore, since incremental search sets the mark at the starting point, we have marked the rectangle in only 6 keystrokes. A similar trick works if we begin with the point at the beginning of the first line: type 【Ctrl+e】 to move to the end of the line, then 【Ctrl+s1,9Return】 【Ctrl+3 Ctrl+b】 to move the point right before the 1,964,375.

I already knew that incremental search sets the mark, of course, because it tells me every time I do an incremental search. The insight I gained from Episode 1 of Emacs Rocks is that it can be a quick and easy way of marking a rectangle.

So welcome to Emacs Rocks. There are 6 episodes so far and I’ve enjoyed them all and am looking forward to more. It’s always nice to see Emacs in action.

Update ⌴ → ␣ (Thanks to Xah Lee for telling me the correct character for space)

Posted in General | Tagged | 2 Comments

The Emacs sort-columns Command

Xah Lee has caught the VimGolf with Emacs bug and proposed an interesting challenge. The final part of the solution involved sorting the following list by the number of square kilometers.

California             423,970 km²
Taiwan                  36,008 km²
Japan                  377,944 km²
Germany                357,021 km²
Iraq                   438,317 km²
Iran                 1,648,195 km²
Korea (North+South)    219,140 km²
Mexico               1,964,375 km²

Normally this wouldn’t be much of a problem but two things make it more difficult than usual. First, the line for Korea has an extra field so commands like sort-fields or sort-numeric-fields don’t work. Second, the numbers have commas in them so the numeric sorts don’t work.

I remarked on Xah’s blog that I had tried sort-regexp-fields but that that didn’t work because the sort was lexicographic rather than numeric. Then jm commented that the lexicographic sort will work if you include the spaces in front of the shorter numbers. He proposed using sort-regexp-fields with the regular expression .*\([0-9 ,]\{9\}\) km. That did the trick and I thought it was probably as simple a solution as we were apt to find.

Later I suddenly realized that an even simpler solution based on the same idea was to use sort-columns. To use that function, you mark the rectangle containing the columns you want to sort on and then just call sort-columns. Thus, I placed the point two spaces before 423,970 on the first line, typed 【Ctrl+Space】 to set the mark, moved the point to right after 1,964,375 on the last line, and typed 【Meta+xsort-columns to sort the list. That worked perfectly and is a reasonably concise solution.

As usual, Emacs had the right tool to get the job done even if it took a little effort to find it. Maybe next time this solution will jump right into my head. Or not.

Posted in General | Tagged | 5 Comments

Speed Marking In Emacs

Sometimes you want to mark just a word or two so that some command can operate on them. The normal way to do that is with 【Ctrl+Space Meta+fMeta+f】 but there’s a slightly faster way. To mark one word, just type 【Meta+@】. If you want to mark the next N words, type 【Meta+N Meta+@】. Similarly, to mark the previous N words, type 【Meta+ Meta+N Meta+@】.

The documentation for this command describes it as setting the mark ARG words away from the point and mentions that the mark goes in the same place that it would if you were moving by 【Meta+f】 with the same ARG.

Summary

Key Sequence Action
Meta+@ Mark the next word
Meta+N Meta+@ Mark the next N words
Meta+ Meta+N Meta+@ Mark the previous N words
Posted in General | Tagged | 2 Comments

Useful Commands For The Emacs Minibuffer

I have long used 【Meta+p】 to recall previously entered information in the minibuffer. For example, when I’m editing Groff input it’s often convenient to typeset what I have so far to check that the result looks good or just to read what I’ve written without the markup. I do that by selecting the entire buffer with 【Ctrl+x h】, piping the buffer to groff with 【Meta+|】, and then specifying the command

groff -ms -pset -X | gxditview

It’s a pain to keep typing that so after the first time I just type 【Meta+p】 to bring up the pipeline again.

You can, of course, move forward in the minibuffer history with 【Meta+n】 but there are some other not so obvious ways of navigating the minibuffer. The command 【Meta+rregexpReturn】 will search backward in the minibuffer history for the entry matching the regular expression regexp. Similarly, 【Meta+sregexpReturn】 will search forward for the entry matching regexp. You can continue either of these searches to the next match with 【Meta+r Return】 or 【Meta+s Return】.

Finally, you can repeat the last echoed message with 【Ctrl+h e

Summary

Key Sequence Operation
Meta+p Backward one entry
Meta+n Forward one entry
Meta+rregexpReturn Search backwards for regexp
Meta+sregexpReturn Search forward for regexp
Meta+r Return Repeat backward REGEXP search
Meta+s Return Repeat foreard REGEXP search
Ctrl+h e Show last echoed message

Update: 【Meta+s】 → 【Meta+n】 in summary

Posted in General | Tagged | 1 Comment

Administrivia—Moderation

Some of you may have noticed that your comments were held in the moderation queue longer than usual the last two days. That’s because I haven’t been getting email notifications of new comments. I’ll look into what’s happening there but in the mean time this seems like the right moment to institute a change I’ve been thinking about anyway.

Since I implemented the captcha, my forum spam has disappeared so I am no longer going to hold normal messages for moderation. Some messages—those WordPress is suspicious of—get held automatically. If the forum spam becomes a problem again in the future I may have to reconsider but for now your comments should appear when you post them.

Again, I’m sorry about the captcha but over 90% of the comments were spam and I was spending a lot of time dealing with them. If you comment regularly, it may pay to register as then the captcha doesn’t appear.

Posted in Blogging | Tagged | Leave a comment

Today Is Dennis Ritchie Day

Tim O’Reilly has declared today Dennis Ritchie Day and asks us all to remember the contributions of this computing pioneer. For his part, O’Reilly insists that without Ritchie’s work, O’Reilly Media would not exist.

As I wrote in my short post about his death, Ritchie had tremendous impact on my growth and career in computing so I am happy to oblige Mr. O’Reilly and mark the day here at Irreal.

Posted in General | Leave a comment

Mickey Plays VimGolf In Emacs

I’ve written a couple of times about Tim Visher’s VimGolf In Emacs series of videos. If you’re an Emacs user and haven’t taken a look at them yet, you should do so without delay. They are very informative and entertaining.

Now Mickey Petersen over at Mastering Emacs has gotten into the act. That makes me very happy because I really enjoy seeing how other Emacs users solve editing problems. I almost invariably learn something useful by watching or reading those solutions. Mickey’s take on the problems is a little different from Visher’s. He says up front that there’s no way Emacs is going to be as efficient in terms of keystrokes as Vim and instead he concentrates on finding a general—or as he says, technically correct—solution. By that he means a solution that works for bigger or smaller data. The problem with VimGolf solutions is that they tend to be crafted for the particular piece of data that’s being edited. That’s because in order to minimize keystrokes the solution has to be tailored to the specific data in the problem.

The problem that Mickey considers is to sort the following records into alphabetical order by people’s names.

## Directory
   * Smith, George
      - 1234 Avenue, New York, NY
   * Bailey, Stephen
      - 4545 Harbor Ln, Atlanta, GA
      - Phone: (412) 291-1238
   * Thomas, Brent
      - 1482 Mystic Oaks, Anaheim, CA
   * Grant, Jenny
      - 198 Circle Dr, Houston, TX
      - Phone: (213) 198-9842
      - Email: jenny.grant@gmail.com
   * Percy, Adam
      - 221 Jaguar Pkwy, Missoula, MT
   * Garfield, Misty
      - 5988 Apple Tree Ln, Memphis, TN
   * Parsons, Betty
      - Phone: (235) 523-2378
      - Email: bettyboop123@gmail.com
   * Sanders, Terry
      - Email: sanderst@yahoo.com
   * Smith, Pete
      - Phone: (294) 984-2938
   * Frost, Jennifer
      - 2498 Temple Terrace, Miami, FL
   * Matthews, Frank
      - 418 Happy Trail, Phoenix, AZ
      - Phone: (985) 129-2394
      - Email: frank@phoenixrealtors.net
   * Allen, Taylor
      - Email: allen.taylor@hotmail.com
   * McCullen, Sarah
      - 247 Hidden Elm, Seattle, WA
      - Phone: (288) 283-4568
   * Perkins, Mike
      - 992 Peartree Ln, Bowling Green, KY

Think for a second or two how you might do that in Emacs and then jump over to Mickey’s post to see how he leveraged the power of Org-mode to solve the problem. It’s a brilliant solution and with smex installed is probably competitive with the Vim solutions even without trying.

Posted in General | Tagged | 5 Comments