From d8b4a60a2ffcae310d79b26d129a744e4fde45c1 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Mon, 8 Feb 2016 12:41:52 +0900 Subject: [PATCH] Update vital and fix inappropriate syntax reset --- autoload/vital/_easymotion.vim | 117 ++++++++---------- .../vital/_easymotion/HitAHint/Motion.vim | 3 +- autoload/vital/_easymotion/Vim/Buffer.vim | 51 +++++++- autoload/vital/_easymotion/Vim/Guard.vim | 117 ++++++++++++++++++ autoload/vital/easymotion.vital | 2 +- 5 files changed, 219 insertions(+), 71 deletions(-) create mode 100644 autoload/vital/_easymotion/Vim/Guard.vim diff --git a/autoload/vital/_easymotion.vim b/autoload/vital/_easymotion.vim index 3ce8c6b..e5e2c38 100644 --- a/autoload/vital/_easymotion.vim +++ b/autoload/vital/_easymotion.vim @@ -1,17 +1,30 @@ let s:self_version = expand(':t:r') let s:self_file = expand('') - -" Note: The extra argument to globpath() was added in Patch 7.2.051. -let s:globpath_third_arg = v:version > 702 || v:version == 702 && has('patch51') +let s:base_dir = expand(':h') let s:loaded = {} let s:cache_module_path = {} let s:cache_sid = {} -let s:_vital_files_cache_runtimepath = '' -let s:_vital_files_cache = [] let s:_unify_path_cache = {} +function! s:plugin_name() abort + let info_file = get(split(glob(s:base_dir . '/*.vital', 1), "\n"), 0, '') + return fnamemodify(info_file, ':t:r') +endfunction + +function! s:vital_files() abort + if !exists('s:vital_files') + let s:vital_files = + \ map( + \ s:plugin_name() ==# 'vital' + \ ? s:_global_vital_files() + \ : s:_self_vital_files(), + \ 'fnamemodify(v:val, ":p:gs?[\\\\/]?/?")') + endif + return copy(s:vital_files) +endfunction + function! s:import(name, ...) abort let target = {} let functions = [] @@ -67,6 +80,7 @@ function! s:unload() abort let s:loaded = {} let s:cache_sid = {} let s:cache_module_path = {} + unlet! s:vital_files endfunction function! s:exists(name) abort @@ -74,35 +88,11 @@ function! s:exists(name) abort endfunction function! s:search(pattern) abort - let paths = s:_vital_files(a:pattern) + let paths = s:_extract_files(a:pattern, s:vital_files()) let modules = sort(map(paths, 's:_file2module(v:val)')) return s:_uniq(modules) endfunction -function! s:expand_modules(entry, all) abort - if type(a:entry) == type([]) - let candidates = s:_concat(map(copy(a:entry), 's:search(v:val)')) - if empty(candidates) - throw printf('vital: Any of module %s is not found', string(a:entry)) - endif - if eval(join(map(copy(candidates), 'has_key(a:all, v:val)'), '+')) - let modules = [] - else - let modules = [candidates[0]] - endif - else - let modules = s:search(a:entry) - if empty(modules) - throw printf('vital: Module %s is not found', a:entry) - endif - endif - call filter(modules, '!has_key(a:all, v:val)') - for module in modules - let a:all[module] = 1 - endfor - return modules -endfunction - function! s:_import(name) abort if type(a:name) == type(0) return s:_build_module(a:name) @@ -134,10 +124,8 @@ function! s:_get_module_path(name) abort if s:_is_absolute_path(a:name) && filereadable(a:name) return a:name endif - if a:name ==# '' - let paths = [s:self_file] - elseif a:name =~# '\v^\u\w*%(\.\u\w*)*$' - let paths = s:_vital_files(a:name) + if a:name =~# '\v^\u\w*%(\.\u\w*)*$' + let paths = s:_extract_files(a:name, s:vital_files()) else throw 'vital: Invalid module name: ' . a:name endif @@ -154,8 +142,8 @@ function! s:_get_sid_by_script(path) abort endif let path = s:_unify_path(a:path) - for line in filter(split(s:_redir('scriptnames'), "\n"), - \ 'stridx(v:val, s:self_version) > 0') + let p = 'stridx(v:val, s:self_version) > 0 || stridx(v:val, "__latest__") > 0' + for line in filter(split(s:_redir('scriptnames'), "\n"), p) let list = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$') if !empty(list) && s:_unify_path(list[2]) ==# path let s:cache_sid[a:path] = list[1] - 0 @@ -191,28 +179,21 @@ else endfunction endif -if s:globpath_third_arg - function! s:_runtime_files(path) abort - return split(globpath(&runtimepath, a:path, 1), "\n") - endfunction -else - function! s:_runtime_files(path) abort - return split(globpath(&runtimepath, a:path), "\n") - endfunction -endif +function! s:_self_vital_files() abort + let base = s:base_dir . '/*/**/*.vim' + return split(glob(base, 1), "\n") +endfunction -function! s:_vital_files(pattern) abort - if s:_vital_files_cache_runtimepath !=# &runtimepath - let path = printf('autoload/vital/%s/**/*.vim', s:self_version) - let s:_vital_files_cache = s:_runtime_files(path) - let mod = ':p:gs?[\\/]\+?/?' - call map(s:_vital_files_cache, 'fnamemodify(v:val, mod)') - let s:_vital_files_cache_runtimepath = &runtimepath - endif - let target = substitute(a:pattern, '\.', '/', 'g') - let target = substitute(target, '\*', '[^/]*', 'g') - let regexp = printf('autoload/vital/%s/%s.vim', s:self_version, target) - return filter(copy(s:_vital_files_cache), 'v:val =~# regexp') +function! s:_global_vital_files() abort + let pattern = 'autoload/vital/__latest__/**/*.vim' + return split(globpath(&runtimepath, pattern, 1), "\n") +endfunction + +function! s:_extract_files(pattern, files) abort + let tr = {'.': '/', '*': '[^/]*', '**': '.*'} + let target = substitute(a:pattern, '\.\|\*\*\?', '\=tr[submatch(0)]', 'g') + let regexp = printf('autoload/vital/[^/]\+/%s.vim$', target) + return filter(a:files, 'v:val =~# regexp') endfunction " Copy from System.Filepath @@ -241,10 +222,17 @@ function! s:_build_module(sid) abort call module._vital_created(module) endif let export_module = filter(copy(module), 'v:key =~# "^\\a"') + " Cache module before calling module.vital_debug() to avoid cyclic + " dependences but remove the cache if module._vital_loaded() fails. let s:loaded[a:sid] = get(g:, 'vital_debug', 0) ? module : export_module if has_key(module, '_vital_loaded') - let V = vital#{s:self_version}#new() - call module._vital_loaded(V) + try + let V = vital#{s:self_version}#new() + call module._vital_loaded(V) + catch + unlet s:loaded[a:sid] + throw 'vital: fail to call ._vital_loaded(): ' . v:exception + endtry endif return copy(s:loaded[a:sid]) endfunction @@ -286,14 +274,6 @@ else endfunction endif -function! s:_concat(lists) abort - let result_list = [] - for list in a:lists - let result_list += list - endfor - return result_list -endfunction - function! s:_redir(cmd) abort let [save_verbose, save_verbosefile] = [&verbose, &verbosefile] set verbose=0 verbosefile= @@ -305,5 +285,6 @@ function! s:_redir(cmd) abort endfunction function! vital#{s:self_version}#new() abort - return s:_import('') + let sid = s:_get_sid_by_script(s:self_file) + return s:_build_module(sid) endfunction diff --git a/autoload/vital/_easymotion/HitAHint/Motion.vim b/autoload/vital/_easymotion/HitAHint/Motion.vim index 53038c5..3bf68a3 100644 --- a/autoload/vital/_easymotion/HitAHint/Motion.vim +++ b/autoload/vital/_easymotion/HitAHint/Motion.vim @@ -507,7 +507,7 @@ function! s:Hinter._show_hint_for_win(winnr) abort let hints += self._show_hint_for_line(a:winnr, lnum, col2hint) endfor " Restore syntax and show hints after replacing all lines for performance. - if !self.config.do_shade + if !s:can_preserve_syntax && !self.config.do_shade let &l:syntax = self.save_syntax[a:winnr] endif execute 'highlight! link Conceal' self.config.highlight.target @@ -778,3 +778,4 @@ endfunction function! s:throw(message) abort throw 'vital: HitAHint.Motion: ' . a:message endfunction + diff --git a/autoload/vital/_easymotion/Vim/Buffer.vim b/autoload/vital/_easymotion/Vim/Buffer.vim index b323f41..22f2c42 100644 --- a/autoload/vital/_easymotion/Vim/Buffer.vim +++ b/autoload/vital/_easymotion/Vim/Buffer.vim @@ -4,10 +4,11 @@ set cpo&vim function! s:_vital_loaded(V) abort let s:V = a:V let s:P = s:V.import('Prelude') + let s:G = s:V.import('Vim.Guard') endfunction function! s:_vital_depends() abort - return ['Prelude'] + return ['Prelude', 'Vim.Guard'] endfunction if exists('*getcmdwintype') @@ -89,6 +90,54 @@ function! s:get_last_selected() abort endif endfunction +function! s:read_content(content, ...) abort + let options = extend({ + \ 'tempfile': '', + \ 'fileformat': '', + \ 'encoding': '', + \ 'binary': 0, + \ 'nobinary': 0, + \ 'bad': '', + \ 'edit': 0, + \}, get(a:000, 0, {})) + let tempfile = empty(options.tempfile) ? tempname() : options.tempfile + let optnames = [ + \ empty(options.fileformat) ? '' : '++ff=' . options.fileformat, + \ empty(options.encoding) ? '' : '++enc=' . options.encoding, + \ empty(options.binary) ? '' : '++bin', + \ empty(options.nobinary) ? '' : '++nobin', + \ empty(options.bad) ? '' : '++bad=' . options.bad, + \ empty(options.edit) ? '' : '++edit', + \] + let optname = join(filter(optnames, '!empty(v:val)')) + try + call writefile(a:content, tempfile) + execute printf('keepalt keepjumps read %s%s', + \ empty(optname) ? '' : optname . ' ', + \ fnameescape(tempfile), + \) + finally + call delete(tempfile) + endtry +endfunction + +function! s:edit_content(content, ...) abort + let options = extend({ + \ 'edit': 1, + \}, get(a:000, 0, {})) + let guard = s:G.store('&l:modifiable') + let saved_view = winsaveview() + try + let &l:modifiable=1 + silent keepjumps %delete _ + silent call s:read_content(a:content, options) + silent keepjumps 1delete _ + finally + keepjump call winrestview(saved_view) + call guard.restore() + endtry + setlocal nomodified +endfunction let &cpo = s:save_cpo unlet s:save_cpo diff --git a/autoload/vital/_easymotion/Vim/Guard.vim b/autoload/vital/_easymotion/Vim/Guard.vim new file mode 100644 index 0000000..a4e927d --- /dev/null +++ b/autoload/vital/_easymotion/Vim/Guard.vim @@ -0,0 +1,117 @@ +let s:save_cpo = &cpo +set cpo&vim + +" Use a Funcref as a special term UNDEFINED +function! s:undefined() abort + return 'undefined' +endfunction +let s:UNDEFINED = function('s:undefined') + +function! s:_vital_created(module) abort + " define constant variables + if !exists('s:const') + let s:const = {} + let s:const.is_local_variable_supported = + \ v:version > 703 || (v:version == 703 && has('patch560')) + lockvar s:const + endif + call extend(a:module, s:const) +endfunction +function! s:_throw(msg) abort + throw printf('vital: Vim.Guard: %s', a:msg) +endfunction + +let s:option = {} +function! s:_new_option(name) abort + if a:name !~# '^&' + call s:_throw(printf( + \'An option name "%s" requires to be started from "&"', a:name + \)) + elseif !exists(a:name) + call s:_throw(printf( + \'An option name "%s" does not exist', a:name + \)) + endif + let option = copy(s:option) + let option.name = a:name + let option.value = eval(a:name) + return option +endfunction +function! s:option.restore() abort + execute printf('let %s = %s', self.name, string(self.value)) +endfunction + +let s:variable = {} +function! s:_new_variable(name, ...) abort + if a:0 == 0 + let m = matchlist(a:name, '^\([bwtg]:\)\(.*\)$') + if empty(m) + call s:_throw(printf( + \ join([ + \ 'An variable name "%s" requires to start from b:, w:, t:, or g:', + \ 'while no {namespace} is specified', + \ ]), + \ a:name, + \)) + endif + let [prefix, name] = m[1 : 2] + let namespace = eval(prefix) + else + let name = a:name + let namespace = a:1 + endif + let variable = copy(s:variable) + let variable.name = name + let variable.value = get(namespace, name, s:UNDEFINED) + let variable.value = + \ type(variable.value) == type({}) || type(variable.value) == type([]) + \ ? deepcopy(variable.value) + \ : variable.value + let variable._namespace = namespace + return variable +endfunction +function! s:variable.restore() abort + " unlet the variable to prevent variable type mis-match in case + silent! unlet! self._namespace[self.name] + if type(self.value) == type(s:UNDEFINED) && self.value == s:UNDEFINED + " do nothing, leave the variable as undefined + else + let self._namespace[self.name] = self.value + endif +endfunction + +let s:guard = {} +function! s:store(...) abort + let resources = [] + for meta in a:000 + if type(meta) == type([]) + call add(resources, call('s:_new_variable', meta)) + elseif type(meta) == type('') + if meta =~# '^[bwtgls]:' + " Note: + " To improve an error message, handle l:XXX or s:XXX as well + call add(resources, s:_new_variable(meta)) + elseif meta =~# '^&' + call add(resources, s:_new_option(meta)) + else + call s:_throw(printf( + \ 'Unknown option or variable "%s" was specified', + \ meta + \)) + endif + endif + unlet meta + endfor + let guard = copy(s:guard) + let guard._resources = resources + return guard +endfunction +function! s:guard.restore() abort + for resource in self._resources + call resource.restore() + endfor +endfunction + +let &cpo = s:save_cpo +unlet! s:save_cpo +" vim:set et ts=2 sts=2 sw=2 tw=0 fdm=marker: diff --git a/autoload/vital/easymotion.vital b/autoload/vital/easymotion.vital index 52c6b09..667262e 100644 --- a/autoload/vital/easymotion.vital +++ b/autoload/vital/easymotion.vital @@ -1,5 +1,5 @@ easymotion -65c9afb0799cb950cbaf9258aefc6c3ad700a98f +e083c2e654d057a09b3e18dfbb728b41de89f4a1 Over.Commandline.Base Over.Commandline.Modules.Cancel