aboutsummaryrefslogtreecommitdiff
path: root/vim/bundle/vim-addon-mw-utils/autoload
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2016-06-30 16:11:56 +0200
committerKarel Kočí <cynerd@email.cz>2016-06-30 16:11:56 +0200
commit9931e0888b2419326ae10ebbfae532261c5c125f (patch)
tree7504be5daccbb7b7d1ea396754de47b11ed790e5 /vim/bundle/vim-addon-mw-utils/autoload
parente573b3020c032400eed60b649a2cbf55266e6bb0 (diff)
downloadmyconfigs-9931e0888b2419326ae10ebbfae532261c5c125f.tar.gz
myconfigs-9931e0888b2419326ae10ebbfae532261c5c125f.tar.bz2
myconfigs-9931e0888b2419326ae10ebbfae532261c5c125f.zip
Fix submodules
Diffstat (limited to 'vim/bundle/vim-addon-mw-utils/autoload')
m---------vim/bundle/vim-addon-mw-utils0
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/buf_utils.vim24
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/cached_file_contents.vim104
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/env_reload.vim12
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/funcref.vim95
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/glob.vim27
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/tiny_cmd.vim19
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/tovl/scratch_buffer.vim103
-rw-r--r--vim/bundle/vim-addon-mw-utils/autoload/tovl/ui/filter_list.vim473
9 files changed, 0 insertions, 857 deletions
diff --git a/vim/bundle/vim-addon-mw-utils b/vim/bundle/vim-addon-mw-utils
new file mode 160000
+Subproject 0c5612fa31ee434ba055e21c76f456244b3b510
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/buf_utils.vim b/vim/bundle/vim-addon-mw-utils/autoload/buf_utils.vim
deleted file mode 100644
index d14d404..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/buf_utils.vim
+++ /dev/null
@@ -1,24 +0,0 @@
-" buf_identifier is either a buf_nr or a filename
-" If any window shows the buffer move to the buffer
-" If not show it in current window (by c-w s c^ you can always
-" reshow the last buffer
-"
-" Example: buf_utils#GotoBuf("/tmp/tfile.txt", {'create': 1})
-" returns: The command which was used to switch to the buffer
-fun! buf_utils#GotoBuf(buf_identifier, opts)
- let buf_nr = bufnr(a:buf_identifier)
- if buf_nr == -1 && ( get(a:opts, 'create', 0) || has_key(a:opts, 'create_cmd'))
- exec get(a:opts,'create_cmd','e').' '.fnameescape(a:buf_identifier)
- return "e"
- else
- let win_nr = bufwinnr(buf_nr)
- if win_nr == -1
- exec 'b '.buf_nr
- return "b"
- else
- exec win_nr.'wincmd w'
- return "w"
- endif
- wincmd w"
- endif
-endf
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/cached_file_contents.vim b/vim/bundle/vim-addon-mw-utils/autoload/cached_file_contents.vim
deleted file mode 100644
index 3fc3ce4..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/cached_file_contents.vim
+++ /dev/null
@@ -1,104 +0,0 @@
-" cached_file_contents.vim
-" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
-" @Last Change: 2010-01-03.
-" @Revision: 0.3.0
-
-"exec vam#DefineAndBind('s:c','g:cache_dir_options','{}')
-if !exists('g:cache_dir_options') | let g:cache_dir_options = {} | endif | let s:c = g:cache_dir_options
-
-let s:c['cache_dir'] = get(s:c, 'cache_dir', expand('$HOME').'/.vim-cache')
-let s:c['scanned_files'] = get(s:c, 'scanned_files', {})
-let s:scanned_files = s:c['scanned_files']
-
-
-let s:define_cache_file = "let this_dir = s:c['cache_dir'].'/cached-file-contents' | let cache_file = expand(this_dir.'/'.substitute(string([func_as_string, a:file]),'[[\\]{}:/\\,''\"# ]\\+','_','g'))"
-
-" read a file, run function to extract contents and cache the result returned
-" by that function in memory. Optionally the result can be cached on disk as
-" because VimL can be slow!
-"
-" file : the file to be read
-" func: { 'func': function which will be called by funcref#Call
-" , 'version' : if this version changes cache will be invalidate automatically
-" , 'ftime_check': optional, default 1. if set to 0 cache isn't updated when file changes and file is in cache
-" }
-"
-" default: what to return if file doesn't exist
-" think twice about adding lines. This function is called many times.
-function! cached_file_contents#CachedFileContents(file, func, ...) abort
- let ignore_ftime = a:0 > 0 ? a:1 : 0
- " using string for default so that is evaluated when needed only
- let use_file_cache = get(a:func, 'use_file_cache', 0)
-
- " simple kind of normalization. necessary when using file caching
- " this seems to be slower:
- " let file = fnamemodify(a:file, ':p') " simple kind of normalization. necessary when using file caching
- " / = assume its an absolute path
- " let file = a:file[0] == '/' ? a:file : expand(a:file, ':p')
- let file = a:file[0] == '/' ? a:file : fnamemodify(a:file, ':p') " simple kind of normalization. necessary when using file caching
- let func_as_string = string(a:func['func'])
-
- if (!has_key(s:scanned_files, func_as_string))
- let s:scanned_files[func_as_string] = {}
- endif
- let dict = s:scanned_files[func_as_string]
- if use_file_cache && !has_key(dict, a:file)
- exec s:define_cache_file
- if filereadable(cache_file)
- let dict[file] = eval(readfile(cache_file,'b')[0])
- endif
- endif
- if has_key(dict, a:file)
- let d = dict[a:file]
- if use_file_cache
- \ && (ignore_ftime || getftime(a:file) <= d['ftime'])
- \ && d['version'] == a:func['version']
- return dict[a:file]['scan_result']
- endif
- endif
- let scan_result = funcref#Call(a:func['func'], [a:file] )
- let dict[a:file] = {"ftime": getftime(a:file), 'version': a:func['version'], "scan_result": scan_result }
- if use_file_cache
- if !exists('cache_file') | exec s:define_cache_file | endif
- if !isdirectory(this_dir) | call mkdir(this_dir,'p',0700) | endif
- call writefile([string(dict[a:file])], cache_file)
- endif
- return scan_result
-endfunction
-
-fun! cached_file_contents#ClearScanCache()
- let s:c['scanned_files'] = {}
-
- " Don't run rm -fr. Ask user to run it. It cache_dir may have been set to
- " $HOME ! (should nevere be the case but who knows
- echoe "run manually in your shell: rm -fr ".shellescape(s:c['cache_dir'])."/*"
-endf
-
-fun! cached_file_contents#Test()
-
- " usually you use a global option so that the function can be reused
- let my_interpreting_func = {'func' : funcref#Function('return len(readfile(ARGS[0]))'), 'version': 2, 'use_file_cache':1}
- let my_interpreting_func2 = {'func' : funcref#Function('return ARGS[0]') , 'version': 2, 'use_file_cache':1}
-
- let tmp = tempname()
- call writefile(['some text','2nd line'], tmp)
-
- let r = [ cached_file_contents#CachedFileContents(tmp, my_interpreting_func)
- \ , cached_file_contents#CachedFileContents(tmp, my_interpreting_func2) ]
- if r != [2, tmp]
- throw "test failed 1, got ".string(r)
- endif
- unlet r
-
- sleep 3
-
- " now let's change contents
- call writefile(['some text','2nd line','3rd line'], tmp)
-
- let r = cached_file_contents#CachedFileContents(tmp, my_interpreting_func)
- if 3 != r
- throw "test failed 2, got ".string(r)
- endif
-
- echo "test passed"
-endf
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/env_reload.vim b/vim/bundle/vim-addon-mw-utils/autoload/env_reload.vim
deleted file mode 100644
index d8af33a..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/env_reload.vim
+++ /dev/null
@@ -1,12 +0,0 @@
-" in sh/bash you can type export to get a list of environment variables
-" This function assigns those env vars to Vim.
-" Does not delete env vars yet
-" Example: env_reload#ReloadEnv(system("sh -c 'export'")
-fun! env_reload#ReloadEnv(bash_export_command_output)
- for i in split(a:bash_export_command_output,"\n")
- let m = matchlist(i, 'export \([^=]\+\)="\(.*\)"')
- if empty(m) | continue | endif
- " don't care about quoted values right now.
- exec 'let $'.m[1].'='.string(m[2])
- endfor
-endf
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/funcref.vim b/vim/bundle/vim-addon-mw-utils/autoload/funcref.vim
deleted file mode 100644
index 20eec54..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/funcref.vim
+++ /dev/null
@@ -1,95 +0,0 @@
-" funcref.vim
-" @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
-" @Last Change: 2010-01-03.
-" @Revision: 0.1.0
-
-" documentation see doc/funcref.txt
-
-" usage:
-" funcref#Function("filename#Function")
-" optionally pass arguments:
-" funcref#Function("filename#Function",{'args': [2]})
-" optionally define self:
-" funcref#Function("filename#Function",{'self': object})
-function! funcref#Function(name,...)
- let d = a:0 > 0 ? a:1 : {}
- let d['faked_function_reference'] = a:name
- return d
-endfunction
-
-" args : same as used for call(f,[args], self)
-" f must be either
-" - a string which can be evaled (use "return 'value'" to return a value)
-" - a Vim function reference created by function('..')
-" - a faked function reference created by funcref#Function(..)
-"
-" the last "self" argument can be overriden by the function reference
-" You can pass arguments in a closure like style
-function! funcref#Call(...)
- let args = copy(a:000)
-
- " add parameters:
- if (len(args) < 2)
- call add(args, [])
- endif
-
-
- let isDict = type(args[0]) == type({})
-
- " prepend parameters which were passed by faked function reference:
- if isDict && has_key(args[0], 'args')
- let args[1] = args[0]['args']+args[1]
- endif
-
- " always pass self. this way you can call functions from dictionaries not
- " refering to self
- if (len(args) < 3)
- call add(args, {})
- endif
-
- " the funcref overrides self:
- if isDict && has_key(args[0], 'self')
- let args[2] = args[0]['self']
- endif
-
- if type(a:1) == 2
- " funcref: function must have been laoded
- return call(function('call'), args)
- elseif isDict && has_key(args[0], 'faked_function_reference')
- let Fun = args[0]['faked_function_reference']
- if type(Fun) == type('')
- \ && (Fun[:len('return ')-1] == 'return '
- \ || Fun[:len('call ')-1] == 'call '
- \ || Fun[:len('if ')-1] == 'if '
- \ || Fun[:len('let ')-1] == 'let '
- \ || Fun[:len('echo ')-1] == 'echo '
- \ || Fun[:len('exec ')-1] == 'exec '
- \ || Fun[:len('debug ')-1] == 'debug ')
- " it doesn't make sense to list all vim commands here
- " So if you want to execute another action consider using
- " funcref#Function('exec '.string('aw')) or such
-
- " function is a String, call exec
- let ARGS = args[1]
- let SELF = args[2]
- exec Fun
- else
- " pseudo function, let's load it..
- if type(Fun) == 1
- if !exists('*'.Fun)
- " lazily load function
- let file = substitute(substitute(Fun,'#[^#]*$','',''),'#','/','g')
- exec 'runtime /autoload/'.file.'.vim'
- endif
- let Fun2 = function(Fun)
- else
- let Fun2 = Fun
- endif
- let args[0] = Fun
- return call(function('call'), args)
- endif
- else
- " no function, return the value
- return args[0]
- endif
-endfunction
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/glob.vim b/vim/bundle/vim-addon-mw-utils/autoload/glob.vim
deleted file mode 100644
index 9a0f79a..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/glob.vim
+++ /dev/null
@@ -1,27 +0,0 @@
-exec vam#DefineAndBind('s:c','g:glob_like', '{}')
-
-" ignore vcs stuff, Don't think you want those..
-let s:c['regex_ignore_directory'] = '\<\%([_.]darcs\|\.git\|.svn\|.hg\|.cvs\|.bzr\)\>'
-let s:c['glob_cache'] = get(s:c, 'glob_cache', {})
-let s:glob_cache = s:c['glob_cache']
-
-fun! glob#Glob(pattern, ...)
- let pattern = a:pattern
- if pattern[0] == '~'
- let pattern = $HOME.pattern[1:]
- endif
- let opts = a:0 > 0 ? a:1 : {}
- " never cache current directory. You're very likely to edit files in it.
-
- let c = getcwd()
- let cachable = get(opts, 'cachable', 0) && pattern[:len(c)-1] != c
- if cachable && has_key(s:glob_cache, pattern)
- return s:glob_cache[pattern]
- endif
-
- " FIXME: don't recurse into \.git directory (thus reimplement glob in vimL!)
- let r = filter(split(glob(pattern),"\n"),'v:val !~ '.string(s:c['regex_ignore_directory']))
- if cachable | let s:glob_cache[pattern] = r | endif
- return r
-endf
-
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/tiny_cmd.vim b/vim/bundle/vim-addon-mw-utils/autoload/tiny_cmd.vim
deleted file mode 100644
index 052bbe0..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/tiny_cmd.vim
+++ /dev/null
@@ -1,19 +0,0 @@
-" vim suffers:
-
-exec vam#DefineAndBind('s:c','g:vim_tiny_cmd', '{}')
-
-fun! tiny_cmd#Put(a)
- let new = get(s:c,'next',0) +1
- let s:c['next'] = new
- let s:c[new] = a:a
- return new
-endf
-
-fun! tiny_cmd#Get(nr)
- return s:c[a:nr]
-endf
-
-" Get and remove item
-fun! tiny_cmd#Pop(nr)
- let r = s:c[a:nr] | unlet s:c[a:nr] | return r
-endf
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/tovl/scratch_buffer.vim b/vim/bundle/vim-addon-mw-utils/autoload/tovl/scratch_buffer.vim
deleted file mode 100644
index 217dca1..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/tovl/scratch_buffer.vim
+++ /dev/null
@@ -1,103 +0,0 @@
-" old code
-
-augroup TOVLWrite
-augroup end
-
-" =========== scratch buffer =========================================
-" a scratch buffer is a temporary buffer where the user can enter some text
-" It can be used to get commit messages, edit configuration options and so on
-
-function! tovl#scratch_buffer#KeepIntactLineNr()
- let i = 0
- while getline(i)!= b:keepIntact && i < line('$')
- let i = i+1
- endwhile
- if i > line('$')
- return -1
- else
- return i
- endif
-endfunction
-
-" opens a buffer and runs an action when the buffer is written
-" keys:
-" name : the name of the buffer
-" onWrite : will be called on write
-" onWrite is responsible for setlocal nomodified to indicate that
-" saving has been successful
-" help : callback returning additional information lines
-" getContent : callback returning lines
-" cmds : extra commands to be run (optional)
-" (maybe you prefer adding them the default way afer the
-" ScratchBuffer call. They'll be rerun on GetContents
-" sp_cmd : the command to use to create the new buffer. Defaults to :e
-" buftype : ...
-" modifiable : 1 / 0 defaults to 1
-function! tovl#scratch_buffer#ScratchBuffer(opts)
- let a:opts['name'] = get(a:opts,'name', 'strach_buffer_without_name')
- exec get(a:opts, 'sp_cmd', 'e').' '.escape(a:opts['name'],' ')
- let b:settings = a:opts
- let b:settings['modifiable'] = get(a:opts,'modifiable', 1)
- setlocal buftype=acwrite
- command! -buffer -nargs=0 Help call tovl#scratch_buffer#Help()
-
- " setup write notification
- au TOVLWrite BufWriteCmd <buffer> call tovl#scratch_buffer#Write()
-
- if has_key(a:opts,'getContent')
- command! -buffer -nargs=0 GetContents call tovl#scratch_buffer#GetContents()
- GetContents
- if !b:settings['modifiable']
- setlocal nomodifiable
- endif
- endif
- "let u=&undolevels
- "setlocal undolevels=-1
- "exec 'setlocal undolevels='.u
-
- " mark buffer as not modified
- setlocal nomodified
-
- au BufReadCmd <buffer> GetContents
-
- " run addittional commands
- for cmd in get(a:opts,'cmds',[])
- exec cmd
- endfor
- silent echo get(a:opts,'echo_help', "type :Help for help")
-endfunction
-
-" =========== utility functions ======================================
-
-function! tovl#scratch_buffer#Write()
- if has_key(b:settings, 'onWrite')
- call funcref#Call(b:settings['onWrite'])
- else
- echo "don't know how to write. Option hasn't been passed"
- endif
-endfunction
-
-function! tovl#scratch_buffer#GetContents()
- setlocal modifiable
- " empty buffer
- %g!//d
- call append(0, funcref#Call(b:settings['getContent']))
- if !b:settings['modifiable']
- setlocal nomodifiable
- endif
- for cmd in get(b:settings,'cmds',[])
- exec cmd
- endfor
-endfunction
-
-function! tovl#scratch_buffer#Help()
- let help = ["use :e! to reload contents, ZZ or :w(q) to write and quit"
- \ ,""
- \ ,"Help for this scratch buffer:"
- \ ,"=======================================================","",""]
- \ + funcref#Call(get(b:settings, 'help', []))
- call tovl#scratch_buffer#ScratchBuffer({
- \ 'name' : "return Help of ".b:settings['name'],
- \ 'getContent' : help
- \ })
-endfunction
diff --git a/vim/bundle/vim-addon-mw-utils/autoload/tovl/ui/filter_list.vim b/vim/bundle/vim-addon-mw-utils/autoload/tovl/ui/filter_list.vim
deleted file mode 100644
index 74b2ab4..0000000
--- a/vim/bundle/vim-addon-mw-utils/autoload/tovl/ui/filter_list.vim
+++ /dev/null
@@ -1,473 +0,0 @@
-" OLD CODE !
-" I should contribute the multiple filter feature to tlib
-
-" filter list displays a list of items
-" you can white / black filter them by regular expressions (similar to the
-" tlib TToC command
-" However you can edit the filters afterwards and select the cols which should
-" be shown
-
-fun! tovl#ui#filter_list#ListTest()
- call tovl#ui#filter_list#ListView({
- \ 'aligned' : 1,
- \ 'Continuation' : funcref#Function('echo string(ARGS[0])'),
- \ 'items' : [ {"aa" : "a\nAAAAAAAAAAA", 'bb' : "bbbbbbbbbbbbb\nB" },
- \ {"aa" : "2a\n2AAAAAAAAAAAA", "bb" : "2 bbbbbbbbbbbbb\n2B"},
- \ {"aa" : "XXX", "bb" : "YY"} ],
- \ })
-
-endfun
-
-fun! s:Intersection(a, b)
- return filter(copy(a:a), 'index(a:b, v:val) >= 0')
-endf
-
-fun! tovl#ui#filter_list#ListTestGotoLineCurrentBuf()
- let nr=1
- let lines = []
- for l in getline(0,line('$'))
- call add(lines, {'nr': nr, 'line' :l})
- let nr = nr +1
- endfor
- call tovl#ui#filter_list#ListView({
- \ 'aligned' : 0,
- \ 'keys' : ['nr','line'],
- \ 'number' : 1,
- \ 'selectByIdOrFilter' : 1,
- \ 'Continuation' : funcref#Function('exec ARGS[0]["nr"]'),
- \ 'items' : lines,
- \ })
-endfun
-
-" opens a new filtered list
-" keys of opts parameters:
-" Continuation: This function will be called with the selected items
-" items: { key : (string or dict) }
-" items willl be modified. use copy(youritems) as argument to prevent
-" this. An item is either a string or a dict
-" (eg {'file' : .., 'line': ... , 'msg' : .. )
-" keys: list of keys to be shown (optional)
-" filter: list of inital filters which must be applied
-" contains [ { filter: .. , keep : .. }, ] see FilterItems() below
-" aligned: default 0
-" sp_cmd: the command to be used to create the new buffer (default ':e')
-" init : 0 / 1 (default 1): wether to show the view right now
-" number: 0 /1 (default 1): number items ?
-" selectByIdOrFilter: 1: start in getchar() loop so that the user can select
-" the item even faster
-" auto: only do this if all items fit on screen
-" (recommend)
-" cmds: extra cmds to be run
-" cursorAt : at which item to put the cursor?
-"
-" If you don't like the default view you can override UpdateDisplay
-"
-" Usage examples of this list control:
-" - db results
-" - replacement of the quickfix window
-" - select a buffer etc
-fun! tovl#ui#filter_list#ListView(opts)
- " ActivateAddons theonevimlib
- let d = {}
- let d.items = a:opts.items
- let d.cursorAt = get(a:opts, 'cursorAt', 0)
- let d.aligned = get(a:opts, 'aligned', 0)
- let d.sep = ' '
- let d.filter = get(a:opts, 'filter', [])
- " using sp because of bd! (FIXME)
- let d.sp_cmd = get(a:opts, 'sp_cmd', 'sp')
- let d.allKeys = {}
- let d.closeOnContinuation = get(a:opts,'closeOnContinuation',1)
- " don't recommend OnSingleMatch, use OnSingleMatchCR instead
- let d.continueOnSingleMatch = get(a:opts, 'continueOnSingleMatch',0)
- let d.continueOnSingleMatchCR = get(a:opts, 'continueOnSingleMatchCR',1)
- let d.selectByIdOrFilter = get(a:opts, 'selectByIdOrFilter', 0)
- let d.linesToItems = {}
- let d.number = get(a:opts, 'number', 1)
- let d.cmds = get(a:opts, 'cmds', [])
- let d.syn_cmds = get(a:opts, 'syn_cmds', [])
-
- if has_key(a:opts,'keys') | let d.keys = a:opts.keys | endif
- if has_key(a:opts,'Continuation') | let d.Continuation = a:opts.Continuation | endif
-
- " cache already filtered items in case we want to view really long results
- " contains [ { filter : { regex: .. , keep : .. } , items : .. , cursorAt :},
- " { filter : { ... } , items: .. , cursorAt : }
- let d.cached = []
- " id of buffer
- let d.buffer = -1
- let d.modeText = ''
-
- fun d.HelpText()
- return [ "you've entered the the help of the powerful filtered view buffer",
- \ "",
- \ "type f to start filtering items by regex",
- \ "type F to start dropping items by regex",
- \ "k / K will ask you for the key to apply the filter to first",
- \ "apply the filter by <cr> and press <cr> again to select item",
- \ "",
- \ "use :ShowAppliedFilters to list active filters",
- \ "use :ToggleAlignment to toggle alignment",
- \ "",
- \ "TODO: Implement sorting, implement interface to change keys (displayed columns)"
- \ ]
- endfun
-
- " create new scratch buffer
- " preprocess items calculating line count and maxwidth for all items
- fun d.NewBufferAndInit()
- let self.bufferId = bufnr(bufname('%'))
- for idx in range(0,len(self.items)-1)
- if type(self.items[idx]) != 4
- " no dict yet, make it one
- let self.items[idx] = {'string_line' : self.items[idx]}
- endif
- let new = {}
- for [k,v] in items(self.items[idx])
- let lines = split(v,"\n")
- let self.items[idx][k] = { 'text' : v, 'rows' : len(lines), 'cols' : max(map(copy(lines),'len(v:val)')), 'lines' : lines }
- let self.allKeys[k] = 1
- unlet k v
- endfor
- endfor
- call tovl#scratch_buffer#ScratchBuffer({
- \ 'help' : funcref#Function(self.HelpText,{ 'self' : self }),
- \ 'sp_cmd' : self.sp_cmd,
- \ 'cmds' : self.cmds
- \ })
- " I assume we have some kind of formatting anyway. Thus breaking lines is bad!
- set nowrap
- setlocal cursorline
- let b:filtered_view = self
- command! -buffer -nargs=0 ToggleAlignment call b:filtered_view.ToggleAlignment()
- command! -buffer -nargs=0 ShowAppliedFilters call b:filtered_view.ShowAppliedFilters()
- command! -buffer -nargs=0 RemoveFilters call b:filtered_view.RemoveFilters()
- noremap <buffer> f :call b:filtered_view.FilterFromKeyboard(1,'')<cr>
- " noremap <buffer> f :call b:filtered_view.FilterFromKeyboard(1)<cr>
- noremap <buffer> F :call b:filtered_view.FilterFromKeyboard(0,'')<cr>
- if has_key(self,'Continuation')
- nnoremap <buffer> <cr> :call b:filtered_view.Continue()<cr>
- endif
- "noremap <buffer> k
- "noremap <buffer> K
-
- let [items, cursorAt] = self.FilteredItems()
- " len(items) is an approximation because one item can have multiple
- " lines.. However adding the lines first to check takes too much time
- if self.selectByIdOrFilter == 1 || (self.selectByIdOrFilter == 'auto' && winheight('%') > len(items) )
- call self.SelectByIdOrFilter()
- else
- " user should choose how to proceed
- call self.UpdateDisplay()
- endif
- endfun
-
- " user interface
- fun d.ToggleAlignment()
- let self.aligned = !self.aligned
- call self.UpdateDisplay()
- endfun
- fun d.ShowAppliedFilters()
- for i in self.filter | echo string(i) | endfor
- endfun
- fun d.RemoveFilters()
- let self.filter = []
- call self.UpdateDisplay()
- endfun
- fun d.Continue()
- let item = self.CurrentItem()
- call self.DoContinue(item)
- endfun
- fun d.DoContinue(v)
- if self.closeOnContinuation | bw! | endif
- call funcref#Call(self.Continuation,[a:v])
- endfun
-
- fun d.MapToOriginal(v)
- if has_key(a:v, 'string_line')
- return a:v.string_line.text
- else
- let d = {}
- for [k,v] in items(a:v)
- let d[k] = v.text
- unlet k v
- endfor
- return d
- endif
- endfun
-
- fun d.CurrentItem()
- let idx=line('.')-len(self.headerLines)
- while idx >= 0
- if has_key(self.linesToItems, idx)
- return self.MapToOriginal(self.FilteredItems()[0][self.linesToItems[idx]])
- else
- let idx = idx -1
- endif
- endwhile
- throw "internal error, couldn't determine selected item!"
- endfun
-
- " updates the filter cache and returns the final filtered items
- fun d.FilteredItems()
- " update cache
- let idx = 0
- let [items, cursorAt] = [self.items, self.cursorAt]
- for idx in range(0, len(self.filter)-1)
- if idx +1 > len(self.cached) || self.cached[idx]['filter'] != self.filter[idx]
- let self.cached = self.cached[:idx-1]
- let [items, cursorAt] = self.FilterItem(copy(items), self.filter[idx], cursorAt)
- call add(self.cached, { 'cursorAt' : cursorAt, 'items' : items, 'filter' : self.filter[idx]})
- else
- let ci = self.cached[idx]
- let [items, cursorAt] = [ci['items'], ci['cursorAt']]
- endif
- endfor
- return [items, cursorAt]
- endfun
-
- " calling this will return a set of lines which are expected to be the new
- " buffer contents. The self.linesToItems dict is updated
- fun d.UpdateDisplay()
-
- if empty(self.filter)
- let self.statusline= 'no filter applied, :Help for help'
- else
- let self.statusline = len(self.filter).' '.string(self.filter[-1])
- endif
-
- let self.linesToItems = {}
- let [items, cursorAt] = self.FilteredItems()
- "let num_width = printf('%.0f', trunc(log10(len(items))+1))
- let num_width = 4
- if self.aligned
- " get column width.. (probably will not work with unicde characters.. I
- " don't have a better solution)
- let maxlens={}
- for i in items
- for [k,v] in items(i)
- if get(maxlens,k,0) < v.cols
- let maxlens[k] = v.cols
- endif
- endfor
- endfor
- endif
-
- " format lines
- let self.headerLines = [self.modeText]
- let lines = copy(self.headerLines)
- let lines_count = 0
- if self.number
- let fmt_startA = '%'.num_width.'s)'
- let fmt_startB = '%'.num_width.'s'
- else
- let fmt_startA = '' | let fmt_startB = ''
- endif
- let cursorAtLine = 1 " sane default
- for idx in range(0,len(items)-1)
- let self.linesToItems[lines_count + 1] = idx
- let i = items[idx]
- let keys = has_key(self,'keys')
- \ ? s:Intersection(self.keys, keys(i))
- \ : keys(i)
- let fmt = ''
- let args = [i]
- let cols = []
- for k in keys
- let fmt .= self.sep.'%-'.(self.aligned ? maxlens[k] : i[k]['cols']).'s'
- call add(cols, i[k])
- endfor
- for row in range(0, max([1] + map(copy(cols),'v:val["rows"]'))-1)
- let fmt_args = row == 0 ? [fmt_startA.fmt] : [fmt_startB.fmt]
- if self.number
- call add(fmt_args, row == 0 ? idx : '')
- endif
- for c in cols
- call add(fmt_args, c.rows <= row ? '' : c.lines[row])
- endfor
- call add(lines, call('printf', fmt_args))
- let lines_count += 1
- endfor
- if idx == cursorAt
- let cursorAtLine = lines_count
- endif
- endfor
- " update stauts line to show last applied filter
- " disabled cause it causes trouble on :wincmd w
- " setlocal statusline=%!b:filtered_view.statusline
-
- " syntax
- syn clear
- for s in self.syn_cmds | exec s | endfor
- let id = 0
- " highlight filter regex in buffer as well
- let syn_ids = [ 'Underlined', 'Todo', 'Error', 'Type', 'Statement' ]
- for f in self.filter
- if !f.keep || !has_key(f, 'regex') | continue | endif
- if f.regex != ''
- try
- exec 'syn match '.syn_ids[id % len(syn_ids)].' '.string(f.regex)
- catch /.*/
- " ignore errors such as \ without following characters. Thus just
- " ignore and wait for the next character
- endtry
- endif
- let id = id +1
- endfor
- if len(lines) > winheight('%')
- call extend(lines, self.headerLines)
- endif
- normal ggdG
- call append(0, lines)
- " place cursor
- exec (cursorAtLine+1)
- " move cursor into the middle of the window
- normal zz
- endf
-
- " filter = keys :
- " filter = string to be executed containing Val
- " keep = 1 keep on match
- " = 0 drop on match
- " key (optional)
- " cursorAt: at which item to put the cursor
- " if that item is deleted it will be placed at the item above
- " optional: key of dict if dict
- fun d.FilterItem(items, filter, cursorAt)
- let filter = 'Val =~ '.string(a:filter.regex)
- let keep = a:filter.keep
- let cursorAt = a:cursorAt
-
- for idx in reverse(range(0, len(a:items)-1))
- let i = a:items[idx]
- if has_key(a:filter,'key')
- let key = a:filter.key
- if has_key(i, key)
- " key given, only filter by this column
- let Val = i[key]['text']
- exec 'let any = '.filter
- else
- let any = 0
- endif
- else
- let any = 0
- " no key given, try all
- for x in values(i)
- let Val = x['text']
- exec 'let any = '.filter
- if any | break | endif
- endfor
- endif
- if any != keep
- call remove(a:items, idx)
- if idx <= cursorAt
- let cursorAt = cursorAt -1
- endif
- endif
- endfor
- return [a:items, cursorAt]
- endfun
-
- " if the user enters a number select by index else start filtering..
- fun d.SelectByIdOrFilter()
- let idx=''
- let items = self.FilteredItems()[0]
- try
- let self.modeText = '[0-9]* : select by index| <esc>: escape getchar() loop, any char: start filtering'
- call self.UpdateDisplay() | redraw
- while 1
- let c=getchar()
- if index([13,10],c) >= 0
- return self.DoContinue(self.MapToOriginal(items[idx]))
- elseif index([27], c) >=0
- " esc, abort
- return
- else
- if type(c) == 0
- let c = nr2char(c)
- endif
- if c == "\<bs>" || index(map(range(0,10),'v:val.""'),c) >= 0
- if c == "\<bs>"
- let idx = idx[:-2]
- else
- let idx .= c
- endif
- if idx < len(items) && idx.'0' > len(items) || idx == 0 && len(items) < 10
- " only match
- return self.DoContinue(self.MapToOriginal(items[idx]))
- endif
- else
- return self.FilterFromKeyboard(1,c)
- endif
- endif
- endwhile
- finally
- let self.modeText = ''
- endtry
- endfun
-
- " gets a regular expresion filter by keybaord and updates the display while
- " you're typing. The regex ist shown in the statusline
- fun d.FilterFromKeyboard(keep, start, ...)
- let self.modeText = 'press ESC to exit getchar() loop'
- call self.UpdateDisplay() | redraw
-
- try
- let key_text = a:0 > 0 ? 'key : '.a:1 : ''
- let filter_bak = self.filter
- let filter = copy(self.filter)
- let start = a:start
- let filter_new = ''
- while 1
- if start != ''
- " use c= last char to force updating display etc
- let filter_new = start[:-2]
- let c = start[-1:]
- let start = ''
- else
- let c=getchar()
- endif
- if index([13,10],c) >= 0
- " c-j or return, accept new filter
- let items = self.FilteredItems()
- if len(items) == 1 && has_key(self, 'Continuation') && self.continueOnSingleMatchCR
- call self.DoContinue(self.MapToOriginal(items[0]))
- endif
- return
- elseif index([27], c) >=0
- " esc, abort
- let self.filter = filter_bak
- call self.UpdateDisplay()
- return
- else
- if type(c) == 0
- let c = nr2char(c)
- endif
- if c == "\<bs>"
- let filter_new = filter_new[:-2]
- else
- let filter_new .= c
- endif
- let d = {'keep' : a:keep, 'regex' : filter_new }
- if a:0 > 0
- let d['key'] = a:1
- endif
- let self.filter = copy(filter_bak)
- call add(self.filter, d)
- let items = self.FilteredItems()
- if len(items) == 1 && has_key(self, 'Continuation') && self.continueOnSingleMatch
- call self.DoContinue(self.MapToOriginal(items[0]))
- return
- endif
- call self.UpdateDisplay() | redraw
- endif
- endwhile
- finally
- let self.modeText = ''
- endtry
- endfun
-
- if get(a:opts,'init',1)
- call d.NewBufferAndInit()
- endif
-endfun