Turn Vim Into Excel: Tips for Editing Tabular Data

Friday, March 29, 2013.

I tried to edit data in spreadsheet programs, I really did.

But it’s a fact: Vim ruins you for life. Power corrupts.

Of course, Vim can edit tabular data too, although there are a few things that will make it more pleasant. For this discussion I’m assuming you’re editing files in tab-separated value format (TSV).

“But what about CSV files?” Just. Don’t.

Do: convert your CSV to TSV and back for editing.

A Note on the TSV Format

To really do TSV right, you should escape newline and tab characters in data. Here are two scripts, csv2tsv and tsv2csv, that will handle escaping during CSV <-> TSV conversions.

Converting CSV to TSV, with C-style escaping:

csv2tsv -e < file.csv > file.tsv

Converting TSV back to CSV, with C-style un-escaping:

tsv2csv -e < file.tsv > file.csv

Setting up Tabular Editing in Vim

Open the file:

:e file.tsv

Excel numbers the rows, why can’t we?

:set number

Adjust your tab settings so you’re editing with hard tabs:

:setlocal noexpandtab

Now, widen the columns enough so they’re aligned:

:setlocal shiftwidth=20
:setlocal softtabstop=20
:setlocal tabstop=20

Fiddle with that number 20 as needed. As far as I can tell, Vim doesn’t support variable tab stops. It would be real nifty if I was wrong about this. It would be even niftier if column width detection / tabstop setting could be automated.

Tall Spreadsheets: Always-Visible Column Names Above

Typically, the first line of the tsv file is a header containing the column names. We want those column names to always be visible, no matter how far down in the file we scroll. The way we’ll do this is by splitting the current window in two. The top window will only be 1 line high and will show the headers. The bottom window will be for data editing.

:sp
:0
1 CTRL-W _
CTRL-W j

At this point you should have two windows, one above the other showing the first row of column headers. If you don’t have very many columns, then you’re done.

Wide Spreadsheets: Horizontal Scrolling

If you do have lots of columns, or very wide columns, you’re probably noticing how confusing it looks when lines wrap. Your columns don’t line up so well anymore. So turn off wrapping for both windows:

:set nowrap
CTRL-W k
:set nowrap
CTRL-W j

One problem remains: when you scroll right to edit columns in the data pane, the header pane doesn’t scroll to the right with it. Once again, your columns aren’t aligned.

Fortunately Vim has a solution: you can “bind” horizontal scrolling of the two windows. This forces them to scroll left and right in tandem.

:set scrollopt=hor
:set scrollbind
CTRL-W k
:set scrollbind
CTRL-W j

But What About Formulas and Calculations?!

It’s true, Excel does far more than just edit tabular data. Vim is just (“just”) an editor.

However, if you’re using Vim, chances are you’re a competent programmer. Chances are you can write programs to manipulate tabular data. So how about this arrangement:

  1. A tsv that contains formulas, calculations, and other potentially interpreted data.
  2. A program that will process that tsv and “render” a tsv with calculated data.
  3. The ability to quickly switch between these tsvs.

I haven’t put this to the test, just throwing out ideas.


Posted by Alan on Friday, March 29, 2013. (Discuss)

How to printf a length-delimited string

Thursday, November 15, 2012.

You often see code like this:

TODO insert example of copying length-delimited string to null-delimited string just for a printf

The extra copying isn’t necessary, since printf(3) can format length-delimited strings too.

I always end up looking this one up in the printf(3) man page.

 The precision

 An optional precision, in the form of a period ('.') followed by an optional decimal digit string. Instead of a decimal digit string one may write "*" or "*m$" (for some decimal integer m) to specify that the precision is given in the next argument, or in the m-th argument, respectively, which must be of type int. This gives ... the maximum number of characters to be printed from a string for s and S conversions.

Posted by Alan on Thursday, November 15, 2012. (Discuss)

Really, Actiontec?

Monday, October 29, 2012.

From a Verizon-branded Actiontec DSL router. Look for adminPassword in the javascript below

$ printf "GET / HTTP/1.1\r\n\r\n" | nc 192.168.1.1 80

HTTP/1.1 200 Ok
Server: micro_httpd
Cache-Control: no-cache
Date: Mon, 29 Oct 2012 17:50:28 GMT
Content-Type: text/html
Connection: close

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Actiontec</title>
<script language="JavaScript" src="js/nav.js"></script>
<script language="Javascript">

var adminPassword = "abc123";
function do_load(){

        if(adminPassword == "abc123")
                window.top.location.href='login.html';
        else
                window.top.location.href='index_real.html';
}
</script>
</head>

<body onload="do_load()">
<form  name="myform">

</form>
</body>
</html>

Posted by Alan on Monday, October 29, 2012. (Discuss)
maelstrom

"After a little while I became possessed with the keenest curiosity about the whirl itself. I positively felt a wish to explore its depths, even at the sacrifice I was going to make; and my principal grief was that I should never be able to tell my old companions on shore about the mysteries I should see."

Illustration for Edgar Allan Poe's story "Descent into the Maelstrom" by Harry Clarke, published in 1919.