Skip to content

Fun with Vimgolf 4: Transpositioning text with Tables

Jan 17 13
by mickey

Here’s another vim challenge, and one you might actually encounter frequently in real life.

Transpose the original lines in separate columns, one for each line.

Link to challenge.

Simple, really; a transposition here, some alignment there… but can we do better than the good ole’ brute force approach the Vim guys will invariably use? Can we do it without a call to a shell commands like column and paste? (Psst.. yes we can! It’s Emacs!)

Here’s the original data:

… Standard comma-, and newline-delimited data, and we must turn it into this:

Looking into the challenge, I was already thinking “tables” — Emacs tables. Transposition is a common operation in tables (spreadsheets) and mathematics, and Emacs can do both very well indeed.

So here’s what I did, utilizing our old friend org-mode; or rather, one of its subsidiary libraries. You don’t have to be in org-mode for this trick to work. It echoes an earlier VimGolf challenge I did where I used its hierarchical “sort” function to sort an address book: Fun with Vimgolf 1: Alphabetize the Directory.

Command Description
C-x h Mark the whole buffer
M-x org-table-convert-region Converts a region into an org table. The defaults use comma and new line separators by default. Bonus.
M-x org-table-transpose-table-at-point As the name implies this will transpose our table as required by the Vimgolf challenge.
C-x C-x Exchange point and mark.
M-x replace-regexp Replace: ^| \\||
With: RET

Replace the pipe at the beginning of the line and a whitespace, or any pipe.

M-x delete-trailing-whitespace Delete trailing whitespace. Could also be done with a more sophisticated regexp in the penultimate step.

Done right, and it should look like this:

Six “keystrokes” (for an arbitrarily large definition of “keystroke”…), but done the Emacs way. The best score on VimGolf is currently 31 (characters). Very impressive, but would it work on a 20×20 or with variable-length rows? “Think Abstract,” the developer cried.

The result above should be identical to that of the Vimgolf output, but done without the hyper-specialized and brittle solutions (most?) of the VimGolfers employ.

I didn’t tweak the cell width (whitespacing between each word) for each column; that it aligns perfectly with VimGolf’s output is dumb luck. Maybe they generated the resultant output in Emacs? :)

Nevertheless, the solution is “typical Emacs” and would scale well to very large datasets, and you don’t have to worry about things like unusually long cells; uneven number of rows and columns; etc.

Fun with Vimgolf 3: Swapping Words by Sorting

Jan 14 13
by mickey

Jon over at Irreal’s been busy with VimGolf challenges, and I figured I’d throw in my two pieces of eight.

The “challenge” is a simple. Take this text:

And turn it into

As you can see, a simple transposition between two words on a line is all that we need, and Jon’s come up with a solution that solves it in 8 keystrokes. Arguably something like his solution is what I would do were I to do it in real life.

I’m not sure if the Vim guys count typing out strings of text as one atomic operation or if they count each character; in Emacs, arguably, each character is in itself a command as each key stroke will invoke self-insert-command but it’s more fun to think of strings of text as a single keystroke, for simplicity’s sake, and to give ourselves a sporting chance against our Vim nemeses.

So here’s my solution. It only solves this particular challenge and nothing more. It relies on the good ole sort order — that C come before S.

Command Description
C-x h Mark whole buffer
M-x sort-regexp-fields Run sort-regexp-fields. See Sorting Text by Line, Field and Regexp in Emacs for more information
Regexp specifying records to sort: \\([a-z_]+\\)$ We want each record -- that's the part of the line we want Emacs to use for sorting -- to be the last word on each line
Regexp specifying key within record: \\1 The key -- that's the part inside the capturing group from above -- we want to sort by is the entire capturing group.

And we're done. So how does it work? Well, we rely on the side effect that the word CHALLENGE_FOLDER is less than, lexicographically, SOLUTIONS_FOLDER, because C comes before S.

It boils down to this: sort-regexp-fields is pure magic. As my article on the subject talks about at length, you can tell Emacs to only sort by parts of a line -- the part that matches the regular expression -- and using that match, you can then tell Emacs how you want to sort that data. We tell Emacs to sort by the last word on each line and leave the rest untouched. Simple :)

So how many keystrokes is that? Good question. I don't know: it depends on how you count it. Two if you count the commands only; four if you count the commands and the prompts; and many more if you count each character.

As always, these challenges are pointless (though fun!) but they do force you to think on your feet.

Jedi: A completion library for Python

Jan 10 13
by mickey

If you’re using Python with Emacs (using one of several competing, incompatible, and slightly different modes) you are used to a pretty… bare-bones experience: no completion; semi-functional dynamic docstring support; and little in the way of two-way communication between Python and Emacs.

Enter Jedi, a completion library. Yes, Jedi, an editor-agnostic library that publishes auto completion, docstring support, and more. Excellent.

I’ve experimented with Pymacs — an interesting science project that adds “Python-like” support Emacs, so you can avoid interacting with Elisp, except not really — rope, and ropemacs and they were… disappointing. Slow, crash-prone, obtuse and impossible to extend. So I never really used them, and lived without completion or, well, much of anything beyond the REPL and my own handcrafted modifications.

The other alternative is the 600 lbs gorilla, CEDET, and its incomplete Python support, but that’s no good either.

Imagine my surprise, after fidgeting with the dependencies for both Jedi and Jedi.el, the Emacs library for Jedi, that it… works! And it’s good! It’s up-and-coming, I should say, but perfectly usable; it doesn’t get in my way, it’s got some crazy deferreds library it depends on for asynchronous, non-blocking querying of Jedi, but that bit works great — no input lag at all.

It seems to resolve, simplistically (which is good), as many assignments and method calls as one can reasonably expect from a non-evaluating, statically analyzing Python completion library.

Functioning Auto Complete in a Python buffer

The Jedi.el module also Just Works with the excellent auto-complete library, as you can see in the picture above.

Aside from completion, it also offers “find symbol definition at point” (a la TAGS, but not crap) and Jedi.el sensibly binds it to C-. by default. It also has a “related names” functionality, tracking down same-named identifiers in other modules; it uses Anything (now Helm) to display the results, and it is bound to C-c r. And finally, it can show the documentation for the identifier at point (be it a class or function) with C-c d. Useful.

I haven’t used Jedi and Jedi.el long enough to really get to know it, but I’m probably going to extend Jedi.el so it uses eldoc-mode for displaying the function parameters; it’s also a bit rough around the edges, and I may want to tweak certain things to my liking, but overall: huge success!

I highly recommend you give Jedi and Jedi.el a try!