11 Commits
2.5.0 ... 2.5.1

Author SHA1 Message Date
Junegunn Choi
e4f86274e3 Update install instructions 2013-09-22 23:04:20 +09:00
Junegunn Choi
2d575bcc25 Underscore between parens 2013-09-22 22:56:27 +09:00
Junegunn Choi
8a783c2125 Fix a failure in test due to change in interactive mode 2013-09-22 22:21:23 +09:00
Junegunn Choi
5230a2402f Disallow 0 as the first character of N-th 2013-09-22 21:58:31 +09:00
Junegunn Choi
94a750e03e Remove unnecessary prev output wipe 2013-09-22 21:48:14 +09:00
Junegunn Choi
afc95b5ed7 Forgiving interactive mode: Do not terminate on invalid input 2013-09-22 21:17:02 +09:00
Junegunn Choi
1d2c58c06a Field index -> N-th parameter 2013-09-22 03:52:36 +09:00
Junegunn Choi
4cdc450126 Update DEMO.md 2013-09-21 23:53:47 +09:00
Junegunn Choi
7e1be152dc Add DEMO.md 2013-09-21 15:46:40 +09:00
Junegunn Choi
c61a11d150 Update doc
- Field number -> Field index
2013-09-21 13:08:55 +09:00
Junegunn Choi
2797baca6c Disallow non-printable character input 2013-09-21 12:04:56 +09:00
7 changed files with 192 additions and 67 deletions

91
DEMO.md Normal file
View File

@@ -0,0 +1,91 @@
# 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

View File

