From 4c6a8c174d59e236a0c7a234a4f380a8aae893b1 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Thu, 3 Oct 2013 21:53:15 +0900 Subject: [PATCH] Implement shortcut expression for options --- README.md | 27 ++++++++++++++++++++++++++- autoload/easy_align.vim | 38 +++++++++++++++++++++++++++++++++++++- doc/easy_align.txt | 25 ++++++++++++++++++++++++- test/regexp.expected | 12 ++++++++++++ test/regexp.script | 2 +- 5 files changed, 100 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1e26ac1..4a2c2c3 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ Go try out vim-easy-align right now, and come back later when you feel like it. --- -### Non-interactive mode +### Non-interactive mode (command line) Instead of going into the interactive mode, you can type in arguments to `:EasyAlign` command. @@ -225,6 +225,31 @@ key combination. - `` (or `` on GVim) - `[:;]\+` +#### Options in shortcut expression + +When you use regular expression in command line, options dictionary can be +written concisely using shortcut expression. + +For example, the command we saw in the previous section, + +- `:EasyAlign*/[:;]\+/{'s':1,'l':0}` + +can also be written as + +- `:EasyAlign*/[:;]\+/s1l0` + +Supported shortcut expressions are listed below. + +| Expression | Option | +| ---------- | ---------------- | +| `l[0-9]` | left_margin | +| `r[0-9]` | right_margin | +| `s[01]` | stick_to_left | +| `u[01]` | ignore_unmatched | +| `d[lrc]` | delimiter_align | +| `m[lrc*]*` | mode_sequence | +| `i[ksdn]` | indentation | + ### Partial alignment in blockwise-visual mode In blockwise-visual mode (`CTRL-V`), EasyAlign command aligns only the selected diff --git a/autoload/easy_align.vim b/autoload/easy_align.vim index 46df4e0..93f8cdd 100644 --- a/autoload/easy_align.vim +++ b/autoload/easy_align.vim @@ -688,6 +688,39 @@ function! s:test_regexp(regexp) return a:regexp endfunction +function! s:parse_shortcut_opts(expr) + let opts = {} + let expr = tolower(substitute(a:expr, '\s', '', 'g')) + let regex = + \ '^\(' + \ .'\(l[0-9]\+\)\|\(r[0-9]\+\)\|\(u[01]\)\|\(s[01]\)\|' + \ .'\(d[clr]\)\|\(m[lrc*]\+\)\|\(i[kdsn]\)' + \ .'\)\+$' + + if empty(expr) + return opts + elseif expr !~ regex + call s:exit("Invalid expression: ". a:expr) + else + let match = matchlist(expr, regex) + if empty(match) | break | endif + for m in filter(match[ 2 : -1 ], '!empty(v:val)') + let k = m[0] + let rest = m[1 : -1] + if index(['l', 'r', 's'], k) >= 0 + let opts[k] = str2nr(rest) + elseif k == 'u' + let opts['iu'] = str2nr(rest) + elseif k == 'i' + let opts['idt'] = rest + else + let opts[k] = rest + endif + endfor + endif + return s:normalize_options(opts) +endfunction + function! s:parse_args(args) let n = '' let ch = '' @@ -728,10 +761,13 @@ function! s:parse_args(args) endif " Has /Regexp/? - let matches = matchlist(args, '^\(.\{-}\)\s*/\(.*\)/\s*$') + let matches = matchlist(args, '^\(.\{-}\)\s*/\(.*\)/\(.\{-}\)$') " Found regexp if !empty(matches) + if empty(opts) && !empty(matches[3]) + let opts = s:parse_shortcut_opts(matches[3]) + endif return [matches[1], s:test_regexp(matches[2]), opts, 1] else let tokens = matchlist(args, '^\([1-9][0-9]*\|-[0-9]*\|\*\*\?\)\?\s*\(.\{-}\)\?$') diff --git a/doc/easy_align.txt b/doc/easy_align.txt index d55c30c..7bbe4bc 100644 --- a/doc/easy_align.txt +++ b/doc/easy_align.txt @@ -100,7 +100,7 @@ described in the following sections. | | *_margin | { 'left_margin': 0, 'right_margin': 0 } | -Non-interactive mode +Non-interactive mode (command line) ------------------------------------------------------------------------- Instead of going into the interactive mode, you can type in arguments to @@ -152,6 +152,29 @@ key combination. - (or on GVim) - [:;]\+ +When you use regular expression in command line, options dictionary can be +written concisely using shortcut expression. + +For example, the command we saw in the previous section, + +- :EasyAlign*/[:;]\+/{'s':1,'l':0} + +can also be written as + +- :EasyAlign*/[:;]\+/s1l0 + +Supported shortcut expressions are listed below. + +| Expression | Option | +| ---------- | -------------- | +| l[0-9] | left_margin | +| r[0-9] | right_margin | +| s[01] | stick_to_left | +| u[01] | ignore_unmatched | +| d[lrc] | delimiter_align | +| m[lrc*]* | mode_sequence | +| i[ksdn] | indentation | + Partial alignment in blockwise-visual mode ------------------------------------------------------------------------- diff --git a/test/regexp.expected b/test/regexp.expected index 0d4ac9f..312b731 100644 --- a/test/regexp.expected +++ b/test/regexp.expected @@ -94,3 +94,15 @@ banana = 'Gros Michel' # comment 2 a()p()p()l()e();():()b()a()n()a()n()a():():()c()a()k()e( d()a()t()a();();()e()x()c()h()a()n()g()e():();()f()o()r()m()a()t( +apple ;: banana :: cake + data ;;exchange :;format + +apple ;: banana :: cake + data ;; exchange :; format + +apple;:banana ::cake +data ;;exchange:;format + +apple ;: banana :: cake +data ;; exchange :; format + diff --git a/test/regexp.script b/test/regexp.script index 85508ee..6730fbe 100644 --- a/test/regexp.script +++ b/test/regexp.script @@ -1 +1 @@ -4Gvipjyvip:EasyAlign: Pvip:EasyAlign*: Pvip:EasyAlign-: Pvip:EasyAlign * : Pvip:EasyAlign -2 : Pvip:EasyAlign -2: Pvip:EasyAlign *: Pvip:EasyAlign; Pvip:EasyAlign /;/ Pvip:EasyAlign/;/ Pvip:EasyAlign*/;/ Pvip:EasyAlign/[:;]\+/ Pvip:EasyAlign*/[:;]\+/ Pvip:EasyAlign* /[:;]\+/ Pvip:EasyAlign */[:;]\+/ Pvip:EasyAlign * /[:;]\+/ Pvip:EasyAlign-/[:;]\+/ Pvip:EasyAlign-2/[:;]\+/ Pvip:EasyAlign/[:;]\+/{ 'l': '<<<', 'r': '>>>'} Pvip:EasyAlign/[:;]\+/{'l':'', 's': 1} Pvip:EasyAlign * /[:;]\+/ {'stick_to': 1, 'le': '???', 'marr': '~~~'} Pvip:EasyAlign /../ Pvip:EasyAlign*/../ Pvip:EasyAlign **/[:;\+]/ Pvip:EasyAlign/[:;]\+/{'rm':'____'} Pvip:EasyAlign**/[:;]\+/ Pvip:EasyAlign!**/[:;]\+/ Pfbjfm:EasyAlign/[:;]\+/ 90Gvip:EasyAlign/#/{'is':['String'],'iu':0} 93Gpvip:EasyAlign*/\s*/{'l':'(', 'r': ')'} +4Gvipjyvip:EasyAlign: Pvip:EasyAlign*: Pvip:EasyAlign-: Pvip:EasyAlign * : Pvip:EasyAlign -2 : Pvip:EasyAlign -2: Pvip:EasyAlign *: Pvip:EasyAlign; Pvip:EasyAlign /;/ Pvip:EasyAlign/;/ Pvip:EasyAlign*/;/ Pvip:EasyAlign/[:;]\+/ Pvip:EasyAlign*/[:;]\+/ Pvip:EasyAlign* /[:;]\+/ Pvip:EasyAlign */[:;]\+/ Pvip:EasyAlign * /[:;]\+/ Pvip:EasyAlign-/[:;]\+/ Pvip:EasyAlign-2/[:;]\+/ Pvip:EasyAlign/[:;]\+/{ 'l': '<<<', 'r': '>>>'} Pvip:EasyAlign/[:;]\+/{'l':'', 's': 1} Pvip:EasyAlign * /[:;]\+/ {'stick_to': 1, 'le': '???', 'marr': '~~~'} Pvip:EasyAlign /../ Pvip:EasyAlign*/../ Pvip:EasyAlign **/[:;\+]/ Pvip:EasyAlign/[:;]\+/{'rm':'____'} Pvip:EasyAlign**/[:;]\+/ Pvip:EasyAlign!**/[:;]\+/ Pfbjfm:EasyAlign/[:;]\+/ 90Gvip:EasyAlign/#/{'is':['String'],'iu':0} 93Gpvip:EasyAlign*/\s*/{'l':'(', 'r': ')'} 96Gpvip:EasyAlign*/[:;]\+/r3l3s1 Pvip:EasyAlign*/[:;]\+/r0l0s0 Pvip:EasyAlign*/[:;]\+/mrcr Pvip:EasyAlign*/[:;]\+/mrcrr0l2