mirror of
https://github.com/junegunn/vim-easy-align.git
synced 2025-11-14 04:43:48 -05:00
This commit implements filter option which can be used to filter lines within the range based on the given pattern. The value of filter option should be either `g/pattern/` or `v/pattern/`. The former aligns lines that match the pattern, the latter aligns lines that do not match the pattern.
This commit is contained in:
26
README.md
26
README.md
@@ -314,6 +314,7 @@ Alignment options
|
|||||||
|
|
||||||
| Option | Type | Default | Description |
|
| Option | Type | Default | Description |
|
||||||
| ------------------ | ------- | --------------------- | ------------------------------------------------------- |
|
| ------------------ | ------- | --------------------- | ------------------------------------------------------- |
|
||||||
|
| `filter` | string | | Line filtering expression: `g/../` or `v/../` |
|
||||||
| `left_margin` | number | 1 | Number of spaces to attach before delimiter |
|
| `left_margin` | number | 1 | Number of spaces to attach before delimiter |
|
||||||
| `left_margin` | string | `' '` | String to attach before delimiter |
|
| `left_margin` | string | `' '` | String to attach before delimiter |
|
||||||
| `right_margin` | number | 1 | Number of spaces to attach after delimiter |
|
| `right_margin` | number | 1 | Number of spaces to attach after delimiter |
|
||||||
@@ -334,6 +335,7 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
|
|||||||
|
|
||||||
| Option name | Shortcut key | Abbreviated | Global variable |
|
| Option name | Shortcut key | Abbreviated | Global variable |
|
||||||
| ------------------ | ------------------- | ----------- | ------------------------------- |
|
| ------------------ | ------------------- | ----------- | ------------------------------- |
|
||||||
|
| `filter` | `CTRL-F` | `[gv]/.*/` | |
|
||||||
| `left_margin` | `CTRL-L` | `l[0-9]+` | |
|
| `left_margin` | `CTRL-L` | `l[0-9]+` | |
|
||||||
| `right_margin` | `CTRL-R` | `r[0-9]+` | |
|
| `right_margin` | `CTRL-R` | `r[0-9]+` | |
|
||||||
| `stick_to_left` | `<Left>`, `<Right>` | `s[01]` | |
|
| `stick_to_left` | `<Left>`, `<Right>` | `s[01]` | |
|
||||||
@@ -343,6 +345,30 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
|
|||||||
| `delimiter_align` | `CTRL-D` | `d[lrc]` | `g:easy_align_delimiter_align` |
|
| `delimiter_align` | `CTRL-D` | `d[lrc]` | `g:easy_align_delimiter_align` |
|
||||||
| `mode_sequence` | `CTRL-O` | `m[lrc*]*` | |
|
| `mode_sequence` | `CTRL-O` | `m[lrc*]*` | |
|
||||||
|
|
||||||
|
### Filtering lines
|
||||||
|
|
||||||
|
With `filter` option, you can align lines that only match or do not match a
|
||||||
|
given pattern. There are several ways to set the pattern.
|
||||||
|
|
||||||
|
1. Press `CTRL-F` in interactive mode and input `g/pat/` or `v/pat/`
|
||||||
|
2. In command-line, it can be written in dictionary format: `{'filter': 'g/pat/'}`
|
||||||
|
3. Or in shorthand notation: `g/pat/` or `v/pat/`
|
||||||
|
|
||||||
|
(You don't need to escape '/'s in the regular expression)
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
```vim
|
||||||
|
" Start interactive mode with filter option set to g/hello/
|
||||||
|
EasyAlign g/hello/
|
||||||
|
|
||||||
|
" Start live interactive mode with filter option set to v/goodbye/
|
||||||
|
LiveEasyAlign v/goodbye/
|
||||||
|
|
||||||
|
" Align the lines with 'hi' around the first colons
|
||||||
|
EasyAlign:g/hi/
|
||||||
|
```
|
||||||
|
|
||||||
### Ignoring delimiters in comments or strings
|
### Ignoring delimiters in comments or strings
|
||||||
|
|
||||||
EasyAlign can be configured to ignore delimiters in certain syntax highlight
|
EasyAlign can be configured to ignore delimiters in certain syntax highlight
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ let s:known_options = {
|
|||||||
\ 'margin_left': [0, 1], 'margin_right': [0, 1], 'stick_to_left': [0],
|
\ 'margin_left': [0, 1], 'margin_right': [0, 1], 'stick_to_left': [0],
|
||||||
\ 'left_margin': [0, 1], 'right_margin': [0, 1], 'indentation': [1],
|
\ 'left_margin': [0, 1], 'right_margin': [0, 1], 'indentation': [1],
|
||||||
\ 'ignore_groups': [3 ], 'ignore_unmatched': [0 ], 'delimiter_align': [1],
|
\ 'ignore_groups': [3 ], 'ignore_unmatched': [0 ], 'delimiter_align': [1],
|
||||||
\ 'mode_sequence': [1 ], 'ignores': [3]
|
\ 'mode_sequence': [1 ], 'ignores': [3], 'filter': [1]
|
||||||
\ }
|
\ }
|
||||||
|
|
||||||
let s:option_values = {
|
let s:option_values = {
|
||||||
@@ -61,7 +61,7 @@ let s:shorthand = {
|
|||||||
\ 'margin_left': 'lm', 'margin_right': 'rm', 'stick_to_left': 'stl',
|
\ 'margin_left': 'lm', 'margin_right': 'rm', 'stick_to_left': 'stl',
|
||||||
\ 'left_margin': 'lm', 'right_margin': 'rm', 'indentation': 'idt',
|
\ 'left_margin': 'lm', 'right_margin': 'rm', 'indentation': 'idt',
|
||||||
\ 'ignore_groups': 'ig', 'ignore_unmatched': 'iu', 'delimiter_align': 'da',
|
\ 'ignore_groups': 'ig', 'ignore_unmatched': 'iu', 'delimiter_align': 'da',
|
||||||
\ 'mode_sequence': 'm', 'ignores': 'ig'
|
\ 'mode_sequence': 'm', 'ignores': 'ig', 'filter': 'f'
|
||||||
\ }
|
\ }
|
||||||
|
|
||||||
if exists("*strwidth")
|
if exists("*strwidth")
|
||||||
@@ -333,9 +333,16 @@ function! s:do_align(todo, modes, all_tokens, all_delims, fl, ll, fc, lc, nth, r
|
|||||||
let max = { 'pivot_len': 0.0, 'token_len': 0, 'just_len': 0, 'delim_len': 0,
|
let max = { 'pivot_len': 0.0, 'token_len': 0, 'just_len': 0, 'delim_len': 0,
|
||||||
\ 'indent': 0, 'tokens': 0, 'strip_len': 0 }
|
\ 'indent': 0, 'tokens': 0, 'strip_len': 0 }
|
||||||
let d = a:dict
|
let d = a:dict
|
||||||
|
let [f, fx] = s:parse_filter(d.filter)
|
||||||
|
|
||||||
" Phase 1
|
" Phase 1
|
||||||
for line in range(a:fl, a:ll)
|
for line in range(a:fl, a:ll)
|
||||||
|
if f == 1 && getline(line) !~ fx
|
||||||
|
continue
|
||||||
|
elseif f == -1 && getline(line) =~ fx
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
if !has_key(a:all_tokens, line)
|
if !has_key(a:all_tokens, line)
|
||||||
" Split line into the tokens by the delimiters
|
" Split line into the tokens by the delimiters
|
||||||
let [tokens, delims] = s:split_line(
|
let [tokens, delims] = s:split_line(
|
||||||
@@ -703,6 +710,16 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
|||||||
else
|
else
|
||||||
let warn = 'Invalid regular expression: '.ch
|
let warn = 'Invalid regular expression: '.ch
|
||||||
endif
|
endif
|
||||||
|
elseif ch == "\<C-F>"
|
||||||
|
let f = s:input("Filter (g/../ or v/../): ", get(opts, 'f', ''), a:vis)
|
||||||
|
let m = matchlist(f, '^[gv]/\(.\{-}\)/\?$')
|
||||||
|
if empty(f)
|
||||||
|
silent! call remove(opts, 'f')
|
||||||
|
elseif !empty(m) && s:valid_regexp(m[1])
|
||||||
|
let opts['f'] = f
|
||||||
|
else
|
||||||
|
let warn = 'Invalid filter expression'
|
||||||
|
endif
|
||||||
elseif ch =~ '[[:print:]]'
|
elseif ch =~ '[[:print:]]'
|
||||||
let check = 1
|
let check = 1
|
||||||
else
|
else
|
||||||
@@ -756,9 +773,9 @@ function! s:test_regexp(regexp)
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:shorthand_regex =
|
let s:shorthand_regex =
|
||||||
\ '\s*\('
|
\ '\s*\%('
|
||||||
\ .'\(lm\?[0-9]\+\)\|\(rm\?[0-9]\+\)\|\(iu[01]\)\|\(s\%(tl\)\?[01]\)\|'
|
\ .'\(lm\?[0-9]\+\)\|\(rm\?[0-9]\+\)\|\(iu[01]\)\|\(s\%(tl\)\?[01]\)\|'
|
||||||
\ .'\(da\?[clr]\)\|\(ms\?[lrc*]\+\)\|\(i\%(dt\)\?[kdsn]\)\|\(ig\[.*\]\)'
|
\ .'\(da\?[clr]\)\|\(ms\?[lrc*]\+\)\|\(i\%(dt\)\?[kdsn]\)\|\([gv]/.*/\)\|\(ig\[.*\]\)'
|
||||||
\ .'\)\+\s*$'
|
\ .'\)\+\s*$'
|
||||||
|
|
||||||
function! s:parse_shorthand_opts(expr)
|
function! s:parse_shorthand_opts(expr)
|
||||||
@@ -773,13 +790,17 @@ function! s:parse_shorthand_opts(expr)
|
|||||||
else
|
else
|
||||||
let match = matchlist(expr, regex)
|
let match = matchlist(expr, regex)
|
||||||
if empty(match) | break | endif
|
if empty(match) | break | endif
|
||||||
for m in filter(match[ 2 : -1 ], '!empty(v:val)')
|
for m in filter(match[ 1 : -1 ], '!empty(v:val)')
|
||||||
for key in ['lm', 'rm', 'l', 'r', 'stl', 's', 'iu', 'da', 'd', 'ms', 'm', 'ig', 'i']
|
for key in ['lm', 'rm', 'l', 'r', 'stl', 's', 'iu', 'da', 'd', 'ms', 'm', 'ig', 'i', 'g', 'v']
|
||||||
if stridx(tolower(m), key) == 0
|
if stridx(tolower(m), key) == 0
|
||||||
let rest = strpart(m, len(key))
|
let rest = strpart(m, len(key))
|
||||||
if key == 'i' | let key = 'idt' | endif
|
if key == 'i' | let key = 'idt' | endif
|
||||||
|
if key == 'g' || key == 'v'
|
||||||
|
let rest = key.rest
|
||||||
|
let key = 'f'
|
||||||
|
endif
|
||||||
|
|
||||||
if key == 'idt' || index(['d', 'm'], key[0]) >= 0
|
if key == 'idt' || index(['d', 'f', 'm'], key[0]) >= 0
|
||||||
let opts[key] = rest
|
let opts[key] = rest
|
||||||
elseif key == 'ig'
|
elseif key == 'ig'
|
||||||
try
|
try
|
||||||
@@ -877,6 +898,15 @@ function! s:parse_args(args)
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:parse_filter(f)
|
||||||
|
let m = matchlist(a:f, '^\([gv]\)/\(.\{-}\)/\?$')
|
||||||
|
if empty(m)
|
||||||
|
return [0, '']
|
||||||
|
else
|
||||||
|
return [m[1] == 'g' ? 1 : -1, m[2]]
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:interactive_modes(bang)
|
function! s:interactive_modes(bang)
|
||||||
return get(g:,
|
return get(g:,
|
||||||
\ (a:bang ? 'easy_align_bang_interactive_modes' : 'easy_align_interactive_modes'),
|
\ (a:bang ? 'easy_align_bang_interactive_modes' : 'easy_align_interactive_modes'),
|
||||||
@@ -936,6 +966,8 @@ function! s:build_dict(delimiters, ch, regexp, opts)
|
|||||||
\ get(dict, 'ignore_unmatched', get(g:, 'easy_align_ignore_unmatched', 2))
|
\ get(dict, 'ignore_unmatched', get(g:, 'easy_align_ignore_unmatched', 2))
|
||||||
let dict.ignore_groups =
|
let dict.ignore_groups =
|
||||||
\ get(dict, 'ignore_groups', get(dict, 'ignores', s:ignored_syntax()))
|
\ get(dict, 'ignore_groups', get(dict, 'ignores', s:ignored_syntax()))
|
||||||
|
let dict.filter =
|
||||||
|
\ get(dict, 'filter', '')
|
||||||
return dict
|
return dict
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ The following table summarizes the shorthand notation.
|
|||||||
|
|
||||||
| Option | Expression |
|
| Option | Expression |
|
||||||
| -------------- | ---------- |
|
| -------------- | ---------- |
|
||||||
|
| filter | [gv]/.*/ |
|
||||||
| left_margin | l[0-9]+ |
|
| left_margin | l[0-9]+ |
|
||||||
| right_margin | r[0-9]+ |
|
| right_margin | r[0-9]+ |
|
||||||
| stick_to_left | s[01] |
|
| stick_to_left | s[01] |
|
||||||
@@ -234,6 +235,7 @@ Available options are as follows.
|
|||||||
|
|
||||||
| Atrribute | Type | Default |
|
| Atrribute | Type | Default |
|
||||||
| ---------------- | ---------------- | ----------------------------- |
|
| ---------------- | ---------------- | ----------------------------- |
|
||||||
|
| filter | string | |
|
||||||
| left_margin | number or string | 1 |
|
| left_margin | number or string | 1 |
|
||||||
| right_margin | number or string | 1 |
|
| right_margin | number or string | 1 |
|
||||||
| stick_to_left | boolean | 0 |
|
| stick_to_left | boolean | 0 |
|
||||||
@@ -255,6 +257,7 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
|
|||||||
|
|
||||||
| Option | Shortcut key | Abbreviated | Global variable |
|
| Option | Shortcut key | Abbreviated | Global variable |
|
||||||
| ---------------- | --------------- | ----------- | ----------------------------- |
|
| ---------------- | --------------- | ----------- | ----------------------------- |
|
||||||
|
| filter | CTRL-F | [gv]/.*/ | |
|
||||||
| left_margin | CTRL-L | l[0-9]+ | |
|
| left_margin | CTRL-L | l[0-9]+ | |
|
||||||
| right_margin | CTRL-R | r[0-9]+ | |
|
| right_margin | CTRL-R | r[0-9]+ | |
|
||||||
| stick_to_left | <Left>, <Right> | s[01] | |
|
| stick_to_left | <Left>, <Right> | s[01] | |
|
||||||
@@ -265,6 +268,30 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
|
|||||||
| mode_sequence | CTRL-O | m[lrc*]+ | |
|
| mode_sequence | CTRL-O | m[lrc*]+ | |
|
||||||
|
|
||||||
|
|
||||||
|
Filtering lines
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
With filter option, you can align lines that only match or do not match a
|
||||||
|
given pattern. There are several ways to set the pattern.
|
||||||
|
|
||||||
|
1. Press CTRL-F in interactive mode and input g/pat/ or v/pat/
|
||||||
|
2. In command-line, it can be written in dictionary format: {'filter': 'g/pat/'}
|
||||||
|
3. Or in shorthand notation: g/pat/ or v/pat/
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
" Start interactive mode with filter option set to g/hello/
|
||||||
|
EasyAlign g/hello/
|
||||||
|
|
||||||
|
" Start live interactive mode with filter option set to v/goodbye/
|
||||||
|
LiveEasyAlign v/goodbye/
|
||||||
|
|
||||||
|
" Align the lines with 'hi' around the first colons
|
||||||
|
EasyAlign : g/hi/
|
||||||
|
|
||||||
|
(You don't need to escape '/'s in the regular expression)
|
||||||
|
|
||||||
|
|
||||||
Ignoring delimiters in comments or strings *g:easy_align_ignore_groups*
|
Ignoring delimiters in comments or strings *g:easy_align_ignore_groups*
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1343,5 +1343,95 @@ Expect:
|
|||||||
a = b = c
|
a = b = c
|
||||||
aabba = bbbbb
|
aabba = bbbbb
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
Given (test filter option):
|
||||||
|
aaa=aaa=aaa
|
||||||
|
aaaaa=aaaaa=aaaaa
|
||||||
|
aaaaaaa=aaaaaaa=aaaaaaab
|
||||||
|
bbbbb=bbbbb=bbbbb
|
||||||
|
aaa=aaa=aaa
|
||||||
|
|
||||||
|
Do (g/a/):
|
||||||
|
vip\<Enter>
|
||||||
|
\<C-F>g/a/\<Enter>
|
||||||
|
*=
|
||||||
|
|
||||||
|
Expect:
|
||||||
|
aaa = aaa = aaa
|
||||||
|
aaaaa = aaaaa = aaaaa
|
||||||
|
aaaaaaa = aaaaaaa = aaaaaaab
|
||||||
|
bbbbb=bbbbb=bbbbb
|
||||||
|
aaa = aaa = aaa
|
||||||
|
|
||||||
|
Do (g/a - you can omit the trailing /):
|
||||||
|
vip\<Enter>
|
||||||
|
\<C-F>g/a\<Enter>
|
||||||
|
*=
|
||||||
|
|
||||||
|
Expect:
|
||||||
|
aaa = aaa = aaa
|
||||||
|
aaaaa = aaaaa = aaaaa
|
||||||
|
aaaaaaa = aaaaaaa = aaaaaaab
|
||||||
|
bbbbb=bbbbb=bbbbb
|
||||||
|
aaa = aaa = aaa
|
||||||
|
|
||||||
|
Do (v/b/):
|
||||||
|
vip\<Enter>
|
||||||
|
\<C-F>v/b/\<Enter>
|
||||||
|
*=
|
||||||
|
|
||||||
|
Expect:
|
||||||
|
aaa = aaa = aaa
|
||||||
|
aaaaa = aaaaa = aaaaa
|
||||||
|
aaaaaaa=aaaaaaa=aaaaaaab
|
||||||
|
bbbbb=bbbbb=bbbbb
|
||||||
|
aaa = aaa = aaa
|
||||||
|
|
||||||
|
Do (invalid filter expression):
|
||||||
|
vip\<Enter>
|
||||||
|
\<C-F>haha\<Enter>
|
||||||
|
*=
|
||||||
|
|
||||||
|
Expect:
|
||||||
|
aaa = aaa = aaa
|
||||||
|
aaaaa = aaaaa = aaaaa
|
||||||
|
aaaaaaa = aaaaaaa = aaaaaaab
|
||||||
|
bbbbb = bbbbb = bbbbb
|
||||||
|
aaa = aaa = aaa
|
||||||
|
|
||||||
|
Execute (g-filter in shorthand notation):
|
||||||
|
%EasyAlign*=g/a/
|
||||||
|
|
||||||
|
Expect:
|
||||||
|
aaa = aaa = aaa
|
||||||
|
aaaaa = aaaaa = aaaaa
|
||||||
|
aaaaaaa = aaaaaaa = aaaaaaab
|
||||||
|
bbbbb=bbbbb=bbbbb
|
||||||
|
aaa = aaa = aaa
|
||||||
|
|
||||||
|
Execute (v-filter in shorthand notation):
|
||||||
|
%EasyAlign*=v/b/
|
||||||
|
|
||||||
|
Expect:
|
||||||
|
aaa = aaa = aaa
|
||||||
|
aaaaa = aaaaa = aaaaa
|
||||||
|
aaaaaaa=aaaaaaa=aaaaaaab
|
||||||
|
bbbbb=bbbbb=bbbbb
|
||||||
|
aaa = aaa = aaa
|
||||||
|
|
||||||
|
Execute (filter in dictionary format):
|
||||||
|
%EasyAlign*={'filter': 'v/b/'}
|
||||||
|
|
||||||
|
Expect:
|
||||||
|
aaa = aaa = aaa
|
||||||
|
aaaaa = aaaaa = aaaaa
|
||||||
|
aaaaaaa=aaaaaaa=aaaaaaab
|
||||||
|
bbbbb=bbbbb=bbbbb
|
||||||
|
aaa = aaa = aaa
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
|
||||||
Execute:
|
Execute:
|
||||||
Restore
|
Restore
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user