vim-addon-mw-utils-0.2/0000755000175000017500000000000013250451477015254 5ustar capriottcapriottvim-addon-mw-utils-0.2/doc/0000755000175000017500000000000013250451477016021 5ustar capriottcapriottvim-addon-mw-utils-0.2/doc/cached_file_contents.txt0000644000175000017500000000037113250451477022706 0ustar capriottcapriott*cached_file_contents* read contents of a file then cache extracted data Author: Marc Weber, marco-oweber@gmx.de ----------------------------------------------------------------------- HOWTO~ see cached_file_contents#Test() vim-addon-mw-utils-0.2/doc/funcref.txt0000644000175000017500000000244613250451477020220 0ustar capriottcapriott*funcref* create lazier function references. Pass arguments to create closure like function calls Author: Marc Weber, marco-oweber@gmx.de ----------------------------------------------------------------------- HOWTO~ Use *funcref#Function* to create a special dict called *faked-function-reference* which can be called by *funcref#Call* > { 'faked_function_reference': 'file#FuncName' } < passing some arguments and / or self: > { 'faked_function_reference': 'MyFunc', 'args': [1,2], 'self' : { a object ] } < You can also create lambda like functions which will be evaled: > { 'faked_function_reference': 'return ARGS[1]' } REASONS ~ Creating a Vim funcref pointing to an autoload function will make Vim source that file. This is not lazy enough. (Seems to be no longer true? Has this changed?) A Vim function reference neither allows attaching arguments nor self. Don't care about case of variables. Normally when using Vim function references you have to use variable names starting with an upper case letter (E704) Example: ~ > let f = funcref#Function('return ARGS[0].ARGS[1].SELF["key"]',{'args':[3], 'self':{'key': 'value'} }) echo funcref#Call(f, [2]) " prints "32value" echo funcref#Call('no value') < echo funcref#Call(f, [2]) vim-addon-mw-utils-0.2/doc/tiny_cmd.txt0000644000175000017500000000113613250451477020371 0ustar capriottcapriott*tiny-cmd* make long commands short so that they hopefully no longer trigger "press Enter .. [ok]" Author: Marc Weber, marco-oweber@gmx.de ----------------------------------------------------------------------- HOWTO~ Problem: > exec 'map :silent! let g:g="'.repeat('foobar ',200).'"' Now run the mapping by pressing and you notice what I'm talking about Solution (Example): Example usage: > let nr = tiny_cmd#Put('let g:g="'.repeat('foobar ',200).'"') exec 'map :exec tiny_cmd#Get('.nr.')' < Use Pop instead of Get if you use this command once only vim-addon-mw-utils-0.2/.gitignore0000644000175000017500000000001113250451477017234 0ustar capriottcapriottdoc/tags vim-addon-mw-utils-0.2/vim-addon-mw-utils-addon-info.txt0000644000175000017500000000062413250451477023470 0ustar capriottcapriott{ "name" : "vim-addon-mw-utils", "version" : "0.0", "author" : "Marc Weber ", "maintainer" : "Marc Weber ", "repository" : {"type": "git", "url": "git://github.com/MarcWeber/vim-addon-manager-known-repositories.git"}, "dependencies" : {}, "description" : "various utils such as caching interpreted contents of files or advanced glob like things" } vim-addon-mw-utils-0.2/autoload/0000755000175000017500000000000013250451477017064 5ustar capriottcapriottvim-addon-mw-utils-0.2/autoload/funcref.vim0000644000175000017500000000552713250451477021242 0ustar capriottcapriott" 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 vim-addon-mw-utils-0.2/autoload/env_reload.vim0000644000175000017500000000077013250451477021723 0ustar capriottcapriott" 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 vim-addon-mw-utils-0.2/autoload/tovl/0000755000175000017500000000000013250451477020050 5ustar capriottcapriottvim-addon-mw-utils-0.2/autoload/tovl/ui/0000755000175000017500000000000013250451477020465 5ustar capriottcapriottvim-addon-mw-utils-0.2/autoload/tovl/ui/filter_list.vim0000644000175000017500000003501113250451477023522 0ustar capriottcapriott" 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 and press 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 f :call b:filtered_view.FilterFromKeyboard(1,'') " noremap f :call b:filtered_view.FilterFromKeyboard(1) noremap F :call b:filtered_view.FilterFromKeyboard(0,'') if has_key(self,'Continuation') nnoremap :call b:filtered_view.Continue() endif "noremap k "noremap 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| : 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 == "\" || index(map(range(0,10),'v:val.""'),c) >= 0 if c == "\" 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 == "\" 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 vim-addon-mw-utils-0.2/autoload/tovl/scratch_buffer.vim0000644000175000017500000000616113250451477023551 0ustar capriottcapriott" 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 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 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 vim-addon-mw-utils-0.2/autoload/cached_file_contents.vim0000644000175000017500000001022513250451477023724 0ustar capriottcapriott" 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 vim-addon-mw-utils-0.2/autoload/buf_utils.vim0000644000175000017500000000137213250451477021600 0ustar capriottcapriott" 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 vim-addon-mw-utils-0.2/autoload/tiny_cmd.vim0000644000175000017500000000051513250451477021410 0ustar capriottcapriott" 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 vim-addon-mw-utils-0.2/autoload/glob_linux.vim0000644000175000017500000000275513250451477021754 0ustar capriottcapriott " TODO refactor: create glob function " noremap \og :callglob_linux#FileByGlobCurrentDir('**/*'.input('glob open '),"\\.git\\\\.hg\\node_modules\\\\.pyc" ) " noremap \og :callglob_linux#FileByGlobCurrentDir('**/*'.input('glob open '),"default" ) function! glob_linux#FileByGlobCurrentDir(glob, exclude_pattern) if a:exclude_pattern == "default" let exclude_pattern = '\.git\|\.hg\|node_modules\|\.pyc' else let exclude_pattern = a:exclude_pattern endif " let files = split(glob(a:glob),"\n") let g = a:glob let replace = {'**': '.*','*': '[^/\]*','.': '\.'} let g = substitute(g, '\(\*\*\|\*\|\.\)', '\='.string(replace).'[submatch(1)]','g') let exclude = exclude_pattern == '' ? '' : ' | grep -v -e '.shellescape(exclude_pattern) let cmd = 'find | grep -e '.shellescape(g).exclude let files = split(system(cmd),"\n") " for nom in a:excludes " call filter(files,nom) " endfor if len(files) > 1000 echoe "more than ".2000." files - would be too slow. Open the file in another way" else if empty(files) echoe "no file found" elseif len(files) == 1 exec 'e '.fnameescape(files[0]) else let g:abc=7 call tovl#ui#filter_list#ListView({ \ 'number' : 1, \ 'selectByIdOrFilter' : 1, \ 'Continuation' : funcref#Function('exec "e ".fnameescape(ARGS[0])'), \ 'items' : files, \ 'cmds' : ['wincmd J'] \ }) endif endif endfunction vim-addon-mw-utils-0.2/autoload/glob.vim0000644000175000017500000000164113250451477020526 0ustar capriottcapriottexec 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