mirror of
https://github.com/junegunn/vim-easy-align.git
synced 2025-11-17 06:13:41 -05:00
Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9815a55dbc | ||
|
|
12dd631697 | ||
|
|
1cd724dc23 | ||
|
|
14c693dfe5 | ||
|
|
d3f8e64261 | ||
|
|
3b395bd5ba | ||
|
|
05cc60d222 | ||
|
|
4be4101ad5 | ||
|
|
3800a5405c | ||
|
|
2e27fe55ad | ||
|
|
0cb6b98fc1 | ||
|
|
dd98d0a895 | ||
|
|
d1b68f9dd0 | ||
|
|
4fb4c1056c | ||
|
|
7cb559eb70 | ||
|
|
9ebd0e82da | ||
|
|
9e6207246c | ||
|
|
4732f10155 | ||
|
|
cd124c2c0b | ||
|
|
ed65b47f1b | ||
|
|
fac9f4dd75 | ||
|
|
0db4ea6132 | ||
|
|
504eab0f59 | ||
|
|
98e0b493ac | ||
|
|
1206c65dcb | ||
|
|
a1118be7d9 | ||
|
|
c62d124be6 | ||
|
|
883c6b67a0 | ||
|
|
32591ec4d4 | ||
|
|
ac9aa14ae4 | ||
|
|
cafe55dd65 | ||
|
|
6c276c37ad | ||
|
|
1744414e7e | ||
|
|
246139c57c | ||
|
|
3afd4540ed | ||
|
|
2782c1d0db | ||
|
|
d983381a99 | ||
|
|
52814ccd96 | ||
|
|
aa1ba68ea0 | ||
|
|
b8abc366a6 | ||
|
|
f6586bad39 | ||
|
|
44216b0a2c | ||
|
|
2595ebf933 | ||
|
|
6bc221c285 | ||
|
|
21697776b4 | ||
|
|
09167c79c9 | ||
|
|
cbb005ee71 | ||
|
|
ec15731bc9 | ||
|
|
eee4735770 | ||
|
|
5e2a588403 | ||
|
|
2fa6a040f6 | ||
|
|
f9a49e441d | ||
|
|
fc9555cd65 | ||
|
|
a98c1ccc99 | ||
|
|
0aa6289d8c | ||
|
|
cc8966c0a5 | ||
|
|
da281d78d3 | ||
|
|
8e8629c0cd | ||
|
|
a9f593fdf8 | ||
|
|
d87ea32cfe | ||
|
|
11a6b03e7e | ||
|
|
ba54df53ca | ||
|
|
d041e17bba | ||
|
|
2ab86911cb | ||
|
|
4929841a7a | ||
|
|
12792cd60f | ||
|
|
f7213f30f3 | ||
|
|
f44c325aa2 | ||
|
|
dc4786841e | ||
|
|
46abd8fb92 | ||
|
|
af39e544ca | ||
|
|
49c7133328 | ||
|
|
4298395085 | ||
|
|
e7fca89dde | ||
|
|
4b706efeb3 | ||
|
|
9bb987599a | ||
|
|
b8e93f96b8 | ||
|
|
6d85e93476 | ||
|
|
9271fc3f8f | ||
|
|
d3eec7fa8b | ||
|
|
62387b78e0 | ||
|
|
f400e4d8d1 | ||
|
|
9716fb3917 | ||
|
|
353ae9b071 | ||
|
|
ba4ba6e3c4 | ||
|
|
da284f908e | ||
|
|
8d4d5b7941 | ||
|
|
165bda1d95 | ||
|
|
ddc1e00b81 | ||
|
|
462a800064 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,3 +1,4 @@
|
||||
.travis.yml export-ignore
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
doc/tags export-ignore
|
||||
|
||||
15
.travis.yml
Normal file
15
.travis.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
language: vim
|
||||
|
||||
before_script: |
|
||||
git clone https://github.com/junegunn/vader.vim.git
|
||||
git clone https://github.com/tpope/vim-repeat
|
||||
|
||||
script: |
|
||||
vim -Nu <(cat << VIMRC
|
||||
filetype off
|
||||
set rtp+=vader.vim
|
||||
set rtp+=vim-repeat
|
||||
set rtp+=.
|
||||
filetype plugin indent on
|
||||
syntax enable
|
||||
VIMRC) -c 'Vader! test/*' > /dev/null
|
||||
91
DEMO.md
91
DEMO.md
@@ -1,91 +0,0 @@
|
||||
# vim: set buftype=nofile colorcolumn= scrolloff=0 noshowcmd:
|
||||
|
||||
vim-easy-align
|
||||
==============
|
||||
|
||||
Where's Lennon?
|
||||
---------------
|
||||
|
||||
Paul McCartney 1942
|
||||
George Harrison 1943
|
||||
Ringo Starr 1940
|
||||
Pete Best 1941
|
||||
|
||||
|
||||
Formatting table
|
||||
----------------
|
||||
```
|
||||
|
||||
| Option| Type | Default | Description |
|
||||
|--|--|--|--|
|
||||
| threads | Fixnum | 1 | number of threads in the thread pool |
|
||||
|queues |Fixnum | 1 | number of concurrent queues |
|
||||
|queue_size | Fixnum | 1000 | size of each queue |
|
||||
| interval | Numeric | 0 | dispatcher interval for processing |
|
||||
|batch | Boolean | false | enables batch processing mode |
|
||||
|batch_size | Fixnum | nil | maximum number of items in batch|
|
||||
|logger | Logger | nil | logger instance for debug logs |
|
||||
|
||||
```
|
||||
Operators with = sign
|
||||
---------------------
|
||||
```ruby
|
||||
|
||||
a =
|
||||
a = 1
|
||||
bbbb = 2
|
||||
ccccccc = 3
|
||||
ccccccccccccccc
|
||||
ddd = 4
|
||||
eeee === eee = eee = eee=f
|
||||
fff = ggg += gg &&= gg
|
||||
g != hhhhhhhh == 888
|
||||
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
|
||||
|
||||
```
|
||||
Formatting YAML (or JSON)
|
||||
-------------------------
|
||||
```yaml
|
||||
|
||||
mysql:
|
||||
# JDBC driver for MySQL database:
|
||||
driver: com.mysql.jdbc.Driver
|
||||
# JDBC URL for the connection (jdbc:mysql://HOSTNAME/DATABASE)
|
||||
url: jdbc:mysql://localhost/test
|
||||
database: test
|
||||
"user:pass":r00t:pa55
|
||||
|
||||
```
|
||||
Using blockwise-visual mode or negative N-th parameter
|
||||
------------------------------------------------------
|
||||
```ruby
|
||||
|
||||
options = { :caching => nil,
|
||||
:versions => 3,
|
||||
"cache=blocks" => false }.merge(options)
|
||||
|
||||
```
|
||||
Commas
|
||||
------
|
||||
|
||||
aaa, bb,c
|
||||
d,eeeeeee
|
||||
fffff, gggggggggg,
|
||||
h, , ii
|
||||
j,,k
|
||||
|
||||
|
||||
112
EXAMPLES.md
112
EXAMPLES.md
@@ -1,14 +1,23 @@
|
||||
vim-easy-align examples
|
||||
=======================
|
||||
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 the following mappings in your .vimrc.
|
||||
|
||||
```vim
|
||||
vnoremap <silent> <Enter> :EasyAlign<cr>
|
||||
" Start interactive EasyAlign in visual mode (e.g. vipga)
|
||||
xmap ga <Plug>(EasyAlign)
|
||||
|
||||
" Start interactive EasyAlign for a motion/text object (e.g. gaip)
|
||||
nmap ga <Plug>(EasyAlign)
|
||||
```
|
||||
|
||||
You can use either of the maps. Place the cursor on the paragraph and press
|
||||
|
||||
- `gaip` "(ga) start easy-align on (i)nner (p)aragraph"
|
||||
- or `vipga` "(v)isual-select (i)nner (p)aragraph and (ga) start easy-align"
|
||||
|
||||
To enable syntax highlighting in the code blocks, define and call the following
|
||||
function.
|
||||
|
||||
@@ -33,15 +42,17 @@ Alignment around whitespaces
|
||||
|
||||
You can align text around whitespaces with `<space>` delimiter key.
|
||||
|
||||
Try these commands:
|
||||
Start the interactive mode as described above (`gaip` or `vipga`) and try
|
||||
these commands:
|
||||
|
||||
- `<space>`
|
||||
- `2<space>`
|
||||
- `*<space>`
|
||||
- `-<space>`
|
||||
- `-2<space>`
|
||||
- `<Enter><space>`
|
||||
- `<Enter>2<space>`
|
||||
- `<Enter>*<space>`
|
||||
- `<Enter>-<space>`
|
||||
- `<Enter>-2<space>`
|
||||
- `<Enter><Enter><space>`
|
||||
- `<Enter><Enter>*<space>`
|
||||
- `<Enter><Enter><Enter>*<space>`
|
||||
|
||||
### Example
|
||||
|
||||
@@ -57,12 +68,13 @@ Pete Best 1941
|
||||
Formatting table
|
||||
----------------
|
||||
|
||||
Try these commands:
|
||||
Again, start the interactive mode and try these commands:
|
||||
|
||||
- `*|`
|
||||
- `**|`
|
||||
- `<Enter>*|`
|
||||
- `<Enter>**|`
|
||||
- `<Enter><Enter>*|`
|
||||
- `<Enter><Enter>**|`
|
||||
- `<Enter><Enter><Enter>*|`
|
||||
|
||||
### Example
|
||||
|
||||
@@ -84,15 +96,16 @@ Try these commands:
|
||||
Alignment around =
|
||||
------------------
|
||||
|
||||
The default rule for delimiter key `=` aligns around a whole family of operators
|
||||
containing `=` character.
|
||||
The default rule for delimiter key `=` aligns around a whole family of
|
||||
operators containing `=` character.
|
||||
|
||||
Try these commands:
|
||||
- `<Enter>=`
|
||||
- `<Enter>*=`
|
||||
Try these commands in the interactive mode.
|
||||
|
||||
- `=`
|
||||
- `*=`
|
||||
- `**=`
|
||||
- `<Enter>**=`
|
||||
- `<Enter><Enter>**=`
|
||||
- `<Enter><Enter><Enter>*=`
|
||||
- `<Enter><Enter>*=`
|
||||
|
||||
### Example
|
||||
|
||||
@@ -128,8 +141,8 @@ gg <=> ee
|
||||
Formatting YAML (or JSON)
|
||||
-------------------------
|
||||
|
||||
Try `<Enter>:` here, to align text around only the first occurrences of colons.
|
||||
In this case, you don't want to align around all the colons: `<Enter>*:`.
|
||||
You can use `:`-rule here to align text around only the first occurrences of
|
||||
colons. In this case, you don't want to align around all the colons: `*:`.
|
||||
|
||||
```yaml
|
||||
mysql:
|
||||
@@ -144,7 +157,7 @@ mysql:
|
||||
Formatting multi-line method chaining
|
||||
-------------------------------------
|
||||
|
||||
Try `<Enter>.` or `<Enter>*.` on the following lines.
|
||||
Try `.` or `*.` on the following lines.
|
||||
|
||||
```ruby
|
||||
my_object
|
||||
@@ -170,8 +183,8 @@ Using blockwise-visual mode or negative N-th parameter
|
||||
------------------------------------------------------
|
||||
|
||||
You can try either:
|
||||
- select text around `=>` in blockwise-visual mode (`CTRL-V`) and `<Enter>=`
|
||||
- or `<Enter>-=`
|
||||
- select text around `=>` in blockwise-visual mode (`CTRL-V`) and `ga=`
|
||||
- or `gaip-=`
|
||||
|
||||
```ruby
|
||||
options = { :caching => nil,
|
||||
@@ -182,8 +195,7 @@ options = { :caching => nil,
|
||||
Commas
|
||||
------
|
||||
|
||||
There is also a predefined rule for commas, try `<Enter>*,` on the following
|
||||
lines.
|
||||
There is also a predefined rule for commas, try `*,`.
|
||||
|
||||
```
|
||||
aaa, bb,c
|
||||
@@ -197,7 +209,7 @@ Ignoring delimiters in comments or strings
|
||||
------------------------------------------
|
||||
|
||||
Delimiters highlighted as comments or strings are ignored by default, try
|
||||
`<Enter>*=` on the following lines.
|
||||
`gaip*=` on the following lines.
|
||||
|
||||
```c
|
||||
|
||||
@@ -214,14 +226,17 @@ 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
|
||||
```
|
||||
|
||||
So, how do we align the trailing comments in the above lines?
|
||||
Simply try `<Enter>-<space>`. The spaces in the comments are ignored, so the
|
||||
trailing comment in each line is considered to be a single chunk.
|
||||
So, how do we align the trailing comments in the above lines? Simply try
|
||||
`-<space>`. The spaces in the comments are ignored, so the trailing comment in
|
||||
each line is considered to be a single chunk.
|
||||
|
||||
But that doesn't work in the following case.
|
||||
|
||||
@@ -246,7 +261,7 @@ let g:easy_align_delimiters['#'] = { 'pattern': '#', 'ignore_groups': ['String']
|
||||
Notice that the rule overrides `ignore_groups` attribute in order *not to ignore*
|
||||
delimiters highlighted as comments.
|
||||
|
||||
Then on `<Enter>#`, we get
|
||||
Then on `#`, we get
|
||||
|
||||
```ruby
|
||||
apple = 1 # comment not aligned
|
||||
@@ -259,13 +274,16 @@ command:
|
||||
|
||||
```vim
|
||||
" Using regular expression /#/
|
||||
" - "is" is fuzzy-matched to "*i*gnore*s*"
|
||||
:EasyAlign/#/{'is':['String']}
|
||||
" - "ig" is a shorthand notation of "ignore_groups"
|
||||
:EasyAlign/#/{'ig':['String']}
|
||||
|
||||
" Or more concisely with the shorthand notation;
|
||||
:EasyAlign/#/ig['String']
|
||||
```
|
||||
|
||||
In this case, the second line is ignored as it doesn't contain a `#`. (The one
|
||||
highlighted as String is ignored.) If you don't want the second line to be
|
||||
ignored, there are three options:
|
||||
In this case, the second line is ignored as it doesn't contain a `#` (The one
|
||||
in `'F#AD'` is ignored as it's highlighted as String). If you don't want the
|
||||
second line to be ignored, there are three options:
|
||||
|
||||
1. Set global `g:easy_align_ignore_unmatched` flag to 0
|
||||
2. Use `:EasyAlign` command with `ignore_unmatched` option
|
||||
@@ -277,11 +295,13 @@ let g:easy_align_ignore_unmatched = 0
|
||||
|
||||
" 2. Using :EasyAlign command with ignore_unmatched option
|
||||
" 2-1. Using predefined rule with delimiter key #
|
||||
" - "iu" is fuzzy-matched to "*i*gnore_*u*nmatched"
|
||||
" - "iu" is expanded to "*i*gnore_*u*nmatched"
|
||||
:EasyAlign#{'iu':0}
|
||||
" or
|
||||
:EasyAlign#iu0
|
||||
|
||||
" 2-2. Using regular expression /#/
|
||||
:EasyAlign/#/{'is':['String'],'iu':0}
|
||||
:EasyAlign/#/ig['String']iu0
|
||||
|
||||
" 3. Update the alignment rule with ignore_unmatched option
|
||||
let g:easy_align_delimiters['#'] = {
|
||||
@@ -308,7 +328,7 @@ static double pi = 3.14;
|
||||
```
|
||||
|
||||
We can align these lines with the predefined `=` rule. Select the lines and
|
||||
press `<Enter>=`
|
||||
press `ga=`
|
||||
|
||||
```c
|
||||
const char* str = "Hello";
|
||||
@@ -318,7 +338,7 @@ static double pi = 3.14;
|
||||
|
||||
Not bad. However, the names of the variables, `str`, `count`, and `pi` are not
|
||||
aligned with each other. Can we do better? We can clearly see that simple
|
||||
`<Enter><space>` won't properly align those names.
|
||||
`<space>`-rule won't properly align those names.
|
||||
So let's define an alignment rule than can handle this case.
|
||||
|
||||
```vim
|
||||
@@ -329,7 +349,7 @@ let g:easy_align_delimiters['d'] = {
|
||||
```
|
||||
|
||||
This new rule aligns text around spaces that are *not* preceded by
|
||||
`const` or `static`. Let's try it with `<Enter>d`.
|
||||
`const` or `static`. Let's select the lines and try `gad`.
|
||||
|
||||
```c
|
||||
const char* str = "Hello";
|
||||
@@ -338,7 +358,7 @@ static double pi = 3.14;
|
||||
```
|
||||
|
||||
Okay, the names are now aligned. We select the lines again with `gv`, and then
|
||||
press `<Enter>=` to finish our alignment.
|
||||
press `ga=` to finish our alignment.
|
||||
|
||||
```c
|
||||
const char* str = "Hello";
|
||||
@@ -369,14 +389,14 @@ So what do we do? Let's try to improve our alignment rule.
|
||||
|
||||
```vim
|
||||
let g:easy_align_delimiters['d'] = {
|
||||
\ 'pattern': ' \(\S\+\s*[;=]\)\@=',
|
||||
\ 'pattern': ' \ze\S\+\s*[;=]',
|
||||
\ 'left_margin': 0, 'right_margin': 0
|
||||
\ }
|
||||
```
|
||||
|
||||
Now the new rule has changed to align text around spaces that are followed
|
||||
by some non-whitespace characters and then an equals sign or a semi-colon.
|
||||
Try `<Enter>d`
|
||||
Try `vipgad`
|
||||
|
||||
```c
|
||||
const char* str = "Hello";
|
||||
@@ -385,7 +405,7 @@ static double pi = 3.14;
|
||||
static std::map<std::string, float>* scores = pointer;
|
||||
```
|
||||
|
||||
We're right on track, now press `gv<Enter>=` and voila!
|
||||
We're right on track, now press `gvga=` and voila!
|
||||
|
||||
```c
|
||||
const char* str = "Hello";
|
||||
|
||||
573
README.md
573
README.md
@@ -1,93 +1,148 @@
|
||||
vim-easy-align
|
||||
vim-easy-align 
|
||||
==============
|
||||
|
||||
A simple, easy-to-use Vim alignment plugin.
|
||||
|
||||
Demo
|
||||
----
|
||||
|
||||

|
||||
|
||||
(Too fast? Slower GIF is [here](https://raw.github.com/junegunn/i/master/vim-easy-align-slow.gif))
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Easy to use
|
||||
- Comes with a predefined set of alignment rules
|
||||
- Provides a fast and intuitive interface
|
||||
- Extensible
|
||||
- You can define your own rules
|
||||
- Supports arbitrary regular expressions
|
||||
- Optimized for code editing
|
||||
- Takes advantage of syntax highlighting feature to avoid unwanted alignments
|
||||
|
||||
### _"I already have a similar one. Should I switch?"_
|
||||
|
||||
Maybe or maybe not. See [related work](https://github.com/junegunn/vim-easy-align#related-work) section.
|
||||

|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Either [download zip file](http://www.vim.org/scripts/script.php?script_id=4520)
|
||||
and extract in ~/.vim or
|
||||
[use](https://github.com/tpope/vim-pathogen)
|
||||
[your](https://github.com/gmarik/vundle)
|
||||
[favorite](https://github.com/junegunn/vim-plug)
|
||||
[plugin](https://github.com/Shougo/neobundle.vim)
|
||||
[manager](https://github.com/MarcWeber/vim-addon-manager).
|
||||
Use your favorite plugin 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`
|
||||
- [vim-plug](https://github.com/junegunn/vim-plug)
|
||||
1. Add `Plug 'junegunn/vim-easy-align'` to .vimrc
|
||||
2. Run `:PlugInstall`
|
||||
Using [vim-plug](https://github.com/junegunn/vim-plug):
|
||||
|
||||
```vim
|
||||
Plug 'junegunn/vim-easy-align'
|
||||
```
|
||||
|
||||
Quick start guide
|
||||
-----------------
|
||||
|
||||
Add the following mappings to your .vimrc.
|
||||
|
||||
```vim
|
||||
" Start interactive EasyAlign in visual mode (e.g. vipga)
|
||||
xmap ga <Plug>(EasyAlign)
|
||||
|
||||
" Start interactive EasyAlign for a motion/text object (e.g. gaip)
|
||||
nmap ga <Plug>(EasyAlign)
|
||||
```
|
||||
|
||||
Then with the following lines of text,
|
||||
|
||||
```
|
||||
apple =red
|
||||
grass+=green
|
||||
sky-= blue
|
||||
```
|
||||
|
||||
try these commands:
|
||||
|
||||
- `vipga=`
|
||||
- `v`isual-select `i`nner `p`aragraph
|
||||
- Start EasyAlign command (`ga`)
|
||||
- Align around `=`
|
||||
- `gaip=`
|
||||
- Start EasyAlign command (`ga`) for `i`nner `p`aragraph
|
||||
- Align around `=`
|
||||
|
||||
Demo
|
||||
----
|
||||
|
||||
*Click on each image to see from the beginning.*
|
||||
|
||||
### Using predefined alignment rules
|
||||
|
||||
An *alignment rule* is a predefined set of options for common alignment tasks,
|
||||
which is identified by a single character, such as `<Space>`, `=`, `:`, `.`,
|
||||
`|`, `&`, `#`, and `,`.
|
||||
|
||||
#### `=`
|
||||
|
||||

|
||||
|
||||
- `=` Around the 1st occurrences
|
||||
- `2=` Around the 2nd occurrences
|
||||
- `*=` Around all occurrences
|
||||
- `**=` Left/Right alternating alignment around all occurrences
|
||||
- `<Enter>` Switching between left/right/center alignment modes
|
||||
|
||||
#### `<Space>`
|
||||
|
||||

|
||||
|
||||
- `<Space>` Around the 1st occurrences of whitespaces
|
||||
- `2<Space>` Around the 2nd occurrences
|
||||
- `-<Space>` Around the last occurrences
|
||||
- `<Enter><Enter>2<Space>` Center-alignment around the 2nd occurrences
|
||||
|
||||
#### `,`
|
||||
|
||||

|
||||
|
||||
- The predefined comma-rule places a comma right next to the preceding token
|
||||
without margin (`{'stick_to_left': 1, 'left_margin': 0}`)
|
||||
- You can change it with `<Right>` arrow
|
||||
|
||||
### Using regular expression
|
||||
|
||||

|
||||
|
||||
You can use an arbitrary regular expression by
|
||||
- pressing `<Ctrl-X>` in interactive mode
|
||||
- or using `:EasyAlign /REGEX/` command in visual mode or in normal mode with
|
||||
a range (e.g. `:%`)
|
||||
|
||||
### Different ways to start
|
||||
|
||||

|
||||
|
||||
This demo shows how you can start interactive mode with visual selection or use
|
||||
non-interactive `:EasyAlign` command.
|
||||
|
||||
### Aligning table cells
|
||||
|
||||

|
||||
|
||||
Check out various alignment options and "live interactive mode".
|
||||
|
||||
### Syntax-aware alignment
|
||||
|
||||

|
||||
|
||||
Delimiters in strings and comments are ignored by default.
|
||||
|
||||
### Using blockwise-visual mode
|
||||
|
||||

|
||||
|
||||
You can limit the scope with blockwise-visual mode.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
_vim-easy-align_ defines `:EasyAlign` command (and the right-align
|
||||
variant `:EasyAlign!`) for visual mode.
|
||||
### Flow of execution
|
||||
|
||||
| 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[!] [...]` |
|
||||
<img src="https://raw.githubusercontent.com/junegunn/i/master/easy-align/usage.png" width="469">
|
||||
|
||||
### Concept of _alignment rule_
|
||||
There are two ways to use easy-align.
|
||||
|
||||
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 `,`.
|
||||
#### 1. `<Plug>` mappings (interactive mode)
|
||||
|
||||
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
|
||||
|
||||
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`.
|
||||
The recommended method is to use `<Plug>(EasyAlign)` mapping in normal and
|
||||
visual mode. They are usually mapped to `ga`, but you can choose any key
|
||||
sequences.
|
||||
|
||||
```vim
|
||||
vnoremap <silent> <Enter> :EasyAlign<Enter>
|
||||
nmap ga <Plug>(EasyAlign)
|
||||
xmap ga <Plug>(EasyAlign)
|
||||
```
|
||||
|
||||
(Of course you can use any key combination as the trigger. e.g. `<Leader>a`)
|
||||
|
||||
With the mapping, you can align selected lines of text with only a few keystrokes.
|
||||
|
||||
1. `<Enter>` key to start interactive EasyAlign command
|
||||
1. Optional: Enter keys to select alignment mode (left, right, or center)
|
||||
1. Optional: N-th delimiter (default: 1)
|
||||
1. `ga` key in visual mode, or `ga` followed by a motion or a text
|
||||
object to start interactive mode
|
||||
1. (Optional) Enter keys to cycle between alignment mode (left, right, or center)
|
||||
1. (Optional) N-th delimiter (default: 1)
|
||||
- `1` Around the 1st occurrences of delimiters
|
||||
- `2` Around the 2nd occurrences of delimiters
|
||||
- ...
|
||||
@@ -96,171 +151,161 @@ 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>`, `=`, `:`, `.`, `|`, `&`, `#`, `,`) or an arbitrary regular expression followed by `<CTRL-X>`
|
||||
|
||||
Alignment rules for the following delimiters have been defined to meet the most needs.
|
||||
#### 2. Using `:EasyAlign` command
|
||||
|
||||
| Delimiter key | Description/Use cases |
|
||||
| ------------- | -------------------------------------------------------------------- |
|
||||
| `<space>` | General alignment around whitespaces |
|
||||
| `=` | Operators containing equals sign (`=`, `==,` `!=`, `+=`, `&&=`, ...) |
|
||||
| `:` | Suitable for formatting JSON or YAML |
|
||||
| `.` | Multi-line method chaining |
|
||||
| `,` | Multi-line method arguments |
|
||||
| `&` | LaTeX tables (matches `&` and `\\`) |
|
||||
| | | Table markdown |
|
||||
If you prefer command-line, use `:EasyAlign` command instead.
|
||||
|
||||
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).
|
||||
```vim
|
||||
" Using predefined rules
|
||||
:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
|
||||
|
||||
#### Example command sequences
|
||||
" Using regular expression
|
||||
:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
|
||||
```
|
||||
|
||||
| With visual map | Description | Equivalent command |
|
||||
| ------------------- | ------------------------------------------------------- | ---------------------- |
|
||||
| `<Enter><space>` | Alignment around 1st whitespaces | `:'<,'>EasyAlign\ ` |
|
||||
| `<Enter>2<space>` | Alignment around 2nd whitespaces | `:'<,'>EasyAlign2\ ` |
|
||||
| `<Enter>-<space>` | Alignment around the last whitespaces | `:'<,'>EasyAlign-\ ` |
|
||||
| `<Enter>-2<space>` | Alignment around the 2nd to last whitespaces | `:'<,'>EasyAlign-2\ ` |
|
||||
| `<Enter>:` | Alignment around 1st colon (`key: value`) | `:'<,'>EasyAlign:` |
|
||||
| `<Enter><Right>:` | Alignment around 1st colon (`key : value`) | `:'<,'>EasyAlign:s0l1` |
|
||||
| `<Enter>=` | Alignment around 1st operators with = | `:'<,'>EasyAlign=` |
|
||||
| `<Enter>2=` | Alignment around 2nd operators with = | `:'<,'>EasyAlign2=` |
|
||||
| `<Enter>3=` | Alignment around 3rd operators with = | `:'<,'>EasyAlign3=` |
|
||||
| `<Enter>*=` | Alignment around all operators with = | `:'<,'>EasyAlign*=` |
|
||||
| `<Enter>**=` | Left-right alternating alignment around all = operators | `:'<,'>EasyAlign**=` |
|
||||
| `<Enter><Enter>=` | Right alignment around 1st equals signs | `:'<,'>EasyAlign!=` |
|
||||
| `<Enter><Enter>**=` | Right-left alternating alignment around all = operators | `:'<,'>EasyAlign!**=` |
|
||||
### Regular expression vs. predefined rules
|
||||
|
||||
#### Using regular expressions
|
||||
You can use regular expressions but it's usually much easier to use predefined
|
||||
alignment rules that you can trigger with a single keystroke.
|
||||
|
||||
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:
|
||||
| Key | Description/Use cases |
|
||||
| --------- | -------------------------------------------------------------------- |
|
||||
| `<Space>` | General alignment around whitespaces |
|
||||
| `=` | Operators containing equals sign (`=`, `==,` `!=`, `+=`, `&&=`, ...) |
|
||||
| `:` | Suitable for formatting JSON or YAML |
|
||||
| `.` | Multi-line method chaining |
|
||||
| `,` | Multi-line method arguments |
|
||||
| `&` | LaTeX tables (matches `&` and `\\`) |
|
||||
| `#` | Ruby/Python comments |
|
||||
| `"` | Vim comments |
|
||||
| `<Bar>` | Table markdown |
|
||||
|
||||
- `<Enter>`
|
||||
- `*`
|
||||
- `<CTRL-/>` (or `<CTRL-X>` on GVim)
|
||||
- `[0-9]\+`
|
||||
You can also define your own rules with `g:easy_align_delimiters` which will
|
||||
be described in [the later section](#extending-alignment-rules).
|
||||
|
||||
----
|
||||
|
||||
### Interactive mode
|
||||
|
||||
Interactive mode is started either with `<Plug>(EasyAlign)` mapping or with
|
||||
`:EasyAlign` command with no argument.
|
||||
|
||||
#### Examples using predefined rules
|
||||
|
||||
| Keystrokes | Description | Equivalent command |
|
||||
| ------------ | ---------------------------------- | --------------------- |
|
||||
| `<Space>` | Around 1st whitespaces | `:'<,'>EasyAlign\ ` |
|
||||
| `2<Space>` | Around 2nd whitespaces | `:'<,'>EasyAlign2\ ` |
|
||||
| `-<Space>` | Around the last whitespaces | `:'<,'>EasyAlign-\ ` |
|
||||
| `-2<Space>` | Around the 2nd to last whitespaces | `:'<,'>EasyAlign-2\ ` |
|
||||
| `:` | Around 1st colon (`key: value`) | `:'<,'>EasyAlign:` |
|
||||
| `<Right>:` | Around 1st colon (`key : value`) | `:'<,'>EasyAlign:>l1` |
|
||||
| `=` | Around 1st operators with = | `:'<,'>EasyAlign=` |
|
||||
| `3=` | Around 3rd operators with = | `:'<,'>EasyAlign3=` |
|
||||
| `*=` | Around all operators with = | `:'<,'>EasyAlign*=` |
|
||||
| `**=` | Left-right alternating around = | `:'<,'>EasyAlign**=` |
|
||||
| `<Enter>=` | Right alignment around 1st = | `:'<,'>EasyAlign!=` |
|
||||
| `<Enter>**=` | Right-left alternating around = | `:'<,'>EasyAlign!**=` |
|
||||
|
||||
Instead of finishing the alignment with a delimiter key, you can type in
|
||||
a regular expression if you press `<CTRL-/>` or `<CTRL-X>`.
|
||||
|
||||
#### Alignment options in interactive mode
|
||||
|
||||
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 following sections](https://github.com/junegunn/vim-easy-align#alignment-options).
|
||||
[the following sections](#alignment-options).
|
||||
|
||||
| Key | Option | Values |
|
||||
| -------- | ------------------ | -------------------------------------------------- |
|
||||
| --------- | ------------------ | -------------------------------------------------- |
|
||||
| `CTRL-F` | `filter` | Input string (`[gv]/.*/?`) |
|
||||
| `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 (`/[lrc]+\*{0,2}/`) |
|
||||
| `CTRL-G` | `ignore_groups` | `[]`, `['String']`, `['Comment']`, `['String', 'Comment']` |
|
||||
| `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>
|
||||
```
|
||||
|
||||
### Live interactive mode
|
||||
#### 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 a mapping such as
|
||||
follows in addition to the one for `:EasyAlign` command.
|
||||
Live interactive mode can be started with either `<Plug>(LiveEasyAlign)` map
|
||||
or `:LiveEasyAlign` command. Or you can switch to live interactive mode while
|
||||
in ordinary interactive mode by pressing `<CTRL-P>`. (P for Preview)
|
||||
|
||||
```vim
|
||||
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.
|
||||
|
||||
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.
|
||||
### :EasyAlign command
|
||||
|
||||
### Using `EasyAlign` in command line
|
||||
|
||||
Instead of going into the interactive mode, you can just type in arguments to
|
||||
`:EasyAlign` command.
|
||||
Instead of starting interactive mode, you can use 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
|
||||
detail later](https://github.com/junegunn/vim-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](#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
|
||||
|
||||
Option names are fuzzy-matched, so you can write as follows:
|
||||
You don't have to write complete names as long as they're distinguishable.
|
||||
|
||||
- `:EasyAlign * /[:;]\+/ { 'stl': 1, 'l': 0 }`
|
||||
|
||||
You can even omit spaces between the arguments, so concisely (or cryptically):
|
||||
You can even omit spaces between the arguments.
|
||||
|
||||
- `:EasyAlign*/[:;]\+/{'s':1,'l':0}`
|
||||
|
||||
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]` |
|
||||
|
||||
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)
|
||||
- `[:;]\+`
|
||||
| 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]` |
|
||||
|
||||
### Partial alignment in blockwise-visual mode
|
||||
|
||||
@@ -289,25 +334,6 @@ my_hash = { :a => 1,
|
||||
However, in this case, we don't really need blockwise visual mode
|
||||
since the same can be easily done using the negative N-th parameter: `<Enter>-=`
|
||||
|
||||
### EasyAlign as Vim operator
|
||||
|
||||
You can define an operator function which executes EasyAlign command, so that it
|
||||
can be used with a Vim movement.
|
||||
|
||||
```vim
|
||||
function! s:easy_align_1st_eq(type, ...)
|
||||
'[,']EasyAlign=
|
||||
endfunction
|
||||
nnoremap <Leader>= :set opfunc=<SID>easy_align_1st_eq<Enter>g@
|
||||
|
||||
function! s:easy_align_1st_colon(type, ...)
|
||||
'[,']EasyAlign:
|
||||
endfunction
|
||||
nnoremap <Leader>: :set opfunc=<SID>easy_align_1st_colon<Enter>g@
|
||||
```
|
||||
|
||||
Now without going into visual mode, you can align the lines in the paragraph
|
||||
by `<Leader>=ip` or `<Leader>:ip`.
|
||||
|
||||
Alignment options
|
||||
-----------------
|
||||
@@ -326,7 +352,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):
|
||||
|
||||
@@ -335,24 +361,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/`
|
||||
|
||||
@@ -380,7 +406,7 @@ highlighted as code comments or strings are ignored.
|
||||
```vim
|
||||
" Default:
|
||||
" If a delimiter is in a highlight group whose name matches
|
||||
" any of the followings, it will be ignored.
|
||||
" any of the following regular expressions, it will be ignored.
|
||||
let g:easy_align_ignore_groups = ['Comment', 'String']
|
||||
```
|
||||
|
||||
@@ -433,7 +459,22 @@ 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.
|
||||
|
||||
To make `ignore_groups` work, and to debug the related issues, it is useful to
|
||||
know which highlight group a certain location in a file belongs to. A special
|
||||
function exists for this purpose, returning exactly the name of the highlight
|
||||
group that is used by the easy align plugin.
|
||||
|
||||
```vim
|
||||
" Highlight group name of the cursor position
|
||||
echo easy_align#get_highlight_group_name()
|
||||
|
||||
" Highlight group name of the line 10, column 20
|
||||
echo easy_align#get_highlight_group_name(10, 20)
|
||||
```
|
||||
|
||||
### Ignoring unmatched lines
|
||||
|
||||
@@ -576,8 +617,6 @@ 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
|
||||
@@ -607,38 +646,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
|
||||
@@ -647,15 +686,17 @@ 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`.
|
||||
|
||||
You may refer to the definitions of the default alignment rules
|
||||
[here](https://github.com/junegunn/vim-easy-align/blob/2.6.1/autoload/easy_align.vim#L29).
|
||||
[here](https://github.com/junegunn/vim-easy-align/blob/2.9.6/autoload/easy_align.vim#L32-L46).
|
||||
|
||||
#### Example
|
||||
#### Examples
|
||||
|
||||
```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,
|
||||
@@ -669,8 +710,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
|
||||
\ }
|
||||
\ }
|
||||
@@ -718,86 +759,12 @@ Advanced examples and use cases
|
||||
See [EXAMPLES.md](https://github.com/junegunn/vim-easy-align/blob/master/EXAMPLES.md)
|
||||
for more examples.
|
||||
|
||||
|
||||
Related work
|
||||
------------
|
||||
|
||||
There are two well-known plugins with the same goal as that of vim-easy-align.
|
||||
|
||||
- [DrChip's Alignment Tool for Vim](http://www.drchip.org/astronaut/vim/align.html) (herein will be referred to as "Align")
|
||||
- [DrChip's Alignment Tool for Vim](http://www.drchip.org/astronaut/vim/align.html)
|
||||
- [Tabular](https://github.com/godlygeek/tabular)
|
||||
|
||||
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?
|
||||
|
||||
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.
|
||||
|
||||
### Ease of use
|
||||
|
||||
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!
|
||||
|
||||
- *Right-align*: `<Enter><Enter>`
|
||||
- around the *second* occurrences: `2`
|
||||
- of *whitespaces*: `<space>`
|
||||
|
||||
For the simplest cases, Tabular and Align are also easy to use. But sooner or
|
||||
later, you will find yourself scratching your head, trying to come up with some
|
||||
complex regular expressions.
|
||||
|
||||
_"How am I going to align the third to the last word in each line to the right
|
||||
without affecting the ones before it?"_
|
||||
|
||||
### Clean
|
||||
|
||||
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.
|
||||
|
||||
### Optimized for code editing
|
||||
|
||||
vim-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>:`
|
||||
|
||||
```javascript
|
||||
var jdbc = {
|
||||
// JDBC driver for MySQL database:
|
||||
driver: "com.mysql.jdbc.Driver",
|
||||
/* JDBC URL for the connection (jdbc:mysql://HOSTNAME/DATABASE) */
|
||||
url: 'jdbc:mysql://localhost/test',
|
||||
database: "test",
|
||||
"user:pass":"r00t:pa55"
|
||||
};
|
||||
```
|
||||
|
||||
(To be fair, Align also can be configured to consider syntax highlighting with
|
||||
`g:AlignSkip` function reference which should point to a custom function that
|
||||
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
|
||||
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
|
||||
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!
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
" Copyright (c) 2013 Junegunn Choi
|
||||
" Copyright (c) 2014 Junegunn Choi
|
||||
"
|
||||
" MIT License
|
||||
"
|
||||
@@ -26,14 +26,19 @@ if exists("g:loaded_easy_align")
|
||||
endif
|
||||
let g:loaded_easy_align = 1
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:easy_align_delimiters_default = {
|
||||
\ ' ': { 'pattern': ' ', 'left_margin': 0, 'right_margin': 0, 'stick_to_left': 0 },
|
||||
\ '=': { 'pattern': '===\|<=>\|\(&&\|||\|<<\|>>\)=\|=\~[#?]\?\|=>\|[:+/*!%^=><&|.-]\?=[#?]\?',
|
||||
\ '=': { 'pattern': '===\|<=>\|\(&&\|||\|<<\|>>\)=\|=\~[#?]\?\|=>\|[:+/*!%^=><&|.?-]\?=[#?]\?',
|
||||
\ 'left_margin': 1, 'right_margin': 1, 'stick_to_left': 0 },
|
||||
\ ':': { 'pattern': ':', 'left_margin': 0, 'right_margin': 1, 'stick_to_left': 1 },
|
||||
\ ',': { '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': '"\+', 'delimiter_align': 'l', 'ignore_groups': ['!Comment'] },
|
||||
\ '&': { 'pattern': '\\\@<!&\|\\\\',
|
||||
\ 'left_margin': 1, 'right_margin': 1, 'stick_to_left': 0 },
|
||||
\ '{': { 'pattern': '(\@<!{',
|
||||
@@ -47,7 +52,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 = {
|
||||
@@ -61,12 +67,13 @@ 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("*strwidth")
|
||||
if exists("*strdisplaywidth")
|
||||
function! s:strwidth(str)
|
||||
return strwidth(a:str) + len(matchstr(a:str, '^\t*')) * (&tabstop - 1)
|
||||
return strdisplaywidth(a:str)
|
||||
endfunction
|
||||
else
|
||||
function! s:strwidth(str)
|
||||
@@ -74,11 +81,44 @@ else
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:ceil2(v)
|
||||
return a:v % 2 == 0 ? a:v : a:v + 1
|
||||
endfunction
|
||||
|
||||
function! s:floor2(v)
|
||||
return a:v % 2 == 0 ? a:v : a:v - 1
|
||||
endfunction
|
||||
|
||||
function! s:get_highlight_group_name(line, col)
|
||||
let hl = synIDattr(synID(a:line, a:col, 0), 'name')
|
||||
|
||||
if hl == '' && has('nvim-0.9.0')
|
||||
let insp = luaeval('vim.inspect_pos and vim.inspect_pos( nil, ' .. (a:line-1) .. ', ' .. (a:col-1) .. ' ) or { treesitter = {} }')
|
||||
if !empty(insp.treesitter)
|
||||
let hl = insp.treesitter[0].hl_group_link
|
||||
endif
|
||||
endif
|
||||
|
||||
" and, finally
|
||||
return hl
|
||||
endfunction
|
||||
|
||||
function! easy_align#get_highlight_group_name(...)
|
||||
let l = get(a:, 1, line('.'))
|
||||
let c = get(a:, 2, col('.'))
|
||||
let hl = s:get_highlight_group_name(l, c)
|
||||
return { 'line': l, 'column': c, 'group': hl }
|
||||
endfunction
|
||||
|
||||
function! s:highlighted_as(line, col, groups)
|
||||
if empty(a:groups) | return 0 | endif
|
||||
let hl = synIDattr(synID(a:line, a:col, 0), 'name')
|
||||
let hl = s:get_highlight_group_name(a:line, a:col)
|
||||
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
|
||||
@@ -128,7 +168,7 @@ endfunction
|
||||
|
||||
function! s:echon(l, n, r, d, o, warn)
|
||||
let tokens = [
|
||||
\ ['Function', ':EasyAlign'],
|
||||
\ ['Function', s:live ? ':LiveEasyAlign' : ':EasyAlign'],
|
||||
\ ['ModeMsg', get(s:mode_labels, a:l, a:l)],
|
||||
\ ['None', ' ']]
|
||||
|
||||
@@ -211,8 +251,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
|
||||
@@ -245,11 +286,8 @@ function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left,
|
||||
\ strpart(getline(a:line), a:fc - 1, a:lc - a:fc + 1) :
|
||||
\ strpart(getline(a:line), a:fc - 1)
|
||||
let idx = 0
|
||||
" Do not allow \zs
|
||||
" 1: whole match
|
||||
" 2: token
|
||||
" 3: delimiter
|
||||
let pattern = '^\(\(.\{-}\s*\)\(' .a:pattern. '\)\s' . (a:stick_to_left ? '*' : '\{-}') . '\)'
|
||||
let nomagic = match(a:pattern, '\\v') > match(a:pattern, '\C\\[mMV]')
|
||||
let pattern = '^.\{-}\s*\zs\('.a:pattern.(nomagic ? ')' : '\)')
|
||||
let tokens = []
|
||||
let delims = []
|
||||
|
||||
@@ -258,18 +296,22 @@ function! s:split_line(line, nth, modes, cycle, fc, lc, pattern, stick_to_left,
|
||||
let token = ''
|
||||
let phantom = 0
|
||||
while 1
|
||||
let matches = matchlist(string, pattern, idx)
|
||||
let matchidx = match(string, pattern, idx)
|
||||
" No match
|
||||
if empty(matches) | break | endif
|
||||
if matchidx < 0 | break | endif
|
||||
let matchend = matchend(string, pattern, idx)
|
||||
let spaces = matchstr(string, '\s'.(a:stick_to_left ? '*' : '\{-}'), matchend + (matchidx == matchend))
|
||||
|
||||
" Match, but empty delimiter
|
||||
if empty(matches[1])
|
||||
" Match, but empty
|
||||
if len(spaces) + matchend - idx == 0
|
||||
let char = strpart(string, idx, 1)
|
||||
if empty(char) | break | endif
|
||||
let [match, part, delim] = [char, char, '']
|
||||
" Match
|
||||
else
|
||||
let [match, part, delim] = matches[1 : 3]
|
||||
let match = strpart(string, idx, matchend - idx + len(spaces))
|
||||
let part = strpart(string, idx, matchidx - idx)
|
||||
let delim = strpart(string, matchidx, matchend - matchidx)
|
||||
endif
|
||||
|
||||
let ignorable = s:highlighted_as(a:line, idx + len(part) + a:fc, a:ignore_groups)
|
||||
@@ -332,16 +374,17 @@ function! s:do_align(todo, modes, all_tokens, all_delims, fl, ll, fc, lc, nth, r
|
||||
let mode = a:modes[0]
|
||||
let lines = {}
|
||||
let min_indent = -1
|
||||
let max = { 'pivot_len': 0.0, 'token_len': 0, 'just_len': 0, 'delim_len': 0,
|
||||
let max = { 'pivot_len2': 0, 'token_len': 0, 'just_len': 0, 'delim_len': 0,
|
||||
\ 'indent': 0, 'tokens': 0, 'strip_len': 0 }
|
||||
let d = a:dict
|
||||
let [f, fx] = s:parse_filter(d.filter)
|
||||
|
||||
" Phase 1
|
||||
for line in range(a:fl, a:ll)
|
||||
if f == 1 && getline(line) !~ fx
|
||||
let snip = a:lc > 0 ? getline(line)[a:fc-1 : a:lc-1] : getline(line)
|
||||
if f == 1 && snip !~ fx
|
||||
continue
|
||||
elseif f == -1 && getline(line) =~ fx
|
||||
elseif f == -1 && snip =~ fx
|
||||
continue
|
||||
endif
|
||||
|
||||
@@ -410,8 +453,9 @@ function! s:do_align(todo, modes, all_tokens, all_delims, fl, ll, fc, lc, nth, r
|
||||
let max.delim_len = max([max.delim_len, s:strwidth(delim)])
|
||||
|
||||
if mode ==? 'c'
|
||||
if max.pivot_len < pw + tw / 2.0
|
||||
let max.pivot_len = pw + tw / 2.0
|
||||
let pivot_len2 = pw * 2 + tw
|
||||
if max.pivot_len2 < pivot_len2
|
||||
let max.pivot_len2 = pivot_len2
|
||||
endif
|
||||
let max.strip_len = max([max.strip_len, s:strwidth(s:trim(token))])
|
||||
endif
|
||||
@@ -432,9 +476,9 @@ function! s:do_align(todo, modes, all_tokens, all_delims, fl, ll, fc, lc, nth, r
|
||||
end
|
||||
|
||||
if idt !=? 'k'
|
||||
let max.just_len = 0
|
||||
let max.token_len = 0
|
||||
let max.pivot_len = 0
|
||||
let max.just_len = 0
|
||||
let max.token_len = 0
|
||||
let max.pivot_len2 = 0
|
||||
|
||||
for [line, elems] in items(lines)
|
||||
let [nth, prefix, token, delim] = elems
|
||||
@@ -460,8 +504,9 @@ function! s:do_align(todo, modes, all_tokens, all_delims, fl, ll, fc, lc, nth, r
|
||||
let max.token_len = max([max.token_len, tw])
|
||||
let max.just_len = max([max.just_len, pw + tw])
|
||||
if mode ==? 'c'
|
||||
if max.pivot_len < pw + tw / 2.0
|
||||
let max.pivot_len = pw + tw / 2.0
|
||||
let pivot_len2 = pw * 2 + tw
|
||||
if max.pivot_len2 < pivot_len2
|
||||
let max.pivot_len2 = pivot_len2
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -496,15 +541,15 @@ function! s:do_align(todo, modes, all_tokens, all_delims, fl, ll, fc, lc, nth, r
|
||||
let indent = matchstr(token, '^\s*')
|
||||
let token = indent . pad . s:ltrim(token)
|
||||
elseif mode ==? 'c'
|
||||
let p1 = max.pivot_len - (pw + tw / 2.0)
|
||||
let p2 = (max.token_len - tw) / 2.0
|
||||
let pf1 = floor(p1)
|
||||
if pf1 < p1 | let p2 = ceil(p2)
|
||||
else | let p2 = floor(p2)
|
||||
let p1 = max.pivot_len2 - (pw * 2 + tw)
|
||||
let p2 = max.token_len - tw
|
||||
let pf1 = s:floor2(p1)
|
||||
if pf1 < p1 | let p2 = s:ceil2(p2)
|
||||
else | let p2 = s:floor2(p2)
|
||||
endif
|
||||
let strip = float2nr(ceil((max.token_len - max.strip_len) / 2.0))
|
||||
let strip = s:ceil2(max.token_len - max.strip_len) / 2
|
||||
let indent = matchstr(token, '^\s*')
|
||||
let token = indent. repeat(' ', float2nr(pf1)) .s:ltrim(token). repeat(' ', float2nr(p2))
|
||||
let token = indent. repeat(' ', pf1 / 2) .s:ltrim(token). repeat(' ', p2 / 2)
|
||||
let token = substitute(token, repeat(' ', strip) . '$', '', '')
|
||||
|
||||
if d.stick_to_left
|
||||
@@ -596,7 +641,7 @@ function! s:shift_opts(opts, key, vals)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
||||
function! s:interactive(range, modes, n, d, opts, rules, vis, bvis)
|
||||
let mode = s:shift(a:modes, 1)
|
||||
let n = a:n
|
||||
let d = a:d
|
||||
@@ -615,11 +660,11 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
||||
let undo = 0
|
||||
let rdrw = 1
|
||||
endif
|
||||
if a:live && !empty(d)
|
||||
let output = s:process(a:range, mode, n, d, s:normalize_options(opts), regx, a:rules, 0)
|
||||
if s:live && !empty(d)
|
||||
let output = s:process(a:range, mode, n, d, s:normalize_options(opts), regx, a:rules, a:bvis)
|
||||
let &undolevels = &undolevels " Break undo block
|
||||
call s:update_lines(output.todo)
|
||||
let undo = 1
|
||||
let undo = !empty(output.todo)
|
||||
let rdrw = 1
|
||||
endif
|
||||
if rdrw
|
||||
@@ -634,7 +679,11 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
||||
let check = 0
|
||||
let warn = ''
|
||||
|
||||
let c = getchar()
|
||||
try
|
||||
let c = getchar()
|
||||
catch /^Vim:Interrupt$/
|
||||
let c = 27
|
||||
endtry
|
||||
let ch = nr2char(c)
|
||||
if c == 3 || c == 27 " CTRL-C / ESC
|
||||
if undo
|
||||
@@ -650,8 +699,8 @@ 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')
|
||||
let opts.m = mode . strpart(opts.m, 1)
|
||||
if has_key(opts, 'a')
|
||||
let opts.a = mode . strpart(opts.a, 1)
|
||||
endif
|
||||
elseif ch == '-'
|
||||
if empty(n) | let n = '-'
|
||||
@@ -692,6 +741,17 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
||||
call s:shift_opts(opts, 'iu', vals['ignore_unmatched'])
|
||||
elseif ch == "\<C-G>"
|
||||
call s:shift_opts(opts, 'ig', vals['ignore_groups'])
|
||||
elseif ch == "\<C-P>"
|
||||
if s:live
|
||||
if !empty(d)
|
||||
let ch = d
|
||||
break
|
||||
else
|
||||
let s:live = 0
|
||||
endif
|
||||
else
|
||||
let s:live = 1
|
||||
endif
|
||||
elseif c == "\<Left>"
|
||||
let opts['stl'] = 1
|
||||
let opts['lm'] = 0
|
||||
@@ -705,18 +765,18 @@ 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)
|
||||
if s:live && regx && !empty(d)
|
||||
break
|
||||
endif
|
||||
|
||||
@@ -725,7 +785,7 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
||||
if !empty(ch) && s:valid_regexp(ch)
|
||||
let regx = 1
|
||||
let d = ch
|
||||
if !a:live | break | endif
|
||||
if !s:live | break | endif
|
||||
else
|
||||
let warn = 'Invalid regular expression: '.ch
|
||||
endif
|
||||
@@ -749,7 +809,10 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
||||
if empty(d)
|
||||
if has_key(a:rules, ch)
|
||||
let d = ch
|
||||
if !a:live
|
||||
if !s:live
|
||||
if a:vis
|
||||
execute "normal! gv\<esc>"
|
||||
endif
|
||||
break
|
||||
endif
|
||||
else
|
||||
@@ -768,9 +831,11 @@ function! s:interactive(range, modes, n, d, opts, rules, vis, live)
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
if a:live
|
||||
if s:live
|
||||
let copts = call('s:summarize', output.summarize)
|
||||
let s:live = 0
|
||||
let g:easy_align_last_command = s:echon('', n, regx, d, copts, '')
|
||||
let s:live = 1
|
||||
end
|
||||
return [mode, n, ch, opts, regx]
|
||||
endfunction
|
||||
@@ -785,16 +850,17 @@ function! s:valid_regexp(regexp)
|
||||
endfunction
|
||||
|
||||
function! s:test_regexp(regexp)
|
||||
if !s:valid_regexp(a:regexp)
|
||||
call s:exit('Invalid regular expression: '. a:regexp)
|
||||
let regexp = empty(a:regexp) ? @/ : a:regexp
|
||||
if !s:valid_regexp(regexp)
|
||||
call s:exit('Invalid regular expression: '. regexp)
|
||||
endif
|
||||
return a:regexp
|
||||
return regexp
|
||||
endfunction
|
||||
|
||||
let s:shorthand_regex =
|
||||
\ '\s*\%('
|
||||
\ .'\(lm\?[0-9]\+\)\|\(rm\?[0-9]\+\)\|\(iu[01]\)\|\(s\%(tl\)\?[01]\)\|'
|
||||
\ .'\(da\?[clr]\)\|\(ms\?[lrc*]\+\)\|\(i\%(dt\)\?[kdsn]\)\|\([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)
|
||||
@@ -808,9 +874,8 @@ function! s:parse_shorthand_opts(expr)
|
||||
call s:exit("Invalid expression: ". a:expr)
|
||||
else
|
||||
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
|
||||
@@ -819,7 +884,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
|
||||
@@ -832,6 +897,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
|
||||
@@ -937,9 +1004,9 @@ function! s:alternating_modes(mode)
|
||||
endfunction
|
||||
|
||||
function! s:update_lines(todo)
|
||||
for [line, content] in items(a:todo)
|
||||
call setline(line, s:rtrim(content))
|
||||
endfor
|
||||
for [line, content] in items(a:todo)
|
||||
call setline(line, s:rtrim(content))
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:parse_nth(n)
|
||||
@@ -1004,22 +1071,21 @@ function! s:build_mode_sequence(expr, recur)
|
||||
endfunction
|
||||
|
||||
function! s:process(range, mode, n, ch, opts, regexp, rules, bvis)
|
||||
let [nth, recur] = s:parse_nth(a:n)
|
||||
let [nth, recur] = s:parse_nth((empty(a:n) && exists('g:easy_align_nth')) ? g:easy_align_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
|
||||
call s:exit('Recursive alignment is not supported in blockwise-visual mode')
|
||||
endif
|
||||
|
||||
let ve = &virtualedit
|
||||
set ve=all
|
||||
let args = [
|
||||
\ {}, split(mode_sequence, '\zs'),
|
||||
\ {}, {}, a:range[0], a:range[1],
|
||||
\ a:bvis ? min([col("'<"), col("'>")]) : 1,
|
||||
\ a:bvis ? max([col("'<"), col("'>")]) : 0,
|
||||
\ a:bvis ? min([virtcol("'<"), virtcol("'>")]) : 1,
|
||||
\ (!recur && a:bvis) ? max([virtcol("'<"), virtcol("'>")]) : 0,
|
||||
\ nth, recur, dict ]
|
||||
let &ve = ve
|
||||
while len(args) > 1
|
||||
let args = call('s:do_align', args)
|
||||
endwhile
|
||||
@@ -1032,26 +1098,31 @@ 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
|
||||
|
||||
function! s:align(bang, live, first_line, last_line, expr)
|
||||
function! s:align(bang, live, visualmode, first_line, last_line, expr)
|
||||
" Heuristically determine if the user was in visual mode
|
||||
let vis = a:first_line == line("'<") && a:last_line == line("'>")
|
||||
let bvis = vis && char2nr(visualmode()) == 22 " ^V
|
||||
if a:visualmode == 'command'
|
||||
let vis = a:first_line == line("'<") && a:last_line == line("'>")
|
||||
let bvis = vis && visualmode() == "\<C-V>"
|
||||
elseif empty(a:visualmode)
|
||||
let vis = 0
|
||||
let bvis = 0
|
||||
else
|
||||
let vis = 1
|
||||
let bvis = a:visualmode == "\<C-V>"
|
||||
end
|
||||
let range = [a:first_line, a:last_line]
|
||||
let modes = s:interactive_modes(a:bang)
|
||||
let mode = modes[0]
|
||||
|
||||
if bvis && a:live
|
||||
call s:exit('Live mode is not supported in blockwise-visual mode')
|
||||
endif
|
||||
let s:live = a:live
|
||||
|
||||
let rules = s:easy_align_delimiters_default
|
||||
if exists('g:easy_align_delimiters')
|
||||
@@ -1065,11 +1136,11 @@ function! s:align(bang, live, first_line, last_line, expr)
|
||||
try
|
||||
if bypass_fold | let &l:foldmethod = 'manual' | endif
|
||||
|
||||
if empty(n) && empty(ch) || a:live
|
||||
let [mode, n, ch, opts, regexp] = s:interactive(range, copy(modes), n, ch, opts, rules, vis, a:live)
|
||||
if empty(n) && empty(ch) || s:live
|
||||
let [mode, n, ch, opts, regexp] = s:interactive(range, copy(modes), n, ch, opts, rules, vis, bvis)
|
||||
endif
|
||||
|
||||
if !a:live
|
||||
if !s:live
|
||||
let output = s:process(range, mode, n, ch, s:normalize_options(opts), regexp, rules, bvis)
|
||||
call s:update_lines(output.todo)
|
||||
let copts = call('s:summarize', output.summarize)
|
||||
@@ -1080,10 +1151,20 @@ function! s:align(bang, live, first_line, last_line, expr)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! easy_align#align(bang, live, expr) range
|
||||
function! easy_align#align(bang, live, visualmode, expr) range
|
||||
try
|
||||
call s:align(a:bang, a:live, a:firstline, a:lastline, a:expr)
|
||||
catch 'exit'
|
||||
call s:align(a:bang, a:live, a:visualmode, a:firstline, a:lastline, a:expr)
|
||||
catch /^\%(Vim:Interrupt\|exit\)$/
|
||||
if empty(a:visualmode)
|
||||
echon "\r"
|
||||
echon "\r"
|
||||
else
|
||||
normal! gv
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
" vim: set et sw=2 :
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
" Copyright (c) 2013 Junegunn Choi
|
||||
" Copyright (c) 2014 Junegunn Choi
|
||||
"
|
||||
" MIT License
|
||||
"
|
||||
@@ -26,5 +26,118 @@ if exists("g:loaded_easy_align_plugin")
|
||||
endif
|
||||
let g:loaded_easy_align_plugin = 1
|
||||
|
||||
command! -nargs=* -range -bang EasyAlign <line1>,<line2>call easy_align#align('<bang>' == '!', 0, <q-args>)
|
||||
command! -nargs=* -range -bang LiveEasyAlign <line1>,<line2>call easy_align#align('<bang>' == '!', 1, <q-args>)
|
||||
command! -nargs=* -range -bang EasyAlign <line1>,<line2>call easy_align#align(<bang>0, 0, 'command', <q-args>)
|
||||
command! -nargs=* -range -bang LiveEasyAlign <line1>,<line2>call easy_align#align(<bang>0, 1, 'command', <q-args>)
|
||||
|
||||
let s:last_command = 'EasyAlign'
|
||||
|
||||
function! s:abs(v)
|
||||
return a:v >= 0 ? a:v : - a:v
|
||||
endfunction
|
||||
|
||||
function! s:remember_visual(mode)
|
||||
let s:last_visual = [a:mode, s:abs(line("'>") - line("'<")), s:abs(col("'>") - col("'<"))]
|
||||
endfunction
|
||||
|
||||
function! s:repeat_visual()
|
||||
let [mode, ldiff, cdiff] = s:last_visual
|
||||
let cmd = 'normal! '.mode
|
||||
if ldiff > 0
|
||||
let cmd .= ldiff . 'j'
|
||||
endif
|
||||
|
||||
let ve_save = &virtualedit
|
||||
try
|
||||
if mode == "\<C-V>"
|
||||
if cdiff > 0
|
||||
let cmd .= cdiff . 'l'
|
||||
endif
|
||||
set virtualedit+=block
|
||||
endif
|
||||
execute cmd.":\<C-r>=g:easy_align_last_command\<Enter>\<Enter>"
|
||||
call s:set_repeat()
|
||||
finally
|
||||
if ve_save != &virtualedit
|
||||
let &virtualedit = ve_save
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:repeat_in_visual()
|
||||
if exists('g:easy_align_last_command')
|
||||
call s:remember_visual(visualmode())
|
||||
call s:repeat_visual()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:set_repeat()
|
||||
silent! call repeat#set("\<Plug>(EasyAlignRepeat)")
|
||||
endfunction
|
||||
|
||||
function! s:generic_easy_align_op(type, vmode, live)
|
||||
if !&modifiable
|
||||
if a:vmode
|
||||
normal! gv
|
||||
endif
|
||||
return
|
||||
endif
|
||||
let sel_save = &selection
|
||||
let &selection = "inclusive"
|
||||
|
||||
if a:vmode
|
||||
let vmode = a:type
|
||||
let [l1, l2] = ["'<", "'>"]
|
||||
call s:remember_visual(vmode)
|
||||
else
|
||||
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 range . g:easy_align_last_command
|
||||
else
|
||||
execute range . "call easy_align#align(0, a:live, vmode, '')"
|
||||
end
|
||||
call s:set_repeat()
|
||||
finally
|
||||
let &selection = sel_save
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:easy_align_op(type, ...)
|
||||
call s:generic_easy_align_op(a:type, a:0, 0)
|
||||
endfunction
|
||||
|
||||
function! s:live_easy_align_op(type, ...)
|
||||
call s:generic_easy_align_op(a:type, a:0, 1)
|
||||
endfunction
|
||||
|
||||
function! s:easy_align_repeat()
|
||||
if exists('s:last_visual')
|
||||
call s:repeat_visual()
|
||||
else
|
||||
try
|
||||
let g:easy_align_need_repeat = 1
|
||||
normal! .
|
||||
finally
|
||||
unlet! g:easy_align_need_repeat
|
||||
endtry
|
||||
endif
|
||||
endfunction
|
||||
|
||||
nnoremap <silent> <Plug>(EasyAlign) :set opfunc=<SID>easy_align_op<Enter>g@
|
||||
vnoremap <silent> <Plug>(EasyAlign) :<C-U>call <SID>easy_align_op(visualmode(), 1)<Enter>
|
||||
nnoremap <silent> <Plug>(LiveEasyAlign) :set opfunc=<SID>live_easy_align_op<Enter>g@
|
||||
vnoremap <silent> <Plug>(LiveEasyAlign) :<C-U>call <SID>live_easy_align_op(visualmode(), 1)<Enter>
|
||||
|
||||
" vim-repeat support
|
||||
nnoremap <silent> <Plug>(EasyAlignRepeat) :call <SID>easy_align_repeat()<Enter>
|
||||
vnoremap <silent> <Plug>(EasyAlignRepeat) :<C-U>call <SID>repeat_in_visual()<Enter>
|
||||
|
||||
" Backward-compatibility (deprecated)
|
||||
nnoremap <silent> <Plug>(EasyAlignOperator) :set opfunc=<SID>easy_align_op<Enter>g@
|
||||
|
||||
" vim: set et sw=2 :
|
||||
|
||||
@@ -7,7 +7,7 @@ Test cases for vim-easy-align
|
||||
|
||||
### Run
|
||||
|
||||
```vim
|
||||
:Vader*
|
||||
```
|
||||
./run
|
||||
```
|
||||
|
||||
|
||||
22
test/blockwise.vader
Normal file
22
test/blockwise.vader
Normal file
@@ -0,0 +1,22 @@
|
||||
Include: include/setup.vader
|
||||
|
||||
Given clojure:
|
||||
(def world [[1 1 1 1 1]
|
||||
[999 999 999 999 1]
|
||||
[1 1 1 1 1]
|
||||
[1 999 999 999 999]
|
||||
[1 1 1 1 1]])
|
||||
|
||||
Do (Recursive alignment in blockwise-visual mode):
|
||||
f[;
|
||||
\<C-V>G
|
||||
\<Enter>*\<Space>
|
||||
|
||||
Expect clojure:
|
||||
(def world [[1 1 1 1 1]
|
||||
[999 999 999 999 1]
|
||||
[1 1 1 1 1]
|
||||
[1 999 999 999 999]
|
||||
[1 1 1 1 1]])
|
||||
|
||||
Include: include/teardown.vader
|
||||
@@ -1,14 +1,4 @@
|
||||
Execute (Clean up test environment):
|
||||
Save g:easy_align_ignore_groups, g:easy_align_ignore_unmatched
|
||||
Save g:easy_align_indentation, g:easy_align_delimiter_align
|
||||
Save g:easy_align_interactive_modes, g:easy_align_bang_interactive_modes
|
||||
Save g:easy_align_delimiters
|
||||
|
||||
let g:easy_align_delimiters = {}
|
||||
silent! unlet g:easy_align_ignore_groups
|
||||
silent! unlet g:easy_align_ignore_unmatched
|
||||
silent! unlet g:easy_align_indentation
|
||||
silent! unlet g:easy_align_delimiter_align
|
||||
Include: include/setup.vader
|
||||
|
||||
Given (fruits):
|
||||
apple;:;;banana::cake
|
||||
@@ -50,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*
|
||||
|
||||
@@ -65,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
|
||||
|
||||
@@ -72,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':'>'}
|
||||
|
||||
@@ -86,6 +105,14 @@ Expect:
|
||||
ap><pl><e;><:;><;b><an><an><a:><:c><ak>e
|
||||
da><ta><;;><ex><ch><an><ge><:;><::><fo> <rm><at
|
||||
|
||||
Execute (Use current search pattern as delimiter if empty regular expression is given):
|
||||
/an
|
||||
%EasyAlign*//
|
||||
|
||||
Expect:
|
||||
apple;:;;b an an a::cake
|
||||
data;;exch an ge:;::format
|
||||
|
||||
Given javascript (json):
|
||||
var jdbc = {
|
||||
// JDBC driver for MySQL database:
|
||||
@@ -161,5 +188,4 @@ Expect javascript:
|
||||
"user: pass": "r00t: pa55"
|
||||
};
|
||||
|
||||
Execute:
|
||||
Restore
|
||||
Include: include/teardown.vader
|
||||
|
||||
13
test/extra.vader
Normal file
13
test/extra.vader
Normal file
@@ -0,0 +1,13 @@
|
||||
Include: include/setup.vader
|
||||
|
||||
Before:
|
||||
set nomodifiable
|
||||
After:
|
||||
set modifiable
|
||||
AssertEqual "hello\nworld\n", @"
|
||||
Given:
|
||||
hello
|
||||
world
|
||||
Do (#43 Do nothing when nomodifiable):
|
||||
vip\<enter>\<enter>\<enter>y
|
||||
|
||||
147
test/fixed.vader
147
test/fixed.vader
@@ -1,5 +1,4 @@
|
||||
Execute:
|
||||
Save &tabstop
|
||||
Include: include/setup.vader
|
||||
|
||||
Given (Table):
|
||||
|a|b|c|d|
|
||||
@@ -118,5 +117,147 @@ Expect:
|
||||
n2gv = {}
|
||||
n2vt = {}
|
||||
|
||||
Given (Tab-indented code (#20)):
|
||||
class MyUnitTest(unittest.TestCase):
|
||||
def test_base(self):
|
||||
# n2f= {}
|
||||
## n2v= {}
|
||||
# f2v = {}
|
||||
## n2gv = {}
|
||||
# n2vt = {}
|
||||
|
||||
Execute:
|
||||
Restore
|
||||
set tabstop=12
|
||||
%EasyAlign=
|
||||
|
||||
Expect:
|
||||
class MyUnitTest(unittest.TestCase):
|
||||
def test_base(self):
|
||||
# n2f = {}
|
||||
## n2v = {}
|
||||
# f2v = {}
|
||||
## 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
|
||||
|
||||
Given c (#40 Ignored delimiters in LiveEasyAlign causes spurious undo):
|
||||
printf("foo = %f\n", foo);
|
||||
printf("foobar = %f\n", foobar);
|
||||
|
||||
Do:
|
||||
gUiw
|
||||
:%LiveEasyAlign\<enter>
|
||||
=\<bs>==
|
||||
|
||||
Expect c:
|
||||
PRINTF("foo = %f\n", foo);
|
||||
printf("foobar = %f\n", foobar);
|
||||
|
||||
* #50 Error when using delimiter alignment option
|
||||
Given:
|
||||
a|bbb|c
|
||||
aa|bb|cc
|
||||
|
||||
Do (#50 EasyAlign command with 'a' option):
|
||||
:%EasyAlign {'a': 'l'}\<cr>
|
||||
\<cr>
|
||||
*|
|
||||
|
||||
Expect (Some text):
|
||||
a | bbb | c
|
||||
aa | bb | cc
|
||||
|
||||
* #51 Repeat of visual <Plug>(LiveEasyAlign) broken
|
||||
Do (#51/#52 <Plug>(EasyAlignRepeat) in visual mode):
|
||||
V\<space>\<enter>\<enter>*||
|
||||
G
|
||||
V\<space>.
|
||||
|
||||
Expect:
|
||||
a | bbb | c
|
||||
aa | bb | cc
|
||||
|
||||
* #65 ?=
|
||||
Given:
|
||||
a?=b
|
||||
aa-=bb
|
||||
aaa?=bbb
|
||||
|
||||
Do (#65 Alignment around ?=):
|
||||
\<space>Aip=
|
||||
|
||||
Expect:
|
||||
a ?= b
|
||||
aa -= bb
|
||||
aaa ?= bbb
|
||||
|
||||
* #67 \v
|
||||
Given c:
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(SERV_PORT);
|
||||
|
||||
Execute (#67 \v breaks surrounding regex):
|
||||
%EasyAlign/\v(\=\s)@<=</
|
||||
|
||||
Expect:
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(SERV_PORT);
|
||||
|
||||
Execute (#67 \V followed by \v shouldn't matter):
|
||||
%EasyAlign/\v(\=\s)@<=<\V/
|
||||
|
||||
Expect:
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(SERV_PORT);
|
||||
|
||||
Execute (#67 \zs is now allowed):
|
||||
%EasyAlign/=\zs/
|
||||
|
||||
Expect:
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(SERV_PORT);
|
||||
|
||||
Include: include/teardown.vader
|
||||
|
||||
Given:
|
||||
hello = world bye all
|
||||
hello world = bye all
|
||||
hello world = foo all
|
||||
|
||||
Do (#105: Incorrectly detection of blockwise visual mode):
|
||||
\<c-v>jj\<esc>
|
||||
\<Space>Aip=
|
||||
|
||||
Expect:
|
||||
hello = world bye all
|
||||
hello world = bye all
|
||||
hello world = foo all
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
Include: include/setup.vader
|
||||
|
||||
# It is currently possible that EasyAlign command incorrectly judges
|
||||
# that it was executed in block-wise visual mode
|
||||
Given:
|
||||
@@ -18,3 +20,5 @@ Do (TODO Workaround: reset visualmode() on error):
|
||||
Expect:
|
||||
a | b | c
|
||||
|
||||
Include: include/teardown.vader
|
||||
|
||||
|
||||
38
test/include/setup.vader
Normal file
38
test/include/setup.vader
Normal file
@@ -0,0 +1,38 @@
|
||||
Execute (Clean up test environment):
|
||||
Save g:easy_align_ignore_groups, g:easy_align_ignore_unmatched
|
||||
Save g:easy_align_indentation, g:easy_align_delimiter_align
|
||||
Save g:easy_align_interactive_modes, g:easy_align_bang_interactive_modes
|
||||
Save g:easy_align_delimiters, g:easy_align_bypass_fold
|
||||
Save &tabstop, mapleader
|
||||
|
||||
unlet! g:easy_align_ignore_groups
|
||||
unlet! g:easy_align_ignore_unmatched
|
||||
unlet! g:easy_align_indentation
|
||||
unlet! g:easy_align_delimiter_align
|
||||
unlet! g:easy_align_interactive_modes
|
||||
unlet! g:easy_align_bang_interactive_modes
|
||||
unlet! g:easy_align_bypass_fold
|
||||
|
||||
let g:easy_align_delimiters = {}
|
||||
let mapleader = ' '
|
||||
vnoremap <silent> r<Enter> :EasyAlign!<Enter>
|
||||
vnoremap <silent> <Leader>r<Enter> :LiveEasyAlign!<Enter>
|
||||
|
||||
" " Legacy
|
||||
" vnoremap <silent> <Enter> :EasyAlign<Enter>
|
||||
" vnoremap <silent> <Leader><Enter> :LiveEasyAlign<Enter>
|
||||
" nmap <leader>A <Plug>(EasyAlignOperator)
|
||||
|
||||
set ts=2
|
||||
|
||||
vmap <Enter> <Plug>(EasyAlign)
|
||||
vmap <leader><Enter> <Plug>(LiveEasyAlign)
|
||||
nmap <leader>A <Plug>(EasyAlign)
|
||||
vmap <leader>. <Plug>(EasyAlignRepeat)
|
||||
|
||||
silent! call plug#load('vim-easy-align')
|
||||
|
||||
Before:
|
||||
After:
|
||||
Given:
|
||||
|
||||
4
test/include/teardown.vader
Normal file
4
test/include/teardown.vader
Normal file
@@ -0,0 +1,4 @@
|
||||
Given:
|
||||
Execute (Restoring test environment):
|
||||
Restore
|
||||
|
||||
@@ -1,24 +1,4 @@
|
||||
Execute (Clean up test environment):
|
||||
Save g:easy_align_ignore_groups, g:easy_align_ignore_unmatched
|
||||
Save g:easy_align_indentation, g:easy_align_delimiter_align
|
||||
Save g:easy_align_interactive_modes, g:easy_align_bang_interactive_modes
|
||||
Save g:easy_align_delimiters, &tabstop
|
||||
Save mapleader
|
||||
|
||||
" TODO: revert after test
|
||||
silent! unlet g:easy_align_ignore_groups
|
||||
silent! unlet g:easy_align_ignore_unmatched
|
||||
silent! unlet g:easy_align_indentation
|
||||
silent! unlet g:easy_align_delimiter_align
|
||||
silent! unlet g:easy_align_interactive_modes
|
||||
silent! unlet g:easy_align_bang_interactive_modes
|
||||
|
||||
let g:easy_align_delimiters = {}
|
||||
let mapleader = ' '
|
||||
vnoremap <silent> <Enter> :EasyAlign<Enter>
|
||||
vnoremap <silent> r<Enter> :EasyAlign!<Enter>
|
||||
vnoremap <silent> <Leader><Enter> :LiveEasyAlign<Enter>
|
||||
vnoremap <silent> <Leader>r<Enter> :LiveEasyAlign!<Enter>
|
||||
Include: include/setup.vader
|
||||
|
||||
###########################################################
|
||||
|
||||
@@ -39,6 +19,26 @@ Expect:
|
||||
111 22 333 444 55555 6666 7 88888
|
||||
1111 2 33 444 555 66 777 8
|
||||
|
||||
Do (left-align / cursor position retained):
|
||||
vGww
|
||||
\<Enter>
|
||||
*\<Space>D
|
||||
|
||||
Expect:
|
||||
1 22222 33 444 555 6666 7 888
|
||||
11 222 3333 4 55 6666 77 888
|
||||
111 22 333 444 55555 6666 7 88888
|
||||
1111 2
|
||||
|
||||
Do (left-align using operator map):
|
||||
\<Space>Aip*\<Space>
|
||||
|
||||
Expect:
|
||||
1 22222 33 444 555 6666 7 888
|
||||
11 222 3333 4 55 6666 77 888
|
||||
111 22 333 444 55555 6666 7 88888
|
||||
1111 2 33 444 555 66 777 8
|
||||
|
||||
Do (right-align):
|
||||
vip
|
||||
\<Enter>\<Enter>
|
||||
@@ -496,6 +496,56 @@ Expect:
|
||||
|)batch_size(|) Fixnum(|)nil (|)number of maximum items to be assigned at once(|
|
||||
|)logger (|) Logger(|)nil (|) logger instance for debug logs(|
|
||||
|
||||
Do (Switching to live interactive mode):
|
||||
vip\<Enter>
|
||||
* Switch to live interactive mode
|
||||
\<C-P>
|
||||
|
|
||||
\<C-L><\<Enter>
|
||||
\<C-R>>\<Enter>
|
||||
***
|
||||
**
|
||||
\<BS>\<BS>\<BS>
|
||||
**|\<Enter>|
|
||||
|
||||
Expect:
|
||||
|>Option <|> Type<|>Default<|> Description<|
|
||||
|>-- <|> --<|>-- <|> --<|
|
||||
|>threads <|> Fixnum<|>1 <|> number of threads in the thread pool<|
|
||||
|>queues <|> Fixnum<|>1 <|> number of concurrent queues<|
|
||||
|>queue_size<|> Fixnum<|>1000 <|> size of each queue<|
|
||||
|>interval <|>Numeric<|>0 <|> dispatcher interval for batch processing<|
|
||||
|>batch <|>Boolean<|>false <|> enables batch processing mode<|
|
||||
|>batch_size<|> Fixnum<|>nil <|>number of maximum items to be assigned at once<|
|
||||
|>logger <|> Logger<|>nil <|> logger instance for debug logs<|
|
||||
|
||||
Do (Toggling live interactive mode (delimiter entered)):
|
||||
vip\<Enter>
|
||||
* Enable live mode
|
||||
\<C-P>
|
||||
|*
|
||||
* Disable live mode
|
||||
\<C-P>
|
||||
gg2jdG
|
||||
|
||||
Expect:
|
||||
| Option | Type | Default | Description |
|
||||
| -- | -- | -- | -- |
|
||||
|
||||
Do (Toggling live interactive mode (delimiter not entered)):
|
||||
vip\<Enter>
|
||||
* Enable live mode
|
||||
\<C-P>
|
||||
\<Enter>
|
||||
* Disable live mode
|
||||
\<C-P>
|
||||
*|
|
||||
gg2jdG
|
||||
|
||||
Expect:
|
||||
| Option | Type | Default | Description |
|
||||
| -- | -- | -- | -- |
|
||||
|
||||
Do (live interactive mode!):
|
||||
vip\<Space>r\<Enter>
|
||||
|
|
||||
@@ -531,6 +581,120 @@ Do:
|
||||
Execute (g:easy_align_last_command should not be set if interrupted):
|
||||
Assert !exists('g:easy_align_last_command')
|
||||
|
||||
Do (g:easy_align_nth is not set (work with default value 1)):
|
||||
vip\<Enter>|
|
||||
|
||||
Expect:
|
||||
| Option| Type | Default | Description |
|
||||
| --|--|--|--|
|
||||
| threads | Fixnum | 1 | number of threads in the thread pool |
|
||||
| queues |Fixnum | 1 | number of concurrent queues |
|
||||
| queue_size | Fixnum | 1000 | size of each queue |
|
||||
| interval | Numeric | 0 | dispatcher interval for batch processing |
|
||||
| batch | Boolean | false | enables batch processing mode |
|
||||
| batch_size | Fixnum | nil | number of maximum items to be assigned at once |
|
||||
| logger | Logger | nil | logger instance for debug logs |
|
||||
|
||||
Execute (set g:easy_align_nth):
|
||||
let g:easy_align_nth = '2'
|
||||
|
||||
Do (g:easy_align_nth is set as 2):
|
||||
vip\<Enter>|
|
||||
|
||||
Expect:
|
||||
| Option | Type | Default | Description |
|
||||
|-- | --|--|--|
|
||||
| threads | Fixnum | 1 | number of threads in the thread pool |
|
||||
|queues | Fixnum | 1 | number of concurrent queues |
|
||||
|queue_size | Fixnum | 1000 | size of each queue |
|
||||
| interval | Numeric | 0 | dispatcher interval for batch processing |
|
||||
|batch | Boolean | false | enables batch processing mode |
|
||||
|batch_size | Fixnum | nil | number of maximum items to be assigned at once |
|
||||
|logger | Logger | nil | logger instance for debug logs |
|
||||
|
||||
Execute (unset g:easy_align_nth):
|
||||
unlet g:easy_align_nth
|
||||
|
||||
Execute (set g:easy_align_nth):
|
||||
let g:easy_align_nth = '*'
|
||||
|
||||
Do (g:easy_align_nth is set as *):
|
||||
vip\<Enter>|
|
||||
|
||||
Expect:
|
||||
| Option | Type | Default | Description |
|
||||
| -- | -- | -- | -- |
|
||||
| threads | Fixnum | 1 | number of threads in the thread pool |
|
||||
| queues | Fixnum | 1 | number of concurrent queues |
|
||||
| queue_size | Fixnum | 1000 | size of each queue |
|
||||
| interval | Numeric | 0 | dispatcher interval for batch processing |
|
||||
| batch | Boolean | false | enables batch processing mode |
|
||||
| batch_size | Fixnum | nil | number of maximum items to be assigned at once |
|
||||
| logger | Logger | nil | logger instance for debug logs |
|
||||
|
||||
Execute (unset g:easy_align_nth):
|
||||
unlet g:easy_align_nth
|
||||
|
||||
Execute (set g:easy_align_nth):
|
||||
let g:easy_align_nth = '**'
|
||||
|
||||
Do (g:easy_align_nth is set as **):
|
||||
vip\<Enter>|
|
||||
|
||||
Expect:
|
||||
| Option | Type | Default | Description |
|
||||
| -- | -- | -- | -- |
|
||||
| threads | Fixnum | 1 | number of threads in the thread pool |
|
||||
| queues | Fixnum | 1 | number of concurrent queues |
|
||||
| queue_size | Fixnum | 1000 | size of each queue |
|
||||
| interval | Numeric | 0 | dispatcher interval for batch processing |
|
||||
| batch | Boolean | false | enables batch processing mode |
|
||||
| batch_size | Fixnum | nil | number of maximum items to be assigned at once |
|
||||
| logger | Logger | nil | logger instance for debug logs |
|
||||
|
||||
Execute (unset g:easy_align_nth):
|
||||
unlet g:easy_align_nth
|
||||
|
||||
Execute (set g:easy_align_nth):
|
||||
let g:easy_align_nth = '-'
|
||||
|
||||
Do (g:easy_align_nth is set as -):
|
||||
vip\<Enter>|
|
||||
|
||||
Expect:
|
||||
| Option| Type | Default | Description |
|
||||
|--|--|--|-- |
|
||||
| threads | Fixnum | 1 | number of threads in the thread pool |
|
||||
|queues |Fixnum | 1 | number of concurrent queues |
|
||||
|queue_size | Fixnum | 1000 | size of each queue |
|
||||
| interval | Numeric | 0 | dispatcher interval for batch processing |
|
||||
|batch | Boolean | false | enables batch processing mode |
|
||||
|batch_size | Fixnum | nil | number of maximum items to be assigned at once |
|
||||
|logger | Logger | nil | logger instance for debug logs |
|
||||
|
||||
Execute (unset g:easy_align_nth):
|
||||
unlet g:easy_align_nth
|
||||
|
||||
Execute (set g:easy_align_nth):
|
||||
let g:easy_align_nth = '-2'
|
||||
|
||||
Do (g:easy_align_nth is set as -2):
|
||||
vip\<Enter>|
|
||||
|
||||
Expect:
|
||||
| Option| Type | Default | Description |
|
||||
|--|--|-- | --|
|
||||
| threads | Fixnum | 1 | number of threads in the thread pool |
|
||||
|queues |Fixnum | 1 | number of concurrent queues |
|
||||
|queue_size | Fixnum | 1000 | size of each queue |
|
||||
| interval | Numeric | 0 | dispatcher interval for batch processing |
|
||||
|batch | Boolean | false | enables batch processing mode |
|
||||
|batch_size | Fixnum | nil | number of maximum items to be assigned at once |
|
||||
|logger | Logger | nil | logger instance for debug logs |
|
||||
|
||||
Execute (unset g:easy_align_nth):
|
||||
unlet g:easy_align_nth
|
||||
|
||||
###########################################################
|
||||
|
||||
Given (comma-separated items):
|
||||
@@ -769,7 +933,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:
|
||||
@@ -798,7 +962,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:
|
||||
@@ -827,6 +1021,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>
|
||||
@@ -904,10 +1127,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>#
|
||||
|
||||
@@ -1430,6 +1649,67 @@ Expect:
|
||||
bbbbb=bbbbb=bbbbb
|
||||
aaa = aaa = aaa
|
||||
|
||||
Given clojure (filter with blockwise-visual mode):
|
||||
(let [a 1
|
||||
bbb 2
|
||||
ccccc (range
|
||||
10 20)]
|
||||
(prn [a bbb ccccc]))
|
||||
|
||||
Do (filter with blockwise-visual mode):
|
||||
f[
|
||||
vi[
|
||||
\<C-V>
|
||||
\<Enter>
|
||||
\<C-F>g/^\S\<Enter>
|
||||
\<Space>
|
||||
|
||||
Expect clojure:
|
||||
(let [a 1
|
||||
bbb 2
|
||||
ccccc (range
|
||||
10 20)]
|
||||
(prn [a bbb ccccc]))
|
||||
|
||||
Given clojure:
|
||||
{:user {:plugins [[cider/cider-nrepl "0.9.1"]
|
||||
[lein-kibit "0.0.8"]
|
||||
[lein-licenses "0.1.1"]
|
||||
[lein-marginalia "0.8.0"] ; lein marg
|
||||
[codox "0.8.13"] ; lein doc
|
||||
[com.jakemccrary/lein-test-refresh "0.10.0"] ; lein test-refresh
|
||||
[lein-pprint "1.1.2"]
|
||||
[lein-exec "0.3.5"]
|
||||
[jonase/eastwood "0.2.1"]]
|
||||
:dependencies [[slamhound "1.5.5"]]
|
||||
:aliases {"slamhound" ["run" "-m" "slam.hound"]}
|
||||
:signing {:gpg-key "FEF9C627"}}}
|
||||
|
||||
Do (Virtual column should be used in blockwise-visual mode):
|
||||
:set ve=block\<Enter>
|
||||
f[
|
||||
vi[
|
||||
\<C-V>
|
||||
$20l
|
||||
\<Enter>\<Space>
|
||||
|
||||
Expect clojure:
|
||||
{:user {:plugins [[cider/cider-nrepl "0.9.1"]
|
||||
[lein-kibit "0.0.8"]
|
||||
[lein-licenses "0.1.1"]
|
||||
[lein-marginalia "0.8.0"] ; lein marg
|
||||
[codox "0.8.13"] ; lein doc
|
||||
[com.jakemccrary/lein-test-refresh "0.10.0"] ; lein test-refresh
|
||||
[lein-pprint "1.1.2"]
|
||||
[lein-exec "0.3.5"]
|
||||
[jonase/eastwood "0.2.1"]]
|
||||
:dependencies [[slamhound "1.5.5"]]
|
||||
:aliases {"slamhound" ["run" "-m" "slam.hound"]}
|
||||
:signing {:gpg-key "FEF9C627"}}}
|
||||
|
||||
Then:
|
||||
set ve=
|
||||
|
||||
###########################################################
|
||||
|
||||
Given (hard-tab indentation (#19)):
|
||||
@@ -1501,6 +1781,106 @@ Expect:
|
||||
'url': 'http://localhost:8090/display/TEST'}
|
||||
|
||||
###########################################################
|
||||
Execute:
|
||||
Restore
|
||||
|
||||
Given (Two paragraphs (requires vim-repeat)):
|
||||
a = 1
|
||||
bb = 2
|
||||
ccc = 3
|
||||
dddd = 4
|
||||
|
||||
d = 1
|
||||
cc = 2
|
||||
bbb = 3
|
||||
aaaa = 4
|
||||
_____ = 5
|
||||
|
||||
Do (Align and repeat):
|
||||
\<Space>Aip\<Enter>=
|
||||
6G
|
||||
.
|
||||
|
||||
Expect:
|
||||
a = 1
|
||||
bb = 2
|
||||
ccc = 3
|
||||
dddd = 4
|
||||
|
||||
d = 1
|
||||
cc = 2
|
||||
bbb = 3
|
||||
aaaa = 4
|
||||
_____ = 5
|
||||
|
||||
Do (Visual-mode operator is also repeatable):
|
||||
vip\<Enter>\<Enter>=
|
||||
6G
|
||||
.
|
||||
|
||||
Expect:
|
||||
a = 1
|
||||
bb = 2
|
||||
ccc = 3
|
||||
dddd = 4
|
||||
|
||||
d = 1
|
||||
cc = 2
|
||||
bbb = 3
|
||||
aaaa = 4
|
||||
_____ = 5
|
||||
|
||||
Do (Repeatable in visual mode):
|
||||
2GvG\<Space>.
|
||||
|
||||
Expect:
|
||||
a = 1
|
||||
bb = 2
|
||||
ccc = 3
|
||||
dddd = 4
|
||||
|
||||
d = 1
|
||||
cc = 2
|
||||
bbb = 3
|
||||
aaaa = 4
|
||||
_____ = 5
|
||||
|
||||
Given:
|
||||
:: a : 1
|
||||
:: bb : 2
|
||||
:: ccc : 3
|
||||
:: dd : 4
|
||||
:: e : 5
|
||||
|
||||
:: :: a:1
|
||||
:: :: b :2
|
||||
:: :: ccc : 3
|
||||
:: :: dd : 4
|
||||
:: :: e : 5
|
||||
:: :: f : 6
|
||||
|
||||
Do (Blockwise-visual-operator is also repeatable):
|
||||
fa
|
||||
\<C-V>
|
||||
f1
|
||||
4j
|
||||
\<Enter>:
|
||||
7G0
|
||||
fa
|
||||
.
|
||||
|
||||
Expect:
|
||||
:: a: 1
|
||||
:: bb: 2
|
||||
:: ccc: 3
|
||||
:: dd: 4
|
||||
:: e: 5
|
||||
|
||||
:: :: a: 1
|
||||
:: :: b: 2
|
||||
:: :: ccc: 3
|
||||
:: :: dd: 4
|
||||
:: :: e: 5
|
||||
:: :: f : 6
|
||||
|
||||
###########################################################
|
||||
|
||||
Include: include/teardown.vader
|
||||
|
||||
11
test/run
Executable file
11
test/run
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd $(dirname $BASH_SOURCE)
|
||||
|
||||
vim -Nu <(cat << EOF
|
||||
syntax on
|
||||
for dep in ['vader.vim', 'vim-repeat']
|
||||
execute 'set rtp+=' . finddir(dep, expand('~/.vim').'/**')
|
||||
endfor
|
||||
set rtp+=..
|
||||
EOF) +Vader*
|
||||
@@ -1,8 +1,6 @@
|
||||
# http://en.wikibooks.org/wiki/LaTeX/Tables
|
||||
Execute:
|
||||
Save g:easy_align_delimiters, g:easy_align_bypass_fold
|
||||
let g:easy_align_delimiters = {}
|
||||
silent! unlet g:easy_align_bypass_fold
|
||||
|
||||
Include: include/setup.vader
|
||||
|
||||
Given tex (table with escaped &):
|
||||
\begin{tabular}{ l c r }
|
||||
@@ -157,5 +155,4 @@ Expect tex:
|
||||
8192 & 9.45\e2 & 0.0 & 4.51\e2 & 0.0 & & & & & & \\
|
||||
\end{tabular}
|
||||
|
||||
Execute:
|
||||
Restore
|
||||
Include: include/teardown.vader
|
||||
|
||||
Reference in New Issue
Block a user