Add delimiter_align option

This commit is contained in:
Junegunn Choi
2013-08-12 20:33:04 +09:00
parent 712bab8c72
commit 5e6e60d620
6 changed files with 258 additions and 55 deletions

125
README.md
View File

@@ -29,10 +29,14 @@ or [Pathogen](https://github.com/tpope/vim-pathogen).
### With Vundle ### With Vundle
Add the following line to your .vimrc,
```vim ```vim
Bundle 'junegunn/vim-easy-align' Bundle 'junegunn/vim-easy-align'
``` ```
then execute `:BundleInstall` command.
Usage Usage
----- -----
@@ -55,7 +59,7 @@ your `.vimrc`.
vnoremap <silent> <Enter> :EasyAlign<cr> vnoremap <silent> <Enter> :EasyAlign<cr>
``` ```
With the mapping, you can align selected lines of text with a few keystrokes. With the mapping, you can align selected lines of text with only a few keystrokes.
1. `<Enter>` key to start interactive EasyAlign command 1. `<Enter>` key to start interactive EasyAlign command
1. Optional Enter keys to toggle right-justification mode 1. Optional Enter keys to toggle right-justification mode
@@ -143,17 +147,7 @@ You can even omit spaces between the arguments, so concisely (or cryptically):
- `:EasyAlign*/[:;]\+/{'s':1,'l':0}` - `:EasyAlign*/[:;]\+/{'s':1,'l':0}`
Available options are as follows. Available options will be shown later in the document.
| Atrribute | Type | Default |
| ---------------- | ---------------- | ----------------------- |
| left_margin | number or string | 0 |
| right_margin | number or string | 0 |
| stick_to_left | boolean | 0 |
| ignore_unmatched | boolean | 1 |
| ignores | array | `['String', 'Comment']` |
(The last two options will be described shortly in the following sections.)
### Partial alignment in blockwise-visual mode ### Partial alignment in blockwise-visual mode
@@ -182,14 +176,35 @@ my_hash = { :a => 1,
However, in this case, we don't really need blockwise visual mode However, in this case, we don't really need blockwise visual mode
since the same can be easily done using the negative field number: `<Enter>-=` since the same can be easily done using the negative field number: `<Enter>-=`
Global options Alignment options
-------------- -----------------
Options values can be 1) specified as global variables, 2) set on each alignment
rule in `g:easy_align_delimiters`, 3) or given to every `:EasyAlign` command.
Command-line options have the highest precedence, and global variables have the
lowest precedence.
### List of options
| Option | Type | Default | Description | | Option | Type | Default | Description |
| ----------------------------- | ---------- | ----------------------- | -------------------------------------------------- | | ------------------ | ----------------- | ----------------------- | ------------------------------------------------------- |
| g:easy_align_ignores | list | `['String', 'Comment']` | Ignore delimiters in these syntax highlight groups | | `left_margin` | number | 0 | Number of spaces to attach before delimiter |
| g:easy_align_ignore_unmatched | boolean | `1` | Ignore lines without matching delimiter | | `left_margin` | string | `''` | String to attach before delimiter |
| g:easy_align_delimiters | dictionary | `{}` | Extend or override alignment rules | | `right_margin` | number | 0 | Number of spaces to attach after delimiter |
| `right_margin` | string | `''` | String to attach after delimiter |
| `stick_to_left` | boolean | 0 | Whether to position delimiter on the left-side |
| `ignore_unmatched` | boolean | 1 | Whether to ignore lines without matching delimiter |
| `ignores` | array | `['String', 'Comment']` | Delimiters in these syntax highlight groups are ignored |
| `delimiter_align` | string | `r` | Determines how to align delimiters of different lengths |
Some of the options can be specified using corresponding global variables.
| Option | Global variable |
| ------------------ | ------------------------------- |
| `ignore_unmatched` | `g:easy_align_ignore_unmatched` |
| `ignores` | `g:easy_align_ignores` |
| `delimiter_align` | `g:easy_align_delimiter_align` |
### Ignoring delimiters in comments or strings ### Ignoring delimiters in comments or strings
@@ -232,21 +247,13 @@ becomes as follows on `<Enter>:` (or `:EasyAlign:`)
Naturally, this feature only works when syntax highlighting is enabled. Naturally, this feature only works when syntax highlighting is enabled.
You can change the default rule by either defining global `g:easy_align_ignores` You can change the default rule by using one of these 3 methods.
array,
```vim 1. Define global `g:easy_align_ignores` list
" Ignore nothing! 2. Define a custom alignment rule in `g:easy_align_delimiters` with `ignores` option
let g:easy_align_ignores = [] 3. Provide `ignores` option to `:EasyAlign` command. e.g. `:EasyAlign:{'is':[]}`
```
or providing `ignores` option directly to `:EasyAlign` command For example if you set `ignores` option to be an empty list, you get
```vim
:EasyAlign:{'is':[]}
```
Then you get,
```ruby ```ruby
{ {
@@ -290,20 +297,12 @@ this is usually what we want.
} }
``` ```
However, this default behavior is also configurable. However, this default behavior is also configurable by using one of these 3
methods.
One way is to set the global `g:easy_align_ignore_unmatched` variable to 0. 1. Set the global `g:easy_align_ignore_unmatched` variable to 0
2. Define a custom alignment rule with `ignore_unmatched` option set to 0
```vim 3. Provide `ignore_unmatched` option to `:EasyAlign` command. e.g. `:EasyAlign:{'iu':0}`
let g:easy_align_ignore_unmatched = 0
```
Or in non-interactive mode, you can provide `ignore_unmatched` option to
`:EasyAlign` command as follows.
```vim
:EasyAlign:{'iu':0}
```
Then we get, Then we get,
@@ -317,6 +316,42 @@ Then we get,
} }
``` ```
### Aligning delimiters of different lengths
Global `g:easy_align_delimiter_align` option and rule-wise/command-wise
`delimiter_align` option determines how matched delimiters of different lengths
are aligned.
```ruby
apple = 1
banana += apple
cake ||= banana
```
By default, delimiters are right-aligned as follows.
```ruby
apple = 1
banana += apple
cake ||= banana
```
However, with `:EasyAlign={'da':l}`, delimiters are left-aligned.
```ruby
apple = 1
banana += apple
cake ||= banana
```
And on `:EasyAlign={'da':c}`, center-aligned.
```ruby
apple = 1
banana += apple
cake ||= banana
```
### Extending alignment rules ### Extending alignment rules
Although the default rules should cover the most of the use cases, Although the default rules should cover the most of the use cases,
@@ -328,7 +363,7 @@ you can extend the rules by setting a dictionary named `g:easy_align_delimiters`
let g:easy_align_delimiters = { let g:easy_align_delimiters = {
\ '>': { 'pattern': '>>\|=>\|>' }, \ '>': { 'pattern': '>>\|=>\|>' },
\ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] }, \ '/': { 'pattern': '//\+\|/\*\|\*/', 'ignores': ['String'] },
\ '#': { 'pattern': '#\+', 'ignores': ['String'] }, \ '#': { 'pattern': '#\+', 'ignores': ['String'], 'delimiter_align': 'l' },
\ ']': { \ ']': {
\ 'pattern': '[\[\]]', \ 'pattern': '[\[\]]',
\ 'left_margin': 0, \ 'left_margin': 0,

View File

@@ -44,7 +44,7 @@ let s:just = ['', '[R]']
let s:known_options = { let s:known_options = {
\ 'margin_left': [0, 1], 'margin_right': [0, 1], 'stick_to_left': [0], \ 'margin_left': [0, 1], 'margin_right': [0, 1], 'stick_to_left': [0],
\ 'left_margin': [0, 1], 'right_margin': [0, 1], \ 'left_margin': [0, 1], 'right_margin': [0, 1],
\ 'ignores': [3], 'ignore_unmatched': [0] \ 'ignores': [3], 'ignore_unmatched': [0], 'delimiter_align': [1]
\ } \ }
if exists("*strwidth") if exists("*strwidth")
@@ -200,7 +200,7 @@ function! s:split_line(line, fc, lc, pattern, stick_to_left, ignore_unmatched, i
return [tokens, delims] return [tokens, delims]
endfunction endfunction
function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth, ml, mr, stick_to_left, ignore_unmatched, ignores, recursive) function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth, ml, mr, da, stick_to_left, ignore_unmatched, ignores, recursive)
let lines = {} let lines = {}
let max_just_len = 0 let max_just_len = 0
let max_delim_len = 0 let max_delim_len = 0
@@ -288,11 +288,16 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
let tokens[nth] = token let tokens[nth] = token
" Pad the delimiter " Pad the delimiter
let dpad = repeat(' ', max_delim_len - s:strwidth(delim)) let dpadl = max_delim_len - s:strwidth(delim)
if a:stick_to_left if a:da == 'l'
let rpad = rpad . dpad let [dl, dr] = ['', repeat(' ', dpadl)]
elseif a:da == 'c'
let dl = repeat(' ', dpadl / 2)
let dr = repeat(' ', dpadl - dpadl / 2)
elseif a:da == 'r'
let [dl, dr] = [repeat(' ', dpadl), '']
else else
let delim = dpad . delim call s:exit('Invalid delimiter_align: ' . a:da)
endif endif
" Before and after the range (for blockwise visual mode) " Before and after the range (for blockwise visual mode)
@@ -318,7 +323,7 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
endif endif
" Align the token " Align the token
let aligned = join([lpad, token, ml, delim, mr, rpad], '') let aligned = join([lpad, token, ml, dl, delim, dr, mr, rpad], '')
let tokens[nth] = aligned let tokens[nth] = aligned
" Update the line " Update the line
@@ -329,7 +334,7 @@ function! s:do_align(just, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth,
if a:recursive && a:nth < max_tokens if a:recursive && a:nth < max_tokens
let just = a:recursive == 2 ? !a:just : a:just let just = a:recursive == 2 ? !a:just : a:just
call s:do_align(just, a:all_tokens, a:all_delims, a:fl, a:ll, a:fc, a:lc, a:pattern, call s:do_align(just, a:all_tokens, a:all_delims, a:fl, a:ll, a:fc, a:lc, a:pattern,
\ a:nth + 1, a:ml, a:mr, a:stick_to_left, a:ignore_unmatched, \ a:nth + 1, a:ml, a:mr, a:da, a:stick_to_left, a:ignore_unmatched,
\ a:ignores, a:recursive) \ a:ignores, a:recursive)
endif endif
endfunction endfunction
@@ -389,6 +394,7 @@ function! s:parse_args(args)
let cand = strpart(args, midx) let cand = strpart(args, midx)
try try
let [l, r, c] = ['l', 'r', 'c']
let o = eval(cand) let o = eval(cand)
if type(o) == 4 if type(o) == 4
let option = o let option = o
@@ -504,6 +510,7 @@ function! easy_align#align(just, expr) range
\ nth, \ nth,
\ ml, \ ml,
\ mr, \ mr,
\ get(dict, 'delimiter_align', get(g:, 'easy_align_delimiter_align', 'r')),
\ get(dict, 'stick_to_left', 0), \ get(dict, 'stick_to_left', 0),
\ get(dict, 'ignore_unmatched', get(g:, 'easy_align_ignore_unmatched', 1)), \ get(dict, 'ignore_unmatched', get(g:, 'easy_align_ignore_unmatched', 1)),
\ get(dict, 'ignores', s:ignored_syntax()), \ get(dict, 'ignores', s:ignored_syntax()),

View File

@@ -1,3 +1,5 @@
*easy_align.txt* A simple, easy-to-use Vim alignment plugin
vim-easy-align *vim-easy-align* *easy-align* vim-easy-align *vim-easy-align* *easy-align*
========================================================================= =========================================================================
@@ -117,6 +119,7 @@ Available options are as follows.
| left_margin | number or string | 0 | | left_margin | number or string | 0 |
| right_margin | number or string | 0 | | right_margin | number or string | 0 |
| stick_to_left | boolean | 0 | | stick_to_left | boolean | 0 |
| delimiter_align | string | 'r' |
| ignore_unmatched | boolean | 1 | | ignore_unmatched | boolean | 1 |
| ignores | array | `['String', 'Comment']` | | ignores | array | `['String', 'Comment']` |
@@ -235,6 +238,36 @@ Then we get,
} }
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={'da':l}`, delimiters are left-aligned.
apple = 1
banana += apple
cake ||= banana
And on `:EasyAlign={'da':c}`, center-aligned.
apple = 1
banana += apple
cake ||= banana
Extending alignment rules *g:easy_align_delimiters* Extending alignment rules *g:easy_align_delimiters*
------------------------------------------------------------------------- -------------------------------------------------------------------------

View File

@@ -379,3 +379,123 @@ George Harrison 1943
Ringo Starr 1940 Ringo Starr 1940
Pete Best 1941 Pete Best 1941
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
... - .-----
.. -- ..----
. --- ...---
---- ....--
. --- .....-
.. -- ......
... - .....-
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
... - .-----
.. -- ..----
. --- ...---
---- ....--
. --- .....-
.. -- ......
... - .....-
... - .-----
.. -- ..----
. --- ...---
---- ....--
. --- .....-
.. -- ......
... - .....-
...-.-----
..--..----
.---...---
----....--
.---.....-
..--......
...-.....-
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
... - .-----
.. -- ..----
. --- ...---
---- ....--
. --- .....-
.. -- ......
... - .....-
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
... - . -----
.. -- .. ----
. --- ... ---
---- .... --
. --- ..... -
.. -- ......
... - ..... -
...-. -----
..--.. ----
.---... ---
----.... --
.---..... -
..--......
...-..... -
... - .-----
.. -- ..----
. --- ...---
---- ....--
. --- .....-
.. -- ......
... - .....-

View File

@@ -122,3 +122,11 @@ George Harrison 1943
Ringo Starr 1940 Ringo Starr 1940
Pete Best 1941 Pete Best 1941
...-.-----
..--..----
.---...---
----....--
.---.....-
..--......
...-.....-

View File

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