Implement special keys to switch option values in interactive mode

With this commit, we can now change option values in interactive mode with the
folowing special keys

- CTRL-L  left_margin
- CTRL-R  right_margin
- CTRL-D  delimiter_align
- CTRL-I  indentation
- CTRL-U  ignore_unmatched
- CTRL-G  ignore_groups

('ignores' option has been renamed to 'ignore_groups', but backward-compatible)
This commit is contained in:
Junegunn Choi
2013-08-20 01:38:20 +09:00
parent 62314afcaf
commit 12c319a8ac
6 changed files with 246 additions and 93 deletions

View File

@@ -240,10 +240,10 @@ So, let's define a custom mapping for `#`.
if !exists('g:easy_align_delimiters') if !exists('g:easy_align_delimiters')
let g:easy_align_delimiters = {} let g:easy_align_delimiters = {}
endif endif
let g:easy_align_delimiters['#'] = { 'pattern': '#', 'ignores': ['String'] } let g:easy_align_delimiters['#'] = { 'pattern': '#', 'ignore_groups': ['String'] }
``` ```
Notice that the rule overrides `ignores` attribute in order *not to ignore* Notice that the rule overrides `ignore_groups` attribute in order *not to ignore*
delimiters highlighted as comments. delimiters highlighted as comments.
Then on `<Enter>#`, we get Then on `<Enter>#`, we get
@@ -285,7 +285,7 @@ let g:easy_align_ignore_unmatched = 0
" 3. Update the alignment rule with ignore_unmatched option " 3. Update the alignment rule with ignore_unmatched option
let g:easy_align_delimiters['#'] = { let g:easy_align_delimiters['#'] = {
\ 'pattern': '#', 'ignores': ['String'], 'ignore_unmatched': 0 } \ 'pattern': '#', 'ignore_groups': ['String'], 'ignore_unmatched': 0 }
``` ```
Then we get, Then we get,

View File

