Sorting Rectangles

Mickey has a nice solution to the last VimGolf in Emacs challenge. It certainly doesn’t win on total keystrokes but it does demonstrate a really powerful method for solving problems like the challenge. Mickey uses sort-regexp-fields to sort parts of each line by

  1. Picking out the part of each line after the =␠ as a field
  2. Sorting the specified fields using the whole field as the key

Since only the specified fields are moved, this effectively switches the ends of the two lines leaving the beginnings of the lines where they were. A very nice solution and a powerful technique. Mickey has an excellent write up on sort-regexp-fields here.

This result is reminiscent of Fuco’s solution where he specified a rectangle that contained the same fields and then reversed the lines in that rectangle. That got me thinking about whether you could sort those fields instead of reversing them. Fuco used 【Meta+Shift+r】 to reverse the lines so I thought maybe there was a similar command for sorting them—【Meta+Shift+s】 perhaps. It turns out that no such command exists but there is 【Meta+|】 which pipes the rectangle to a shell command and with a preceding 【Ctrl+u】 will replace the rectangle with the result. Thus given

abc 789
def 123
ghi 456

we can get

abc 123
def 456
ghi 789

with

Ctrl+s Space Move to upper left of triangle
Ctrl+Return Enter CUA rectangle mode
Ctrl+s 6 Move to lower right of triangle
Ctrl+u Meta+|sort Sort and replace rectangle

That’s a bit faster and easier than sort-regexp-fields but not as powerful because with sort-regexp-fields you can use just a part of the field (rather than the whole field) as a key and the fields don’t have to form a rectangle.

To illustrate that last point, suppose you have

abc 789
123 def
ghi 456

and you want

abc 123
456 def
ghi 789

You can do that with

Ctrl+x h Mark buffer
Meta+xsort-regexp-fields Call sort-regexp-fields
[1-9]+ Define fields
\& Define keys

Mickey remarks that these challenges are pointless but fun. They’re certainly fun and they’re pointless in the sense that the solutions are mostly ad hoc and not useful outside of the challenge they solve but I, at least, find them useful as a way to learn new Emacs techniques. With just this last challenge, I learned about reversing lines in a rectangle and sort-regexp-fields and both of those are things I will most certainly find useful later even if I’m unlikely to need to resolve the particular challenge where I learned them.

Posted in General | Tagged | Leave a comment

Emacs Ahhhhh! Moments

Over at the reddit Emacs subreddit Tribaal asks for advice on learning Emacs and, in particular, solicits “ahhhhh! moments” from Emacs veterans. The ensuing discussion is quite interesting and, at least at the time I read it, free of trolls and the usual silliness that such questions often engender.

One commenter remarked that his Ahhhhh! moment was when he realized that Emacs is really just a Lisp interpreter enhanced with text editing functionality. Another says that Vim is an editor while Emacs is a Lisp environment tailored to look like an editor. These are both views that we’ve discussed before but the idea comes close, I think, to capturing what it is about the Emacs experience that makes it so great.

I enjoyed the entire discussion and if you like to read about how people use and feel about Emacs you probably will too. If you’ve got your own Ahhhhh! moments leave a comment and share them with us. Mine is just what I wrote about above: Emacs is really a comprehensive Lisp environment—much like the Lisp machines of old—that has some features that make text editing particularly pleasant. Once I adopted that view point I found that it was often easier to solve some small Lisp-amenable problem in Emacs rather than crank up Slime and SBCL.

Posted in General | Tagged | Leave a comment

Plain Text Offenders

A year ago, I wrote about Plain Text Offenders a website dedicated to naming and shaming Web sites that store their user’s passwords in plain text. Sadly, the Website has recently celebrated their 1000th post. Think about that for a moment. One thousand Websites storing passwords in plain text. No salting. No hashing. Just your password (and presumably other credentials) in plain text.

This would be merely bad if it exposed user accounts only on the offending site. Unfortunately, too many users reuse their passwords so multiple accounts are at risk making this transgression really bad. But the news is not all bad: seven (!) sites have reformed their ways and been removed from the list. I’m sure that will make you feel better.

Keep in mind that this is not merely some pointy haired boss with no clue doing this. This code is being written by developers who should know better. There really is no excuse.

Posted in General | Tagged | Leave a comment

The Universal Argument

Over at Wisdom and Wonder, Grant tells us how to move forward several spaces in the minibuffer. That’s just 【Ctrl+u 1 0 0 Ctrl+f】, of course but Fuco (who wowed us by doing the last VimGolf in Emacs challenge in only 5 keystrokes) points out that really all you need is 【Ctrl+1+0+0+f】. I’ve been seeing this misunderstanding a lot lately, both in comments to my posts and in other Emacs-oriented blogs, so perhaps it’s worth mentioning how the Universal Argument works.

The most useful thing to know is that you can give numeric arguments to commands by holding down 【Ctrl】 or 【Meta】 and typing the digits. That’s why Fuco’s method works. Notice how much more convenient it is: you merely hold down the 【Ctrl】 key and type the numeric argument and command. The same thing works with the 【Meta】 key. To delete the next five words, type 【Meta+5+d】. Much easier than 【Ctrl+u 5 Meta+d

The next thing to know is that if you don’t type any digits after 【Ctrl+u】 the argument count is increased by a factor of 4. Thus 【Ctrl+u+p】 will move the point up four lines and 【Ctrl+u+u+p】 will move the point up 16 lines and so on.

Finally, the Universal Argument can act as a flag that tells the command to use an alternative behavior. Usually, the command will use

(interactive "P")

to get this behavior. Here’s an example from my init.el file:

(defun jcs-datetime (arg)
  "Without argument: insert date as yyyy-mm-dd
With C-u: insert time
With C-u C-u: insert date and time"
  (interactive "P")
  (cond ((equal arg '(4)) (insert (format-time-string "%T")))
        ((equal arg '(16)) (insert (format-time-string "%Y-%m-%d %T")))
        (t (insert (format-time-string "%Y-%m-%d")))))

Notice that in this case the function sees the argument as (4), (16), and so on. Of course, unless you’re writing Elisp code you don’t have to worry about this case—the function writer has taken care of it for you and you just need to know that you need one or more 【Ctrl+u】 to get the desired alternative behavior.

Posted in General | Tagged | 6 Comments

Emacs and Reprogrammability

A recurring theme here at Irreal is the notion of Emacs as a Lisp Machine (see here and here, for example) and the advantages that this point of view provides. Now Martin Fowler explores this idea a little more with a beautiful post entitled InternalReprogrammability. Fowler begins by recounting an anecdote that most Emacs users will find familiar: He’s typing along and realizes that he needs to put a blank line above the line he’s currently typing but Emacs doesn’t provide a built-in way of doing it. This has come up before and now he’s fed up and decides to do something about it. That “something” is to add a bit of Elisp to his .emacs file and execute it. Problem solved. Fowler makes some useful observations about this:

  • He doesn’t leave Emacs to do this.
  • He doesn’t have to restart Emacs after he does it.
  • His addition is indistinguishable from the core code of Emacs. This is how Emacs itself is built except that most of it doesn’t live in his .emacs file.

Notice how much this is like what the Lisp Machines provided. You can change or extend your environment without leaving it. Everything you need is right there and you have the same rights and capabilities as the original implementers.

Fowler goes on to remark how rare this is. Lots of software has some form of extensibility but mostly this involves plug-ins or the ability to add scripts. That’s different from Emacs where you can “reach deep into the editor’s guts” and change any behavior at all not just those aspects that the implementer has chosen to expose.

This is a great post and you really should take a look at it. It will give you a renewed appreciation for how powerful and special Emacs really is.

Posted in General | Tagged | 2 Comments

The Greatest Innovation

Chris Dixon asks “What would be the greatest technological leap you’d have to explain to someone who time traveled from the 1950’s?” It’s hard to argue with his answer. It surely has changed everything.

Posted in General | Leave a comment

UPS and the Traveling Salesman

If you know anything at all about United Parcel Service you know that they put a lot of effort into optimizing their operations. For example, the white roofs on their trucks are actually a translucent material that lets light into the back of the truck so drivers can see the packages and read their labels.

In view of this, I had always assumed that UPS was using some sort of traveling salesman algorithm to plan out their routes. After all, a savings of even 5 miles per route would mean millions of dollars saved over all the routes. It turns out that UPS does exactly that but they didn’t start testing the system until 2008 and have rolled it out to only 50 depots so far. UPS estimates that it will take another half decade before the system is installed throughout the company.

The linked article is pretty interesting if you have even a passing interest in Operations Research or practical applications of the traveling salesman problem. It’s also worth noting the difference between the mathematical solution and the real-world solution as pointed out to one of the UPS staffers working on the problem by a 5 year old.

Posted in General | Leave a comment

Tabs, Spaces, and All That

Xah Lee has a helpful post on dealing with tabs, whitespace, and indentation. Nothing in the post qualifies as advanced and most of you will be familiar with the material but I remember being confused about tabs and indentation when I first started Emacs so n00bs may find it helpful. The Emacs tab behavior is rich and complicated. Vim (and other editors with which I’m familiar) tend to be more straightforward but less flexible so n00b confusion is understandable. In any event, Lee’s post is worth a look.

Posted in General | Tagged | 2 Comments

Schadenfreude

Live by the copyright, die by the patent.

Posted in General | Leave a comment

An Easy VimGolf in Emacs Challenge

Here’s an interesting VimGolf challenge. As they say in the challenge, it’s a simple problem but they’re looking for interesting solutions. The challenge is to turn this

app.config['CHALLENGE_FOLDER'] = SOLUTIONS_FOLDER
app.config['SOLUTIONS_FOLDER'] = CHALLENGE_FOLDER

into this

app.config['CHALLENGE_FOLDER'] = CHALLENGE_FOLDER
app.config['SOLUTIONS_FOLDER'] = SOLUTIONS_FOLDER

The obvious solution that any Emacs user would think of does the job in 81 keystrokes.

Ctrl+s = cursor to =
Ctrl+k kill after =
Ctrl+n down one line
Ctrl+y insert ␠SOLUTION_FOLDER
Ctrl+k kill rest of line
Ctrl+p up one line
Ctrl+y insert ␠CHALLENGE_FOLDER

The best Vim solutions also do it in 8.

What I really want to do is something along the lines of

Ctrl+s = Ctrl+s Mark rectangle
Ctrl+x r k Kill rectangle
Ctrl+x Ctrl+t Swap lines
Ctrl+< Beginning of buffer
Ctrl+x r y Yank rectangle

that’s 12 keystrokes, 50% more than the obvious solution. If I use CUA Selection Mode (as I wrote about previously) I can do it in 9 with essentially the same method as above. Is there a clever way of doing this or is the obvious solution with 8 keystrokes the best we can do? If you can beat 8 keystrokes—especially if it’s something clever—be sure to leave a comment.

Update: Fuco does it in 6.

Update 2: Fuco shaves off another keystroke to a total of 5. Definitely a heavy weight contender.

Footnotes:

1 Using our usual rules of changing the text but not saving the buffer.

Posted in General | Tagged | 8 Comments