From f14f0f7cb62855844fcdac60911c279813d3cd05 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 00:31:25 +0900 Subject: Testable --- autoload/lsp_settings.vim | 298 +++++++++++++++++++++++++++++++++++--- autoload/lsp_settings/utils.vim | 27 ++++ plugin/lsp_settings.vim | 310 +--------------------------------------- 3 files changed, 305 insertions(+), 330 deletions(-) create mode 100644 autoload/lsp_settings/utils.vim diff --git a/autoload/lsp_settings.vim b/autoload/lsp_settings.vim index 0e11c0a..429aa5a 100644 --- a/autoload/lsp_settings.vim +++ b/autoload/lsp_settings.vim @@ -1,7 +1,81 @@ +let s:settings_dir = expand(':h:h').'/settings' +let s:checkers_dir = expand(':h:h').'/checkers' let s:servers_dir = expand(':h:h').'/servers' let s:installer_dir = expand(':h:h').'/installer' let s:root_dir = expand(':h:h') +let s:settings = json_decode(join(readfile(expand(':h:h') . '/settings.json'), "\n")) +call remove(s:settings, '$schema') + +let s:ftmap = {} + +function! s:executable(cmd) abort + if executable(a:cmd) + return 1 + endif + let l:paths = get(g:, 'lsp_settings_extra_paths', '') + if type(l:paths) == type([]) + let l:paths = join(l:paths, ',') + endif + let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) + let l:paths .= ',' . l:servers_dir . '/' . a:cmd + if !has('win32') + let l:found = globpath(l:paths, a:cmd) + return !empty(l:found) + endif + for l:ext in ['.exe', '.cmd', '.bat'] + if !empty(globpath(l:paths, a:cmd . l:ext)) + return 1 + endif + endfor + return 0 +endfunction + +function! s:vim_lsp_installer(ft, ...) abort + let l:ft = tolower(get(split(a:ft, '\.'), 0, '')) + let l:ft = empty(l:ft) ? '_' : l:ft + if !has_key(s:settings, l:ft) + return [] + endif + let l:server = s:settings[l:ft] + if empty(l:server) + return [] + endif + let l:found = {} + for l:conf in l:server + let l:missing = 0 + for l:require in l:conf.requires + if !s:executable(l:require) + let l:missing = 1 + break + endif + endfor + if l:missing ==# 0 + let l:found = l:conf + break + endif + endfor + if empty(l:found) + return [] + endif + let l:name = get(a:000, 0, '') + for l:conf in l:server + if !empty(l:name) && l:conf.command != l:name + continue + endif + let l:command = printf('%s/install-%s', s:installer_dir, l:conf.command) + if has('win32') + let l:command = substitute(l:command, '/', '\', 'g') . '.cmd' + else + let l:command = l:command . '.sh' + endif + if s:executable(l:command) + return [l:conf.command, l:command] + endif + endfor + return [] +endfunction + function! lsp_settings#get(name, key, default) abort let l:config = get(g:, 'lsp_settings', {}) if !has_key(l:config, a:name) @@ -24,13 +98,6 @@ function! lsp_settings#get(name, key, default) abort return l:config[a:key] endfunction -function! s:first_one(cmd) abort - if empty(a:cmd) - return '' - endif - return fnamemodify(split(a:cmd, "\n")[0], ':p') -endfunction - function! lsp_settings#exec_path(cmd) abort let l:paths = [] if has('win32') @@ -48,13 +115,13 @@ function! lsp_settings#exec_path(cmd) abort let l:path = globpath(l:paths, a:cmd) if !has('win32') if !empty(l:path) - return s:first_one(l:path) + return lsp_settings#utils#first_one(l:path) endif else for l:ext in ['.exe', '.cmd', '.bat'] let l:path = globpath(l:paths, a:cmd . l:ext) if !empty(l:path) - return s:first_one(l:path) + return lsp_settings#utils#first_one(l:path) endif endfor endif @@ -66,12 +133,12 @@ function! lsp_settings#exec_path(cmd) abort let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) let l:paths .= l:servers_dir . '/' . a:cmd if !has('win32') - return s:first_one(globpath(l:paths, a:cmd)) + return lsp_settings#utils#first_one(globpath(l:paths, a:cmd)) endif for l:ext in ['.exe', '.cmd', '.bat'] let l:path = globpath(l:paths, a:cmd . l:ext) if !empty(l:path) - return s:first_one(l:path) + return lsp_settings#utils#first_one(l:path) endif endfor return '' @@ -101,13 +168,10 @@ function! lsp_settings#autocd(server_info) abort endfunction function! lsp_settings#complete_uninstall(arglead, cmdline, cursorpos) abort - let l:settings = json_decode(join(readfile(s:root_dir . '/settings.json'), "\n")) - call remove(l:settings, '$schema') - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) let l:installers = [] - for l:ft in keys(l:settings) - for l:conf in l:settings[l:ft] + for l:ft in keys(s:settings) + for l:conf in s:settings[l:ft] if !isdirectory(l:servers_dir . '/' . l:conf.command) continue endif @@ -118,15 +182,12 @@ function! lsp_settings#complete_uninstall(arglead, cmdline, cursorpos) abort endfunction function! lsp_settings#complete_install(arglead, cmdline, cursorpos) abort - let l:settings = json_decode(join(readfile(s:root_dir . '/settings.json'), "\n")) - call remove(l:settings, '$schema') - let l:ft = tolower(get(split(&filetype, '\.'), 0, '')) let l:ft = empty(l:ft) ? '_' : l:ft - if !has_key(l:settings, l:ft) + if !has_key(s:settings, l:ft) return [] endif - let l:server = l:settings[l:ft] + let l:server = s:settings[l:ft] if empty(l:server) return [] endif @@ -154,3 +215,198 @@ function! lsp_settings#complete_install(arglead, cmdline, cursorpos) abort endfor return filter(uniq(l:installers), 'stridx(v:val, a:arglead) == 0') endfunction + +function! s:vim_lsp_uninstall_server(command) abort + if !lsp_settings#utils#valid_name(a:command) + call lsp_settings#utils#error('Invalid server name') + return + endif + call lsp_settings#utils#msg('Uninstalling ' . a:command) + let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) + let l:server_install_dir = l:servers_dir . '/' . a:command + if !isdirectory(l:server_install_dir) + call lsp_settings#utils#error('Server not found') + return + endif + call delete(l:server_install_dir, 'rf') + call lsp_settings#utils#msg('Uninstalled ' . a:command) +endfunction + +" neovim passes third argument as 'exit' while vim passes only 2 arguments +function! s:vim_lsp_install_server_post(command, job, code, ...) abort + if a:code != 0 + return + endif + if s:executable(a:command) + let l:script = printf('%s/%s.vim', s:settings_dir, a:command) + if filereadable(l:script) + if has('patch-8.1.1113') + command! -nargs=1 LspRegisterServer autocmd User lsp_setup ++once call lsp#register_server() + else + command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server() + endif + exe 'source' l:script + delcommand LspRegisterServer + doautocmd User lsp_setup + endif + endif + call lsp_settings#utils#msg('Installed ' . a:command) +endfunction + +function! s:vim_lsp_install_server(ft, command) abort + if !empty(a:command) && !lsp_settings#utils#valid_name(a:command) + call lsp_settings#utils#error('Invalid server name') + return + endif + let l:entry = s:vim_lsp_installer(a:ft, a:command) + if empty(l:entry) + call lsp_settings#utils#error('Server not found') + return + endif + let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) + let l:server_install_dir = l:servers_dir . '/' . l:entry[0] + if isdirectory(l:server_install_dir) + call delete(l:server_install_dir, 'rf') + endif + call mkdir(l:server_install_dir, 'p') + call lsp_settings#utils#msg('Installing ' . l:entry[0]) + if has('nvim') + split new + call termopen(l:entry[1], {'cwd': l:server_install_dir, 'on_exit': function('s:vim_lsp_install_server_post', [l:entry[0]])}) | startinsert + else + let l:bufnr = term_start(l:entry[1], {'cwd': l:server_install_dir}) + let l:job = term_getjob(l:bufnr) + if l:job != v:null + call job_setoptions(l:job, {'exit_cb': function('s:vim_lsp_install_server_post', [l:entry[0]])}) + endif + endif +endfunction + +function! s:vim_lsp_settings_suggest(ft) abort + let l:entry = s:vim_lsp_installer(a:ft) + if empty(l:entry) + return + endif + if exists(':LspInstallServer') !=# 2 + redraw! + echohl Directory + echomsg 'Please do :LspInstallServer to enable Language Server ' . l:entry[0] + echohl None + command! -nargs=? -buffer -complete=customlist,lsp_settings#complete_install LspInstallServer call s:vim_lsp_install_server(&l:filetype, ) + endif +endfunction + +function! s:vim_lsp_suggest_plugin() abort + if &ft != '' + return + endif + let l:ext = expand('%:e') + for l:ft in keys(s:settings) + for l:server in s:settings[l:ft] + if !has_key(l:server, 'vim-plugin') + continue + endif + if index(l:server['vim-plugin']['extensions'], l:ext) == -1 + continue + endif + redraw + echohl Directory + echomsg printf('Please install vim-plugin "%s" to enable Language Server', l:server['vim-plugin']['name']) + echohl None + return + endfor + endfor +endfunction + +function! s:vim_lsp_load_or_suggest(ft) abort + if get(s:ftmap, a:ft, 0) + return + endif + let l:group_name = lsp_settings#utils#group_name(a:ft) + exe 'augroup' l:group_name + autocmd! + augroup END + exe 'augroup!' l:group_name + + if has('patch-8.1.1113') + command! -nargs=1 LspRegisterServer autocmd User lsp_setup ++once call lsp#register_server() + else + command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server() + endif + + let l:found = 0 + let l:disabled = 0 + + for l:server in s:settings[a:ft] + if lsp_settings#get(l:server.command, 'disabled', get(l:server, 'disabled', 0)) + let l:disabled += 1 + continue + endif + let l:default = get(g:, 'lsp_settings_' . a:ft, '') + if !empty(l:default) && l:default != l:server.command + continue + endif + let l:command = lsp_settings#get(l:server.command, 'cmd', l:server.command) + if type(l:command) == type([]) + let l:command = l:command[0] + endif + if !s:executable(l:command) + let l:script = printf('%s/%s.vim', s:checkers_dir, l:server.command) + if !filereadable(l:script) || has_key(l:server, 'fallback') + continue + endif + let l:server['fallback'] = '' + try + exe 'source' l:script + let l:command = LspCheckCommand() + let l:server['fallback'] = l:command + catch + finally + if exists('*LspCheckCommand') + delfunction LspCheckCommand + endif + if empty(l:server['fallback']) + continue + endif + endtry + endif + let l:script = printf('%s/%s.vim', s:settings_dir, l:server.command) + if filereadable(l:script) + exe 'source' l:script + let l:found += 1 + let s:ftmap[a:ft] = 1 + break + endif + endfor + + if l:disabled == 0 && l:found ==# 0 + call s:vim_lsp_settings_suggest(a:ft) + else + doautocmd User lsp_setup + if exists(':LspInstallServer') !=# 2 + command! -nargs=? -buffer -complete=customlist,lsp_settings#complete_install LspInstallServer call s:vim_lsp_install_server(&l:filetype, ) + endif + endif + + if exists(':LspRegisterServer') !=# 2 + delcommand LspRegisterServer + endif +endfunction + +function! lsp_settings#init() abort + for l:ft in keys(s:settings) + if has_key(g:, 'lsp_settings_whitelist') && index(g:lsp_settings_whitelist, l:ft) == -1 || empty(s:settings[l:ft]) + continue + endif + exe 'augroup' lsp_settings#utils#group_name(l:ft) + autocmd! + exe 'autocmd FileType' l:ft 'call s:vim_lsp_load_or_suggest(' string(l:ft) ')' + augroup END + endfor + augroup vim_lsp_suggest + autocmd! + autocmd BufNewFile,BufRead * call s:vim_lsp_suggest_plugin() + autocmd VimEnter * call s:vim_lsp_load_or_suggest('_') + augroup END + command! -nargs=? -complete=customlist,lsp_settings#complete_uninstall LspUninstallServer call s:vim_lsp_uninstall_server() +endfunction diff --git a/autoload/lsp_settings/utils.vim b/autoload/lsp_settings/utils.vim new file mode 100644 index 0000000..940acb1 --- /dev/null +++ b/autoload/lsp_settings/utils.vim @@ -0,0 +1,27 @@ +function! lsp_settings#utils#msg(msg) abort + redraw + echohl Comment + echo a:msg + echohl None +endfunction + +function! lsp_settings#utils#error(msg) abort + echohl Error + echomsg a:msg + echohl None +endfunction + +function! lsp_settings#utils#valid_name(command) abort + return a:command =~# '^[a-zA-Z0-9_-]\+$' +endfunction + +function! lsp_settings#utils#group_name(ft) abort + return printf('vim_lsp_suggest_%s', a:ft) +endfunction + +function! lsp_settings#utils#first_one(cmd) abort + if empty(a:cmd) + return '' + endif + return fnamemodify(split(a:cmd, "\n")[0], ':p') +endfunction diff --git a/plugin/lsp_settings.vim b/plugin/lsp_settings.vim index e5936e0..7b89ee0 100644 --- a/plugin/lsp_settings.vim +++ b/plugin/lsp_settings.vim @@ -10,312 +10,4 @@ let g:lsp_settings_root_markers = get(g:, 'lsp_settings_root_markers', [ \ '.bzr/' \ ]) -let s:settings_dir = expand(':h:h').'/settings' -let s:checkers_dir = expand(':h:h').'/checkers' -let s:installer_dir = expand(':h:h').'/installer' -let s:servers_dir = expand(':h:h').'/servers' -let s:settings = json_decode(join(readfile(expand(':h:h') . '/settings.json'), "\n")) -let s:ftmap = {} - -call remove(s:settings, '$schema') - -function! s:executable(cmd) abort - if executable(a:cmd) - return 1 - endif - let l:paths = get(g:, 'lsp_settings_extra_paths', '') - if type(l:paths) == type([]) - let l:paths = join(l:paths, ',') - endif - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) - let l:paths .= ',' . l:servers_dir . '/' . a:cmd - if !has('win32') - let l:found = globpath(l:paths, a:cmd) - return !empty(l:found) - endif - for l:ext in ['.exe', '.cmd', '.bat'] - if !empty(globpath(l:paths, a:cmd . l:ext)) - return 1 - endif - endfor - return 0 -endfunction - -function! s:vim_lsp_installer(ft, ...) abort - let l:ft = tolower(get(split(a:ft, '\.'), 0, '')) - let l:ft = empty(l:ft) ? '_' : l:ft - if !has_key(s:settings, l:ft) - return [] - endif - let l:server = s:settings[l:ft] - if empty(l:server) - return [] - endif - let l:found = {} - for l:conf in l:server - let l:missing = 0 - for l:require in l:conf.requires - if !s:executable(l:require) - let l:missing = 1 - break - endif - endfor - if l:missing ==# 0 - let l:found = l:conf - break - endif - endfor - if empty(l:found) - return [] - endif - let l:name = get(a:000, 0, '') - for l:conf in l:server - if !empty(l:name) && l:conf.command != l:name - continue - endif - let l:command = printf('%s/install-%s', s:installer_dir, l:conf.command) - if has('win32') - let l:command = substitute(l:command, '/', '\', 'g') . '.cmd' - else - let l:command = l:command . '.sh' - endif - if s:executable(l:command) - return [l:conf.command, l:command] - endif - endfor - return [] -endfunction - -function! s:msg(msg) abort - redraw - echohl Comment - echo a:msg - echohl None -endfunction - -function! s:error(msg) abort - echohl Error - echomsg a:msg - echohl None -endfunction - -function! s:valid_name(command) abort - return a:command =~# '^[a-zA-Z0-9_-]\+$' -endfunction - -function! s:vim_lsp_uninstall_server(command) abort - if !s:valid_name(a:command) - call s:error('invalid server name') - return - endif - call s:msg('Uninstalling ' . a:command) - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) - let l:server_install_dir = l:servers_dir . '/' . a:command - if !isdirectory(l:server_install_dir) - call s:error('server not found') - return - endif - call delete(l:server_install_dir, 'rf') - call s:msg('Uninstalled ' . a:command) -endfunction - -" neovim passes third argument as 'exit' while vim passes only 2 arguments -function! s:vim_lsp_install_server_post(command, job, code, ...) abort - if a:code != 0 - return - endif - if s:executable(a:command) - let l:script = printf('%s/%s.vim', s:settings_dir, a:command) - if filereadable(l:script) - if has('patch-8.1.1113') - command! -nargs=1 LspRegisterServer autocmd User lsp_setup ++once call lsp#register_server() - else - command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server() - endif - exe 'source' l:script - delcommand LspRegisterServer - doautocmd User lsp_setup - endif - endif - call s:msg('Installed ' . a:command) -endfunction - -function! s:vim_lsp_install_server(ft, command) abort - if !empty(a:command) && !s:valid_name(a:command) - call s:error('invalid server name') - return - endif - let l:entry = s:vim_lsp_installer(a:ft, a:command) - if empty(l:entry) - call s:error('server not found') - return - endif - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) - let l:server_install_dir = l:servers_dir . '/' . l:entry[0] - if isdirectory(l:server_install_dir) - call delete(l:server_install_dir, 'rf') - endif - call mkdir(l:server_install_dir, 'p') - call s:msg('Installing ' . l:entry[0]) - if has('nvim') - split new - call termopen(l:entry[1], {'cwd': l:server_install_dir, 'on_exit': function('s:vim_lsp_install_server_post', [l:entry[0]])}) | startinsert - else - let l:bufnr = term_start(l:entry[1], {'cwd': l:server_install_dir}) - let l:job = term_getjob(l:bufnr) - if l:job != v:null - call job_setoptions(l:job, {'exit_cb': function('s:vim_lsp_install_server_post', [l:entry[0]])}) - endif - endif -endfunction - -function! s:vim_lsp_settings_suggest(ft) abort - let l:entry = s:vim_lsp_installer(a:ft) - if empty(l:entry) - return - endif - if exists(':LspInstallServer') !=# 2 - redraw! - echohl Directory - echomsg 'Please do :LspInstallServer to enable Language Server ' . l:entry[0] - echohl None - command! -nargs=? -buffer -complete=customlist,lsp_settings#complete_install LspInstallServer call s:vim_lsp_install_server(&l:filetype, ) - endif -endfunction - -function! s:vim_lsp_settings_get(name, key, default) abort - let l:config = get(g:, 'lsp_settings', {}) - if !has_key(l:config, a:name) - if !has_key(l:config, '*') - return a:default - endif - let l:config = l:config['*'] - else - let l:config = l:config[a:name] - endif - if !has_key(l:config, a:key) - return a:default - endif - return l:config[a:key] -endfunction - -function! s:vim_lsp_settings() abort - for l:ft in keys(s:settings) - if has_key(g:, 'lsp_settings_whitelist') && index(g:lsp_settings_whitelist, l:ft) == -1 || empty(s:settings[l:ft]) - continue - endif - exe 'augroup' s:load_or_suggest_group_name(l:ft) - autocmd! - exe 'autocmd FileType' l:ft 'call s:vim_lsp_load_or_suggest(' string(l:ft) ')' - augroup END - endfor - augroup vim_lsp_suggest - autocmd! - autocmd BufNewFile,BufRead * call s:vim_lsp_suggest_plugin() - autocmd VimEnter * call s:vim_lsp_load_or_suggest('_') - augroup END - command! -nargs=? -complete=customlist,lsp_settings#complete_uninstall LspUninstallServer call s:vim_lsp_uninstall_server() -endfunction - -function! s:vim_lsp_suggest_plugin() abort - if &ft != '' - return - endif - let l:ext = expand('%:e') - for l:ft in keys(s:settings) - for l:server in s:settings[l:ft] - if !has_key(l:server, 'vim-plugin') - continue - endif - if index(l:server['vim-plugin']['extensions'], l:ext) == -1 - continue - endif - redraw - echohl Directory - echomsg printf('Please install vim-plugin "%s" to enable Language Server', l:server['vim-plugin']['name']) - echohl None - return - endfor - endfor -endfunction - -function! s:vim_lsp_load_or_suggest(ft) abort - if get(s:ftmap, a:ft, 0) - return - endif - let l:group_name = s:load_or_suggest_group_name(a:ft) - exe 'augroup' l:group_name - autocmd! - augroup END - exe 'augroup!' l:group_name - - if has('patch-8.1.1113') - command! -nargs=1 LspRegisterServer autocmd User lsp_setup ++once call lsp#register_server() - else - command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server() - endif - - let l:found = 0 - let l:disabled = 0 - - for l:server in s:settings[a:ft] - if s:vim_lsp_settings_get(l:server.command, 'disabled', get(l:server, 'disabled', 0)) - let l:disabled += 1 - continue - endif - let l:default = get(g:, 'lsp_settings_' . a:ft, '') - if !empty(l:default) && l:default != l:server.command - continue - endif - let l:command = s:vim_lsp_settings_get(l:server.command, 'cmd', l:server.command) - if type(l:command) == type([]) - let l:command = l:command[0] - endif - if !s:executable(l:command) - let l:script = printf('%s/%s.vim', s:checkers_dir, l:server.command) - if !filereadable(l:script) || has_key(l:server, 'fallback') - continue - endif - let l:server['fallback'] = '' - try - exe 'source' l:script - let l:command = LspCheckCommand() - let l:server['fallback'] = l:command - catch - finally - if exists('*LspCheckCommand') - delfunction LspCheckCommand - endif - if empty(l:server['fallback']) - continue - endif - endtry - endif - let l:script = printf('%s/%s.vim', s:settings_dir, l:server.command) - if filereadable(l:script) - exe 'source' l:script - let l:found += 1 - let s:ftmap[a:ft] = 1 - break - endif - endfor - - if l:disabled == 0 && l:found ==# 0 - call s:vim_lsp_settings_suggest(a:ft) - else - doautocmd User lsp_setup - if exists(':LspInstallServer') !=# 2 - command! -nargs=? -buffer -complete=customlist,lsp_settings#complete_install LspInstallServer call s:vim_lsp_install_server(&l:filetype, ) - endif - endif - - if exists(':LspRegisterServer') !=# 2 - delcommand LspRegisterServer - endif -endfunction - -function! s:load_or_suggest_group_name(ft) abort - return printf('vim_lsp_suggest_%s', a:ft) -endfunction - -call s:vim_lsp_settings() +call lsp_settings#init() -- cgit v1.2.3-54-g00ecf From 61dccb88b0d0fd1df2ee3778a7c96210689e8c59 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 00:45:13 +0900 Subject: Add tests --- .github/workflows/linux_vim.yml | 46 +++++++++++++++++++++++++++++++++++++++++ autoload/lsp_settings/utils.vim | 7 ++++--- test/.themisrc | 3 +++ test/lsp_settings/utils.vimspec | 43 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/linux_vim.yml create mode 100644 test/.themisrc create mode 100644 test/lsp_settings/utils.vimspec diff --git a/.github/workflows/linux_vim.yml b/.github/workflows/linux_vim.yml new file mode 100644 index 0000000..8b0f4f2 --- /dev/null +++ b/.github/workflows/linux_vim.yml @@ -0,0 +1,46 @@ +name: linux_vim + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + name: [vim-v82-x64, vim-v81-x64] + include: + - name: vim-v82-x64 + os: ubuntu-latest + vim_version: 8.2.0037 + glibc_version: 2.15 + - name: vim-v81-x64 + os: ubuntu-latest + vim_version: 8.1.2414 + glibc_version: 2.15 + runs-on: ${{matrix.os}} + steps: + - uses: actions/checkout@v1 + - name: Download vim + shell: bash + run: | + mkdir -p ~/vim/bin + curl -L https://github.com/vim/vim-appimage/releases/download/v${{matrix.vim_version}}/GVim-v${{matrix.vim_version}}.glibc${{matrix.glibc_version}}-x86_64.AppImage -o ~/vim/bin/vim + chmod u+x ~/vim/bin/vim + - name: Download test runner + shell: bash + run: git clone --depth 1 --branch v1.5.4 --single-branch https://github.com/thinca/vim-themis ~/themis + - name: Run tests + shell: bash + run: | + export PATH=~/vim/bin:$PATH + export PATH=~/themis/bin:$PATH + export THEMIS_VIM=vim + vim --version + themis --reporter spec diff --git a/autoload/lsp_settings/utils.vim b/autoload/lsp_settings/utils.vim index 940acb1..d342388 100644 --- a/autoload/lsp_settings/utils.vim +++ b/autoload/lsp_settings/utils.vim @@ -6,6 +6,7 @@ function! lsp_settings#utils#msg(msg) abort endfunction function! lsp_settings#utils#error(msg) abort + redraw echohl Error echomsg a:msg echohl None @@ -19,9 +20,9 @@ function! lsp_settings#utils#group_name(ft) abort return printf('vim_lsp_suggest_%s', a:ft) endfunction -function! lsp_settings#utils#first_one(cmd) abort - if empty(a:cmd) +function! lsp_settings#utils#first_one(lines) abort + if empty(a:lines) return '' endif - return fnamemodify(split(a:cmd, "\n")[0], ':p') + return fnamemodify(split(a:lines, "\n")[0], ':p') endfunction diff --git a/test/.themisrc b/test/.themisrc new file mode 100644 index 0000000..d73cbf9 --- /dev/null +++ b/test/.themisrc @@ -0,0 +1,3 @@ +set encoding=utf-8 +call themis#option('recursive', 1) +call themis#helper('command').with(themis#helper('assert')) diff --git a/test/lsp_settings/utils.vimspec b/test/lsp_settings/utils.vimspec new file mode 100644 index 0000000..ee94ccc --- /dev/null +++ b/test/lsp_settings/utils.vimspec @@ -0,0 +1,43 @@ +Describe lsp_settings#utils + Describe lsp_settings#utils#first_one + It should return first item in lines + Assert Equals(lsp_settings#utils#first_one("\nfoo"), fnamemodify('foo', ':p')) + Assert Equals(lsp_settings#utils#first_one('foo'), fnamemodify('foo', ':p')) + Assert Equals(lsp_settings#utils#first_one("foo\nbar\n"), fnamemodify('foo', ':p')) + End + End + + Describe lsp_settings#utils#group_name + It should return autocmd group name + Assert Equals(lsp_settings#utils#group_name('foo'), 'vim_lsp_suggest_foo') + End + End + + Describe lsp_settings#utils#valid_name + It should return whether the command is valid + Assert Equals(lsp_settings#utils#valid_name('foo'), 1) + Assert Equals(lsp_settings#utils#valid_name('foo bar'), 0) + Assert Equals(lsp_settings#utils#valid_name(' foo'), 0) + Assert Equals(lsp_settings#utils#valid_name(' foo '), 0) + Assert Equals(lsp_settings#utils#valid_name('foo '), 0) + Assert Equals(lsp_settings#utils#valid_name('foo-bar'), 1) + Assert Equals(lsp_settings#utils#valid_name('foo_bar'), 1) + Assert Equals(lsp_settings#utils#valid_name('foo&bar'), 0) + Assert Equals(lsp_settings#utils#valid_name('foo#bar'), 0) + End + End + + Describe lsp_settings#utils#msg + It should display information + Assert Equals(execute("call lsp_settings#utils#msg('foo')"), "\nfoo") + Assert Equals(execute("call lsp_settings#utils#msg('foo')"), "\nfoo") + End + End + + Describe lsp_settings#utils#error + It should display information + Assert Equals(execute("call lsp_settings#utils#error('foo')"), "\nfoo") + Assert Equals(execute("call lsp_settings#utils#error('foo')"), "\nfoo") + End + End +End -- cgit v1.2.3-54-g00ecf From 3fa9d50e0e3cf5c4b34eef7ce9ea20a52d82e572 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 00:52:30 +0900 Subject: Add test --- test/lsp_settings.vimspec | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 test/lsp_settings.vimspec diff --git a/test/lsp_settings.vimspec b/test/lsp_settings.vimspec new file mode 100644 index 0000000..743f951 --- /dev/null +++ b/test/lsp_settings.vimspec @@ -0,0 +1,14 @@ +Describe lsp_settings + Describe lsp_settings#get + It should return configuration value from key and name + Assert Equals(lsp_settings#get('pyls', 'cmd', 'bad'), 'bad') + let g:lsp_settings = {'pyls': {'cmd': 'good'}} + Assert Equals(lsp_settings#get('pyls', 'cmd', 'bad'), 'good') + unlet g:lsp_settings + End + + It should return default value with lambda + Assert Equals(lsp_settings#get('pyls', 'cmd', {key, name-> 'good'}), 'good') + End + End +End -- cgit v1.2.3-54-g00ecf From ef182997b0e6793cc2517cc9fed0fe15c0ea5df0 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 01:33:17 +0900 Subject: Add test --- autoload/lsp_settings.vim | 18 +++++++++--------- test/lsp_settings.vimspec | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/autoload/lsp_settings.vim b/autoload/lsp_settings.vim index 429aa5a..1f0717a 100644 --- a/autoload/lsp_settings.vim +++ b/autoload/lsp_settings.vim @@ -1,7 +1,7 @@ -let s:settings_dir = expand(':h:h').'/settings' -let s:checkers_dir = expand(':h:h').'/checkers' -let s:servers_dir = expand(':h:h').'/servers' -let s:installer_dir = expand(':h:h').'/installer' +let s:settings_dir = expand(':h:h') . '/settings' +let s:checkers_dir = expand(':h:h') . '/checkers' +let s:servers_dir = expand(':h:h') . '/servers' +let s:installer_dir = expand(':h:h') . '/installer' let s:root_dir = expand(':h:h') let s:settings = json_decode(join(readfile(expand(':h:h') . '/settings.json'), "\n")) @@ -9,7 +9,7 @@ call remove(s:settings, '$schema') let s:ftmap = {} -function! s:executable(cmd) abort +function! lsp_settings#executable(cmd) abort if executable(a:cmd) return 1 endif @@ -45,7 +45,7 @@ function! s:vim_lsp_installer(ft, ...) abort for l:conf in l:server let l:missing = 0 for l:require in l:conf.requires - if !s:executable(l:require) + if !lsp_settings#executable(l:require) let l:missing = 1 break endif @@ -69,7 +69,7 @@ function! s:vim_lsp_installer(ft, ...) abort else let l:command = l:command . '.sh' endif - if s:executable(l:command) + if lsp_settings#executable(l:command) return [l:conf.command, l:command] endif endfor @@ -237,7 +237,7 @@ function! s:vim_lsp_install_server_post(command, job, code, ...) abort if a:code != 0 return endif - if s:executable(a:command) + if lsp_settings#executable(a:command) let l:script = printf('%s/%s.vim', s:settings_dir, a:command) if filereadable(l:script) if has('patch-8.1.1113') @@ -350,7 +350,7 @@ function! s:vim_lsp_load_or_suggest(ft) abort if type(l:command) == type([]) let l:command = l:command[0] endif - if !s:executable(l:command) + if !lsp_settings#executable(l:command) let l:script = printf('%s/%s.vim', s:checkers_dir, l:server.command) if !filereadable(l:script) || has_key(l:server, 'fallback') continue diff --git a/test/lsp_settings.vimspec b/test/lsp_settings.vimspec index 743f951..3b34941 100644 --- a/test/lsp_settings.vimspec +++ b/test/lsp_settings.vimspec @@ -11,4 +11,28 @@ Describe lsp_settings Assert Equals(lsp_settings#get('pyls', 'cmd', {key, name-> 'good'}), 'good') End End + + Describe lsp_settings#executable + It should return command is executable in $PATH + if has('win32') + Assert Equals(lsp_settings#executable('cmd'), 1) + else + Assert Equals(lsp_settings#executable('sh'), 1) + endif + Assert Equals(lsp_settings#executable('unknown-command'), 0) + End + + It should return command is executable in server/foo-bar/foo-bar + let l:servers_dir = fnamemodify(expand(':h:h').'/servers', ':p') + + try + call delete(l:servers_dir . '/foo-bar', 'rf') + call mkdir(l:servers_dir . '/foo-bar') + call writefile(['echo foo-bar'], l:servers_dir . '/foo-bar/foo-bar.cmd') + Assert Equals(lsp_settings#executable('foo-bar'), 1) + finally + call delete(l:servers_dir . '/foo-bar', 'rf') + endtry + End + End End -- cgit v1.2.3-54-g00ecf From 9bc485f53d4606a142fc676119670cda6d83dcce Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 01:40:17 +0900 Subject: Add lsp_settings#servers_dir() --- autoload/lsp_settings.vim | 19 +++++++++---------- test/lsp_settings.vimspec | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/autoload/lsp_settings.vim b/autoload/lsp_settings.vim index 1f0717a..08d1d64 100644 --- a/autoload/lsp_settings.vim +++ b/autoload/lsp_settings.vim @@ -9,6 +9,10 @@ call remove(s:settings, '$schema') let s:ftmap = {} +function! lsp_settings#servers_dir() abort + return get(g:, 'lsp_settings_servers_dir', s:servers_dir) +endfunction + function! lsp_settings#executable(cmd) abort if executable(a:cmd) return 1 @@ -17,8 +21,7 @@ function! lsp_settings#executable(cmd) abort if type(l:paths) == type([]) let l:paths = join(l:paths, ',') endif - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) - let l:paths .= ',' . l:servers_dir . '/' . a:cmd + let l:paths .= ',' . lsp_settings#servers_dir() . '/' . a:cmd if !has('win32') let l:found = globpath(l:paths, a:cmd) return !empty(l:found) @@ -130,8 +133,7 @@ function! lsp_settings#exec_path(cmd) abort if type(l:paths) == type([]) let l:paths = join(l:paths, ',') . ',' endif - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) - let l:paths .= l:servers_dir . '/' . a:cmd + let l:paths .= lsp_settings#servers_dir() . '/' . a:cmd if !has('win32') return lsp_settings#utils#first_one(globpath(l:paths, a:cmd)) endif @@ -168,11 +170,10 @@ function! lsp_settings#autocd(server_info) abort endfunction function! lsp_settings#complete_uninstall(arglead, cmdline, cursorpos) abort - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) let l:installers = [] for l:ft in keys(s:settings) for l:conf in s:settings[l:ft] - if !isdirectory(l:servers_dir . '/' . l:conf.command) + if !isdirectory(lsp_settings#servers_dir() . '/' . l:conf.command) continue endif call add(l:installers, l:conf.command) @@ -222,8 +223,7 @@ function! s:vim_lsp_uninstall_server(command) abort return endif call lsp_settings#utils#msg('Uninstalling ' . a:command) - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) - let l:server_install_dir = l:servers_dir . '/' . a:command + let l:server_install_dir = lsp_settings#servers_dir() . '/' . a:command if !isdirectory(l:server_install_dir) call lsp_settings#utils#error('Server not found') return @@ -263,8 +263,7 @@ function! s:vim_lsp_install_server(ft, command) abort call lsp_settings#utils#error('Server not found') return endif - let l:servers_dir = get(g:, 'lsp_settings_servers_dir', s:servers_dir) - let l:server_install_dir = l:servers_dir . '/' . l:entry[0] + let l:server_install_dir = lsp_settings#servers_dir() . '/' . l:entry[0] if isdirectory(l:server_install_dir) call delete(l:server_install_dir, 'rf') endif diff --git a/test/lsp_settings.vimspec b/test/lsp_settings.vimspec index 3b34941..1303780 100644 --- a/test/lsp_settings.vimspec +++ b/test/lsp_settings.vimspec @@ -23,7 +23,7 @@ Describe lsp_settings End It should return command is executable in server/foo-bar/foo-bar - let l:servers_dir = fnamemodify(expand(':h:h').'/servers', ':p') + let l:servers_dir = lsp_settings#servers_dir() try call delete(l:servers_dir . '/foo-bar', 'rf') -- cgit v1.2.3-54-g00ecf From 2fa26259015237d3fce193a7e07ab5d3c1fbbc79 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 01:42:43 +0900 Subject: Add p for mkdir() --- test/lsp_settings.vimspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lsp_settings.vimspec b/test/lsp_settings.vimspec index 1303780..ff59d09 100644 --- a/test/lsp_settings.vimspec +++ b/test/lsp_settings.vimspec @@ -27,7 +27,7 @@ Describe lsp_settings try call delete(l:servers_dir . '/foo-bar', 'rf') - call mkdir(l:servers_dir . '/foo-bar') + call mkdir(l:servers_dir . '/foo-bar', 'p') call writefile(['echo foo-bar'], l:servers_dir . '/foo-bar/foo-bar.cmd') Assert Equals(lsp_settings#executable('foo-bar'), 1) finally -- cgit v1.2.3-54-g00ecf From 91882919de32d7f121f88ba1350293bf31ff484d Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 01:47:46 +0900 Subject: setfperm --- test/lsp_settings.vimspec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/lsp_settings.vimspec b/test/lsp_settings.vimspec index ff59d09..a6055c9 100644 --- a/test/lsp_settings.vimspec +++ b/test/lsp_settings.vimspec @@ -28,7 +28,12 @@ Describe lsp_settings try call delete(l:servers_dir . '/foo-bar', 'rf') call mkdir(l:servers_dir . '/foo-bar', 'p') - call writefile(['echo foo-bar'], l:servers_dir . '/foo-bar/foo-bar.cmd') + if has('win32') + call writefile(['@echo off', 'echo foo-bar'], l:servers_dir . '/foo-bar/foo-bar.cmd') + else + call writefile(['#!/bin/sh', 'echo foo-bar'], l:servers_dir . '/foo-bar/foo-bar') + call setfperm(l:servers_dir . '/foo-bar/foo-bar', 'rwxr-xr-x') + endif Assert Equals(lsp_settings#executable('foo-bar'), 1) finally call delete(l:servers_dir . '/foo-bar', 'rf') -- cgit v1.2.3-54-g00ecf From a12bd9573bbb80d545937ffd386e94daef246204 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 01:52:42 +0900 Subject: Add test --- test/lsp_settings.vimspec | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/lsp_settings.vimspec b/test/lsp_settings.vimspec index a6055c9..cff06a7 100644 --- a/test/lsp_settings.vimspec +++ b/test/lsp_settings.vimspec @@ -22,7 +22,19 @@ Describe lsp_settings Assert Equals(lsp_settings#executable('unknown-command'), 0) End - It should return command is executable in server/foo-bar/foo-bar + It should return 0 when command is not in server/foo-bar/foo-bar + let l:servers_dir = lsp_settings#servers_dir() + + try + call delete(l:servers_dir . '/foo-bar', 'rf') + call mkdir(l:servers_dir . '/foo-bar', 'p') + Assert Equals(lsp_settings#executable('foo-bar'), 0) + finally + call delete(l:servers_dir . '/foo-bar', 'rf') + endtry + End + + It should return 1 when command is executable in server/foo-bar/foo-bar let l:servers_dir = lsp_settings#servers_dir() try -- cgit v1.2.3-54-g00ecf From e1ce15f714658b7f39e6f50c166cf2d0743a5727 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Thu, 30 Jan 2020 02:26:24 +0900 Subject: Add test --- autoload/lsp_settings.vim | 6 +++++- autoload/lsp_settings/utils.vim | 6 +++++- test/lsp_settings.vimspec | 29 +++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/autoload/lsp_settings.vim b/autoload/lsp_settings.vim index 08d1d64..867c1ff 100644 --- a/autoload/lsp_settings.vim +++ b/autoload/lsp_settings.vim @@ -10,7 +10,11 @@ call remove(s:settings, '$schema') let s:ftmap = {} function! lsp_settings#servers_dir() abort - return get(g:, 'lsp_settings_servers_dir', s:servers_dir) + let l:path = fnamemodify(get(g:, 'lsp_settings_servers_dir', s:servers_dir), ':p') + if has('win32') + let l:path = substitute(l:path, '/', '\', 'g') + endif + return substitute(l:path, '[\/]$', '', '') endfunction function! lsp_settings#executable(cmd) abort diff --git a/autoload/lsp_settings/utils.vim b/autoload/lsp_settings/utils.vim index d342388..96feb0a 100644 --- a/autoload/lsp_settings/utils.vim +++ b/autoload/lsp_settings/utils.vim @@ -24,5 +24,9 @@ function! lsp_settings#utils#first_one(lines) abort if empty(a:lines) return '' endif - return fnamemodify(split(a:lines, "\n")[0], ':p') + let l:path = fnamemodify(split(a:lines, "\n")[0], ':p') + if has('win32') + let l:path = substitute(l:path, '/', '\', 'g') + endif + return l:path endfunction diff --git a/test/lsp_settings.vimspec b/test/lsp_settings.vimspec index cff06a7..30995f6 100644 --- a/test/lsp_settings.vimspec +++ b/test/lsp_settings.vimspec @@ -52,4 +52,33 @@ Describe lsp_settings endtry End End + + Describe lsp_settings#exec_path + It should return full-path to the command + if has('win32') + Assert Equals(empty(lsp_settings#exec_path('cmd')), 0) + else + Assert Equals(empty(lsp_settings#exec_path('sh')), 0) + endif + End + + It should return 1 when command is executable in server/foo-bar/foo-bar + let l:servers_dir = lsp_settings#servers_dir() + + try + call delete(l:servers_dir . '/foo-bar', 'rf') + call mkdir(l:servers_dir . '/foo-bar', 'p') + if has('win32') + call writefile(['@echo off', 'echo foo-bar'], l:servers_dir . '/foo-bar/foo-bar.cmd') + Assert Equals(lsp_settings#exec_path('foo-bar'), l:servers_dir . '\foo-bar\foo-bar.cmd') + else + call writefile(['#!/bin/sh', 'echo foo-bar'], l:servers_dir . '/foo-bar/foo-bar') + call setfperm(l:servers_dir . '/foo-bar/foo-bar', 'rwxr-xr-x') + Assert Equals(lsp_settings#exec_path('foo-bar'), l:servers_dir . '/foo-bar/foo-bar') + endif + finally + call delete(l:servers_dir . '/foo-bar', 'rf') + endtry + End + End End -- cgit v1.2.3-54-g00ecf