aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattn <mattn.jp@gmail.com>2020-01-30 09:14:46 +0900
committerGitHub <noreply@github.com>2020-01-30 09:14:46 +0900
commit6690922a98b1c623c5703d5cacde7adf795124cd (patch)
treea5179aa361361ece40039add1bf83db4ef503ac2
parentb881ac53a671c1ebffc38ebb584b9a851e2cfb70 (diff)
parent00eba157bc8c50501943dee8cdab7c70c13c39d6 (diff)
downloadvim-lsp-settings-6690922a98b1c623c5703d5cacde7adf795124cd.tar.gz
vim-lsp-settings-6690922a98b1c623c5703d5cacde7adf795124cd.tar.bz2
vim-lsp-settings-6690922a98b1c623c5703d5cacde7adf795124cd.zip
Merge pull request #119 from mattn/testable
Testable
-rw-r--r--.github/workflows/linux_vim.yml46
-rw-r--r--autoload/lsp_settings.vim315
-rw-r--r--autoload/lsp_settings/utils.vim32
-rw-r--r--plugin/lsp_settings.vim310
-rw-r--r--test/.themisrc3
-rw-r--r--test/lsp_settings.vimspec84
-rw-r--r--test/lsp_settings/utils.vimspec43
7 files changed, 497 insertions, 336 deletions
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.vim b/autoload/lsp_settings.vim
index 0e11c0a..1596762 100644
--- a/autoload/lsp_settings.vim
+++ b/autoload/lsp_settings.vim
@@ -1,7 +1,88 @@
-let s:servers_dir = expand('<sfile>:h:h').'/servers'
-let s:installer_dir = expand('<sfile>:h:h').'/installer'
+let s:settings_dir = expand('<sfile>:h:h') . '/settings'
+let s:checkers_dir = expand('<sfile>:h:h') . '/checkers'
+let s:servers_dir = expand('<sfile>:h:h') . '/servers'
+let s:installer_dir = expand('<sfile>:h:h') . '/installer'
let s:root_dir = expand('<sfile>:h:h')
+let s:settings = json_decode(join(readfile(expand('<sfile>:h:h') . '/settings.json'), "\n"))
+call remove(s:settings, '$schema')
+
+let s:ftmap = {}
+
+function! lsp_settings#servers_dir() abort
+ 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
+ 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:paths .= ',' . lsp_settings#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 !lsp_settings#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 lsp_settings#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 +105,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 +122,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
@@ -63,15 +137,14 @@ 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 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,14 +174,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]
- if !isdirectory(l:servers_dir . '/' . l:conf.command)
+ for l:ft in keys(s:settings)
+ for l:conf in s:settings[l:ft]
+ if !isdirectory(lsp_settings#servers_dir() . '/' . l:conf.command)
continue
endif
call add(l:installers, l:conf.command)
@@ -118,15 +187,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 +220,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:server_install_dir = lsp_settings#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 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')
+ command! -nargs=1 LspRegisterServer autocmd User lsp_setup ++once call lsp#register_server(<args>)
+ else
+ command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server(<args>)
+ 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:server_install_dir = lsp_settings#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, <q-args>)
+ 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(<args>)
+ else
+ command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server(<args>)
+ 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 !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
+ 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, <q-args>)
+ 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(<q-args>)
+ call s:vim_lsp_load_or_suggest('_')
+
+endfunction
diff --git a/autoload/lsp_settings/utils.vim b/autoload/lsp_settings/utils.vim
new file mode 100644
index 0000000..96feb0a
--- /dev/null
+++ b/autoload/lsp_settings/utils.vim
@@ -0,0 +1,32 @@
+function! lsp_settings#utils#msg(msg) abort
+ redraw
+ echohl Comment
+ echo a:msg
+ echohl None
+endfunction
+
+function! lsp_settings#utils#error(msg) abort
+ redraw
+ 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(lines) abort
+ if empty(a:lines)
+ return ''
+ endif
+ 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/plugin/lsp_settings.vim b/plugin/lsp_settings.vim
index bf37a82..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('<sfile>:h:h').'/settings'
-let s:checkers_dir = expand('<sfile>:h:h').'/checkers'
-let s:installer_dir = expand('<sfile>:h:h').'/installer'
-let s:servers_dir = expand('<sfile>:h:h').'/servers'
-let s:settings = json_decode(join(readfile(expand('<sfile>: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(<args>)
- else
- command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server(<args>)
- 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, <q-args>)
- 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()
- call s:vim_lsp_load_or_suggest('_')
- augroup END
- command! -nargs=? -complete=customlist,lsp_settings#complete_uninstall LspUninstallServer call s:vim_lsp_uninstall_server(<q-args>)
-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(<args>)
- else
- command! -nargs=1 LspRegisterServer autocmd User lsp_setup call lsp#register_server(<args>)
- 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, <q-args>)
- 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()
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.vimspec b/test/lsp_settings.vimspec
new file mode 100644
index 0000000..30995f6
--- /dev/null
+++ b/test/lsp_settings.vimspec
@@ -0,0 +1,84 @@
+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
+
+ 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 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
+ 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')
+ 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')
+ 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
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