Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern reuse #3

Merged
merged 4 commits into from
Nov 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 13 additions & 87 deletions autoload/tabular.vim
Original file line number Diff line number Diff line change
@@ -1,42 +1,7 @@
" Tabular: Align columnar data using regex-designated column boundaries
" Maintainer: Matthew Wozniski (godlygeek@gmail.com)
" Date: Thu, 03 May 2012 20:49:32 -0400
" Version: 1.0
"
" Long Description:
" Sometimes, it's useful to line up text. Naturally, it's nicer to have the
" computer do this for you, since aligning things by hand quickly becomes
" unpleasant. While there are other plugins for aligning text, the ones I've
" tried are either impossibly difficult to understand and use, or too simplistic
" to handle complicated tasks. This plugin aims to make the easy things easy
" and the hard things possible, without providing an unnecessarily obtuse
" interface. It's still a work in progress, and criticisms are welcome.
"
" License:
" Copyright (c) 2012, Matthew J. Wozniski
" All rights reserved.
"
" Redistribution and use in source and binary forms, with or without
" modification, are permitted provided that the following conditions are met:
" * Redistributions of source code must retain the above copyright notice,
" this list of conditions and the following disclaimer.
" * Redistributions in binary form must reproduce the above copyright
" notice, this list of conditions and the following disclaimer in the
" documentation and/or other materials provided with the distribution.
" * The names of the contributors may not be used to endorse or promote
" products derived from this software without specific prior written
" permission.
"
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
" NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT,
" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
" OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
" Maintainer: Matthew Wozniski (mjw@drexel.edu)
" Date: Thu, 11 Oct 2007 00:35:34 -0400
" Version: 0.1

" Stupid vimscript crap {{{1
let s:savecpo = &cpo
Expand Down Expand Up @@ -219,10 +184,6 @@ function! tabular#TabularizeStrings(strings, delim, ...)
" intentionally
" - Don't strip leading spaces from the first element; we like indenting.
for line in lines
if len(line) == 1 && s:do_gtabularize
continue " Leave non-matching lines unchanged for GTabularize
endif

if line[0] !~ '^\s*$'
let line[0] = s:StripTrailingSpaces(line[0])
endif
Expand All @@ -236,10 +197,6 @@ function! tabular#TabularizeStrings(strings, delim, ...)
" Find the max length of each field
let maxes = []
for line in lines
if len(line) == 1 && s:do_gtabularize
continue " non-matching lines don't affect field widths for GTabularize
endif

for i in range(len(line))
if i == len(maxes)
let maxes += [ s:Strlen(line[i]) ]
Expand All @@ -254,12 +211,6 @@ function! tabular#TabularizeStrings(strings, delim, ...)
" Concatenate the fields, according to the format pattern.
for idx in range(len(lines))
let line = lines[idx]

if len(line) == 1 && s:do_gtabularize
let lines[idx] = line[0] " GTabularize doesn't change non-matching lines
continue
endif

for i in range(len(line))
let how = format[i % len(format)][0]
let pad = format[i % len(format)][1:-1]
Expand All @@ -284,8 +235,6 @@ endfunction
" If the function is called with a range containing multiple lines, then
" those lines will be used as the range.
" If the function is called with no range or with a range of 1 line, then
" if GTabularize mode is being used,
" the range will not be adjusted
" if "includepat" is not specified,
" that 1 line will be filtered,
" if "includepat" is specified and that line does not match it,
Expand All @@ -297,41 +246,24 @@ endfunction
" 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.
function! tabular#PipeRange(includepat, ...) range
exe a:firstline . ',' . a:lastline
\ . 'call tabular#PipeRangeWithOptions(a:includepat, a:000, {})'
endfunction

" Extended version of tabular#PipeRange, which
" 1) Takes the list of filters as an explicit list rather than as varargs
" 2) Supports passing a dictionary of options to control the routine.
" Currently, the only supported option is 'mode', which determines whether
" to behave as :Tabularize or as :GTabularize
" This allows me to add new features here without breaking API compatibility
" in the future.
function! tabular#PipeRangeWithOptions(includepat, filterlist, options) range
let top = a:firstline
let bot = a:lastline

