citadel

My dotfiles, scripts and nix configs
git clone git://jb55.com/citadel
Log | Files | Refs | README | LICENSE

Tabular.txt (12376B)


      1 *Tabular.txt*   Configurable, flexible, intuitive text aligning
      2 
      3                                                        *tabular* *tabular.vim*
      4 
      5        #|#|#|#|#|          #|                  #|                     ~
      6            #|      #|#|#|  #|#|#|    #|    #|  #|    #|#|#|  #|  #|#| ~
      7            #|    #|    #|  #|    #|  #|    #|  #|  #|    #|  #|#|     ~
      8            #|    #|    #|  #|    #|  #|    #|  #|  #|    #|  #|       ~
      9            #|      #|#|#|  #|#|#|      #|#|#|  #|    #|#|#|  #|       ~
     10 
     11                                                   For Vim version 7.0 or newer
     12 
     13                                By Matt Wozniski
     14                                 mjw@drexel.edu
     15 
     16                                Reference Manual ~
     17 
     18                                                                  *tabular-toc*
     19 
     20 1. Description                                           |tabular-intro|
     21 2. Walkthrough                                           |tabular-walkthrough|
     22 3. Scripting                                             |tabular-scripting|
     23 
     24 The functionality mentioned here is a plugin, see |add-plugin|.
     25 You can avoid loading this plugin by setting the "Tabular_loaded" global
     26 variable in your |vimrc| file: >
     27     :let g:tabular_loaded = 1
     28 
     29 ==============================================================================
     30 1. Description                                                 *tabular-intro*
     31 
     32 Sometimes, it's useful to line up text.  Naturally, it's nicer to have the
     33 computer do this for you, since aligning things by hand quickly becomes
     34 unpleasant.  While there are other plugins for aligning text, the ones I've
     35 tried are either impossibly difficult to understand and use, or too simplistic
     36 to handle complicated tasks.  This plugin aims to make the easy things easy
     37 and the hard things possible, without providing an unnecessarily obtuse
     38 interface.  It's still a work in progress, and criticisms are welcome.
     39 
     40 ==============================================================================
     41 2. Walkthrough                                           *tabular-walkthrough*
     42 
     43 Tabular's commands are based largely on regular expressions.  The basic
     44 technique used by Tabular is taking some regex to match field delimiters,
     45 splitting the input lines at those delimiters, trimming unnecessary spaces
     46 from the non-delimiter parts, padding the non-delimiter parts of the lines
     47 with spaces to make them the same length, and joining things back together
     48 again.
     49 
     50 For instance, consider starting with the following lines:
     51 >
     52     Some short phrase,some other phrase
     53     A much longer phrase here,and another long phrase
     54 <
     55 Let's say we want to line these lines up at the commas.  We can tell
     56 Tabularize to do this by passing a pattern matching , to the Tabularize
     57 command:
     58 >
     59   :Tabularize /,
     60 
     61     Some short phrase         , some other phrase
     62     A much longer phrase here , and another long phrase
     63 <
     64 I encourage you to try copying those lines to another buffer and trying to
     65 call :Tabularize.  You'll want to take notice of two things quickly: First,
     66 instead of requiring a range, Tabularize tries to figure out what you want to
     67 happen.  Since it knows that you want to act on lines matching a comma, it
     68 will look upwards and downwards for lines around the current line that match a
     69 comma, and consider all contiguous lines matching the pattern to be the range
     70 to be acted upon.  You can always override this by specifying a range, though.
     71 
     72 The second thing you should notice is that you'll almost certainly be able to
     73 abbreviate :Tabularize to :Tab - using this form in mappings and scripts is
     74 discouraged as it will make conflicts with other scripts more likely, but for
     75 interactive use it's a nice timesaver.
     76 
     77 So, anyway, now the commas line up.  Splitting the lines on commas, Tabular
     78 realized that 'Some short phrase' would need to be padded with spaces to match
     79 the length of 'A much longer phrase here', and it did that before joining the
     80 lines back together.  You'll also notice that, in addition to the spaces
     81 inserting for padding, extra spaces were inserted between fields.  That's
     82 because by default, Tabular prints things left-aligned with one space between
     83 fields.  If you wanted to print things right-aligned with no spaces between
     84 fields, you would provide a different format to the Tabularize command:
     85 >
     86   :Tabularize /,/r0
     87 
     88             Some short phrase,      some other phrase
     89     A much longer phrase here,and another long phrase
     90 <
     91 A format specifier is either l, r, or c, followed by one or more digits.  If
     92 the letter is l, the field will be left aligned, similarly for r and right
     93 aligning and c and center aligning.  The number following the letter is the
     94 number of spaces padding to insert before the start of the next field.
     95 Multiple format specifiers can be added to the same command - each field will
     96 be printed with the next format specifier in the list; when they all have been
     97 used the first will be used again, and so on.  So, the last command right
     98 aligned every field, then inserted 0 spaces of padding before the next field.
     99 What if we wanted to right align the text before the comma, and left align the
    100 text after the comma?  The command would look like this:
    101 >
    102   :Tabularize /,/r1c1l0
    103 
    104             Some short phrase , some other phrase
    105     A much longer phrase here , and another long phrase
    106 <
    107 That command would be read as "Align the matching text, splitting fields on
    108 commas.  Print everything before the first comma right aligned, then 1 space,
    109 then the comma center aligned, then 1 space, then everything after the comma
    110 left aligned."  Notice that the alignment of the field the comma is in is
    111 irrelevant - since it's only 1 cell wide, it looks the same whether it's right,
    112 left, or center aligned.  Also notice that the 0 padding spaces specified for
    113 the 3rd field are unused - but they would be used if there were enough fields
    114 to require looping through the fields again.  For instance:
    115 >
    116     abc,def,ghi
    117     a,b
    118     a,b,c
    119 
    120   :Tabularize /,/r1c1l0
    121 
    122     abc , def, ghi
    123       a , b
    124       a , b  ,  c
    125 <
    126 Notice that now, the format pattern has been reused; field 4 (the second comma)
    127 is right aligned, field 5 is center aligned.  No spaces were inserted between
    128 the 3rd field (containing "def") and the 4th field (the second comma) because
    129 the format specified 'l0'.
    130 
    131 But, what if you only wanted to act on the first comma on the line, rather than
    132 all of the commas on the line?  Let's say we want everything before the first
    133 comma right aligned, then the comma, then everything after the comma left
    134 aligned:
    135 >
    136     abc,def,ghi
    137     a,b
    138     a,b,c
    139 
    140   :Tabularize /^[^,]*\zs,/r0c0l0
    141 
    142     abc,def,ghi
    143       a,b
    144       a,b,c
    145 <
    146 Here, we used a Vim regex that would only match the first comma on the line.
    147 It matches the beginning of the line, followed by all the non-comma characters
    148 up to the first comma, and then forgets about what it matched so far and
    149 pretends that the match starts exactly at the comma.
    150 
    151 But, now that this command does exactly what we want it to, it's become pretty
    152 unwieldy.  It would be unpleasant to need to type that more than once or
    153 twice.  The solution is to assign a name to it.
    154 >
    155   :AddTabularPattern first_comma /^[^,]*\zs,/r0c0l0
    156 <
    157 Now, typing ":Tabularize first_comma" will do the same thing as typing the
    158 whole pattern out each time.  Of course this is more useful if you store the
    159 name in a file to be used later.
    160 
    161 NOTE: In order to make these new commands available every time vim starts,
    162 you'll need to put those new commands into a .vim file in a plugin directory
    163 somewhere in your 'runtimepath'.  In order to make sure that Tabular.vim has
    164 already been loaded before your file tries to use :AddTabularPattern or
    165 :AddTabularPipeline, the new file should be installed in an after/plugin
    166 directory in 'runtimepath'.  In general, it will be safe to find out where the
    167 TabularMaps.vim plugin was installed, and place other files extending
    168 Tabular.vim in the same directory as TabularMaps.vim.  For more information,
    169 and some suggested best practices, check out the |tabular-scripting| section.
    170 
    171 Lastly, we'll approach the case where tabular cannot achieve your desired goal
    172 just by splitting lines appart, trimming whitespace, padding with whitespace,
    173 and rejoining the lines.  As an example, consider the multiple_spaces command
    174 from TabularMaps.vim.  The goal is to split using two or more spaces as a
    175 field delimiter, and join fields back together, properly lined up, with only
    176 two spaces between the end of each field and the beginning of the next.
    177 Unfortunately, Tabular can't do this with only the commands we know so far:
    178 >
    179   :Tabularize /  /
    180 <
    181 The above function won't work, because it will consider "a    b" as 5 fields
    182 delimited by two pairs of 2 spaces ( 'a', '  ', '', '  ', 'b' ) instead of as
    183 3 fields delimited by one set of 2 or more spaces ( 'a', '    ', 'b' ).
    184 >
    185   :Tabularize /  \+/
    186 <
    187 The above function won't work either, because it will leave the delimiter as 4
    188 spaces when used against "a    b", meaning that we would fail at our goal of
    189 collapsing everything down to two spaces between fields.  So, we need a new
    190 command to get around this:
    191 >
    192   :AddTabularPipeline multiple_spaces / \{2,}/
    193     \ map(a:lines, "substitute(v:val, ' \{2,}', '  ', 'g')")
    194     \   | tabular#TabularizeStrings(a:lines, '  ', 'l0')
    195 <
    196 Yeah.  I know it looks complicated.  Bear with me.  I probably will try to add
    197 in some shortcuts for this syntax, but this verbose will be guaranteed to
    198 always work.
    199 
    200 You should already recognize the name being assigned.  The next thing to
    201 happen is / \{2,}/ which is a pattern specifying which lines should
    202 automatically be included in the range when no range is given.  Without this,
    203 there would be no pattern to use for extending the range.  Everything after
    204 that is a | separated list of expressions to be evaluated.  In the context in
    205 which they will be evaluated, a:lines will be set to a List of Strings
    206 containing the text of the lines being filtered as they procede through the
    207 pipeline you've set up.  The \ at the start of the lines are just vim's line
    208 continuation marker; you needn't worry much about them.  So, the first
    209 expression in the pipeline transforms each line by replacing every instance of
    210 2 or more spaces with exactly two spaces.  The second command in the pipeline
    211 performs the equivalent of ":Tabularize /  /l0"; the only difference is that
    212 it is operating on a List of Strings rather than text in the buffer.  At the
    213 end of the pipeline, the Strings in the modified a:lines (or the return value
    214 of the last expression in the pipeline, if it returns a List) will replace the
    215 chosen range.
    216 
    217 ==============================================================================
    218 3. Extending                                               *tabular-scripting*
    219 
    220 As mentioned above, the most important consideration when extending Tabular
    221 with new maps or commands is that your plugin must be loaded after Tabular.vim
    222 has finished loading, and only if Tabular.vim has loaded successfully.  The
    223 easiest approach to making sure it loads after Tabular.vim is simply putting
    224 the new file (we'll call it "tabular_extra.vim" as an example) into an
    225 "after/plugin/" directory in 'runtimepath', for instance:
    226 >
    227   ~/.vim/after/plugin/tabular_extra.vim
    228 <
    229 The default set of mappings, found in "TabularMaps.vim", is installed in
    230 the after/plugin/ subdirectory of whatever directory Tabular was installed to.
    231 
    232 The other important consideration is making sure that your commands are only
    233 called if Tabular.vim was actually loaded.  The easiest way to do this is by
    234 checking for the existence of the :Tabularize command at the start of your
    235 plugin.  A short example plugin would look like this:
    236 >
    237   " after/plugin/my_tabular_commands.vim
    238   " Provides extra :Tabularize commands
    239 
    240   if !exists(':Tabularize')
    241     finish " Give up here; the Tabular plugin musn't have been loaded
    242   endif
    243 
    244   " Make line wrapping possible by resetting the 'cpo' option, first saving it
    245   let s:save_cpo = &cpo
    246   set cpo&vim
    247 
    248   AddTabularPattern! asterisk /*/l1
    249 
    250   AddTabularPipeline! remove_leading_spaces /^ /
    251                   \ map(a:lines, "substitute(v:val, '^ *', '', '')")
    252 
    253   " Restore the saved value of 'cpo'
    254   let &cpo = s:save_cpo
    255   unlet s:save_cpo
    256 <
    257 ==============================================================================
    258 vim:tw=78:fo=tcq2:isk=!-~,^*,^\|,^\":ts=8:ft=help:norl: