Allow rule-wise configuration of ignores and ignore_unmatched

This commit is contained in:
Junegunn Choi
2013-08-02 12:21:55 +09:00
parent ec456f82a6
commit 6d841110af
3 changed files with 102 additions and 16 deletions

View File

@@ -1,5 +1,3 @@
vim: set scrolloff=1 buftype=nofile colorcolumn=:
vim-easy-align examples vim-easy-align examples
======================= =======================
@@ -37,10 +35,13 @@ Pete Best 1941
``` ```
Formatting table Formatting table
---------------- ----------------
Try `<Enter>*|`
```
| Option| Type | Default | Description | | Option| Type | Default | Description |
|--|--|--|--| |--|--|--|--|
| threads | Fixnum | 1 | number of threads in the thread pool | | 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 | |batch_size | Fixnum | nil | number of maximum items to be assigned at once |
|logger | Logger | nil | logger instance for debug logs | |logger | Logger | nil | logger instance for debug logs |
```
Alignment around = Alignment around =
------------------ ------------------
The default rule for delimiter key `=` aligns around the most of the operators
containing `=` character.
Try:
- `<Enter>=`
- `<Enter>*=`
- `<Enter>**=`
- `<Enter><Enter>**=`
```ruby ```ruby
a = a =
@@ -87,15 +99,18 @@ gg <=> ee
Formatting YAML (or JSON) Formatting YAML (or JSON)
------------------------- -------------------------
Try `<Enter>:` here, to align text around only the first occurrences of colons.
In this case, you don't want to align around all the colons: `<Enter>*:`.
```yaml ```yaml
mysql: mysql:
# JDBC driver for MySQL database: # JDBC driver for MySQL database:
driver: com.mysql.jdbc.Driver driver: com.mysql.jdbc.Driver
# JDBC URL for the connection (jdbc:mysql://HOSTNAME/DATABASE) # JDBC URL for the connection (jdbc:mysql://HOSTNAME/DATABASE)
url: jdbc:mysql://localhost/test url: jdbc:mysql://localhost/test
database: test database: test
"user:pass":r00t:pa55 "user:pass": r00t:pa55
``` ```
@@ -113,6 +128,9 @@ options = { :caching => nil,
Commas Commas
------ ------
There is also a predefined rule for commas, try `<Enter>*,` for the following
lines.
``` ```
aaa, bb,c aaa, bb,c
@@ -126,11 +144,55 @@ j,,k
Ignoring delimiters in comments and strings Ignoring delimiters in comments and strings
------------------------------------------- -------------------------------------------
Delimiters highlighted as comments or strings are ignored by default, try
`<Enter>*=` for the following lines.
```c ```c
/* a */ b = c /* a */ b = c
aa >= bb aa >= bb
// aaa = bbb = cccc // aaa = bbb = cccc
/* aaaa = */ bbbb === cccc " = dddd = " = eeee /* aaaa = */ bbbb === cccc " = dddd = " = eeee
aaaaa /* bbbbb */ == ccccc /* != eeeee = */ === fffff 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 `<Enter>-<space>`! 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 `<Enter>#`, to get
```ruby
apple = 1 # comment not aligned
apricot = 'A#B'
banana = 'string' # comment 2
``` ```

View File

@@ -233,12 +233,27 @@ Then we get,
### Extending alignment rules ### 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 ```vim
" Examples " Examples
let g:easy_align_delimiters = { let g:easy_align_delimiters = {
\ '>': { 'pattern': '>>\|=>\|>' }, \ '>': { 'pattern': '>>\|=>\|>' },
\ '/': { 'pattern': '//\+\|/\*\|\*/' }, \ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] },
\ '#': { 'pattern': '#\+' }, \ '#': { 'pattern': '#\+', 'ignores': ['String'] },
\ ']': { \ ']': {
\ 'pattern': '[\[\]]', \ 'pattern': '[\[\]]',
\ 'margin_left': '', \ '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 Author
------ ------

View File

@@ -73,13 +73,12 @@ function! s:ignored_syntax()
endif endif
endfunction 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 lines = {}
let max_just_len = 0 let max_just_len = 0
let max_delim_len = 0 let max_delim_len = 0
let max_tokens = 0 let max_tokens = 0
let pattern = '\s*\(' .a:pattern. '\)\s' . (a:stick_to_left ? '*' : '\{-}') let pattern = '\s*\(' .a:pattern. '\)\s' . (a:stick_to_left ? '*' : '\{-}')
let ignored_syntax = s:ignored_syntax()
" Phase 1 " Phase 1
for line in range(a:fl, a:ll) 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), \ strpart(getline(line), a:fc - 1),
\ pattern.'\zs') \ pattern.'\zs')
let concat = 0 let concat = 0
if empty(ignored_syntax) if empty(a:ignores)
let tokens = raw_tokens let tokens = raw_tokens
else else
" Concat adjacent tokens that are split by ignorable delimiters " 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 else
call add(tokens, token) call add(tokens, token)
endif 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 endfor
endif 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 token = substitute(last, pattern.'$', '', '')
let delim = get(matchlist(last, pattern.'$'), 1, '') 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 continue
endif 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 if a:recursive && a:nth < max_tokens
let just = a:recursive == 2 ? !a:just : a:just 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, 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 endif
endfunction endfunction
@@ -298,7 +298,10 @@ function! easy_align#align(just, ...) range
\ nth, \ nth,
\ get(dict, 'margin_left', ' '), \ get(dict, 'margin_left', ' '),
\ get(dict, 'margin_right', ' '), \ 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) call s:echon(just, n, ch)
else else
echon "\rUnknown delimiter: ". ch echon "\rUnknown delimiter: ". ch