1
0
mirror of https://github.com/amix/vimrc synced 2025-06-16 01:25:00 +08:00

lets try again...

This commit is contained in:
amix
2012-08-16 23:41:25 -04:00
parent 85888ddbd3
commit bb9c85e523
306 changed files with 47995 additions and 21 deletions

View File

@ -0,0 +1,72 @@
This is a mirror of http://www.vim.org/scripts/script.php?script_id=1863
This library provides some utility functions. There isn't much need to
install it unless another plugin requires you to do so.
The most useful functions provided by this library probably are:
tlib#input#List(), tlib#input#ListW()
- Display a list
- Dynamically filter items matching a pattern (somethat like google)
- E.g. you filter for "foo -bar": show all entries containing foo but not bar.
- Select items from a list
- Do stuff
- Developers can define keys that trigger some action with the
selected items
- Demo: http://vimsomnia.blogspot.com/2010/11/selecting-items-from-list-with-tlibs.html
tlib#input#EditList
+ Edit a list (copy, cut, paste, delete, edit ...)
:TLet VAR = VALUE
Set a variable only if it doesn't already exist.
:TScratch
Open a scratch buffer (a buffer without a file).
:TVarArg VAR1, [VAR2, DEFAULT2] ...
Handle "rest" (variable) arguments in functions.
EXAMPLES:
function! Foo(...)
TVarArg ['a', 1], 'b'
echo 'a='. a
echo 'b='. b
endf
TBrowseOutput COMMAND
Every wondered how to effciently browse the output of a command
without redirecting it to a file? This command takes a command as
argument and presents the output via |tlib#input#List()| so that you
can easily search for a keyword (e.g. the name of a variable or
function) and the like.
If you press enter, the selected line will be copied to the command
line. Press ESC to cancel browsing.
EXAMPLES:
TBrowseOutput 20verb TeaseTheCulprit
TBrowseOutput let
TBrowseOutput map
Related (small) plugins that utilize tlib and thus provide some degree of uniform user experience:
tbibtools (vimscript #1915): bibtex-related utilities (sort, reformat, list contents ...)
tmarks (vimscript #2594): Browse, place, & delete marks
tmboxbrowser (vimscript #1906): A mbox browser -- Read your e-mails with vim
tmru (vimscript #1864): Most Recently Used Files
trag (vimscript #2033): A slightly language-aware alternative to grep
tregisters (vimscript #2017): List, edit, and run/execute registers/clipboards
tselectbuffer (vimscript #1866): A quick buffer selector/switcher
tselectfiles (vimscript #1865): A quick file selector/browser/explorer (sort of)
ttagecho (vimscript #2055): Show current tag information
ttagcomplete (vimscript #2069): Context-sensitive tags-based completion and code skeletons
ttags (vimscript #2018): Tag list browser (List, filter, preview, jump to tags)
ttoc (vimscript #2014): A regexp-based table of contents of the current buffer
vikitasks (vimscript #2894): Search viki files for tasks and display them in a list
For full details, please see:
http://github.com/tomtom/tlib_vim/blob/master/doc/tlib.txt
Also available via git
http://github.com/tomtom/tlib_vim

View File

@ -0,0 +1,12 @@
" tlib.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-07-17.
" @Last Change: 2010-01-03.
" @Revision: 0.0.7
" call tlog#Log('Load: '. expand('<sfile>')) " vimtlib-sfile
" Dummy file for backwards compatibility.

View File

@ -0,0 +1,151 @@
" Filter_cnf.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-11-25.
" @Last Change: 2010-11-20.
" @Revision: 0.0.79
let s:prototype = tlib#Object#New({'_class': ['Filter_cnf'], 'name': 'cnf'}) "{{{2
let s:prototype.highlight = g:tlib_inputlist_higroup
" The search pattern for |tlib#input#List()| is in conjunctive normal
" form: (P1 OR P2 ...) AND (P3 OR P4 ...) ...
" The pattern is a '/\V' very no-'/magic' regexp pattern.
"
" Pressing <space> joins two patterns with AND.
" Pressing | joins two patterns with OR.
" I.e. In order to get "lala AND (foo OR bar)", you type
" "lala foo|bar".
"
" This is also the base class for other filters.
function! tlib#Filter_cnf#New(...) "{{{3
let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
return object
endf
" :nodoc:
function! s:prototype.Init(world) dict "{{{3
endf
" :nodoc:
function! s:prototype.AssessName(world, name) dict "{{{3
let xa = 0
let prefix = self.FilterRxPrefix()
for flt in a:world.filter_pos
" let flt = prefix . a:world.GetRx(fltl)
" if flt =~# '\u' && a:name =~# flt
" let xa += 5
" endif
if a:name =~ '\^'. flt
let xa += 4
elseif a:name =~ '\<'. flt
let xa += 3
" elseif a:name =~ '[[:punct:][:space:][:digit:]]'. flt
" let xa += 2
elseif a:name =~ '\A'. flt .'\|'. flt .'\A'
let xa += 1
endif
" if a:name =~ '\^'. flt .'\|'. flt .'\$'
" let xa += 4
" elseif a:name =~ '\<'. flt .'\|'. flt .'\>'
" let xa += 3
" " elseif a:name =~ flt .'\>'
" " let xa += 2
" elseif a:name =~ '\A'. flt .'\|'. flt .'\A'
" let xa += 1
" endif
" if flt[0] =~# '\u' && matchstr(a:name, '\V\.\ze'. flt) =~# '\U'
" let xa += 1
" endif
" if flt[0] =~# '\U' && matchstr(a:name, '\V\.\ze'. flt) =~# '\u'
" let xa += 1
" endif
" if flt[-1] =~# '\u' && matchstr(a:name, '\V'. flt .'\zs\.') =~# '\U'
" let xa += 1
" endif
" if flt[-1] =~# '\U' && matchstr(a:name, '\V'. flt .'\zs\.') =~# '\u'
" let xa += 1
" endif
endfor
" TLogVAR a:name, xa
return xa
endf
" :nodoc:
function! s:prototype.Match(world, text) dict "{{{3
" TLogVAR a:text
" let sc = &smartcase
" let ic = &ignorecase
" if &ignorecase
" set smartcase
" endif
" try
for rx in a:world.filter_neg
" TLogVAR rx
if a:text =~ rx
return 0
endif
endfor
for rx in a:world.filter_pos
" TLogVAR rx
if a:text !~ rx
return 0
endif
endfor
" finally
" let &smartcase = sc
" let &ignorecase = ic
" endtry
return 1
endf
" :nodoc:
function! s:prototype.DisplayFilter(filter) dict "{{{3
let filter1 = deepcopy(a:filter)
call map(filter1, '"(". join(reverse(s:Pretty(v:val)), " OR ") .")"')
return join(reverse(filter1), ' AND ')
endf
function! s:Pretty(filter) "{{{3
call map(a:filter, 'substitute(v:val, ''\\\.\\{-}'', ''__'', ''g'')')
return a:filter
endf
" :nodoc:
function! s:prototype.SetFrontFilter(world, pattern) dict "{{{3
let a:world.filter[0] = reverse(split(a:pattern, '\s*|\s*')) + a:world.filter[0][1 : -1]
endf
" :nodoc:
function! s:prototype.PushFrontFilter(world, char) dict "{{{3
let a:world.filter[0][0] .= nr2char(a:char)
endf
" :nodoc:
function! s:prototype.ReduceFrontFilter(world) dict "{{{3
let a:world.filter[0][0] = a:world.filter[0][0][0:-2]
endf
" :nodoc:
function! s:prototype.FilterRxPrefix() dict "{{{3
return '\V'
endf
" :nodoc:
function! s:prototype.CleanFilter(filter) dict "{{{3
return a:filter
endf

View File

@ -0,0 +1,54 @@
" Filter_cnfd.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-11-25.
" @Last Change: 2010-09-15.
" @Revision: 0.0.35
let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_cnfd'], 'name': 'cnfd'}) "{{{2
let s:prototype.highlight = g:tlib_inputlist_higroup
" The same as |tlib#FilterCNF#New()| but a dot is expanded to '\.\{-}'.
" As a consequence, patterns cannot match dots.
" The pattern is a '/\V' very no-'/magic' regexp pattern.
function! tlib#Filter_cnfd#New(...) "{{{3
let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
return object
endf
" :nodoc:
function! s:prototype.Init(world) dict "{{{3
endf
" :nodoc:
function! s:prototype.SetFrontFilter(world, pattern) dict "{{{3
let pattern = substitute(a:pattern, '\.', '\\.\\{-}', 'g')
let a:world.filter[0] = reverse(split(pattern, '\s*|\s*')) + a:world.filter[0][1 : -1]
endf
" :nodoc:
function! s:prototype.PushFrontFilter(world, char) dict "{{{3
let a:world.filter[0][0] .= a:char == 46 ? '\.\{-}' : nr2char(a:char)
endf
" :nodoc:
function! s:prototype.ReduceFrontFilter(world) dict "{{{3
let flt = a:world.filter[0][0]
if flt =~ '\\\.\\{-}$'
let a:world.filter[0][0] = flt[0:-7]
else
let a:world.filter[0][0] = flt[0:-2]
endif
endf
" :nodoc:
function! s:prototype.CleanFilter(filter) dict "{{{3
return substitute(a:filter, '\\.\\{-}', '.', 'g')
endf

View File

@ -0,0 +1,73 @@
" Filter_fuzzy.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-11-25.
" @Last Change: 2010-09-15.
" @Revision: 0.0.38
let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_fuzzy'], 'name': 'fuzzy'}) "{{{2
let s:prototype.highlight = ''
" Support for "fuzzy" pattern matching in |tlib#input#List()|.
" Characters are interpreted as if connected with '.\{-}'.
"
" In "fuzzy" mode, the pretty printing of filenames is disabled.
function! tlib#Filter_fuzzy#New(...) "{{{3
let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
return object
endf
" :nodoc:
function! s:prototype.Init(world) dict "{{{3
" TLogVAR a:world.display_format
function! a:world.Set_display_format(value) dict "{{{3
if a:value == 'filename'
let self.display_format = ''
else
let self.display_format = a:value
endif
endf
endf
" :nodoc:
function! s:prototype.DisplayFilter(filter) dict "{{{3
" TLogVAR a:filter
let filter1 = deepcopy(a:filter)
call map(filter1, '"{". join(reverse(v:val), " OR ") ."}"')
return join(reverse(filter1), ' AND ')
endf
" :nodoc:
function! s:prototype.SetFrontFilter(world, pattern) dict "{{{3
let a:world.filter[0] = map(reverse(split(a:pattern, '\s*|\s*')), 'join(map(split(v:val, ''\zs''), ''tlib#rx#Escape(v:val, "V")''), ''\.\{-}'')') + a:world.filter[0][1 : -1]
endif
endf
" :nodoc:
function! s:prototype.PushFrontFilter(world, char) dict "{{{3
let ch = tlib#rx#Escape(nr2char(a:char), 'V')
if empty(a:world.filter[0][0])
let a:world.filter[0][0] .= ch
else
let a:world.filter[0][0] .= '\.\{-}'. ch
endif
endf
" :nodoc:
function! s:prototype.ReduceFrontFilter(world) dict "{{{3
let a:world.filter[0][0] = substitute(a:world.filter[0][0], '\(\\\.\\{-}\)\?.$', '', '')
endf
" :nodoc:
function! s:prototype.CleanFilter(filter) dict "{{{3
return substitute(a:filter, '\\\.\\{-}', '', 'g')
endf

View File

@ -0,0 +1,98 @@
" Filter_seq.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-11-25.
" @Last Change: 2010-11-20.
" @Revision: 0.0.30
let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_seq'], 'name': 'seq'}) "{{{2
let s:prototype.highlight = g:tlib_inputlist_higroup
" The search pattern for |tlib#input#List()| is interpreted as a
" disjunction of 'magic' regular expressions with the exception of a dot
" ".", which is interpreted as ".\{-}".
" The pattern is a '/magic' regexp pattern.
function! tlib#Filter_seq#New(...) "{{{3
let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
return object
endf
" :nodoc:
function! s:prototype.Init(world) dict "{{{3
endf
" :nodoc:
function! s:prototype.Match(world, text) dict "{{{3
" TLogVAR a:text
for rx in a:world.filter_neg
if a:text !~ rx
" TLogDBG "filter_neg ". rx
return 1
endif
endfor
for rx in a:world.filter_pos
if a:text =~ rx
" TLogDBG "filter_pos ". rx
return 1
endif
endfor
return 0
endf
" :nodoc:
function! s:prototype.DisplayFilter(filter) dict "{{{3
let filter1 = deepcopy(a:filter)
call map(filter1, '"(". join(reverse(s:Pretty(v:val)), "_") .")"')
return join(reverse(filter1), ' OR ')
endf
function! s:Pretty(filter) "{{{3
call map(a:filter, 's:prototype.CleanFilter(v:val)')
return a:filter
endf
" :nodoc:
function! s:prototype.SetFrontFilter(world, pattern) dict "{{{3
let a:world.filter[0] = map(reverse(split(a:pattern, '\s*|\s*')), 'join(split(v:val, ''\.''), ''.\{-}'')') + a:world.filter[0][1 : -1]
endf
" :nodoc:
function! s:prototype.PushFrontFilter(world, char) dict "{{{3
let cc = nr2char(a:char)
if cc == '.'
let a:world.filter[0][0] .= '.\{-}'
else
let a:world.filter[0][0] .= nr2char(a:char)
endif
endf
" :nodoc:
function! s:prototype.ReduceFrontFilter(world) dict "{{{3
let flt = a:world.filter[0][0]
if flt =~ '\.\\{-}$'
let a:world.filter[0][0] = flt[0:-6]
else
let a:world.filter[0][0] = flt[0:-2]
endif
endf
" :nodoc:
function! s:prototype.FilterRxPrefix() dict "{{{3
return ''
endf
" :nodoc:
function! s:prototype.CleanFilter(filter) dict "{{{3
return substitute(a:filter, '.\\{-}', '.', 'g')
endf

View File

@ -0,0 +1,163 @@
" Object.vim -- Prototype objects?
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-05-01.
" @Last Change: 2011-03-10.
" @Revision: 0.1.126
" :filedoc:
" Provides a prototype plus some OO-like methods.
if &cp || exists("loaded_tlib_object_autoload")
finish
endif
let loaded_tlib_object_autoload = 1
let s:id_counter = 0
let s:prototype = {'_class': ['object'], '_super': [], '_id': 0} "{{{2
" :def: function! tlib#Object#New(?fields={})
" This function creates a prototype that provides some kind of
" inheritance mechanism and a way to call parent/super methods.
"
" The usage demonstrated in the following example works best when every
" class/prototype is defined in a file of its own.
"
" The reason for why there is a dedicated constructor function is that
" this layout facilitates the use of templates and that methods are
" hidden from the user. Other solutions are possible.
"
" EXAMPLES: >
" let s:prototype = tlib#Object#New({
" \ '_class': ['FooBar'],
" \ 'foo': 1,
" \ 'bar': 2,
" \ })
" " Constructor
" function! FooBar(...)
" let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
" return object
" endf
" function! s:prototype.babble() {
" echo "I think, therefore I am ". (self.foo * self.bar) ." months old."
" }
"
" < This could now be used like this: >
" let myfoo = FooBar({'foo': 3})
" call myfoo.babble()
" => I think, therefore I am 6 months old.
" echo myfoo.IsA('FooBar')
" => 1
" echo myfoo.IsA('object')
" => 1
" echo myfoo.IsA('Foo')
" => 0
" echo myfoo.RespondTo('babble')
" => 1
" echo myfoo.RespondTo('speak')
" => 0
function! tlib#Object#New(...) "{{{3
return s:prototype.New(a:0 >= 1 ? a:1 : {})
endf
function! s:prototype.New(...) dict "{{{3
let object = deepcopy(self)
let s:id_counter += 1
let object._id = s:id_counter
if a:0 >= 1 && !empty(a:1)
" call object.Extend(deepcopy(a:1))
call object.Extend(a:1)
endif
return object
endf
function! s:prototype.Inherit(object) dict "{{{3
let class = copy(self._class)
" TLogVAR class
let objid = self._id
for c in get(a:object, '_class', [])
" TLogVAR c
if index(class, c) == -1
call add(class, c)
endif
endfor
call extend(self, a:object, 'keep')
let self._class = class
" TLogVAR self._class
let self._id = objid
" let self._super = [super] + self._super
call insert(self._super, a:object)
return self
endf
function! s:prototype.Extend(dictionary) dict "{{{3
let super = copy(self)
let class = copy(self._class)
" TLogVAR class
let objid = self._id
let thisclass = get(a:dictionary, '_class', [])
for c in type(thisclass) == 3 ? thisclass : [thisclass]
" TLogVAR c
if index(class, c) == -1
call add(class, c)
endif
endfor
call extend(self, a:dictionary)
let self._class = class
" TLogVAR self._class
let self._id = objid
" let self._super = [super] + self._super
call insert(self._super, super)
return self
endf
function! s:prototype.IsA(class) dict "{{{3
return index(self._class, a:class) != -1
endf
function! s:prototype.IsRelated(object) dict "{{{3
return len(filter(a:object._class, 'self.IsA(v:val)')) > 1
endf
function! s:prototype.RespondTo(name) dict "{{{3
" return has_key(self, a:name) && type(self[a:name]) == 2
return has_key(self, a:name)
endf
function! s:prototype.Super(method, arglist) dict "{{{3
for o in self._super
" TLogVAR o
if o.RespondTo(a:method)
" let self._tmp_method = o[a:method]
" TLogVAR self._tmp_method
" return call(self._tmp_method, a:arglist, self)
return call(o[a:method], a:arglist, self)
endif
endfor
echoerr 'tlib#Object: Does not respond to '. a:method .': '. string(self)
endf
function! tlib#Object#Methods(object, ...) "{{{3
TVarArg ['pattern', '\d\+']
let o = items(a:object)
call filter(o, 'type(v:val[1]) == 2 && string(v:val[1]) =~ "^function(''\\d\\+'')"')
let acc = {}
for e in o
let id = matchstr(string(e[1]), pattern)
if !empty(id)
let acc[id] = e[0]
endif
endfor
return acc
endf

View File

@ -0,0 +1,27 @@
" Test.vim -- A test class
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-05-01.
" @Last Change: 2010-09-05.
" @Revision: 0.1.10
" :enddoc:
if &cp || exists("loaded_tlib_Test_autoload")
finish
endif
let loaded_tlib_Test_autoload = 1
let s:prototype = tlib#Object#New({'_class': ['Test']}) "{{{2
function! tlib#Test#New(...) "{{{3
let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
return object
endf
function! s:prototype.Dummy() dict "{{{3
return 'Test.vim'
endf

View File

@ -0,0 +1,27 @@
" TestChild.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-05-18.
" @Last Change: 2010-09-05.
" @Revision: 0.1.14
" :enddoc:
if &cp || exists("loaded_tlib_TestChild_autoload")
finish
endif
let loaded_tlib_TestChild_autoload = 1
let s:prototype = tlib#Test#New({'_class': ['TestChild']}) "{{{2
function! tlib#TestChild#New(...) "{{{3
let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
return object
endf
function! s:prototype.Dummy() dict "{{{3
return 'TestChild.vim'
endf

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,514 @@
" agent.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-24.
" @Last Change: 2010-11-20.
" @Revision: 0.1.185
" :filedoc:
" Various agents for use as key handlers in tlib#input#List()
" General {{{1
function! tlib#agent#Exit(world, selected) "{{{3
call a:world.CloseScratch()
let a:world.state = 'exit empty escape'
let a:world.list = []
" let a:world.base = []
call a:world.ResetSelected()
return a:world
endf
function! tlib#agent#CopyItems(world, selected) "{{{3
let @* = join(a:selected, "\n")
let a:world.state = 'redisplay'
return a:world
endf
" InputList related {{{1
function! tlib#agent#PageUp(world, selected) "{{{3
let a:world.offset -= (winheight(0) / 2)
let a:world.state = 'scroll'
return a:world
endf
function! tlib#agent#PageDown(world, selected) "{{{3
let a:world.offset += (winheight(0) / 2)
let a:world.state = 'scroll'
return a:world
endf
function! tlib#agent#Up(world, selected, ...) "{{{3
TVarArg ['lines', 1]
let a:world.idx = ''
if a:world.prefidx > lines
let a:world.prefidx -= lines
else
let a:world.prefidx = len(a:world.list)
endif
let a:world.state = 'redisplay'
return a:world
endf
function! tlib#agent#Down(world, selected, ...) "{{{3
TVarArg ['lines', 1]
let a:world.idx = ''
if a:world.prefidx <= (len(a:world.list) - lines)
let a:world.prefidx += lines
else
let a:world.prefidx = 1
endif
let a:world.state = 'redisplay'
return a:world
endf
function! tlib#agent#UpN(world, selected) "{{{3
return tlib#agent#Up(a:world, a:selected, g:tlib_scroll_lines)
endf
function! tlib#agent#DownN(world, selected) "{{{3
return tlib#agent#Down(a:world, a:selected, g:tlib_scroll_lines)
endf
function! tlib#agent#ShiftLeft(world, selected) "{{{3
let a:world.offset_horizontal -= (winwidth(0) / 2)
if a:world.offset_horizontal < 0
let a:world.offset_horizontal = 0
endif
let a:world.state = 'display shift'
return a:world
endf
function! tlib#agent#ShiftRight(world, selected) "{{{3
let a:world.offset_horizontal += (winwidth(0) / 2)
let a:world.state = 'display shift'
return a:world
endf
function! tlib#agent#Reset(world, selected) "{{{3
let a:world.state = 'reset'
return a:world
endf
function! tlib#agent#Input(world, selected) "{{{3
let flt0 = a:world.CleanFilter(a:world.filter[0][0])
let flt1 = input('Filter: ', flt0)
echo
if flt1 != flt0
if empty(flt1)
call getchar(0)
else
call a:world.SetFrontFilter(flt1)
endif
endif
let a:world.state = 'display'
return a:world
endf
" Suspend (see |tlib#agent#Suspend|) the input loop and jump back to the
" original position in the parent window.
function! tlib#agent#SuspendToParentWindow(world, selected) "{{{3
let world = a:world
let winnr = world.win_wnr
" TLogVAR winnr
if winnr != -1
let world = tlib#agent#Suspend(world, a:selected)
if world.state =~ '\<suspend\>'
call world.SwitchWindow('win')
" let pos = world.cursor
" " TLogVAR pos
" if !empty(pos)
" call setpos('.', pos)
" endif
return world
endif
endif
let world.state = 'redisplay'
return world
endf
" Suspend lets you temporarily leave the input loop of
" |tlib#input#List|. You can resume editing the list by pressing <c-z>,
" <m-z>. <space>, <c-LeftMouse> or <MiddleMouse> in the suspended window.
" <cr> and <LeftMouse> will immediatly select the item under the cursor.
" < will select the item but the window will remain opened.
function! tlib#agent#Suspend(world, selected) "{{{3
if a:world.allow_suspend
" TAssert IsNotEmpty(a:world.scratch)
" TLogDBG bufnr('%')
let br = tlib#buffer#Set(a:world.scratch)
" TLogVAR br, a:world.bufnr, a:world.scratch
" TLogDBG bufnr('%')
call tlib#autocmdgroup#Init()
autocmd TLib InsertEnter,InsertChange <buffer> call tlib#input#Resume("world", 0)
let b:tlib_suspend = {
\ '<m-z>': 0, '<c-z>': 0, '<space>': 0,
\ '<cr>': 1,
\ '<LeftMouse>': 1, '<MiddleMouse>': 0, '<RightMouse>': 0, '<c-LeftMouse>': 0,
\ '<': 2}
for [m, pick] in items(b:tlib_suspend)
exec 'noremap <buffer> '. m .' :call tlib#input#Resume("world", '. pick .')<cr>'
endfor
let b:tlib_world = a:world
exec br
let a:world.state = 'exit suspend'
else
echom 'Suspend disabled'
let a:world.state = 'redisplay'
endif
return a:world
endf
function! tlib#agent#Help(world, selected) "{{{3
let a:world.state = 'help'
return a:world
endf
function! tlib#agent#OR(world, selected) "{{{3
if !empty(a:world.filter[0])
call insert(a:world.filter[0], '')
endif
let a:world.state = 'display'
return a:world
endf
function! tlib#agent#AND(world, selected) "{{{3
if !empty(a:world.filter[0])
call insert(a:world.filter, [''])
endif
let a:world.state = 'display'
return a:world
endf
function! tlib#agent#ReduceFilter(world, selected) "{{{3
call a:world.ReduceFilter()
let a:world.offset = 1
let a:world.state = 'display'
return a:world
endf
function! tlib#agent#PopFilter(world, selected) "{{{3
call a:world.PopFilter()
let a:world.offset = 1
let a:world.state = 'display'
return a:world
endf
function! tlib#agent#Debug(world, selected) "{{{3
" echo string(world.state)
echo string(a:world.filter)
echo string(a:world.idx)
echo string(a:world.prefidx)
echo string(a:world.sel_idx)
call getchar()
let a:world.state = 'display'
return a:world
endf
function! tlib#agent#Select(world, selected) "{{{3
call a:world.SelectItem('toggle', a:world.prefidx)
" let a:world.state = 'display keepcursor'
let a:world.state = 'redisplay'
return a:world
endf
function! tlib#agent#SelectUp(world, selected) "{{{3
call a:world.SelectItem('toggle', a:world.prefidx)
if a:world.prefidx > 1
let a:world.prefidx -= 1
endif
let a:world.state = 'redisplay'
return a:world
endf
function! tlib#agent#SelectDown(world, selected) "{{{3
call a:world.SelectItem('toggle', a:world.prefidx)
if a:world.prefidx < len(a:world.list)
let a:world.prefidx += 1
endif
let a:world.state = 'redisplay'
return a:world
endf
function! tlib#agent#SelectAll(world, selected) "{{{3
let listrange = range(1, len(a:world.list))
let mode = empty(filter(copy(listrange), 'index(a:world.sel_idx, a:world.GetBaseIdx(v:val)) == -1'))
\ ? 'toggle' : 'set'
for i in listrange
call a:world.SelectItem(mode, i)
endfor
let a:world.state = 'display keepcursor'
return a:world
endf
function! tlib#agent#ToggleStickyList(world, selected) "{{{3
let a:world.sticky = !a:world.sticky
let a:world.state = 'display keepcursor'
return a:world
endf
" EditList related {{{1
function! tlib#agent#EditItem(world, selected) "{{{3
let lidx = a:world.prefidx
" TLogVAR lidx
" TLogVAR a:world.table
let bidx = a:world.GetBaseIdx(lidx)
" TLogVAR bidx
let item = a:world.GetBaseItem(bidx)
let item = input(lidx .'@'. bidx .': ', item)
if item != ''
call a:world.SetBaseItem(bidx, item)
endif
let a:world.state = 'display'
return a:world
endf
" Insert a new item below the current one.
function! tlib#agent#NewItem(world, selected) "{{{3
let basepi = a:world.GetBaseIdx(a:world.prefidx)
let item = input('New item: ')
call insert(a:world.base, item, basepi)
let a:world.state = 'reset'
return a:world
endf
function! tlib#agent#DeleteItems(world, selected) "{{{3
let remove = copy(a:world.sel_idx)
let basepi = a:world.GetBaseIdx(a:world.prefidx)
if index(remove, basepi) == -1
call add(remove, basepi)
endif
" call map(remove, 'a:world.GetBaseIdx(v:val)')
for idx in reverse(sort(remove))
call remove(a:world.base, idx - 1)
endfor
let a:world.state = 'display'
call a:world.ResetSelected()
" let a:world.state = 'reset'
return a:world
endf
function! tlib#agent#Cut(world, selected) "{{{3
let world = tlib#agent#Copy(a:world, a:selected)
return tlib#agent#DeleteItems(world, a:selected)
endf
function! tlib#agent#Copy(world, selected) "{{{3
let a:world.clipboard = []
let bidxs = copy(a:world.sel_idx)
call add(bidxs, a:world.GetBaseIdx(a:world.prefidx))
for bidx in sort(bidxs)
call add(a:world.clipboard, a:world.GetBaseItem(bidx))
endfor
let a:world.state = 'redisplay'
return a:world
endf
function! tlib#agent#Paste(world, selected) "{{{3
if has_key(a:world, 'clipboard')
for e in reverse(copy(a:world.clipboard))
call insert(a:world.base, e, a:world.prefidx)
endfor
endif
let a:world.state = 'display'
call a:world.ResetSelected()
return a:world
endf
function! tlib#agent#EditReturnValue(world, rv) "{{{3
return [a:world.state !~ '\<exit\>', a:world.base]
endf
" Files related {{{1
function! tlib#agent#ViewFile(world, selected) "{{{3
if !empty(a:selected)
let back = a:world.SwitchWindow('win')
" TLogVAR back
if !&hidden && &l:modified
let cmd0 = 'split'
let cmd1 = 'sbuffer'
else
let cmd0 = 'edit'
let cmd1 = 'buffer'
endif
call tlib#file#With(cmd0, cmd1, a:selected, a:world)
exec back
let a:world.state = 'display'
endif
return a:world
endf
function! tlib#agent#EditFile(world, selected) "{{{3
return tlib#agent#Exit(tlib#agent#ViewFile(a:world, a:selected), a:selected)
endf
function! tlib#agent#EditFileInSplit(world, selected) "{{{3
call a:world.CloseScratch()
" call tlib#file#With('edit', 'buffer', a:selected[0:0], a:world)
" call tlib#file#With('split', 'sbuffer', a:selected[1:-1], a:world)
call tlib#file#With('split', 'sbuffer', a:selected, a:world)
return tlib#agent#Exit(a:world, a:selected)
endf
function! tlib#agent#EditFileInVSplit(world, selected) "{{{3
call a:world.CloseScratch()
" call tlib#file#With('edit', 'buffer', a:selected[0:0], a:world)
" call tlib#file#With('vertical split', 'vertical sbuffer', a:selected[1:-1], a:world)
call tlib#file#With('vertical split', 'vertical sbuffer', a:selected, a:world)
return tlib#agent#Exit(a:world, a:selected)
endf
function! tlib#agent#EditFileInTab(world, selected) "{{{3
call a:world.CloseScratch()
call tlib#file#With('tabedit', 'tab sbuffer', a:selected, a:world)
return tlib#agent#Exit(a:world, a:selected)
endf
function! tlib#agent#ToggleScrollbind(world, selected) "{{{3
let a:world.scrollbind = get(a:world, 'scrollbind') ? 0 : 1
let a:world.state = 'redisplay'
return a:world
endf
function! tlib#agent#ShowInfo(world, selected)
for f in a:selected
if filereadable(f)
let desc = [getfperm(f), strftime('%c', getftime(f)), getfsize(f) .' bytes', getftype(f)]
echo fnamemodify(f, ':t') .':'
echo ' '. join(desc, '; ')
endif
endfor
echohl MoreMsg
echo 'Press any key to continue'
echohl NONE
call getchar()
let a:world.state = 'redisplay'
return a:world
endf
" Buffer related {{{1
function! tlib#agent#PreviewLine(world, selected) "{{{3
let l = a:selected[0]
let ww = winnr()
exec a:world.win_wnr .'wincmd w'
call tlib#buffer#ViewLine(l, 1)
exec ww .'wincmd w'
let a:world.state = 'redisplay'
return a:world
endf
" If not called from the scratch, we assume/guess that we don't have to
" suspend the input-evaluation loop.
function! tlib#agent#GotoLine(world, selected) "{{{3
if !empty(a:selected)
" let l = a:selected[0]
" " TLogVAR l
" let back = a:world.SwitchWindow('win')
" " TLogVAR back
" " if a:world.win_wnr != winnr()
" " let world = tlib#agent#Suspend(a:world, a:selected)
" " exec a:world.win_wnr .'wincmd w'
" " endif
" call tlib#buffer#ViewLine(l)
" exec back
" let a:world.state = 'display'
let l = a:selected[0]
if a:world.win_wnr != winnr()
let world = tlib#agent#Suspend(a:world, a:selected)
exec a:world.win_wnr .'wincmd w'
endif
call tlib#buffer#ViewLine(l, 1)
endif
return a:world
endf
function! tlib#agent#DoAtLine(world, selected) "{{{3
if !empty(a:selected)
let cmd = input('Command: ', '', 'command')
if !empty(cmd)
call a:world.SwitchWindow('win')
" let pos = getpos('.')
let view = winsaveview()
for l in a:selected
call tlib#buffer#ViewLine(l, '')
exec cmd
endfor
" call setpos('.', pos)
call winrestview(view)
endif
endif
call a:world.ResetSelected()
let a:world.state = 'exit'
return a:world
endf
function! tlib#agent#Wildcard(world, selected) "{{{3
if !empty(a:world.filter[0])
let rx_type = a:world.matcher.FilterRxPrefix()
let flt0 = a:world.CleanFilter(a:world.filter[0][0])
if rx_type == '\V'
let flt0 .= '\.\{-}'
else
let flt0 .= '.\{-}'
endif
call a:world.SetFrontFilter(flt0)
endif
let a:world.state = 'redisplay'
return a:world
endf

View File

@ -0,0 +1,102 @@
" arg.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2009-02-15.
" @Revision: 0.0.50
if &cp || exists("loaded_tlib_arg_autoload")
finish
endif
let loaded_tlib_arg_autoload = 1
" :def: function! tlib#arg#Get(n, var, ?default="", ?test='')
" Set a positional argument from a variable argument list.
" See tlib#string#RemoveBackslashes() for an example.
function! tlib#arg#Get(n, var, ...) "{{{3
let default = a:0 >= 1 ? a:1 : ''
let atest = a:0 >= 2 ? a:2 : ''
" TLogVAR default, atest
if !empty(atest)
let atest = ' && (a:'. a:n .' '. atest .')'
endif
let test = printf('a:0 >= %d', a:n) . atest
return printf('let %s = %s ? a:%d : %s', a:var, test, a:n, string(default))
endf
" :def: function! tlib#arg#Let(list, ?default='')
" Set a positional arguments from a variable argument list.
" See tlib#input#List() for an example.
function! tlib#arg#Let(list, ...) "{{{3
let default = a:0 >= 1 ? a:1 : ''
let list = map(copy(a:list), 'type(v:val) == 3 ? v:val : [v:val, default]')
let args = map(range(1, len(list)), 'call("tlib#arg#Get", [v:val] + list[v:val - 1])')
return join(args, ' | ')
endf
" :def: function! tlib#arg#Key(dict, list, ?default='')
" See |:TKeyArg|.
function! tlib#arg#Key(list, ...) "{{{3
let default = a:0 >= 1 ? a:1 : ''
let dict = a:list[0]
let list = map(copy(a:list[1:-1]), 'type(v:val) == 3 ? v:val : [v:val, default]')
let args = map(list, '"let ". v:val[0] ." = ". string(get(dict, v:val[0], v:val[1]))')
" TLogVAR dict, list, args
return join(args, ' | ')
endf
" :def: function! tlib#arg#StringAsKeyArgs(string, ?keys=[], ?evaluate=0)
function! tlib#arg#StringAsKeyArgs(string, ...) "{{{1
TVarArg ['keys', {}], ['evaluate', 0]
let keyargs = {}
let args = split(a:string, '\\\@<! ')
let arglist = map(args, 'matchlist(v:val, ''^\(\w\+\):\(.*\)$'')')
" TLogVAR a:string, args, arglist
for matchlist in arglist
if len(matchlist) < 3
throw 'Malformed key arguments: '. string(matchlist) .' in '. a:string
endif
let [match, key, val; rest] = matchlist
if empty(keys) || has_key(keys, key)
let val = substitute(val, '\\\\', '\\', 'g')
if evaluate
let val = eval(val)
endif
let keyargs[key] = val
else
echom 'Unknown key: '. key .'='. val
endif
endfor
return keyargs
endf
""" Command line {{{1
" :def: function! tlib#arg#Ex(arg, ?chars='%#! ')
" Escape some characters in a string.
"
" Use |fnamescape()| if available.
"
" EXAMPLES: >
" exec 'edit '. tlib#arg#Ex('foo%#bar.txt')
function! tlib#arg#Ex(arg, ...) "{{{3
if exists('*fnameescape') && a:0 == 0
return fnameescape(a:arg)
else
" let chars = '%# \'
let chars = '%#! '
if a:0 >= 1
let chars .= a:1
endif
return escape(a:arg, chars)
endif
endf

View File

@ -0,0 +1,23 @@
" autocmdgroup.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-08-19.
" @Last Change: 2010-01-05.
" @Revision: 0.0.6
let s:save_cpo = &cpo
set cpo&vim
augroup TLib
autocmd!
augroup END
function! tlib#autocmdgroup#Init() "{{{3
endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,52 @@
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @GIT: http://github.com/tomtom/tlib_vim/
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2010-08-30.
" @Last Change: 2010-09-05.
" @Revision: 23
function! tlib#balloon#Register(expr) "{{{3
if !has('balloon_eval')
return
endif
if !exists('b:tlib_balloons')
let b:tlib_balloons = []
endif
if !&ballooneval
setlocal ballooneval
endif
if &balloonexpr != 'tlib#balloon#Expr()'
if !empty(&balloonexpr)
call add(b:tlib_balloons, &balloonexpr)
endif
setlocal ballooneval balloonexpr=tlib#balloon#Expr()
endif
if index(b:tlib_balloons, a:expr) == -1
call add(b:tlib_balloons, a:expr)
endif
endf
function! tlib#balloon#Remove(expr) "{{{3
if !exists('b:tlib_balloons')
call filter(b:tlib_balloons, 'v:val != a:expr')
endif
endf
function! tlib#balloon#Expr() "{{{3
if !exists('b:tlib_balloons')
return ''
endif
let text = map(copy(b:tlib_balloons), 'eval(v:val)')
call filter(text, '!empty(v:val)')
if has('balloon_multiline')
return join(text, "\n----------------------------------\n")
else
return get(text, 0, '')
endif
endf

View File

@ -0,0 +1,394 @@
" buffer.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2010-09-23.
" @Revision: 0.0.334
let s:bmru = []
function! tlib#buffer#EnableMRU() "{{{3
call tlib#autocmdgroup#Init()
autocmd TLib BufEnter * call s:BMRU_Push(bufnr('%'))
endf
function! tlib#buffer#DisableMRU() "{{{3
call tlib#autocmdgroup#Init()
autocmd! TLib BufEnter
endf
function! s:BMRU_Push(bnr) "{{{3
let i = index(s:bmru, a:bnr)
if i >= 0
call remove(s:bmru, i)
endif
call insert(s:bmru, a:bnr)
endf
function! s:CompareBuffernameByBasename(a, b) "{{{3
let rx = '"\zs.\{-}\ze" \+\S\+ \+\d\+$'
let an = matchstr(a:a, rx)
let an = fnamemodify(an, ':t')
let bn = matchstr(a:b, rx)
let bn = fnamemodify(bn, ':t')
let rv = an == bn ? 0 : an > bn ? 1 : -1
return rv
endf
function! s:CompareBufferNrByMRU(a, b) "{{{3
let an = matchstr(a:a, '\s*\zs\d\+\ze')
let bn = matchstr(a:b, '\s*\zs\d\+\ze')
let ai = index(s:bmru, 0 + an)
if ai == -1
return 1
else
let bi = index(s:bmru, 0 + bn)
if bi == -1
return -1
else
return ai == bi ? 0 : ai > bi ? 1 : -1
endif
endif
endf
" Set the buffer to buffer and return a command as string that can be
" evaluated by |:execute| in order to restore the original view.
function! tlib#buffer#Set(buffer) "{{{3
let lazyredraw = &lazyredraw
set lazyredraw
try
let cb = bufnr('%')
let sn = bufnr(a:buffer)
if sn != cb
let ws = bufwinnr(sn)
if ws != -1
let wb = bufwinnr('%')
exec ws.'wincmd w'
return wb.'wincmd w'
else
silent exec 'sbuffer! '. sn
return 'wincmd c'
endif
else
return ''
endif
finally
let &lazyredraw = lazyredraw
endtry
endf
" :def: function! tlib#buffer#Eval(buffer, code)
" Evaluate CODE in BUFFER.
"
" EXAMPLES: >
" call tlib#buffer#Eval('foo.txt', 'echo b:bar')
function! tlib#buffer#Eval(buffer, code) "{{{3
" let cb = bufnr('%')
" let wb = bufwinnr('%')
" " TLogVAR cb
" let sn = bufnr(a:buffer)
" let sb = sn != cb
let lazyredraw = &lazyredraw
set lazyredraw
let restore = tlib#buffer#Set(a:buffer)
try
exec a:code
" if sb
" let ws = bufwinnr(sn)
" if ws != -1
" try
" exec ws.'wincmd w'
" exec a:code
" finally
" exec wb.'wincmd w'
" endtry
" else
" try
" silent exec 'sbuffer! '. sn
" exec a:code
" finally
" wincmd c
" endtry
" endif
" else
" exec a:code
" endif
finally
exec restore
let &lazyredraw = lazyredraw
endtry
endf
" :def: function! tlib#buffer#GetList(?show_hidden=0, ?show_number=0, " ?order='bufnr')
" Possible values for the "order" argument:
" bufnr :: Default behaviour
" mru :: Sort buffers according to most recent use
" basename :: Sort by the file's basename (last component)
"
" NOTE: MRU order works on second invocation only. If you want to always
" use MRU order, call tlib#buffer#EnableMRU() in your ~/.vimrc file.
function! tlib#buffer#GetList(...)
TVarArg ['show_hidden', 0], ['show_number', 0], ['order', '']
" TLogVAR show_hidden, show_number, order
let ls_bang = show_hidden ? '!' : ''
redir => bfs
exec 'silent ls'. ls_bang
redir END
let buffer_list = split(bfs, '\n')
if order == 'mru'
if empty(s:bmru)
call tlib#buffer#EnableMRU()
echom 'tlib: Installed Buffer MRU logger; disable with: call tlib#buffer#DisableMRU()'
else
call sort(buffer_list, function('s:CompareBufferNrByMRU'))
endif
elseif order == 'basename'
call sort(buffer_list, function('s:CompareBuffernameByBasename'))
endif
let buffer_nr = map(copy(buffer_list), 'matchstr(v:val, ''\s*\zs\d\+\ze'')')
" TLogVAR buffer_list, buffer_nr
if show_number
call map(buffer_list, 'matchstr(v:val, ''^\s*\d\+.\{-}\ze\s\+\S\+ \d\+\s*$'')')
else
call map(buffer_list, 'matchstr(v:val, ''^\s*\d\+\zs.\{-}\ze\s\+\S\+ \d\+\s*$'')')
endif
" TLogVAR buffer_list
" call map(buffer_list, 'matchstr(v:val, ''^.\{-}\ze\s\+line \d\+\s*$'')')
" TLogVAR buffer_list
call map(buffer_list, 'matchstr(v:val, ''^[^"]\+''). printf("%-20s %s", fnamemodify(matchstr(v:val, ''"\zs.\{-}\ze"$''), ":t"), fnamemodify(matchstr(v:val, ''"\zs.\{-}\ze"$''), ":h"))')
" TLogVAR buffer_list
return [buffer_nr, buffer_list]
endf
" :def: function! tlib#buffer#ViewLine(line, ?position='z')
" line is either a number or a string that begins with a number.
" For possible values for position see |scroll-cursor|.
" See also |g:tlib_viewline_position|.
function! tlib#buffer#ViewLine(line, ...) "{{{3
if a:line
TVarArg 'pos'
let ln = matchstr(a:line, '^\d\+')
let lt = matchstr(a:line, '^\d\+: \zs.*')
" TLogVAR pos, ln, lt
exec ln
if empty(pos)
let pos = tlib#var#Get('tlib_viewline_position', 'wbg')
endif
" TLogVAR pos
if !empty(pos)
exec 'norm! '. pos
endif
call tlib#buffer#HighlightLine(ln)
" let @/ = '\%'. ln .'l.*'
endif
endf
function! s:UndoHighlightLine() "{{{3
3match none
autocmd! TLib CursorMoved,CursorMovedI <buffer>
autocmd! TLib CursorHold,CursorHoldI <buffer>
autocmd! TLib InsertEnter,InsertChange,InsertLeave <buffer>
autocmd! TLib BufLeave,BufWinLeave,WinLeave,BufHidden <buffer>
endf
function! tlib#buffer#HighlightLine(...) "{{{3
TVarArg ['line', line('.')]
" exec '3match MatchParen /^\%'. a:line .'l.*/'
exec '3match Search /^\%'. line .'l.*/'
call tlib#autocmdgroup#Init()
exec 'autocmd TLib CursorMoved,CursorMovedI <buffer> if line(".") != '. line .' | call s:UndoHighlightLine() | endif'
autocmd TLib CursorHold,CursorHoldI <buffer> call s:UndoHighlightLine()
autocmd TLib InsertEnter <buffer> call s:UndoHighlightLine()
" autocmd TLib BufLeave,BufWinLeave,WinLeave,BufHidden <buffer> call s:UndoHighlightLine()
endf
" Delete the lines in the current buffer. Wrapper for |:delete|.
function! tlib#buffer#DeleteRange(line1, line2) "{{{3
let r = @t
try
exec a:line1.','.a:line2.'delete t'
finally
let @t = r
endtry
endf
" Replace a range of lines.
function! tlib#buffer#ReplaceRange(line1, line2, lines)
call tlib#buffer#DeleteRange(a:line1, a:line2)
call append(a:line1 - 1, a:lines)
endf
" Initialize some scratch area at the bottom of the current buffer.
function! tlib#buffer#ScratchStart() "{{{3
norm! Go
let b:tlib_inbuffer_scratch = line('$')
return b:tlib_inbuffer_scratch
endf
" Remove the in-buffer scratch area.
function! tlib#buffer#ScratchEnd() "{{{3
if !exists('b:tlib_inbuffer_scratch')
echoerr 'tlib: In-buffer scratch not initalized'
endif
call tlib#buffer#DeleteRange(b:tlib_inbuffer_scratch, line('$'))
unlet b:tlib_inbuffer_scratch
endf
" Run exec on all buffers via bufdo and return to the original buffer.
function! tlib#buffer#BufDo(exec) "{{{3
let bn = bufnr('%')
exec 'bufdo '. a:exec
exec 'buffer! '. bn
endf
" :def: function! tlib#buffer#InsertText(text, keyargs)
" Keyargs:
" 'shift': 0|N
" 'col': col('.')|N
" 'lineno': line('.')|N
" 'indent': 0|1
" 'pos': 'e'|'s' ... Where to locate the cursor (somewhat like s and e in {offset})
" Insert text (a string) in the buffer.
function! tlib#buffer#InsertText(text, ...) "{{{3
TVarArg ['keyargs', {}]
" TLogVAR a:text, keyargs
TKeyArg keyargs, ['shift', 0], ['col', col('.')], ['lineno', line('.')], ['pos', 'e'],
\ ['indent', 0]
" TLogVAR shift, col, lineno, pos, indent
let grow = 0
let post_del_last_line = line('$') == 1
let line = getline(lineno)
if col + shift > 0
let pre = line[0 : (col - 1 + shift)]
let post = line[(col + shift): -1]
else
let pre = ''
let post = line
endif
" TLogVAR lineno, line, pre, post
let text0 = pre . a:text . post
let text = split(text0, '\n', 1)
" TLogVAR text
let icol = len(pre)
" exec 'norm! '. lineno .'G'
call cursor(lineno, col)
if indent && col > 1
if &fo =~# '[or]'
" FIXME: Is the simple version sufficient?
" VERSION 1
" " This doesn't work because it's not guaranteed that the
" " cursor is set.
" let cline = getline('.')
" norm! a
" "norm! o
" " TAssertExec redraw | sleep 3
" let idt = strpart(getline('.'), 0, col('.') + shift)
" " TLogVAR idt
" let idtl = len(idt)
" -1,.delete
" " TAssertExec redraw | sleep 3
" call append(lineno - 1, cline)
" call cursor(lineno, col)
" " TAssertExec redraw | sleep 3
" if idtl == 0 && icol != 0
" let idt = matchstr(pre, '^\s\+')
" let idtl = len(idt)
" endif
" VERSION 2
let idt = matchstr(pre, '^\s\+')
let idtl = len(idt)
else
let [m_0, idt, iline; rest] = matchlist(pre, '^\(\s*\)\(.*\)$')
let idtl = len(idt)
endif
if idtl < icol
let idt .= repeat(' ', icol - idtl)
endif
" TLogVAR idt
let idtl1 = len(idt)
for i in range(1, len(text) - 1)
let text[i] = idt . text[i]
let grow += idtl1
endfor
endif
" TLogVAR text
" exec 'norm! '. lineno .'Gdd'
call tlib#normal#WithRegister('"tdd', 't')
call append(lineno - 1, text)
if post_del_last_line
call tlib#buffer#KeepCursorPosition('$delete')
endif
let tlen = len(text)
let posshift = matchstr(pos, '\d\+')
" TLogVAR pos
if pos =~ '^e'
exec lineno + tlen - 1
exec 'norm! 0'. (len(text[-1]) - len(post) + posshift - 1) .'l'
elseif pos =~ '^s'
" TLogVAR lineno, pre, posshift
exec lineno
exec 'norm! '. len(pre) .'|'
if !empty(posshift)
exec 'norm! '. posshift .'h'
endif
endif
" TLogDBG string(getline(1, '$'))
return grow
endf
function! tlib#buffer#InsertText0(text, ...) "{{{3
TVarArg ['keyargs', {}]
let mode = get(keyargs, 'mode', 'i')
" TLogVAR mode
if !has_key(keyargs, 'shift')
let col = col('.')
" if mode =~ 'i'
" let col += 1
" endif
let keyargs.shift = col >= col('$') ? 0 : -1
" let keyargs.shift = col('.') >= col('$') ? 0 : -1
" TLogVAR col
" TLogDBG col('.') .'-'. col('$') .': '. string(getline('.'))
endif
" TLogVAR keyargs.shift
return tlib#buffer#InsertText(a:text, keyargs)
endf
function! tlib#buffer#CurrentByte() "{{{3
return line2byte(line('.')) + col('.')
endf
" Evaluate cmd while maintaining the cursor position and jump registers.
function! tlib#buffer#KeepCursorPosition(cmd) "{{{3
" let pos = getpos('.')
let view = winsaveview()
try
keepjumps exec a:cmd
finally
" call setpos('.', pos)
call winrestview(view)
endtry
endf

View File

@ -0,0 +1,261 @@
" cache.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2011-03-10.
" @Revision: 0.1.182
" |tlib#cache#Purge()|: Remove cache files older than N days.
TLet g:tlib#cache#purge_days = 31
" Purge the cache every N days. Disable automatic purging by setting
" this value to a negative value.
TLet g:tlib#cache#purge_every_days = 31
" The encoding used for the purge-cache script.
" Default: 'enc'
TLet g:tlib#cache#script_encoding = &enc
" Whether to run the directory removal script:
" 0 ... No
" 1 ... Query user
" 2 ... Yes
TLet g:tlib#cache#run_script = 1
" A list of regexps that are matched against partial filenames of the
" cached files. If a regexp matches, the file won't be removed by
" |tlib#cache#Purge()|.
TLet g:tlib#cache#dont_purge = ['[\/]\.last_purge$']
" :display: tlib#cache#Dir(?mode = 'bg')
" The default cache directory.
function! tlib#cache#Dir(...) "{{{3
TVarArg ['mode', 'bg']
let dir = tlib#var#Get('tlib_cache', mode)
if empty(dir)
let dir = tlib#file#Join([tlib#dir#MyRuntime(), 'cache'])
endif
return dir
endf
" :def: function! tlib#cache#Filename(type, ?file=%, ?mkdir=0)
function! tlib#cache#Filename(type, ...) "{{{3
" TLogDBG 'bufname='. bufname('.')
let dir = tlib#cache#Dir()
if a:0 >= 1 && !empty(a:1)
let file = a:1
else
if empty(expand('%:t'))
return ''
endif
let file = expand('%:p')
let file = tlib#file#Relative(file, tlib#file#Join([dir, '..']))
endif
" TLogVAR file, dir
let mkdir = a:0 >= 2 ? a:2 : 0
let file = substitute(file, '\.\.\|[:&<>]\|//\+\|\\\\\+', '_', 'g')
let dirs = [dir, a:type]
let dirf = fnamemodify(file, ':h')
if dirf != '.'
call add(dirs, dirf)
endif
let dir = tlib#file#Join(dirs)
" TLogVAR dir
let dir = tlib#dir#PlainName(dir)
" TLogVAR dir
let file = fnamemodify(file, ':t')
" TLogVAR file, dir, mkdir
if mkdir && !isdirectory(dir)
try
call mkdir(dir, 'p')
catch /^Vim\%((\a\+)\)\=:E739:/
if filereadable(dir) && !isdirectory(dir)
echoerr 'TLib: Cannot create directory for cache file because a file with the same name exists (please delete it):' dir
" call delete(dir)
" call mkdir(dir, 'p')
endif
endtry
endif
let cache_file = tlib#file#Join([dir, file])
" TLogVAR cache_file
return cache_file
endf
function! tlib#cache#Save(cfile, dictionary) "{{{3
if !empty(a:cfile)
" TLogVAR a:dictionary
call writefile([string(a:dictionary)], a:cfile, 'b')
endif
endf
function! tlib#cache#Get(cfile) "{{{3
call tlib#cache#MaybePurge()
if !empty(a:cfile) && filereadable(a:cfile)
let val = readfile(a:cfile, 'b')
return eval(join(val, "\n"))
else
return {}
endif
endf
" Call |tlib#cache#Purge()| if the last purge was done before
" |g:tlib#cache#purge_every_days|.
function! tlib#cache#MaybePurge() "{{{3
if g:tlib#cache#purge_every_days < 0
return
endif
let dir = tlib#cache#Dir('g')
let last_purge = tlib#file#Join([dir, '.last_purge'])
let last_purge_exists = filereadable(last_purge)
if last_purge_exists
let threshold = localtime() - g:tlib#cache#purge_every_days * g:tlib#date#dayshift
let should_purge = getftime(last_purge) < threshold
else
let should_purge = 0 " should ignore empty dirs, like the tmru one: !empty(glob(tlib#file#Join([dir, '**'])))
endif
if should_purge
if last_purge_exists
let yn = 'y'
else
let txt = "TLib: The cache directory '". dir ."' should be purged of old files.\nDelete files older than ". g:tlib#cache#purge_days ." days now?"
let yn = tlib#input#Dialog(txt, ['yes', 'no'], 'no')
endif
if yn =~ '^y\%[es]$'
call tlib#cache#Purge()
else
let g:tlib#cache#purge_every_days = -1
if !last_purge_exists
call s:PurgeTimestamp(dir)
endif
echohl WarningMsg
echom "TLib: Please run :call tlib#cache#Purge() to clean up ". dir
echohl NONE
endif
elseif !last_purge_exists
call s:PurgeTimestamp(dir)
endif
endf
" Delete old files.
function! tlib#cache#Purge() "{{{3
let threshold = localtime() - g:tlib#cache#purge_days * g:tlib#date#dayshift
let dir = tlib#cache#Dir('g')
echohl WarningMsg
echom "TLib: Delete files older than ". g:tlib#cache#purge_days ." days from ". dir
echohl NONE
let files = tlib#cache#ListFilesInCache()
let deldir = []
let newer = []
let msg = []
let more = &more
set nomore
try
for file in files
if isdirectory(file)
if empty(filter(copy(newer), 'strpart(v:val, 0, len(file)) ==# file'))
call add(deldir, file)
endif
else
if getftime(file) < threshold
if delete(file)
call add(msg, "TLib: Could not delete cache file: ". file)
else
call add(msg, "TLib: Delete cache file: ". file)
" echo "TLib: Delete cache file: ". file
endif
else
call add(newer, file)
endif
endif
endfor
finally
let &more = more
endtry
if !empty(msg)
echo join(msg, "\n")
endif
if !empty(deldir)
if &shell =~ 'sh\(\.exe\)\?$'
let scriptfile = 'deldir.sh'
let rmdir = 'rm -rf %s'
else
let scriptfile = 'deldir.bat'
let rmdir = 'rmdir /S /Q %s'
endif
let enc = g:tlib#cache#script_encoding
if has('multi_byte') && enc != &enc
call map(deldir, 'iconv(v:val, &enc, enc)')
endif
let scriptfile = tlib#file#Join([dir, scriptfile])
if filereadable(scriptfile)
let script = readfile(scriptfile)
else
let script = []
endif
let script += map(copy(deldir), 'printf(rmdir, shellescape(v:val, 1))')
let script = tlib#list#Uniq(script)
call writefile(script, scriptfile)
call inputsave()
if g:tlib#cache#run_script == 0
echohl WarningMsg
echom "TLib: Please review and execute ". scriptfile
echohl NONE
else
try
let yn = g:tlib#cache#run_script == 2 ? 'y' : tlib#input#Dialog("TLib: Could not delete some directories.\nDirectory removal script: ". scriptfile ."\nRun script to delete directories now?", ['yes', 'no', 'edit'], 'no')
if yn =~ '^y\%[es]$'
exec 'cd '. fnameescape(dir)
exec '! ' &shell shellescape(scriptfile, 1)
exec 'cd -'
call delete(scriptfile)
elseif yn =~ '^e\%[dit]$'
exec 'edit '. fnameescape(scriptfile)
endif
finally
call inputrestore()
endtry
endif
endif
call s:PurgeTimestamp(dir)
endf
function! s:PurgeTimestamp(dir) "{{{3
let last_purge = tlib#file#Join([a:dir, '.last_purge'])
" TLogVAR last_purge
call writefile([" "], last_purge)
endf
function! tlib#cache#ListFilesInCache(...) "{{{3
let dir = a:0 >= 1 ? a:1 : tlib#cache#Dir('g')
if v:version > 702 || (v:version == 702 && has('patch51'))
let filess = glob(tlib#file#Join([dir, '**']), 1)
else
let filess = glob(tlib#file#Join([dir, '**']))
endif
let files = reverse(split(filess, '\n'))
let pos0 = len(tlib#dir#CanonicName(dir))
call filter(files, 's:ShouldPurge(strpart(v:val, pos0))')
return files
endf
function! s:ShouldPurge(partial_filename) "{{{3
" TLogVAR a:partial_filename
for rx in g:tlib#cache#dont_purge
if a:partial_filename =~ rx
" TLogVAR a:partial_filename, rx
return 0
endif
endfor
return 1
endf

View File

@ -0,0 +1,58 @@
" char.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2009-02-15.
" @Revision: 0.0.30
if &cp || exists("loaded_tlib_char_autoload")
finish
endif
let loaded_tlib_char_autoload = 1
" :def: function! tlib#char#Get(?timeout=0)
" Get a character.
"
" EXAMPLES: >
" echo tlib#char#Get()
" echo tlib#char#Get(5)
function! tlib#char#Get(...) "{{{3
TVarArg ['timeout', 0], ['resolution', 0]
if timeout == 0 || !has('reltime')
return getchar()
else
return tlib#char#GetWithTimeout(timeout, resolution)
endif
return -1
endf
function! tlib#char#IsAvailable() "{{{3
let ch = getchar(1)
return type(ch) == 0 && ch != 0
endf
function! tlib#char#GetWithTimeout(timeout, ...) "{{{3
TVarArg ['resolution', 2]
" TLogVAR a:timeout, resolution
let start = tlib#time#MSecs()
while 1
let c = getchar(0)
if type(c) != 0 || c != 0
return c
else
let now = tlib#time#MSecs()
let diff = tlib#time#DiffMSecs(now, start, resolution)
" TLogVAR diff
if diff > a:timeout
return -1
endif
endif
endwh
return -1
endf

View File

@ -0,0 +1,94 @@
" cmd.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-08-23.
" @Last Change: 2011-04-28.
" @Revision: 0.0.31
if &cp || exists("loaded_tlib_cmd_autoload")
finish
endif
let loaded_tlib_cmd_autoload = 1
function! tlib#cmd#OutputAsList(command) "{{{3
" let lines = ''
redir => lines
silent! exec a:command
redir END
return split(lines, '\n')
endf
" See |:TBrowseOutput|.
function! tlib#cmd#BrowseOutput(command) "{{{3
call tlib#cmd#BrowseOutputWithCallback("tlib#cmd#DefaultBrowseOutput", a:command)
endf
" :def: function! tlib#cmd#BrowseOutputWithCallback(callback, command)
" Execute COMMAND and present its output in a |tlib#input#List()|;
" when a line is selected, execute the function named as the CALLBACK
" and pass in that line as an argument.
"
" The CALLBACK function gives you an opportunity to massage the COMMAND output
" and possibly act on it in a meaningful way. For example, if COMMAND listed
" all URIs found in the current buffer, CALLBACK could validate and then open
" the selected URI in the system's default browser.
"
" This function is meant to be a tool to help compose the implementations of
" powerful commands that use |tlib#input#List()| as a common interface. See
" |TBrowseScriptnames| as an example.
"
" EXAMPLES: >
" call tlib#cmd#BrowseOutputWithCallback('tlib#cmd#ParseScriptname', 'scriptnames')
function! tlib#cmd#BrowseOutputWithCallback(callback, command) "{{{3
let list = tlib#cmd#OutputAsList(a:command)
let cmd = tlib#input#List('s', 'Output of: '. a:command, list)
if !empty(cmd)
let Callback = function(a:callback)
call call(Callback, [cmd])
endif
endf
function! tlib#cmd#DefaultBrowseOutput(cmd) "{{{3
call feedkeys(':'. a:cmd)
endf
function! tlib#cmd#ParseScriptname(line) "{{{3
let parsedValue = substitute(a:line, '^.\{-}\/', '/', '')
exe ':e '. parsedValue
endf
" :def: function! tlib#cmd#UseVertical(?rx='')
" Look at the history whether the command was called with vertical. If
" an rx is provided check first if the last entry in the history matches
" this rx.
function! tlib#cmd#UseVertical(...) "{{{3
TVarArg ['rx']
let h0 = histget(':')
let rx0 = '\C\<vert\%[ical]\>\s\+'
if !empty(rx)
let rx0 .= '.\{-}'.rx
endif
" TLogVAR h0, rx0
return h0 =~ rx0
endf
" Print the time in seconds or milliseconds (if your version of VIM
" has |+reltime|) a command takes.
function! tlib#cmd#Time(cmd) "{{{3
if has('reltime')
let start = tlib#time#Now()
exec a:cmd
let end = tlib#time#Now()
let diff = string(tlib#time#Diff(end, start)) .'ms'
else
let start = localtime()
exec a:cmd
let diff = (localtime() - start) .'s'
endif
echom 'Time: '. diff .': '. a:cmd
endf

View File

@ -0,0 +1,57 @@
" comments.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-11-15.
" @Last Change: 2009-02-15.
" @Revision: 0.0.24
if &cp || exists("loaded_tlib_comments_autoload")
finish
endif
let loaded_tlib_comments_autoload = 1
let s:save_cpo = &cpo
set cpo&vim
" function! tlib#comments#Comments(?rx='')
function! tlib#comments#Comments(...)
TVarArg ['rx', '']
let comments = {}
let co = &comments
while !empty(co)
" TLogVAR co
let [m_0, m_key, m_val, m_val1, co0, co; rest] = matchlist(co, '^\([^:]*\):\(\(\\.\|[^,]*\)\+\)\(,\(.*\)$\|$\)')
" TLogVAR m_key, m_val, co
if empty(m_key)
let m_key = ':'
endif
if empty(rx) || m_key =~ rx
let comments[m_key] = m_val
endif
endwh
return comments
endf
" function! tlib#comments#PartitionLine(line) "{{{3
" if !empty(&commentstring)
" let cs = '^\(\s*\)\('. printf(tlib#rx#Escape(&commentstring), '\)\(.\{-}\)\(') .'\)\(.*\)$'
" let ml = matchlist(a:line, cs)
" else
" let ml = []
" endif
" if !empty(ml)
" let [m_0, pre, open, line, close, post; rest] = ml
" else
" let [m_0, pre, line; rest] = matchstr(a:line, '^\(\s*\)\(.*\)$')
" for [key, val] in tlib#comments#Comments()
" if +++
" endfor
" endif
" return {'pre': pre, 'open': open, 'line': line, 'close': close, 'post': post}
" endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,120 @@
" date.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2010-03-25.
" @Last Change: 2010-09-17.
" @Revision: 0.0.34
if !exists('g:tlib#date#ShortDatePrefix') | let g:tlib#date#ShortDatePrefix = '20' | endif "{{{2
if !exists('g:tlib#date#TimeZoneShift') | let g:tlib#date#TimeZoneShift = 0 | endif "{{{2
let g:tlib#date#dayshift = 60 * 60 * 24
" :display: tlib#date#DiffInDays(date1, ?date2=localtime(), ?allow_zero=0)
function! tlib#date#DiffInDays(date, ...)
let allow_zero = a:0 >= 2 ? a:2 : 0
let s0 = tlib#date#SecondsSince1970(a:date, 0, allow_zero)
let s1 = a:0 >= 1 ? tlib#date#SecondsSince1970(a:1, 0, allow_zero) : localtime()
let dd = (s0 - s1) / g:tlib#date#dayshift
" TLogVAR dd
return dd
endf
" :display: tlib#date#Parse(date, ?allow_zero=0) "{{{3
function! tlib#date#Parse(date, ...) "{{{3
let min = a:0 >= 1 && a:1 ? 0 : 1
" TLogVAR a:date, min
let m = matchlist(a:date, '^\(\d\{2}\|\d\{4}\)-\(\d\{1,2}\)-\(\d\{1,2}\)$')
if !empty(m)
let year = m[1]
let month = m[2]
let days = m[3]
else
let m = matchlist(a:date, '^\(\d\+\)/\(\d\{1,2}\)/\(\d\{1,2}\)$')
if !empty(m)
let year = m[1]
let month = m[3]
let days = m[2]
else
let m = matchlist(a:date, '^\(\d\{1,2}\)\.\s*\(\d\{1,2}\)\.\s*\(\d\d\{2}\|\d\{4}\)$')
if !empty(m)
let year = m[3]
let month = m[2]
let days = m[1]
endif
endif
endif
if empty(m) || year == '' || month == '' || days == '' ||
\ month < min || month > 12 || days < min || days > 31
echoerr 'TLib: Invalid date: '. a:date
return []
endif
if strlen(year) == 2
let year = g:tlib#date#ShortDatePrefix . year
endif
return [0 + year, 0 + month, 0 + days]
endf
" tlib#date#SecondsSince1970(date, ?daysshift=0, ?allow_zero=0)
function! tlib#date#SecondsSince1970(date, ...) "{{{3
let allow_zero = a:0 >= 2 ? a:2 : 0
" TLogVAR a:date, allow_zero
let date = tlib#date#Parse(a:date, allow_zero)
if empty(date)
return 0
endif
let [year, month, days] = date
if a:0 >= 1 && a:1 > 0
let days = days + a:1
end
let days_passed = days
let i = 1970
while i < year
let days_passed = days_passed + 365
if i % 4 == 0 || i == 2000
let days_passed = days_passed + 1
endif
let i = i + 1
endwh
let i = 1
while i < month
if i == 1
let days_passed = days_passed + 31
elseif i == 2
let days_passed = days_passed + 28
if year % 4 == 0 || year == 2000
let days_passed = days_passed + 1
endif
elseif i == 3
let days_passed = days_passed + 31
elseif i == 4
let days_passed = days_passed + 30
elseif i == 5
let days_passed = days_passed + 31
elseif i == 6
let days_passed = days_passed + 30
elseif i == 7
let days_passed = days_passed + 31
elseif i == 8
let days_passed = days_passed + 31
elseif i == 9
let days_passed = days_passed + 30
elseif i == 10
let days_passed = days_passed + 31
elseif i == 11
let days_passed = days_passed + 30
endif
let i = i + 1
endwh
let seconds = (days_passed - 1) * 24 * 60 * 60
let seconds = seconds + (strftime('%H') + g:tlib#date#TimeZoneShift) * 60 * 60
let seconds = seconds + strftime('%M') * 60
let seconds = seconds + strftime('%S')
return seconds
endf

View File

@ -0,0 +1,83 @@
" dir.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2009-08-04.
" @Revision: 0.0.32
if &cp || exists("loaded_tlib_dir_autoload")
finish
endif
let loaded_tlib_dir_autoload = 1
let s:dir_stack = []
" EXAMPLES: >
" tlib#dir#CanonicName('foo/bar')
" => 'foo/bar/'
function! tlib#dir#CanonicName(dirname) "{{{3
if a:dirname !~ '[/\\]$'
return a:dirname . g:tlib_filename_sep
endif
return a:dirname
endf
" EXAMPLES: >
" tlib#dir#PlainName('foo/bar/')
" => 'foo/bar'
function! tlib#dir#PlainName(dirname) "{{{3
let dirname = a:dirname
while index(['/', '\'], dirname[-1 : -1]) != -1
let dirname = dirname[0 : -2]
endwh
return dirname
" return substitute(a:dirname, tlib#rx#Escape(g:tlib_filename_sep).'\+$', '', '')
endf
" Create a directory if it doesn't already exist.
function! tlib#dir#Ensure(dir) "{{{3
if !isdirectory(a:dir)
let dir = tlib#dir#PlainName(a:dir)
return mkdir(dir, 'p')
endif
return 1
endf
" Return the first directory in &rtp.
function! tlib#dir#MyRuntime() "{{{3
return get(split(&rtp, ','), 0)
endf
" :def: function! tlib#dir#CD(dir, ?locally=0) => CWD
function! tlib#dir#CD(dir, ...) "{{{3
TVarArg ['locally', 0]
let cmd = locally ? 'lcd ' : 'cd '
" let cwd = getcwd()
let cmd .= tlib#arg#Ex(a:dir)
" TLogVAR a:dir, locally, cmd
exec cmd
" return cwd
return getcwd()
endf
" :def: function! tlib#dir#Push(dir, ?locally=0) => CWD
function! tlib#dir#Push(dir, ...) "{{{3
TVarArg ['locally', 0]
call add(s:dir_stack, [getcwd(), locally])
return tlib#dir#CD(a:dir, locally)
endf
" :def: function! tlib#dir#Pop() => CWD
function! tlib#dir#Pop() "{{{3
let [dir, locally] = remove(s:dir_stack, -1)
return tlib#dir#CD(dir, locally)
endf

View File

@ -0,0 +1,55 @@
" eval.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-09-16.
" @Last Change: 2009-02-15.
" @Revision: 0.0.34
if &cp || exists("loaded_tlib_eval_autoload")
finish
endif
let loaded_tlib_eval_autoload = 1
function! tlib#eval#FormatValue(value, ...) "{{{3
TVarArg ['indent', 0]
" TLogVAR a:value, indent
let indent1 = indent + 1
let indenti = repeat(' ', &sw)
let type = type(a:value)
let acc = []
if type == 0 || type == 1 || type == 2
" TLogDBG 'Use string() for type='. type
call add(acc, string(a:value))
elseif type == 3 "List
" TLogDBG 'List'
call add(acc, '[')
for e in a:value
call add(acc, printf('%s%s,', indenti, tlib#eval#FormatValue(e, indent1)))
unlet e
endfor
call add(acc, ']')
elseif type == 4 "Dictionary
" TLogDBG 'Dictionary'
call add(acc, '{')
let indent1 = indent + 1
for [k, v] in items(a:value)
call add(acc, printf("%s%s: %s,", indenti, string(k), tlib#eval#FormatValue(v, indent1)))
unlet k v
endfor
call add(acc, '}')
else
" TLogDBG 'Unknown type: '. string(a:value)
call add(acc, string(a:value))
endif
if indent > 0
let is = repeat(' ', indent * &sw)
for i in range(1,len(acc) - 1)
let acc[i] = is . acc[i]
endfor
endif
return join(acc, "\n")
endf

View File

@ -0,0 +1,127 @@
" file.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2010-04-03.
" @Revision: 0.0.74
if &cp || exists("loaded_tlib_file_autoload")
finish
endif
let loaded_tlib_file_autoload = 1
""" File related {{{1
" For the following functions please see ../../test/tlib.vim for examples.
" EXAMPLES: >
" tlib#file#Split('foo/bar/filename.txt')
" => ['foo', 'bar', 'filename.txt']
function! tlib#file#Split(filename) "{{{3
let prefix = matchstr(a:filename, '^\(\w\+:\)\?/\+')
" TLogVAR prefix
if !empty(prefix)
let filename = a:filename[len(prefix) : -1]
else
let filename = a:filename
endif
let rv = split(filename, '[\/]')
" let rv = split(filename, '[\/]', 1)
if !empty(prefix)
call insert(rv, prefix[0:-2])
endif
return rv
endf
" :display: tlib#file#Join(filename_parts, ?strip_slashes=0)
" EXAMPLES: >
" tlib#file#Join(['foo', 'bar', 'filename.txt'])
" => 'foo/bar/filename.txt'
function! tlib#file#Join(filename_parts, ...) "{{{3
TVarArg 'strip_slashes'
if strip_slashes
" let rx = tlib#rx#Escape(g:tlib_filename_sep) .'$'
let rx = '[/\\]$'
let parts = map(copy(a:filename_parts), 'substitute(v:val, rx, "", "")')
return join(parts, g:tlib_filename_sep)
else
return join(a:filename_parts, g:tlib_filename_sep)
endif
endf
" EXAMPLES: >
" tlib#file#Relative('foo/bar/filename.txt', 'foo')
" => 'bar/filename.txt'
function! tlib#file#Relative(filename, basedir) "{{{3
" TLogVAR a:filename, a:basedir
" TLogDBG getcwd()
" TLogDBG expand('%:p')
let f0 = fnamemodify(a:filename, ':p')
let fn = fnamemodify(f0, ':t')
let fd = fnamemodify(f0, ':h')
let f = tlib#file#Split(fd)
" TLogVAR f
let b0 = fnamemodify(a:basedir, ':p')
let b = tlib#file#Split(b0)
" TLogVAR b
if f[0] != b[0]
let rv = f0
else
while !empty(f) && !empty(b)
if f[0] != b[0]
break
endif
call remove(f, 0)
call remove(b, 0)
endwh
let rv = tlib#file#Join(repeat(['..'], len(b)) + f + [fn])
endif
" TLogVAR rv
return rv
endf
function! s:SetScrollBind(world) "{{{3
let sb = get(a:world, 'scrollbind', &scrollbind)
if sb != &scrollbind
let &scrollbind = sb
endif
endf
" :def: function! tlib#file#With(fcmd, bcmd, files, ?world={})
function! tlib#file#With(fcmd, bcmd, files, ...) "{{{3
" TLogVAR a:fcmd, a:bcmd, a:files
exec tlib#arg#Let([['world', {}]])
for f in a:files
let bn = bufnr('^'.f.'$')
" TLogVAR f, bn
if bn != -1 && buflisted(bn)
if !empty(a:bcmd)
" TLogDBG a:bcmd .' '. bn
exec a:bcmd .' '. bn
call s:SetScrollBind(world)
endif
else
if filereadable(f)
if !empty(a:fcmd)
" TLogDBG a:fcmd .' '. escape(f, '%#\ ')
" exec a:fcmd .' '. escape(f, '%#\ ')
" exec a:fcmd .' '. escape(f, '%# ')
exec a:fcmd .' '. tlib#arg#Ex(f)
call s:SetScrollBind(world)
endif
else
echohl error
echom 'File not readable: '. f
echohl NONE
endif
endif
endfor
endf

View File

@ -0,0 +1,33 @@
" hook.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-08-21.
" @Last Change: 2009-02-15.
" @Revision: 0.0.10
if &cp || exists("loaded_tlib_hook_autoload")
finish
endif
let loaded_tlib_hook_autoload = 1
" :def: function! tlib#hook#Run(hook, ?dict={})
" Execute dict[hook], w:{hook}, b:{hook}, or g:{hook} if existent.
function! tlib#hook#Run(hook, ...) "{{{3
TVarArg ['dict', {}]
if has_key(dict, a:hook)
let hook = dict[a:hook]
else
let hook = tlib#var#Get(a:hook, 'wbg')
endif
if empty(hook)
return 0
else
let world = dict
exec hook
return 1
endif
endf

View File

@ -0,0 +1,781 @@
" input.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2011-03-31.
" @Revision: 0.0.840
" :filedoc:
" Input-related, select from a list etc.
" Functions related to tlib#input#List(type, ...) "{{{2
" :def: function! tlib#input#List(type. ?query='', ?list=[], ?handlers=[], ?default="", ?timeout=0)
" Select a single or multiple items from a list. Return either the list
" of selected elements or its indexes.
"
" By default, typing numbers will select an item by its index. See
" |g:tlib_numeric_chars| to find out how to change this.
"
" The item is automatically selected if the numbers typed equals the
" number of digits of the list length. I.e. if a list contains 20 items,
" typing 1 will first highlight item 1 but it won't select/use it
" because 1 is an ambiguous input in this context. If you press enter,
" the first item will be selected. If you press another digit (e.g. 0),
" item 10 will be selected. Another way to select item 1 would be to
" type 01. If the list contains only 9 items, typing 1 would select the
" first item right away.
"
" type can be:
" s ... Return one selected element
" si ... Return the index of the selected element
" m ... Return a list of selected elements
" mi ... Return a list of indexes
"
" Several pattern matching styles are supported. See
" |g:tlib_inputlist_match|.
"
" EXAMPLES: >
" echo tlib#input#List('s', 'Select one item', [100,200,300])
" echo tlib#input#List('si', 'Select one item', [100,200,300])
" echo tlib#input#List('m', 'Select one or more item(s)', [100,200,300])
" echo tlib#input#List('mi', 'Select one or more item(s)', [100,200,300])
"
" See ../samples/tlib/input/tlib_input_list.vim (move the cursor over
" the filename and press gf) for a more elaborated example.
function! tlib#input#List(type, ...) "{{{3
exec tlib#arg#Let([
\ ['query', ''],
\ ['list', []],
\ ['handlers', []],
\ ['rv', ''],
\ ['timeout', 0],
\ ])
" let handlers = a:0 >= 1 ? a:1 : []
" let rv = a:0 >= 2 ? a:2 : ''
" let timeout = a:0 >= 3 ? a:3 : 0
" let backchar = ["\<bs>", "\<del>"]
if a:type =~ '^resume'
let world = b:tlib_{matchstr(a:type, ' \zs.\+')}
else
let world = tlib#World#New({
\ 'type': a:type,
\ 'base': list,
\ 'query': query,
\ 'timeout': timeout,
\ 'rv': rv,
\ 'handlers': handlers,
\ })
let scratch_name = tlib#list#Find(handlers, 'has_key(v:val, "scratch_name")', '', 'v:val.scratch_name')
if !empty(scratch_name)
let world.scratch = scratch_name
endif
let world.scratch_vertical = tlib#list#Find(handlers, 'has_key(v:val, "scratch_vertical")', 0, 'v:val.scratch_vertical')
call world.Set_display_format(tlib#list#Find(handlers, 'has_key(v:val, "display_format")', '', 'v:val.display_format'))
let world.initial_index = tlib#list#Find(handlers, 'has_key(v:val, "initial_index")', 1, 'v:val.initial_index')
let world.index_table = tlib#list#Find(handlers, 'has_key(v:val, "index_table")', [], 'v:val.index_table')
let world.state_handlers = filter(copy(handlers), 'has_key(v:val, "state")')
let world.post_handlers = filter(copy(handlers), 'has_key(v:val, "postprocess")')
let world.filter_format = tlib#list#Find(handlers, 'has_key(v:val, "filter_format")', '', 'v:val.filter_format')
let world.return_agent = tlib#list#Find(handlers, 'has_key(v:val, "return_agent")', '', 'v:val.return_agent')
let world.help_extra = tlib#list#Find(handlers, 'has_key(v:val, "help_extra")', '', 'v:val.help_extra')
let world.resize = tlib#list#Find(handlers, 'has_key(v:val, "resize")', '', 'v:val.resize')
let world.show_empty = tlib#list#Find(handlers, 'has_key(v:val, "show_empty")', 0, 'v:val.show_empty')
let world.pick_last_item = tlib#list#Find(handlers, 'has_key(v:val, "pick_last_item")',
\ tlib#var#Get('tlib_pick_last_item', 'bg'), 'v:val.pick_last_item')
let world.numeric_chars = tlib#list#Find(handlers, 'has_key(v:val, "numeric_chars")',
\ tlib#var#Get('tlib_numeric_chars', 'bg'), 'v:val.numeric_chars')
let world.key_handlers = filter(copy(handlers), 'has_key(v:val, "key")')
let filter = tlib#list#Find(handlers, 'has_key(v:val, "filter")', '', 'v:val.filter')
if !empty(filter)
" let world.initial_filter = [[''], [filter]]
" let world.initial_filter = [[filter]]
" TLogVAR world.initial_filter
call world.SetInitialFilter(filter)
endif
endif
return tlib#input#ListW(world)
endf
" A wrapper for |tlib#input#ListW()| that builds |tlib#World#New| from
" dict.
function! tlib#input#ListD(dict) "{{{3
return tlib#input#ListW(tlib#World#New(a:dict))
endf
" :def: function! tlib#input#ListW(world, ?command='')
" The second argument (command) is meant for internal use only.
" The same as |tlib#input#List| but the arguments are packed into world
" (an instance of tlib#World as returned by |tlib#World#New|).
function! tlib#input#ListW(world, ...) "{{{3
TVarArg 'cmd'
if a:world.pick_last_item >= 1 && stridx(a:world.type, 'e') == -1 && len(a:world.base) <= 1
return get(a:world.base, 0, a:world.rv)
endif
let world = a:world
let world.filetype = &filetype
let world.fileencoding = &fileencoding
call world.SetMatchMode(tlib#var#Get('tlib_inputlist_match', 'wb'))
call s:Init(world, cmd)
" TLogVAR world.state, world.sticky, world.initial_index
let key_agents = copy(g:tlib_keyagents_InputList_s)
if stridx(world.type, 'm') != -1
call extend(key_agents, g:tlib_keyagents_InputList_m, 'force')
endif
if has('menu')
amenu ]TLibInputListPopupMenu.Pick\ selected\ item <cr>
amenu ]TLibInputListPopupMenu.Select #
amenu ]TLibInputListPopupMenu.Select\ all <c-a>
amenu ]TLibInputListPopupMenu.Reset\ list <c-r>
amenu ]TLibInputListPopupMenu.Cancel <esc>
amenu ]TLibInputListPopupMenu.-StandardEntries- :
endif
for handler in world.key_handlers
let k = get(handler, 'key', '')
if !empty(k)
let key_agents[k] = handler.agent
if has('menu') && has_key(handler, 'help') && !empty(handler.help)
exec 'amenu ]TLibInputListPopupMenu.'. escape(handler.help, ' .\')
\ .' '. handler.key_name
let world.has_menu = 1
endif
endif
endfor
" let statusline = &l:statusline
" let laststatus = &laststatus
let lastsearch = @/
let @/ = ''
let dlist = []
" let &laststatus = 2
let world.initial_display = 1
try
while !empty(world.state) && world.state !~ '^exit' && (world.show_empty || !empty(world.base))
" TLogDBG 'while'
" TLogVAR world.state
try
for handler in world.state_handlers
let eh = get(handler, 'state', '')
if !empty(eh) && world.state =~ eh
let ea = get(handler, 'exec', '')
if !empty(ea)
exec ea
else
let agent = get(handler, 'agent', '')
let world = call(agent, [world, world.GetSelectedItems(world.CurrentItem())])
call s:CheckAgentReturnValue(agent, world)
endif
endif
endfor
if world.state =~ '\<reset\>'
" TLogDBG 'reset'
" call world.Reset(world.state =~ '\<initial\>')
call world.Reset()
continue
endif
let llenw = len(world.base) - winheight(0) + 1
if world.offset > llenw
let world.offset = llenw
endif
if world.offset < 1
let world.offset = 1
endif
" TLogDBG 1
" TLogVAR world.state
if world.state == 'scroll'
let world.prefidx = world.offset
let world.state = 'redisplay'
endif
if world.state =~ '\<sticky\>'
let world.sticky = 1
endif
" TLogVAR world.filter
" TLogVAR world.sticky
if world.state =~ '\<pick\>'
let world.rv = world.CurrentItem()
" TLogVAR world.rv
throw 'pick'
elseif world.state =~ 'display'
if world.state =~ '^display'
if world.IsValidFilter()
call world.BuildTableList()
" TLogDBG 2
" TLogDBG len(world.table)
" TLogVAR world.table
" let world.list = map(copy(world.table), 'world.GetBaseItem(v:val)')
" TLogDBG 3
let world.llen = len(world.list)
" TLogVAR world.index_table
if empty(world.index_table)
let dindex = range(1, world.llen)
let world.index_width = len(world.llen)
else
let dindex = world.index_table
let world.index_width = len(max(dindex))
endif
if world.llen == 0 && !world.show_empty
call world.ReduceFilter()
let world.offset = 1
" TLogDBG 'ReduceFilter'
continue
else
if world.llen == 1
let world.last_item = world.list[0]
if world.pick_last_item >= 2
" echom 'Pick last item: '. world.list[0]
let world.prefidx = '1'
" TLogDBG 'pick last item'
throw 'pick'
endif
else
let world.last_item = ''
endif
endif
" TLogDBG 4
" TLogVAR world.idx, world.llen, world.state
" TLogDBG world.FilterIsEmpty()
if world.state == 'display'
if world.idx == '' && world.llen < g:tlib_sortprefs_threshold && !world.FilterIsEmpty()
call world.SetPrefIdx()
else
let world.prefidx = world.idx == '' ? world.initial_index : world.idx
endif
if world.prefidx > world.llen
let world.prefidx = world.llen
elseif world.prefidx < 1
let world.prefidx = 1
endif
endif
" TLogVAR world.initial_index, world.prefidx
" TLogDBG 5
" TLogDBG len(world.list)
" TLogVAR world.list
let dlist = copy(world.list)
" TLogVAR world.display_format
if !empty(world.display_format)
let display_format = world.display_format
let cache = world.fmt_display
" TLogVAR display_format, fmt_entries
call map(dlist, 'world.FormatName(cache, display_format, v:val)')
endif
" TLogVAR world.prefidx
" TLogDBG 6
if world.offset_horizontal > 0
call map(dlist, 'v:val[world.offset_horizontal:-1]')
endif
" TLogVAR dindex
let dlist = map(range(0, world.llen - 1), 'printf("%0'. world.index_width .'d", dindex[v:val]) .": ". dlist[v:val]')
" TLogVAR dlist
else
let dlist = ['Malformed filter']
endif
endif
" TLogDBG 7
" TLogVAR world.prefidx, world.offset
" TLogDBG (world.prefidx > world.offset + winheight(0) - 1)
" if world.prefidx > world.offset + winheight(0) - 1
" let listtop = world.llen - winheight(0) + 1
" let listoff = world.prefidx - winheight(0) + 1
" let world.offset = min([listtop, listoff])
" TLogVAR world.prefidx
" TLogDBG len(list)
" TLogDBG winheight(0)
" TLogVAR listtop, listoff, world.offset
" elseif world.prefidx < world.offset
" let world.offset = world.prefidx
" endif
" TLogDBG 8
if world.initial_display || !tlib#char#IsAvailable()
" TLogDBG len(dlist)
if g:tlib_inputlist_shortmessage
let query = 'Filter: '. world.DisplayFilter()
else
let query = world.query .' (filter: '. world.DisplayFilter() .'; press "?" for help)'
endif
call world.DisplayList(query, dlist)
call world.FollowCursor()
let world.initial_display = 0
" TLogDBG 9
endif
if world.state =~ '\<hibernate\>'
let world.state = 'suspend'
else
let world.state = ''
endif
else
" if world.state == 'scroll'
" let world.prefidx = world.offset
" endif
call world.DisplayList('')
if world.state == 'help'
let world.state = 'display'
else
let world.state = ''
call world.FollowCursor()
endif
endif
" TAssert IsNotEmpty(world.scratch)
let world.list_wnr = winnr()
" TLogVAR world.next_state, world.state
if !empty(world.next_state)
let world.state = world.next_state
let world.next_state = ''
endif
if world.state =~ '\<suspend\>'
let world = tlib#agent#SuspendToParentWindow(world, world.rv)
continue
endif
" TLogVAR world.timeout
let c = tlib#char#Get(world.timeout, world.timeout_resolution)
if world.state != ''
" continue
elseif has_key(key_agents, c)
let sr = @/
silent! let @/ = lastsearch
" TLogVAR c, key_agents[c]
" TLog "Agent: ". string(key_agents[c])
let world = call(key_agents[c], [world, world.GetSelectedItems(world.CurrentItem())])
call s:CheckAgentReturnValue(c, world)
silent! let @/ = sr
" continue
elseif c == 13
throw 'pick'
elseif c == 27
let world.state = 'exit empty'
elseif c == "\<LeftMouse>"
let world.prefidx = world.GetLineIdx(v:mouse_lnum)
" let world.offset = world.prefidx
" TLogVAR v:mouse_lnum, world.prefidx
if empty(world.prefidx)
" call feedkeys(c, 't')
let c = tlib#char#Get(world.timeout)
let world.state = 'help'
continue
endif
throw 'pick'
elseif c == "\<RightMouse>"
if has('menu')
" if v:mouse_lnum != line('.')
" endif
let world.prefidx = world.GetLineIdx(v:mouse_lnum)
let world.state = 'redisplay'
call world.DisplayList('')
if line('w$') - v:mouse_lnum < 6
popup ]TLibInputListPopupMenu
else
popup! ]TLibInputListPopupMenu
endif
else
let world.state = 'redisplay'
endif
" TLogVAR world.prefidx, world.state
elseif c >= 32
let world.state = 'display'
let numbase = get(world.numeric_chars, c, -99999)
" TLogVAR numbase, world.numeric_chars, c
if numbase != -99999
let world.idx .= (c - numbase)
if len(world.idx) == world.index_width
let world.prefidx = world.idx
" TLogVAR world.prefidx
throw 'pick'
endif
else
let world.idx = ''
" TLogVAR world.filter
if world.llen > g:tlib_inputlist_livesearch_threshold
let pattern = input('Filter: ', world.CleanFilter(world.filter[0][0]) . nr2char(c))
if empty(pattern)
let world.state = 'exit empty'
else
call world.SetFrontFilter(pattern)
echo
endif
elseif c == 124
call insert(world.filter[0], [])
else
call world.PushFrontFilter(c)
endif
" continue
if c == 45 && world.filter[0][0] == '-'
let world.state = 'redisplay'
end
endif
else
let world.state = 'redisplay'
" let world.state = 'continue'
endif
catch /^pick$/
call world.ClearAllMarks()
call world.MarkCurrent(world.prefidx)
let world.state = ''
" TLogDBG 'Pick item #'. world.prefidx
finally
" TLogDBG 'finally 1'
if world.state =~ '\<suspend\>'
" if !world.allow_suspend
" echom "Cannot be suspended"
" let world.state = 'redisplay'
" endif
elseif !empty(world.list) && !empty(world.base)
" TLogVAR world.list
if empty(world.state)
" TLogVAR world.state
let world.rv = world.CurrentItem()
endif
" TLog "postprocess"
for handler in world.post_handlers
let state = get(handler, 'postprocess', '')
" TLogVAR handler
" TLogVAR state
" TLogVAR world.state
if state == world.state
let agent = handler.agent
let [world, world.rv] = call(agent, [world, world.rv])
" TLogVAR world.state, world.rv
call s:CheckAgentReturnValue(agent, world)
endif
endfor
endif
" TLogDBG 'state0='. world.state
endtry
" TLogDBG 'state1='. world.state
endwh
" TLogVAR world.state
" TLogDBG string(tlib#win#List())
" TLogDBG 'exit while loop'
" TLogVAR world.list
" TLogVAR world.sel_idx
" TLogVAR world.idx
" TLogVAR world.prefidx
" TLogVAR world.rv
" TLogVAR world.type, world.state, world.return_agent, world.index_table, world.rv
if world.state =~ '\<\(empty\|escape\)\>'
let world.sticky = 0
endif
if world.state =~ '\<suspend\>'
" TLogDBG 'return suspended'
" TLogVAR world.prefidx
" exec world.prefidx
return
elseif world.state =~ '\<empty\>'
" TLog "empty"
" TLogDBG 'return empty'
" TLogVAR world.type
if stridx(world.type, 'm') != -1
return []
elseif stridx(world.type, 'i') != -1
return 0
else
return ''
endif
elseif !empty(world.return_agent)
" TLog "return_agent"
" TLogDBG 'return agent'
" TLogVAR world.return_agent
call world.CloseScratch()
" TLogDBG "return_agent ". string(tlib#win#List())
" TAssert IsNotEmpty(world.scratch)
return call(world.return_agent, [world, world.GetSelectedItems(world.rv)])
elseif stridx(world.type, 'w') != -1
" TLog "return_world"
" TLogDBG 'return world'
return world
elseif stridx(world.type, 'm') != -1
" TLog "return_multi"
" TLogDBG 'return multi'
return world.GetSelectedItems(world.rv)
elseif stridx(world.type, 'i') != -1
" TLog "return_index"
" TLogDBG 'return index'
if empty(world.index_table)
return world.rv
else
return world.index_table[world.rv - 1]
endif
else
" TLog "return_else"
" TLogDBG 'return normal'
return world.rv
endif
finally
call world.Leave()
" TLogVAR statusline
" let &l:statusline = statusline
" let &laststatus = laststatus
silent! let @/ = lastsearch
if has('menu') && world.has_menu
silent! aunmenu ]TLibInputListPopupMenu
endif
" TLogDBG 'finally 2'
" TLogDBG string(world.Methods())
" TLogVAR world.state
" TLogDBG string(tlib#win#List())
if world.state !~ '\<suspend\>'
" redraw
" TLogVAR world.sticky, bufnr("%")
if world.sticky
" TLogDBG "sticky"
" TLogVAR world.bufnr
" TLogDBG bufwinnr(world.bufnr)
if world.scratch_split > 0
if bufwinnr(world.bufnr) == -1
" TLogDBG "UseScratch"
call world.UseScratch()
endif
let world = tlib#agent#SuspendToParentWindow(world, world.GetSelectedItems(world.rv))
endif
else
" TLogDBG "non sticky"
" TLogVAR world.state, world.win_wnr, world.bufnr
if world.CloseScratch()
" TLogVAR world.winview
call tlib#win#SetLayout(world.winview)
endif
endif
endif
" for i in range(0,5)
" call getchar(0)
" endfor
echo
redraw!
endtry
endf
function! s:Init(world, cmd) "{{{3
" TLogVAR a:cmd
if a:cmd =~ '\<sticky\>'
let a:world.sticky = 1
endif
if a:cmd =~ '^resume'
call a:world.UseInputListScratch()
let a:world.initial_index = line('.')
if a:cmd =~ '\<pick\>'
let a:world.state = 'pick'
let a:world.prefidx = a:world.initial_index
else
call a:world.Retrieve(1)
endif
elseif !a:world.initialized
" TLogVAR a:world.initialized, a:world.win_wnr, a:world.bufnr
call a:world.Initialize()
if !empty(a:cmd)
let a:world.state .= ' '. a:cmd
endif
endif
" TLogVAR a:world.state, a:world.sticky
endf
function! s:CheckAgentReturnValue(name, value) "{{{3
if type(a:value) != 4 && !has_key(a:value, 'state')
echoerr 'Malformed agent: '. a:name
endif
return a:value
endf
" Functions related to tlib#input#EditList(type, ...) "{{{2
" :def: function! tlib#input#EditList(query, list, ?timeout=0)
" Edit a list.
"
" EXAMPLES: >
" echo tlib#input#EditList('Edit:', [100,200,300])
function! tlib#input#EditList(query, list, ...) "{{{3
let handlers = a:0 >= 1 && !empty(a:1) ? a:1 : g:tlib_handlers_EditList
let default = a:0 >= 2 ? a:2 : []
let timeout = a:0 >= 3 ? a:3 : 0
" TLogVAR handlers
let rv = tlib#input#List('me', a:query, copy(a:list), handlers, default, timeout)
" TLogVAR rv
if empty(rv)
return a:list
else
let [success, list] = rv
return success ? list : a:list
endif
endf
function! tlib#input#Resume(name, pick) "{{{3
echo
if exists('b:tlib_suspend')
for [m, pick] in items(b:tlib_suspend)
exec 'unmap <buffer> '. m
endfor
unlet b:tlib_suspend
endif
call tlib#autocmdgroup#Init()
autocmd! TLib InsertEnter,InsertChange <buffer>
let b:tlib_{a:name}.state = 'display'
" call tlib#input#List('resume '. a:name)
let cmd = 'resume '. a:name
if a:pick >= 1
let cmd .= ' pick'
if a:pick >= 2
let cmd .= ' sticky'
end
endif
call tlib#input#ListW(b:tlib_{a:name}, cmd)
endf
" :def: function! tlib#input#CommandSelect(command, ?keyargs={})
" Take a command, view the output, and let the user select an item from
" its output.
"
" EXAMPLE: >
" command! TMarks exec 'norm! `'. matchstr(tlib#input#CommandSelect('marks'), '^ \+\zs.')
" command! TAbbrevs exec 'norm i'. matchstr(tlib#input#CommandSelect('abbrev'), '^\S\+\s\+\zs\S\+')
function! tlib#input#CommandSelect(command, ...) "{{{3
TVarArg ['args', {}]
if has_key(args, 'retrieve')
let list = call(args.retrieve)
elseif has_key(args, 'list')
let list = args.list
else
let list = tlib#cmd#OutputAsList(a:command)
endif
if has_key(args, 'filter')
call map(list, args.filter)
endif
let type = has_key(args, 'type') ? args.type : 's'
let handlers = has_key(args, 'handlers') ? args.handlers : []
let rv = tlib#input#List(type, 'Select', list, handlers)
if !empty(rv)
if has_key(args, 'process')
let rv = call(args.process, [rv])
endif
endif
return rv
endf
" :def: function! tlib#input#Edit(name, value, callback, ?cb_args=[])
"
" Edit a value (asynchronously) in a scratch buffer. Use name for
" identification. Call callback when done (or on cancel).
" In the scratch buffer:
" Press <c-s> or <c-w><cr> to enter the new value, <c-w>c to cancel
" editing.
" EXAMPLES: >
" fun! FooContinue(success, text)
" if a:success
" let b:var = a:text
" endif
" endf
" call tlib#input#Edit('foo', b:var, 'FooContinue')
function! tlib#input#Edit(name, value, callback, ...) "{{{3
" TLogVAR a:value
TVarArg ['args', []]
let sargs = {'scratch': '__EDIT__'. a:name .'__', 'win_wnr': winnr()}
let scr = tlib#scratch#UseScratch(sargs)
" :nodoc:
map <buffer> <c-w>c :call <SID>EditCallback(0)<cr>
" :nodoc:
imap <buffer> <c-w>c <c-o>call <SID>EditCallback(0)<cr>
" :nodoc:
map <buffer> <c-s> :call <SID>EditCallback(1)<cr>
" :nodoc:
imap <buffer> <c-s> <c-o>call <SID>EditCallback(1)<cr>
" :nodoc:
map <buffer> <c-w><cr> :call <SID>EditCallback(1)<cr>
" :nodoc:
imap <buffer> <c-w><cr> <c-o>call <SID>EditCallback(1)<cr>
call tlib#normal#WithRegister('gg"tdG', 't')
call append(1, split(a:value, "\<c-j>", 1))
" let hrm = 'DON''T DELETE THIS HEADER'
" let hr3 = repeat('"', (tlib#win#Width(0) - len(hrm)) / 2)
let s:horizontal_line = repeat('`', tlib#win#Width(0))
" hr3.hrm.hr3
let hd = ['Keys: <c-s>, <c-w><cr> ... save/accept; <c-w>c ... cancel', s:horizontal_line]
call append(1, hd)
call tlib#normal#WithRegister('gg"tdd', 't')
syntax match TlibEditComment /^\%1l.*/
syntax match TlibEditComment /^```.*/
hi link TlibEditComment Comment
exec len(hd) + 1
if type(a:callback) == 4
let b:tlib_scratch_edit_callback = get(a:callback, 'submit', '')
call call(get(a:callback, 'init', ''), [])
else
let b:tlib_scratch_edit_callback = a:callback
endif
let b:tlib_scratch_edit_args = args
let b:tlib_scratch_edit_scratch = sargs
" exec 'autocmd BufDelete,BufHidden,BufUnload <buffer> call s:EditCallback('. string(a:name) .')'
" echohl MoreMsg
" echom 'Press <c-s> to enter, <c-w>c to cancel editing.'
" echohl NONE
endf
function! s:EditCallback(...) "{{{3
TVarArg ['ok', -1]
" , ['bufnr', -1]
" autocmd! BufDelete,BufHidden,BufUnload <buffer>
if ok == -1
let ok = confirm('Use value')
endif
let start = getline(2) == s:horizontal_line ? 3 : 1
let text = ok ? join(getline(start, '$'), "\n") : ''
let cb = b:tlib_scratch_edit_callback
let args = b:tlib_scratch_edit_args
let sargs = b:tlib_scratch_edit_scratch
" TLogVAR cb, args, sargs
call tlib#scratch#CloseScratch(b:tlib_scratch_edit_scratch)
call tlib#win#Set(sargs.win_wnr)
call call(cb, args + [ok, text])
endf
function! tlib#input#Dialog(text, options, default) "{{{3
if has('dialog_con') || has('dialog_gui')
let opts = join(map(a:options, '"&". v:val'), "\n")
let val = confirm(a:text, opts)
if val
let yn = a:options[val - 1]
else
let yn = a:default
endif
else
let oi = index(a:options, a:default)
if oi == -1
let opts = printf("(%s|%s)", join(a:options, '/'), a:default)
else
let options = copy(a:options)
let options[oi] = toupper(options[oi])
let opts = printf("(%s)", join(a:options, '/'))
endif
let yn = inputdialog(a:text .' '. opts)
endif
return yn
endf

View File

@ -0,0 +1,164 @@
" list.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2011-03-18.
" @Revision: 36
""" List related functions {{{1
" For the following functions please see ../../test/tlib.vim for examples.
" :def: function! tlib#list#Inject(list, initial_value, funcref)
" EXAMPLES: >
" echo tlib#list#Inject([1,2,3], 0, function('Add')
" => 6
function! tlib#list#Inject(list, value, Function) "{{{3
if empty(a:list)
return a:value
else
let item = a:list[0]
let rest = a:list[1:-1]
let value = call(a:Function, [a:value, item])
return tlib#list#Inject(rest, value, a:Function)
endif
endf
" EXAMPLES: >
" tlib#list#Compact([0,1,2,3,[], {}, ""])
" => [1,2,3]
function! tlib#list#Compact(list) "{{{3
return filter(copy(a:list), '!empty(v:val)')
endf
" EXAMPLES: >
" tlib#list#Flatten([0,[1,2,[3,""]]])
" => [0,1,2,3,""]
function! tlib#list#Flatten(list) "{{{3
let acc = []
for e in a:list
if type(e) == 3
let acc += tlib#list#Flatten(e)
else
call add(acc, e)
endif
unlet e
endfor
return acc
endf
" :def: function! tlib#list#FindAll(list, filter, ?process_expr="")
" Basically the same as filter()
"
" EXAMPLES: >
" tlib#list#FindAll([1,2,3], 'v:val >= 2')
" => [2, 3]
function! tlib#list#FindAll(list, filter, ...) "{{{3
let rv = filter(copy(a:list), a:filter)
if a:0 >= 1 && a:1 != ''
let rv = map(rv, a:1)
endif
return rv
endf
" :def: function! tlib#list#Find(list, filter, ?default="", ?process_expr="")
"
" EXAMPLES: >
" tlib#list#Find([1,2,3], 'v:val >= 2')
" => 2
function! tlib#list#Find(list, filter, ...) "{{{3
let default = a:0 >= 1 ? a:1 : ''
let expr = a:0 >= 2 ? a:2 : ''
return get(tlib#list#FindAll(a:list, a:filter, expr), 0, default)
endf
" EXAMPLES: >
" tlib#list#Any([1,2,3], 'v:val >= 2')
" => 1
function! tlib#list#Any(list, expr) "{{{3
return !empty(tlib#list#FindAll(a:list, a:expr))
endf
" EXAMPLES: >
" tlib#list#All([1,2,3], 'v:val >= 2')
" => 0
function! tlib#list#All(list, expr) "{{{3
return len(tlib#list#FindAll(a:list, a:expr)) == len(a:list)
endf
" EXAMPLES: >
" tlib#list#Remove([1,2,1,2], 2)
" => [1,1,2]
function! tlib#list#Remove(list, element) "{{{3
let idx = index(a:list, a:element)
if idx != -1
call remove(a:list, idx)
endif
return a:list
endf
" EXAMPLES: >
" tlib#list#RemoveAll([1,2,1,2], 2)
" => [1,1]
function! tlib#list#RemoveAll(list, element) "{{{3
call filter(a:list, 'v:val != a:element')
return a:list
endf
" :def: function! tlib#list#Zip(lists, ?default='')
" EXAMPLES: >
" tlib#list#Zip([[1,2,3], [4,5,6]])
" => [[1,4], [2,5], [3,6]]
function! tlib#list#Zip(lists, ...) "{{{3
TVarArg 'default'
let lists = copy(a:lists)
let max = 0
for l in lists
let ll = len(l)
if ll > max
let max = ll
endif
endfor
" TLogVAR default, max
return map(range(0, max - 1), 's:GetNthElement(v:val, lists, default)')
endf
function! s:GetNthElement(n, lists, default) "{{{3
" TLogVAR a:n, a:lists, a:default
return map(copy(a:lists), 'get(v:val, a:n, a:default)')
endf
function! tlib#list#Uniq(list, ...) "{{{3
TVarArg ['get_value', '']
let s:uniq_values = {}
if empty(get_value)
call filter(a:list, 's:UniqValue(v:val)')
else
call filter(a:list, 's:UniqValue(eval(printf(get_value, string(v:val))))')
endif
unlet s:uniq_values
return a:list
endf
function! s:UniqValue(value) "{{{3
if get(s:uniq_values, a:value, 0)
return 0
else
let s:uniq_values[a:value] = 1
return 1
endif
endf

View File

@ -0,0 +1,23 @@
" map.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2009-08-23.
" @Last Change: 2009-08-23.
" @Revision: 0.0.4
let s:save_cpo = &cpo
set cpo&vim
" If |pumvisible()| is true, return "\<c-y>". Otherwise return a:key.
" For use in maps like: >
" imap <expr> <cr> tlib#map#PumAccept("\<cr>")
function! tlib#map#PumAccept(key) "{{{3
return pumvisible() ? "\<c-y>" : a:key
endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,34 @@
" normal.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-10-06.
" @Last Change: 2010-09-22.
" @Revision: 28
let s:save_cpo = &cpo
set cpo&vim
" :display: tlib#normal#WithRegister(cmd, ?register='t', ?norm_cmd='norm!')
" Execute a normal command while maintaining all registers.
function! tlib#normal#WithRegister(cmd, ...) "{{{3
TVarArg ['register', 't'], ['norm_cmd', 'norm!']
let registers = {}
for reg in split('123456789'. register, '\zs')
exec 'let registers[reg] = @'. reg
endfor
exec 'let reg = @'. register
try
exec norm_cmd .' '. a:cmd
exec 'return @'. register
finally
for [reg, value] in items(registers)
exec 'let @'. reg .' = value'
endfor
endtry
endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,103 @@
" notify.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2008-09-19.
" @Last Change: 2011-03-10.
" @Revision: 0.0.15
let s:save_cpo = &cpo
set cpo&vim
" Print text in the echo area. Temporarily disable 'ruler' and 'showcmd'
" in order to prevent |press-enter| messages.
function! tlib#notify#Echo(text, ...) "{{{3
TVarArg 'style'
let ruler = &ruler
let showcmd = &showcmd
try
set noruler
set noshowcmd
if !empty(style)
exec 'echohl '. style
endif
echo strpart(a:text, 0, &columns - 1)
finally
if !empty(style)
echohl None
endif
let &ruler = ruler
let &showcmd = showcmd
endtry
endf
" Contributed by Erik Falor:
" If the line containing the message is too long, echoing it will cause
" a 'Hit ENTER' prompt to appear. This function cleans up the line so
" that does not happen.
" The echoed line is too long if it is wider than the width of the
" window, minus cmdline space taken up by the ruler and showcmd
" features.
function! tlib#notify#TrimMessage(message) "{{{3
let filler = '...'
" If length of message with tabs converted into spaces + length of
" line number + 2 (for the ': ' that follows the line number) is
" greater than the width of the screen, truncate in the middle
let to_fill = &columns
" TLogVAR to_fill
" Account for space used by elements in the command-line to avoid
" 'Hit ENTER' prompts.
" If showcmd is on, it will take up 12 columns.
" If the ruler is enabled, but not displayed in the statusline, it
" will in its default form take 17 columns. If the user defines a
" custom &rulerformat, they will need to specify how wide it is.
if has('cmdline_info')
if &showcmd
let to_fill -= 12
else
let to_fill -= 1
endif
" TLogVAR &showcmd, to_fill
" TLogVAR &laststatus, &ruler, &rulerformat
if &ruler
if &laststatus == 0 || winnr('$') == 1
if has('statusline')
if &rulerformat == ''
" default ruler is 17 chars wide
let to_fill -= 17
elseif exists('g:MP_rulerwidth')
let to_fill -= g:MP_rulerwidth
else
" tml: fallback: guess length
let to_fill -= strlen(&rulerformat)
endif
else
endif
endif
else
endif
else
let to_fill -= 1
endif
" TLogVAR to_fill
" TLogDBG strlen(a:message)
if strlen(a:message) > to_fill
let front = to_fill / 2 - 1
let back = front
if to_fill % 2 == 0 | let back -= 1 | endif
return strpart(a:message, 0, front) . filler .
\strpart(a:message, strlen(a:message) - back)
else
return a:message
endif
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,97 @@
" paragraph.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2009-10-26.
" @Last Change: 2011-04-03.
" @Revision: 62
let s:save_cpo = &cpo
set cpo&vim
" Return an object describing a |paragraph|.
function! tlib#paragraph#GetMetric() "{{{3
let sp = {'text_start': line("'{") + 1}
if line("'}") == line("$")
let sp.last = 1
let sp.text_end = line("'}")
if line("'{") == 1
let sp.ws_start = 0
let sp.ws_end = 0
let sp.top = sp.text_start
let sp.bottom = sp.text_end
else
let sp.ws_start = prevnonblank(line("'{")) + 1
let sp.ws_end = line("'{")
let sp.top = sp.ws_start
let sp.bottom = sp.text_end
endif
else
let sp.last = 0
let sp.text_end = line("'}") - 1
let sp.ws_start = line("'}")
for i in range(line("'}"), line('$'))
if getline(i) =~ '\w'
let sp.ws_end = i - 1
break
elseif i == line("$")
let sp.ws_end = i
endif
endfor
let sp.top = sp.text_start
let sp.bottom = sp.ws_end
endif
return sp
endf
" This function can be used with the tinymode plugin to move around
" paragraphs.
"
" Example configuration: >
"
" call tinymode#EnterMap("para_move", "gp")
" call tinymode#ModeMsg("para_move", "Move paragraph: j/k")
" call tinymode#Map("para_move", "j", "silent call tlib#paragraph#Move('Down', '[N]')")
" call tinymode#Map("para_move", "k", "silent call tlib#paragraph#Move('Up', '[N]')")
" call tinymode#ModeArg("para_move", "owncount", 1)
function! tlib#paragraph#Move(direction, count)
" TLogVAR a:direction, a:count
let mycount = empty(a:count) ? 1 : a:count
for i in range(1, mycount)
let para = tlib#paragraph#GetMetric()
" TLogVAR para
let text = getline(para.text_start, para.text_end)
let ws = getline(para.ws_start, para.ws_end)
" TLogVAR text, ws
exec para.top .','. para.bottom .'delete'
if a:direction == "Down"
let other = tlib#paragraph#GetMetric()
let target = other.bottom + 1
if other.last
let lines = ws + text
let pos = target + len(ws)
else
let lines = text + ws
let pos = target
endif
elseif a:direction == "Up"
if !para.last
norm! {
endif
let other = tlib#paragraph#GetMetric()
let target = other.text_start
let lines = text + ws
let pos = target
endif
" TLogVAR other, target
" TLogVAR lines
call append(target - 1, lines)
exec pos
endfor
endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,79 @@
" progressbar.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-09-30.
" @Last Change: 2010-01-07.
" @Revision: 0.0.66
if &cp || exists("loaded_tlib_progressbar_autoload")
finish
endif
let loaded_tlib_progressbar_autoload = 1
let s:statusline = []
let s:laststatus = []
let s:max = []
let s:format = []
let s:width = []
let s:value = []
let s:timestamp = -1
" EXAMPLE: >
" call tlib#progressbar#Init(20)
" try
" for i in range(20)
" call tlib#progressbar#Display(i)
" call DoSomethingThatTakesSomeTime(i)
" endfor
" finally
" call tlib#progressbar#Restore()
" endtry
function! tlib#progressbar#Init(max, ...) "{{{3
TVarArg ['format', '%s'], ['width', 10]
call insert(s:statusline, &statusline)
call insert(s:laststatus, &laststatus)
call insert(s:max, a:max)
call insert(s:format, format)
call insert(s:width, width)
call insert(s:value, -1)
let &laststatus = 2
let s:timestamp = localtime()
endf
function! tlib#progressbar#Display(value, ...) "{{{3
TVarArg 'extra'
let ts = localtime()
if ts == s:timestamp
return
else
let s:timestamp = ts
endif
let val = a:value * s:width[0] / s:max[0]
if val != s:value[0]
let s:value[0] = val
let pbl = repeat('#', val)
let pbr = repeat('.', s:width[0] - val)
let txt = printf(s:format[0], '['.pbl.pbr.']') . extra
let &l:statusline = txt
redrawstatus
" redraw
" call tlib#notify#Echo(txt)
endif
endf
function! tlib#progressbar#Restore() "{{{3
let &l:statusline = remove(s:statusline, 0)
let &laststatus = remove(s:laststatus, 0)
redrawstatus
" redraw
" echo
call remove(s:max, 0)
call remove(s:format, 0)
call remove(s:width, 0)
call remove(s:value, 0)
endf

View File

@ -0,0 +1,63 @@
" rx.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-07-20.
" @Last Change: 2010-02-26.
" @Revision: 0.0.28
if &cp || exists("loaded_tlib_rx_autoload")
finish
endif
let loaded_tlib_rx_autoload = 1
" :def: function! tlib#rx#Escape(text, ?magic='m')
" magic can be one of: m, M, v, V
" See :help 'magic'
function! tlib#rx#Escape(text, ...) "{{{3
TVarArg 'magic'
if empty(magic)
let magic = 'm'
endif
if magic =~# '^\\\?m$'
return escape(a:text, '^$.*\[]~')
elseif magic =~# '^\\\?M$'
return escape(a:text, '^$\')
elseif magic =~# '^\\\?V$'
return escape(a:text, '\')
elseif magic =~# '^\\\?v$'
return substitute(a:text, '[^0-9a-zA-Z_]', '\\&', 'g')
else
echoerr 'tlib: Unsupported magic type'
return a:text
endif
endf
" :def: function! tlib#rx#EscapeReplace(text, ?magic='m')
" Escape return |sub-replace-special|.
function! tlib#rx#EscapeReplace(text, ...) "{{{3
TVarArg ['magic', 'm']
if magic ==# 'm' || magic ==# 'v'
return escape(a:text, '\&~')
elseif magic ==# 'M' || magic ==# 'V'
return escape(a:text, '\')
else
echoerr 'magic must be one of: m, v, M, V'
endif
endf
function! tlib#rx#Suffixes(...) "{{{3
TVarArg ['magic', 'm']
let sfx = split(&suffixes, ',')
call map(sfx, 'tlib#rx#Escape(v:val, magic)')
if magic ==# 'v'
return '('. join(sfx, '|') .')$'
elseif magic ==# 'V'
return '\('. join(sfx, '\|') .'\)\$'
else
return '\('. join(sfx, '\|') .'\)$'
endif
endf

View File

@ -0,0 +1,123 @@
" scratch.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-07-18.
" @Last Change: 2011-03-10.
" @Revision: 0.0.166
if &cp || exists("loaded_tlib_scratch_autoload")
finish
endif
let loaded_tlib_scratch_autoload = 1
" :def: function! tlib#scratch#UseScratch(?keyargs={})
" Display a scratch buffer (a buffer with no file). See :TScratch for an
" example.
" Return the scratch buffer's number.
" Values for keyargs:
" scratch_split ... 1: split, 0: window, -1: tab
function! tlib#scratch#UseScratch(...) "{{{3
exec tlib#arg#Let([['keyargs', {}]])
" TLogDBG string(keys(keyargs))
let id = get(keyargs, 'scratch', '__Scratch__')
" TLogVAR id
" TLogDBG winnr()
" TLogDBG bufnr(id)
" TLogDBG bufwinnr(id)
" TLogDBG bufnr('%')
if id =~ '^\d\+$' && bufwinnr(id) != -1
if bufnr('%') != id
exec 'buffer! '. id
endif
" let ft = &ft
let ft = '*'
else
let bn = bufnr(id)
let wpos = get(keyargs, 'scratch_pos', g:tlib_scratch_pos)
" TLogVAR keyargs.scratch_vertical
if get(keyargs, 'scratch_vertical')
let wpos .= ' vertical'
endif
" TLogVAR wpos
let scratch_split = get(keyargs, 'scratch_split', 1)
if bn != -1
" TLogVAR bn
let wn = bufwinnr(bn)
if wn != -1
" TLogVAR wn
exec wn .'wincmd w'
else
if scratch_split == 1
let cmd = wpos.' sbuffer! '
elseif scratch_split == -1
let cmd = wpos.' tab sbuffer! '
else
let cmd = 'buffer! '
endif
" TLogVAR cmd
silent exec cmd . bn
endif
else
" TLogVAR id
if scratch_split == 1
let cmd = wpos.' split '
elseif scratch_split == -1
let cmd = wpos.' tab split '
else
let cmd = 'edit '
endif
" TLogVAR cmd
silent exec cmd . escape(id, '%#\ ')
" silent exec 'split '. id
endif
let ft = get(keyargs, 'scratch_filetype', '')
" TLogVAR ft
endif
setlocal buftype=nofile
setlocal bufhidden=hide
setlocal noswapfile
setlocal nobuflisted
setlocal foldmethod=manual
setlocal foldcolumn=0
setlocal modifiable
setlocal nospell
if &ft != '*'
let &ft = ft
endif
let keyargs.scratch = bufnr('%')
return keyargs.scratch
endf
" Close a scratch buffer as defined in keyargs (usually a World).
" Return 1 if the scratch buffer is closed (or if it already was
" closed).
function! tlib#scratch#CloseScratch(keyargs, ...) "{{{3
TVarArg ['reset_scratch', 1]
let scratch = get(a:keyargs, 'scratch', '')
" TLogVAR scratch, reset_scratch
" TLogDBG string(tlib#win#List())
if !empty(scratch) && winnr('$') > 1
let wn = bufwinnr(scratch)
" TLogVAR wn
try
if wn != -1
" TLogDBG winnr()
let wb = tlib#win#Set(wn)
wincmd c
" exec wb
" redraw
" TLogVAR winnr()
endif
return 1
finally
if reset_scratch
let a:keyargs.scratch = ''
endif
endtry
endif
return 0
endf

View File

@ -0,0 +1,103 @@
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2009-03-12.
" @Last Change: 2011-03-10.
" @Revision: 0.0.45
let s:save_cpo = &cpo
set cpo&vim
let s:base = 2327
let s:register = {}
" Clear all signs with name SIGN.
function! tlib#signs#ClearAll(sign) "{{{3
" TLog a:sign
for bn in keys(s:register)
let idxs = keys(s:register)
call filter(idxs, 's:register[v:val].sign == a:sign')
" TLogVAR bns
for idx in idxs
exec 'sign unplace '. idx .' buffer='. s:register[idx].bn
call remove(s:register, idx)
endfor
endfor
endf
" Clear all signs with name SIGN in buffer BUFNR.
function! tlib#signs#ClearBuffer(sign, bufnr) "{{{3
for bn in keys(s:register)
let idxs = keys(s:register)
call filter(idxs, 's:register[v:val].sign == a:sign && s:register[v:val].bn == a:bufnr')
" TLogVAR bns
for idx in idxs
exec 'sign unplace '. idx .' buffer='. s:register[idx].bn
call remove(s:register, idx)
endfor
endfor
endf
" function! tlib#signs#Clear(sign, list) "{{{3
" " TLogVAR a:sign
" let done = []
" for item in a:list
" let bn = get(item, 'bufnr', -1)
" if index(done, bn) == -1
" let idxs = keys(s:register)
" call filter(idxs, 's:register[v:val].sign == a:sign && s:register[v:val].bn == bn')
" for idx in idxs
" exec 'sign unplace '. idx .' buffer='. s:register[idx].bn
" call remove(s:register, idx)
" endfor
" call add(done, bn)
" endif
" endfor
" endf
" Add signs for all locations in LIST. LIST must adhere with the
" quickfix list format (see |getqflist()|; only the fields lnum and
" bufnr are required).
"
" list:: a quickfix or location list
" sign:: a sign defined with |:sign-define|
function! tlib#signs#Mark(sign, list) "{{{3
" TLogVAR a:sign
for item in a:list
let idx = s:SignId(item)
if idx >= 0
let lnum = get(item, 'lnum', 0)
if lnum > 0
let bn = get(item, 'bufnr')
exec ':sign place '. idx .' line='. lnum .' name='. a:sign .' buffer='. bn
let s:register[idx] = {'sign': a:sign, 'bn': bn}
endif
endif
endfor
endf
function! s:SignId(item) "{{{3
" TLogVAR a:item
" let bn = bufnr('%')
let bn = get(a:item, 'bufnr', -1)
if bn == -1
return -1
else
let idx = s:base + bn * 500
while has_key(s:register, idx)
let idx += 1
endwh
return idx
endif
endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,156 @@
" string.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2009-02-15.
" @Revision: 0.0.110
if &cp || exists("loaded_tlib_string_autoload")
finish
endif
let loaded_tlib_string_autoload = 1
" :def: function! tlib#string#RemoveBackslashes(text, ?chars=' ')
" Remove backslashes from text (but only in front of the characters in
" chars).
function! tlib#string#RemoveBackslashes(text, ...) "{{{3
exec tlib#arg#Get(1, 'chars', ' ')
" TLogVAR chars
let rv = substitute(a:text, '\\\(['. chars .']\)', '\1', 'g')
return rv
endf
function! tlib#string#Chomp(string) "{{{3
return substitute(a:string, '[[:cntrl:][:space:]]*$', '', '')
endf
function! tlib#string#Format(template, dict) "{{{3
let parts = split(a:template, '\ze%\({.\{-}}\|.\)')
let out = []
for part in parts
let ml = matchlist(part, '^%\({\(.\{-}\)}\|\(.\)\)\(.*\)$')
if empty(ml)
let rest = part
else
let var = empty(ml[2]) ? ml[3] : ml[2]
let rest = ml[4]
if has_key(a:dict, var)
call add(out, a:dict[var])
elseif var == '%%'
call add(out, '%')
else
call add(out, ml[1])
endif
endif
call add(out, rest)
endfor
return join(out, '')
endf
" This function deviates from |printf()| in certain ways.
" Additional items:
" %{rx} ... insert escaped regexp
" %{fuzzyrx} ... insert typo-tolerant regexp
function! tlib#string#Printf1(format, string) "{{{3
let s = split(a:format, '%.\zs')
" TLogVAR s
return join(map(s, 's:PrintFormat(v:val, a:string)'), '')
endf
function! s:PrintFormat(format, string) "{{{3
let cut = match(a:format, '%\({.\{-}}\|.\)$')
if cut == -1
return a:format
else
let head = cut > 0 ? a:format[0 : cut - 1] : ''
let tail = a:format[cut : -1]
" TLogVAR head, tail
if tail == '%{fuzzyrx}'
let frx = []
for i in range(len(a:string))
if i > 0
let pb = i - 1
else
let pb = 0
endif
let slice = tlib#rx#Escape(a:string[pb : i + 1])
call add(frx, '['. slice .']')
call add(frx, '.\?')
endfor
let tail = join(frx, '')
elseif tail == '%{rx}'
let tail = tlib#rx#Escape(a:string)
elseif tail == '%%'
let tail = '%'
elseif tail == '%s'
let tail = a:string
endif
" TLogVAR tail
return head . tail
endif
endf
" function! tlib#string#Printf1(format, string) "{{{3
" let n = len(split(a:format, '%\@<!%s', 1)) - 1
" let f = a:format
" if f =~ '%\@<!%{fuzzyrx}'
" let frx = []
" for i in range(len(a:string))
" if i > 0
" let pb = i - 1
" else
" let pb = 0
" endif
" let slice = tlib#rx#Escape(a:string[pb : i + 1])
" call add(frx, '['. slice .']')
" call add(frx, '.\?')
" endfor
" let f = s:RewriteFormatString(f, '%{fuzzyrx}', join(frx, ''))
" endif
" if f =~ '%\@<!%{rx}'
" let f = s:RewriteFormatString(f, '%{rx}', tlib#rx#Escape(a:string))
" endif
" if n == 0
" return substitute(f, '%%', '%', 'g')
" else
" let a = repeat([a:string], n)
" return call('printf', insert(a, f))
" endif
" endf
function! s:RewriteFormatString(format, pattern, string) "{{{3
let string = substitute(a:string, '%', '%%', 'g')
return substitute(a:format, tlib#rx#Escape(a:pattern), escape(string, '\'), 'g')
endf
function! tlib#string#TrimLeft(string) "{{{3
return substitute(a:string, '^[[:space:][:cntrl:]]\+', '', '')
endf
function! tlib#string#TrimRight(string) "{{{3
return substitute(a:string, '[[:space:][:cntrl:]]\+$', '', '')
endf
function! tlib#string#Strip(string) "{{{3
return tlib#string#TrimRight(tlib#string#TrimLeft(a:string))
endf
function! tlib#string#Count(string, rx) "{{{3
let s:count = 0
call substitute(a:string, a:rx, '\=s:CountHelper()', 'g')
return s:count
endf
function! s:CountHelper() "{{{3
let s:count += 1
endf

View File

@ -0,0 +1,51 @@
" syntax.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-11-19.
" @Last Change: 2009-02-15.
" @Revision: 0.0.11
if &cp || exists("loaded_tlib_syntax_autoload")
finish
endif
let loaded_tlib_syntax_autoload = 1
let s:save_cpo = &cpo
set cpo&vim
function! tlib#syntax#Collect() "{{{3
let acc = {}
let syn = ''
for line in tlib#cmd#OutputAsList('syntax')
if line =~ '^---'
continue
elseif line =~ '^\w'
let ml = matchlist(line, '^\(\w\+\)\s\+\(xxx\s\+\(.*\)\|\(cluster.*\)\)$')
if empty(ml)
echoerr 'Internal error: '. string(line)
else
let [m_0, syn, m_1, m_def1, m_def2; m_rest] = ml
let acc[syn] = [empty(m_def1) ? m_def2 : m_def1]
endif
else
call add(acc[syn], matchstr(line, '^\s\+\zs.*$'))
endif
endfor
return acc
endf
" :def: function! tlib#syntax#Names(?rx='')
function! tlib#syntax#Names(...) "{{{3
TVarArg 'rx'
let names = keys(tlib#syntax#Collect())
if !empty(rx)
call filter(names, 'v:val =~ rx')
endif
return names
endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,55 @@
" tab.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-08-27.
" @Last Change: 2009-02-15.
" @Revision: 0.0.29
if &cp || exists("loaded_tlib_tab_autoload")
finish
endif
let loaded_tlib_tab_autoload = 1
" Return a dictionary of bufnumbers => [[tabpage, winnr] ...]
function! tlib#tab#BufMap() "{{{3
let acc = {}
for t in range(tabpagenr('$'))
let bb = tabpagebuflist(t + 1)
for b in range(len(bb))
let bn = bb[b]
let bd = [t + 1, b + 1]
if has_key(acc, bn)
call add(acc[bn], bd)
else
let acc[bn] = [bd]
endif
endfor
endfor
return acc
endf
" Find a buffer's window at some tab page.
function! tlib#tab#TabWinNr(buffer) "{{{3
let bn = bufnr(a:buffer)
let bt = tlib#tab#BufMap()
let tn = tabpagenr()
let wn = winnr()
let bc = get(bt, bn)
if !empty(bc)
for [t, w] in bc
if t == tn
return [t, w]
endif
endfor
return bc[0]
endif
endf
function! tlib#tab#Set(tabnr) "{{{3
exec a:tabnr .'tabnext'
endf

View File

@ -0,0 +1,122 @@
" tag.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-11-01.
" @Last Change: 2011-03-10.
" @Revision: 0.0.53
if &cp || exists("loaded_tlib_tag_autoload")
finish
endif
let loaded_tlib_tag_autoload = 1
" :def: function! tlib#tag#Retrieve(rx, ?extra_tags=0)
" Get all tags matching rx. Basically, this function simply calls
" |taglist()|, but when extra_tags is true, the list of the tag files
" (see 'tags') is temporarily expanded with |g:tlib_tags_extra|.
"
" Example use:
" If you want to include tags for, eg, JDK, normal tags use can become
" slow. You could proceed as follows:
" 1. Create a tags file for the JDK sources. When creating the tags
" file, make sure to include inheritance information and the like
" (command-line options like --fields=+iaSm --extra=+q should be ok).
" In this example, we want tags only for public methods (there are
" most likely better ways to do this): >
" ctags -R --fields=+iaSm --extra=+q ${JAVA_HOME}/src
" head -n 6 tags > tags0
" grep access:public tags >> tags0
" < 2. Make 'tags' include project specific tags files. In
" ~/vimfiles/after/ftplugin/java.vim insert: >
" let b:tlib_tags_extra = $JAVA_HOME .'/tags0'
" < 3. When this function is invoked as >
" echo tlib#tag#Retrieve('print')
" < it will return only project-local tags. If it is invoked as >
" echo tlib#tag#Retrieve('print', 1)
" < tags from the JDK will be included.
function! tlib#tag#Retrieve(rx, ...) "{{{3
TVarArg ['extra_tags', 0]
if extra_tags
let tags_orig = &l:tags
if empty(tags_orig)
setlocal tags<
endif
try
let more_tags = tlib#var#Get('tlib_tags_extra', 'bg')
if !empty(more_tags)
let &l:tags .= ','. more_tags
endif
let taglist = taglist(a:rx)
finally
let &l:tags = tags_orig
endtry
else
let taglist = taglist(a:rx)
endif
return taglist
endf
" Retrieve tags that meet the constraints (a dictionnary of fields and
" regexp, with the exception of the kind field which is a list of chars).
" For the use of the optional use_extra argument see
" |tlib#tag#Retrieve()|.
" :def: function! tlib#tag#Collect(constraints, ?use_extra=1, ?match_front=1)
function! tlib#tag#Collect(constraints, ...) "{{{3
TVarArg ['use_extra', 0], ['match_end', 1], ['match_front', 1]
" TLogVAR a:constraints, use_extra
let rx = get(a:constraints, 'name', '')
if empty(rx) || rx == '*'
let rx = '.'
else
let rxl = ['\C']
if match_front
call add(rxl, '^')
endif
" call add(rxl, tlib#rx#Escape(rx))
call add(rxl, rx)
if match_end
call add(rxl, '$')
endif
let rx = join(rxl, '')
endif
" TLogVAR rx, use_extra
let tags = tlib#tag#Retrieve(rx, use_extra)
" TLogDBG len(tags)
for [field, rx] in items(a:constraints)
if !empty(rx) && rx != '*'
" TLogVAR field, rx
if field == 'kind'
call filter(tags, 'v:val.kind =~ "['. rx .']"')
elseif field != 'name'
call filter(tags, '!empty(get(v:val, field)) && get(v:val, field) =~ rx')
endif
endif
endfor
" TLogVAR tags
return tags
endf
function! tlib#tag#Format(tag) "{{{3
if has_key(a:tag, 'signature')
let name = a:tag.name . a:tag.signature
elseif a:tag.cmd[0] == '/'
let name = a:tag.cmd
let name = substitute(name, '^/\^\?\s*', '', '')
let name = substitute(name, '\s*\$\?/$', '', '')
let name = substitute(name, '\s\{2,}', ' ', 'g')
let tsub = tlib#var#Get('tlib_tag_substitute', 'bg')
if has_key(tsub, &filetype)
for [rx, rplc, sub] in tsub[&filetype]
let name = substitute(name, rx, rplc, sub)
endfor
endif
else
let name = a:tag.name
endif
return name
endf

View File

@ -0,0 +1,45 @@
" textobjects.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2010-01-09.
" @Last Change: 2010-01-10.
" @Revision: 0.0.29
let s:save_cpo = &cpo
set cpo&vim
" :tag: standard-paragraph
" Select a "Standard Paragraph", i.e. a text block followed by blank
" lines. Other than |ap|, the last paragraph in a document is handled
" just the same.
"
" The |text-object| can be accessed as "sp". Example: >
"
" vsp ... select the current standard paragraph
"
" Return 1, if the paragraph is the last one in the document.
function! tlib#textobjects#StandardParagraph() "{{{3
if line("'}") == line('$')
norm! vip
return 1
else
norm! vap
return 0
endif
endf
function! tlib#textobjects#Init() "{{{3
if !exists('s:tlib_done_textobjects')
" sp ... Standard paragraph (for use as |text-objects|).
vnoremap <silent> sp <Esc>:call tlib#textobjects#StandardParagraph()<CR>
onoremap <silent> sp :<C-u>normal Vsp<CR>
let s:tlib_done_textobjects = 1
endif
endf
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,60 @@
" time.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-10-17.
" @Last Change: 2009-02-22.
" @Revision: 0.0.29
if &cp || exists("loaded_tlib_time_autoload")
finish
endif
let loaded_tlib_time_autoload = 1
function! tlib#time#MSecs() "{{{3
let rts = reltimestr(reltime())
return substitute(rts, '\.', '', '')
endf
function! tlib#time#Now() "{{{3
let rts = reltimestr(reltime())
let rtl = split(rts, '\.')
return rtl
endf
function! tlib#time#Diff(a, b, ...) "{{{3
TVarArg ['resolution', 2]
let [as, am] = a:a
let [bs, bm] = a:b
let rv = 0 + (as - bs)
if resolution > 0
let rv .= repeat('0', resolution)
let am = am[0 : resolution - 1]
let bm = bm[0 : resolution - 1]
let rv += (am - bm)
endif
return rv
endf
function! tlib#time#DiffMSecs(a, b, ...) "{{{3
TVarArg ['resolution', 2]
if a:a == a:b
return 0
endif
let a = printf('%30s', a:a[0 : -(7 - resolution)])
let b = printf('%30s', a:b[0 : -(7 - resolution)])
for i in range(0, 29)
if a[i] != b[i]
let a = a[i : -1]
let b = b[i : -1]
return a - b
endif
endfor
return 0
endf

View File

@ -0,0 +1,29 @@
" type.vim
" @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-09-30.
" @Last Change: 2010-09-27.
" @Revision: 0.0.4
function! tlib#type#IsNumber(expr)
return type(a:expr) == 0
endf
function! tlib#type#IsString(expr)
return type(a:expr) == 1
endf
function! tlib#type#IsFuncref(expr)
return type(a:expr) == 2
endf
function! tlib#type#IsList(expr)
return type(a:expr) == 3
endf
function! tlib#type#IsDictionary(expr)
return type(a:expr) == 4
endf

View File

@ -0,0 +1,52 @@
" url.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2011-03-10.
" @Revision: 0.0.28
" TODO: These functions could use printf() now.
" Decode an encoded URL.
function! tlib#url#Decode(url) "{{{3
return substitute(a:url, '\(+\|%\(%\|\x\x\)\)', '\=tlib#url#DecodeChar(submatch(1))', 'g')
endf
" Decode a single character.
function! tlib#url#DecodeChar(char) "{{{3
if a:char == '%%'
return '%'
elseif a:char == '+'
return ' '
else
return nr2char("0x".a:char[1 : -1])
endif
endf
" Encode a single character.
function! tlib#url#EncodeChar(char) "{{{3
if a:char == '%'
return '%%'
elseif a:char == ' '
return '+'
else
return printf("%%%X", char2nr(a:char))
endif
endf
" Encode an URL.
function! tlib#url#Encode(url, ...) "{{{3
TVarArg ['extrachars', '']
let rx = '\([^a-zA-Z0-9_.'. extrachars .'-]\)'
" TLogVAR a:url, rx
let rv = substitute(a:url, rx, '\=tlib#url#EncodeChar(submatch(1))', 'g')
" TLogVAR rv
return rv
endf

View File

@ -0,0 +1,85 @@
" var.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-06-30.
" @Last Change: 2009-02-15.
" @Revision: 0.0.23
if &cp || exists("loaded_tlib_var_autoload")
finish
endif
let loaded_tlib_var_autoload = 1
" Define a variable called NAME if yet undefined.
" You can also use the :TLLet command.
"
" EXAMPLES: >
" exec tlib#var#Let('g:foo', 1)
" TLet g:foo = 1
function! tlib#var#Let(name, val) "{{{3
return printf('if !exists(%s) | let %s = %s | endif', string(a:name), a:name, string(a:val))
" return printf('if !exists(%s) | let %s = %s | endif', string(a:name), a:name, a:val)
endf
" :def: function! tlib#var#EGet(var, namespace, ?default='')
" Retrieve a variable by searching several namespaces.
"
" EXAMPLES: >
" let g:foo = 1
" let b:foo = 2
" let w:foo = 3
" echo eval(tlib#var#EGet('foo', 'vg')) => 1
" echo eval(tlib#var#EGet('foo', 'bg')) => 2
" echo eval(tlib#var#EGet('foo', 'wbg')) => 3
function! tlib#var#EGet(var, namespace, ...) "{{{3
let pre = []
let post = []
for namespace in split(a:namespace, '\zs')
let var = namespace .':'. a:var
call add(pre, printf('exists("%s") ? %s : (', var, var))
call add(post, ')')
endfor
let default = a:0 >= 1 ? a:1 : ''
return join(pre) . string(default) . join(post)
endf
" :def: function! tlib#var#Get(var, namespace, ?default='')
" Retrieve a variable by searching several namespaces.
"
" EXAMPLES: >
" let g:foo = 1
" let b:foo = 2
" let w:foo = 3
" echo tlib#var#Get('foo', 'bg') => 1
" echo tlib#var#Get('foo', 'bg') => 2
" echo tlib#var#Get('foo', 'wbg') => 3
function! tlib#var#Get(var, namespace, ...) "{{{3
for namespace in split(a:namespace, '\zs')
let var = namespace .':'. a:var
if exists(var)
return eval(var)
endif
endfor
return a:0 >= 1 ? a:1 : ''
endf
" :def: function! tlib#var#List(rx, ?prefix='')
" Get a list of variables matching rx.
" EXAMPLE:
" echo tlib#var#List('tlib_', 'g:')
function! tlib#var#List(rx, ...) "{{{3
TVarArg ['prefix', '']
redir => vars
silent! exec 'let '. prefix
redir END
let varlist = split(vars, '\n')
call map(varlist, 'matchstr(v:val, ''^\S\+'')')
call filter(varlist, 'v:val =~ a:rx')
return varlist
endf

View File

@ -0,0 +1,107 @@
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @GIT: http://github.com/tomtom/tlib_vim/
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2010-07-19.
" @Last Change: 2010-10-24.
" @Revision: 24
let s:restoreframecmd = ''
let s:fullscreen = 0
if has('win16') || has('win32') || has('win64')
if !exists('g:tlib#vim#simalt_maximize')
let g:tlib#vim#simalt_maximize = 'x' "{{{2
endif
if !exists('g:tlib#vim#simalt_restore')
let g:tlib#vim#simalt_restore = 'r' "{{{2
endif
if !exists('g:tlib#vim#use_vimtweak')
let g:tlib#vim#use_vimtweak = 0 "{{{2
endif
" Maximize the window.
" You might need to redefine |g:tlib#vim#simalt_maximize| if it doesn't
" work for you.
fun! tlib#vim#Maximize(fullscreen) "{{{3
if !has("gui_running")
return
endif
call s:SaveFrameParams()
let s:fullscreen = a:fullscreen
if g:tlib#vim#use_vimtweak && a:fullscreen
call libcallnr("vimtweak.dll", "EnableCaption", 0)
endif
exec 'simalt ~'. g:tlib#vim#simalt_maximize
endf
" Restore the original vimsize after having called |tlib#vim#Maximize()|.
function! tlib#vim#RestoreWindow() "{{{3
if !has("gui_running")
return
endif
if g:tlib#vim#use_vimtweak
call libcallnr("vimtweak.dll", "EnableCaption", 1)
endif
exec 'simalt ~'. g:tlib#vim#simalt_restore
call s:RestoreFrameParams()
endf
else
if !exists('g:tlib#vim#use_wmctrl')
let g:tlib#vim#use_wmctrl = executable('wmctrl') "{{{2
endif
" :nodoc:
fun! tlib#vim#Maximize(fullscreen) "{{{3
if !has("gui_running")
return
endif
call s:SaveFrameParams()
let s:fullscreen = a:fullscreen
if g:tlib#vim#use_wmctrl
if a:fullscreen
silent !wmctrl -r :ACTIVE: -b add,fullscreen
else
silent !wmctrl -r :ACTIVE: -b add,maximized_vert,maximized_horz
endif
else
set lines=1000 columns=1000
endif
endf
" :nodoc:
function! tlib#vim#RestoreWindow() "{{{3
if !has("gui_running")
return
endif
if g:tlib#vim#use_wmctrl
if s:fullscreen
silent !wmctrl -r :ACTIVE: -b remove,fullscreen
else
silent !wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz
endif
endif
call s:RestoreFrameParams()
endf
endif
function! s:SaveFrameParams() "{{{3
let s:restoreframecmd = printf("set lines=%d columns=%d | winpos %d %d", &lines, &columns, getwinposx(), getwinposy())
endf
function! s:RestoreFrameParams() "{{{3
if !empty(s:restoreframecmd)
exec s:restoreframecmd
let s:restoreframecmd = ''
endif
endf

View File

@ -0,0 +1,136 @@
" win.vim
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-08-24.
" @Last Change: 2010-12-04.
" @Revision: 0.0.54
if &cp || exists("loaded_tlib_win_autoload")
finish
endif
let loaded_tlib_win_autoload = 1
" Return vim code to jump back to the original window.
function! tlib#win#Set(winnr) "{{{3
if a:winnr > 0
" TLogVAR a:winnr
" TLogDBG winnr()
" TLogDBG string(tlib#win#List())
if winnr() != a:winnr && winbufnr(a:winnr) != -1
let rv = winnr().'wincmd w'
exec a:winnr .'wincmd w'
" TLogVAR rv
" TLogDBG string(tlib#win#List())
return rv
endif
endif
return ''
endf
" :def: function! tlib#win#GetLayout(?save_view=0)
function! tlib#win#GetLayout(...) "{{{3
TVarArg ['save_view', 0]
let views = {}
if save_view
let winnr = winnr()
windo let views[winnr()] = winsaveview()
" for w in range(1, winnr('$'))
" call tlib#win#Set(w)
" let views[w] = winsaveview()
" endfor
call tlib#win#Set(winnr)
endif
return {'winnr': winnr('$'), 'winrestcmd': winrestcmd(), 'views': views, 'cmdheight': &cmdheight, 'guioptions': &guioptions, 'tabpagenr': tabpagenr()}
endf
function! tlib#win#SetLayout(layout) "{{{3
if a:layout.tabpagenr == tabpagenr() && a:layout.winnr == winnr('$')
" TLogVAR a:layout.winrestcmd
" TLogDBG string(tlib#win#List())
exec a:layout.winrestcmd
if !empty(a:layout.views)
let winnr = winnr()
" TLogVAR winnr
for [w, v] in items(a:layout.views)
" TLogVAR w, v
call tlib#win#Set(w)
call winrestview(v)
endfor
call tlib#win#Set(winnr)
endif
if a:layout.cmdheight != &cmdheight
let &cmdheight = a:layout.cmdheight
endif
" TLogDBG string(tlib#win#List())
return 1
endif
return 0
endf
function! tlib#win#List() "{{{3
let wl = {}
for wn in range(1, winnr('$'))
let wl[wn] = bufname(winbufnr(wn))
endfor
return wl
endf
" " :def: function! tlib#win#GetLayout1(?save_view=0)
" " Contrary to |tlib#win#GetLayout|, this version doesn't use
" " |winrestcmd()|. It can also save windows views.
" function! tlib#win#GetLayout1(...) "{{{3
" TVarArg ['save_view', 0]
" let winnr = winnr()
" let acc = {}
" for w in range(1, winnr('$'))
" let def = {'h': winheight(w), 'w': winwidth(w)}
" if save_view
" call tlib#win#Set(w)
" let def.view = winsaveview()
" endif
" let acc[w] = def
" endfor
" call tlib#win#Set(winnr)
" return acc
" endf
"
"
" " Reset layout from the value of |tlib#win#GetLayout1|.
" function! tlib#win#SetLayout1(layout) "{{{3
" if len(a:layout) != winnr('$')
" return 0
" endif
" let winnr = winnr()
" for [w, def] in items(a:layout)
" if tlib#win#Set(w)
" exec 'resize '. def.h
" exec 'vertical resize '. def.w
" if has_key(def, 'view')
" call winrestview(def.view)
" endif
" else
" break
" endif
" endfor
" call tlib#win#Set(winnr)
" return 1
" endf
function! tlib#win#Width(wnr) "{{{3
return winwidth(a:wnr) - &fdc
endf
function! tlib#win#WinDo(ex) "{{{3
let w = winnr()
exec 'windo '. a:ex
exec w .'wincmd w'
endf

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,318 @@
" tlib.vim -- Some utility functions
" @Author: Tom Link (micathom AT gmail com?subject=[vim])
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-04-10.
" @Last Change: 2011-04-28.
" @Revision: 672
" GetLatestVimScripts: 1863 1 tlib.vim
if &cp || exists("loaded_tlib")
finish
endif
if v:version < 700 "{{{2
echoerr "tlib requires Vim >= 7"
finish
endif
let loaded_tlib = 41
let s:save_cpo = &cpo
set cpo&vim
" Init~ {{{1
" call tlib#autocmdgroup#Init()
" Commands~ {{{1
" :display: TRequire NAME [VERSION [FILE]]
" Make a certain vim file is loaded.
"
" Conventions: If FILE isn't defined, plugin/NAME.vim is loaded. The
" file must provide a variable loaded_{NAME} that represents the version
" number.
command! -nargs=+ TRequire let s:require = [<f-args>]
\ | if !exists('loaded_'. get(s:require, 0))
\ | exec 'runtime '. get(s:require, 2, 'plugin/'. get(s:require, 0) .'.vim')
\ | if !exists('loaded_'. get(s:require, 0)) || loaded_{get(s:require, 0)} < get(s:require, 1, loaded_{get(s:require, 0)})
\ | echoerr 'Require '. get(s:require, 0) .' >= '. get(s:require, 1, 'any version will do')
\ | finish
\ | endif
\ | endif | unlet s:require
" :display: :TLet VAR = VALUE
" Set a variable only if it doesn't already exist.
" EXAMPLES: >
" TLet foo = 1
" TLet foo = 2
" echo foo
" => 1
command! -nargs=+ TLet if !exists(matchstr(<q-args>, '^[^=[:space:]]\+')) | exec 'let '. <q-args> | endif
" Open a scratch buffer (a buffer without a file).
" TScratch ... use split window
" TScratch! ... use the whole frame
" This command takes an (inner) dictionary as optional argument.
" EXAMPLES: >
" TScratch 'scratch': '__FOO__'
" => Open a scratch buffer named __FOO__
command! -bar -nargs=* -bang TScratch call tlib#scratch#UseScratch({'scratch_split': '<bang>' != '!', <args>})
" :display: :TVarArg VAR1, [VAR2, DEFAULT2] ...
" A convenience wrapper for |tlib#arg#Let|.
" EXAMPLES: >
" function! Foo(...)
" TVarArg ['a', 1], 'b'
" echo 'a='. a
" echo 'b='. b
" endf
command! -nargs=+ TVarArg exec tlib#arg#Let([<args>])
" :display: :TKeyArg DICT, VAR1, [VAR2, DEFAULT2] ...
" A convenience wrapper for |tlib#arg#Let|.
" EXAMPLES: >
" function! Foo(keyargs)
" TKeyArg a:keyargs, ['a', 1], 'b'
" echo 'a='. a
" echo 'b='. b
" endf
command! -nargs=+ TKeyArg exec tlib#arg#Key([<args>])
" :display: TBrowseOutput COMMAND
" Ever wondered how to efficiently browse the output of a command
" without redirecting it to a file? This command takes a command as
" argument and presents the output via |tlib#input#List()| so that you
" can easily search for a keyword (e.g. the name of a variable or
" function) and the like.
"
" If you press enter, the selected line will be copied to the command
" line. Press ESC to cancel browsing.
"
" EXAMPLES: >
" TBrowseOutput 20verb TeaseTheCulprit
command! -nargs=1 -complete=command TBrowseOutput call tlib#cmd#BrowseOutput(<q-args>)
" :display: TBrowseScriptnames
" List all sourced script names (the output of ':scriptnames').
"
" When you press enter, the selected script will be opened in the current
" window. Press ESC to cancel.
"
" EXAMPLES: >
" TBrowseScriptnames
command! -nargs=0 -complete=command TBrowseScriptnames call
\ tlib#cmd#BrowseOutputWithCallback("tlib#cmd#ParseScriptname", "scriptnames")
" :display: TTimeCommand CMD
" Time the execution time of CMD.
command! -nargs=1 -complete=command TTimeCommand call tlib#cmd#Time(<q-args>)
" Variables~ {{{1
" When 1, automatically select the last remaining item only if the list
" had only one item to begin with.
" When 2, automatically select a last remaining item after applying
" any filters.
TLet g:tlib_pick_last_item = 1
" If a list is bigger than this value, don't try to be smart when
" selecting an item. Be slightly faster instead.
TLet g:tlib_sortprefs_threshold = 200
" Scratch window position. By default the list window is opened on the
" bottom. Set this variable to 'topleft' or '' to change this behaviour.
TLet g:tlib_scratch_pos = 'botright'
" Size of the input list window (in percent) from the main size (of &lines).
TLet g:tlib_inputlist_pct = 50
" Size of filename columns when listing filenames.
TLet g:tlib_inputlist_width_filename = '&co / 3'
" TLet g:tlib_inputlist_width_filename = 25
" The highlight group to use for showing matches in the input list window.
TLet g:tlib_inputlist_higroup = 'IncSearch'
" If a list contains more items, don't do an incremental "live search",
" but use |input()| to query the user for a filter. This is useful on
" slower machines or with very long lists.
TLet g:tlib_inputlist_livesearch_threshold = 1000
" If true, show some indicators about the status of a filename (e.g.
" buflisted(), bufloaded() etc.).
" This is disabled by default because vim checks also for the file on
" disk when doing this.
TLet g:tlib_inputlist_filename_indicators = 0
" Can be "cnf", "cnfd", "seq", or "fuzzy". See:
" cnf :: Match substrings
" - |tlib#Filter_cnf#New()| (this is the default method)
" - |tlib#Filter_cnfd#New()|
" seq :: Match sequences of characters
" - |tlib#Filter_seq#New()|
" fuzzy :: Match fuzzy character sequences
" - |tlib#Filter_fuzzy#New()|
TLet g:tlib_inputlist_match = 'cnf'
" If not null, display only a short info about the filter.
TLet g:tlib_inputlist_shortmessage = 0
" Extra tags for |tlib#tag#Retrieve()| (see there). Can also be buffer-local.
TLet g:tlib_tags_extra = ''
" Filter the tag description through |substitute()| for these filetypes.
" This applies only if the tag cmd field (see |taglist()|) is used.
" :nodefault:
TLet g:tlib_tag_substitute = {
\ 'java': [['\s*{\s*$', '', '']],
\ 'ruby': [['\<\(def\|class\|module\)\>\s\+', '', '']],
\ 'vim': [
\ ['^\s*com\%[mand]!\?\(\s\+-\S\+\)*\s*\u\w*\zs.*$', '', ''],
\ ['^\s*\(let\|aug\%[roup]\|fu\%[nction]!\?\|com\%[mand]!\?\(\s\+-\S\+\)*\)\s*', '', ''],
\ ['"\?\s*{{{\d.*$', '', ''],
\ ],
\ }
" " Alternative rx for keywords, in case 'iskeyword' is inadequate for
" " the purposes of tlib but you don't want to change it's value.
" TLet g:tlib_keyword_rx = {
" \ 'vim': '\(\w\|#\)',
" \ }
TLet g:tlib_filename_sep = '/'
" TLet g:tlib_filename_sep = exists('+shellslash') && !&shellslash ? '\' : '/' " {{{2
" The cache directory. If empty, use |tlib#dir#MyRuntime|.'/cache'.
" You might want to delete old files from this directory from time to
" time with a command like: >
" find ~/vimfiles/cache/ -atime +31 -type f -print -delete
TLet g:tlib_cache = ''
" Where to display the line when using |tlib#buffer#ViewLine|.
" For possible values for position see |scroll-cursor|.
TLet g:tlib_viewline_position = 'zz'
" :doc:
" Keys for |tlib#input#List|~
TLet g:tlib_inputlist_and = ' '
TLet g:tlib_inputlist_or = '|'
TLet g:tlib_inputlist_not = '-'
" When editing a list with |tlib#input#List|, typing these numeric chars
" (as returned by getchar()) will select an item based on its index, not
" based on its name. I.e. in the default setting, typing a "4" will
" select the fourth item, not the item called "4".
" In order to make keys 0-9 filter the items in the list and make
" <m-[0-9]> select an item by its index, remove the keys 48 to 57 from
" this dictionary.
" Format: [KEY] = BASE ... the number is calculated as KEY - BASE.
" :nodefault:
TLet g:tlib_numeric_chars = {
\ 176: 176,
\ 177: 176,
\ 178: 176,
\ 179: 176,
\ 180: 176,
\ 181: 176,
\ 182: 176,
\ 183: 176,
\ 184: 176,
\ 185: 176,
\}
" \ 48: 48,
" \ 49: 48,
" \ 50: 48,
" \ 51: 48,
" \ 52: 48,
" \ 53: 48,
" \ 54: 48,
" \ 55: 48,
" \ 56: 48,
" \ 57: 48,
" :nodefault:
" The default key bindings for single-item-select list views. If you
" want to use <c-j>, <c-k> to move the cursor up and down, add these two
" lines to after/plugin/02tlib.vim: >
"
" let g:tlib_keyagents_InputList_s[10] = 'tlib#agent#Down' " <c-j>
" let g:tlib_keyagents_InputList_s[11] = 'tlib#agent#Up' " <c-k>
TLet g:tlib_keyagents_InputList_s = {
\ "\<PageUp>": 'tlib#agent#PageUp',
\ "\<PageDown>": 'tlib#agent#PageDown',
\ "\<Up>": 'tlib#agent#Up',
\ "\<Down>": 'tlib#agent#Down',
\ "\<c-Up>": 'tlib#agent#UpN',
\ "\<c-Down>": 'tlib#agent#DownN',
\ "\<Left>": 'tlib#agent#ShiftLeft',
\ "\<Right>": 'tlib#agent#ShiftRight',
\ 18: 'tlib#agent#Reset',
\ 242: 'tlib#agent#Reset',
\ 17: 'tlib#agent#Input',
\ 241: 'tlib#agent#Input',
\ 27: 'tlib#agent#Exit',
\ 26: 'tlib#agent#Suspend',
\ 250: 'tlib#agent#Suspend',
\ 15: 'tlib#agent#SuspendToParentWindow',
\ 63: 'tlib#agent#Help',
\ "\<F1>": 'tlib#agent#Help',
\ "\<bs>": 'tlib#agent#ReduceFilter',
\ "\<del>": 'tlib#agent#ReduceFilter',
\ "\<c-bs>": 'tlib#agent#PopFilter',
\ "\<m-bs>": 'tlib#agent#PopFilter',
\ "\<c-del>": 'tlib#agent#PopFilter',
\ "\<m-del>": 'tlib#agent#PopFilter',
\ "\<s-space>": 'tlib#agent#Wildcard',
\ 191: 'tlib#agent#Debug',
\ char2nr(g:tlib_inputlist_or): 'tlib#agent#OR',
\ char2nr(g:tlib_inputlist_and): 'tlib#agent#AND',
\ }
" Number of items to move when pressing <c-up/down> in the input list window.
TLet g:tlib_scroll_lines = 10
" :nodefault:
TLet g:tlib_keyagents_InputList_m = {
\ 35: 'tlib#agent#Select',
\ "\<s-up>": 'tlib#agent#SelectUp',
\ "\<s-down>": 'tlib#agent#SelectDown',
\ 1: 'tlib#agent#SelectAll',
\ 225: 'tlib#agent#SelectAll',
\ }
" "\<c-space>": 'tlib#agent#Select'
" :nodefault:
TLet g:tlib_handlers_EditList = [
\ {'key': 5, 'agent': 'tlib#agent#EditItem', 'key_name': '<c-e>', 'help': 'Edit item'},
\ {'key': 4, 'agent': 'tlib#agent#DeleteItems', 'key_name': '<c-d>', 'help': 'Delete item(s)'},
\ {'key': 14, 'agent': 'tlib#agent#NewItem', 'key_name': '<c-n>', 'help': 'New item'},
\ {'key': 24, 'agent': 'tlib#agent#Cut', 'key_name': '<c-x>', 'help': 'Cut item(s)'},
\ {'key': 3, 'agent': 'tlib#agent#Copy', 'key_name': '<c-c>', 'help': 'Copy item(s)'},
\ {'key': 22, 'agent': 'tlib#agent#Paste', 'key_name': '<c-v>', 'help': 'Paste item(s)'},
\ {'pick_last_item': 0},
\ {'return_agent': 'tlib#agent#EditReturnValue'},
\ {'help_extra': [
\ 'Submit changes by pressing ENTER or <c-s> or <c-w><cr>',
\ 'Cancel editing by pressing <c-w>c'
\ ]},
\ ]
" " TEST:
" TRequire tselectbuffer 6
" echo loaded_tselectbuffer
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,219 @@
" tLib.vim
" @Author: Thomas Link (mailto:micathom AT gmail com?subject=vim-tLib)
" @Website: http://www.vim.org/account/profile.php?user_id=4037
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2006-12-17.
" @Last Change: 2008-11-23.
" @Revision: 129
if !exists("loaded_tassert")
echoerr 'tAssert (vimscript #1730) is required'
endif
TAssertBegin! "tlib"
" List {{{2
fun! Add(a,b)
return a:a + a:b
endf
TAssert IsEqual(tlib#list#Inject([], 0, function('Add')), 0)
TAssert IsEqual(tlib#list#Inject([1,2,3], 0, function('Add')), 6)
delfunction Add
TAssert IsEqual(tlib#list#Compact([]), [])
TAssert IsEqual(tlib#list#Compact([0,1,2,3,[], {}, ""]), [1,2,3])
TAssert IsEqual(tlib#list#Flatten([]), [])
TAssert IsEqual(tlib#list#Flatten([1,2,3]), [1,2,3])
TAssert IsEqual(tlib#list#Flatten([1,2, [1,2,3], 3]), [1,2,1,2,3,3])
TAssert IsEqual(tlib#list#Flatten([0,[1,2,[3,""]]]), [0,1,2,3,""])
TAssert IsEqual(tlib#list#FindAll([1,2,3], 'v:val >= 2'), [2,3])
TAssert IsEqual(tlib#list#FindAll([1,2,3], 'v:val >= 2', 'v:val * 10'), [20,30])
TAssert IsEqual(tlib#list#Find([1,2,3], 'v:val >= 2'), 2)
TAssert IsEqual(tlib#list#Find([1,2,3], 'v:val >= 2', 0, 'v:val * 10'), 20)
TAssert IsEqual(tlib#list#Find([1,2,3], 'v:val >= 5', 10), 10)
TAssert IsEqual(tlib#list#Any([1,2,3], 'v:val >= 2'), 1)
TAssert IsEqual(tlib#list#Any([1,2,3], 'v:val >= 5'), 0)
TAssert IsEqual(tlib#list#All([1,2,3], 'v:val < 5'), 1)
TAssert IsEqual(tlib#list#All([1,2,3], 'v:val >= 2'), 0)
TAssert IsEqual(tlib#list#Remove([1,2,1,2], 2), [1,1,2])
TAssert IsEqual(tlib#list#RemoveAll([1,2,1,2], 2), [1,1])
TAssert IsEqual(tlib#list#Zip([[1,2,3], [4,5,6]]), [[1,4], [2,5], [3,6]])
TAssert IsEqual(tlib#list#Zip([[1,2,3], [4,5,6,7]]), [[1,4], [2,5], [3,6], ['', 7]])
TAssert IsEqual(tlib#list#Zip([[1,2,3], [4,5,6,7]], -1), [[1,4], [2,5], [3,6], [-1,7]])
TAssert IsEqual(tlib#list#Zip([[1,2,3,7], [4,5,6]], -1), [[1,4], [2,5], [3,6], [7,-1]])
" Vars {{{2
let g:foo = 1
let g:bar = 2
let b:bar = 3
let s:bar = 4
TAssert IsEqual(tlib#var#Get('bar', 'bg'), 3)
TAssert IsEqual(tlib#var#Get('bar', 'g'), 2)
TAssert IsEqual(tlib#var#Get('foo', 'bg'), 1)
TAssert IsEqual(tlib#var#Get('foo', 'g'), 1)
TAssert IsEqual(tlib#var#Get('none', 'l'), '')
TAssert IsEqual(eval(tlib#var#EGet('bar', 'bg')), 3)
TAssert IsEqual(eval(tlib#var#EGet('bar', 'g')), 2)
" TAssert IsEqual(eval(tlib#var#EGet('bar', 'sg')), 4)
TAssert IsEqual(eval(tlib#var#EGet('foo', 'bg')), 1)
TAssert IsEqual(eval(tlib#var#EGet('foo', 'g')), 1)
TAssert IsEqual(eval(tlib#var#EGet('none', 'l')), '')
unlet g:foo
unlet g:bar
unlet b:bar
" Filenames {{{2
TAssert IsEqual(tlib#file#Split('foo/bar/filename.txt'), ['foo', 'bar', 'filename.txt'])
TAssert IsEqual(tlib#file#Split('/foo/bar/filename.txt'), ['', 'foo', 'bar', 'filename.txt'])
TAssert IsEqual(tlib#file#Split('ftp://foo/bar/filename.txt'), ['ftp:/', 'foo', 'bar', 'filename.txt'])
TAssert IsEqual(tlib#file#Join(['foo', 'bar', 'filename.txt']), 'foo/bar/filename.txt')
TAssert IsEqual(tlib#file#Join(['', 'foo', 'bar', 'filename.txt']), '/foo/bar/filename.txt')
TAssert IsEqual(tlib#file#Join(['ftp:/', 'foo', 'bar', 'filename.txt']), 'ftp://foo/bar/filename.txt')
TAssert IsEqual(tlib#file#Relative('foo/bar/filename.txt', 'foo'), 'bar/filename.txt')
TAssert IsEqual(tlib#file#Relative('foo/bar/filename.txt', 'foo/base'), '../bar/filename.txt')
TAssert IsEqual(tlib#file#Relative('filename.txt', 'foo/base'), '../../filename.txt')
TAssert IsEqual(tlib#file#Relative('/foo/bar/filename.txt', '/boo/base'), '../../foo/bar/filename.txt')
TAssert IsEqual(tlib#file#Relative('/bar/filename.txt', '/boo/base'), '../../bar/filename.txt')
TAssert IsEqual(tlib#file#Relative('/foo/bar/filename.txt', '/base'), '../foo/bar/filename.txt')
TAssert IsEqual(tlib#file#Relative('c:/bar/filename.txt', 'x:/boo/base'), 'c:/bar/filename.txt')
" Prototype-based programming {{{2
let test = tlib#Test#New()
TAssert test.IsA('Test')
TAssert !test.IsA('foo')
TAssert test.RespondTo('RespondTo')
TAssert !test.RespondTo('RespondToNothing')
let test1 = tlib#Test#New()
TAssert test.IsRelated(test1)
let testworld = tlib#World#New()
TAssert !test.IsRelated(testworld)
let testc = tlib#TestChild#New()
TAssert IsEqual(testc.Dummy(), 'TestChild.vim')
TAssert IsEqual(testc.Super('Dummy', []), 'Test.vim')
" Optional arguments {{{2
function! TestGetArg(...) "{{{3
exec tlib#arg#Get(1, 'foo', 1)
return foo
endf
function! TestGetArg1(...) "{{{3
exec tlib#arg#Get(1, 'foo', 1, '!= ""')
return foo
endf
TAssert IsEqual(TestGetArg(), 1)
TAssert IsEqual(TestGetArg(''), '')
TAssert IsEqual(TestGetArg(2), 2)
TAssert IsEqual(TestGetArg1(), 1)
TAssert IsEqual(TestGetArg1(''), 1)
TAssert IsEqual(TestGetArg1(2), 2)
function! TestArgs(...) "{{{3
exec tlib#arg#Let([['foo', "o"], ['bar', 2]])
return repeat(foo, bar)
endf
TAssert IsEqual(TestArgs(), 'oo')
TAssert IsEqual(TestArgs('a'), 'aa')
TAssert IsEqual(TestArgs('a', 3), 'aaa')
function! TestArgs1(...) "{{{3
exec tlib#arg#Let(['foo', ['bar', 2]])
return repeat(foo, bar)
endf
TAssert IsEqual(TestArgs1(), '')
TAssert IsEqual(TestArgs1('a'), 'aa')
TAssert IsEqual(TestArgs1('a', 3), 'aaa')
function! TestArgs2(...) "{{{3
exec tlib#arg#Let(['foo', 'bar'], 1)
return repeat(foo, bar)
endf
TAssert IsEqual(TestArgs2(), '1')
TAssert IsEqual(TestArgs2('a'), 'a')
TAssert IsEqual(TestArgs2('a', 3), 'aaa')
function! TestArgs3(...)
TVarArg ['a', 1], 'b'
return a . b
endf
TAssert IsEqual(TestArgs3(), '1')
TAssert IsEqual(TestArgs3('a'), 'a')
TAssert IsEqual(TestArgs3('a', 3), 'a3')
delfunction TestGetArg
delfunction TestGetArg1
delfunction TestArgs
delfunction TestArgs1
delfunction TestArgs2
delfunction TestArgs3
" Strings {{{2
TAssert IsString(tlib#string#RemoveBackslashes('foo bar'))
TAssert IsEqual(tlib#string#RemoveBackslashes('foo bar'), 'foo bar')
TAssert IsEqual(tlib#string#RemoveBackslashes('foo\ bar'), 'foo bar')
TAssert IsEqual(tlib#string#RemoveBackslashes('foo\ \\bar'), 'foo \\bar')
TAssert IsEqual(tlib#string#RemoveBackslashes('foo\ \\bar', '\ '), 'foo \bar')
" Regexp {{{2
for c in split('^$.*+\()|{}[]~', '\zs')
let s = printf('%sfoo%sbar%s', c, c, c)
TAssert (s =~ '\m^'. tlib#rx#Escape(s, 'm') .'$')
TAssert (s =~ '\M^'. tlib#rx#Escape(s, 'M') .'$')
TAssert (s =~ '\v^'. tlib#rx#Escape(s, 'v') .'$')
TAssert (s =~ '\V\^'. tlib#rx#Escape(s, 'V') .'\$')
endfor
" Encode, decode
TAssert IsEqual(tlib#url#Decode('http://example.com/foo+bar%25bar'), 'http://example.com/foo bar%bar')
TAssert IsEqual(tlib#url#Decode('Hello%20World.%20%20Good%2c%20bye.'), 'Hello World. Good, bye.')
TAssert IsEqual(tlib#url#Encode('foo bar%bar'), 'foo+bar%%bar')
TAssert IsEqual(tlib#url#Encode('Hello World. Good, bye.'), 'Hello+World.+Good%2c+bye.')
TAssertEnd test test1 testc testworld
TAssert IsEqual(tlib#string#Count("fooo", "o"), 3)
TAssert IsEqual(tlib#string#Count("***", "\\*"), 3)
TAssert IsEqual(tlib#string#Count("***foo", "\\*"), 3)
TAssert IsEqual(tlib#string#Count("foo***", "\\*"), 3)
finish "{{{1
" Input {{{2
echo tlib#input#List('s', 'Test', ['barfoobar', 'barFoobar'])
echo tlib#input#List('s', 'Test', ['barfoobar', 'bar foo bar', 'barFoobar'])
echo tlib#input#List('s', 'Test', ['barfoobar', 'bar1Foo1bar', 'barFoobar'])
echo tlib#input#EditList('Test', ['bar1', 'bar2', 'bar3', 'foo1', 'foo2', 'foo3'])