6

I often run into situations like this:

title : Jekyll Bootstrap tagline: Site Tagline author : name : Name Lastname email : [email protected] github : username twitter : username feedburner : feedname 

Where the arguments are not lined up well, is there a standard way in vim for to have it formatted with each of the according arguments aligned to the nearest indent where an indent is defined as 2 spaces without having to go through line by line to the, such as in the following:

title : Jekyll Bootstrap tagline : Site Tagline author : name : Name Lastname email : [email protected] github : username twitter : username feedburner: feedname 

UPDATE:

I believe tabular.vim is the plugin I am looking for but I am having a difficult time forming a regular expression which would take into account the number of spaces at the beginning of the line when deciding something should be part of a block, i.e. Tabularize/: produces:

title : Jekyll Bootstrap tagline : Site Tagline author : name : Name Lastname email : [email protected] github : username twitter : username feedburner: feedname 

The is an example in the documentation where the following is achieved via a regular expression:

abc,def,ghi a,b a,b,c 

:Tabularize /^[^,]*\zs,/r0c0l0

abc,def,ghi a,b a,b,c 

But I am unsure how to formulate this when consider each line with the same number of spaces in front part of the same block while still evaluating subblock such as in the following more complex than my original example:

comments : provider : disqus disqus : short_name : jekyllbootstrap livefyre : site_id : 123 intensedebate : account : 123abc facebook : appid : 123 num_posts : 5 width : 580 colorscheme : light 

would be transformed tabularize\some_regular_expression_I_cant_figure_out to:

comments : provider : disqus disqus : short_name : jekyllbootstrap livefyre : site_id : 123 intensedebate : account : 123abc facebook : appid : 123 num_posts : 5 width : 580 colorscheme : light 
1
  • Helpful screen cast Commented Apr 5, 2012 at 15:11

2 Answers 2

4

The Tabularize plugin for vim can do exactly what you want. It comes down to typing Tabularize /:

This will probably not keep the indentation on the left however.

Edit on your updated question: I was not able to do that with Tabular directly, but I was able to do this with a second command, which is a search and replace on a range:

 :%s/\([ ]*\)[[:alpha:][:punct:]]*[ ]*/\0\1/ 

This searches for a certain amount of spaces in front of the :, and pastes them just before this semicolon.

4
  • thank you for your answer, that is exactly what I'm looking for but would you mind taking a peek at my latest update to the question? Commented Apr 5, 2012 at 15:06
  • 1
    I couldn't achieve that with Tabular, but offer a work-around in an edit. Commented Apr 5, 2012 at 18:39
  • There has to be a way to accomplish this via a single command! Commented Apr 5, 2012 at 23:51
  • Off course, if you dig into the Tabularize plugin you are certainly able to implement this. Good luck :) Commented Apr 6, 2012 at 8:19
2

So, bad news and good news. The bad news is that Tabular can't really do what you're asking for without a bit of work - the problem at hand requires more context than Tabular normally has access to. The good news is that Tabular is designed to allow being used as an extremely flexible general text manipulation tool, and in that context it's not too tough to get Tabular to do what you want.

Create a file named ~/.vim/after/plugin/TabularizeRecord.vim with these (hopefully heavily commented enough) contents:

" Create a new tabular pipeline named 'record' that includes all adjacent " lines containing a : in its default range, and manipulates those lines by " passing them through the TabularizeIndentedRecord function AddTabularPipeline! record /:/ TabularizeIndentedRecord(a:lines) function! TabularizeIndentedRecord(lines) " A list containing each of the lines with leading spaces removed let text = map(copy(a:lines), 'substitute(v:val, "^ *", "", "")') " A list containing just the leading spaces for each line let spaces = map(copy(a:lines), 'substitute(v:val, "^ *\\zs.*", "", "")') " Tabularize only the text, not the leading spaces. This pattern is more " complicated than just /:/ to handle lines with multiple colons. call tabular#TabularizeStrings(text, '[^:]*\zs:', 'l1') " Tack the spaces back on to the beginning of each line, and store the " resulting lines back in the a:lines list call map(a:lines, 'remove(spaces, 0) . remove(text, 0)') endfunction 

Once that file exists, restart vim, and you should then be able to get the indenting you want by doing:

:Tab record 

As far as I can tell, the end result of that is exactly what you're looking for - let me know if it doesn't work out for some reason, though, or if I misunderstood the requirements.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.