11 Commits
2.9.3 ... 2.9.6

Author SHA1 Message Date
Junegunn Choi
ec15731bc9 Update README: Shorthand notation for stick_to_left option 2014-08-14 14:14:22 +09:00
Junegunn Choi
eee4735770 Update shorthand notation for stick_to_left: > to unset
- `<` == `stl1`
- `>` == `stl0`
2014-08-14 12:38:44 +09:00
Junegunn Choi
5e2a588403 Update README 2014-07-23 22:17:40 +09:00
Junegunn Choi
2fa6a040f6 Change option name and shorthand notations
- `mode_sequence` (`ms`) -> `align` (`a`)
- `stick_to_left` (`<` / `s01`)

This commit does not break backward compatibility.
`mode_sequence` is still allowed.
2014-07-23 22:15:01 +09:00
Junegunn Choi
f9a49e441d Preserve last selection when using <Plug>(EasyAlign) 2014-06-27 23:31:22 +09:00
Junegunn Choi
fc9555cd65 Allow negation operator in ignore_groups option
e.g. ig['!String']
2014-06-24 00:09:51 +09:00
Junegunn Choi
a98c1ccc99 Add '#'-rule (#30)
For Ruby/Python comments. This new '#' rule will only match
'#' characters that are highlighted as comments.
2014-06-20 10:36:37 +09:00
Junegunn Choi
0aa6289d8c Update EXAMPLES.md 2014-06-08 00:36:07 +09:00
Junegunn Choi
cc8966c0a5 Update README 2014-05-31 02:59:14 +09:00
Junegunn Choi
da281d78d3 Update document 2014-05-31 00:50:25 +09:00
Junegunn Choi
8e8629c0cd Export-ignore .travis.yml 2014-05-16 11:56:25 +09:00
9 changed files with 463 additions and 387 deletions

1
.gitattributes vendored
View File

@@ -1,3 +1,4 @@
.travis.yml export-ignore
.gitattributes export-ignore
.gitignore export-ignore
doc/tags export-ignore

View File

@@ -3,10 +3,14 @@ vim-easy-align examples
Open this document in your Vim and try it yourself.
This document assumes that you have defined the following mapping.
This document assumes that you have defined the following mappings.
```vim
vnoremap <silent> <Enter> :EasyAlign<cr>
" Start interactive EasyAlign in visual mode (e.g. vip<Enter>)
vmap <Enter> <Plug>(EasyAlign)
" Start interactive EasyAlign for a motion/text object (e.g. <Leader>aip)
nmap <Leader>a <Plug>(EasyAlign)
```
To enable syntax highlighting in the code blocks, define and call the following
@@ -214,6 +218,9 @@ This only works when syntax highlighting is enabled.
Aligning in-line comments
-------------------------
*Note: Since the current version provides '#'-rule as one of the default rules,
you can ignore this section.*
```ruby
apple = 1 # comment not aligned
banana = 'Gros Michel' # comment 2

306
README.md
View File

@@ -37,14 +37,9 @@ and extract in ~/.vim or
[plugin](https://github.com/Shougo/neobundle.vim)
[manager](https://github.com/MarcWeber/vim-addon-manager).
- [Pathogen](https://github.com/tpope/vim-pathogen)
- `git clone https://github.com/junegunn/vim-easy-align.git ~/.vim/bundle/vim-easy-align`
- [Vundle](https://github.com/gmarik/vundle)
1. Add `Bundle 'junegunn/vim-easy-align'` to .vimrc
2. Run `:BundleInstall`
- [NeoBundle](https://github.com/Shougo/neobundle.vim)
1. Add `NeoBundle 'junegunn/vim-easy-align'` to .vimrc
2. Run `:NeoBundleInstall`
1. Add `Plugin 'junegunn/vim-easy-align'` to .vimrc
2. Run `:PluginInstall`
- [vim-plug](https://github.com/junegunn/vim-plug)
1. Add `Plug 'junegunn/vim-easy-align'` to .vimrc
2. Run `:PlugInstall`
@@ -55,10 +50,10 @@ TL;DR - One-minute guide
Add the following mappings to your .vimrc.
```vim
" Start interactive EasyAlign in visual mode
" Start interactive EasyAlign in visual mode (e.g. vip<Enter>)
vmap <Enter> <Plug>(EasyAlign)
" Start interactive EasyAlign with a Vim movement
" Start interactive EasyAlign for a motion/text object (e.g. <Leader>aip)
nmap <Leader>a <Plug>(EasyAlign)
```
@@ -88,57 +83,62 @@ to repeat in visual mode.
Usage
-----
_vim-easy-align_ defines `:EasyAlign` command (and the right-align
variant `:EasyAlign!`).
| Mode | Command |
| ------------------------- | ------------------------------------------------ |
| Interactive mode | `:EasyAlign[!] [OPTIONS]` |
| Using predefined rules | `:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]` |
| Using regular expressions | `:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]` |
| Live interactive mode | `:LiveEasyAlign[!] [...]` |
### Concept of _alignment rule_
Though easy-align can align lines of text around any delimiter, it provides
shortcuts for the most common use cases with the concept of "_alignment rule_".
An *alignment rule* is a predefined set of options for common alignment tasks,
which is identified by a single character, *DELIMITER KEY*, such as `<Space>`,
`=`, `:`, `.`, `|`, `&`, and `,`.
`=`, `:`, `.`, `|`, `&`, `#`, and `,`.
Think of it as a shortcut. Instead of writing regular expression and setting
several options, you can just type in a single character.
### Execution models
There are two ways to use easy-align.
#### 1. Using `<Plug>` mappings
The recommended method is to use `<Plug>` mappings as described earlier.
| Mapping | Mode | Description |
| ----------------------- | ------ | ---------------------------------------------------- |
| `<Plug>(EasyAlign)` | normal | Start interactive mode for a motion/text object |
| `<Plug>(EasyAlign)` | visual | Start interactive mode for the selection |
| `<Plug>(LiveEasyAlign)` | normal | Start live-interactive mode for a motion/text object |
| `<Plug>(LiveEasyAlign)` | visual | Start live-interactive mode for the selection |
#### 2. Using `:EasyAlign` command
If you prefer command-line or do not want to start interactive mode, you can use
`:EasyAlign` command instead.
| Mode | Command |
| ------------------------------------------ | ------------------------------------------------ |
| Interactive mode | `:EasyAlign[!] [OPTIONS]` |
| Live interactive mode | `:LiveEasyAlign[!] [...]` |
| Non-interactive mode (predefined rules) | `:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]` |
| Non-interactive mode (regular expressions) | `:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]` |
### Interactive mode
The command will go into the interactive mode when no argument is given.
The following sections will assume that you have `<Plug>(EasyAlign)` mappings in
your .vimrc as below:
```vim
:EasyAlign
```
" Start interactive EasyAlign in visual mode (e.g. vip<Enter>)
vmap <Enter> <Plug>(EasyAlign)
However, it is strongly advised that you define mappings for triggering it in
your `.vimrc` as follows. (Of course you can use any key combination as the
trigger.)
```vim
" For visual mode (e.g. vip<Enter>)
vmap <Enter> <Plug>(EasyAlign)
" For normal mode, with Vim movement (e.g. <Leader>aip)
" Start interactive EasyAlign for a motion/text object (e.g. <Leader>aip)
nmap <Leader>a <Plug>(EasyAlign)
```
The advantages of using the above mappings are two-fold:
With these mappings, you can align text with only a few keystrokes.
- They require less keystrokes
- They make alignments repeatable with
[repeat.vim](https://github.com/tpope/vim-repeat) and
[visualrepeat](https://github.com/vim-scripts/visualrepeat)
With the mapping, you can align selected lines of text with only a few keystrokes.
1. `<Enter>` key in visual mode, or `<Leader>a` followed by a Vim movement to
start interactive EasyAlign command
1. `<Enter>` key in visual mode, or `<Leader>a` followed by a motion or a text
object to start interactive mode
1. Optional: Enter keys to select alignment mode (left, right, or center)
1. Optional: N-th delimiter (default: 1)
- `1` Around the 1st occurrences of delimiters
@@ -149,9 +149,9 @@ With the mapping, you can align selected lines of text with only a few keystroke
- `-` Around the last occurrences of delimiters (`-1`)
- `-2` Around the second to last occurrences of delimiters
- ...
1. Delimiter key (a single keystroke; `<Space>`, `=`, `:`, `.`, `|`, `&`, `,`)
1. Delimiter key (a single keystroke; `<Space>`, `=`, `:`, `.`, `|`, `&`, `#`, `,`)
Alignment rules for the following delimiters have been defined to meet the most needs.
#### Predefined alignment rules
| Delimiter key | Description/Use cases |
| ------------- | -------------------------------------------------------------------- |
@@ -161,29 +161,29 @@ Alignment rules for the following delimiters have been defined to meet the most
| `.` | Multi-line method chaining |
| `,` | Multi-line method arguments |
| `&` | LaTeX tables (matches `&` and `\\`) |
| `#` | Ruby/Python comments |
| `<Bar>` | 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](https://github.com/junegunn/vim-easy-align#extending-alignment-rules).
#### Example command sequences
#### Examples
| With visual map | Description | Equivalent command |
| ------------------- | ---------------------------------- | ---------------------- |
| `<Enter><Space>` | Around 1st whitespaces | `:'<,'>EasyAlign\ ` |
| `<Enter>2<Space>` | Around 2nd whitespaces | `:'<,'>EasyAlign2\ ` |
| `<Enter>-<Space>` | Around the last whitespaces | `:'<,'>EasyAlign-\ ` |
| `<Enter>-2<Space>` | Around the 2nd to last whitespaces | `:'<,'>EasyAlign-2\ ` |
| `<Enter>:` | Around 1st colon (`key: value`) | `:'<,'>EasyAlign:` |
| `<Enter><Right>:` | Around 1st colon (`key : value`) | `:'<,'>EasyAlign:s0l1` |
| `<Enter>=` | Around 1st operators with = | `:'<,'>EasyAlign=` |
| `<Enter>2=` | Around 2nd operators with = | `:'<,'>EasyAlign2=` |
| `<Enter>3=` | Around 3rd operators with = | `:'<,'>EasyAlign3=` |
| `<Enter>*=` | Around all operators with = | `:'<,'>EasyAlign*=` |
| `<Enter>**=` | Left-right alternating around = | `:'<,'>EasyAlign**=` |
| `<Enter><Enter>=` | Right alignment around 1st = | `:'<,'>EasyAlign!=` |
| `<Enter><Enter>**=` | Right-left alternating around = | `:'<,'>EasyAlign!**=` |
| With visual map | Description | Equivalent command |
| ------------------- | ---------------------------------- | --------------------- |
| `<Enter><Space>` | Around 1st whitespaces | `:'<,'>EasyAlign\ ` |
| `<Enter>2<Space>` | Around 2nd whitespaces | `:'<,'>EasyAlign2\ ` |
| `<Enter>-<Space>` | Around the last whitespaces | `:'<,'>EasyAlign-\ ` |
| `<Enter>-2<Space>` | Around the 2nd to last whitespaces | `:'<,'>EasyAlign-2\ ` |
| `<Enter>:` | Around 1st colon (`key: value`) | `:'<,'>EasyAlign:` |
| `<Enter><Right>:` | Around 1st colon (`key : value`) | `:'<,'>EasyAlign:<l1` |
| `<Enter>=` | Around 1st operators with = | `:'<,'>EasyAlign=` |
| `<Enter>3=` | Around 3rd operators with = | `:'<,'>EasyAlign3=` |
| `<Enter>*=` | Around all operators with = | `:'<,'>EasyAlign*=` |
| `<Enter>**=` | Left-right alternating around = | `:'<,'>EasyAlign**=` |
| `<Enter><Enter>=` | Right alignment around 1st = | `:'<,'>EasyAlign!=` |
| `<Enter><Enter>**=` | Right-left alternating around = | `:'<,'>EasyAlign!**=` |
#### Using regular expressions
@@ -193,7 +193,7 @@ For example, if you want to align text around all occurrences of numbers:
- `<Enter>`
- `*`
- `<CTRL-/>` (or `<CTRL-X>` on GVim)
- `<CTRL-X>`
- `[0-9]\+`
#### Alignment options in interactive mode
@@ -211,85 +211,55 @@ keys listed below. The meaning of each option will be described in
| `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 (`/[lrc]+\*{0,2}/`) |
| `CTRL-A` | `align` | Input string (`/[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>
```
### EasyAlign as Vim operator
With normal-mode map to `<Plug>(EasyAlign)`, EasyAlign command becomes a Vim
operator that can be used with any Vim movement.
```vim
nmap <Leader>a <Plug>(EasyAlign)
```
Now without going into visual mode, you can align the lines in the paragraph
with `<Leader>aip=`, `<Leader>aip*|`, or `<Leader>aip:`. And if you have
installed [repeat.vim](https://github.com/tpope/vim-repeat) by Tim Pope, the
exact alignment can be repeated with `.` key.
### Live interactive mode
If you're performing a complex alignment where multiple options should be
carefully adjusted, try "live interactive mode" where you can preview the result
of the alignment 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 mappings such as
follows in addition to the ones for `:EasyAlign` command.
```vim
vmap <Leader><Enter> <Plug>(LiveEasyAlign)
nmap <Leader><Leader>a <Plug>(LiveEasyAlign)
```
Live interactive mode can be started with either `<Plug>(LiveEasyAlign)` or
`:LiveEasyAlign` command.
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.
### Using `EasyAlign` in command line
### Non-interactive mode
Instead of going into the interactive mode, you can just type in arguments to
Instead of starting interactive mode, you can use declarative, non-interactive
`:EasyAlign` command.
```vim
" Using predefined alignment rules
:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
" :EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
:EasyAlign :
:EasyAlign =
:EasyAlign *=
:EasyAlign 3\
" Using arbitrary regular expressions
:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
" :EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
:EasyAlign /[:;]\+/
:EasyAlign 2/[:;]\+/
:EasyAlign */[:;]\+/
:EasyAlign **/[:;]\+/
```
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
A command can end with alignment options, [each of which will be discussed in
detail later](https://github.com/junegunn/vim-easy-align#alignment-options),
to EasyAlign command in Vim dictionary format.
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:
`stick_to_left` of 1 means that the matched delimiter should be positioned right
next to the preceding token, and `left_margin` of 0 removes the margin on the
left. So we get:
apple;: banana:: cake
data;; exchange:; format
@@ -305,29 +275,29 @@ You can even omit spaces between the arguments, so concisely (or cryptically):
Nice. But let's make it even shorter. Option values can be written in shorthand
notation.
- `:EasyAlign*/[:;]\+/s1l0`
- `:EasyAlign*/[:;]\+/<l0`
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]` |
| Option | Expression |
| ------------------ | -------------- |
| `filter` | `[gv]/.*/` |
| `left_margin` | `l[0-9]+` |
| `right_margin` | `r[0-9]+` |
| `stick_to_left` | `<` or `>` |
| `ignore_unmatched` | `iu[01]` |
| `ignore_groups` | `ig\[.*\]` |
| `align` | `a[lrc*]*` |
| `delimiter_align` | `d[lrc]` |
| `indentation` | `i[ksdn]` |
For your information, the same thing can be done in the interactive mode as well
with the following key combination.
For your information, the same operation can be done in interactive mode as
follows:
- `<Enter>`
- `*`
- `<Left>`
- `<CTRL-/>` (or `<CTRL-X>` on GVim)
- `<CTRL-X>`
- `[:;]\+`
### Partial alignment in blockwise-visual mode
@@ -375,7 +345,7 @@ Alignment options
| `ignore_unmatched` | boolean | 1 | Whether to ignore lines without matching delimiter |
| `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 |
| `mode_sequence` | string | | Alignment modes for multiple occurrences of delimiters |
| `align` | string | `l` | Alignment modes for multiple occurrences of delimiters |
There are 4 ways to set alignment options (from lowest precedence to highest):
@@ -384,24 +354,24 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
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 name | 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*]*` | |
| Option name | 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>` | `<` or `>` | |
| `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` |
| `align` | `CTRL-A` | `a[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/`
1. Press `CTRL-F` in interactive mode and type in `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/`
@@ -482,7 +452,9 @@ For example if you set `ignore_groups` option to be an empty list, you get
}
```
Satisfied? :satisfied:
If a pattern in `ignore_groups` is prepended by a `!`, it will have the opposite
meaning. For instance, if `ignore_groups` is given as `['!Comment']`, delimiters
that are *not* highlighted as Comment will be ignored during the alignment.
### Ignoring unmatched lines
@@ -654,38 +626,38 @@ To recap:
: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`)
In addition to these, you can fine-tune alignments over multiple occurrences
of the delimiters with 'align' option. (The option can also be set in
interactive mode with the special key `CTRL-A`)
```vim
" Left alignment over the first two occurrences of delimiters
:EasyAlign = { 'mode_sequence': 'll' }
:EasyAlign = { 'align': 'll' }
" Right, left, center alignment over the 1st to 3rd occurrences of delimiters
:EasyAlign = { 'm': 'rlc' }
:EasyAlign = { 'a': 'rlc' }
" Using shorthand notation
:EasyAlign = mrlc
:EasyAlign = arlc
" Right, left, center alignment over the 2nd to 4th occurrences of delimiters
:EasyAlign 2=mrlc
:EasyAlign 2=arlc
" (*) Repeating alignments (default: l, r, or c)
" Right, left, center, center, center, center, ...
:EasyAlign *=mrlc
:EasyAlign *=arlc
" (**) Alternating alignments (default: lr or rl)
" Right, left, center, right, left, center, ...
:EasyAlign **=mrlc
:EasyAlign **=arlc
" Right, left, center, center, center, ... repeating alignment
" over the 3rd to the last occurrences of delimiters
:EasyAlign 3=mrlc*
:EasyAlign 3=arlc*
" Right, left, center, right, left, center, ... alternating alignment
" over the 3rd to the last occurrences of delimiters
:EasyAlign 3=mrlc**
:EasyAlign 3=arlc**
```
### Extending alignment rules
@@ -701,8 +673,10 @@ You may refer to the definitions of the default alignment rules
```vim
let g:easy_align_delimiters = {
\ '>': { 'pattern': '>>\|=>\|>' },
\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignore_groups': ['String'] },
\ '#': { 'pattern': '#\+', 'ignore_groups': ['String'], 'delimiter_align': 'l' },
\ '/': {
\ 'pattern': '//\+\|/\*\|\*/',
\ 'delimiter_align': 'l',
\ 'ignore_groups': ['!Comment'] },
\ ']': {
\ 'pattern': '[[\]]',
\ 'left_margin': 0,
@@ -716,8 +690,8 @@ let g:easy_align_delimiters = {
\ 'stick_to_left': 0
\ },
\ 'd': {
\ 'pattern': ' \(\S\+\s*[;=]\)\@=',
\ 'left_margin': 0,
\ 'pattern': ' \(\S\+\s*[;=]\)\@=',
\ 'left_margin': 0,
\ 'right_margin': 0
\ }
\ }
@@ -769,7 +743,7 @@ for more examples.
Related work
------------
There are two well-known plugins with the same goal as that of vim-easy-align.
There are two well-known plugins with the same goal as that of easy-align.
- [DrChip's Alignment Tool for Vim](http://www.drchip.org/astronaut/vim/align.html) (herein will be referred to as "Align")
- [Tabular](https://github.com/godlygeek/tabular)
@@ -777,15 +751,15 @@ There are two well-known plugins with the same goal as that of vim-easy-align.
Both are great plugins with very large user bases. I actually had been a Tabular
user for a couple of years before I finally made up my mind to roll out my own.
So why would someone choose vim-easy-align over those two?
So why would someone choose easy-align over those two?
Feature-by-feature comparison I believe is not quite useful, since a typical
user will end up using only a small subset of the features.
So I will mention just a few core benefits of vim-easy-align.
So I will mention just a few core benefits of easy-align.
### Ease of use
As the name implies, vim-easy-align is *easier* to use. Its interactive mode
As the name implies, easy-align is *easier* to use. Its interactive mode
allows you to achieve what you want with just a few keystrokes.
The key sequence is mnemonic, so it's easy to remember and execute.
It even feels like a native Vim command!
@@ -803,17 +777,17 @@ without affecting the ones before it?"_
### Clean
vim-easy-align doesn't clutter your workspace with mappings and global
easy-align doesn't clutter your workspace with mappings and global
variables. All you would need is a single mapping to the interactive EasyAlign
command, and even that is totally up to you.
### Optimized for code editing
vim-easy-align by default performs syntax-aware alignment, which is invaluable
easy-align by default performs syntax-aware alignment, which is invaluable
when editing codes.
Try to come up with a regular expression to correctly format the following code
snippet. With vim-easy-align under default configuration and a mapping, it can
snippet. With easy-align under default configuration and a mapping, it can
be done with just two keystrokes: `<Enter>:`
```javascript
@@ -833,13 +807,13 @@ looks up the syntax group of a character on a certain position)
### Thoroughly tested
Virtually every aspect of vim-easy-align is being tested with a comprehensive
Virtually every aspect of easy-align is being tested with a comprehensive
set of test cases using [Vader.vim](https://github.com/junegunn/vader.vim).
### "Okay. So should I switch?"
Maybe, but I can't really say. I have no ambition to make vim-easy-align
an absolute superior to the others. For some cases, vim-easy-align works better
Maybe, but I can't really say. I have no ambition to make easy-align
an absolute superior to the others. For some cases, easy-align works better
than the others, but for some other cases, Tabular or Align.vim might be a
better choice.

View File

@@ -37,6 +37,7 @@ let s:easy_align_delimiters_default = {
\ ',': { 'pattern': ',', 'left_margin': 0, 'right_margin': 1, 'stick_to_left': 1 },
\ '|': { 'pattern': '|', 'left_margin': 1, 'right_margin': 1, 'stick_to_left': 0 },
\ '.': { 'pattern': '\.', 'left_margin': 0, 'right_margin': 0, 'stick_to_left': 0 },
\ '#': { 'pattern': '#\+', 'delimiter_align': 'l', 'ignore_groups': ['!Comment'] },
\ '&': { 'pattern': '\\\@<!&\|\\\\',
\ 'left_margin': 1, 'right_margin': 1, 'stick_to_left': 0 },
\ '{': { 'pattern': '(\@<!{',
@@ -50,7 +51,8 @@ let s:known_options = {
\ 'margin_left': [0, 1], 'margin_right': [0, 1], 'stick_to_left': [0],
\ 'left_margin': [0, 1], 'right_margin': [0, 1], 'indentation': [1],
\ 'ignore_groups': [3 ], 'ignore_unmatched': [0 ], 'delimiter_align': [1],
\ 'mode_sequence': [1 ], 'ignores': [3], 'filter': [1]
\ 'mode_sequence': [1 ], 'ignores': [3], 'filter': [1],
\ 'align': [1 ]
\ }
let s:option_values = {
@@ -64,7 +66,8 @@ let s:shorthand = {
\ 'margin_left': 'lm', 'margin_right': 'rm', 'stick_to_left': 'stl',
\ 'left_margin': 'lm', 'right_margin': 'rm', 'indentation': 'idt',
\ 'ignore_groups': 'ig', 'ignore_unmatched': 'iu', 'delimiter_align': 'da',
\ 'mode_sequence': 'm', 'ignores': 'ig', 'filter': 'f'
\ 'mode_sequence': 'a', 'ignores': 'ig', 'filter': 'f',
\ 'align': 'a'
\ }
if exists("*strdisplaywidth")
@@ -89,7 +92,11 @@ function! s:highlighted_as(line, col, groups)
if empty(a:groups) | return 0 | endif
let hl = synIDattr(synID(a:line, a:col, 0), 'name')
for grp in a:groups
if hl =~# grp
if grp[0] == '!'
if hl !~# grp[1:-1]
return 1
endif
elseif hl =~# grp
return 1
endif
endfor
@@ -222,8 +229,9 @@ function! s:normalize_options(opts)
let v = a:opts[k]
let k = s:fuzzy_lu(k)
" Backward-compatibility
if k == 'margin_left' | let k = 'left_margin' | endif
if k == 'margin_right' | let k = 'right_margin' | endif
if k == 'margin_left' | let k = 'left_margin' | endif
if k == 'margin_right' | let k = 'right_margin' | endif
if k == 'mode_sequence' | let k = 'align' | endif
let ret[k] = v
unlet v
endfor
@@ -663,7 +671,7 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
endif
elseif c == 13 " Enter key
let mode = s:shift(a:modes, 1)
if has_key(opts, 'm')
if has_key(opts, 'a')
let opts.m = mode . strpart(opts.m, 1)
endif
elseif ch == '-'
@@ -718,15 +726,15 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
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))
elseif ch == "\<C-A>" || ch == "\<C-O>"
let modes = tolower(s:input("Alignment ([lrc...][[*]*]): ", get(opts, 'a', mode), a:vis))
if match(modes, '^[lrc]\+\*\{0,2}$') != -1
let opts['m'] = modes
let opts['a'] = modes
let mode = modes[0]
while mode != s:shift(a:modes, 1)
endwhile
else
silent! call remove(opts, 'm')
silent! call remove(opts, 'a')
endif
elseif ch == "\<C-_>" || ch == "\<C-X>"
if a:live && regx && !empty(d)
@@ -806,8 +814,8 @@ endfunction
let s:shorthand_regex =
\ '\s*\%('
\ .'\(lm\?[0-9]\+\)\|\(rm\?[0-9]\+\)\|\(iu[01]\)\|\(s\%(tl\)\?[01]\)\|'
\ .'\(da\?[clr]\)\|\(ms\?[lrc*]\+\)\|\(i\%(dt\)\?[kdsn]\)\|\([gv]/.*/\)\|\(ig\[.*\]\)'
\ .'\(lm\?[0-9]\+\)\|\(rm\?[0-9]\+\)\|\(iu[01]\)\|\(\%(s\%(tl\)\?[01]\)\|[<>]\)\|'
\ .'\(da\?[clr]\)\|\(\%(ms\?\|a\)[lrc*]\+\)\|\(i\%(dt\)\?[kdsn]\)\|\([gv]/.*/\)\|\(ig\[.*\]\)'
\ .'\)\+\s*$'
function! s:parse_shorthand_opts(expr)
@@ -823,7 +831,7 @@ function! s:parse_shorthand_opts(expr)
let match = matchlist(expr, regex)
if empty(match) | break | endif
for m in filter(match[ 1 : -1 ], '!empty(v:val)')
for key in ['lm', 'rm', 'l', 'r', 'stl', 's', 'iu', 'da', 'd', 'ms', 'm', 'ig', 'i', 'g', 'v']
for key in ['lm', 'rm', 'l', 'r', 'stl', 's', '<', '>', 'iu', 'da', 'd', 'ms', 'm', 'ig', 'i', 'g', 'v', 'a']
if stridx(tolower(m), key) == 0
let rest = strpart(m, len(key))
if key == 'i' | let key = 'idt' | endif
@@ -832,7 +840,7 @@ function! s:parse_shorthand_opts(expr)
let key = 'f'
endif
if key == 'idt' || index(['d', 'f', 'm'], key[0]) >= 0
if key == 'idt' || index(['d', 'f', 'm', 'a'], key[0]) >= 0
let opts[key] = rest
elseif key == 'ig'
try
@@ -845,6 +853,8 @@ function! s:parse_shorthand_opts(expr)
catch
call s:exit("Invalid ignore_groups: ". a:expr)
endtry
elseif key =~ '[<>]'
let opts['stl'] = key == '<'
else
let opts[key] = str2nr(rest)
endif
@@ -1020,7 +1030,7 @@ function! s:process(range, mode, n, ch, opts, regexp, rules, bvis)
let [nth, recur] = s:parse_nth(a:n)
let dict = s:build_dict(a:rules, a:ch, a:regexp, a:opts)
let [mode_sequence, recur] = s:build_mode_sequence(
\ get(dict, 'mode_sequence', recur == 2 ? s:alternating_modes(a:mode) : a:mode),
\ get(dict, 'align', recur == 2 ? s:alternating_modes(a:mode) : a:mode),
\ recur)
if recur && a:bvis
@@ -1045,11 +1055,11 @@ endfunction
function s:summarize(opts, recur, mode_sequence)
let copts = s:compact_options(a:opts)
let nbmode = s:interactive_modes(0)[0]
if !has_key(copts, 'm') && (
if !has_key(copts, 'a') && (
\ (a:recur == 2 && s:alternating_modes(nbmode) != a:mode_sequence) ||
\ (a:recur != 2 && (a:mode_sequence[0] != nbmode || len(a:mode_sequence) > 1))
\ )
call extend(copts, { 'm': a:mode_sequence })
call extend(copts, { 'a': a:mode_sequence })
endif
return copts
endfunction

View File

@@ -1,4 +1,4 @@
easy-align.txt vim-easy-align Last change: December 22 2013
easy-align.txt vim-easy-align Last change: August 14 2014
VIM-EASY-ALIGN - TABLE OF CONTENTS *easyalign* *easy-align* *easy-align-toc*
==============================================================================
@@ -10,13 +10,16 @@ VIM-EASY-ALIGN - TABLE OF CONTENTS *easyalign* *easy-align* *easy-align-
TLDR - One-minute guide |easy-align-4|
Usage |easy-align-5|
Concept of alignment rule |easy-align-5-1|
Interactive mode |easy-align-5-2|
Example command sequences |easy-align-5-2-1|
Using regular expressions |easy-align-5-2-2|
Alignment options in interactive mode |easy-align-5-2-3|
EasyAlign as Vim operator |easy-align-5-3|
Execution models |easy-align-5-2|
1. Using <Plug> mappings |easy-align-5-2-1|
2. Using :EasyAlign command |easy-align-5-2-2|
Interactive mode |easy-align-5-3|
Predefined alignment rules |easy-align-5-3-1|
Examples |easy-align-5-3-2|
Using regular expressions |easy-align-5-3-3|
Alignment options in interactive mode |easy-align-5-3-4|
Live interactive mode |easy-align-5-4|
Using EasyAlign in command line |easy-align-5-5|
Non-interactive mode |easy-align-5-5|
Partial alignment in blockwise-visual mode |easy-align-5-6|
Alignment options |easy-align-6|
List of options |easy-align-6-1|
@@ -97,14 +100,9 @@ Either {download zip file}{2} and extract in ~/.vim or {use}{3} {your}{4}
{6} https://github.com/Shougo/neobundle.vim
{7} https://github.com/MarcWeber/vim-addon-manager
- {Pathogen}{3}
- `git clone https://github.com/junegunn/vim-easy-align.git ~/.vim/bundle/vim-easy-align`
- {Vundle}{4}
- Add `Bundle 'junegunn/vim-easy-align'` to .vimrc
- Run `:BundleInstall`
- {NeoBundle}{6}
- Add `NeoBundle 'junegunn/vim-easy-align'` to .vimrc
- Run `:NeoBundleInstall`
- Add `Plugin 'junegunn/vim-easy-align'` to .vimrc
- Run `:PluginInstall`
- {vim-plug}{5}
- Add `Plug 'junegunn/vim-easy-align'` to .vimrc
- Run `:PlugInstall`
@@ -116,10 +114,10 @@ TLDR - ONE-MINUTE GUIDE *easy-align-tldr-one-minute-guide*
Add the following mappings to your .vimrc.
>
" Start interactive EasyAlign in visual mode
" Start interactive EasyAlign in visual mode (e.g. vip<Enter>)
vmap <Enter> <Plug>(EasyAlign)
" Start interactive EasyAlign with a Vim movement
" Start interactive EasyAlign for a motion/text object (e.g. <Leader>aip)
nmap <Leader>a <Plug>(EasyAlign)
<
And with the following lines of text,
@@ -140,74 +138,89 @@ try these commands:
Notice that the commands are repeatable with `.` key if you have installed
{repeat.vim}{8}. Install {visualrepeat}{9} as well if you want to repeat in
visual mode. Or you can add the following mapping to your .vimrc.
visual mode.
{8} https://github.com/tpope/vim-repeat
{9} https://github.com/vim-scripts/visualrepeat
*<Plug>(EasyAlignRepeat)*
>
" Repeat alignment in visual mode with . key
vmap . <Plug>(EasyAlignRepeat)
<
*easy-align-5*
USAGE *easy-align-usage*
==============================================================================
*:EasyAlign* *:EasyAlign!*
vim-easy-align defines `:EasyAlign` command (and the right-align variant
`:EasyAlign!`).
Mode | Command~
------------------------- | ------------------------------------------------
Interactive mode | `:EasyAlign[!] [OPTIONS]`
Using predefined rules | `:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]`
Using regular expressions | `:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]`
Live interactive mode | `:LiveEasyAlign[!] [...]`
< Concept of alignment rule >_________________________________________________~
*easy-align-concept-of-alignment-rule*
*easy-align-5-1*
Though easy-align can align lines of text around any delimiter, it provides
shortcuts for the most common use cases with the concept of "alignment rule".
An alignment rule is a predefined set of options for common alignment tasks,
which is identified by a single character, DELIMITER KEY, such as <Space> ,
`=`, `:`, `.`, `|`, `&`, and `,`.
`=`, `:`, `.`, `|`, `&`, `#`, and `,`.
Think of it as a shortcut. Instead of writing regular expression and setting
several options, you can just type in a single character.
< Interactive mode >__________________________________________________________~
*easy-align-interactive-mode*
< Execution models >__________________________________________________________~
*easy-align-execution-models*
*easy-align-5-2*
The command will go into the interactive mode when no argument is given.
>
:EasyAlign
<
However, it is strongly advised that you define mappings for triggering it in
your `.vimrc` as follows. (Of course you can use any key combination as the
trigger.)
>
" For visual mode (e.g. vip<Enter>)
vmap <Enter> <Plug>(EasyAlign)
There are two ways to use easy-align.
" For normal mode, with Vim movement (e.g. <Leader>aip)
1. Using <Plug> mappings~
*easy-align-1-using-plug-mappings*
*easy-align-5-2-1*
The recommended method is to use <Plug> mappings as described earlier.
*<Plug>(EasyAlign)* *<Plug>(LiveEasyAlign)*
Mapping | Mode | Description~
----------------------- | ------ | ----------------------------------------------------
<Plug>(EasyAlign) | normal | Start interactive mode for a motion/text object
<Plug>(EasyAlign) | visual | Start interactive mode for the selection
<Plug>(LiveEasyAlign) | normal | Start live-interactive mode for a motion/text object
<Plug>(LiveEasyAlign) | visual | Start live-interactive mode for the selection
2. Using :EasyAlign command~
*easy-align-2-using-easyalign-command*
*easy-align-5-2-2*
*:EasyAlign*
If you prefer command-line or do not want to start interactive mode, you can
use `:EasyAlign` command instead.
Mode | Command~
------------------------------------------ | ------------------------------------------------
Interactive mode | `:EasyAlign[!] [OPTIONS]`
Live interactive mode | `:LiveEasyAlign[!] [...]`
Non-interactive mode (predefined rules) | `:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]`
Non-interactive mode (regular expressions) | `:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]`
< Interactive mode >__________________________________________________________~
*easy-align-interactive-mode*
*easy-align-5-3*
The following sections will assume that you have <Plug>(EasyAlign) mappings in
your .vimrc as below:
>
" Start interactive EasyAlign in visual mode (e.g. vip<Enter>)
vmap <Enter> <Plug>(EasyAlign)
" Start interactive EasyAlign for a motion/text object (e.g. <Leader>aip)
nmap <Leader>a <Plug>(EasyAlign)
<
The advantages of using the above mappings are two-fold:
With these mappings, you can align text with only a few keystrokes.
- They require less keystrokes
- They make alignments repeatable with {repeat.vim}{8} and {visualrepeat}{9}
With the mapping, you can align selected lines of text with only a few
keystrokes.
1. <Enter> key in visual mode, or <Leader>a followed by a Vim movement to start
interactive EasyAlign command
1. <Enter> key in visual mode, or <Leader>a followed by a motion or a text object
to start interactive mode
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
@@ -218,10 +231,12 @@ keystrokes.
- `-` Around the last occurrences of delimiters (`-1`)
- `-2` Around the second to last occurrences of delimiters
- ...
4. Delimiter key (a single keystroke; <Space> , `=`, `:`, `.`, `|`, `&`, `,`)
4. Delimiter key (a single keystroke; <Space> , `=`, `:`, `.`, `|`, `&`, `#`, `,`)
Alignment rules for the following delimiters have been defined to meet the most
needs.
Predefined alignment rules~
*easy-align-predefined-alignment-rules*
*easy-align-5-3-1*
Delimiter key | Description/Use cases~
------------- | --------------------------------------------------------------------
@@ -231,6 +246,7 @@ needs.
`.` | Multi-line method chaining
`,` | Multi-line method arguments
`&` | LaTeX tables (matches `&` and `\\` )
`#` | Ruby/Python comments
<Bar> | Table markdown
*g:easy_align_delimiters*
@@ -240,20 +256,19 @@ You can override these default rules or define your own rules with
(|easy-align-extending-alignment-rules|).
Example command sequences~
*easy-align-example-command-sequences*
*easy-align-5-2-1*
Examples~
*easy-align-examples*
*easy-align-5-3-2*
With visual map | Description | Equivalent command~
------------------- | ---------------------------------- | ----------------------
------------------- | ---------------------------------- | ---------------------
<Enter><Space> | Around 1st whitespaces | :'<,'>EasyAlign\
<Enter>2<Space> | Around 2nd whitespaces | :'<,'>EasyAlign2\
<Enter>-<Space> | Around the last whitespaces | :'<,'>EasyAlign-\
<Enter>-2<Space> | Around the 2nd to last whitespaces | :'<,'>EasyAlign-2\
<Enter>: | Around 1st colon (`key: value`) | :'<,'>EasyAlign:
<Enter><Right>: | Around 1st colon (`key : value`) | :'<,'>EasyAlign:s0l1
<Enter><Right>: | Around 1st colon (`key : value`) | :'<,'>EasyAlign:<l1
<Enter>= | Around 1st operators with = | :'<,'>EasyAlign=
<Enter>2= | Around 2nd operators with = | :'<,'>EasyAlign2=
<Enter>3= | Around 3rd operators with = | :'<,'>EasyAlign3=
<Enter>*= | Around all operators with = | :'<,'>EasyAlign*=
<Enter>**= | Left-right alternating around = | :'<,'>EasyAlign**=
@@ -263,7 +278,7 @@ Example command sequences~
Using regular expressions~
*easy-align-using-regular-expressions*
*easy-align-5-2-2*
*easy-align-5-3-3*
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
@@ -271,13 +286,13 @@ align text around all occurrences of numbers:
- <Enter>
- `*`
- CTRL-/ (or CTRL-X on GVim)
- CTRL-X
- `[0-9]\+`
Alignment options in interactive mode~
*easy-align-alignment-options-in-interactive-mode*
*easy-align-5-2-3*
*easy-align-5-3-4*
While in interactive mode, you can set alignment options using special shortcut
keys listed below. The meaning of each option will be described in the
@@ -292,36 +307,11 @@ following sections (|easy-align-alignment-options|).
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 (`/[lrc]+\*{0,2}/` )
CTRL-A | `align` | Input string (`/[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>
<
< EasyAlign as Vim operator >_________________________________________________~
*easy-align-easyalign-as-vim-operator*
*easy-align-5-3*
*<Plug>(EasyAlign)*
With normal-mode map to <Plug>(EasyAlign) , EasyAlign command becomes a Vim
operator that can be used with any Vim movement.
>
nmap <Leader>a <Plug>(EasyAlign)
<
Now without going into visual mode, you can align the lines in the paragraph
with <Leader>aip= , <Leader>aip*| , or <Leader>aip: . And if you have installed
{repeat.vim}{8} by Tim Pope, the exact alignment can be repeated with `.` key.
{8} https://github.com/tpope/vim-repeat
< Live interactive mode >_____________________________________________________~
*easy-align-live-interactive-mode*
@@ -333,54 +323,44 @@ result of the alignment on-the-fly as you type in.
*:LiveEasyAlign*
Live interactive mode can be started with `:LiveEasyAlign` command which takes
the same parameters as `:EasyAlign`. I suggest you define mappings such as
follows in addition to the ones for `:EasyAlign` command.
Live interactive mode can be started with either <Plug>(LiveEasyAlign) or
`:LiveEasyAlign` command.
*<Plug>(LiveEasyAlign)*
>
vmap <Leader><Enter> <Plug>(LiveEasyAlign)
nmap <Leader><Leader>a <Plug>(LiveEasyAlign)
<
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.
< Using EasyAlign in command line >___________________________________________~
*easy-align-using-easyalign-in-command-line*
< Non-interactive mode >______________________________________________________~
*easy-align-non-interactive-mode*
*easy-align-5-5*
Instead of going into the interactive mode, you can just type in arguments to
Instead of starting interactive mode, you can use declarative, non-interactive
`:EasyAlign` command.
>
" Using predefined alignment rules
:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
" :EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
:EasyAlign :
:EasyAlign =
:EasyAlign *=
:EasyAlign 3\
" Using arbitrary regular expressions
:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
" :EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
:EasyAlign /[:;]\+/
:EasyAlign 2/[:;]\+/
:EasyAlign */[:;]\+/
:EasyAlign **/[:;]\+/
<
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 (|easy-align-alignment-options|), to EasyAlign command in Vim
dictionary format.
A command can end with alignment options, each of which will be discussed in
detail later (|easy-align-alignment-options|), 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:
`stick_to_left` of 1 means that the matched delimiter should be positioned
right next to the preceding token, and `left_margin` of 0 removes the margin on
the left. So we get:
>
apple;: banana:: cake
data;; exchange:; format
@@ -396,29 +376,29 @@ You can even omit spaces between the arguments, so concisely (or cryptically):
Nice. But let's make it even shorter. Option values can be written in shorthand
notation.
- `:EasyAlign*/[:;]\+/s1l0`
- `:EasyAlign*/[:;]\+/<l0`
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]`
`stick_to_left` | `<` or `>`
`ignore_unmatched` | `iu[01]`
`ignore_groups` | `ig\[.*\]`
`align` | `a[lrc*]*`
`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.
For your information, the same operation can be done in interactive mode as
follows:
- <Enter>
- `*`
- <Left>
- CTRL-/ (or CTRL-X on GVim)
- CTRL-X
- `[:;]\+`
@@ -469,7 +449,7 @@ ALIGNMENT OPTIONS *easy-align-alignment-options*
`ignore_unmatched` | boolean | 1 | Whether to ignore lines without matching delimiter
`indentation` | string | `k` | Indentation method (keep, deep, shallow, none)
`delimiter_align` | string | `r` | Determines how to align delimiters of different lengths
`mode_sequence` | string | | Alignment modes for multiple occurrences of delimiters
`align` | string | `l` | Alignment modes for multiple occurrences of delimiters
There are 4 ways to set alignment options (from lowest precedence to highest):
@@ -481,17 +461,17 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
*g:easy_align_ignore_groups* *g:easy_align_ignore_unmatched*
*g:easy_align_indentation* *g:easy_align_delimiter_align*
Option name | 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*]*` |
Option name | 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> | `<` or `>` |
`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`
`align` | CTRL-A | `a[lrc*]*` |
< Filtering lines >___________________________________________________________~
@@ -501,7 +481,7 @@ There are 4 ways to set alignment options (from lowest precedence to highest):
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/`
1. Press CTRL-F in interactive mode and type in `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/`
@@ -509,7 +489,7 @@ given pattern. There are several ways to set the pattern.
Examples~
*easy-align-examples*
*easy-align-examples-2*
*easy-align-6-2-1*
>
" Start interactive mode with filter option set to g/hello/
@@ -577,7 +557,10 @@ For example if you set `ignore_groups` option to be an empty list, you get
'grape: fruits': 3
}
<
Satisfied?
If a pattern in `ignore_groups` is prepended by a `!`, it will have the
opposite meaning. For instance, if `ignore_groups` is given as `['!Comment']`,
delimiters that are not highlighted as Comment will be ignored during the
alignment.
< Ignoring unmatched lines >__________________________________________________~
@@ -714,8 +697,6 @@ then again we have `indentation` option. See the following example.
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.
@@ -747,36 +728,36 @@ To recap:
: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)
the delimiters with 'align' option. (The option can also be set in interactive
mode with the special key CTRL-A)
>
" Left alignment over the first two occurrences of delimiters
:EasyAlign = { 'mode_sequence': 'll' }
:EasyAlign = { 'align': 'll' }
" Right, left, center alignment over the 1st to 3rd occurrences of delimiters
:EasyAlign = { 'm': 'rlc' }
:EasyAlign = { 'a': 'rlc' }
" Using shorthand notation
:EasyAlign = mrlc
:EasyAlign = arlc
" Right, left, center alignment over the 2nd to 4th occurrences of delimiters
:EasyAlign 2=mrlc
:EasyAlign 2=arlc
" (*) Repeating alignments (default: l, r, or c)
" Right, left, center, center, center, center, ...
:EasyAlign *=mrlc
:EasyAlign *=arlc
" (**) Alternating alignments (default: lr or rl)
" Right, left, center, right, left, center, ...
:EasyAlign **=mrlc
:EasyAlign **=arlc
" Right, left, center, center, center, ... repeating alignment
" over the 3rd to the last occurrences of delimiters
:EasyAlign 3=mrlc*
:EasyAlign 3=arlc*
" Right, left, center, right, left, center, ... alternating alignment
" over the 3rd to the last occurrences of delimiters
:EasyAlign 3=mrlc**
:EasyAlign 3=arlc**
<
< Extending alignment rules >_________________________________________________~
@@ -792,13 +773,15 @@ You may refer to the definitions of the default alignment rules {here}{10}.
Examples~
*easy-align-examples-2*
*easy-align-examples-3*
*easy-align-6-8-1*
>
let g:easy_align_delimiters = {
\ '>': { 'pattern': '>>\|=>\|>' },
\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignore_groups': ['String'] },
\ '#': { 'pattern': '#\+', 'ignore_groups': ['String'], 'delimiter_align': 'l' },
\ '/': {
\ 'pattern': '//\+\|/\*\|\*/',
\ 'delimiter_align': 'l',
\ 'ignore_groups': ['!Comment'] },
\ ']': {
\ 'pattern': '[[\]]',
\ 'left_margin': 0,
@@ -812,8 +795,8 @@ Examples~
\ 'stick_to_left': 0
\ },
\ 'd': {
\ 'pattern': ' \(\S\+\s*[;=]\)\@=',
\ 'left_margin': 0,
\ 'pattern': ' \(\S\+\s*[;=]\)\@=',
\ 'left_margin': 0,
\ 'right_margin': 0
\ }
\ }
@@ -878,7 +861,7 @@ See {EXAMPLES.md}{12} for more examples.
RELATED WORK *easy-align-related-work*
==============================================================================
There are two well-known plugins with the same goal as that of vim-easy-align.
There are two well-known plugins with the same goal as that of easy-align.
- {DrChip's Alignment Tool for Vim}{13} (herein will be referred to as "Align")
- {Tabular}{14}
@@ -887,21 +870,21 @@ Both are great plugins with very large user bases. I actually had been a
Tabular user for a couple of years before I finally made up my mind to roll out
my own.
So why would someone choose vim-easy-align over those two?
So why would someone choose easy-align over those two?
Feature-by-feature comparison I believe is not quite useful, since a typical
user will end up using only a small subset of the features. So I will mention
just a few core benefits of vim-easy-align.
just a few core benefits of easy-align.
< Ease of use >_______________________________________________________________~
*easy-align-ease-of-use*
*easy-align-9-1*
As the name implies, vim-easy-align is easier to use. Its interactive mode
allows you to achieve what you want with just a few keystrokes. The key
sequence is mnemonic, so it's easy to remember and execute. It even feels like
a native Vim command!
As the name implies, easy-align is easier to use. Its interactive mode allows
you to achieve what you want with just a few keystrokes. The key sequence is
mnemonic, so it's easy to remember and execute. It even feels like a native Vim
command!
- Right-align: <Enter><Enter>
- around the second occurrences: `2`
@@ -919,21 +902,21 @@ without affecting the ones before it?"
*easy-align-clean*
*easy-align-9-2*
vim-easy-align doesn't clutter your workspace with mappings and global
variables. All you would need is a single mapping to the interactive EasyAlign
command, and even that is totally up to you.
easy-align doesn't clutter your workspace with mappings and global variables.
All you would need is a single mapping to the interactive EasyAlign command,
and even that is totally up to you.
< Optimized for code editing >________________________________________________~
*easy-align-optimized-for-code-editing*
*easy-align-9-3*
vim-easy-align by default performs syntax-aware alignment, which is invaluable
when editing codes.
easy-align by default performs syntax-aware alignment, which is invaluable when
editing codes.
Try to come up with a regular expression to correctly format the following code
snippet. With vim-easy-align under default configuration and a mapping, it can
be done with just two keystrokes: <Enter>:
snippet. With easy-align under default configuration and a mapping, it can be
done with just two keystrokes: <Enter>:
>
var jdbc = {
// JDBC driver for MySQL database:
@@ -953,8 +936,8 @@ looks up the syntax group of a character on a certain position)
*easy-align-thoroughly-tested*
*easy-align-9-4*
Virtually every aspect of vim-easy-align is being tested with a comprehensive
set of test cases using {Vader.vim}{15}.
Virtually every aspect of easy-align is being tested with a comprehensive set
of test cases using {Vader.vim}{15}.
{15} https://github.com/junegunn/vader.vim
@@ -963,10 +946,10 @@ set of test cases using {Vader.vim}{15}.
*easy-align-okay-so-should-i-switch*
*easy-align-9-5*
Maybe, but I can't really say. I have no ambition to make vim-easy-align an
absolute superior to the others. For some cases, vim-easy-align works better
than the others, but for some other cases, Tabular or Align.vim might be a
better choice.
Maybe, but I can't really say. I have no ambition to make easy-align an
absolute superior to the others. For some cases, easy-align works better than
the others, but for some other cases, Tabular or Align.vim might be a better
choice.
So try it yourself and see if it works for you!

View File

@@ -80,25 +80,20 @@ function! s:generic_easy_align_op(type, vmode, live)
if a:vmode
let vmode = a:type
let [l1, l2] = ["'<", "'>"]
call s:remember_visual(vmode)
else
let tail = "\<C-c>"
if a:type == 'line'
silent execute "normal! '[V']".tail
elseif a:type == 'block'
silent execute "normal! `[\<C-V>`]".tail
else
silent execute "normal! `[v`]".tail
endif
let vmode = ''
let [l1, l2] = [line("'["), line("']")]
unlet! s:last_visual
endif
try
let range = l1.','.l2
if get(g:, 'easy_align_need_repeat', 0)
execute "'<,'>". g:easy_align_last_command
execute range . g:easy_align_last_command
else
'<,'>call easy_align#align('<bang>' == '!', a:live, vmode, '')
execute range . "call easy_align#align('<bang>' == '!', a:live, vmode, '')"
end
call s:set_repeat()
finally

View File

@@ -40,14 +40,21 @@ Expect:
apple;:;;banana :: cake
data ;; exchange:;::format
Execute (shorthand notation of mode_sequence and margin):
Execute (DEPRECATED: shorthand notation of mode_sequence and margin):
%EasyAlign/[:;]\+/mrc*l2r2
Expect:
apple ;:;; banana :: cake
data ;; exchange :;:: format
Execute (deep indentation):
Execute (shorthand notation of align and margin):
%EasyAlign/[:;]\+/arc*l2r2
Expect:
apple ;:;; banana :: cake
data ;; exchange :;:: format
Execute (DEPRECATED: deep indentation):
%EasyAlign/[:;]\+/mrc*l2r2
%EasyAlign*/[:;]\+/idmrl*
@@ -55,6 +62,14 @@ Expect:
apple ;:;; banana :: cake
data ;; exchange :;:: format
Execute (deep indentation):
%EasyAlign/[:;]\+/arc*l2r2
%EasyAlign*/[:;]\+/idarl*
Expect:
apple ;:;; banana :: cake
data ;; exchange :;:: format
Execute (stick_to_left):
%EasyAlign*/[:;]\+/stl1l0dlrm3
@@ -62,6 +77,20 @@ Expect:
apple;:;; banana:: cake
data;; exchange:;:: format
Execute (<):
%EasyAlign*/[:;]\+/<l0dlrm3
Expect:
apple;:;; banana:: cake
data;; exchange:;:: format
Execute (>):
%EasyAlign*/[:;]\+/l0dl<>rm3
Expect:
apple;:;; banana :: cake
data ;; exchange:;:: format
Execute (different regular expression):
%EasyAlign*/../{'lm':'<','rm':'>'}

View File

@@ -139,4 +139,26 @@ Expect:
## n2gv = {}
# n2vt = {}
Given (Some text):
a,b,c
d,e,f
Do (Select 1st line, align 3rd line):
- First line
V\<esc>
- Last line
G
- Align
\<space>Aip*,
- Previous selection
gv
- Upcase
U
Expect:
A,B,C
d, e, f
Include: include/teardown.vader

View File

@@ -758,7 +758,7 @@ Expect ruby:
dddddd /= 123
gg <=> ee
Do (Alignment using mode_sequence, delimiter_align):
Do (DEPRECATED: Alignment using mode_sequence, delimiter_align):
vip\<Enter>\<C-O>\<Backspace>cr*\<Enter>\<C-D>=
Expect ruby:
@@ -787,7 +787,37 @@ Expect ruby:
dddddd /= 123
gg <=> ee
Do (mode_sequence starting from 2nd, delimiter_align = center):
Do (Alignment using align, delimiter_align):
vip\<Enter>\<C-A>\<Backspace>cr*\<Enter>\<C-D>=
Expect 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
Do (DEPRECATED: mode_sequence starting from 2nd, delimiter_align = center):
vip\<Enter>\<C-O>\<Backspace>rc**\<Enter>\<C-D>\<C-D>2=
Expect ruby:
@@ -816,6 +846,35 @@ Expect ruby:
dddddd /= 123
gg <=> ee
Do (align starting from 2nd, delimiter_align = center):
vip\<Enter>\<C-A>\<Backspace>rc**\<Enter>\<C-D>\<C-D>2=
Expect 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
Do (around all =s, do not ignore unmatched):
vip\<Enter>\<C-U>
\<C-L>0\<Enter>
@@ -893,10 +952,6 @@ Expect ruby:
apricot = 'DAD' + 'F#AD'
banana = 'Gros Michel' ## comment 2
Execute (define # rule):
let g:easy_align_delimiters =
\ { '#': { 'pattern': '#\+', 'ignores': ['String'], 'delimiter_align': 'l' } }
Do (using # rule):
vip\<Enter>\<C-U>#