Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Version 0.28

- tlib#input#List():
-- Improved handling of sticky lists; <cr> and <Leftmouse> resume a suspended list and immediately selects the item under the cursor
-- Experimental "seq" matching style: the conjunctions are sequentially ordered, they are combined with "OR" (disjunctions), the regexp is 'magic', and "." is expanded to '.\{-}'
-- Experimental "cnfd" matching style: Same as cnf but with an "elastic" dot "." that matches '\.\{-}'
-- Filtering acts as if &ic=1 && $sc=1
-- Weighting is done by the filter
- tlib#agent#Input(): Consume <esc> when aborting input()
- INCOMPATIBLE CHANGE: Changed eligible values of g:tlib_inputlist_match to "cnf", "cnfd", "seq" and "fuzzy"
- NEW: tlib#buffer#KeepCursorPosition()
- tlib#buffer#InsertText(): Take care of the extra line when appending text to an empty buffer.
  • Loading branch information...
commit 3c72e14bd233fa51541210f1741c2f0232d71254 1 parent 3731cc3
@tomtom tomtom authored committed
View
129 autoload/tlib/Filter_cnf.vim
@@ -0,0 +1,129 @@
+" Filter_cnf.vim
+" @Author: Thomas 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: 2008-11-30.
+" @Revision: 0.0.53
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+
+let s:prototype = tlib#Object#New({'_class': ['Filter_cnf'], 'name': 'cnf'}) "{{{2
+
+" 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.
+"
+" 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.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 .'\|'. 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
+ " 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(v:val), " OR ") .")"')
+ return join(reverse(filter1), ' AND ')
+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
+
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
View
54 autoload/tlib/Filter_cnfd.vim
@@ -0,0 +1,54 @@
+" Filter_cnfd.vim
+" @Author: Thomas 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: 2008-11-30.
+" @Revision: 0.0.31
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+
+let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_cnfd'], 'name': 'cnfd'}) "{{{2
+
+" 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.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
+
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
View
64 autoload/tlib/Filter_fuzzy.vim
@@ -0,0 +1,64 @@
+" Filter_fuzzy.vim
+" @Author: Thomas 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: 2008-11-30.
+" @Revision: 0.0.30
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+
+let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_fuzzy'], 'name': 'fuzzy'}) "{{{2
+
+" Support for "fuzzy" pattern matching in |tlib#input#List()|.
+" Characters are interpreted as if connected with '.\{-}'.
+function! tlib#Filter_fuzzy#New(...) "{{{3
+ let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
+ return object
+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
+
+
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
View
94 autoload/tlib/Filter_seq.vim
@@ -0,0 +1,94 @@
+" Filter_seq.vim
+" @Author: Thomas 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: 2008-11-30.
+" @Revision: 0.0.21
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+
+let s:prototype = tlib#Filter_cnf#New({'_class': ['Filter_seq'], 'name': 'seq'}) "{{{2
+
+" 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.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(v:val), "_") .")"')
+ return join(reverse(filter1), ' OR ')
+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
+
+
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
View
235 autoload/tlib/World.vim
@@ -3,8 +3,8 @@
" @Website: http://members.a1.net/t.link/
" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
" @Created: 2007-05-01.
-" @Last Change: 2008-10-16.
-" @Revision: 0.1.518
+" @Last Change: 2008-12-01.
+" @Revision: 0.1.669
" :filedoc:
" A prototype used by |tlib#input#List|.
@@ -24,9 +24,10 @@ let s:prototype = tlib#Object#New({
\ 'base': [],
\ 'bufnr': -1,
\ 'display_format': '',
+ \ 'filetype': '',
\ 'filter': [['']],
\ 'filter_format': '',
- \ 'filter_options': '\c',
+ \ 'filter_options': '',
\ 'follow_cursor': '',
\ 'index_table': [],
\ 'initial_filter': [['']],
@@ -35,7 +36,7 @@ let s:prototype = tlib#Object#New({
\ 'initialized': 0,
\ 'key_handlers': [],
\ 'list': [],
- \ 'match_mode': 'strings',
+ \ 'matcher': {},
\ 'next_state': '',
\ 'numeric_chars': tlib#var#Get('tlib_numeric_chars', 'bg'),
\ 'offset': 1,
@@ -62,13 +63,16 @@ let s:prototype = tlib#Object#New({
\ 'win_wnr': -1,
\ })
" \ 'handlers': [],
+ " \ 'filter_options': '\c',
function! tlib#World#New(...)
let object = s:prototype.New(a:0 >= 1 ? a:1 : {})
+ call object.SetMatchMode(tlib#var#Get('tlib_inputlist_match', 'g', 'cnf'))
return object
endf
+" :nodoc:
function! s:prototype.Set_display_format(value) dict "{{{3
if a:value == 'filename'
call self.Set_highlight_filename()
@@ -79,6 +83,7 @@ function! s:prototype.Set_display_format(value) dict "{{{3
endf
+" :nodoc:
function! s:prototype.Set_highlight_filename() dict "{{{3
let self.tlib_UseInputListScratch = 'call world.Highlight_filename()'
" \ 'syntax match TLibMarker /\%>'. (1 + eval(g:tlib_inputlist_width_filename)) .'c |.\{-}| / | hi def link TLibMarker Special'
@@ -86,6 +91,7 @@ function! s:prototype.Set_highlight_filename() dict "{{{3
endf
+" :nodoc:
function! s:prototype.Highlight_filename() dict "{{{3
" exec 'syntax match TLibDir /\%>'. (3 + eval(g:tlib_inputlist_width_filename)) .'c \(\S:\)\?[\/].*$/ contained containedin=TLibMarker'
exec 'syntax match TLibDir /\(\a:\|\.\.\..\{-}\)\?[\/][^&<>*|]*$/ contained containedin=TLibMarker'
@@ -95,6 +101,7 @@ function! s:prototype.Highlight_filename() dict "{{{3
endf
+" :nodoc:
function! s:prototype.FormatFilename(file) dict "{{{3
let fname = fnamemodify(a:file, ":p:t")
" let fname = fnamemodify(a:file, ":t")
@@ -137,6 +144,7 @@ function! s:prototype.FormatFilename(file) dict "{{{3
endf
+" :nodoc:
function! s:prototype.GetSelectedItems(current) dict "{{{3
if stridx(self.type, 'i') != -1
let rv = copy(self.sel_idx)
@@ -161,6 +169,7 @@ function! s:prototype.GetSelectedItems(current) dict "{{{3
endf
+" :nodoc:
function! s:prototype.SelectItem(mode, index) dict "{{{3
let bi = self.GetBaseIdx(a:index)
" if self.RespondTo('MaySelectItem')
@@ -181,17 +190,20 @@ function! s:prototype.SelectItem(mode, index) dict "{{{3
endf
+" :nodoc:
function! s:prototype.FormatArgs(format_string, arg) dict "{{{3
let nargs = len(substitute(a:format_string, '%%\|[^%]', '', 'g'))
return [a:format_string] + repeat([string(a:arg)], nargs)
endf
+" :nodoc:
function! s:prototype.GetRx(filter) dict "{{{3
return '\('. join(filter(copy(a:filter), 'v:val[0] != "!"'), '\|') .'\)'
endf
+" :nodoc:
function! s:prototype.GetRx0(...) dict "{{{3
exec tlib#arg#Let(['negative'])
let rx0 = []
@@ -207,22 +219,25 @@ function! s:prototype.GetRx0(...) dict "{{{3
if empty(rx0s)
return ''
else
- return '\V\('. rx0s .'\)'
+ return self.FilterRxPrefix() .'\('. rx0s .'\)'
endif
endf
+" :nodoc:
function! s:prototype.FormatName(format, value) dict "{{{3
let world = self
return eval(call(function("printf"), self.FormatArgs(a:format, a:value)))
endf
+" :nodoc:
function! s:prototype.GetItem(idx) dict "{{{3
return self.list[a:idx - 1]
endf
+" :nodoc:
function! s:prototype.GetListIdx(baseidx) dict "{{{3
" if empty(self.index_table)
let baseidx = a:baseidx
@@ -236,6 +251,7 @@ function! s:prototype.GetListIdx(baseidx) dict "{{{3
endf
+" :nodoc:
function! s:prototype.GetBaseIdx(idx) dict "{{{3
" TLogVAR a:idx, self.table, self.index_table
if !empty(self.table) && a:idx > 0 && a:idx <= len(self.table)
@@ -246,16 +262,45 @@ function! s:prototype.GetBaseIdx(idx) dict "{{{3
endf
+" :nodoc:
function! s:prototype.GetBaseItem(idx) dict "{{{3
return self.base[a:idx - 1]
endf
+" :nodoc:
function! s:prototype.SetBaseItem(idx, item) dict "{{{3
let self.base[a:idx - 1] = a:item
endf
+" :nodoc:
+function! s:prototype.SetPrefIdx() dict "{{{3
+ " let pref = sort(range(1, self.llen), 'self.SortPrefs')
+ " let self.prefidx = get(pref, 0, self.initial_index)
+ let pref_idx = -1
+ let pref_weight = -1
+ " TLogVAR self.filter_pos, self.filter_neg
+ for idx in range(1, self.llen)
+ let item = self.GetItem(idx)
+ let weight = self.matcher.AssessName(self, item)
+ " TLogVAR item, weight
+ if weight > pref_weight
+ let pref_idx = idx
+ let pref_weight = weight
+ endif
+ endfor
+ " TLogVAR pref_idx
+ " TLogDBG self.GetItem(pref_idx)
+ if pref_idx == -1
+ let self.prefidx = self.initial_index
+ else
+ let self.prefidx = pref_idx
+ endif
+endf
+
+
+" :nodoc:
function! s:prototype.GetCurrentItem() dict "{{{3
let idx = self.prefidx
" TLogVAR idx
@@ -274,6 +319,7 @@ function! s:prototype.GetCurrentItem() dict "{{{3
endf
+" :nodoc:
function! s:prototype.CurrentItem() dict "{{{3
if stridx(self.type, 'i') != -1
return self.GetBaseIdx(self.llen == 1 ? 1 : self.prefidx)
@@ -289,28 +335,43 @@ function! s:prototype.CurrentItem() dict "{{{3
endf
+" :nodoc:
+function! s:prototype.FilterRxPrefix() dict "{{{3
+ return self.matcher.FilterRxPrefix()
+endf
+
+
+" :nodoc:
function! s:prototype.SetFilter() dict "{{{3
" let mrx = '\V'. (a:0 >= 1 && a:1 ? '\C' : '')
- let mrx = '\V'. self.filter_options
+ let mrx = self.FilterRxPrefix() . self.filter_options
let self.filter_pos = []
let self.filter_neg = []
+ " TLogVAR self.filter
for filter in self.filter
" TLogVAR filter
let rx = join(reverse(filter(copy(filter), '!empty(v:val)')), '\|')
+ if rx =~ '\u'
+ let mrx1 = mrx .'\C'
+ else
+ let mrx1 = mrx
+ endif
" TLogVAR rx
if rx[0] == g:tlib_inputlist_not
if len(rx) > 1
- call add(self.filter_neg, mrx .'\('. rx[1:-1] .'\)')
+ call add(self.filter_neg, mrx1 .'\('. rx[1:-1] .'\)')
endif
else
- call add(self.filter_pos, mrx .'\('. rx .'\)')
+ call add(self.filter_pos, mrx1 .'\('. rx .'\)')
endif
endfor
+ " TLogVAR self.filter_pos, self.filter_neg
endf
+" :nodoc:
function! s:prototype.IsValidFilter() dict "{{{3
- let last = '\V\('. self.filter[0][0] .'\)'
+ let last = self.FilterRxPrefix() .'\('. self.filter[0][0] .'\)'
" TLogVAR last
try
let a = match("", last)
@@ -321,66 +382,46 @@ function! s:prototype.IsValidFilter() dict "{{{3
endf
-function! s:prototype.SetMatchMode() dict "{{{3
- let match_mode = tlib#var#Get('tlib_inputlist_match', 'bg')
- if !empty(match_mode)
- if index(['strings', 'chars'], match_mode) != -1
- let self.match_mode = match_mode
- else
- throw 'tlib: Unknown mode for tlib_inputlist_match: '. match_mode
- endif
+" :nodoc:
+function! s:prototype.SetMatchMode(match_mode) dict "{{{3
+ " TLogVAR a:match_mode
+ if !empty(a:match_mode)
+ unlet self.matcher
+ try
+ let self.matcher = tlib#Filter_{a:match_mode}#New()
+ catch /^Vim\%((\a\+)\)\=:E117/
+ throw 'tlib: Unknown mode for tlib_inputlist_match: '. a:match_mode
+ endtry
endif
endf
-function! s:prototype.Match(text, ...) dict "{{{3
- for rx in self.filter_neg
- " TLogVAR rx
- if a:text =~ rx
- return 0
- endif
- endfor
- for rx in self.filter_pos
- " TLogVAR rx
- if a:text !~ rx
- return 0
- endif
- endfor
- " for filter in self.filter
- " " TLogVAR filter
- " let rx = join(reverse(filter(copy(filter), '!empty(v:val)')), '\|')
- " " TLogVAR rx
- " if rx[0] == g:tlib_inputlist_not
- " if len(rx) > 1 && a:text =~ mrx .'\('. rx[1:-1] .'\)'
- " return 0
- " endif
- " elseif a:text !~ mrx .'\('. rx .'\)'
- " return 0
- " endif
- " " if a:text !~ mrx. self.GetRx(filter)
- " " return 0
- " " endif
- " endfor
- return 1
-endf
+" function! s:prototype.Match(text) dict "{{{3
+" return self.matcher.Match(self, text)
+" endf
+" :nodoc:
function! s:prototype.MatchBaseIdx(idx) dict "{{{3
let text = self.GetBaseItem(a:idx)
if !empty(self.filter_format)
let text = self.FormatName(self.filter_format, text)
endif
" TLogVAR text
- return self.Match(text)
+ " return self.Match(text)
+ return self.matcher.Match(self, text)
endf
+" :nodoc:
function! s:prototype.BuildTable() dict "{{{3
call self.SetFilter()
+ " TLogVAR self.filter_neg, self.filter_pos
let self.table = filter(range(1, len(self.base)), 'self.MatchBaseIdx(v:val)')
endf
+" :nodoc:
function! s:prototype.ReduceFilter() dict "{{{3
" TLogVAR self.filter
if self.filter[0] == [''] && len(self.filter) > 1
@@ -388,11 +429,12 @@ function! s:prototype.ReduceFilter() dict "{{{3
elseif empty(self.filter[0][0]) && len(self.filter[0]) > 1
call remove(self.filter[0], 0)
else
- let self.filter[0][0] = self.filter[0][0][0:-2]
+ call self.matcher.ReduceFrontFilter(self)
endif
endf
+" :nodoc:
function! s:prototype.SetInitialFilter(filter) dict "{{{3
" let self.initial_filter = [[''], [a:filter]]
if type(a:filter) == 3
@@ -403,6 +445,7 @@ function! s:prototype.SetInitialFilter(filter) dict "{{{3
endf
+" :nodoc:
function! s:prototype.PopFilter() dict "{{{3
" TLogVAR self.filter
if len(self.filter[0]) > 1
@@ -415,44 +458,66 @@ function! s:prototype.PopFilter() dict "{{{3
endf
+" :nodoc:
function! s:prototype.FilterIsEmpty() dict "{{{3
" TLogVAR self.filter
return self.filter == copy(self.initial_filter)
endf
+" :nodoc:
function! s:prototype.DisplayFilter() dict "{{{3
- " TLogVAR self.filter
- let filter1 = deepcopy(self.filter)
+ let filter1 = copy(self.filter)
call filter(filter1, 'v:val != [""]')
- " TLogVAR filter1
- if self.match_mode == 'strings'
- call map(filter1, '"(". join(reverse(v:val), " OR ") .")"')
- return join(reverse(filter1), ' AND ')
- elseif self.match_mode == 'chars'
- call map(filter1, 'v:val[0]')
- return '['. join(reverse(filter1), '') .']'
- end
+ " TLogVAR self.matcher['_class']
+ let rv = self.matcher.DisplayFilter(filter1)
+ let rv = self.CleanFilter(rv)
+ return rv
+endf
+
+
+" :nodoc:
+function! s:prototype.SetFrontFilter(pattern) dict "{{{3
+ call self.matcher.SetFrontFilter(self, a:pattern)
+endf
+
+
+" :nodoc:
+function! s:prototype.PushFrontFilter(char) dict "{{{3
+ call self.matcher.PushFrontFilter(self, a:char)
+endf
+
+
+" :nodoc:
+function! s:prototype.CleanFilter(filter) dict "{{{3
+ return self.matcher.CleanFilter(a:filter)
endf
+" :nodoc:
function! s:prototype.UseScratch() dict "{{{3
return tlib#scratch#UseScratch(self)
endf
+" :nodoc:
function! s:prototype.CloseScratch(...) dict "{{{3
TVarArg ['reset_scratch', 0]
" TVarArg ['reset_scratch', 1]
" TLogVAR reset_scratch
- let rv = tlib#scratch#CloseScratch(self, reset_scratch)
- if rv
- call self.SwitchWindow('win')
+ if self.sticky
+ return 0
+ else
+ let rv = tlib#scratch#CloseScratch(self, reset_scratch)
+ if rv
+ call self.SwitchWindow('win')
+ endif
+ return rv
endif
- return rv
endf
+" :nodoc:
function! s:prototype.UseInputListScratch() dict "{{{3
let scratch = self.UseScratch()
" TLogVAR scratch
@@ -473,6 +538,7 @@ endf
" :def: function! s:prototype.Reset(?initial=0)
+" :nodoc:
function! s:prototype.Reset(...) dict "{{{3
TVarArg ['initial', 0]
" TLogVAR initial
@@ -489,11 +555,13 @@ function! s:prototype.Reset(...) dict "{{{3
endf
+" :nodoc:
function! s:prototype.ResetSelected() dict "{{{3
let self.sel_idx = []
endf
+" :nodoc:
function! s:prototype.Retrieve(anyway) dict "{{{3
" TLogVAR a:anyway, self.base
" TLogDBG (a:anyway || empty(self.base))
@@ -513,9 +581,10 @@ function! s:prototype.Retrieve(anyway) dict "{{{3
endf
+" :nodoc:
function! s:prototype.DisplayHelp() dict "{{{3
+ " \ 'Help:',
let help = [
- \ 'Help:',
\ 'Mouse ... Pick an item Letter ... Filter the list',
\ printf('Number ... Pick an item "%s", "%s", %sWORD ... AND, OR, NOT',
\ g:tlib_inputlist_and, g:tlib_inputlist_or, g:tlib_inputlist_not),
@@ -547,13 +616,8 @@ function! s:prototype.DisplayHelp() dict "{{{3
endfor
let help += [
\ '',
- \ 'Warning:',
- \ 'Please don''t resize the window with the mouse.',
- \ '',
- \ 'Note on filtering:',
- \ 'The filter is prepended with "\V". Basically, filtering is case-insensitive.',
- \ 'Letters at word boundaries or upper-case lettes in camel-case names is given',
- \ 'more weight. If an OR-joined pattern start with "!", matches will be excluded.',
+ \ 'Exact matches and matches at word boundaries is given more weight.',
+ \ 'Warning: Please don''t resize the window with the mouse.',
\ '',
\ 'Press any key to continue.',
\ ]
@@ -567,6 +631,7 @@ function! s:prototype.DisplayHelp() dict "{{{3
endf
+" :nodoc:
function! s:prototype.Resize(hsize, vsize) dict "{{{3
" TLogVAR self.scratch_vertical, a:hsize, a:vsize
if self.scratch_vertical
@@ -582,6 +647,7 @@ endf
" :def: function! s:prototype.DisplayList(query, ?list)
+" :nodoc:
function! s:prototype.DisplayList(query, ...) dict "{{{3
" TLogVAR a:query
" TLogVAR self.state
@@ -653,19 +719,21 @@ function! s:prototype.DisplayList(query, ...) dict "{{{3
endif
endif
let query = a:query
- let options = []
+ let options = [self.matcher.name]
if self.sticky
- call add(options, 's')
+ call add(options, '#')
endif
if !empty(options)
- let query .= printf(' [%s]', join(options))
+ let query .= printf('%%=[%s] ', join(options, ', '))
endif
+ " TLogVAR query
let &statusline = query
endif
redraw
endf
+" :nodoc:
function! s:prototype.SetOffset() dict "{{{3
" TLogVAR self.prefidx, self.offset
" TLogDBG winheight(0)
@@ -690,6 +758,21 @@ function! s:prototype.SetOffset() dict "{{{3
endf
+" :nodoc:
+function! s:prototype.ClearAllMarks() dict "{{{3
+ let x = self.index_width + 1
+ call map(range(1, line('$')), 'self.DisplayListMark(x, v:val, ":")')
+endf
+
+
+" :nodoc:
+function! s:prototype.MarkCurrent(y) dict "{{{3
+ let x = self.index_width + 1
+ call self.DisplayListMark(x, a:y, '*')
+endf
+
+
+" :nodoc:
function! s:prototype.DisplayListMark(x, y, mark) dict "{{{3
" TLogVAR a:y, a:mark
if a:x > 0 && a:y >= 0
@@ -706,6 +789,7 @@ function! s:prototype.DisplayListMark(x, y, mark) dict "{{{3
endf
+" :nodoc:
function! s:prototype.SwitchWindow(where) dict "{{{3
let wnr = get(self, a:where.'_wnr')
" TLogVAR self, wnr
@@ -713,6 +797,7 @@ function! s:prototype.SwitchWindow(where) dict "{{{3
endf
+" :nodoc:
function! s:prototype.FollowCursor() dict "{{{3
if !empty(self.follow_cursor)
let back = self.SwitchWindow('win')
@@ -727,6 +812,7 @@ function! s:prototype.FollowCursor() dict "{{{3
endf
+" :nodoc:
function! s:prototype.SetOrigin(...) dict "{{{3
TVarArg ['winview', 0]
" TLogVAR self.win_wnr, self.bufnr
@@ -744,6 +830,7 @@ function! s:prototype.SetOrigin(...) dict "{{{3
endf
+" :nodoc:
function! s:prototype.RestoreOrigin(...) dict "{{{3
TVarArg ['winview', 0]
if winview
View
54 autoload/tlib/agent.vim
@@ -3,8 +3,8 @@
" @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: 2008-10-03.
-" @Revision: 0.1.142
+" @Last Change: 2008-11-30.
+" @Revision: 0.1.165
if &cp || exists("loaded_tlib_agent_autoload") "{{{2
finish
@@ -110,11 +110,15 @@ endf
function! tlib#agent#Input(world, selected) "{{{3
- let flt0 = a:world.filter[0][0]
+ let flt0 = a:world.CleanFilter(a:world.filter[0][0])
let flt1 = input('Filter: ', flt0)
echo
- if flt1 != flt0 && !empty(flt1)
- let a:world.filter[0][0] = flt1
+ 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
@@ -146,7 +150,9 @@ 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>. <cr>, <space>, or <LeftMouse> in the suspended window.
+" <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)
@@ -154,9 +160,13 @@ function! tlib#agent#Suspend(world, selected) "{{{3
let br = tlib#buffer#Set(a:world.scratch)
" TLogVAR br, a:world.bufnr, a:world.scratch
" TLogDBG bufnr('%')
- let b:tlib_suspend = ['<m-z>', '<c-z>', '<cr>', '<space>', '<LeftMouse>']
- for m in b:tlib_suspend
- exec 'noremap <buffer> '. m .' :call tlib#input#Resume("world")<cr>'
+ let b:tlib_suspend = {
+ \ '<m-z>': 0, '<c-z>': 0, '<space>': 0,
+ \ '<cr>': 1,
+ \ '<LeftMouse>': 1, '<c-LeftMouse>': 0, '<MiddleMouse>': 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
@@ -352,11 +362,13 @@ endf
" Files related {{{1
function! tlib#agent#ViewFile(world, selected) "{{{3
- let back = a:world.SwitchWindow('win')
- " TLogVAR back
- call tlib#file#With('edit', 'buffer', a:selected, a:world)
- exec back
- let a:world.state = 'display'
+ if !empty(a:selected)
+ let back = a:world.SwitchWindow('win')
+ " TLogVAR back
+ call tlib#file#With('edit', 'buffer', a:selected, a:world)
+ exec back
+ let a:world.state = 'display'
+ endif
return a:world
endf
@@ -432,12 +444,26 @@ endf
" 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)
+
endif
return a:world
endf
View
19 autoload/tlib/buffer.vim
@@ -3,8 +3,8 @@
" @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: 2008-10-06.
-" @Revision: 0.0.255
+" @Last Change: 2008-12-01.
+" @Revision: 0.0.260
if &cp || exists("loaded_tlib_buffer_autoload")
finish
@@ -238,6 +238,7 @@ function! tlib#buffer#InsertText(text, ...) "{{{3
TKeyArg keyargs, ['shift', 0], ['col', col('.')], ['lineno', line('.')], ['pos', 'e'],
\ ['indent', 0]
" TLogVAR shift, col, lineno, pos, indent
+ let post_del_last_line = line('$') == 1
let line = getline(lineno)
if col + shift > 0
let pre = line[0 : (col - 1 + shift)]
@@ -289,6 +290,9 @@ function! tlib#buffer#InsertText(text, ...) "{{{3
" 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\+')
if pos =~ '^e'
@@ -328,3 +332,14 @@ 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('.')
+ try
+ keepjumps exec a:cmd
+ finally
+ call setpos('.', pos)
+ endtry
+endf
+
View
4 autoload/tlib/file.vim
@@ -3,8 +3,8 @@
" @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: 2007-12-03.
-" @Revision: 0.0.56
+" @Last Change: 2008-12-01.
+" @Revision: 0.0.58
if &cp || exists("loaded_tlib_file_autoload")
finish
View
146 autoload/tlib/input.vim
@@ -3,8 +3,8 @@
" @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: 2008-10-16.
-" @Revision: 0.0.534
+" @Last Change: 2008-12-01.
+" @Revision: 0.0.620
if &cp || exists("loaded_tlib_input_autoload")
finish
@@ -39,6 +39,12 @@ let loaded_tlib_input_autoload = 1
" m ... Return a list of selcted elements
" mi ... Return a list of indexes
"
+" Several pattern matching styles are supported. See:
+" - |tlib#Filter_cnf#New()|
+" - |tlib#Filter_cnfd#New()|
+" - |tlib#Filter_fuzzy#New()|
+" - |tlib#Filter_seq#New()|
+"
" EXAMPLES: >
" echo tlib#input#List('s', 'Select one item', [100,200,300])
" echo tlib#input#List('si', 'Select one item', [100,200,300])
@@ -112,8 +118,10 @@ endf
function! tlib#input#ListW(world, ...) "{{{3
TVarArg 'cmd'
let world = a:world
+ let world.filetype = &filetype
+ call world.SetMatchMode(tlib#var#Get('tlib_inputlist_match', 'wb'))
call s:Init(world, cmd)
- " TLogVAR world.initial_index
+ " 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')
@@ -130,7 +138,6 @@ function! tlib#input#ListW(world, ...) "{{{3
let @/ = ''
let &laststatus = 2
let world.initial_display = 1
- call world.SetMatchMode()
try
while !empty(world.state) && world.state !~ '^exit' && (world.show_empty || !empty(world.base))
@@ -172,8 +179,16 @@ function! tlib#input#ListW(world, ...) "{{{3
let world.prefidx = world.offset
let world.state = 'redisplay'
endif
+ if world.state =~ '\<sticky\>'
+ let world.sticky = 1
+ endif
" TLogVAR world.filter
- if world.state =~ 'display'
+ " TLogVAR world.sticky
+ if world.state =~ '\<pick\>'
+ let world.rv = world.CurrentItem()
+ " TLogVAR world.rv
+ throw 'pick'
+ elseif world.state =~ 'display'
if world.IsValidFilter() && world.state =~ '^display'
call world.BuildTable()
@@ -200,7 +215,7 @@ function! tlib#input#ListW(world, ...) "{{{3
if world.llen == 1
let world.last_item = world.list[0]
if world.pick_last_item
- echom 'Pick last item: '. world.list[0]
+ " echom 'Pick last item: '. world.list[0]
let world.prefidx = '1'
" TLogDBG 'pick last item'
throw 'pick'
@@ -214,9 +229,7 @@ function! tlib#input#ListW(world, ...) "{{{3
" TLogDBG world.FilterIsEmpty()
if world.state == 'display'
if world.idx == '' && world.llen < g:tlib_sortprefs_threshold && !world.FilterIsEmpty()
- let s:world = world
- let pref = sort(range(1, world.llen), 's:SortPrefs')
- let world.prefidx = get(pref, 0, world.initial_index)
+ call world.SetPrefIdx()
else
let world.prefidx = world.idx == '' ? world.initial_index : world.idx
endif
@@ -246,6 +259,7 @@ function! tlib#input#ListW(world, ...) "{{{3
" TLogVAR dlist
endif
+
" TLogDBG 7
" TLogVAR world.prefidx, world.offset
" TLogDBG (world.prefidx > world.offset + winheight(0) - 1)
@@ -337,25 +351,17 @@ function! tlib#input#ListW(world, ...) "{{{3
let world.idx = ''
" TLogVAR world.filter
if world.llen > g:tlib_inputlist_livesearch_threshold
- let pattern = input('Filter: ', world.filter[0][0] . nr2char(c))
+ let pattern = input('Filter: ', world.CleanFilter(world.filter[0][0]) . nr2char(c))
if empty(pattern)
let world.state = 'exit empty'
else
- if world.match_mode == 'strings'
- let world.filter[0] = split(pattern, '\s*|\s*') + world.filter[0][1 : -1]
- elseif world.match_mode == 'chars'
- let world.filter = map(split(pattern, '\zs'), '[v:val]') + world.filter[1 : -1]
- endif
+ call world.SetFrontFilter(pattern)
echo
endif
elseif c == 124
call insert(world.filter[0], [])
else
- if world.match_mode == 'strings'
- let world.filter[0][0] .= nr2char(c)
- elseif world.match_mode == 'chars'
- call insert(world.filter, [nr2char(c)])
- endif
+ call world.PushFrontFilter(c)
endif
" continue
if c == 45 && world.filter[0][0] == '-'
@@ -368,8 +374,10 @@ function! tlib#input#ListW(world, ...) "{{{3
endif
catch /^pick$/
+ call world.ClearAllMarks()
+ call world.MarkCurrent(world.prefidx)
let world.state = ''
- " echom 'Pick item #'. world.prefidx
+ " TLogDBG 'Pick item #'. world.prefidx
finally
" TLogDBG 'finally 1'
@@ -402,6 +410,7 @@ function! tlib#input#ListW(world, ...) "{{{3
" TLogDBG 'state1='. world.state
endwh
+ " TLogVAR world.state
" TLogDBG 'exit while loop'
" TLogVAR world.list
" TLogVAR world.sel_idx
@@ -409,6 +418,9 @@ function! tlib#input#ListW(world, ...) "{{{3
" 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
@@ -444,12 +456,17 @@ function! tlib#input#ListW(world, ...) "{{{3
finally
let &statusline = statusline
let &laststatus = laststatus
- silent! let @/ = lastsearch
+ silent! let @/ = lastsearch
" TLogDBG 'finally 2'
" TLogDBG string(world.Methods())
+ " TLogVAR world.state
if world.state !~ '\<suspend\>'
+ " TLogVAR world.sticky
if world.sticky
+ " TLogVAR world.bufnr
+ " TLogDBG bufwinnr(world.bufnr)
if bufwinnr(world.bufnr) == -1
+ " TLogDBG "UseScratch"
call world.UseScratch()
endif
let world = tlib#agent#SuspendToParentWindow(world, world.GetSelectedItems(world.rv))
@@ -471,68 +488,26 @@ 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('.')
- call a:world.Retrieve(1)
+ 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
let a:world.initialized = 1
call a:world.SetOrigin(1)
call a:world.Reset(1)
endif
-endf
-
-
-function! s:AssessName(name) "{{{3
- let xa = 0
- for fltl in s:world.filter
- let flt = s:world.GetRx(fltl)
- if a:name =~# '\V'. flt
- let xa += 3
- endif
- if a:name =~ '\V\^'. flt .'\|'. flt .'\$'
- let xa += 3
- elseif a:name =~ '\V\<'. flt .'\|'. flt .'\>'
- let xa += 2
- elseif a:name =~ '\V\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
- return xa
-endf
-
-
-function! s:SortPrefs(a, b) "{{{3
- let a = s:world.GetItem(a:a)
- let b = s:world.GetItem(a:b)
- let xa = s:AssessName(a)
- let xb = s:AssessName(b)
- if a < b
- let xa += 1
- elseif b < a
- let xb += 1
- endif
- " let la = len(a)
- " let lb = len(b)
- " if la < lb
- " let xa += 1
- " elseif lb < la
- " let xb += 1
- " endif
- return xa == xb ? 0 : xa < xb ? 1 : -1
+ " TLogVAR a:world.state, a:world.sticky
endf
@@ -561,17 +536,24 @@ function! tlib#input#EditList(query, list, ...) "{{{3
endf
-function! tlib#input#Resume(name) "{{{3
+function! tlib#input#Resume(name, pick) "{{{3
echo
if exists('b:tlib_suspend')
- for m in b:tlib_suspend
+ for [m, pick] in items(b:tlib_suspend)
exec 'unmap <buffer> '. m
endfor
unlet b:tlib_suspend
endif
let b:tlib_{a:name}.state = 'display'
" call tlib#input#List('resume '. a:name)
- call tlib#input#ListW(b:tlib_{a:name}, '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
@@ -625,12 +607,20 @@ function! tlib#input#Edit(name, value, callback, ...) "{{{3
TVarArg ['args', []]
let sargs = {'scratch': '__EDIT__'. a:name .'__'}
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')
norm
call append(1, split(a:value, "\<c-j>", 1))
View
17 autoload/tlib/rx.vim
@@ -3,8 +3,8 @@
" @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: 2008-07-16.
-" @Revision: 0.0.16
+" @Last Change: 2008-12-01.
+" @Revision: 0.0.17
if &cp || exists("loaded_tlib_rx_autoload")
finish
@@ -34,3 +34,16 @@ function! tlib#rx#Escape(text, ...) "{{{3
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 a:text
+ else
+ echoerr 'magic must be one of: m, v, M, V'
+ endif
+endf
+
View
14 autoload/tlib/string.vim
@@ -3,8 +3,8 @@
" @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: 2008-10-03.
-" @Revision: 0.0.95
+" @Last Change: 2008-11-23.
+" @Revision: 0.0.108
if &cp || exists("loaded_tlib_string_autoload")
finish
@@ -144,3 +144,13 @@ function! tlib#string#Strip(string) "{{{3
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
281 doc/tlib.txt
@@ -56,6 +56,14 @@ Contents~
g:tlib_scroll_lines ..................... |g:tlib_scroll_lines|
g:tlib_keyagents_InputList_m ............ |g:tlib_keyagents_InputList_m|
g:tlib_handlers_EditList ................ |g:tlib_handlers_EditList|
+ autoload/tlib/Filter_cnf.vim
+ tlib#Filter_cnf#New ..................... |tlib#Filter_cnf#New()|
+ autoload/tlib/Filter_cnfd.vim
+ tlib#Filter_cnfd#New .................... |tlib#Filter_cnfd#New()|
+ autoload/tlib/Filter_fuzzy.vim
+ tlib#Filter_fuzzy#New ................... |tlib#Filter_fuzzy#New()|
+ autoload/tlib/Filter_seq.vim
+ tlib#Filter_seq#New ..................... |tlib#Filter_seq#New()|
autoload/tlib/Object.vim
tlib#Object#New ......................... |tlib#Object#New()|
prototype.New
@@ -68,49 +76,6 @@ Contents~
prototype.Methods
autoload/tlib/World.vim
tlib#World#New .......................... |tlib#World#New()|
- prototype.Set_display_format
- prototype.Set_highlight_filename
- prototype.Highlight_filename
- prototype.FormatFilename
- prototype.GetSelectedItems
- prototype.SelectItem
- prototype.FormatArgs
- prototype.GetRx
- prototype.GetRx0
- prototype.FormatName
- prototype.GetItem
- prototype.GetListIdx
- prototype.GetBaseIdx
- prototype.GetBaseItem
- prototype.SetBaseItem
- prototype.GetCurrentItem
- prototype.CurrentItem
- prototype.SetFilter
- prototype.IsValidFilter
- prototype.SetMatchMode
- prototype.Match
- prototype.MatchBaseIdx
- prototype.BuildTable
- prototype.ReduceFilter
- prototype.SetInitialFilter
- prototype.PopFilter
- prototype.FilterIsEmpty
- prototype.DisplayFilter
- prototype.UseScratch
- prototype.CloseScratch
- prototype.UseInputListScratch
- prototype.Reset
- prototype.ResetSelected
- prototype.Retrieve
- prototype.DisplayHelp
- prototype.Resize
- prototype.DisplayList
- prototype.SetOffset
- prototype.DisplayListMark
- prototype.SwitchWindow
- prototype.FollowCursor
- prototype.SetOrigin
- prototype.RestoreOrigin
autoload/tlib/agent.vim
tlib#agent#Exit ......................... |tlib#agent#Exit()|
tlib#agent#CopyItems .................... |tlib#agent#CopyItems()|
@@ -178,6 +143,7 @@ Contents~
tlib#buffer#InsertText .................. |tlib#buffer#InsertText()|
tlib#buffer#InsertText0 ................. |tlib#buffer#InsertText0()|
tlib#buffer#CurrentByte ................. |tlib#buffer#CurrentByte()|
+ tlib#buffer#KeepCursorPosition .......... |tlib#buffer#KeepCursorPosition()|
autoload/tlib/cache.vim
tlib#cache#Filename ..................... |tlib#cache#Filename()|
tlib#cache#Save ......................... |tlib#cache#Save()|
@@ -218,12 +184,6 @@ Contents~
tlib#input#Resume ....................... |tlib#input#Resume()|
tlib#input#CommandSelect ................ |tlib#input#CommandSelect()|
tlib#input#Edit ......................... |tlib#input#Edit()|
- <c-w>c .................................. |<c-w>c|
- i_<c-w>c ................................ |i_<c-w>c|
- <c-s> ................................... |<c-s>|
- i_<c-s> ................................. |i_<c-s>|
- <c-w><cr> ............................... |<c-w><cr>|
- i_<c-w><cr> ............................. |i_<c-w><cr>|
autoload/tlib/list.vim
tlib#list#Inject ........................ |tlib#list#Inject()|
tlib#list#Compact ....................... |tlib#list#Compact()|
@@ -247,6 +207,7 @@ Contents~
tlib#progressbar#Restore ................ |tlib#progressbar#Restore()|
autoload/tlib/rx.vim
tlib#rx#Escape .......................... |tlib#rx#Escape()|
+ tlib#rx#EscapeReplace ................... |tlib#rx#EscapeReplace()|
autoload/tlib/scratch.vim
tlib#scratch#UseScratch ................. |tlib#scratch#UseScratch()|
tlib#scratch#CloseScratch ............... |tlib#scratch#CloseScratch()|
@@ -258,6 +219,7 @@ Contents~
tlib#string#TrimLeft .................... |tlib#string#TrimLeft()|
tlib#string#TrimRight ................... |tlib#string#TrimRight()|
tlib#string#Strip ....................... |tlib#string#Strip()|
+ tlib#string#Count ....................... |tlib#string#Count()|
autoload/tlib/syntax.vim
tlib#syntax#Collect ..................... |tlib#syntax#Collect()|
tlib#syntax#Names ....................... |tlib#syntax#Names()|
@@ -399,10 +361,10 @@ g:tlib_inputlist_filename_indicators (default: 0)
disk when doing this.
*g:tlib_inputlist_match*
-g:tlib_inputlist_match (default: 'strings')
- Can be "strings" or "chars".
- strings :: substrings
- chars :: match characters
+g:tlib_inputlist_match (default: 'cnf')
+ Can be "cnf" or "fuzzy".
+ cnf :: substrings
+ fuzzy :: match characters
*g:tlib_tags_extra*
g:tlib_tags_extra (default: '')
@@ -463,6 +425,48 @@ g:tlib_handlers_EditList
========================================================================
+autoload/tlib/Filter_cnf.vim~
+
+ *tlib#Filter_cnf#New()*
+tlib#Filter_cnf#New(...)
+ 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.
+
+ This is also the base class for other filters.
+
+
+========================================================================
+autoload/tlib/Filter_cnfd.vim~
+
+ *tlib#Filter_cnfd#New()*
+tlib#Filter_cnfd#New(...)
+ 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.
+
+
+========================================================================
+autoload/tlib/Filter_fuzzy.vim~
+
+ *tlib#Filter_fuzzy#New()*
+tlib#Filter_fuzzy#New(...)
+ Support for "fuzzy" pattern matching in |tlib#input#List()|.
+ Characters are interpreted as if connected with '.\{-}'.
+
+
+========================================================================
+autoload/tlib/Filter_seq.vim~
+
+ *tlib#Filter_seq#New()*
+tlib#Filter_seq#New(...)
+ 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.
+
+
+========================================================================
autoload/tlib/Object.vim~
Provides a prototype plus some OO-like methods.
@@ -543,135 +547,6 @@ Inherits from |tlib#Object#New|.
tlib#World#New(...)
-prototype.Set_display_format
-
-
-prototype.Set_highlight_filename
-
-
-prototype.Highlight_filename
-
-
-prototype.FormatFilename
-
-
-prototype.GetSelectedItems
-
-
-prototype.SelectItem
-
-
-prototype.FormatArgs
-
-
-prototype.GetRx
-
-
-prototype.GetRx0
-
-
-prototype.FormatName
-
-
-prototype.GetItem
-
-
-prototype.GetListIdx
-
-
-prototype.GetBaseIdx
-
-
-prototype.GetBaseItem
-
-
-prototype.SetBaseItem
-
-
-prototype.GetCurrentItem
-
-
-prototype.CurrentItem
-
-
-prototype.SetFilter
-
-
-prototype.IsValidFilter
-
-
-prototype.SetMatchMode
-
-
-prototype.Match
-
-
-prototype.MatchBaseIdx
-
-
-prototype.BuildTable
-
-
-prototype.ReduceFilter
-
-
-prototype.SetInitialFilter
-
-
-prototype.PopFilter
-
-
-prototype.FilterIsEmpty
-
-
-prototype.DisplayFilter
-
-
-prototype.UseScratch
-
-
-prototype.CloseScratch
-
-
-prototype.UseInputListScratch
-
-
-prototype.Reset
-
-
-prototype.ResetSelected
-
-
-prototype.Retrieve
-
-
-prototype.DisplayHelp
-
-
-prototype.Resize
-
-
-prototype.DisplayList
-
-
-prototype.SetOffset
-
-
-prototype.DisplayListMark
-
-
-prototype.SwitchWindow
-
-
-prototype.FollowCursor
-
-
-prototype.SetOrigin
-
-
-prototype.RestoreOrigin
-
-
========================================================================
autoload/tlib/agent.vim~
Various agents for use as key handlers in tlib#input#List()
@@ -721,7 +596,9 @@ tlib#agent#SuspendToParentWindow(world, selected)
tlib#agent#Suspend(world, selected)
Suspend lets you temporarily leave the input loop of
|tlib#input#List|. You can resume editing the list by pressing <c-z>,
- <m-z>. <cr>, <space>, or <LeftMouse> in the suspended window.
+ <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.
*tlib#agent#Help()*
tlib#agent#Help(world, selected)
@@ -918,6 +795,10 @@ tlib#buffer#InsertText0(text, ...)
*tlib#buffer#CurrentByte()*
tlib#buffer#CurrentByte()
+ *tlib#buffer#KeepCursorPosition()*
+tlib#buffer#KeepCursorPosition(cmd)
+ Evaluate cmd while maintaining the cursor position and jump registers.
+
========================================================================
autoload/tlib/cache.vim~
@@ -1085,6 +966,12 @@ tlib#input#List(type. ?query='', ?list=[], ?handlers=[], ?default="", ?timeout=0
m ... Return a list of selcted elements
mi ... Return a list of indexes
+ Several pattern matching styles are supported. See:
+ - |tlib#Filter_cnf#New()|
+ - |tlib#Filter_cnfd#New()|
+ - |tlib#Filter_fuzzy#New()|
+ - |tlib#Filter_seq#New()|
+
EXAMPLES: >
echo tlib#input#List('s', 'Select one item', [100,200,300])
echo tlib#input#List('si', 'Select one item', [100,200,300])
@@ -1112,7 +999,7 @@ tlib#input#EditList(query, list, ?timeout=0)
<
*tlib#input#Resume()*
-tlib#input#Resume(name)
+tlib#input#Resume(name, pick)
*tlib#input#CommandSelect()*
tlib#input#CommandSelect(command, ?keyargs={})
@@ -1141,25 +1028,6 @@ tlib#input#Edit(name, value, callback, ?cb_args=[])
call tlib#input#Edit('foo', b:var, 'FooContinue')
<
- *<c-w>c*
-<c-w>c ... :call <SID>EditCallback(0)<cr>
- TLogVAR a:value
-
- *i_<c-w>c*
-i_<c-w>c ... <c-o>call <SID>EditCallback(0)<cr>
-
- *<c-s>*
-<c-s> ... :call <SID>EditCallback(1)<cr>
-
- *i_<c-s>*
-i_<c-s> ... <c-o>call <SID>EditCallback(1)<cr>
-
- *<c-w><cr>*
-<c-w><cr> ... :call <SID>EditCallback(1)<cr>
-
- *i_<c-w><cr>*
-i_<c-w><cr> ... <c-o>call <SID>EditCallback(1)<cr>
-
========================================================================
autoload/tlib/list.vim~
@@ -1299,6 +1167,10 @@ tlib#rx#Escape(text, ?magic='m')
magic can be one of: m, M, v, V
See :help 'magic'
+ *tlib#rx#EscapeReplace()*
+tlib#rx#EscapeReplace(text, ?magic='m')
+ Escape return |sub-replace-special|.
+
========================================================================
autoload/tlib/scratch.vim~
@@ -1344,6 +1216,9 @@ tlib#string#TrimRight(string)
*tlib#string#Strip()*
tlib#string#Strip(string)
+ *tlib#string#Count()*
+tlib#string#Count(string, rx)
+
========================================================================
autoload/tlib/syntax.vim~
View
42 plugin/02tlib.vim
@@ -3,13 +3,15 @@
" @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: 2008-10-16.
-" @Revision: 478
+" @Last Change: 2008-12-01.
+" @Revision: 521
" GetLatestVimScripts: 1863 1 tlib.vim
"
" Please see also ../test/tlib.vim for usage examples.
"
" TODO:
+" - tlib#input#List(): RightMouse -> Make commands accessible via
+" popup-menu
" - List isn't updated on some occassions (eg tselectfiles + pick file
" per mouse) when resetting the state from an post-process agent
" - tlib#agent#SwitchLayout(): switch between horizontal and vertical
@@ -19,7 +21,6 @@
" - tlib#input#EditList(): Disable selection by index number
" - tlib#input#List(): Some kind of command line to edit some
" preferences (sort etc.) on the fly
-" - tlib#input#List(): Make commands accessible via popup-menu
if &cp || exists("loaded_tlib")
finish
@@ -28,7 +29,7 @@ if v:version < 700 "{{{2
echoerr "tlib requires Vim >= 7"
finish
endif
-let loaded_tlib = 26
+let loaded_tlib = 28
let s:save_cpo = &cpo
set cpo&vim
@@ -126,10 +127,10 @@ TLet g:tlib_inputlist_livesearch_threshold = 500
" disk when doing this.
TLet g:tlib_inputlist_filename_indicators = 0
-" Can be "strings" or "chars".
-" strings :: substrings
-" chars :: match characters
-TLet g:tlib_inputlist_match = 'strings'
+" Can be "cnf" or "fuzzy".
+" cnf :: substrings
+" fuzzy :: match characters
+TLet g:tlib_inputlist_match = 'cnf'
" Extra tags for |tlib#tag#Retrieve()| (see there). Can also be buffer-local.
TLet g:tlib_tags_extra = ''
@@ -147,6 +148,12 @@ TLet g:tlib_tag_substitute = {
\ ],
\ }
+" " 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
@@ -470,4 +477,23 @@ messages (contributed by Erik Falor)
- FIX: Cosmetic bug, wrong packaging (thanks Nathan Neff)
- Meaning of World#filter_format changed; new World#filter_options
- Filtering didn't work as advertised
+- tlib#string#Count()
+
+0.28
+- tlib#input#List():
+-- Improved handling of sticky lists; <cr> and <Leftmouse> resume a
+suspended list and immediately selects the item under the cursor
+-- Experimental "seq" matching style: the conjunctions are sequentially
+ordered, they are combined with "OR" (disjunctions), the regexp is
+'magic', and "." is expanded to '.\{-}'
+-- Experimental "cnfd" matching style: Same as cnf but with an "elastic"
+dot "." that matches '\.\{-}'
+-- Filtering acts as if &ic=1 && $sc=1
+-- Weighting is done by the filter
+- tlib#agent#Input(): Consume <esc> when aborting input()
+- INCOMPATIBLE CHANGE: Changed eligible values of g:tlib_inputlist_match
+to "cnf", "cnfd", "seq" and "fuzzy"
+- NEW: tlib#buffer#KeepCursorPosition()
+- tlib#buffer#InsertText(): Take care of the extra line when appending
+text to an empty buffer.
View
10 test/tlib.vim
@@ -3,8 +3,8 @@
" @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-06-15.
-" @Revision: 125
+" @Last Change: 2008-11-23.
+" @Revision: 129
if !exists("loaded_tassert")
echoerr 'tAssert (vimscript #1730) is required'
@@ -201,6 +201,12 @@ TAssert IsEqual(tlib#url#Encode('Hello World. Good, bye.'), 'Hello+World.+Good%2
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
Please sign in to comment.
Something went wrong with that request. Please try again.