Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| *Tabular.txt* Configurable, flexible, intuitive text aligning | |
| *tabular* *tabular.vim* | |
| #|#|#|#|#| #| #| ~ | |
| #| #|#|#| #|#|#| #| #| #| #|#|#| #| #|#| ~ | |
| #| #| #| #| #| #| #| #| #| #| #|#| ~ | |
| #| #| #| #| #| #| #| #| #| #| #| ~ | |
| #| #|#|#| #|#|#| #|#|#| #| #|#|#| #| ~ | |
| For Vim version 7.0 or newer | |
| By Matt Wozniski | |
| mjw@drexel.edu | |
| Reference Manual ~ | |
| *tabular-toc* | |
| 1. Description |tabular-intro| | |
| 2. Walkthrough |tabular-walkthrough| | |
| 3. Scripting |tabular-scripting| | |
| The functionality mentioned here is a plugin, see |add-plugin|. | |
| You can avoid loading this plugin by setting the "Tabular_loaded" global | |
| variable in your |vimrc| file: > | |
| :let g:tabular_loaded = 1 | |
| ============================================================================== | |
| 1. Description *tabular-intro* | |
| Sometimes, it's useful to line up text. Naturally, it's nicer to have the | |
| computer do this for you, since aligning things by hand quickly becomes | |
| unpleasant. While there are other plugins for aligning text, the ones I've | |
| tried are either impossibly difficult to understand and use, or too simplistic | |
| to handle complicated tasks. This plugin aims to make the easy things easy | |
| and the hard things possible, without providing an unnecessarily obtuse | |
| interface. It's still a work in progress, and criticisms are welcome. | |
| ============================================================================== | |
| 2. Walkthrough *tabular-walkthrough* *:Tabularize* | |
| Tabular's commands are based largely on regular expressions. The basic | |
| technique used by Tabular is taking some regex to match field delimiters, | |
| splitting the input lines at those delimiters, trimming unnecessary spaces | |
| from the non-delimiter parts, padding the non-delimiter parts of the lines | |
| with spaces to make them the same length, and joining things back together | |
| again. | |
| For instance, consider starting with the following lines: | |
| > | |
| Some short phrase,some other phrase | |
| A much longer phrase here,and another long phrase | |
| < | |
| Let's say we want to line these lines up at the commas. We can tell | |
| Tabularize to do this by passing a pattern matching , to the Tabularize | |
| command: | |
| > | |
| :Tabularize /, | |
| Some short phrase , some other phrase | |
| A much longer phrase here , and another long phrase | |
| < | |
| I encourage you to try copying those lines to another buffer and trying to | |
| call :Tabularize. You'll want to take notice of two things quickly: First, | |
| instead of requiring a range, Tabularize tries to figure out what you want to | |
| happen. Since it knows that you want to act on lines matching a comma, it | |
| will look upwards and downwards for lines around the current line that match a | |
| comma, and consider all contiguous lines matching the pattern to be the range | |
| to be acted upon. You can always override this by specifying a range, though. | |
| The second thing you should notice is that you'll almost certainly be able to | |
| abbreviate :Tabularize to :Tab - using this form in mappings and scripts is | |
| discouraged as it will make conflicts with other scripts more likely, but for | |
| interactive use it's a nice timesaver. Another convenience feature is that | |
| running :Tabularize without providing a new pattern will cause it to reuse the | |
| last pattern it was called with. | |
| So, anyway, now the commas line up. Splitting the lines on commas, Tabular | |
| realized that 'Some short phrase' would need to be padded with spaces to match | |
| the length of 'A much longer phrase here', and it did that before joining the | |
| lines back together. You'll also notice that, in addition to the spaces | |
| inserting for padding, extra spaces were inserted between fields. That's | |
| because by default, Tabular prints things left-aligned with one space between | |
| fields. If you wanted to print things right-aligned with no spaces between | |
| fields, you would provide a different format to the Tabularize command: | |
| > | |
| :Tabularize /,/r0 | |
| Some short phrase, some other phrase | |
| A much longer phrase here,and another long phrase | |
| < | |
| A format specifier is either l, r, or c, followed by one or more digits. If | |
| the letter is l, the field will be left aligned, similarly for r and right | |
| aligning and c and center aligning. The number following the letter is the | |
| number of spaces padding to insert before the start of the next field. | |
| Multiple format specifiers can be added to the same command - each field will | |
| be printed with the next format specifier in the list; when they all have been | |
| used the first will be used again, and so on. So, the last command right | |
| aligned every field, then inserted 0 spaces of padding before the next field. | |
| What if we wanted to right align the text before the comma, and left align the | |
| text after the comma? The command would look like this: | |
| > | |
| :Tabularize /,/r1c1l0 | |
| Some short phrase , some other phrase | |
| A much longer phrase here , and another long phrase | |
| < | |
| That command would be read as "Align the matching text, splitting fields on | |
| commas. Print everything before the first comma right aligned, then 1 space, | |
| then the comma center aligned, then 1 space, then everything after the comma | |
| left aligned." Notice that the alignment of the field the comma is in is | |
| irrelevant - since it's only 1 cell wide, it looks the same whether it's right, | |
| left, or center aligned. Also notice that the 0 padding spaces specified for | |
| the 3rd field are unused - but they would be used if there were enough fields | |
| to require looping through the fields again. For instance: | |
| > | |
| abc,def,ghi | |
| a,b | |
| a,b,c | |
| :Tabularize /,/r1c1l0 | |
| abc , def, ghi | |
| a , b | |
| a , b , c | |
| < | |
| Notice that now, the format pattern has been reused; field 4 (the second comma) | |
| is right aligned, field 5 is center aligned. No spaces were inserted between | |
| the 3rd field (containing "def") and the 4th field (the second comma) because | |
| the format specified 'l0'. | |
| But, what if you only wanted to act on the first comma on the line, rather than | |
| all of the commas on the line? Let's say we want everything before the first | |
| comma right aligned, then the comma, then everything after the comma left | |
| aligned: | |
| > | |
| abc,def,ghi | |
| a,b | |
| a,b,c | |
| :Tabularize /^[^,]*\zs,/r0c0l0 | |
| abc,def,ghi | |
| a,b | |
| a,b,c | |
| < | |
| Here, we used a Vim regex that would only match the first comma on the line. | |
| It matches the beginning of the line, followed by all the non-comma characters | |
| up to the first comma, and then forgets about what it matched so far and | |
| pretends that the match starts exactly at the comma. | |
| But, now that this command does exactly what we want it to, it's become pretty | |
| unwieldy. It would be unpleasant to need to type that more than once or | |
| twice. The solution is to assign a name to it. | |
| > | |
| :AddTabularPattern first_comma /^[^,]*\zs,/r0c0l0 | |
| < | |
| Now, typing ":Tabularize first_comma" will do the same thing as typing the | |
| whole pattern out each time. Of course this is more useful if you store the | |
| name in a file to be used later. | |
| NOTE: In order to make these new commands available every time vim starts, | |
| you'll need to put those new commands into a .vim file in a plugin directory | |
| somewhere in your 'runtimepath'. In order to make sure that Tabular.vim has | |
| already been loaded before your file tries to use :AddTabularPattern or | |
| :AddTabularPipeline, the new file should be installed in an after/plugin | |
| directory in 'runtimepath'. In general, it will be safe to find out where the | |
| TabularMaps.vim plugin was installed, and place other files extending | |
| Tabular.vim in the same directory as TabularMaps.vim. For more information, | |
| and some suggested best practices, check out the |tabular-scripting| section. | |
| Lastly, we'll approach the case where tabular cannot achieve your desired goal | |
| just by splitting lines appart, trimming whitespace, padding with whitespace, | |
| and rejoining the lines. As an example, consider the multiple_spaces command | |
| from TabularMaps.vim. The goal is to split using two or more spaces as a | |
| field delimiter, and join fields back together, properly lined up, with only | |
| two spaces between the end of each field and the beginning of the next. | |
| Unfortunately, Tabular can't do this with only the commands we know so far: | |
| > | |
| :Tabularize / / | |
| < | |
| The above function won't work, because it will consider "a b" as 5 fields | |
| delimited by two pairs of 2 spaces ( 'a', ' ', '', ' ', 'b' ) instead of as | |
| 3 fields delimited by one set of 2 or more spaces ( 'a', ' ', 'b' ). | |
| > | |
| :Tabularize / \+/ | |
| < | |
| The above function won't work either, because it will leave the delimiter as 4 | |
| spaces when used against "a b", meaning that we would fail at our goal of | |
| collapsing everything down to two spaces between fields. So, we need a new | |
| command to get around this: | |
| > | |
| :AddTabularPipeline multiple_spaces / \{2,}/ | |
| \ map(a:lines, "substitute(v:val, ' \{2,}', ' ', 'g')") | |
| \ | tabular#TabularizeStrings(a:lines, ' ', 'l0') | |
| < | |
| Yeah. I know it looks complicated. Bear with me. I probably will try to add | |
| in some shortcuts for this syntax, but this verbose will be guaranteed to | |
| always work. | |
| You should already recognize the name being assigned. The next thing to | |
| happen is / \{2,}/ which is a pattern specifying which lines should | |
| automatically be included in the range when no range is given. Without this, | |
| there would be no pattern to use for extending the range. Everything after | |
| that is a | separated list of expressions to be evaluated. In the context in | |
| which they will be evaluated, a:lines will be set to a List of Strings | |
| containing the text of the lines being filtered as they procede through the | |
| pipeline you've set up. The \ at the start of the lines are just vim's line | |
| continuation marker; you needn't worry much about them. So, the first | |
| expression in the pipeline transforms each line by replacing every instance of | |
| 2 or more spaces with exactly two spaces. The second command in the pipeline | |
| performs the equivalent of ":Tabularize / /l0"; the only difference is that | |
| it is operating on a List of Strings rather than text in the buffer. At the | |
| end of the pipeline, the Strings in the modified a:lines (or the return value | |
| of the last expression in the pipeline, if it returns a List) will replace the | |
| chosen range. | |
| ============================================================================== | |
| 3. Extending *tabular-scripting* | |
| As mentioned above, the most important consideration when extending Tabular | |
| with new maps or commands is that your plugin must be loaded after Tabular.vim | |
| has finished loading, and only if Tabular.vim has loaded successfully. The | |
| easiest approach to making sure it loads after Tabular.vim is simply putting | |
| the new file (we'll call it "tabular_extra.vim" as an example) into an | |
| "after/plugin/" directory in 'runtimepath', for instance: | |
| > | |
| ~/.vim/after/plugin/tabular_extra.vim | |
| < | |
| The default set of mappings, found in "TabularMaps.vim", is installed in | |
| the after/plugin/ subdirectory of whatever directory Tabular was installed to. | |
| The other important consideration is making sure that your commands are only | |
| called if Tabular.vim was actually loaded. The easiest way to do this is by | |
| checking for the existence of the :Tabularize command at the start of your | |
| plugin. A short example plugin would look like this: | |
| > | |
| " after/plugin/my_tabular_commands.vim | |
| " Provides extra :Tabularize commands | |
| if !exists(':Tabularize') | |
| finish " Give up here; the Tabular plugin musn't have been loaded | |
| endif | |
| " Make line wrapping possible by resetting the 'cpo' option, first saving it | |
| let s:save_cpo = &cpo | |
| set cpo&vim | |
| AddTabularPattern! asterisk /*/l1 | |
| AddTabularPipeline! remove_leading_spaces /^ / | |
| \ map(a:lines, "substitute(v:val, '^ *', '', '')") | |
| " Restore the saved value of 'cpo' | |
| let &cpo = s:save_cpo | |
| unlet s:save_cpo | |
| < | |
| ============================================================================== | |
| vim:tw=78:fo=tcq2:isk=!-~,^*,^\|,^\":ts=8:ft=help:norl: |