mirror of
https://github.com/junegunn/vim-easy-align.git
synced 2025-11-18 06:43:40 -05:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
013fb54dd1 | ||
|
|
2bf1b2164d | ||
|
|
bab23a1917 | ||
|
|
fa26fd7b42 | ||
|
|
a4a1e27395 | ||
|
|
98bd9fe6f0 | ||
|
|
f944f5bf29 | ||
|
|
484b4ba5ec | ||
|
|
9d3afa6206 | ||
|
|
4c6a8c174d | ||
|
|
3304f4e95a |
153
README.md
153
README.md
@@ -77,7 +77,7 @@ For convenience, it is advised that you define a mapping for triggering it in
|
||||
your `.vimrc`.
|
||||
|
||||
```vim
|
||||
vnoremap <silent> <Enter> :EasyAlign<cr>
|
||||
vnoremap <silent> <Enter> :EasyAlign<Enter>
|
||||
```
|
||||
|
||||
(Of course you can use any key combination as the trigger. e.g. `<Leader>a`)
|
||||
@@ -114,21 +114,21 @@ You can override these default rules or define your own rules with
|
||||
|
||||
#### Example command sequences
|
||||
|
||||
| With visual map | Description | Equivalent command |
|
||||
| ------------------- | ------------------------------------------------------- | ------------------------------- |
|
||||
| `<Enter><space>` | Alignment around 1st whitespaces | `:'<,'>EasyAlign\ ` |
|
||||
| `<Enter>2<space>` | Alignment around 2nd whitespaces | `:'<,'>EasyAlign2\ ` |
|
||||
| `<Enter>-<space>` | Alignment around the last whitespaces | `:'<,'>EasyAlign-\ ` |
|
||||
| `<Enter>-2<space>` | Alignment around the 2nd to last whitespaces | `:'<,'>EasyAlign-2\ ` |
|
||||
| `<Enter>:` | Alignment around 1st colon (`key: value`) | `:'<,'>EasyAlign:` |
|
||||
| `<Enter><Right>:` | Alignment around 1st colon (`key : value`) | `:'<,'>EasyAlign:{'s':0,'l':1}` |
|
||||
| `<Enter>=` | Alignment around 1st operators with = | `:'<,'>EasyAlign=` |
|
||||
| `<Enter>2=` | Alignment around 2nd operators with = | `:'<,'>EasyAlign2=` |
|
||||
| `<Enter>3=` | Alignment around 3rd operators with = | `:'<,'>EasyAlign3=` |
|
||||
| `<Enter>*=` | Alignment around all operators with = | `:'<,'>EasyAlign*=` |
|
||||
| `<Enter>**=` | Left-right alternating alignment around all = operators | `:'<,'>EasyAlign**=` |
|
||||
| `<Enter><Enter>=` | Right alignment around 1st equals signs | `:'<,'>EasyAlign!=` |
|
||||
| `<Enter><Enter>**=` | Right-left alternating alignment around all = operators | `:'<,'>EasyAlign!**=` |
|
||||
| With visual map | Description | Equivalent command |
|
||||
| ------------------- | ------------------------------------------------------- | ---------------------- |
|
||||
| `<Enter><space>` | Alignment around 1st whitespaces | `:'<,'>EasyAlign\ ` |
|
||||
| `<Enter>2<space>` | Alignment around 2nd whitespaces | `:'<,'>EasyAlign2\ ` |
|
||||
| `<Enter>-<space>` | Alignment around the last whitespaces | `:'<,'>EasyAlign-\ ` |
|
||||
| `<Enter>-2<space>` | Alignment around the 2nd to last whitespaces | `:'<,'>EasyAlign-2\ ` |
|
||||
| `<Enter>:` | Alignment around 1st colon (`key: value`) | `:'<,'>EasyAlign:` |
|
||||
| `<Enter><Right>:` | Alignment around 1st colon (`key : value`) | `:'<,'>EasyAlign:s0l1` |
|
||||
| `<Enter>=` | Alignment around 1st operators with = | `:'<,'>EasyAlign=` |
|
||||
| `<Enter>2=` | Alignment around 2nd operators with = | `:'<,'>EasyAlign2=` |
|
||||
| `<Enter>3=` | Alignment around 3rd operators with = | `:'<,'>EasyAlign3=` |
|
||||
| `<Enter>*=` | Alignment around all operators with = | `:'<,'>EasyAlign*=` |
|
||||
| `<Enter>**=` | Left-right alternating alignment around all = operators | `:'<,'>EasyAlign**=` |
|
||||
| `<Enter><Enter>=` | Right alignment around 1st equals signs | `:'<,'>EasyAlign!=` |
|
||||
| `<Enter><Enter>**=` | Right-left alternating alignment around all = operators | `:'<,'>EasyAlign!**=` |
|
||||
|
||||
#### Using regular expressions
|
||||
|
||||
@@ -158,6 +158,14 @@ keys listed below. The meaning of each option will be described in
|
||||
| `CTRL-O` | `mode_sequence` | Input string of `/[lrc]+\*{0,2}/` |
|
||||
| `<Left>` | `stick_to_left` | `{ 'stick_to_left': 1, 'left_margin': 0 }` |
|
||||
| `<Right>` | `stick_to_left` | `{ 'stick_to_left': 0, 'left_margin': 1 }` |
|
||||
| `<Down>` | `*_margin` | `{ 'left_margin': 0, 'right_margin': 0 }` |
|
||||
|
||||
After a successful alignment, you can repeat the same operation using the
|
||||
repeatable, non-interactive command recorded in `g:easy_align_last_command`.
|
||||
|
||||
```vim
|
||||
:<C-R>=g:easy_align_last_command<Enter><Enter>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -171,9 +179,9 @@ Go try out vim-easy-align right now, and come back later when you feel like it.
|
||||
|
||||
---
|
||||
|
||||
### Non-interactive mode
|
||||
### Using `EasyAlign` in command line
|
||||
|
||||
Instead of going into the interactive mode, you can type in arguments to
|
||||
Instead of going into the interactive mode, you can just type in arguments to
|
||||
`:EasyAlign` command.
|
||||
|
||||
```vim
|
||||
@@ -215,8 +223,26 @@ You can even omit spaces between the arguments, so concisely (or cryptically):
|
||||
|
||||
- `:EasyAlign*/[:;]\+/{'s':1,'l':0}`
|
||||
|
||||
The same thing can be done in the interactive mode as well with the following
|
||||
key combination.
|
||||
Nice. But let's make it even shorter. Option values can be written in shorthand
|
||||
notation.
|
||||
|
||||
- `:EasyAlign*/[:;]\+/s1l0`
|
||||
|
||||
The following table summarizes the shorthand notation.
|
||||
|
||||
| Option | Expression |
|
||||
| ---------------- | ---------- |
|
||||
| left_margin | `l[0-9]+` |
|
||||
| right_margin | `r[0-9]+` |
|
||||
| stick_to_left | `s[01]` |
|
||||
| ignore_unmatched | `iu[01]` |
|
||||
| ignore_groups | `ig\[.*\]` |
|
||||
| delimiter_align | `d[lrc]` |
|
||||
| mode_sequence | `m[lrc*]*` |
|
||||
| indentation | `i[ksdn]` |
|
||||
|
||||
For your information, the same thing can be done in the interactive mode as well
|
||||
with the following key combination.
|
||||
|
||||
- `<Enter>`
|
||||
- `*`
|
||||
@@ -273,19 +299,19 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
|
||||
|
||||
1. Some option values can be set with corresponding global variables
|
||||
2. Option values can be specified in the definition of each alignment rule
|
||||
3. Option values can be given as a dictionary argument to `:EasyAlign` command
|
||||
3. Option values can be given as arguments to `:EasyAlign` command
|
||||
4. Option values can be set in interactive mode using special shortcut keys
|
||||
|
||||
| Option | Shortcut key | Global variable |
|
||||
| ------------------ | ------------------- | ------------------------------- |
|
||||
| `left_margin` | `CTRL-L` | |
|
||||
| `right_margin` | `CTRL-R` | |
|
||||
| `stick_to_left` | `<Left>`, `<Right>` | |
|
||||
| `ignore_groups` | `CTRL-G` | `g:easy_align_ignore_groups` |
|
||||
| `ignore_unmatched` | `CTRL-U` | `g:easy_align_ignore_unmatched` |
|
||||
| `indentation` | `CTRL-I` | `g:easy_align_indentation` |
|
||||
| `delimiter_align` | `CTRL-D` | `g:easy_align_delimiter_align` |
|
||||
| `mode_sequence` | `CTRL-O` | |
|
||||
| Option name | Shortcut key | Abbreviated | Global variable |
|
||||
| ------------------ | ------------------- | ----------- | ------------------------------- |
|
||||
| `left_margin` | `CTRL-L` | `l[0-9]+` | |
|
||||
| `right_margin` | `CTRL-R` | `r[0-9]+` | |
|
||||
| `stick_to_left` | `<Left>`, `<Right>` | `s[01]` | |
|
||||
| `ignore_groups` | `CTRL-G` | `ig\[.*\]` | `g:easy_align_ignore_groups` |
|
||||
| `ignore_unmatched` | `CTRL-U` | `iu[01]` | `g:easy_align_ignore_unmatched` |
|
||||
| `indentation` | `CTRL-I` | `i[ksdn]` | `g:easy_align_indentation` |
|
||||
| `delimiter_align` | `CTRL-D` | `d[lrc]` | `g:easy_align_delimiter_align` |
|
||||
| `mode_sequence` | `CTRL-O` | `m[lrc*]*` | |
|
||||
|
||||
### Ignoring delimiters in comments or strings
|
||||
|
||||
@@ -334,7 +360,7 @@ You can change the default rule by using one of these 4 methods.
|
||||
2. Define global `g:easy_align_ignore_groups` list
|
||||
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':[]}`
|
||||
e.g. `:EasyAlign:ig[]`
|
||||
|
||||
For example if you set `ignore_groups` option to be an empty list, you get
|
||||
|
||||
@@ -353,10 +379,18 @@ Satisfied? :satisfied:
|
||||
|
||||
### Ignoring unmatched lines
|
||||
|
||||
Lines without any matching delimiter are ignored as well (except in
|
||||
right-align mode).
|
||||
`ignore_unmatched` option determines how EasyAlign command processes lines that
|
||||
do not have N-th delimiter.
|
||||
|
||||
For example, when aligning the following code block around the colons,
|
||||
1. In left-alignment mode, they are ignored
|
||||
2. In right or center-alignment mode, they are *not* ignored, and the last
|
||||
tokens from those lines are aligned as well as if there is an invisible
|
||||
trailing delimiter at the end of each line
|
||||
3. If `ignore_unmatched` is 1, they are ignored regardless of the alignment mode
|
||||
4. If `ignore_unmatched` is 0, they are *not* ignored regardless of the mode
|
||||
|
||||
Let's take an example.
|
||||
When we align the following code block around the (1st) colons,
|
||||
|
||||
```ruby
|
||||
{
|
||||
@@ -380,13 +414,13 @@ this is usually what we want.
|
||||
}
|
||||
```
|
||||
|
||||
However, this default behavior is also configurable by using one of these 4
|
||||
methods.
|
||||
However, we can override this default behavior by setting `ignore_unmatched`
|
||||
option to zero using one of the following methods.
|
||||
|
||||
1. Press `CTRL-U` in interactive mode to toggle `ignore_unmatched` option
|
||||
2. Set the global `g:easy_align_ignore_unmatched` variable to 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}`
|
||||
4. Provide `ignore_unmatched` option to `:EasyAlign` command. e.g. `:EasyAlign:iu0`
|
||||
|
||||
Then we get,
|
||||
|
||||
@@ -420,7 +454,7 @@ banana += apple
|
||||
cake ||= banana
|
||||
```
|
||||
|
||||
However, with `:EasyAlign={'da':l}`, delimiters are left-aligned.
|
||||
However, with `:EasyAlign=dl`, delimiters are left-aligned.
|
||||
|
||||
```ruby
|
||||
apple = 1
|
||||
@@ -428,7 +462,7 @@ banana += apple
|
||||
cake ||= banana
|
||||
```
|
||||
|
||||
And on `:EasyAlign={'da':c}`, center-aligned.
|
||||
And on `:EasyAlign=dc`, center-aligned.
|
||||
|
||||
```ruby
|
||||
apple = 1
|
||||
@@ -460,7 +494,7 @@ then again we have `indentation` option. See the following example.
|
||||
eggplant = 5
|
||||
|
||||
# Use the _s_hallowest indentation among the lines
|
||||
# :EasyAlign={'idt':s}
|
||||
# :EasyAlign=is
|
||||
apple = 1
|
||||
banana = 2
|
||||
cake = 3
|
||||
@@ -468,7 +502,7 @@ then again we have `indentation` option. See the following example.
|
||||
eggplant = 5
|
||||
|
||||
# Use the _d_eepest indentation among the lines
|
||||
# :EasyAlign={'idt':d}
|
||||
# :EasyAlign=id
|
||||
apple = 1
|
||||
banana = 2
|
||||
cake = 3
|
||||
@@ -476,7 +510,7 @@ then again we have `indentation` option. See the following example.
|
||||
eggplant = 5
|
||||
|
||||
# Indentation: _n_one
|
||||
# :EasyAlign={'idt':n}
|
||||
# :EasyAlign=in
|
||||
apple = 1
|
||||
banana = 2
|
||||
cake = 3
|
||||
@@ -488,26 +522,6 @@ 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
|
||||
|
||||
In interactive mode, you can choose the alignment mode you want by pressing
|
||||
enter keys. The non-bang command, `:EasyAlign` starts in left-alignment mode
|
||||
and changes to right and center mode as you press enter keys, while the bang
|
||||
version first starts in right-alignment mode.
|
||||
|
||||
- `:EasyAlign`
|
||||
- Left, Right, Center
|
||||
- `:EasyAlign!`
|
||||
- Right, Left, Center
|
||||
|
||||
If you do not prefer this default mode transition, you can define your own
|
||||
settings as follows.
|
||||
|
||||
```vim
|
||||
let g:easy_align_interactive_modes = ['l', 'r']
|
||||
let g:easy_align_bang_interactive_modes = ['c', 'r']
|
||||
```
|
||||
|
||||
### Alignments over multiple occurrences of delimiters
|
||||
|
||||
As stated above, "N-th" parameter is used to target specific occurrences of
|
||||
@@ -546,24 +560,27 @@ in interactive mode with the special key `CTRL-O`)
|
||||
" Right, left, center alignment over the 1st to 3rd occurrences of delimiters
|
||||
:EasyAlign = { 'm': 'rlc' }
|
||||
|
||||
" Using shorthand notation
|
||||
:EasyAlign = mrlc
|
||||
|
||||
" Right, left, center alignment over the 2nd to 4th occurrences of delimiters
|
||||
:EasyAlign 2={ 'm': 'rlc' }
|
||||
:EasyAlign 2=mrlc
|
||||
|
||||
" (*) Repeating alignments (default: l, r, or c)
|
||||
" Right, left, center, center, center, center, ...
|
||||
:EasyAlign *={ 'm': 'rlc' }
|
||||
:EasyAlign *=mrlc
|
||||
|
||||
" (**) Alternating alignments (default: lr or rl)
|
||||
" Right, left, center, right, left, center, ...
|
||||
:EasyAlign **={ 'm': 'rlc' }
|
||||
:EasyAlign **=mrlc
|
||||
|
||||
" Right, left, center, center, center, ... repeating alignment
|
||||
" over the 3rd to the last occurrences of delimiters
|
||||
:EasyAlign 3={ 'm': 'rlc*' }
|
||||
:EasyAlign 3=mrlc*
|
||||
|
||||
" Right, left, center, right, left, center, ... alternating alignment
|
||||
" over the 3rd to the last occurrences of delimiters
|
||||
:EasyAlign 3={ 'm': 'rlc**' }
|
||||
:EasyAlign 3=mrlc**
|
||||
```
|
||||
|
||||
### Extending alignment rules
|
||||
|
||||
@@ -49,10 +49,10 @@ let s:known_options = {
|
||||
\ }
|
||||
|
||||
let s:option_values = {
|
||||
\ 'indentation': ['shallow', 'deep', 'none', 'keep'],
|
||||
\ 'delimiter_align': ['left', 'center', 'right'],
|
||||
\ 'ignore_unmatched': [0, 1],
|
||||
\ 'ignore_groups': [[], ['String'], ['Comment'], ['String', 'Comment']]
|
||||
\ 'indentation': ['shallow', 'deep', 'none', 'keep', -1],
|
||||
\ 'delimiter_align': ['left', 'center', 'right', -1],
|
||||
\ 'ignore_unmatched': [0, 1, -1],
|
||||
\ 'ignore_groups': [[], ['String'], ['Comment'], ['String', 'Comment'], -1]
|
||||
\ }
|
||||
|
||||
let s:shorthand = {
|
||||
@@ -142,6 +142,7 @@ function! s:echon(l, n, r, d, o, warn)
|
||||
endif
|
||||
|
||||
call s:echon_(tokens)
|
||||
return join(map(tokens, 'v:val[1]'), '')
|
||||
endfunction
|
||||
|
||||
function! s:exit(msg)
|
||||
@@ -311,7 +312,10 @@ function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left,
|
||||
let delims = []
|
||||
" Append an empty item to enable right/center alignment of the last token
|
||||
" - if the last token is not ignorable or ignorable but not the only token
|
||||
elseif (mode ==? 'r' || mode ==? 'c') && (!ignorable || len(tokens) > 1) && a:nth >= 0 " includes -0
|
||||
elseif a:ignore_unmatched != 1 &&
|
||||
\ (mode ==? 'r' || mode ==? 'c') &&
|
||||
\ (!ignorable || len(tokens) > 1) &&
|
||||
\ a:nth >= 0 " includes -0
|
||||
call add(tokens, '')
|
||||
call add(delims, '')
|
||||
endif
|
||||
@@ -557,6 +561,15 @@ function! s:atoi(str)
|
||||
return (a:str =~ '^[0-9]\+$') ? str2nr(a:str) : a:str
|
||||
endfunction
|
||||
|
||||
function! s:shift_opts(opts, key, vals)
|
||||
let val = s:shift(a:vals, 1)
|
||||
if type(val) == 0 && val == -1
|
||||
call remove(a:opts, a:key)
|
||||
else
|
||||
let a:opts[a:key] = val
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:interactive(modes, vis, opts, delims)
|
||||
let mode = s:shift(a:modes, 1)
|
||||
let n = ''
|
||||
@@ -600,9 +613,9 @@ function! s:interactive(modes, vis, opts, delims)
|
||||
else | let n = n . ch
|
||||
end
|
||||
elseif ch == "\<C-D>"
|
||||
let opts['da'] = s:shift(vals['delimiter_align'], 1)
|
||||
call s:shift_opts(opts, 'da', vals['delimiter_align'])
|
||||
elseif ch == "\<C-I>"
|
||||
let opts['idt'] = s:shift(vals['indentation'], 1)
|
||||
call s:shift_opts(opts, 'idt', vals['indentation'])
|
||||
elseif ch == "\<C-L>"
|
||||
let lm = s:input("Left margin: ", get(opts, 'lm', ''), a:vis)
|
||||
if empty(lm)
|
||||
@@ -620,18 +633,22 @@ function! s:interactive(modes, vis, opts, delims)
|
||||
let opts['rm'] = s:atoi(rm)
|
||||
endif
|
||||
elseif ch == "\<C-U>"
|
||||
let opts['iu'] = s:shift(vals['ignore_unmatched'], 1)
|
||||
call s:shift_opts(opts, 'iu', vals['ignore_unmatched'])
|
||||
elseif ch == "\<C-G>"
|
||||
let opts['ig'] = s:shift(vals['ignore_groups'], 1)
|
||||
call s:shift_opts(opts, 'ig', vals['ignore_groups'])
|
||||
elseif c == "\<Left>"
|
||||
let opts['stl'] = 1
|
||||
let opts['lm'] = 0
|
||||
elseif c == "\<Right>"
|
||||
let opts['stl'] = 0
|
||||
let opts['lm'] = 1
|
||||
elseif c == "\<Up>" || c == "\<Down>"
|
||||
elseif c == "\<Down>"
|
||||
let opts['lm'] = 0
|
||||
let opts['rm'] = 0
|
||||
elseif c == "\<Up>"
|
||||
silent! call remove(opts, 'stl')
|
||||
silent! call remove(opts, 'lm')
|
||||
silent! call remove(opts, 'rm')
|
||||
elseif ch == "\<C-O>"
|
||||
let modes = tolower(s:input("Mode sequence: ", get(opts, 'm', mode), a:vis))
|
||||
if match(modes, '^[lrc]\+\*\{0,2}$') != -1
|
||||
@@ -684,6 +701,54 @@ function! s:test_regexp(regexp)
|
||||
return a:regexp
|
||||
endfunction
|
||||
|
||||
let s:shorthand_regex =
|
||||
\ '\s*\('
|
||||
\ .'\(lm\?[0-9]\+\)\|\(rm\?[0-9]\+\)\|\(iu[01]\)\|\(s\%(tl\)\?[01]\)\|'
|
||||
\ .'\(da\?[clr]\)\|\(ms\?[lrc*]\+\)\|\(i\%(dt\)\?[kdsn]\)\|\(ig\[.*\]\)'
|
||||
\ .'\)\+\s*$'
|
||||
|
||||
function! s:parse_shorthand_opts(expr)
|
||||
let opts = {}
|
||||
let expr = substitute(a:expr, '\s', '', 'g')
|
||||
let regex = '^'. s:shorthand_regex
|
||||
|
||||
if empty(expr)
|
||||
return opts
|
||||
elseif expr !~ regex
|
||||
call s:exit("Invalid expression: ". a:expr)
|
||||
else
|
||||
let match = matchlist(expr, regex)
|
||||
if empty(match) | break | endif
|
||||
for m in filter(match[ 2 : -1 ], '!empty(v:val)')
|
||||
for key in ['lm', 'rm', 'l', 'r', 'stl', 's', 'iu', 'da', 'd', 'ms', 'm', 'ig', 'i']
|
||||
if stridx(tolower(m), key) == 0
|
||||
let rest = strpart(m, len(key))
|
||||
if key == 'i' | let key = 'idt' | endif
|
||||
|
||||
if key == 'idt' || index(['d', 'm'], key[0]) >= 0
|
||||
let opts[key] = rest
|
||||
elseif key == 'ig'
|
||||
try
|
||||
let arr = eval(rest)
|
||||
if type(arr) == 3
|
||||
let opts[key] = arr
|
||||
else
|
||||
throw 'Not an array'
|
||||
endif
|
||||
catch
|
||||
call s:exit("Invalid ignore_groups: ". a:expr)
|
||||
endtry
|
||||
else
|
||||
let opts[key] = str2nr(rest)
|
||||
endif
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
return s:normalize_options(opts)
|
||||
endfunction
|
||||
|
||||
function! s:parse_args(args)
|
||||
let n = ''
|
||||
let ch = ''
|
||||
@@ -723,6 +788,13 @@ function! s:parse_args(args)
|
||||
let opts = s:normalize_options(opts)
|
||||
endif
|
||||
|
||||
" Shorthand option notation
|
||||
let sopts = matchstr(args, s:shorthand_regex)
|
||||
if !empty(sopts)
|
||||
let args = strpart(args, 0, len(args) - len(sopts))
|
||||
let opts = extend(s:parse_shorthand_opts(sopts), opts)
|
||||
endif
|
||||
|
||||
" Has /Regexp/?
|
||||
let matches = matchlist(args, '^\(.\{-}\)\s*/\(.*\)/\s*$')
|
||||
|
||||
@@ -848,7 +920,7 @@ function! s:align(bang, first_line, last_line, expr)
|
||||
\ get(dict, 'delimiter_align', get(g:, 'easy_align_delimiter_align', 'r'))[0],
|
||||
\ get(dict, 'indentation', get(g:, 'easy_align_indentation', 'k'))[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', 2)),
|
||||
\ get(dict, 'ignore_groups', get(dict, 'ignores', s:ignored_syntax())),
|
||||
\ recur)
|
||||
|
||||
@@ -860,6 +932,6 @@ function! s:align(bang, first_line, last_line, expr)
|
||||
\ )
|
||||
call extend(copts, { 'm': aseq_str })
|
||||
endif
|
||||
call s:echon('', n, regexp, ch, copts, '')
|
||||
let g:easy_align_last_command = s:echon('', n, regexp, ch, copts, '')
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ The command will go into the interactive mode when no argument is given.
|
||||
For convenience, it is advised that you define a mapping for triggering it in
|
||||
your `.vimrc`.
|
||||
|
||||
vnoremap <silent> <Enter> :EasyAlign<cr>
|
||||
vnoremap <silent> <Enter> :EasyAlign<Enter>
|
||||
|
||||
With this mapping, you can align selected lines of text with a few keystrokes.
|
||||
|
||||
@@ -97,9 +97,39 @@ described in the following sections.
|
||||
| CTRL-O | mode_sequence | Input string of /[lrc]+\*{0,2}/ |
|
||||
| <Left> | stick_to_left | { 'stick_to_left': 1, 'left_margin': 0 } |
|
||||
| <Right> | stick_to_left | { 'stick_to_left': 0, 'left_margin': 1 } |
|
||||
| <Down> | *_margin | { 'left_margin': 0, 'right_margin': 0 } |
|
||||
|
||||
*g:easy_align_last_command*
|
||||
|
||||
After a successful alignment, you can repeat the same operation using the
|
||||
repeatable, non-interactive command recorded in `g:easy_align_last_command`.
|
||||
|
||||
:<C-R>=g:easy_align_last_command<Enter><Enter>
|
||||
|
||||
|
||||
Non-interactive mode
|
||||
Left/right/center mode switch in interactive mode
|
||||
-------------------------------------------------------------------------
|
||||
*g:easy_align_interactive_modes*
|
||||
*g:easy_align_bang_interactive_modes*
|
||||
|
||||
In interactive mode, you can choose the alignment mode you want by pressing
|
||||
enter keys. The non-bang command, `:EasyAlign` starts in left-alignment mode
|
||||
and changes to right and center mode as you press enter keys, while the bang
|
||||
version first starts in right-alignment mode.
|
||||
|
||||
- `:EasyAlign`
|
||||
- Left, Right, Center
|
||||
- `:EasyAlign!`
|
||||
- Right, Left, Center
|
||||
|
||||
If you do not prefer this default mode transition, you can define your own
|
||||
settings as follows.
|
||||
|
||||
let g:easy_align_interactive_modes = ['l', 'r']
|
||||
let g:easy_align_bang_interactive_modes = ['c', 'r']
|
||||
|
||||
|
||||
Using EasyAlign in command line
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Instead of going into the interactive mode, you can type in arguments to
|
||||
@@ -118,16 +148,16 @@ For example, when aligning the following lines around colons and semi-colons,
|
||||
|
||||
try these commands:
|
||||
|
||||
- :EasyAlign /[:;]\+/
|
||||
- :EasyAlign 2/[:;]\+/
|
||||
- :EasyAlign */[:;]\+/
|
||||
- :EasyAlign **/[:;]\+/
|
||||
:EasyAlign /[:;]\+/
|
||||
:EasyAlign 2/[:;]\+/
|
||||
:EasyAlign */[:;]\+/
|
||||
:EasyAlign **/[:;]\+/
|
||||
|
||||
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
|
||||
format.
|
||||
|
||||
- :EasyAlign * /[:;]\+/ { 'stick_to_left': 1, 'left_margin': 0 }
|
||||
:EasyAlign * /[:;]\+/ { 'stick_to_left': 1, 'left_margin': 0 }
|
||||
|
||||
Then we get:
|
||||
|
||||
@@ -136,20 +166,38 @@ Then we get:
|
||||
|
||||
Option names are fuzzy-matched, so you can write as follows:
|
||||
|
||||
- :EasyAlign * /[:;]\+/ { 'stl': 1, 'l': '' }
|
||||
:EasyAlign * /[:;]\+/ { 'stl': 1, 'l': '' }
|
||||
|
||||
You can even omit spaces between the arguments, so concisely (or cryptically):
|
||||
|
||||
- :EasyAlign*/[:;]\+/{'s':1,'l':''}
|
||||
:EasyAlign*/[:;]\+/{'s':1,'l':''}
|
||||
|
||||
The same thing can be done in the interactive mode as well with the following
|
||||
key combination.
|
||||
Nice. But let's make it even shorter. Option values can be written in shorthand
|
||||
notation.
|
||||
|
||||
- <Enter>
|
||||
- *
|
||||
- <Left>
|
||||
- <CTRL-/> (or <CTRL-X> on GVim)
|
||||
- [:;]\+
|
||||
:EasyAlign*/[:;]\+/s1l0
|
||||
|
||||
The following table summarizes the shorthand notation.
|
||||
|
||||
| Option | Expression |
|
||||
| -------------- | ---------- |
|
||||
| left_margin | l[0-9]+ |
|
||||
| right_margin | r[0-9]+ |
|
||||
| stick_to_left | s[01] |
|
||||
| ignore_unmatched | iu[01] |
|
||||
| ignore_groups | ig\[.*\] |
|
||||
| delimiter_align | d[lrc] |
|
||||
| mode_sequence | m[lrc*]+ |
|
||||
| indentation | i[ksdn] |
|
||||
|
||||
For your information, the same thing can be done in the interactive mode as well
|
||||
with the following key combination.
|
||||
|
||||
- <Enter>
|
||||
- *
|
||||
- <Left>
|
||||
- <CTRL-/> (or <CTRL-X> on GVim)
|
||||
- [:;]\+
|
||||
|
||||
|
||||
Partial alignment in blockwise-visual mode
|
||||
@@ -182,19 +230,19 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
|
||||
|
||||
1. Some option values can be set with corresponding global variables
|
||||
2. Option values can be specified in the definition of each alignment rule
|
||||
3. Option values can be given as a dictionary argument to :EasyAlign command
|
||||
3. Option values can be given as arguments to :EasyAlign command
|
||||
4. Option values can be set in interactive mode using special shortcut keys
|
||||
|
||||
| Option | Shortcut key | Global variable |
|
||||
| ---------------- | ------------------- | ------------------------------- |
|
||||
| left_margin | CTRL-L | |
|
||||
| right_margin | CTRL-R | |
|
||||
| stick_to_left | <Left>, <Right> | |
|
||||
| ignore_groups | CTRL-G | `g:easy_align_ignore_groups` |
|
||||
| ignore_unmatched | CTRL-U | `g:easy_align_ignore_unmatched` |
|
||||
| indentation | CTRL-I | `g:easy_align_indentation` |
|
||||
| delimiter_align | CTRL-D | `g:easy_align_delimiter_align` |
|
||||
| mode_sequence | CTRL-O | |
|
||||
| Option | Shortcut key | Abbreviated | Global variable |
|
||||
| ---------------- | --------------- | ----------- | ----------------------------- |
|
||||
| left_margin | CTRL-L | l[0-9]+ | |
|
||||
| right_margin | CTRL-R | r[0-9]+ | |
|
||||
| stick_to_left | <Left>, <Right> | s[01] | |
|
||||
| ignore_groups | CTRL-G | ig\[.*\] | `g:easy_align_ignore_groups` |
|
||||
| ignore_unmatched | CTRL-U | iu[01] | `g:easy_align_ignore_unmatched` |
|
||||
| indentation | CTRL-I | i[ksdn] | `g:easy_align_indentation` |
|
||||
| delimiter_align | CTRL-D | d[lrc] | `g:easy_align_delimiter_align` |
|
||||
| mode_sequence | CTRL-O | m[lrc*]+ | |
|
||||
|
||||
|
||||
Ignoring delimiters in comments or strings *g:easy_align_ignore_groups*
|
||||
@@ -239,7 +287,7 @@ You can change the default rule by using one of these 4 methods.
|
||||
2. Define global `g:easy_align_ignore_groups` list
|
||||
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':[]}
|
||||
e.g. :EasyAlign:ig[]
|
||||
|
||||
For example if you set 'ignore_groups' option to be an empty list, you get
|
||||
|
||||
@@ -256,10 +304,18 @@ For example if you set 'ignore_groups' option to be an empty list, you get
|
||||
Ignoring unmatched lines *g:easy_align_ignore_unmatched*
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Lines without any matching delimiter are ignored as well (except in
|
||||
right-align mode).
|
||||
'ignore_unmatched' option determines how EasyAlign command processes lines that
|
||||
do not have N-th delimiter.
|
||||
|
||||
For example, when aligning the following code block around the colons,
|
||||
1. In left-alignment mode, they are ignored
|
||||
2. In right or center-alignment mode, they are not ignored, and the last
|
||||
tokens from those lines are aligned as well as if there is an invisible
|
||||
trailing delimiter at the end of each line
|
||||
3. If 'ignore_unmatched' is 1, they are ignored regardless of the alignment mode
|
||||
4. If 'ignore_unmatched' is 0, they are not ignored regardless of the mode
|
||||
|
||||
Let's take an example.
|
||||
When we align the following code block around the (1st) colons,
|
||||
|
||||
{
|
||||
apple: proc {
|
||||
@@ -279,14 +335,14 @@ this is usually what we want.
|
||||
grapefruits: 3
|
||||
}
|
||||
|
||||
However, this default behavior is also configurable by using one of these 4
|
||||
methods.
|
||||
However, we can override this default behavior by setting 'ignore_unmatched'
|
||||
option to zero using one of the following methods.
|
||||
|
||||
1. Press CTRL-U in interactive mode to toggle 'ignore_unmatched' option
|
||||
2. Set the global `g:easy_align_ignore_unmatched` variable to 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}
|
||||
e.g. :EasyAlign:iu0
|
||||
|
||||
Then we get,
|
||||
|
||||
@@ -316,13 +372,13 @@ By default, delimiters are right-aligned as follows.
|
||||
banana += apple
|
||||
cake ||= banana
|
||||
|
||||
However, with ':EasyAlign={'da':l}', delimiters are left-aligned.
|
||||
However, with ':EasyAlign=dl', delimiters are left-aligned.
|
||||
|
||||
apple = 1
|
||||
banana += apple
|
||||
cake ||= banana
|
||||
|
||||
And on ':EasyAlign={'da':c}', center-aligned.
|
||||
And on ':EasyAlign=dc', center-aligned.
|
||||
|
||||
apple = 1
|
||||
banana += apple
|
||||
@@ -353,7 +409,7 @@ But then again we have 'indentation' option. See the following example.
|
||||
eggplant = 5
|
||||
|
||||
# Use the _s_hallowest indentation among the lines
|
||||
# :EasyAlign={'idt':s}
|
||||
# :EasyAlign=is
|
||||
apple = 1
|
||||
banana = 2
|
||||
cake = 3
|
||||
@@ -361,7 +417,7 @@ But then again we have 'indentation' option. See the following example.
|
||||
eggplant = 5
|
||||
|
||||
# Use the _d_eepest indentation among the lines
|
||||
# :EasyAlign={'idt':d}
|
||||
# :EasyAlign=id
|
||||
apple = 1
|
||||
banana = 2
|
||||
cake = 3
|
||||
@@ -369,7 +425,7 @@ But then again we have 'indentation' option. See the following example.
|
||||
eggplant = 5
|
||||
|
||||
# Indentation: _n_one
|
||||
# :EasyAlign={'idt':n}
|
||||
# :EasyAlign=in
|
||||
apple = 1
|
||||
banana = 2
|
||||
cake = 3
|
||||
@@ -382,28 +438,6 @@ 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
|
||||
-------------------------------------------------------------------------
|
||||
*g:easy_align_interactive_modes*
|
||||
*g:easy_align_bang_interactive_modes*
|
||||
|
||||
In interactive mode, you can choose the alignment mode you want by pressing
|
||||
enter keys. The non-bang command, `:EasyAlign` starts in left-alignment mode
|
||||
and changes to right and center mode as you press enter keys, while the bang
|
||||
version first starts in right-alignment mode.
|
||||
|
||||
- `:EasyAlign`
|
||||
- Left, Right, Center
|
||||
- `:EasyAlign!`
|
||||
- Right, Left, Center
|
||||
|
||||
If you do not prefer this default mode transition, you can define your own
|
||||
settings as follows.
|
||||
|
||||
let g:easy_align_interactive_modes = ['l', 'r']
|
||||
let g:easy_align_bang_interactive_modes = ['c', 'r']
|
||||
|
||||
|
||||
Alignments over multiple occurrences of delimiters
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
@@ -440,24 +474,27 @@ in interactive mode with the special key CTRL-O)
|
||||
" Right, left, center alignment over the 1st to 3rd occurrences of delimiters
|
||||
:EasyAlign = { 'm': 'rlc' }
|
||||
|
||||
" Using shorthand notation
|
||||
:EasyAlign = mrlc
|
||||
|
||||
" Right, left, center alignment over the 2nd to 4th occurrences of delimiters
|
||||
:EasyAlign 2={ 'm': 'rlc' }
|
||||
:EasyAlign 2=mrlc
|
||||
|
||||
" (*) Repeating alignments (default: l, r, or c)
|
||||
" Right, left, center, center, center, center, ...
|
||||
:EasyAlign *={ 'm': 'rlc' }
|
||||
:EasyAlign *=mrlc
|
||||
|
||||
" (**) Alternating alignments (default: lr or rl)
|
||||
" Right, left, center, right, left, center, ...
|
||||
:EasyAlign **={ 'm': 'rlc' }
|
||||
:EasyAlign **=mrlc
|
||||
|
||||
" Right, left, center, center, center, ... repeating alignment
|
||||
" over the 3rd to the last occurrences of delimiters
|
||||
:EasyAlign 3={ 'm': 'rlc*' }
|
||||
:EasyAlign 3=mrlc*
|
||||
|
||||
" Right, left, center, right, left, center, ... alternating alignment
|
||||
" over the 3rd to the last occurrences of delimiters
|
||||
:EasyAlign 3={ 'm': 'rlc**' }
|
||||
:EasyAlign 3=mrlc**
|
||||
|
||||
|
||||
Extending alignment rules *g:easy_align_delimiters*
|
||||
|
||||
@@ -1064,3 +1064,12 @@ aaa, b,
|
||||
111 22 333 444 55555 6666 7 88888
|
||||
1111 2 33 444 555 66 777 8
|
||||
|
||||
a = 1
|
||||
bb = 2
|
||||
ccccc
|
||||
ddd = 3
|
||||
|
||||
a = 1
|
||||
bb = 2
|
||||
ccccc
|
||||
ddd = 3
|
||||
|
||||
@@ -1 +1 @@
|
||||
4Gvipjyvip
|
||||
4Gvipjyvip
|
||||
|
||||
@@ -94,3 +94,35 @@ banana = 'Gros Michel' # comment 2
|
||||
a()p()p()l()e();():()b()a()n()a()n()a():():()c()a()k()e(
|
||||
d()a()t()a();();()e()x()c()h()a()n()g()e():();()f()o()r()m()a()t(
|
||||
|
||||
apple ;: banana :: cake
|
||||
data ;;exchange :;format
|
||||
|
||||
apple ;: banana :: cake
|
||||
data ;; exchange :; format
|
||||
|
||||
apple;:banana ::cake
|
||||
data ;;exchange:;format
|
||||
|
||||
apple ;: banana :: cake
|
||||
data ;; exchange :; format
|
||||
|
||||
a+= 1
|
||||
bb==# 2
|
||||
ccc= 3
|
||||
dddd=> 4
|
||||
|
||||
apple;: banana:: cake
|
||||
data;; exchange:; format
|
||||
|
||||
```ruby
|
||||
apple = 1 # comment not aligned
|
||||
apricot = 'DAD' + 'F#AD'
|
||||
banana = 'Gros Michel' # comment 2
|
||||
```
|
||||
|
||||
```ruby
|
||||
apple = 1 # comment not aligned
|
||||
apricot = 'DAD' + 'F#AD'
|
||||
banana = 'Gros Michel' # comment 2
|
||||
```
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
4Gvipjyvip:EasyAlign:
|
||||
4Gvipjyvip:EasyAlign:
|
||||
|
||||
Reference in New Issue
Block a user