10

I have a frequent need to manually manipulate tab-delimited text for data entry and other purposes. When I do this, it helps if the text is aligned properly into columns. For example (assuming 4-space tabs):

# original format
abcdefghijklmnop    field2
abcdefgh    field2
abcdefghijkl    field2

# ideal format
abcdefghijklmnop    field2
abcdefgh            field2
abcdefghijkl        field2

I am very familiar with using the column utility to columnize text this way, but the problem is that it uses spaces to align the columns, and I specifically need tabs. This requirement also appears to rule out the Tabularize plug-in.

Is there any way that I can columnize text with tabs specifically, either within vim or at the shell? It looks like I might be able to do it with groff/tbl, but honestly I'd rather columnize it by hand than mess with that....

6 Answers 6

7

The csv.vim - A Filetype plugin for csv files also supports tab-delimited files, and has :ArrangeColumn and :UnArrangeColumn commands for that.

4
  • This actually sounds really promising. I will take a look and get back to you. Thanks!
    – kine
    Oct 30, 2013 at 17:11
  • I haven't actually tried this yet, but i'm going to mark it as the accepted answer based on the documentation of the plug-in, and the fact that the only other useful answer was written by you anyway. Cheers.
    – kine
    Nov 3, 2013 at 16:34
  • If you want to change colors, the fg colors are hardcoded in macvim. github.com/b4winckler/macvim/blob/master/src/…
    – Nick
    Sep 24, 2014 at 2:15
  • some sort of documented example of the syntax to use would help, since none exist on on the github page for that plugin.
    – ryantuck
    Mar 30, 2018 at 20:25
10

Set the tab display size to just larger than your longest field.

# original format
abcdefghijklmnop<Tab>field2
abcdefgh<Tab>field2
abcdefghijkl<Tab>field2
I have spaces!<Tab>field2

In Vim,

:echo len("abcdefghijklmnop") " Reports 16
:set noexpandtab tabstop=17

You can probably condense this to one command, but I don't know how. If you're running a modern Vim, :set list will indicate hard tabs with a fancy character (which you can also configure). Otherwise they'll just show as ^I (not what you want) or whitespace.

# displays like this
abcdefghijklmnop>field2
abcdefgh>        field2
abcdefghijkl>    field2
I have spaces!>  field2

EDIT: An example from a real running vim!

3

Ideally you would like to use a command like

column -t -o '\t' file

But this doesn't work, since the column program does not escape the \t to interpret it like a Tab. But you can still insert a literal tab. To do so, press Ctrl-V and then the Tab key. So your command should be something like this:

column -t -o '        ' file

Where the big ' ' is in fact a tab.

This works pretty neat. You can also run it inside vim. Visually select the lines you want to columnate, and then run:

:'<,'>!column -t -o '^I'

The '<,'> will automatically be written by vim, and the '^I is how vim will represent the literal tab, which you can insert with the method explained above.

1
1

When you have properly space-aligned the table (with the mentioned Tabularize or the alternative Align plugin), you can then convert the spaces to tabs with the following commands:

:%retab!
:%substitute/ \+/\t/g

The first command replaces indent with tabs where possible without changing the widths (this assumes you've :set noexpandtab), the second then transforms the left-over spaces to (larger) tabstops.

2
  • I guess this will work, but only if i can be absolutely certain that there are no spaces within the fields themselves. Otherwise, i am not sure how it would be able to tell the difference between spaces within a field and the columnating ones left over by :retab. I will accept this answer if nobody has a more ideal solution.
    – kine
    Oct 30, 2013 at 2:58
  • The initial alignment wouldn't handle spaces within the fields, neither (but align on them, too). If you have such data, you'd probably have to substitute those inner spaces temporarily. Oct 30, 2013 at 6:15
1

Using godlygeek/tabular plugin you can select

:%Tabularize /\t.*/

As mentioned by @paul-rougieux in the comments we can abreviate the above command to:

:%Tab /\t.*/
1
  • You can abbreviate :Tabularize and call it like this :Tab /\t to align all tab separated text in the current buffer. Jul 21, 2020 at 9:31
-1

Tab-separated columns only work when the program used to display them is able to expand/shrink tab characters to honor their actual meaning. Vim, and I believe most other plain text editors, is unable to use tabs for tabulation because tabs have a single fixed width. Vim can use a mix of tabs and spaces to obtain a roughly similar result but what you'd get is obviously not tab-separated anymore.

You'd need to convert all those tab/spaces mixes into single tabs on each write.

In short, a plain text editor is probably not the right tool for the job.

1
  • "tabs have a single fixed width" Not true. See my answer. Many other editors have configurable tab size as wel. Jun 1, 2014 at 21:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .