From 6e0fb7d708f0a9adad6829da0f054d42a833347f Mon Sep 17 00:00:00 2001 From: Wang Shidong Date: Tue, 25 Aug 2020 15:55:19 +0800 Subject: [PATCH] Update alternate file manager (#3725) --- .SpaceVim.d/init.vim | 2 +- .projections.json | 5 +- autoload/SpaceVim/commands.vim | 15 +++ autoload/SpaceVim/logger.vim | 2 +- autoload/SpaceVim/plugins/a.vim | 135 ++++++++++++++++++-------- autoload/SpaceVim/plugins/flygrep.vim | 24 ++--- config/commands.vim | 12 --- doc/SpaceVim.txt | 3 + docs/api/cmdlinemenu.md | 0 docs/cn/api/cmdlinemenu.md | 20 ++++ test/plugin/a.vader | 4 +- 11 files changed, 153 insertions(+), 69 deletions(-) delete mode 100644 config/commands.vim create mode 100644 docs/api/cmdlinemenu.md create mode 100644 docs/cn/api/cmdlinemenu.md diff --git a/.SpaceVim.d/init.vim b/.SpaceVim.d/init.vim index d50a4842d..4e25bc349 100644 --- a/.SpaceVim.d/init.vim +++ b/.SpaceVim.d/init.vim @@ -28,7 +28,7 @@ function! s:language_specified_mappings() abort \ 'execute current file', 1) endfunction call SpaceVim#mapping#space#regesit_lang_mappings('vader', function('s:language_specified_mappings')) -call SpaceVim#plugins#a#set_config_name('.projections.json') +call SpaceVim#plugins#a#set_config_name(getcwd(), '.projections.json') command! -nargs=1 IssueEdit call SpaceVim#dev#issuemanager#edit() command! -nargs=1 PullCreate call SpaceVim#dev#pull#create() command! -nargs=1 PullMerge call SpaceVim#dev#pull#merge() diff --git a/.projections.json b/.projections.json index 53eff1598..b0541e694 100644 --- a/.projections.json +++ b/.projections.json @@ -1,5 +1,8 @@ { - "autoload/SpaceVim/api/*.vim": { "alternate": "test/api/{}.vader" }, + "autoload/SpaceVim/api/*.vim": { + "alternate": "test/api/{}.vader", + "doc" : "docs/api/{}.md" + }, "autoload/SpaceVim/plugins/a.vim": { "alternate": "test/plugin/a.vader" }, "test/plugin/a.vader": { "alternate": "autoload/SpaceVim/plugins/a.vim" }, "autoload/SpaceVim/layers/lang/*.vim": { "doc": "docs/layers/lang/{}.md" }, diff --git a/autoload/SpaceVim/commands.vim b/autoload/SpaceVim/commands.vim index b8df0bf0a..f4e22fb36 100644 --- a/autoload/SpaceVim/commands.vim +++ b/autoload/SpaceVim/commands.vim @@ -58,6 +58,21 @@ function! SpaceVim#commands#load() abort command! -nargs=* SPInstall call SpaceVim#commands#install_plugin() command! -nargs=* SPClean call SpaceVim#commands#clean_plugin() command! -nargs=0 Report call SpaceVim#issue#new() + " Convenient command to see the difference between the current buffer and the + " file it was loaded from, thus the changes you made. Only define it when not + " defined already. + command! DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis + \ | wincmd p | diffthis + command! -nargs=* -complete=custom,SpaceVim#plugins#complete_plugs Plugin :call SpaceVim#plugins#Plugin() + "command for open project + command! -nargs=+ -complete=custom,SpaceVim#plugins#projectmanager#complete_project OpenProject :call SpaceVim#plugins#projectmanager#OpenProject() + + command! -nargs=* -complete=custom,SpaceVim#plugins#pmd#complete PMD :call SpaceVim#plugins#pmd#run() + + + "" + " Switch to alternate file based on {type}. + command! -nargs=? -complete=custom,SpaceVim#plugins#a#complete -bang A :call SpaceVim#plugins#a#alt(0,) endfunction " @vimlint(EVL103, 1, a:ArgLead) diff --git a/autoload/SpaceVim/logger.vim b/autoload/SpaceVim/logger.vim index c4f5783bc..7066d71e9 100644 --- a/autoload/SpaceVim/logger.vim +++ b/autoload/SpaceVim/logger.vim @@ -143,6 +143,6 @@ function! s:derive.error(msg) abort endfunction function! SpaceVim#logger#derive(name) abort - let s:derive.derive_name = a:name + let s:derive.derive_name = printf('%' . strdisplaywidth(s:LOGGER.get_name()) . 'S', a:name) return deepcopy(s:derive) endfunction diff --git a/autoload/SpaceVim/plugins/a.vim b/autoload/SpaceVim/plugins/a.vim index 5baefd246..3d0b20dc7 100644 --- a/autoload/SpaceVim/plugins/a.vim +++ b/autoload/SpaceVim/plugins/a.vim @@ -16,8 +16,17 @@ scriptencoding utf-8 let s:CMP = SpaceVim#api#import('vim#compatible') let s:JSON = SpaceVim#api#import('data#json') let s:FILE = SpaceVim#api#import('file') -let s:conf = '.project_alt.json' -let s:cache_path = g:spacevim_data_dir.'/SpaceVim/a.json' +let s:LOGGER =SpaceVim#logger#derive('a.vim') + + +" local value +" +" s:alternate_conf define which file should be loaded as alternate +" file configuration for current project, This is a directory +let s:alternate_conf = { + \ '_' : '.project_alt.json' + \ } +let s:cache_path = s:FILE.unify_path(g:spacevim_data_dir, ':p') . 'SpaceVim/a.json' " this is for saving the project configuration information. Use the path of @@ -32,61 +41,81 @@ function! s:cache() abort endfunction function! s:load_cache() abort - let s:project_config = s:JSON.json_decode(join(readfile(s:cache_path, ''), '')) + call s:LOGGER.info('Try to load alt cache from: ' . s:cache_path) + let cache_context = join(readfile(s:cache_path, ''), '') + if !empty(cache_context) + let s:project_config = s:JSON.json_decode(cache_context) + endif endfunction " when this function is called, the project_config file name is changed, and " the project_config info is cleared. -function! SpaceVim#plugins#a#set_config_name(name) abort - let s:conf = a:name - let s:project_config = {} +function! SpaceVim#plugins#a#set_config_name(path, name) abort + let s:alternate_conf[a:path] = a:name endfunction function! s:get_project_config(conf_file) abort - let project_config_conf = get(b:, 'project_alt_json', {}) - if !empty(project_config_conf) - return project_config_conf - endif - return s:JSON.json_decode(join(readfile(a:conf_file), "\n")) + let conf = s:JSON.json_decode(join(readfile(a:conf_file), "\n")) + let root = s:FILE.unify_path(a:conf_file, ':p:h') + return { + \ 'root' : root, + \ 'config' : conf + \ } endfunction function! SpaceVim#plugins#a#alt(request_paser,...) abort let type = get(a:000, 0, 'alternate') - let conf_file_path = s:FILE.unify_path(s:conf, ':p') + let conf_file_path = s:FILE.unify_path(get(s:alternate_conf, getcwd(), '_'), ':p') let file = s:FILE.unify_path(bufname('%'), ':.') let alt = SpaceVim#plugins#a#get_alt(file, conf_file_path, a:request_paser, type) if !empty(alt) exe 'e ' . alt + else + echo 'failed to find alternate file!' endif endfunction -function! s:paser(conf, root) abort - for key in keys(a:conf) + +" the paser function should only accept one argv +" the alt_config_json +" +" @todo Rewrite alternate file paser +" paser function is written in vim script, and it is too slow, +" we are going to rewrite this function in other language. +" asynchronous paser should be supported. +function! s:paser(alt_config_json) abort + call s:LOGGER.info('Start to paser alternate files for: ' . a:alt_config_json.root) + let s:project_config[a:alt_config_json.root] = {} + for key in keys(a:alt_config_json.config) let searchpath = key - if match(key, '/\*') - let searchpath = substitute(key, '*', '**/*', 'g') + if match(searchpath, '/\*') + let searchpath = substitute(searchpath, '*', '**/*', 'g') endif for file in s:CMP.globpath('.', searchpath) let file = s:FILE.unify_path(file, ':.') - let s:project_config[a:root][file] = {} - if has_key(a:conf, file) - for type in keys(a:conf[file]) - if len(begin_end) == 2 - let s:project_config[a:root][file][type] = a:conf[key][type] - endif + let s:project_config[a:alt_config_json.root][file] = {} + if has_key(a:alt_config_json.config, file) + for type in keys(a:alt_config_json.config[file]) + let s:project_config[a:alt_config_json.root][file][type] = a:alt_config_json.config[file][type] endfor else - for type in keys(a:conf[key]) + for type in keys(a:alt_config_json.config[key]) let begin_end = split(key, '*') if len(begin_end) == 2 - let s:project_config[a:root][file][type] = s:get_type_path(begin_end, file, a:conf[key][type]) + let s:project_config[a:alt_config_json.root][file][type] = + \ s:get_type_path( + \ begin_end, + \ file, + \ a:alt_config_json.config[key][type] + \ ) endif endfor endif endfor endfor + call s:LOGGER.info('Paser done, try to cache alternate info') call s:cache() endfunction @@ -100,37 +129,63 @@ function! s:get_type_path(a, f, b) abort return substitute(a:b, '{}', a:f[begin_len : (end_len+1) * -1], 'g') endfunction -function! SpaceVim#plugins#a#get_alt(file, conf_path, request_paser,...) abort - if getftime(a:conf_path) < getftime(s:cache_path) +function! s:is_config_changed(conf_path) abort + if getftime(a:conf_path) > getftime(s:cache_path) + call s:LOGGER.info('alt config file (' + \ . a:conf_path + \ . ') has been changed, paser required!') + return 1 endif - if a:request_paser || !has_key(s:project_config, a:conf_path) - let altconfa = s:get_project_config(a:conf_path) - let s:project_config[a:conf_path] = {} - call s:paser(altconfa, a:conf_path) +endfunction + +function! SpaceVim#plugins#a#get_alt(file, conf_path, request_paser,...) abort + call s:LOGGER.info('getting alt file for:' . a:file) + call s:LOGGER.info(' > type: ' . get(a:000, 0, 'alternate')) + call s:LOGGER.info(' > paser: ' . a:request_paser) + call s:LOGGER.info(' > config: ' . a:conf_path) + " @question when should the cache be loaded? + " if the local value s:project_config do not has the key a:conf_path + " and the file a:conf_path has not been updated since last cache + " and no request_paser specified + let alt_config_json = s:get_project_config(a:conf_path) + if !has_key(s:project_config, alt_config_json.root) + \ && !s:is_config_changed(a:conf_path) + \ && !a:request_paser + " config file has been cached since last update. + " so no need to paser the config for current config file + " just load the cache + call s:load_cache() + if !has_key(s:project_config, alt_config_json.root) + \ || !has_key(s:project_config[alt_config_json.root], a:file) + call s:paser(alt_config_json) + endif + else + call s:paser(alt_config_json) endif try - return s:project_config[a:conf_path][a:file][get(a:000, 0, 'alternate')] + return s:project_config[alt_config_json.root][a:file][get(a:000, 0, 'alternate')] catch return '' endtry endfunction +function! s:get_alternate(file) abort -function! SpaceVim#plugins#a#get_root() abort - return s:FILE.unify_path(s:conf, ':p') +endfunction + + +function! SpaceVim#plugins#a#getConfigPath() abort + return s:FILE.unify_path(get(s:alternate_conf, getcwd(), '_'), ':p') endfunction function! SpaceVim#plugins#a#complete(ArgLead, CmdLine, CursorPos) abort let file = s:FILE.unify_path(bufname('%'), ':.') - let conf = s:FILE.unify_path(s:conf, ':p') + let conf_file_path = s:FILE.unify_path(get(s:alternate_conf, getcwd(), '_'), ':p') + let alt_config_json = s:get_project_config(conf_file_path) - if !has_key(s:project_config, conf ) - let altconfa = s:get_project_config(conf) - let s:project_config[conf] = {} - call s:paser(altconfa, conf) - endif + call SpaceVim#plugins#a#get_alt(file, conf_file_path, 0) try - let a = s:project_config[s:FILE.unify_path(s:conf, ':p')][file] + let a = s:project_config[alt_config_json.root][file] catch let a = {} endtry diff --git a/autoload/SpaceVim/plugins/flygrep.vim b/autoload/SpaceVim/plugins/flygrep.vim index 54b13cdcf..2328343c2 100644 --- a/autoload/SpaceVim/plugins/flygrep.vim +++ b/autoload/SpaceVim/plugins/flygrep.vim @@ -14,7 +14,7 @@ let s:SYS = SpaceVim#api#import('system') let s:BUFFER = SpaceVim#api#import('vim#buffer') let s:LIST = SpaceVim#api#import('data#list') -let s:LOGGER =SpaceVim#logger#derive('flygrep ') +let s:LOGGER =SpaceVim#logger#derive('FlyGrep') let s:HI = SpaceVim#api#import('vim#highlight') if has('nvim') let s:FLOATING = SpaceVim#api#import('neovim#floating') @@ -88,7 +88,7 @@ function! s:grep_timer(timer) abort \ }) " sometimes the flygrep command failed to run, so we need to log the jobid " of the grep command. - call SpaceVim#logger#info('flygrep job id is: ' . string(s:grepid)) + call s:LOGGER.info('flygrep job id is: ' . string(s:grepid)) endfunction function! s:get_search_cmd(expr) abort @@ -833,22 +833,22 @@ function! SpaceVim#plugins#flygrep#open(argv) abort let s:grep_ignore_case = get(a:argv, 'ignore_case', s:grep_default_ignore_case) let s:grep_smart_case = get(a:argv, 'smart_case', s:grep_default_smart_case) let s:grep_expr_opt = get(a:argv, 'expr_opt', s:grep_default_expr_opt) - call SpaceVim#logger#info('FlyGrep startting ===========================') - call SpaceVim#logger#info(' executable : ' . s:grep_exe) - call SpaceVim#logger#info(' option : ' . string(s:grep_opt)) - call SpaceVim#logger#info(' r_option : ' . string(s:grep_ropt)) - call SpaceVim#logger#info(' files : ' . string(s:grep_files)) - call SpaceVim#logger#info(' dir : ' . string(s:grep_dir)) - call SpaceVim#logger#info(' ignore_case : ' . string(s:grep_ignore_case)) - call SpaceVim#logger#info(' smart_case : ' . string(s:grep_smart_case)) - call SpaceVim#logger#info(' expr opt : ' . string(s:grep_expr_opt)) + call s:LOGGER.info('FlyGrep startting ===========================') + call s:LOGGER.info(' executable : ' . s:grep_exe) + call s:LOGGER.info(' option : ' . string(s:grep_opt)) + call s:LOGGER.info(' r_option : ' . string(s:grep_ropt)) + call s:LOGGER.info(' files : ' . string(s:grep_files)) + call s:LOGGER.info(' dir : ' . string(s:grep_dir)) + call s:LOGGER.info(' ignore_case : ' . string(s:grep_ignore_case)) + call s:LOGGER.info(' smart_case : ' . string(s:grep_smart_case)) + call s:LOGGER.info(' expr opt : ' . string(s:grep_expr_opt)) " sometimes user can not see the flygrep windows, redraw only once. redraw call s:MPT.open() if s:SL.support_float() call s:close_statusline() endif - call SpaceVim#logger#info('FlyGrep ending ===========================') + call s:LOGGER.info('FlyGrep ending ===========================') let &t_ve = save_tve if has('gui_running') call s:HI.hi(cursor_hi) diff --git a/config/commands.vim b/config/commands.vim deleted file mode 100644 index 943ac7b7d..000000000 --- a/config/commands.vim +++ /dev/null @@ -1,12 +0,0 @@ -" Convenient command to see the difference between the current buffer and the -" file it was loaded from, thus the changes you made. Only define it when not -" defined already. -command! DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis - \ | wincmd p | diffthis -command! -nargs=* -complete=custom,SpaceVim#plugins#complete_plugs Plugin :call SpaceVim#plugins#Plugin() -"command for open project -command! -nargs=+ -complete=custom,SpaceVim#plugins#projectmanager#complete_project OpenProject :call SpaceVim#plugins#projectmanager#OpenProject() - -command! -nargs=* -complete=custom,SpaceVim#plugins#pmd#complete PMD :call SpaceVim#plugins#pmd#run() - -command! -nargs=? -complete=custom,SpaceVim#plugins#a#complete -bang A :call SpaceVim#plugins#a#alt(0,) diff --git a/doc/SpaceVim.txt b/doc/SpaceVim.txt index c682e1e9d..45c890ca4 100644 --- a/doc/SpaceVim.txt +++ b/doc/SpaceVim.txt @@ -1258,6 +1258,9 @@ COMMANDS *SpaceVim-commands* :SPInstall *:SPInstall* Command for install plugins. +:A[!] {type} *:A* + Switch to alternate file based on {type}. + ============================================================================== FUNCTIONS *SpaceVim-functions* diff --git a/docs/api/cmdlinemenu.md b/docs/api/cmdlinemenu.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/cn/api/cmdlinemenu.md b/docs/cn/api/cmdlinemenu.md new file mode 100644 index 000000000..d8dfbb0c8 --- /dev/null +++ b/docs/cn/api/cmdlinemenu.md @@ -0,0 +1,20 @@ +--- +title: "cmdlinemenu 函数" +description: "cmdlinemenu 函数提供了基础的文件读写相关函数,兼容不同系统平台。" +lang: zh +--- + +# [公共 API](../) >> cmdlinemenu + + + + +- [简介](#简介) + + + +## 简介 + +文件函数提供了基础的文件读写相关函数,兼容不同系统平台。 + + diff --git a/test/plugin/a.vader b/test/plugin/a.vader index d98c24019..fb62bd5cc 100644 --- a/test/plugin/a.vader +++ b/test/plugin/a.vader @@ -1,6 +1,6 @@ Execute ( SpaceVim plugin: a.vim ): - call SpaceVim#plugins#a#set_config_name('.projections.json') - let root = SpaceVim#plugins#a#get_root() + call SpaceVim#plugins#a#set_config_name(getcwd(), '.projections.json') + let root = SpaceVim#plugins#a#getConfigPath() AssertEqual SpaceVim#plugins#a#get_alt('docs/index.md', root, 1), 'docs/cn/index.md' AssertEqual SpaceVim#plugins#a#get_alt('docs/cn/index.md', root, 1), 'docs/index.md' AssertEqual SpaceVim#plugins#a#get_alt('docs/api/job.md', root, 1), 'docs/cn/api/job.md'