let s:do_gtabularize = (get(a:options, 'mode', '') ==# 'GTabularize')

if !s:do_gtabularize
" In the default mode, apply range extension logic
if a:includepat != '' && top == bot
if top < 0 || top > line('$') || getline(top) !~ a:includepat
return
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
if a:includepat != '' && top == bot
if top < 0 || top > line('$') || getline(top) !~ a:includepat
return
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

let lines = map(range(top, bot), 'getline(v:val)')

for filter in a:filterlist
for filter in a:000
if type(filter) != type("")
echoerr "PipeRange: Bad filter: " . string(filter)
endif
Expand All @@ -344,12 +276,6 @@ function! tabular#PipeRangeWithOptions(includepat, filterlist, options) range
call s:SetLines(top, bot - top + 1, lines)
endfunction

" Part of the public interface so interested pipelines can query this and
" adjust their behavior appropriately.
function! tabular#DoGTabularize()
return s:do_gtabularize
endfunction

function! s:SplitDelimTest(string, delim, expected)
let result = s:SplitDelim(a:string, a:delim)

Expand Down
93 changes: 20 additions & 73 deletions plugin/Tabular.vim
Original file line number Diff line number Diff line change
@@ -1,42 +1,7 @@
" Tabular: Align columnar data using regex-designated column boundaries
" Maintainer: Matthew Wozniski (godlygeek@gmail.com)
" Date: Thu, 03 May 2012 20:49:32 -0400
" Version: 1.0
"
" Long Description:
" Sometimes, it's useful to line up text. Naturally, it's nicer to have the
" computer do this for you, since aligning things by hand quickly becomes
" unpleasant. While there are other plugins for aligning text, the ones I've
" tried are either impossibly difficult to understand and use, or too simplistic
" to handle complicated tasks. This plugin aims to make the easy things easy
" and the hard things possible, without providing an unnecessarily obtuse
" interface. It's still a work in progress, and criticisms are welcome.
"
" License:
" Copyright (c) 2012, Matthew J. Wozniski
" All rights reserved.
"
" Redistribution and use in source and binary forms, with or without
" modification, are permitted provided that the following conditions are met:
" * Redistributions of source code must retain the above copyright notice,
" this list of conditions and the following disclaimer.
" * Redistributions in binary form must reproduce the above copyright
" notice, this list of conditions and the following disclaimer in the
" documentation and/or other materials provided with the distribution.
" * The names of the contributors may not be used to endorse or promote
" products derived from this software without specific prior written
" permission.
"
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS
" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
" NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT,
" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
" OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
" Maintainer: Matthew Wozniski (mjw@drexel.edu)
" Date: Thu, 11 Oct 2007 00:35:34 -0400
" Version: 0.1

" Abort if running in vi-compatible mode or the user doesn't want us.
if &cp || exists('g:tabular_loaded')
Expand Down Expand Up @@ -194,7 +159,9 @@ function! AddTabularPattern(command, force)

let command .= ")"

let commandmap[name] = { 'pattern' : pattern, 'commands' : [ command ] }
let commandmap[name] = ":call tabular#PipeRange("
\ . string(pattern) . ","
\ . string(command) . ")"
catch
echohl ErrorMsg
echomsg "AddTabularPattern: " . v:exception
Expand Down Expand Up @@ -247,7 +214,15 @@ function! AddTabularPipeline(command, force)
throw "Must provide a list of functions!"
endif

let commandmap[name] = { 'pattern' : pattern, 'commands' : commandlist }
let cmd = ":call tabular#PipeRange(" . string(pattern)

for command in commandlist
let cmd .= "," . string(command)
endfor

let cmd .= ")"

let commandmap[name] = cmd
catch
echohl ErrorMsg
echomsg "AddTabularPipeline: " . v:exception
Expand All @@ -263,12 +238,7 @@ endfunction
com! -nargs=* -range -complete=customlist,<SID>CompleteTabularizeCommand
\ Tabularize <line1>,<line2>call Tabularize(<q-args>)

function! Tabularize(command, ...) range
let piperange_opt = {}
if a:0
let piperange_opt = a:1
endif

function! Tabularize(command) range
if empty(a:command)
if !exists("s:last_tabularize_command")
echohl ErrorMsg
Expand Down Expand Up @@ -296,19 +266,17 @@ function! Tabularize(command, ...) range

let cmd .= ")"

exe range . 'call tabular#PipeRangeWithOptions(pattern, [ cmd ], '
\ . 'piperange_opt)'
exe range . 'call tabular#PipeRange(pattern, cmd)'
else
if exists('b:TabularCommands') && has_key(b:TabularCommands, command)
let usercmd = b:TabularCommands[command]
let command = b:TabularCommands[command]
elseif has_key(s:TabularCommands, command)
let usercmd = s:TabularCommands[command]
let command = s:TabularCommands[command]
else
throw "Unrecognized command " . string(command)
endif

exe range . 'call tabular#PipeRangeWithOptions(usercmd["pattern"], '
\ . 'usercmd["commands"], piperange_opt)'
exe range . command
endif
catch
echohl ErrorMsg
Expand All @@ -318,27 +286,6 @@ function! Tabularize(command, ...) range
endtry
endfunction

" GTabularize /pattern[/format] {{{2
" GTabularize name
"
" Align text on only matching lines, either using the given pattern, or the
" command associated with the given name. Mnemonically, this is similar to
" the :global command, which takes some action on all rows matching a pattern
" in a range. This command is different from normal :Tabularize in 3 ways:
" 1) If a line in the range does not match the pattern, it will be left
" unchanged, and not in any way affect the outcome of other lines in the
" range (at least, normally - but Pipelines can and will still look at
" non-matching rows unless they are specifically written to be aware of
" tabular#DoGTabularize() and handle it appropriately).
" 2) No automatic range determination - :Tabularize automatically expands
" a single-line range (or a call with no range) to include all adjacent
" matching lines. That behavior does not make sense for this command.
" 3) If called without a range, it will act on all lines in the buffer (like
" :global) rather than only a single line
com! -nargs=* -range=% -complete=customlist,<SID>CompleteTabularizeCommand
\ GTabularize <line1>,<line2>
\ call Tabularize(<q-args>, { 'mode': 'GTabularize' } )

" Stupid vimscript crap, part 2 {{{1
let &cpo = s:savecpo
unlet s:savecpo
Expand Down