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: