Ignore comment lines

This commit is contained in:
Junegunn Choi
2013-06-19 14:20:21 +09:00
parent 34a555c220
commit a6e707b1b3
4 changed files with 288 additions and 114 deletions

177
README.md
View File

@@ -3,6 +3,14 @@ vim-easy-align
A simple, easy-to-use Vim alignment plugin without too much ambition.
Features:
- Optimized for code editing
- Extensible alignment rules
- Aligns text around either _all or n-th_ appearance(s) of the delimiter
- Ignores comment lines
- Ignores lines without a matching delimiter
Demo
----
@@ -78,7 +86,7 @@ Alignment rules for the following delimiters have been defined to meet the most
### Partial alignment in blockwise-visual mode
In blockwise-visual mode (`CTRL-V`), EasyAlign command aligns only the selected
parts, instead of the whole lines in the range.
text in the block, instead of the whole lines in the range.
Consider the following case where you want to align text around `=>` operators.
@@ -102,8 +110,114 @@ 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 field number: `<Enter>-=`
Defining custom alignment rules
-------------------------------
Options
-------
| Option | Type | Default | Description |
| ----------------------------- | ---------- | ------- | --------------------------------------- |
| g:easy_align_ignore_comment | boolean | `1` | Ignore comment lines |
| g:easy_align_ignore_unmatched | boolean | `1` | Ignore lines without matching delimiter |
| g:easy_align_delimiters | dictionary | `{}` | Extend or override alignment rules |
### Ignoring comment lines
EasyAlign by default ignores comment lines.
For example,
```ruby
{
# Quantity of apples: 1
apple: 1,
# Quantity of bananas: 2
bananas: 2,
# Quantity of grapefruits: 3
grapefruits: 3
}
```
becomes
```ruby
{
# Quantity of apples: 1
apple: 1,
# Quantity of bananas: 2
bananas: 2,
# Quantity of grapefruits: 3
grapefruits: 3
}
```
Since finding comment lines is done heuristically using syntax highlighting feature,
this only works when syntax highlighting is enabled.
If you do not want comment lines to be ignored, you can unset `g:easy_align_ignore_comment` as follows.
```vim
let g:easy_align_ignore_comment = 0
```
Then you get,
```ruby
{
# Quantity of apples: 1
apple: 1,
# Quantity of bananas: 2
bananas: 2,
# Quantity of grapefruits: 3
grapefruits: 3
}
```
### Ignoring unmatched lines
Lines without a matching delimiter are ignored as well (except in right-justification mode).
For example, when aligning the following code block around the colons,
```ruby
{
apple: proc {
this_line_does_not_have_a_colon
},
bananas: 2,
grapefruits: 3
}
```
this is usually what we want.
```ruby
{
apple: proc {
this_line_does_not_have_a_colon
},
bananas: 2,
grapefruits: 3
}
```
However, this default behavior is also configurable.
```vim
let g:easy_align_ignore_unmatched = 0
```
Then we get,
```ruby
{
apple: proc {
this_line_does_not_have_a_colon
},
bananas: 2,
grapefruits: 3
}
```
### Extending alignment rules
```vim
let g:easy_align_delimiters = {
@@ -125,59 +239,12 @@ let g:easy_align_delimiters = {
\ }
```
Handling unmatched lines
------------------------
EasyAlign by default ignores lines without the matching delimiters (except in right-justification mode).
This is to ignore interleaved comments commonly found in code.
For example, when aligning the following code block,
```
{
# Quantity of apples
apple: 1,
# Quantity of bananas
bananas: 2,
# Quantity of grapefruits
grapefruits: 3
}
```
we don't want the comment lines to affect the alignment,
so this is usually what we want.
```
{
# Quantity of apples
apple: 1,
# Quantity of bananas
bananas: 2,
# Quantity of grapefruits
grapefruits: 3
}
```
However, this default behavior is configurable.
```vim
let g:easy_align_ignore_unmatched = 0
```
Then we get,
```
{
# Quantity of apples
apple: 1,
# Quantity of bananas
bananas: 2,
# Quantity of grapefruits
grapefruits: 3
}
```
Author
------
[Junegunn Choi](https://github.com/junegunn)
License
-------
MIT

View File

@@ -1,7 +1,30 @@
if exists("g:easy_align_loaded")
" Copyright (c) 2013 Junegunn Choi
"
" MIT License
"
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to
" permit persons to whom the Software is furnished to do so, subject to
" the following conditions:
"
" The above copyright notice and this permission notice shall be
" included in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
if exists("g:loaded_easy_align")
finish
endif
let g:easy_align_loaded = 1
let g:loaded_easy_align = 1
let s:easy_align_delimiters_default = {
\ ' ': { 'pattern': ' ', 'margin_left': '', 'margin_right': '', 'stick_to_left': 0 },
@@ -27,11 +50,13 @@ else
endif
function! s:do_align(just, fl, ll, fc, lc, pattern, nth, ml, mr, stick_to_left, recursive)
let lines = {}
let max_just_len = 0
let max_delim_len = 0
let max_tokens = 0
let pattern = '\s*\(' .a:pattern. '\)\s' . (a:stick_to_left ? '*' : '\{-}')
let lines = {}
let max_just_len = 0
let max_delim_len = 0
let max_tokens = 0
let pattern = '\s*\(' .a:pattern. '\)\s' . (a:stick_to_left ? '*' : '\{-}')
let ignore_comment = has('syntax') && exists('g:syntax_on') &&
\ get(g:, 'easy_align_ignore_comment', 1)
for line in range(a:fl, a:ll)
let tokens = split(a:lc ?
\ strpart(getline(line), a:fc - 1, a:lc - a:fc + 1) :
@@ -41,6 +66,14 @@ function! s:do_align(just, fl, ll, fc, lc, pattern, nth, ml, mr, stick_to_left,
continue
endif
if ignore_comment
execute "normal! ". line ."G^"
if synIDattr(synID(line, a:fc == 1 ? col('.') : a:fc, 0), 'name') =~? 'comment' &&
\ synIDattr(synID(line, a:lc ? min([a:lc, col('$') - 1]) : (col('$') - 1), 0), 'name') =~? 'comment'
continue
endif
endif
" Preserve indentation
if match(tokens[0], '^\s*$') != -1
let tokens = extend([join(tokens[0:1], '')], tokens[2:-1])
@@ -69,7 +102,7 @@ function! s:do_align(just, fl, ll, fc, lc, pattern, nth, ml, mr, stick_to_left,
let suffix = substitute(join(tokens[nth + 1: -1], ''), '^\s*', '', '')
if match(last, pattern.'$') == -1
if a:just == 0 && (!exists("g:easy_align_ignore_unmatched") || g:easy_align_ignore_unmatched)
if a:just == 0 && get(g:, 'easy_align_ignore_unmatched', 1)
continue
else
let delim = ''
@@ -190,7 +223,7 @@ function! easy_align#align(just, ...) range
endif
let delimiters = extend(copy(s:easy_align_delimiters_default),
\ exists("g:easy_align_delimiters") ? g:easy_align_delimiters : {})
\ get(g:, 'easy_align_delimiters', {}))
if has_key(delimiters, ch)
let dict = delimiters[ch]

View File

@@ -63,17 +63,112 @@ Partial alignment in blockwise-visual mode
-------------------------------------------------------------------------
In blockwise-visual mode (`CTRL-V`), EasyAlign command aligns only
the selected parts, instead of the whole lines in the range.
the selected text in the block, instead of the whole lines in the range.
Defining custom alignment rules *g:easy_align_delimiters*
Ignoring comment lines *g:easy_align_ignore_comment*
-------------------------------------------------------------------------
EasyAlign by default ignores comment lines.
For example,
{
# Quantity of apples: 1
apple: 1,
# Quantity of bananas: 2
bananas: 2,
# Quantity of grapefruits: 3
grapefruits: 3
}
becomes
{
# Quantity of apples: 1
apple: 1,
# Quantity of bananas: 2
bananas: 2,
# Quantity of grapefruits: 3
grapefruits: 3
}
Since finding comment lines is done heuristically using syntax highlighting
feature, this only works when syntax highlighting is enabled.
If you do not want comment lines to be ignored, you can unset
`g:easy_align_ignore_comment` as follows.
let g:easy_align_ignore_comment = 0
Then you get,
{
# Quantity of apples: 1
apple: 1,
# Quantity of bananas: 2
bananas: 2,
# Quantity of grapefruits: 3
grapefruits: 3
}
Handling unmatched lines *g:easy_align_ignore_unmatched*
-------------------------------------------------------------------------
Lines without a matching delimiter are ignored as well (except in
right-justification mode).
For example, when aligning the following code block around the colons,
{
apple: proc {
this_line_does_not_have_a_colon
},
bananas: 2,
grapefruits: 3
}
this is usually what we want.
{
apple: proc {
this_line_does_not_have_a_colon
},
bananas: 2,
grapefruits: 3
}
However, this default behavior is also configurable.
let g:easy_align_ignore_unmatched = 0
Then we get,
{
apple: proc {
this_line_does_not_have_a_colon
},
bananas: 2,
grapefruits: 3
}
Extending alignment rules *g:easy_align_delimiters*
-------------------------------------------------------------------------
let g:easy_align_delimiters = {
\ '>': { 'pattern': '>>\|=>\|>' },
\ '/': { 'pattern': '//*' },
\ '/': { 'pattern': '//\+' },
\ '#': { 'pattern': '#\+' },
\ ']': {
\ 'pattern': '[\[\]]',
\ 'margin_left': '',
\ 'margin_right': '',
\ 'stick_to_left': 0
\ },
\ ')': {
\ 'pattern': ')',
\ 'pattern': '[()]',
\ 'margin_left': '',
\ 'margin_right': '',
\ 'stick_to_left': 0
@@ -81,47 +176,3 @@ Defining custom alignment rules *g:easy_align_delimiters*
\ }
Handling unmatched lines *g:easy_align_ignore_unmatched*
-------------------------------------------------------------------------
EasyAlign by default ignores lines without the matching delimiters
(except in right-justification mode).
This is to ignore interleaved comments commonly found in code.
For example, when aligning the following code,
{
# Quantity of apples
apple: 1,
# Quantity of bananas
bananas: 2,
# Quantity of grapefruits
grapefruits: 3
}
this is usually what we want.
{
# Quantity of apples
apple: 1,
# Quantity of bananas
bananas: 2,
# Quantity of grapefruits
grapefruits: 3
}
However, this default behavior is configurable.
let g:easy_align_ignore_unmatched = 0
Then we get,
{
# Quantity of apples
apple: 1,
# Quantity of bananas
bananas: 2,
# Quantity of grapefruits
grapefruits: 3
}

View File

@@ -1,7 +1,30 @@
if exists("g:easy_align_plugin_loaded")
" Copyright (c) 2013 Junegunn Choi
"
" MIT License
"
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to
" permit persons to whom the Software is furnished to do so, subject to
" the following conditions:
"
" The above copyright notice and this permission notice shall be
" included in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
if exists("g:loaded_easy_align_plugin")
finish
endif
let g:easy_align_plugin_loaded = 1
let g:loaded_easy_align_plugin = 1
command! -nargs=* -range EasyAlign <line1>,<line2>call easy_align#align(0, <f-args>)
command! -nargs=* -range EasyAlignRight <line1>,<line2>call easy_align#align(1, <f-args>)