Refactoring for GTabularize

This commit is contained in:
Matt Wozniski 2012-09-05 00:09:18 -04:00
parent 4894d4add2
commit df28fbc369
2 changed files with 65 additions and 84 deletions

View File

@ -219,9 +219,7 @@ function! tabular#TabularizeStrings(strings, delim, ...)
" intentionally " intentionally
" - Don't strip leading spaces from the first element; we like indenting. " - Don't strip leading spaces from the first element; we like indenting.
for line in lines for line in lines
if len(line) == 1 && len(tabular#LineInclusionPattern()) if len(line) == 1 && s:do_gtabularize
" FIXME Does LineInclusionPattern even need to be a pattern? Can it
" just be a boolean? That's all I've needed to use it as...
continue " Leave non-matching lines unchanged for GTabularize continue " Leave non-matching lines unchanged for GTabularize
endif endif
@ -238,7 +236,7 @@ function! tabular#TabularizeStrings(strings, delim, ...)
" Find the max length of each field " Find the max length of each field
let maxes = [] let maxes = []
for line in lines for line in lines
if len(line) == 1 && len(tabular#LineInclusionPattern()) if len(line) == 1 && s:do_gtabularize
continue " non-matching lines don't affect field widths for GTabularize continue " non-matching lines don't affect field widths for GTabularize
endif endif
@ -257,7 +255,7 @@ function! tabular#TabularizeStrings(strings, delim, ...)
for idx in range(len(lines)) for idx in range(len(lines))
let line = lines[idx] let line = lines[idx]
if len(line) == 1 && len(tabular#LineInclusionPattern()) if len(line) == 1 && s:do_gtabularize
let lines[idx] = line[0] " GTabularize just ignores non-matching lines let lines[idx] = line[0] " GTabularize just ignores non-matching lines
continue continue
endif endif
@ -299,65 +297,57 @@ endfunction
" The remaining arguments must each be a filter to apply to the text. " The remaining arguments must each be a filter to apply to the text.
" Each filter must either be a String evaluating to a function to be called. " Each filter must either be a String evaluating to a function to be called.
function! tabular#PipeRange(includepat, ...) range function! tabular#PipeRange(includepat, ...) range
try exe a:firstline . ',' . a:lastline
let top = a:firstline \ . 'call tabular#PipeRangeWithOptions(a:includepat, a:000, {})'
let bot = a:lastline endfunction
if get(s:, 'tabularize_mode', '') ==# 'GTabularize' " Extended version of tabular#PipeRange, which
" Save the include pattern for future use by TabularizeStrings (and by " 1) Takes the list of filters as an explicit list rather than as varargs
" any Pipeline that wants to handle it) for GTabularize; it can be " 2) Supports passing a dictionary of options to control the routine.
" queried later via tabular#LineInclusionPattern " Currently, the only supported option is 'mode', which determines whether
let s:line_inclusion_pattern = a:includepat " to behave as :Tabularize or as :GTabularize
else " This allows me to add new features here without breaking API compatibility
" In the default mode, apply range extension logic " in the future.
if a:includepat != '' && top == bot function! tabular#PipeRangeWithOptions(includepat, filterlist, options) range
if top < 0 || top > line('$') || getline(top) !~ a:includepat let top = a:firstline
return let bot = a:lastline
endif
while top > 1 && getline(top-1) =~ a:includepat let s:do_gtabularize = (a:options['mode'] ==# 'GTabularize')
let top -= 1
endwhile if !s:do_gtabularize
while bot < line('$') && getline(bot+1) =~ a:includepat " In the default mode, apply range extension logic
let bot += 1 if a:includepat != '' && top == bot
endwhile if top < 0 || top > line('$') || getline(top) !~ a:includepat
return
endif endif
while top > 1 && getline(top-1) =~ a:includepat
let top -= 1
endwhile
while bot < line('$') && getline(bot+1) =~ a:includepat
let bot += 1
endwhile
endif
endif
let lines = map(range(top, bot), 'getline(v:val)')
for filter in a:filterlist
if type(filter) != type("")
echoerr "PipeRange: Bad filter: " . string(filter)
endif endif
let lines = map(range(top, bot), 'getline(v:val)') call s:FilterString(lines, filter)
for filter in a:000 unlet filter
if type(filter) != type("") endfor
echoerr "PipeRange: Bad filter: " . string(filter)
endif
call s:FilterString(lines, filter) call s:SetLines(top, bot - top + 1, lines)
unlet filter
endfor
call s:SetLines(top, bot - top + 1, lines)
finally
unlet! s:line_inclusion_pattern
endtry
endfunction endfunction
" For passing the current mode to autoload/tabular.vim from plugin/Tabular.vim " Part of the public interface so interested pipelines can query this and
" FIXME This could be done more cleanly if the :AddTabularize* functions " adjust their behavior appropriately.
" didn't hardcode the arguments to the PipeRange call... function! tabular#DoGTabularize()
function! tabular#SetTabularizeMode(mode) return s:do_gtabularize
if len(a:mode)
let s:tabularize_mode = a:mode
else
unlet! s:tabularize_mode
endif
endfunction
" Part of the public interface so interested pipelines can query this.
" When not in GTabularize mode, an empty string will be returned, otherwise
" the pattern to be used to determine whether a line should be changed is
" returned.
function! tabular#LineInclusionPattern()
return get(s:, 'line_inclusion_pattern', '')
endfunction endfunction
function! s:SplitDelimTest(string, delim, expected) function! s:SplitDelimTest(string, delim, expected)

View File

@ -194,9 +194,7 @@ function! AddTabularPattern(command, force)
let command .= ")" let command .= ")"
let commandmap[name] = ":call tabular#PipeRange(" let commandmap[name] = { 'pattern' : pattern, 'commands' : [ command ] }
\ . string(pattern) . ","
\ . string(command) . ")"
catch catch
echohl ErrorMsg echohl ErrorMsg
echomsg "AddTabularPattern: " . v:exception echomsg "AddTabularPattern: " . v:exception
@ -249,15 +247,7 @@ function! AddTabularPipeline(command, force)
throw "Must provide a list of functions!" throw "Must provide a list of functions!"
endif endif
let cmd = ":call tabular#PipeRange(" . string(pattern) let commandmap[name] = { 'pattern' : pattern, 'commands' : commandlist }
for command in commandlist
let cmd .= "," . string(command)
endfor
let cmd .= ")"
let commandmap[name] = cmd
catch catch
echohl ErrorMsg echohl ErrorMsg
echomsg "AddTabularPipeline: " . v:exception echomsg "AddTabularPipeline: " . v:exception
@ -273,7 +263,15 @@ endfunction
com! -nargs=* -range -complete=customlist,<SID>CompleteTabularizeCommand com! -nargs=* -range -complete=customlist,<SID>CompleteTabularizeCommand
\ Tabularize <line1>,<line2>call Tabularize(<q-args>) \ Tabularize <line1>,<line2>call Tabularize(<q-args>)
function! Tabularize(command) range function! Tabularize(command, ...) range
if a:0
let options = a:1
else
let options = {}
endif
let piperange_opt = { 'mode': get(options, 'mode', '') }
if empty(a:command) if empty(a:command)
if !exists("s:last_tabularize_command") if !exists("s:last_tabularize_command")
echohl ErrorMsg echohl ErrorMsg
@ -301,17 +299,19 @@ function! Tabularize(command) range
let cmd .= ")" let cmd .= ")"
exe range . 'call tabular#PipeRange(pattern, cmd)' exe range . 'call tabular#PipeRangeWithOptions(pattern, [ cmd ], '
\ . 'piperange_opt)'
else else
if exists('b:TabularCommands') && has_key(b:TabularCommands, command) if exists('b:TabularCommands') && has_key(b:TabularCommands, command)
let command = b:TabularCommands[command] let usercmd = b:TabularCommands[command]
elseif has_key(s:TabularCommands, command) elseif has_key(s:TabularCommands, command)
let command = s:TabularCommands[command] let usercmd = s:TabularCommands[command]
else else
throw "Unrecognized command " . string(command) throw "Unrecognized command " . string(command)
endif endif
exe range . command exe range . 'call tabular#PipeRangeWithOptions(usercmd["pattern"], '
\ . 'usercmd["commands"], piperange_opt)'
endif endif
catch catch
echohl ErrorMsg echohl ErrorMsg
@ -339,17 +339,8 @@ endfunction
" 3) If called without a range, it will act on all lines in the buffer (like " 3) If called without a range, it will act on all lines in the buffer (like
" :global) rather than only a single line " :global) rather than only a single line
com! -nargs=* -range=% -complete=customlist,<SID>CompleteTabularizeCommand com! -nargs=* -range=% -complete=customlist,<SID>CompleteTabularizeCommand
\ GTabularize <line1>,<line2>call GTabularize(<q-args>) \ GTabularize <line1>,<line2>
\ call Tabularize(<q-args>, { 'mode': 'GTabularize' } )
function! GTabularize(command) range
call tabular#SetTabularizeMode('GTabularize')
try
exe a:firstline . ',' . a:lastline
\ . 'call Tabularize(' . string(a:command) . ')'
finally
call tabular#SetTabularizeMode('')
endtry
endfunction
" Stupid vimscript crap, part 2 {{{1 " Stupid vimscript crap, part 2 {{{1
let &cpo = s:savecpo let &cpo = s:savecpo