From 6d841110af7ed4588bfae06dcabe651449f2d66f Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Fri, 2 Aug 2013 12:21:55 +0900 Subject: [PATCH] Allow rule-wise configuration of `ignores` and `ignore_unmatched` --- EXAMPLES.md | 76 +++++++++++++++++++++++++++++++++++++---- README.md | 25 ++++++++++++-- autoload/easy_align.vim | 17 +++++---- 3 files changed, 102 insertions(+), 16 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index d3bfa98..97fa3d8 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -1,5 +1,3 @@ -vim: set scrolloff=1 buftype=nofile colorcolumn=: - vim-easy-align examples ======================= @@ -37,10 +35,13 @@ Pete Best 1941 ``` - Formatting table ---------------- +Try `*|` + +``` + | Option| Type | Default | Description | |--|--|--|--| | threads | Fixnum | 1 | number of threads in the thread pool | @@ -51,10 +52,21 @@ Formatting table |batch_size | Fixnum | nil | number of maximum items to be assigned at once | |logger | Logger | nil | logger instance for debug logs | +``` + Alignment around = ------------------ +The default rule for delimiter key `=` aligns around the most of the operators +containing `=` character. + +Try: +- `=` +- `*=` +- `**=` +- `**=` + ```ruby a = @@ -87,15 +99,18 @@ gg <=> ee Formatting YAML (or JSON) ------------------------- +Try `:` here, to align text around only the first occurrences of colons. +In this case, you don't want to align around all the colons: `*:`. + ```yaml mysql: # JDBC driver for MySQL database: - driver: com.mysql.jdbc.Driver + driver: com.mysql.jdbc.Driver # JDBC URL for the connection (jdbc:mysql://HOSTNAME/DATABASE) - url: jdbc:mysql://localhost/test - database: test - "user:pass":r00t:pa55 + url: jdbc:mysql://localhost/test + database: test + "user:pass": r00t:pa55 ``` @@ -113,6 +128,9 @@ options = { :caching => nil, Commas ------ +There is also a predefined rule for commas, try `*,` for the following +lines. + ``` aaa, bb,c @@ -126,11 +144,55 @@ j,,k Ignoring delimiters in comments and strings ------------------------------------------- +Delimiters highlighted as comments or strings are ignored by default, try +`*=` for the following lines. + ```c + /* a */ b = c aa >= bb // aaa = bbb = cccc /* aaaa = */ bbbb === cccc " = dddd = " = eeee aaaaa /* bbbbb */ == ccccc /* != eeeee = */ === fffff + +``` + +Aligning in-line comments +------------------------- + +```ruby +apple = 1 # comment not aligned +banana = "string" # comment 2 +``` + +So, how do we align the trailing comments in the above lines? +Simply try `-`! The spaces in the comments are ignored, so the +trailing comment in each line is considered to be a single chunk. + +But this doesn't work in the following case. + +```ruby +apple = 1 # comment not aligned +apricot = 'A#B' +banana = 'string' # comment 2 +``` + +The second line doesn't have trailing comment, and *the last space* is the one +before `'A#B'`. So we define a custom mapping for `#` + +```vim +if !exists('g:easy_align_delimiters') + let g:easy_align_delimiters = {} +endif +let g:easy_align_delimiters['#'] = { 'pattern': '#\+', 'ignores': ['String'] } } +``` + +Notice that the rule overrides `ignores` attribute in order *not* to ignore +delimiters highlighted as comments. Then we try `#`, to get + +```ruby +apple = 1 # comment not aligned +apricot = 'A#B' +banana = 'string' # comment 2 ``` diff --git a/README.md b/README.md index 1da3890..67bc74a 100644 --- a/README.md +++ b/README.md @@ -233,12 +233,27 @@ Then we get, ### Extending alignment rules +Although the default predefined rules should cover the most of the use cases, +you can extend the rules by setting a dictionary named `g:easy_align_delimiters`. +Each entry in the dictionary can have the following attributes. + +| Atrribute | Type | Default | +| ---------------- | ------- | --------------------- | +| pattern | regexp | | +| margin_left | string | `' '` | +| margin_right | string | `' '` | +| stick_to_left | boolean | 0 | +| ignore_unmatched | boolean | 1 | +| ignores | array | ['String', 'Comment'] | + +#### Example + ```vim " Examples let g:easy_align_delimiters = { \ '>': { 'pattern': '>>\|=>\|>' }, -\ '/': { 'pattern': '//\+\|/\*\|\*/' }, -\ '#': { 'pattern': '#\+' }, +\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] }, +\ '#': { 'pattern': '#\+', 'ignores': ['String'] }, \ ']': { \ 'pattern': '[\[\]]', \ 'margin_left': '', @@ -254,6 +269,12 @@ let g:easy_align_delimiters = { \ } ``` +Examples and use cases +---------------------- + +See the [link](https://github.com/junegunn/vim-easy-align/blob/master/EXAMPLES.md) +for more examples. + Author ------ diff --git a/autoload/easy_align.vim b/autoload/easy_align.vim index d3a35a9..79c79db 100644 --- a/autoload/easy_align.vim +++ b/autoload/easy_align.vim @@ -73,13 +73,12 @@ function! s:ignored_syntax() endif endfunction -function! s:do_align(just, all_tokens, fl, ll, fc, lc, pattern, nth, ml, mr, stick_to_left, recursive) +function! s:do_align(just, all_tokens, fl, ll, fc, lc, pattern, nth, ml, mr, stick_to_left, ignore_unmatched, ignores, recursive) let lines = {} let max_just_len = 0 let max_delim_len = 0 let max_tokens = 0 let pattern = '\s*\(' .a:pattern. '\)\s' . (a:stick_to_left ? '*' : '\{-}') - let ignored_syntax = s:ignored_syntax() " Phase 1 for line in range(a:fl, a:ll) @@ -90,7 +89,7 @@ function! s:do_align(just, all_tokens, fl, ll, fc, lc, pattern, nth, ml, mr, sti \ strpart(getline(line), a:fc - 1), \ pattern.'\zs') let concat = 0 - if empty(ignored_syntax) + if empty(a:ignores) let tokens = raw_tokens else " Concat adjacent tokens that are split by ignorable delimiters @@ -103,7 +102,7 @@ function! s:do_align(just, all_tokens, fl, ll, fc, lc, pattern, nth, ml, mr, sti else call add(tokens, token) endif - let concat = s:highlighted_as(line, idx + a:fc - 1, ignored_syntax) + let concat = s:highlighted_as(line, idx + a:fc - 1, a:ignores) endfor endif @@ -152,7 +151,7 @@ function! s:do_align(just, all_tokens, fl, ll, fc, lc, pattern, nth, ml, mr, sti let token = substitute(last, pattern.'$', '', '') let delim = get(matchlist(last, pattern.'$'), 1, '') - if empty(delim) && a:just == 0 && get(g:, 'easy_align_ignore_unmatched', 1) + if empty(delim) && a:just == 0 && a:ignore_unmatched continue endif @@ -211,7 +210,8 @@ function! s:do_align(just, all_tokens, fl, ll, fc, lc, pattern, nth, ml, mr, sti if a:recursive && a:nth < max_tokens let just = a:recursive == 2 ? !a:just : a:just call s:do_align(just, a:all_tokens, a:fl, a:ll, a:fc, a:lc, a:pattern, - \ a:nth + 1, a:ml, a:mr, a:stick_to_left, a:recursive) + \ a:nth + 1, a:ml, a:mr, a:stick_to_left, a:ignore_unmatched, + \ a:ignores, a:recursive) endif endfunction @@ -298,7 +298,10 @@ function! easy_align#align(just, ...) range \ nth, \ get(dict, 'margin_left', ' '), \ get(dict, 'margin_right', ' '), - \ get(dict, 'stick_to_left', 0), recursive) + \ get(dict, 'stick_to_left', 0), + \ get(dict, 'ignore_unmatched', get(g:, 'easy_align_ignore_unmatched', 1)), + \ get(dict, 'ignores', s:ignored_syntax()), + \ recursive) call s:echon(just, n, ch) else echon "\rUnknown delimiter: ". ch