@@ -194,28 +194,40 @@ lowest precedence.
### List of options ### List of options
| Option | Type | Default | Description | | Option | Type | Default | Description |
| ------------------ | ----------------- | --------------------- | ------------------------------------------------------- | | ------------------ | ------- | --------------------- | ------------------------------------------------------- |
| `left_margin` | number | 0 | Number of spaces to attach before delimiter | | `left_margin` | number | 0 | 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 | 0 | Number of spaces to attach after delimiter | | `right_margin` | number | 0 | Number of spaces to attach after delimiter |
| `right_margin` | string | `''` | String to attach after delimiter | | `right_margin` | string | `''` | String to attach after delimiter |
| `stick_to_left` | boolean | 0 | Whether to position delimiter on the left-side | | `stick_to_left` | boolean | 0 | Whether to position delimiter on the left-side |
| `ignore_unmatched` | boolean | 1 | Whether to ignore lines without matching delimiter | | `ignore_groups` | list | ['String', 'Comment'] | Delimiters in these syntax highlight groups are ignored |
| `ignores` | list | ['String', 'Comment'] | Delimiters in these syntax highlight groups are ignored | | `ignore_unmatched` | boolean | 1 | Whether to ignore lines without matching delimiter |
| `indentation` | string | `k` | Indentation method (*k*eep, *d*eep, *s*hallow, *n*one) | | `indentation` | string | `k` | Indentation method (*k*eep, *d*eep, *s*hallow, *n*one) |
| `delimiter_align` | string | `r` | Determines how to align delimiters of different lengths | | `delimiter_align` | string | `r` | Determines how to align delimiters of different lengths |
| `mode_sequence` | string | | Alignment modes for multiple occurrences of delimiters | | `mode_sequence` | string | | Alignment modes for multiple occurrences of delimiters |
Some of the options can be specified using corresponding global variables. Some of the options can be specified using corresponding global variables.
| Option | Global variable | | Option | Global variable |
| ------------------ | ------------------------------- | | ------------------ | ------------------------------- |
| `ignore_groups` | `g:easy_align_ignore_groups` |
| `ignore_unmatched` | `g:easy_align_ignore_unmatched` | | `ignore_unmatched` | `g:easy_align_ignore_unmatched` |
| `ignores` | `g:easy_align_ignores` |
| `delimiter_align` | `g:easy_align_delimiter_align` | | `delimiter_align` | `g:easy_align_delimiter_align` |
| `indentation` | `g:easy_align_indentation` | | `indentation` | `g:easy_align_indentation` |
In interactive mode, you can switch some of the alignment options using special
keys listed below.
| Key | Option | Values |
| -------- | ------------------ | -------------------------------------------------- |
| `CTRL-I` | `indentation` | shallow, deep, none, keep |
| `CTRL-L` | `left_margin` | Input number or string |
| `CTRL-R` | `right_margin` | Input number or string |
| `CTRL-D` | `delimiter_align` | left, center, right |
| `CTRL-U` | `ignore_unmatched` | 0, 1 |
| `CTRL-G` | `ignore_groups` | [], ['String'], ['Comment'], ['String', 'Comment'] |
### 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
@@ -226,7 +238,7 @@ highlighted as code comments or strings are ignored.
" Default: " Default:
" If a delimiter is in a highlight group whose name matches " If a delimiter is in a highlight group whose name matches
" any of the followings, it will be ignored. " any of the followings, it will be ignored.
let g:easy_align_ignores = ['Comment', 'String'] let g:easy_align_ignore_groups = ['Comment', 'String']
``` ```
For example, the following paragraph For example, the following paragraph
@@ -257,13 +269,15 @@ becomes as follows on `<Enter>:` (or `:EasyAlign:`)
Naturally, this feature only works when syntax highlighting is enabled. Naturally, this feature only works when syntax highlighting is enabled.
You can change the default rule by using one of these 3 methods. You can change the default rule by using one of these 4 methods.
1. Define global `g:easy_align_ignores` list 1. Press `CTRL-G` in interactive mode to switch groups
2. Define a custom alignment rule in `g:easy_align_delimiters` with `ignores` option 2. Define global `g:easy_align_ignore_groups` list
3. Provide `ignores` option to `:EasyAlign` command. e.g. `:EasyAlign:{'is':[]}` 3. Define a custom rule in `g:easy_align_delimiters` with `ignore_groups` option
4. Provide `ignore_groups` option to `:EasyAlign` command.
e.g. `:EasyAlign:{'ig':[]}`
For example if you set `ignores` option to be an empty list, you get For example if you set `ignore_groups` option to be an empty list, you get
```ruby ```ruby
{ {
@@ -307,12 +321,13 @@ this is usually what we want.
} }
``` ```
However, this default behavior is also configurable by using one of these 3 However, this default behavior is also configurable by using one of these 4
methods. methods.
1. Set the global `g:easy_align_ignore_unmatched` variable to 0 1. Press `CTRL-U` in interactive mode to toggle `ignore_unmatched` option
2. Define a custom alignment rule with `ignore_unmatched` option set to 0 2. Set the global `g:easy_align_ignore_unmatched` variable to 0
3. Provide `ignore_unmatched` option to `:EasyAlign` command. e.g. `:EasyAlign:{'iu':0}` 3. Define a custom alignment rule with `ignore_unmatched` option set to 0
4. Provide `ignore_unmatched` option to `:EasyAlign` command. e.g. `:EasyAlign:{'iu':0}`
Then we get, Then we get,
@@ -362,6 +377,8 @@ banana += apple
cake ||= banana cake ||= banana
``` ```
In interactive mode, you can change the option value with `CTRL-D` key.
### Adjusting indentation ### Adjusting indentation
By default :EasyAlign command keeps the original indentation of the lines. But By default :EasyAlign command keeps the original indentation of the lines. But
@@ -410,6 +427,8 @@ eggplant = 5
Notice that `idt` is fuzzy-matched to `indentation`. Notice that `idt` is fuzzy-matched to `indentation`.
In interactive mode, you can change the option value with `CTRL-I` key.
### Left/right/center mode switch in interactive mode ### Left/right/center mode switch in interactive mode
In interactive mode, you can choose the alignment mode you want by pressing In interactive mode, you can choose the alignment mode you want by pressing
@@ -489,8 +508,8 @@ you can extend the rules by setting a dictionary named `g:easy_align_delimiters`
```vim ```vim
let g:easy_align_delimiters = { let g:easy_align_delimiters = {
\ '>': { 'pattern': '>>\|=>\|>' }, \ '>': { 'pattern': '>>\|=>\|>' },
\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] }, \ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignore_groups': ['String'] },
\ '#': { 'pattern': '#\+', 'ignores': ['String'], 'delimiter_align': 'l' }, \ '#': { 'pattern': '#\+', 'ignore_groups': ['String'], 'delimiter_align': 'l' },
\ ']': { \ ']': {
\ 'pattern': '[[\]]', \ 'pattern': '[[\]]',
\ 'left_margin': 0, \ 'left_margin': 0,

View File

@@ -44,8 +44,15 @@ let s:mode_labels = { 'l': '', 'r': '[R]', 'c': '[C]' }
let s:known_options = { 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],
\ 'ignores': [3 ], 'ignore_unmatched': [0 ], 'delimiter_align': [1], \ 'ignore_groups': [3 ], 'ignore_unmatched': [0 ], 'delimiter_align': [1],
\ 'mode_sequence': [1 ] \ 'mode_sequence': [1 ], 'ignores': [3]
\ }
let s:option_values = {
\ 'indentation': ['shallow', 'deep', 'none', 'keep'],
\ 'delimiter_align': ['left', 'center', 'right'],
\ 'ignore_unmatched': [0, 1],
\ 'ignore_groups': [[], ['String'], ['Comment'], ['String', 'Comment']]
\ } \ }
if exists("*strwidth") if exists("*strwidth")
@@ -72,17 +79,19 @@ endfunction
function! s:ignored_syntax() function! s:ignored_syntax()
if has('syntax') && exists('g:syntax_on') if has('syntax') && exists('g:syntax_on')
" Backward-compatibility " Backward-compatibility
return get(g:, 'easy_align_ignores', return get(g:, 'easy_align_ignore_groups',
\ (get(g:, 'easy_align_ignore_comment', 1) == 0) ? \ get(g:, 'easy_align_ignores',
\ ['String'] : ['String', 'Comment']) \ (get(g:, 'easy_align_ignore_comment', 1) == 0) ?
\ ['String'] : ['String', 'Comment']))
else else
return [] return []
endif endif
endfunction endfunction
function! s:echon(l, n, d) function! s:echon(l, n, d, o)
echon "\r" echon "\r"
echon "\rEasyAlign". s:mode_labels[a:l] ." (" .a:n.a:d. ")" echon "\rEasyAlign". s:mode_labels[a:l] ." (" .a:n.a:d. ")"
\ . (empty(a:o) ? '' : ' '.string(a:o))
endfunction endfunction
function! s:exit(msg) function! s:exit(msg)
@@ -106,9 +115,18 @@ function! s:fuzzy_lu(key)
if has_key(s:known_options, a:key) if has_key(s:known_options, a:key)
return a:key return a:key
endif endif
let key = tolower(a:key)
let regexp = '^' . substitute(substitute(a:key, '-', '_', 'g'), '\(.\)', '\1.*', 'g') " stl -> ^s.*_t.*_l.*
let matches = filter(keys(s:known_options), 'v:val =~ regexp') let regexp1 = '^' .key[0]. '.*' .substitute(key[1 : -1], '\(.\)', '_\1.*', 'g')
let matches = filter(keys(s:known_options), 'v:val =~ regexp1')
if len(matches) == 1
return matches[0]
endif
" stl -> ^s.*t.*l.*
let regexp2 = '^' . substitute(substitute(key, '-', '_', 'g'), '\(.\)', '\1.*', 'g')
let matches = filter(keys(s:known_options), 'v:val =~ regexp2')
if empty(matches) if empty(matches)
call s:exit("Unknown option key: ". a:key) call s:exit("Unknown option key: ". a:key)
@@ -116,9 +134,12 @@ function! s:fuzzy_lu(key)
return matches[0] return matches[0]
else else
" Avoid ambiguity introduced by deprecated margin_left and margin_right " Avoid ambiguity introduced by deprecated margin_left and margin_right
if index(matches, 'mode_sequence') != -1 if sort(matches) == ['margin_left', 'margin_right', 'mode_sequence']
return 'mode_sequence' return 'mode_sequence'
endif endif
if sort(matches) == ['ignore_groups', 'ignores']
return 'ignore_groups'
endif
call s:exit("Ambiguous option key: ". a:key ." (" .join(matches, ', '). ")") call s:exit("Ambiguous option key: ". a:key ." (" .join(matches, ', '). ")")
endif endif
endfunction endfunction
@@ -156,7 +177,7 @@ function! s:validate_options(opts)
return a:opts return a:opts
endfunction endfunction
function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left, ignore_unmatched, ignores) function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left, ignore_unmatched, ignore_groups)
let mode = '' let mode = ''
let string = a:lc ? let string = a:lc ?
@@ -189,7 +210,7 @@ function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left,
let [match, part, delim] = matches[1 : 3] let [match, part, delim] = matches[1 : 3]
endif endif
let ignorable = s:highlighted_as(a:line, idx + len(part) + a:fc, a:ignores) let ignorable = s:highlighted_as(a:line, idx + len(part) + a:fc, a:ignore_groups)
if ignorable if ignorable
let token .= match let token .= match
else else
@@ -212,7 +233,7 @@ function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left,
let leftover = token . strpart(string, idx) let leftover = token . strpart(string, idx)
if !empty(leftover) if !empty(leftover)
let ignorable = s:highlighted_as(a:line, len(string) + a:fc - 1, a:ignores) let ignorable = s:highlighted_as(a:line, len(string) + a:fc - 1, a:ignore_groups)
call add(tokens, leftover) call add(tokens, leftover)
call add(delims, '') call add(delims, '')
endif endif
@@ -249,7 +270,7 @@ function! s:max(old, new)
endfunction endfunction
function! s:do_align(modes, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth, function! s:do_align(modes, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
\ ml, mr, da, indentation, stick_to_left, ignore_unmatched, ignores, recur) \ ml, mr, da, indentation, stick_to_left, ignore_unmatched, ignore_groups, recur)
let mode = a:modes[0] let mode = a:modes[0]
let lines = {} let lines = {}
let min_indent = -1 let min_indent = -1
@@ -263,7 +284,7 @@ function! s:do_align(modes, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth
let [tokens, delims] = s:split_line( let [tokens, delims] = s:split_line(
\ line, a:nth, copy(a:modes), a:recur == 2, \ line, a:nth, copy(a:modes), a:recur == 2,
\ a:fc, a:lc, a:pattern, \ a:fc, a:lc, a:pattern,
\ a:stick_to_left, a:ignore_unmatched, a:ignores) \ a:stick_to_left, a:ignore_unmatched, a:ignore_groups)
" Remember tokens for subsequent recursive calls " Remember tokens for subsequent recursive calls
let a:all_tokens[line] = tokens let a:all_tokens[line] = tokens
@@ -434,17 +455,31 @@ function! s:do_align(modes, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth
\ a:modes, a:all_tokens, a:all_delims, \ a:modes, a:all_tokens, a:all_delims,
\ a:fl, a:ll, a:fc, a:lc, a:pattern, \ a:fl, a:ll, a:fc, a:lc, a:pattern,
\ a:nth + 1, a:ml, a:mr, a:da, a:indentation, a:stick_to_left, \ a:nth + 1, a:ml, a:mr, a:da, a:indentation, a:stick_to_left,
\ a:ignore_unmatched, a:ignores, a:recur) \ a:ignore_unmatched, a:ignore_groups, a:recur)
endif endif
endfunction endfunction
function! s:input(str)
redraw
call inputsave()
let got = input(a:str)
call inputrestore()
try
return eval(got)
catch
return got
endtry
endfunction
function! s:interactive(modes) function! s:interactive(modes)
let mode = s:shift(a:modes, 1) let mode = s:shift(a:modes, 1)
let n = '' let n = ''
let ch = '' let ch = ''
let opts = {}
let vals = deepcopy(s:option_values)
while 1 while 1
call s:echon(mode, n, '') call s:echon(mode, n, '', opts)
let c = getchar() let c = getchar()
let ch = nr2char(c) let ch = nr2char(c)
@@ -471,11 +506,23 @@ function! s:interactive(modes)
if n[0] == '*' | break if n[0] == '*' | break
else | let n = n . ch else | let n = n . ch
end end
elseif ch == "\<C-D>"
let opts['da'] = s:shift(vals['delimiter_align'], 1)
elseif ch == "\<C-I>"
let opts['idt'] = s:shift(vals['indentation'], 1)
elseif ch == "\<C-L>"
let opts['lm'] = s:input("Left margin: ")
elseif ch == "\<C-R>"
let opts['rm'] = s:input("Right margin: ")
elseif ch == "\<C-U>"
let opts['iu'] = s:shift(vals['ignore_unmatched'], 1)
elseif ch == "\<C-G>"
let opts['ig'] = s:shift(vals['ignore_groups'], 1)
else else
break break
endif endif
endwhile endwhile
return [mode, n, ch] return [mode, n, ch, s:normalize_options(opts)]
endfunction endfunction
function! s:parse_args(args) function! s:parse_args(args)
@@ -483,7 +530,7 @@ function! s:parse_args(args)
let ch = '' let ch = ''
let args = a:args let args = a:args
let cand = '' let cand = ''
let option = {} let opts = {}
" Poor man's option parser " Poor man's option parser
let idx = 0 let idx = 0
@@ -497,7 +544,7 @@ function! s:parse_args(args)
let [L, R, C, K, S, D, N] = ['l', 'r', 'c', 'k', 's', 'd', 'n'] let [L, R, C, K, S, D, N] = ['l', 'r', 'c', 'k', 's', 'd', 'n']
let o = eval(cand) let o = eval(cand)
if type(o) == 4 if type(o) == 4
let option = o let opts = o
if args[midx - 1 : midx] == '\ ' if args[midx - 1 : midx] == '\ '
let midx += 1 let midx += 1
endif endif
@@ -511,8 +558,10 @@ function! s:parse_args(args)
endwhile endwhile
" Invalid option dictionary " Invalid option dictionary
if len(substitute(cand, '\s', '', 'g')) > 2 && empty(option) if len(substitute(cand, '\s', '', 'g')) > 2 && empty(opts)
call s:exit("Invalid option: ". cand) call s:exit("Invalid option: ". cand)
else
let opts = s:normalize_options(opts)
endif endif
" Has /Regexp/? " Has /Regexp/?
@@ -525,10 +574,10 @@ function! s:parse_args(args)
try | call matchlist('', regexp) try | call matchlist('', regexp)
catch | call s:exit("Invalid regular expression: ". regexp) catch | call s:exit("Invalid regular expression: ". regexp)
endtry endtry
return [matches[1], regexp, option, 1] return [matches[1], regexp, opts, 1]
else else
let tokens = matchlist(args, '^\([1-9][0-9]*\|-[0-9]*\|\*\*\?\)\?\s*\(.\{-}\)\?$') let tokens = matchlist(args, '^\([1-9][0-9]*\|-[0-9]*\|\*\*\?\)\?\s*\(.\{-}\)\?$')
return [tokens[1], tokens[2], option, 0] return [tokens[1], tokens[2], opts, 0]
endif endif
endfunction endfunction
@@ -540,16 +589,17 @@ function! easy_align#align(bang, expr) range
let recur = 0 let recur = 0
let n = '' let n = ''
let ch = '' let ch = ''
let option = {} let opts = {}
let iopts = {}
let regexp = 0 let regexp = 0
try try
if empty(a:expr) if empty(a:expr)
let [mode, n, ch] = s:interactive(copy(modes)) let [mode, n, ch, iopts] = s:interactive(copy(modes))
else else
let [n, ch, option, regexp] = s:parse_args(a:expr) let [n, ch, opts, regexp] = s:parse_args(a:expr)
if empty(n) && empty(ch) if empty(n) && empty(ch)
let [mode, n, ch] = s:interactive(copy(modes)) let [mode, n, ch, iopts] = s:interactive(copy(modes))
elseif empty(ch) elseif empty(ch)
" Try swapping n and ch " Try swapping n and ch
let [n, ch] = ['', n] let [n, ch] = ['', n]
@@ -595,13 +645,11 @@ function! easy_align#align(bang, expr) range
let dict = delimiters[ch] let dict = delimiters[ch]
endif endif
try for opt in [opts, iopts]
if !empty(option) if !empty(opt)
let dict = extend(copy(dict), s:normalize_options(option)) let dict = extend(copy(dict), opt)
endif endif
catch 'exit' endfor
return
endtry
let ml = get(dict, 'left_margin', ' ') let ml = get(dict, 'left_margin', ' ')
let mr = get(dict, 'right_margin', ' ') let mr = get(dict, 'right_margin', ' ')
@@ -628,13 +676,13 @@ function! easy_align#align(bang, expr) range
\ nth, \ nth,
\ ml, \ ml,
\ mr, \ mr,
\ get(dict, 'delimiter_align', get(g:, 'easy_align_delimiter_align', 'r')), \ get(dict, 'delimiter_align', get(g:, 'easy_align_delimiter_align', 'r'))[0],
\ get(dict, 'indentation', get(g:, 'easy_align_indentation', 'k')), \ get(dict, 'indentation', get(g:, 'easy_align_indentation', 'k'))[0],
\ get(dict, 'stick_to_left', 0), \ get(dict, 'stick_to_left', 0),
\ get(dict, 'ignore_unmatched', get(g:, 'easy_align_ignore_unmatched', 1)), \ get(dict, 'ignore_unmatched', get(g:, 'easy_align_ignore_unmatched', 1)),
\ get(dict, 'ignores', s:ignored_syntax()), \ get(dict, 'ignore_groups', get(dict, 'ignores', s:ignored_syntax())),
\ recur) \ recur)
call s:echon(mode, n, regexp ? '/'.ch.'/' : ch) call s:echon(mode, n, regexp ? '/'.ch.'/' : ch, iopts)
catch 'exit' catch 'exit'
endtry endtry
endfunction endfunction

