Open this document in your Vim and try it yourself.
This document assumes that you have the following mappings in your .vimrc.
" 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.
function! GFM()
let langs = ['ruby', 'yaml', 'vim', 'c']
for lang in langs
unlet b:current_syntax
silent! exec printf("syntax include @%s syntax/%s.vim", lang, lang)
exec printf("syntax region %sSnip matchgroup=Snip start='```%s' end='```' contains=@%s",
\ lang, lang, lang)
endfor
let b:current_syntax='mkd'
syntax sync fromstart
endfunction
You can align text around whitespaces with <space>
delimiter key.
Start the interactive mode as described above (gaip
or vipga
) and try
these commands:
<space>
2<space>
*<space>
-<space>
-2<space>
<Enter><space>
<Enter>*<space>
<Enter><Enter>*<space>
Paul McCartney 1942
George Harrison 1943
Ringo Starr 1940
Pete Best 1941
Again, start the interactive mode and try these commands:
*|
**|
<Enter>*|
<Enter>**|
<Enter><Enter>*|
| 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 |
The default rule for delimiter key =
aligns around a whole family of
operators containing =
character.
Try these commands in the interactive mode.
=
*=
**=
<Enter>**=
<Enter><Enter>*=
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
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: *:
.
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
Try .
or *.
on the following lines.
my_object
.method1().chain()
.second_method().call()
.third().call()
.method_4().execute()
Notice that the indentation is adjusted to match the shortest one among those of the lines starting with the delimiter.
my_object
.method1() .chain()
.second_method().call()
.third() .call()
.method_4() .execute()
You can try either:
- select text around
=>
in blockwise-visual mode (CTRL-V
) andga=
- or
gaip-=
options = { :caching => nil,
:versions => 3,
"cache=blocks" => false }.merge(options)
There is also a predefined rule for commas, try *,
.
aaa, bb,c
d,eeeeeee
fffff, gggggggggg,
h, , ii
j,,k
Delimiters highlighted as comments or strings are ignored by default, try
gaip*=
on the following lines.
/* a */ b = c
aa >= bb
// aaa = bbb = cccc
/* aaaa = */ bbbb === cccc " = dddd = " = eeee
aaaaa /* bbbbb */ == ccccc /* != eeeee = */ === fffff
This only works when syntax highlighting is enabled.
Note: Since the current version provides '#'-rule as one of the default rules, you can ignore this section.
apple = 1 # comment not aligned
banana = 'Gros Michel' # comment 2
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.
apple = 1 # comment not aligned
apricot = 'DAD' + 'F#AD'
banana = 'Gros Michel' # comment 2
That is because the second line doesn't have trailing comment, and
the last (-
) space for that line is the one just before 'F#AD'
.
So, let's define a custom mapping for #
.
if !exists('g:easy_align_delimiters')
let g:easy_align_delimiters = {}
endif
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 #
, we get
apple = 1 # comment not aligned
apricot = 'DAD' + 'F#AD'
banana = 'string' # comment 2
If you don't want to define the rule, you can do the same with the following command:
" Using regular expression /#/
" - "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
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:
- Set global
g:easy_align_ignore_unmatched
flag to 0 - Use
:EasyAlign
command withignore_unmatched
option - Update the alignment rule with
ignore_unmatched
option
" 1. Set global g:easy_align_ignore_unmatched to zero
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 expanded to "*i*gnore_*u*nmatched"
:EasyAlign#{'iu':0}
" or
:EasyAlign#iu0
" 2-2. Using regular expression /#/
:EasyAlign/#/ig['String']iu0
" 3. Update the alignment rule with ignore_unmatched option
let g:easy_align_delimiters['#'] = {
\ 'pattern': '#', 'ignore_groups': ['String'], 'ignore_unmatched': 0 }
Then we get,
apple = 1 # comment not aligned
apricot = 'DAD' + 'F#AD'
banana = 'string' # comment 2
Take the following example:
const char* str = "Hello";
int64_t count = 1 + 2;
static double pi = 3.14;
We can align these lines with the predefined =
rule. Select the lines and
press ga=
const char* str = "Hello";
int64_t count = 1 + 2;
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
<space>
-rule won't properly align those names.
So let's define an alignment rule than can handle this case.
let g:easy_align_delimiters['d'] = {
\ 'pattern': '\(const\|static\)\@<! ',
\ 'left_margin': 0, 'right_margin': 0
\ }
This new rule aligns text around spaces that are not preceded by
const
or static
. Let's select the lines and try gad
.
const char* str = "Hello";
int64_t count = 1 + 2;
static double pi = 3.14;
Okay, the names are now aligned. We select the lines again with gv
, and then
press ga=
to finish our alignment.
const char* str = "Hello";
int64_t count = 1 + 2;
static double pi = 3.14;
So far, so good. However, this rule is not sufficient to handle more complex cases involving C++ templates or Java generics. Take the following example:
const char* str = "Hello";
int64_t count = 1 + 2;
static double pi = 3.14;
static std::map<std::string, float>* scores = pointer;
We see that our rule above doesn't work anymore.
const char* str = "Hello";
int64_t count = 1 + 2;
static double pi = 3.14;
static std::map<std::string, float>* scores = pointer;
So what do we do? Let's try to improve our alignment rule.
let g:easy_align_delimiters['d'] = {
\ '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 vipgad
const char* str = "Hello";
int64_t count = 1 + 2;
static double pi = 3.14;
static std::map<std::string, float>* scores = pointer;
We're right on track, now press gvga=
and voila!
const char* str = "Hello";
int64_t count = 1 + 2;
static double pi = 3.14;
static std::map<std::string, float>* scores = pointer;