@@ -166,8 +166,8 @@ my_object
```
Using blockwise-visual mode or negative field index
---------------------------------------------------
Using blockwise-visual mode or negative N-th parameter
------------------------------------------------------
You can try either:
- select text around `=>` in blockwise-visual mode (`CTRL-V`) and `<Enter>=`

View File

@@ -37,15 +37,17 @@ and extract in ~/.vim or
[plugin](https://github.com/Shougo/neobundle.vim)
[manager](https://github.com/MarcWeber/vim-addon-manager).
### With Vundle
Add the following line to your .vimrc,
```vim
Bundle 'junegunn/vim-easy-align'
```
then execute `:BundleInstall` command.
- [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`
Usage
-----
@@ -56,8 +58,8 @@ variant `:EasyAlign!`) for visual mode.
| Mode | Command |
| ------------------------- | ------------------------------------------------ |
| Interactive mode | `:EasyAlign[!] [OPTIONS]` |
| Using predefined rules | `:EasyAlign[!] [FIELD#] DELIMITER_KEY [OPTIONS]` |
| Using regular expressions | `:EasyAlign[!] [FIELD#] /REGEXP/ [OPTIONS]` |
| Using predefined rules | `:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]` |
| Using regular expressions | `:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]` |
### Concept of _alignment rule_
@@ -83,8 +85,8 @@ vnoremap <silent> <Enter> :EasyAlign<cr>
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 field number (default: 1)
1. Optional: Enter keys to select alignment mode (left, right, or center)
1. Optional: N-th delimiter (default: 1)
- `1` Around the 1st occurrences of delimiters
- `2` Around the 2nd occurrences of delimiters
- ...
@@ -176,10 +178,10 @@ Instead of going into the interactive mode, you can type in arguments to
```vim
" Using predefined alignment rules
:EasyAlign[!] [FIELD#] DELIMITER_KEY [OPTIONS]
:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
" Using arbitrary regular expressions
:EasyAlign[!] [FIELD#] /REGEXP/ [OPTIONS]
:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
```
For example, when aligning the following lines around colons and semi-colons,
@@ -247,7 +249,7 @@ 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>-=`
since the same can be easily done using the negative N-th parameter: `<Enter>-=`
Alignment options
-----------------
@@ -508,7 +510,7 @@ let g:easy_align_bang_interactive_modes = ['c', 'r']
### Alignments over multiple occurrences of delimiters
As stated above, "field number" is used to target specific occurrences of
As stated above, "N-th" parameter is used to target specific occurrences of
the delimiter when it appears multiple times in each line.
To recap:

View File

@@ -95,7 +95,6 @@ function! s:ignored_syntax()
endif
endfunction
let s:prev_echon_len = 0
function! s:echon_(tokens)
" http://vim.wikia.com/wiki/How_to_print_full_screen_width_messages
let xy = [&ruler, &showcmd]
@@ -104,11 +103,6 @@ function! s:echon_(tokens)
let winlen = winwidth(winnr()) - 2
let len = len(join(map(copy(a:tokens), 'v:val[1]'), ''))
if len < s:prev_echon_len
echohl None
echon "\r". repeat(' ', min([winlen, s:prev_echon_len]))
endif
let s:prev_echon_len = len
let ellipsis = len > winlen ? '..' : ''
echon "\r"
@@ -130,7 +124,7 @@ function! s:echon_(tokens)
endtry
endfunction
function! s:echon(l, n, r, d, o)
function! s:echon(l, n, r, d, o, warn)
let tokens = [
\ ['Function', ':EasyAlign'],
\ ['ModeMsg', get(s:mode_labels, a:l, a:l)],
@@ -141,8 +135,11 @@ function! s:echon(l, n, r, d, o)
call extend(tokens, a:r == 1 ?
\ [['Delimiter', '/'], ['String', a:d], ['Delimiter', '/']] :
\ [['Identifier', a:d == ' ' ? '\ ' : (a:d == '\' ? '\\' : a:d)]])
if a:r == -1 | call add(tokens, ['Comment', ')']) | endif
if a:r == -1 | call extend(tokens, [['Normal', '_'], ['Comment', ')']]) | endif
call add(tokens, ['Statement', empty(a:o) ? '' : ' '.string(a:o)])
if !empty(a:warn)
call add(tokens, ['WarningMsg', ' ('.a:warn.')'])
endif
call s:echon_(tokens)
endfunction
@@ -363,12 +360,12 @@ function! s:do_align(modes, all_tokens, all_delims, fl, ll, fc, lc, pattern, nth
" Calculate the maximum number of tokens for a line within the range
call s:max(max, { 'tokens': len(tokens) })
if a:nth > 0 " Positive field number
if a:nth > 0 " Positive N-th
if len(tokens) < a:nth
continue
endif
let nth = a:nth - 1 " make it 0-based
else " -0 or Negative field number
else " -0 or Negative N-th
if a:nth == 0 && mode !=? 'l'
let nth = len(tokens) - 1
else
@@ -560,16 +557,19 @@ function! s:atoi(str)
return (a:str =~ '^[0-9]\+$') ? str2nr(a:str) : a:str
endfunction
function! s:interactive(modes, vis, opts)
function! s:interactive(modes, vis, opts, delims)
let mode = s:shift(a:modes, 1)
let n = ''
let ch = ''
let opts = s:compact_options(a:opts)
let vals = deepcopy(s:option_values)
let regx = 0
let warn = ''
while 1
call s:echon(mode, n, -1, '', opts)
call s:echon(mode, n, -1, '', opts, warn)
let check = 0
let warn = ''
let c = getchar()
let ch = nr2char(c)
@@ -587,16 +587,16 @@ function! s:interactive(modes, vis, opts)
elseif ch == '-'
if empty(n) | let n = '-'
elseif n == '-' | let n = ''
else | break
else | let check = 1
endif
elseif ch == '*'
if empty(n) | let n = '*'
elseif n == '*' | let n = '**'
elseif n == '**' | let n = ''
else | break
else | let check = 1
endif
elseif c >= 48 && c <= 57 " Numbers
if n[0] == '*' | break
elseif (c == 48 && len(n) > 0) || c > 48 && c <= 57 " Numbers
if n[0] == '*' | let check = 1
else | let n = n . ch
end
elseif ch == "\<C-D>"
@@ -604,9 +604,21 @@ function! s:interactive(modes, vis, opts)
elseif ch == "\<C-I>"
let opts['idt'] = s:shift(vals['indentation'], 1)
elseif ch == "\<C-L>"
let opts['lm'] = s:atoi(s:input("Left margin: ", get(opts, 'lm', ''), a:vis))
let lm = s:input("Left margin: ", get(opts, 'lm', ''), a:vis)
if empty(lm)
let warn = 'Set to default. Input 0 to remove it'
silent! call remove(opts, 'lm')
else
let opts['lm'] = s:atoi(lm)
endif
elseif ch == "\<C-R>"
let opts['rm'] = s:atoi(s:input("Right margin: ", get(opts, 'rm', ''), a:vis))
let rm = s:input("Right margin: ", get(opts, 'rm', ''), a:vis)
if empty(rm)
let warn = 'Set to default. Input 0 to remove it'
silent! call remove(opts, 'rm')
else
let opts['rm'] = s:atoi(rm)
endif
elseif ch == "\<C-U>"
let opts['iu'] = s:shift(vals['ignore_unmatched'], 1)
elseif ch == "\<C-G>"
@@ -633,22 +645,43 @@ function! s:interactive(modes, vis, opts)
elseif ch == "\<C-_>" || ch == "\<C-X>"
let prompt = 'Regular expression: '
let ch = s:input(prompt, '', a:vis)
if !empty(ch)
if !empty(ch) && s:valid_regexp(ch)
let regx = 1
let s:prev_echon_len = len(prompt . ch)
break
else
let warn = 'Invalid regular expression: '.ch
endif
elseif ch =~ '[[:print:]]'
let check = 1
else
break
let warn = 'Invalid character'
endif
if check
if has_key(a:delims, ch)
break
else
let warn = 'Unknown delimiter key: '.ch
endif
endif
endwhile
return [mode, n, ch, s:normalize_options(opts), regx]
endfunction
function! s:test_regexp(regexp)
try | call matchlist('', a:regexp)
catch | call s:exit("Invalid regular expression: ". a:regexp)
function! s:valid_regexp(regexp)
try
call matchlist('', a:regexp)
catch
return 0
endtry
return 1
endfunction
function! s:test_regexp(regexp)
if !s:valid_regexp(a:regexp)
call s:exit('Invalid regular expression: '. a:regexp)
endif
return a:regexp
endfunction
function! s:parse_args(args)
@@ -695,7 +728,7 @@ function! s:parse_args(args)
" Found regexp
if !empty(matches)
return [matches[1], matches[2], opts, 1]
return [matches[1], s:test_regexp(matches[2]), opts, 1]
else
let tokens = matchlist(args, '^\([1-9][0-9]*\|-[0-9]*\|\*\*\?\)\?\s*\(.\{-}\)\?$')
return [tokens[1], tokens[2], opts, 0]
@@ -730,12 +763,17 @@ function! s:align(bang, 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 delimiters = s:easy_align_delimiters_default
if exists('g:easy_align_delimiters')
let delimiters = extend(copy(delimiters), g:easy_align_delimiters)
endif
if empty(a:expr)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts, delimiters)
else
let [n, ch, opts, regexp] = s:parse_args(a:expr)
if empty(n) && empty(ch)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts)
let [mode, n, ch, opts, regexp] = s:interactive(copy(modes), vis, opts, delimiters)
elseif empty(ch)
" Try swapping n and ch
let [n, ch] = ['', n]
@@ -747,18 +785,12 @@ function! s:align(bang, first_line, last_line, expr)
elseif n == '-' | let nth = -1
elseif empty(n) | let nth = 1
elseif n == '0' || ( n != '-0' && n != string(str2nr(n)) )
call s:exit('Invalid field number: '. n)
call s:exit('Invalid N-th parameter: '. n)
else
let nth = n
endif
let delimiters = s:easy_align_delimiters_default
if exists('g:easy_align_delimiters')
let delimiters = extend(copy(delimiters), g:easy_align_delimiters)
endif
if regexp
call s:test_regexp(ch)
let dict = { 'pattern': ch }
else
" Resolving command-line ambiguity
@@ -828,6 +860,6 @@ function! s:align(bang, first_line, last_line, expr)
\ )
call extend(copts, { 'm': aseq_str })
endif
call s:echon('', n, regexp, ch, copts)
call s:echon('', n, regexp, ch, copts, '')
endfunction

View File

@@ -16,11 +16,11 @@ EasyAlign *:EasyAlign* *:EasyAlign!*
vim-easy-align defines `:EasyAlign` command in the visual mode.
(:EasyAlign! is the right-align version.)
| Mode | Command |
| ------------------------- | ---------------------------------------------- |
| Interactive mode | :EasyAlign[!] [OPTIONS] |
| Using predefined rules | :EasyAlign[!] [FIELD#] DELIMITER_KEY [OPTIONS] |
| Using regular expressions | :EasyAlign[!] [FIELD#] /REGEXP/ [OPTIONS] |
| Mode | Command |
| ------------------------- | -------------------------------------------- |
| Interactive mode | :EasyAlign[!] [OPTIONS] |
| Using predefined rules | :EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS] |
| Using regular expressions | :EasyAlign[!] [N-th] /REGEXP/ [OPTIONS] |
Interactive mode
@@ -35,8 +35,8 @@ your `.vimrc`.
With this mapping, you can align selected lines of text with a few keystrokes.
1. <Enter> key to start interactive EasyAlign command
2. Optional Enter keys to select alignment mode (left, right, or center)
3. Optional field number (default: 1)
2. Optional: Enter keys to select alignment mode (left, right, or center)
3. Optional: N-th delimiter (default: 1)
1 Around the 1st occurrences of delimiters
2 Around the 2nd occurrences of delimiters
* Around all occurrences of delimiters
@@ -106,10 +106,10 @@ Instead of going into the interactive mode, you can type in arguments to
`:EasyAlign` command.
" Using predefined alignment rules
:EasyAlign[!] [FIELD#] DELIMITER_KEY [OPTIONS]
:EasyAlign[!] [N-th] DELIMITER_KEY [OPTIONS]
" Using arbitrary regular expressions
:EasyAlign[!] [FIELD#] /REGEXP/ [OPTIONS]
:EasyAlign[!] [N-th] /REGEXP/ [OPTIONS]
For example, when aligning the following lines around colons and semi-colons,
@@ -175,7 +175,7 @@ Available options are as follows.
| | | (right, left, center) |
| indentation | string | 'k' |
| | | (keep, shallow, deep, none) |
| mode_sequence | string | (Depends on field number and |
| mode_sequence | string | (Depends on N-th param and |
| | | selected alignment mode) |
There are 4 ways to set alignment options (from lowest precedence to highest):
@@ -407,7 +407,7 @@ settings as follows.
Alignments over multiple occurrences of delimiters
-------------------------------------------------------------------------
As stated above, "field number" is used to target specific occurrences of
As stated above, "N-th" parameter is used to target specific occurrences of
the delimiter when it appears multiple times in each line.
To recap:

View File

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

View File

@@ -1 +1 @@
4Gvipjyvip:EasyAlign:
4Gvipjyvip:EasyAlign: