Add indentation option

This commit is contained in:
Junegunn Choi
2013-08-16 00:15:57 +09:00
parent aad5012615
commit 90a5487974
6 changed files with 254 additions and 39 deletions

View File

@@ -188,14 +188,15 @@ 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_unmatched` | boolean | 1 | Whether to ignore lines without matching delimiter |
| `ignores` | array | `['String', 'Comment']` | Delimiters in these syntax highlight groups are ignored | | `ignores` | list | ['String', 'Comment'] | Delimiters in these syntax highlight groups are ignored |
| `indentation` | string | `k` | Indentation method (*k*eep, *d*eep, *s*hallow) |
| `delimiter_align` | string | `r` | Determines how to align delimiters of different lengths | | `delimiter_align` | string | `r` | Determines how to align delimiters of different lengths |
Some of the options can be specified using corresponding global variables. Some of the options can be specified using corresponding global variables.
@@ -352,6 +353,45 @@ banana += apple
cake ||= banana cake ||= banana
``` ```
### Adjusting indentation
By default :EasyAlign command keeps the original indentation of the lines. But
then again we have `indentation` option. See the following example.
```ruby
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
# Default: _k_eep the original indentation
# :EasyAlign=
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
# Use the _s_hallowest indentation among the lines
# :EasyAlign={'idt':s}
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
# Use the _d_eepest indentation among the lines
# :EasyAlign={'idt':d}
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
```
Notice that `idt` is fuzzy-matched to `indentation`.
### Extending alignment rules ### Extending alignment rules
Although the default rules should cover the most of the use cases, Although the default rules should cover the most of the use cases,
@@ -365,7 +405,7 @@ let g:easy_align_delimiters = {
\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] }, \ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] },
\ '#': { 'pattern': '#\+', 'ignores': ['String'], 'delimiter_align': 'l' }, \ '#': { 'pattern': '#\+', 'ignores': ['String'], 'delimiter_align': 'l' },
\ ']': { \ ']': {
\ 'pattern': '[\[\]]', \ 'pattern': '[[\]]',
\ 'left_margin': 0, \ 'left_margin': 0,
\ 'right_margin': 0, \ 'right_margin': 0,
\ 'stick_to_left': 0 \ 'stick_to_left': 0

View File

@@ -43,7 +43,7 @@ let s:just = ['', '[R]']
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], \ 'left_margin': [0, 1], 'right_margin': [0, 1], 'indentation': [1],
\ 'ignores': [3 ], 'ignore_unmatched': [0 ], 'delimiter_align': [1] \ 'ignores': [3 ], 'ignore_unmatched': [0 ], 'delimiter_align': [1]
\ } \ }
@@ -200,12 +200,14 @@ function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, i
return [tokens, delims] return [tokens, delims]
endfunction endfunction
function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth, ml, mr, da, stick_to_left, ignore_unmatched, ignores, recursive) function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
\ ml, mr, da, indentation, 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 min_indent = -1 let min_indent = -1
let max_indent = 0
" Phase 1 " Phase 1
for line in range(a:fl, a:ll) for line in range(a:fl, a:ll)
@@ -257,11 +259,35 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
if min_indent < 0 || indent < min_indent if min_indent < 0 || indent < min_indent
let min_indent = indent let min_indent = indent
endif endif
let max_indent = max([indent, max_indent])
let max_just_len = max([s:strwidth(prefix.token), max_just_len]) let max_just_len = max([s:strwidth(prefix.token), max_just_len])
let max_delim_len = max([s:strwidth(delim), max_delim_len]) let max_delim_len = max([s:strwidth(delim), max_delim_len])
let lines[line] = [nth, prefix, token, delim] let lines[line] = [nth, prefix, token, delim]
endfor endfor
" Phase 1-5: indentation handling (only on a:nth == 1)
if a:nth == 1
if a:indentation ==? 'd'
let indent = repeat(' ', max_indent)
elseif a:indentation ==? 's'
let indent = repeat(' ', min_indent)
elseif a:indentation !=? 'k'
call s:exit('Invalid indentation: ' . a:indentation)
end
if a:indentation !=? 'k'
let max_just_len = 0
for [line, elems] in items(lines)
let [nth, prefix, token, delim] = elems
let token = substitute(token, '^\s*', indent, '')
let max_just_len = max([max_just_len, s:strwidth(token)])
let lines[line][2] = token
endfor
endif
endif
" Phase 2 " Phase 2
for [line, elems] in items(lines) for [line, elems] in items(lines)
let tokens = a:all_tokens[line] let tokens = a:all_tokens[line]
@@ -314,7 +340,7 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
" Adjust indentation of the lines starting with a delimiter " Adjust indentation of the lines starting with a delimiter
let lpad = '' let lpad = ''
if nth == 0 if nth == 0
let ipad = repeat(' ', min_indent - len(strpart(before.token, '^\s\+').ml)) let ipad = repeat(' ', min_indent - len(token.ml))
if a:just == 0 if a:just == 0
let token = ipad . token let token = ipad . token
else else
@@ -334,8 +360,8 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
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:all_delims, a:fl, a:ll, a:fc, a:lc, a:pattern, call s:do_align(just, a:all_tokens, a:all_delims, a:fl, a:ll, a:fc, a:lc, a:pattern,
\ a:nth + 1, a:ml, a:mr, a:da, a:stick_to_left, a:ignore_unmatched, \ a:nth + 1, a:ml, a:mr, a:da, a:indentation, a:stick_to_left,
\ a:ignores, a:recursive) \ a:ignore_unmatched, a:ignores, a:recursive)
endif endif
endfunction endfunction
@@ -394,8 +420,8 @@ function! s:parse_args(args)
let cand = strpart(args, midx) let cand = strpart(args, midx)
try try
let [l, r, c] = ['l', 'r', 'c'] let [l, r, c, k, s, d] = ['l', 'r', 'c', 'k', 's', 'd']
let [L, R, C] = ['l', 'r', 'c'] let [L, R, C, K, S, D] = ['l', 'r', 'c', 'k', 's', 'd']
let o = eval(cand) let o = eval(cand)
if type(o) == 4 if type(o) == 4
let option = o let option = o
@@ -520,6 +546,7 @@ function! easy_align#align(just, expr) range
\ 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')),
\ get(dict, 'indentation', 'k'),
\ 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, 'ignores', s:ignored_syntax()),

View File

@@ -40,7 +40,7 @@ With this mapping, you can align selected lines of text with a few keystrokes.
2 Around the 2nd occurrences of delimiters 2 Around the 2nd occurrences of delimiters
* Around all occurrences of delimiters * Around all occurrences of delimiters
** Left-right alternating alignment around all delimiters ** Left-right alternating alignment around all delimiters
- Around the last occurrences of delimiters (`-1`) - Around the last occurrences of delimiters (-1)
-2 Around the second to last occurrences of delimiters -2 Around the second to last occurrences of delimiters
... ...
4. Delimiter key (a single keystroke) 4. Delimiter key (a single keystroke)
@@ -93,7 +93,7 @@ try these commands:
- :EasyAlign */[:;]\+/ - :EasyAlign */[:;]\+/
- :EasyAlign **/[:;]\+/ - :EasyAlign **/[:;]\+/
Notice that you can't append `\zs` to your regular expression to put delimiters Notice that you can't append '\zs' to your regular expression to put delimiters
on the left. It can be done by providing additional options in Vim dictionary on the left. It can be done by providing additional options in Vim dictionary
format. format.
@@ -115,19 +115,20 @@ You can even omit spaces between the arguments, so concisely (or cryptically):
Available options are as follows. Available options are as follows.
| Atrribute | Type | Default | | Atrribute | Type | Default |
| ---------------- | ---------------- | ----------------------- | | ---------------- | ---------------- | --------------------- |
| left_margin | number or string | 0 | | left_margin | number or string | 0 |
| right_margin | number or string | 0 | | right_margin | number or string | 0 |
| stick_to_left | boolean | 0 | | stick_to_left | boolean | 0 |
| delimiter_align | string | 'r' | | delimiter_align | string | 'r' |
| ignore_unmatched | boolean | 1 | | ignore_unmatched | boolean | 1 |
| ignores | array | `['String', 'Comment']` | | ignores | array | ['String', 'Comment'] |
| indentation | string | 'k' |
Partial alignment in blockwise-visual mode Partial alignment in blockwise-visual mode
------------------------------------------------------------------------- -------------------------------------------------------------------------
In blockwise-visual mode (`CTRL-V`), EasyAlign command aligns only 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.
@@ -154,7 +155,7 @@ For example, the following paragraph
'grape:fruits': 3 'grape:fruits': 3
} }
becomes as follows on `<Enter>:` becomes as follows on '<Enter>:'
{ {
# Quantity of apples: 1 # Quantity of apples: 1
@@ -173,7 +174,7 @@ array,
" Ignore nothing! " Ignore nothing!
let g:easy_align_ignores = [] let g:easy_align_ignores = []
or providing `ignores` option directly to :EasyAlign command or providing 'ignores' option directly to :EasyAlign command
:EasyAlign:{'is':[]} :EasyAlign:{'is':[]}
@@ -221,7 +222,7 @@ One way is to set the global `g:easy_align_ignore_unmatched` variable to 0.
let g:easy_align_ignore_unmatched = 0 let g:easy_align_ignore_unmatched = 0
Or in non-interactive mode, you can provide `ignore_unmatched` option to Or in non-interactive mode, you can provide 'ignore_unmatched' option to
`:EasyAlign` command as follows. `:EasyAlign` command as follows.
:EasyAlign:{'iu':0} :EasyAlign:{'iu':0}
@@ -238,12 +239,11 @@ Then we get,
} }
Aligning delimiters of different lengths *g:easy_align_delimiter_align* Aligning delimiters of different lengths *g:easy_align_delimiter_align*
------------------------------------------------------------------------- -------------------------------------------------------------------------
Global `g:easy_align_delimiter_align` option and rule-wise/command-wise Global `g:easy_align_delimiter_align` option and rule-wise/command-wise
`delimiter_align` option determines how matched delimiters of different 'delimiter_align' option determines how matched delimiters of different
lengths are aligned. lengths are aligned.
apple = 1 apple = 1
@@ -256,18 +256,58 @@ By default, delimiters are right-aligned as follows.
banana += apple banana += apple
cake ||= banana cake ||= banana
However, with `:EasyAlign={'da':l}`, delimiters are left-aligned. However, with ':EasyAlign={'da':l}', delimiters are left-aligned.
apple = 1 apple = 1
banana += apple banana += apple
cake ||= banana cake ||= banana
And on `:EasyAlign={'da':c}`, center-aligned. And on ':EasyAlign={'da':c}', center-aligned.
apple = 1 apple = 1
banana += apple banana += apple
cake ||= banana cake ||= banana
Adjusting indentation
-------------------------------------------------------------------------
By default :EasyAlign command keeps the original indentation of the lines.
But then again we have 'indentation' option. See the following example.
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
# Default: _k_eep the original indentation
# :EasyAlign=
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
# Use the _s_hallowest indentation among the lines
# :EasyAlign={'idt':s}
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
# Use the _d_eepest indentation among the lines
# :EasyAlign={'idt':d}
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
Notice that 'idt' is fuzzy-matched to 'indentation'.
Extending alignment rules *g:easy_align_delimiters* Extending alignment rules *g:easy_align_delimiters*
------------------------------------------------------------------------- -------------------------------------------------------------------------

View File

@@ -504,3 +504,105 @@ George Harrison 1943
.. -- ...... .. -- ......
... - .....- ... - .....-
apple = 1 = 2
banana = 2 = 2
cake = 3 = 2
daisy = 4 = 2
eggplant = 5 = 2
apple = 1 = 2
banana = 2 = 2
cake = 3 = 2
daisy = 4 = 2
eggplant = 5 = 2
apple = 1 = 2
banana = 2 = 2
cake = 3 = 2
daisy = 4 = 2
eggplant = 5 = 2
1 apple = 1 = 2
1 banana = 2 = 2
1 cake = 3 = 2
1 daisy = 4 = 2
1 eggplant = 5 = 2
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
a pple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1 = 2
banana = 2 = 2
cake = 3 = 2
daisy = 4 = 2
eggplant = 5 = 2
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5

View File

@@ -130,3 +130,9 @@ Pete Best 1941
..--...... ..--......
...-.....- ...-.....-
apple = 1
banana = 2
cake = 3
daisy = 4
eggplant = 5

View File

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