mirror of
https://github.com/amix/vimrc
synced 2025-06-16 09:35:01 +08:00
Updated vim plugins
This commit is contained in:
346
sources_non_forked/tabular/plugin/Tabular.vim
Normal file
346
sources_non_forked/tabular/plugin/Tabular.vim
Normal file
@ -0,0 +1,346 @@
|
||||
" 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.
|
||||
|
||||
" Abort if running in vi-compatible mode or the user doesn't want us.
|
||||
if &cp || exists('g:tabular_loaded')
|
||||
if &cp && &verbose
|
||||
echo "Not loading Tabular in compatible mode."
|
||||
endif
|
||||
finish
|
||||
endif
|
||||
|
||||
let g:tabular_loaded = 1
|
||||
|
||||
" Stupid vimscript crap {{{1
|
||||
let s:savecpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Private Things {{{1
|
||||
|
||||
" Dictionary of command name to command
|
||||
let s:TabularCommands = {}
|
||||
|
||||
" Generate tab completion list for :Tabularize {{{2
|
||||
" Return a list of commands that match the command line typed so far.
|
||||
" NOTE: Tries to handle commands with spaces in the name, but Vim doesn't seem
|
||||
" to handle that terribly well... maybe I should give up on that.
|
||||
function! s:CompleteTabularizeCommand(argstart, cmdline, cursorpos)
|
||||
let names = keys(s:TabularCommands)
|
||||
if exists("b:TabularCommands")
|
||||
let names += keys(b:TabularCommands)
|
||||
endif
|
||||
|
||||
let cmdstart = substitute(a:cmdline, '^\s*\S\+\s*', '', '')
|
||||
|
||||
return filter(names, 'v:val =~# ''^\V'' . escape(cmdstart, ''\'')')
|
||||
endfunction
|
||||
|
||||
" Choose the proper command map from the given command line {{{2
|
||||
" Returns [ command map, command line with leading <buffer> removed ]
|
||||
function! s:ChooseCommandMap(commandline)
|
||||
let map = s:TabularCommands
|
||||
let cmd = a:commandline
|
||||
|
||||
if cmd =~# '^<buffer>\s\+'
|
||||
if !exists('b:TabularCommands')
|
||||
let b:TabularCommands = {}
|
||||
endif
|
||||
let map = b:TabularCommands
|
||||
let cmd = substitute(cmd, '^<buffer>\s\+', '', '')
|
||||
endif
|
||||
|
||||
return [ map, cmd ]
|
||||
endfunction
|
||||
|
||||
" Parse '/pattern/format' into separate pattern and format parts. {{{2
|
||||
" If parsing fails, return [ '', '' ]
|
||||
function! s:ParsePattern(string)
|
||||
if a:string[0] != '/'
|
||||
return ['','']
|
||||
endif
|
||||
|
||||
let pat = '\\\@<!\%(\\\\\)\{-}\zs/' . tabular#ElementFormatPattern() . '*$'
|
||||
let format = matchstr(a:string[1:-1], pat)
|
||||
if !empty(format)
|
||||
let format = format[1 : -1]
|
||||
let pattern = a:string[1 : -len(format) - 2]
|
||||
else
|
||||
let pattern = a:string[1 : -1]
|
||||
endif
|
||||
|
||||
return [pattern, format]
|
||||
endfunction
|
||||
|
||||
" Split apart a list of | separated expressions. {{{2
|
||||
function! s:SplitCommands(string)
|
||||
if a:string =~ '^\s*$'
|
||||
return []
|
||||
endif
|
||||
|
||||
let end = match(a:string, "[\"'|]")
|
||||
|
||||
" Loop until we find a delimiting | or end-of-string
|
||||
while end != -1 && (a:string[end] != '|' || a:string[end+1] == '|')
|
||||
if a:string[end] == "'"
|
||||
let end = match(a:string, "'", end+1) + 1
|
||||
if end == 0
|
||||
throw "No matching end single quote"
|
||||
endif
|
||||
elseif a:string[end] == '"'
|
||||
" Find a " preceded by an even number of \ (or 0)
|
||||
let pattern = '\%(\\\@<!\%(\\\\\)*\)\@<="'
|
||||
let end = matchend(a:string, pattern, end+1) + 1
|
||||
if end == 0
|
||||
throw "No matching end double quote"
|
||||
endif
|
||||
else " Found ||
|
||||
let end += 2
|
||||
endif
|
||||
|
||||
let end = match(a:string, "[\"'|]", end)
|
||||
endwhile
|
||||
|
||||
if end == 0 || a:string[0 : end - (end > 0)] =~ '^\s*$'
|
||||
throw "Empty element"
|
||||
endif
|
||||
|
||||
if end == -1
|
||||
let rv = [ a:string ]
|
||||
else
|
||||
let rv = [ a:string[0 : end-1] ] + s:SplitCommands(a:string[end+1 : -1])
|
||||
endif
|
||||
|
||||
return rv
|
||||
endfunction
|
||||
|
||||
" Public Things {{{1
|
||||
|
||||
" Command associating a command name with a simple pattern command {{{2
|
||||
" AddTabularPattern[!] [<buffer>] name /pattern[/format]
|
||||
"
|
||||
" If <buffer> is provided, the command will only be available in the current
|
||||
" buffer, and will be used instead of any global command with the same name.
|
||||
"
|
||||
" If a command with the same name and scope already exists, it is an error,
|
||||
" unless the ! is provided, in which case the existing command will be
|
||||
" replaced.
|
||||
"
|
||||
" pattern is a regex describing the delimiter to be used.
|
||||
"
|
||||
" format describes the format pattern to be used. The default will be used if
|
||||
" none is provided.
|
||||
com! -nargs=+ -bang AddTabularPattern
|
||||
\ call AddTabularPattern(<q-args>, <bang>0)
|
||||
|
||||
function! AddTabularPattern(command, force)
|
||||
try
|
||||
let [ commandmap, rest ] = s:ChooseCommandMap(a:command)
|
||||
|
||||
let name = matchstr(rest, '.\{-}\ze\s*/')
|
||||
let pattern = substitute(rest, '.\{-}\s*\ze/', '', '')
|
||||
|
||||
let [ pattern, format ] = s:ParsePattern(pattern)
|
||||
|
||||
if empty(name) || empty(pattern)
|
||||
throw "Invalid arguments!"
|
||||
endif
|
||||
|
||||
if !a:force && has_key(commandmap, name)
|
||||
throw string(name) . " is already defined, use ! to overwrite."
|
||||
endif
|
||||
|
||||
let command = "tabular#TabularizeStrings(a:lines, " . string(pattern)
|
||||
|
||||
if !empty(format)
|
||||
let command .= ", " . string(format)
|
||||
endif
|
||||
|
||||
let command .= ")"
|
||||
|
||||
let commandmap[name] = { 'pattern' : pattern, 'commands' : [ command ] }
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echomsg "AddTabularPattern: " . v:exception
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Command associating a command name with a pipeline of functions {{{2
|
||||
" AddTabularPipeline[!] [<buffer>] name /pattern/ func [ | func2 [ | func3 ] ]
|
||||
"
|
||||
" If <buffer> is provided, the command will only be available in the current
|
||||
" buffer, and will be used instead of any global command with the same name.
|
||||
"
|
||||
" If a command with the same name and scope already exists, it is an error,
|
||||
" unless the ! is provided, in which case the existing command will be
|
||||
" replaced.
|
||||
"
|
||||
" pattern is a regex that will be used to determine which lines will be
|
||||
" filtered. If the cursor line doesn't match the pattern, using the command
|
||||
" will be a no-op, otherwise the cursor and all contiguous lines matching the
|
||||
" pattern will be filtered.
|
||||
"
|
||||
" Each 'func' argument represents a function to be called. This function
|
||||
" will have access to a:lines, a List containing one String per line being
|
||||
" filtered.
|
||||
com! -nargs=+ -bang AddTabularPipeline
|
||||
\ call AddTabularPipeline(<q-args>, <bang>0)
|
||||
|
||||
function! AddTabularPipeline(command, force)
|
||||
try
|
||||
let [ commandmap, rest ] = s:ChooseCommandMap(a:command)
|
||||
|
||||
let name = matchstr(rest, '.\{-}\ze\s*/')
|
||||
let pattern = substitute(rest, '.\{-}\s*\ze/', '', '')
|
||||
|
||||
let commands = matchstr(pattern, '^/.\{-}\\\@<!\%(\\\\\)\{-}/\zs.*')
|
||||
let pattern = matchstr(pattern, '/\zs.\{-}\\\@<!\%(\\\\\)\{-}\ze/')
|
||||
|
||||
if empty(name) || empty(pattern)
|
||||
throw "Invalid arguments!"
|
||||
endif
|
||||
|
||||
if !a:force && has_key(commandmap, name)
|
||||
throw string(name) . " is already defined, use ! to overwrite."
|
||||
endif
|
||||
|
||||
let commandlist = s:SplitCommands(commands)
|
||||
|
||||
if empty(commandlist)
|
||||
throw "Must provide a list of functions!"
|
||||
endif
|
||||
|
||||
let commandmap[name] = { 'pattern' : pattern, 'commands' : commandlist }
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echomsg "AddTabularPipeline: " . v:exception
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Tabularize /pattern[/format] {{{2
|
||||
" Tabularize name
|
||||
"
|
||||
" Align text, either using the given pattern, or the command associated with
|
||||
" the given name.
|
||||
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
|
||||
|
||||
if empty(a:command)
|
||||
if !exists("s:last_tabularize_command")
|
||||
echohl ErrorMsg
|
||||
echomsg "Tabularize hasn't been called yet; no pattern/command to reuse!"
|
||||
echohl None
|
||||
return
|
||||
endif
|
||||
else
|
||||
let s:last_tabularize_command = a:command
|
||||
endif
|
||||
|
||||
let command = s:last_tabularize_command
|
||||
|
||||
let range = a:firstline . ',' . a:lastline
|
||||
|
||||
try
|
||||
let [ pattern, format ] = s:ParsePattern(command)
|
||||
|
||||
if !empty(pattern)
|
||||
let cmd = "tabular#TabularizeStrings(a:lines, " . string(pattern)
|
||||
|
||||
if !empty(format)
|
||||
let cmd .= "," . string(format)
|
||||
endif
|
||||
|
||||
let cmd .= ")"
|
||||
|
||||
exe range . 'call tabular#PipeRangeWithOptions(pattern, [ cmd ], '
|
||||
\ . 'piperange_opt)'
|
||||
else
|
||||
if exists('b:TabularCommands') && has_key(b:TabularCommands, command)
|
||||
let usercmd = b:TabularCommands[command]
|
||||
elseif has_key(s:TabularCommands, command)
|
||||
let usercmd = s:TabularCommands[command]
|
||||
else
|
||||
throw "Unrecognized command " . string(command)
|
||||
endif
|
||||
|
||||
exe range . 'call tabular#PipeRangeWithOptions(usercmd["pattern"], '
|
||||
\ . 'usercmd["commands"], piperange_opt)'
|
||||
endif
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echomsg "Tabularize: " . v:exception
|
||||
echohl None
|
||||
return
|
||||
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
|
||||
|
||||
" vim:set sw=2 sts=2 fdm=marker:
|
Reference in New Issue
Block a user