View File

@@ -116,21 +116,7 @@ You can even omit spaces between the arguments, so concisely (or cryptically):
- :EasyAlign*/[:;]\+/{'s':1,'l':''} - :EasyAlign*/[:;]\+/{'s':1,'l':''}
Available options are as follows. Available options will be shown later in the document.
| Atrribute | Type | Default |
| ---------------- | ---------------- | ----------------------------- |
| left_margin | number or string | 0 |
| right_margin | number or string | 0 |
| stick_to_left | boolean | 0 |
| ignore_unmatched | boolean | 1 |
| ignores | array | ['String', 'Comment'] |
| delimiter_align | string | 'r' |
| | | (right, left, center) |
| indentation | string | 'k' |
| | | (keep, shallow, deep, none) |
| mode_sequence | string | (Depends on field number and |
| | | selected alignment mode) |
Partial alignment in blockwise-visual mode Partial alignment in blockwise-visual mode
@@ -140,7 +126,50 @@ In blockwise-visual mode (CTRL-V), EasyAlign command aligns only
the selected text in the block, instead of the whole lines in the range. the selected text in the block, instead of the whole lines in the range.
Ignoring delimiters in comments or strings *g:easy_align_ignores* Alignment options
-------------------------------------------------------------------------
Available options are as follows.
| Atrribute | Type | Default |
| ---------------- | ---------------- | ----------------------------- |
| left_margin | number or string | 0 |
| right_margin | number or string | 0 |
| stick_to_left | boolean | 0 |
| ignore_unmatched | boolean | 1 |
| ignore_groups | array | ['String', 'Comment'] |
| delimiter_align | string | 'r' |
| | | (right, left, center) |
| indentation | string | 'k' |
| | | (keep, shallow, deep, none) |
| mode_sequence | string | (Depends on field number and |
| | | selected alignment mode) |
Some of the options can be specified using corresponding global variables.
| Option | Global variable |
| ------------------ | ------------------------------- |
| ignore_groups | `g:easy_align_ignore_groups` |
| ignore_unmatched | `g:easy_align_ignore_unmatched` |
| delimiter_align | `g:easy_align_delimiter_align` |
| indentation | `g:easy_align_indentation` |
In interactive mode, you can switch some of the alignment options using special
keys listed below.
| Key | Option | Values |
| ------ | ---------------- | -------------------------------------------------- |
| CTRL-I | indentation | shallow, deep, none, keep |
| CTRL-L | left_margin | Input number or string |
| CTRL-R | right_margin | Input number or string |
| CTRL-D | delimiter_align | left, center, right |
| CTRL-U | ignore_unmatched | 0, 1 |
| CTRL-G | ignore_groups | [], ['String'], ['Comment'], ['String', 'Comment'] |
Ignoring delimiters in comments or strings *g:easy_align_ignore_groups*
------------------------------------------------------------------------- -------------------------------------------------------------------------
EasyAlign can be configured to ignore delimiters in certain syntax EasyAlign can be configured to ignore delimiters in certain syntax
@@ -150,7 +179,7 @@ that are highlighted as code comments or strings are ignored.
" Default: " Default:
" If a delimiter is in a highlight group whose name matches " If a delimiter is in a highlight group whose name matches
" any of the followings, it will be ignored. " any of the followings, it will be ignored.
let g:easy_align_ignores = ['Comment', 'String'] let g:easy_align_ignore_groups = ['Comment', 'String']
For example, the following paragraph For example, the following paragraph
@@ -176,13 +205,15 @@ becomes as follows on '<Enter>:' (or `:EasyAlign:`)
Naturally, this feature only works when syntax highlighting is enabled. Naturally, this feature only works when syntax highlighting is enabled.
You can change the default rule by using one of these 3 methods. You can change the default rule by using one of these 4 methods.
1. Define global `g:easy_align_ignores` list 1. Press CTRL-G in interactive mode to switch groups
2. Define a custom rule in `g:easy_align_delimiters` with 'ignores' option 2. Define global `g:easy_align_ignore_groups` list
3. Provide 'ignores' option to `:EasyAlign` command. e.g. :EasyAlign:{'is':[]} 3. Define a custom rule in `g:easy_align_delimiters` with 'ignore_groups' option
4. Provide 'ignore_groups' option to `:EasyAlign` command.
e.g. :EasyAlign:{'is':[]}
For example if you set 'ignores' option to be an empty list, you get For example if you set 'ignore_groups' option to be an empty list, you get
{ {
# Quantity of apples: 1 # Quantity of apples: 1
@@ -220,12 +251,13 @@ this is usually what we want.
grapefruits: 3 grapefruits: 3
} }
However, this default behavior is also configurable by using one of these 3 However, this default behavior is also configurable by using one of these 4
methods. methods.
1. Set the global `g:easy_align_ignore_unmatched` variable to 0 1. Press CTRL-U in interactive mode to toggle 'ignore_unmatched' option
2. Define a custom alignment rule with 'ignore_unmatched' option set to 0 2. Set the global `g:easy_align_ignore_unmatched` variable to 0
3. Provide 'ignore_unmatched' option to `:EasyAlign` command. 3. Define a custom alignment rule with 'ignore_unmatched' option set to 0
4. Provide 'ignore_unmatched' option to `:EasyAlign` command.
e.g. :EasyAlign:{'iu':0} e.g. :EasyAlign:{'iu':0}
Then we get, Then we get,
@@ -268,6 +300,8 @@ And on ':EasyAlign={'da':c}', center-aligned.
banana += apple banana += apple
cake ||= banana cake ||= banana
In interactive mode, you can change the option value with `CTRL-D` key.
Adjusting indentation *g:easy_align_indentation* Adjusting indentation *g:easy_align_indentation*
------------------------------------------------------------------------- -------------------------------------------------------------------------
@@ -317,6 +351,8 @@ But then again we have 'indentation' option. See the following example.
Notice that 'idt' is fuzzy-matched to 'indentation'. Notice that 'idt' is fuzzy-matched to 'indentation'.
In interactive mode, you can change the option value with `CTRL-I` key.
Left/right/center mode switch in interactive mode Left/right/center mode switch in interactive mode
------------------------------------------------------------------------- -------------------------------------------------------------------------
@@ -396,8 +432,8 @@ you can extend the rules by setting a dictionary named
let g:easy_align_delimiters = { let g:easy_align_delimiters = {
\ '>': { 'pattern': '>>\|=>\|>' }, \ '>': { 'pattern': '>>\|=>\|>' },
\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] }, \ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignore_groups': ['String'] },
\ '#': { 'pattern': '#\+', 'ignores': ['String'] }, \ '#': { 'pattern': '#\+', 'ignore_groups': ['String'] },
\ ']': { \ ']': {
\ 'pattern': '[[\]]', \ 'pattern': '[[\]]',
\ 'left_margin': 0, \ 'left_margin': 0,

View File

@@ -104,6 +104,56 @@ j, , k
```ruby ```ruby
a =
a = 1
bbbb = 2
ccccccc = 3
ccccccccccccccc
ddd = #
eeee === eee = eee = eee = f
fff = ggg += gg &&= gg
g != hhhhhhhh == # 8
i := 5
i %= 5
i *= 5
j =~ 5
j >= 5
aa => 123
aa <<= 123
aa >>= 123
bbb => 123
c => 1233123
d => 123
dddddd &&= 123
dddddd ||= 123
dddddd /= 123
gg <=> ee
a =
a = 1
bbbb = 2
ccccccc = 3
ccccccccccccccc
ddd = #
eeee === eee = eee = eee = f
fff = ggg += gg &&= gg
g != hhhhhhhh == # 8
i := 5
i %= 5
i *= 5
j =~ 5
j >= 5
aa => 123
aa <<= 123
aa >>= 123
bbb => 123
c => 1233123
d => 123
dddddd &&= 123
dddddd ||= 123
dddddd /= 123
gg <=> ee
a = a =
a = 1 a = 1
bbbb = 2 bbbb = 2

View File

@@ -1 +1 @@
4Gvipjyvip 4Gvipjyvip