mirror of
https://github.com/junegunn/vim-easy-align.git
synced 2025-11-11 03:13: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.
584 lines
20 KiB
Plaintext
584 lines
20 KiB
Plaintext
*easy_align.txt* A simple, easy-to-use Vim alignment plugin
|
|
|
|
vim-easy-align *vim-easy-align* *easy-align*
|
|
=========================================================================
|
|
|
|
A simple, easy-to-use Vim alignment plugin.
|
|
|
|
Author: Junegunn Choi
|
|
Source: https://github.com/junegunn/vim-easy-align
|
|
License: MIT
|
|
|
|
|
|
EasyAlign *:EasyAlign* *:EasyAlign!*
|
|
-------------------------------------------------------------------------
|
|
|
|
vim-easy-align defines `:EasyAlign` command in the visual mode.
|
|
(:EasyAlign! is the right-align version.)
|
|
|
|
| Mode | Command |
|
|
| ------------------------- | -------------------------------------------- |
|
|
| Interactive mode | :EasyAlign[!] [OPTIONS] |
|
|
| Using predefined rules | :EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS] |
|
|
| Using regular expressions | :EasyAlign[!] [N-th] /REGEXP/ [OPTIONS] |
|
|
|
|
|
|
Interactive mode
|
|
-------------------------------------------------------------------------
|
|
|
|
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<Enter>
|
|
|
|
With this mapping, you can align selected lines of text with a few keystrokes.
|
|
|
|
1. <Enter> key to start interactive EasyAlign command
|
|
2. Optional: Enter keys to select alignment mode (left, right, or center)
|
|
3. Optional: N-th delimiter (default: 1)
|
|
1 Around the 1st occurrences of delimiters
|
|
2 Around the 2nd occurrences of delimiters
|
|
* Around all occurrences of delimiters
|
|
** Left-right alternating alignment around all delimiters
|
|
- Around the last occurrences of delimiters (-1)
|
|
-2 Around the second to last occurrences of delimiters
|
|
...
|
|
4. Delimiter key for the predefined rules (a single keystroke)
|
|
<space> General alignment around whitespaces
|
|
= Operators containing equals sign (=, ==, !=, +=, &&=, ...)
|
|
: Suitable for formatting JSON or YAML
|
|
. Multi-line method chaining
|
|
, Multi-line method arguments. CSV.
|
|
& LaTeX tables (matches & and \\)
|
|
| Table markdown
|
|
|
|
(You can override these default rules or define your own rules with
|
|
`g:easy_align_delimiters`, which will be described in the later section.)
|
|
|
|
During the key sequence, <Enter> key will toggle right-align mode.
|
|
|
|
Examples:
|
|
|
|
<Enter><space> Alignment around 1st whitespaces
|
|
<Enter>2<space> Alignment around 2nd whitespaces
|
|
<Enter>-<space> Alignment around the last whitespaces
|
|
<Enter>: Alignment around 1st colon
|
|
<Enter>= Alignment around 1st equals signs (and the likes)
|
|
<Enter>2= Alignment around 2nd equals signs (and the likes)
|
|
<Enter>3= Alignment around 3rd equals signs (and the likes)
|
|
<Enter>*= Alignment around all equals signs (and the likes)
|
|
<Enter>**= Left-right alternating alignment around all equals signs
|
|
<Enter><Enter>= Right-alignment around 1st equals signs
|
|
<Enter><Enter>**= Right-left alternating alignment around all equals signs
|
|
|
|
|
|
Instead of finishing the command with a predefined delimiter key, you can type
|
|
in a regular expression after `<CTRL-/>` or `<CTRL-X>` key.
|
|
For example, if you want to align text around all occurrences of numbers:
|
|
|
|
- <Enter>
|
|
- *
|
|
- <CTRL-/> (or <CTRL-X> on Gvim)
|
|
- [0-9]\+
|
|
|
|
|
|
While in interactive mode, you can adjust some of the alignment options using
|
|
special shortcut keys listed below. The meanings of the options will be
|
|
described in the following sections.
|
|
|
|
| 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] |
|
|
| 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>
|
|
|
|
|
|
Live interactive mode *:LiveEasyAlign* *:LiveEasyAlign!*
|
|
-------------------------------------------------------------------------
|
|
|
|
If you're performing a complex alignment where multiple options should be
|
|
carefully adjusted, try "live interactive mode" which aligns the text
|
|
on-the-fly as you type in.
|
|
|
|
Live interactive mode can be started with `:LiveEasyAlign` command which
|
|
takes the same parameters as `:EasyAlign`. I suggest you define the
|
|
following mapping in addition to the one for `:EasyAlign` command.
|
|
|
|
vnoremap <silent> <Leader><Enter> :LiveEasyAlign<Enter>
|
|
|
|
In live interactive mode, you have to type in the same delimiter (or
|
|
`CTRL-X` on regular expression) again to finalize the alignment. This
|
|
allows you to preview the result of the alignment and freely change the
|
|
delimiter using backspace key without leaving the 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
|
|
`:EasyAlign` command.
|
|
|
|
" Using predefined alignment rules
|
|
:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
|
|
|
|
" Using arbitrary regular expressions
|
|
:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
|
|
|
|
For example, when aligning the following lines around colons and semi-colons,
|
|
|
|
apple;:banana::cake
|
|
data;;exchange:;format
|
|
|
|
try these commands:
|
|
|
|
:EasyAlign /[:;]\+/
|
|
:EasyAlign 2/[:;]\+/
|
|
:EasyAlign */[:;]\+/
|
|
:EasyAlign **/[:;]\+/
|
|
|
|
You can also provide a number of alignment options, which will be discussed in
|
|
detail later, to EasyAlign command in Vim dictionary format.
|
|
|
|
:EasyAlign * /[:;]\+/ { 'stick_to_left': 1, 'left_margin': 0 }
|
|
|
|
Which means that the matched delimiter should be positioned right next to the
|
|
preceding token, without margin on the left. So we get:
|
|
|
|
apple;: banana:: cake
|
|
data;; exchange:; format
|
|
|
|
Option names are fuzzy-matched, so you can write as follows:
|
|
|
|
:EasyAlign * /[:;]\+/ { 'stl': 1, 'l': '' }
|
|
|
|
You can even omit spaces between the arguments, so concisely (or cryptically):
|
|
|
|
:EasyAlign*/[:;]\+/{'s':1,'l':''}
|
|
|
|
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 |
|
|
| -------------- | ---------- |
|
|
| filter | [gv]/.*/ |
|
|
| 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
|
|
-------------------------------------------------------------------------
|
|
|
|
In blockwise-visual mode (CTRL-V), EasyAlign command aligns only
|
|
the selected text in the block, instead of the whole lines in the range.
|
|
|
|
|
|
Alignment options
|
|
-------------------------------------------------------------------------
|
|
|
|
Available options are as follows.
|
|
|
|
| Atrribute | Type | Default |
|
|
| ---------------- | ---------------- | ----------------------------- |
|
|
| filter | string | |
|
|
| left_margin | number or string | 1 |
|
|
| right_margin | number or string | 1 |
|
|
| 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 N-th param and |
|
|
| | | selected alignment mode) |
|
|
|
|
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 arguments to :EasyAlign command
|
|
4. Option values can be set in interactive mode using special shortcut keys
|
|
|
|
| Option | Shortcut key | Abbreviated | Global variable |
|
|
| ---------------- | --------------- | ----------- | ----------------------------- |
|
|
| filter | CTRL-F | [gv]/.*/ | |
|
|
| 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*]+ | |
|
|
|
|
|
|
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*
|
|
-------------------------------------------------------------------------
|
|
|
|
EasyAlign can be configured to ignore delimiters in certain syntax
|
|
highlight groups, such as code comments or strings. By default, delimiters
|
|
that are highlighted as code comments or strings are ignored.
|
|
|
|
" Default:
|
|
" If a delimiter is in a highlight group whose name matches
|
|
" any of the followings, it will be ignored.
|
|
let g:easy_align_ignore_groups = ['Comment', 'String']
|
|
|
|
For example, the following paragraph
|
|
|
|
{
|
|
# Quantity of apples: 1
|
|
apple: 1,
|
|
# Quantity of bananas: 2
|
|
bananas: 2,
|
|
# Quantity of grape:fruits: 3
|
|
'grape:fruits': 3
|
|
}
|
|
|
|
becomes as follows on '<Enter>:' (or `:EasyAlign:`)
|
|
|
|
{
|
|
# Quantity of apples: 1
|
|
apple: 1,
|
|
# Quantity of bananas: 2
|
|
bananas: 2,
|
|
# Quantity of grape:fruits: 3
|
|
'grape:fruits': 3
|
|
}
|
|
|
|
Naturally, this feature only works when syntax highlighting is enabled.
|
|
|
|
You can change the default rule by using one of these 4 methods.
|
|
|
|
1. Press CTRL-G in interactive mode to switch groups
|
|
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[]
|
|
|
|
For example if you set 'ignore_groups' option to be an empty list, you get
|
|
|
|
{
|
|
# Quantity of apples: 1
|
|
apple: 1,
|
|
# Quantity of bananas: 2
|
|
bananas: 2,
|
|
# Quantity of grape: fruits: 3
|
|
'grape: fruits': 3
|
|
}
|
|
|
|
|
|
Ignoring unmatched lines *g:easy_align_ignore_unmatched*
|
|
-------------------------------------------------------------------------
|
|
|
|
'ignore_unmatched' option determines how EasyAlign command processes lines that
|
|
do not have N-th delimiter.
|
|
|
|
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 {
|
|
this_line_does_not_have_a_colon
|
|
},
|
|
bananas: 2,
|
|
grapefruits: 3
|
|
}
|
|
|
|
this is usually what we want.
|
|
|
|
{
|
|
apple: proc {
|
|
this_line_does_not_have_a_colon
|
|
},
|
|
bananas: 2,
|
|
grapefruits: 3
|
|
}
|
|
|
|
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:iu0
|
|
|
|
Then we get,
|
|
|
|
{
|
|
apple: proc {
|
|
this_line_does_not_have_a_colon
|
|
},
|
|
bananas: 2,
|
|
grapefruits: 3
|
|
}
|
|
|
|
|
|
Aligning delimiters of different lengths *g:easy_align_delimiter_align*
|
|
-------------------------------------------------------------------------
|
|
|
|
Global `g:easy_align_delimiter_align` option and rule-wise/command-wise
|
|
'delimiter_align' option determines how matched delimiters of different
|
|
lengths are aligned.
|
|
|
|
apple = 1
|
|
banana += apple
|
|
cake ||= banana
|
|
|
|
By default, delimiters are right-aligned as follows.
|
|
|
|
apple = 1
|
|
banana += apple
|
|
cake ||= banana
|
|
|
|
However, with ':EasyAlign=dl', delimiters are left-aligned.
|
|
|
|
apple = 1
|
|
banana += apple
|
|
cake ||= banana
|
|
|
|
And on ':EasyAlign=dc', center-aligned.
|
|
|
|
apple = 1
|
|
banana += apple
|
|
cake ||= banana
|
|
|
|
In interactive mode, you can change the option value with `CTRL-D` key.
|
|
|
|
|
|
Adjusting indentation *g:easy_align_indentation*
|
|
-------------------------------------------------------------------------
|
|
|
|
By default :EasyAlign command keeps the original indentation of the lines.
|
|
But then again we have 'indentation' option. See the following example.
|
|
|
|
# Lines with different indentation
|
|
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=is
|
|
apple = 1
|
|
banana = 2
|
|
cake = 3
|
|
daisy = 4
|
|
eggplant = 5
|
|
|
|
# Use the _d_eepest indentation among the lines
|
|
# :EasyAlign=id
|
|
apple = 1
|
|
banana = 2
|
|
cake = 3
|
|
daisy = 4
|
|
eggplant = 5
|
|
|
|
# Indentation: _n_one
|
|
# :EasyAlign=in
|
|
apple = 1
|
|
banana = 2
|
|
cake = 3
|
|
daisy = 4
|
|
eggplant = 5
|
|
|
|
|
|
Notice that 'idt' is fuzzy-matched to 'indentation'.
|
|
|
|
In interactive mode, you can change the option value with `CTRL-I` key.
|
|
|
|
|
|
Alignments over multiple occurrences of delimiters
|
|
-------------------------------------------------------------------------
|
|
|
|
As stated above, "N-th" parameter is used to target specific occurrences of
|
|
the delimiter when it appears multiple times in each line.
|
|
|
|
To recap:
|
|
|
|
" Left-alignment around the FIRST occurrences of delimiters
|
|
:EasyAlign =
|
|
|
|
" Left-alignment around the SECOND occurrences of delimiters
|
|
:EasyAlign 2=
|
|
|
|
" Left-alignment around the LAST occurrences of delimiters
|
|
:EasyAlign -=
|
|
|
|
" Left-alignment around ALL occurrences of delimiters
|
|
:EasyAlign *=
|
|
|
|
" Left-right ALTERNATING alignment around all occurrences of delimiters
|
|
:EasyAlign **=
|
|
|
|
" Right-left ALTERNATING alignment around all occurrences of delimiters
|
|
:EasyAlign! **=
|
|
|
|
In addition to these, you can fine-tune alignments over multiple occurrences of
|
|
the delimiters with 'mode_sequence' option. (The option can also be set
|
|
in interactive mode with the special key CTRL-O)
|
|
|
|
" Left alignment over the first two occurrences of delimiters
|
|
:EasyAlign = { 'mode_sequence': 'll' }
|
|
|
|
" 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=mrlc
|
|
|
|
" (*) Repeating alignments (default: l, r, or c)
|
|
" Right, left, center, center, center, center, ...
|
|
:EasyAlign *=mrlc
|
|
|
|
" (**) Alternating alignments (default: lr or rl)
|
|
" Right, left, center, right, left, center, ...
|
|
:EasyAlign **=mrlc
|
|
|
|
" Right, left, center, center, center, ... repeating alignment
|
|
" over the 3rd to the last occurrences of delimiters
|
|
:EasyAlign 3=mrlc*
|
|
|
|
" Right, left, center, right, left, center, ... alternating alignment
|
|
" over the 3rd to the last occurrences of delimiters
|
|
:EasyAlign 3=mrlc**
|
|
|
|
|
|
Extending alignment rules *g:easy_align_delimiters*
|
|
-------------------------------------------------------------------------
|
|
|
|
Although the default rules should cover the most of the use cases,
|
|
you can extend the rules by setting a dictionary named
|
|
`g:easy_align_delimiters`.
|
|
|
|
let g:easy_align_delimiters = {
|
|
\ '>': { 'pattern': '>>\|=>\|>' },
|
|
\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignore_groups': ['String'] },
|
|
\ '#': { 'pattern': '#\+', 'ignore_groups': ['String'] },
|
|
\ ']': {
|
|
\ 'pattern': '[[\]]',
|
|
\ 'left_margin': 0,
|
|
\ 'right_margin': 0,
|
|
\ 'stick_to_left': 0
|
|
\ },
|
|
\ ')': {
|
|
\ 'pattern': '[()]',
|
|
\ 'left_margin': 0,
|
|
\ 'right_margin': 0,
|
|
\ 'stick_to_left': 0
|
|
\ }
|
|
\ }
|
|
|
|
|
|
Disabling `foldmethod` during alignment *g:easy_align_bypass_fold*
|
|
-------------------------------------------------------------------------
|
|
|
|
It is reported that `foldmethod` value of expr or syntax can significantly
|
|
slow down the alignment when editing a large, complex file with many
|
|
folds. To alleviate this issue, EasyAlign provides an option to
|
|
temporarily set `foldmethod` to manual during the alignment task.
|
|
In order to enable this feature, set g:easy_align_bypass_fold to 1.
|
|
|
|
let g:easy_align_bypass_fold = 1
|
|
|