Stop loading coc because node uses huge amounts of RAM
This commit is contained in:
parent
a382c219c2
commit
8fd753e28d
25 changed files with 0 additions and 103340 deletions
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"languageserver": {
|
|
||||||
"go": {
|
|
||||||
"command": "gopls",
|
|
||||||
"rootPatterns": ["go.mod"],
|
|
||||||
"trace.server": "verbose",
|
|
||||||
"filetypes": ["go"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
12
pack/acp/opt/coc.nvim/.gitignore
vendored
12
pack/acp/opt/coc.nvim/.gitignore
vendored
|
@ -1,12 +0,0 @@
|
||||||
lib
|
|
||||||
*.map
|
|
||||||
coverage
|
|
||||||
__pycache__
|
|
||||||
.pyc
|
|
||||||
.log
|
|
||||||
src
|
|
||||||
publish.sh
|
|
||||||
doc/tags
|
|
||||||
doc/tags-cn
|
|
||||||
node_modules
|
|
||||||
src/__tests__/tags
|
|
|
@ -1,7 +0,0 @@
|
||||||
Copyright 2018-2018 by Qiming Zhao <chemzqm@gmail.com>aaa
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
@ -1,283 +0,0 @@
|
||||||
<p align="center">
|
|
||||||
<a href="https://www.vim.org/scripts/script.php?script_id=5779">
|
|
||||||
<img alt="Coc Logo" src="https://user-images.githubusercontent.com/251450/55009068-f4ed2780-501c-11e9-9a3b-cf3aa6ab9272.png" height="160" />
|
|
||||||
</a>
|
|
||||||
<p align="center">Make your Vim/Neovim as smart as VSCode.</p>
|
|
||||||
<p align="center">
|
|
||||||
<a href="/LICENSE.md"><img alt="Software License" src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square"></a>
|
|
||||||
<a href="https://github.com/neoclide/coc.nvim/actions"><img alt="Actions" src="https://img.shields.io/github/workflow/status/neoclide/coc.nvim/coc.nvim%20CI?style=flat-square"></a>
|
|
||||||
<a href="/doc/coc.txt"><img alt="Doc" src="https://img.shields.io/badge/doc-%3Ah%20coc.txt-brightgreen.svg?style=flat-square"></a>
|
|
||||||
<a href="https://gitter.im/neoclide/coc.nvim"><img alt="Gitter" src="https://img.shields.io/gitter/room/neoclide/coc.nvim.svg?style=flat-square"></a>
|
|
||||||
</p>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<img alt="Gif" src="https://user-images.githubusercontent.com/251450/55285193-400a9000-53b9-11e9-8cff-ffe4983c5947.gif" width="60%" />
|
|
||||||
|
|
||||||
_True snippet and additional text editing support_
|
|
||||||
|
|
||||||
## Why?
|
|
||||||
|
|
||||||
- 🚀 **Fast**: [instant increment completion](https://github.com/neoclide/coc.nvim/wiki/Completion-with-sources), increment buffer sync using buffer update events.
|
|
||||||
- 💎 **Reliable**: typed language, tested with CI.
|
|
||||||
- 🌟 **Featured**: [full LSP support](https://github.com/neoclide/coc.nvim/wiki/Language-servers#supported-features)
|
|
||||||
- ❤️ **Flexible**: [configured like VSCode](https://github.com/neoclide/coc.nvim/wiki/Using-the-configuration-file), [extensions work like in VSCode](https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions)
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
Install [nodejs](https://nodejs.org/en/download/) >= 10.12:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
curl -sL install-node.now.sh/lts | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
For [vim-plug](https://github.com/junegunn/vim-plug) users:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
" Use release branch (recommend)
|
|
||||||
Plug 'neoclide/coc.nvim', {'branch': 'release'}
|
|
||||||
|
|
||||||
" Or build from source code by using yarn: https://yarnpkg.com
|
|
||||||
Plug 'neoclide/coc.nvim', {'do': 'yarn install --frozen-lockfile'}
|
|
||||||
```
|
|
||||||
|
|
||||||
in your `.vimrc` or `init.vim`, then restart Vim and run `:PlugInstall`.
|
|
||||||
|
|
||||||
Checkout [Install
|
|
||||||
coc.nvim](https://github.com/neoclide/coc.nvim/wiki/Install-coc.nvim) for
|
|
||||||
more info.
|
|
||||||
|
|
||||||
You **have to** install coc extension or configure language servers for
|
|
||||||
LSP support.
|
|
||||||
|
|
||||||
Install extensions like:
|
|
||||||
|
|
||||||
:CocInstall coc-json coc-tsserver
|
|
||||||
|
|
||||||
Or configure language server in `coc-settings.json` opened by
|
|
||||||
`:CocConfig`, like:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"languageserver": {
|
|
||||||
"go": {
|
|
||||||
"command": "gopls",
|
|
||||||
"rootPatterns": ["go.mod"],
|
|
||||||
"trace.server": "verbose",
|
|
||||||
"filetypes": ["go"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Checkout wiki for more details:
|
|
||||||
|
|
||||||
- [Completion with sources](https://github.com/neoclide/coc.nvim/wiki/Completion-with-sources)
|
|
||||||
- [Using the configuration file](https://github.com/neoclide/coc.nvim/wiki/Using-the-configuration-file)
|
|
||||||
- [Using coc extensions](https://github.com/neoclide/coc.nvim/wiki/Using-coc-extensions)
|
|
||||||
- [Configure language servers](https://github.com/neoclide/coc.nvim/wiki/Language-servers)
|
|
||||||
- [F.A.Q](https://github.com/neoclide/coc.nvim/wiki/F.A.Q)
|
|
||||||
|
|
||||||
Checkout `:h coc-nvim` for vim interface.
|
|
||||||
|
|
||||||
## Example vim configuration
|
|
||||||
|
|
||||||
Configuration is required to make coc.nvim easier to work with, since it
|
|
||||||
doesn't change your key-mappings or Vim options. This is done as much as
|
|
||||||
possible to avoid conflict with your other plugins.
|
|
||||||
|
|
||||||
**❗️Important**: Some Vim plugins could change key mappings. Please use
|
|
||||||
`:verbose imap <tab>` to make sure that your keymap has taken effect.
|
|
||||||
|
|
||||||
```vim
|
|
||||||
" TextEdit might fail if hidden is not set.
|
|
||||||
set hidden
|
|
||||||
|
|
||||||
" Some servers have issues with backup files, see #649.
|
|
||||||
set nobackup
|
|
||||||
set nowritebackup
|
|
||||||
|
|
||||||
" Give more space for displaying messages.
|
|
||||||
set cmdheight=2
|
|
||||||
|
|
||||||
" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
|
|
||||||
" delays and poor user experience.
|
|
||||||
set updatetime=300
|
|
||||||
|
|
||||||
" Don't pass messages to |ins-completion-menu|.
|
|
||||||
set shortmess+=c
|
|
||||||
|
|
||||||
" Always show the signcolumn, otherwise it would shift the text each time
|
|
||||||
" diagnostics appear/become resolved.
|
|
||||||
if has("patch-8.1.1564")
|
|
||||||
" Recently vim can merge signcolumn and number column into one
|
|
||||||
set signcolumn=number
|
|
||||||
else
|
|
||||||
set signcolumn=yes
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Use tab for trigger completion with characters ahead and navigate.
|
|
||||||
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
|
|
||||||
" other plugin before putting this into your config.
|
|
||||||
inoremap <silent><expr> <TAB>
|
|
||||||
\ pumvisible() ? "\<C-n>" :
|
|
||||||
\ <SID>check_back_space() ? "\<TAB>" :
|
|
||||||
\ coc#refresh()
|
|
||||||
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
|
|
||||||
|
|
||||||
function! s:check_back_space() abort
|
|
||||||
let col = col('.') - 1
|
|
||||||
return !col || getline('.')[col - 1] =~# '\s'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Use <c-space> to trigger completion.
|
|
||||||
if has('nvim')
|
|
||||||
inoremap <silent><expr> <c-space> coc#refresh()
|
|
||||||
else
|
|
||||||
inoremap <silent><expr> <c-@> coc#refresh()
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Make <CR> auto-select the first completion item and notify coc.nvim to
|
|
||||||
" format on enter, <cr> could be remapped by other vim plugin
|
|
||||||
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
|
|
||||||
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
|
|
||||||
|
|
||||||
" Use `[g` and `]g` to navigate diagnostics
|
|
||||||
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
|
|
||||||
nmap <silent> [g <Plug>(coc-diagnostic-prev)
|
|
||||||
nmap <silent> ]g <Plug>(coc-diagnostic-next)
|
|
||||||
|
|
||||||
" GoTo code navigation.
|
|
||||||
nmap <silent> gd <Plug>(coc-definition)
|
|
||||||
nmap <silent> gy <Plug>(coc-type-definition)
|
|
||||||
nmap <silent> gi <Plug>(coc-implementation)
|
|
||||||
nmap <silent> gr <Plug>(coc-references)
|
|
||||||
|
|
||||||
" Use K to show documentation in preview window.
|
|
||||||
nnoremap <silent> K :call <SID>show_documentation()<CR>
|
|
||||||
|
|
||||||
function! s:show_documentation()
|
|
||||||
if (index(['vim','help'], &filetype) >= 0)
|
|
||||||
execute 'h '.expand('<cword>')
|
|
||||||
elseif (coc#rpc#ready())
|
|
||||||
call CocActionAsync('doHover')
|
|
||||||
else
|
|
||||||
execute '!' . &keywordprg . " " . expand('<cword>')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Highlight the symbol and its references when holding the cursor.
|
|
||||||
autocmd CursorHold * silent call CocActionAsync('highlight')
|
|
||||||
|
|
||||||
" Symbol renaming.
|
|
||||||
nmap <leader>rn <Plug>(coc-rename)
|
|
||||||
|
|
||||||
" Formatting selected code.
|
|
||||||
xmap <leader>f <Plug>(coc-format-selected)
|
|
||||||
nmap <leader>f <Plug>(coc-format-selected)
|
|
||||||
|
|
||||||
augroup mygroup
|
|
||||||
autocmd!
|
|
||||||
" Setup formatexpr specified filetype(s).
|
|
||||||
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
|
|
||||||
" Update signature help on jump placeholder.
|
|
||||||
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
|
|
||||||
augroup end
|
|
||||||
|
|
||||||
" Applying codeAction to the selected region.
|
|
||||||
" Example: `<leader>aap` for current paragraph
|
|
||||||
xmap <leader>a <Plug>(coc-codeaction-selected)
|
|
||||||
nmap <leader>a <Plug>(coc-codeaction-selected)
|
|
||||||
|
|
||||||
" Remap keys for applying codeAction to the current buffer.
|
|
||||||
nmap <leader>ac <Plug>(coc-codeaction)
|
|
||||||
" Apply AutoFix to problem on the current line.
|
|
||||||
nmap <leader>qf <Plug>(coc-fix-current)
|
|
||||||
|
|
||||||
" Map function and class text objects
|
|
||||||
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
|
|
||||||
xmap if <Plug>(coc-funcobj-i)
|
|
||||||
omap if <Plug>(coc-funcobj-i)
|
|
||||||
xmap af <Plug>(coc-funcobj-a)
|
|
||||||
omap af <Plug>(coc-funcobj-a)
|
|
||||||
xmap ic <Plug>(coc-classobj-i)
|
|
||||||
omap ic <Plug>(coc-classobj-i)
|
|
||||||
xmap ac <Plug>(coc-classobj-a)
|
|
||||||
omap ac <Plug>(coc-classobj-a)
|
|
||||||
|
|
||||||
" Remap <C-f> and <C-b> for scroll float windows/popups.
|
|
||||||
" Note coc#float#scroll works on neovim >= 0.4.3 or vim >= 8.2.0750
|
|
||||||
nnoremap <nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
|
|
||||||
nnoremap <nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"
|
|
||||||
inoremap <nowait><expr> <C-f> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(1)\<cr>" : "\<Right>"
|
|
||||||
inoremap <nowait><expr> <C-b> coc#float#has_scroll() ? "\<c-r>=coc#float#scroll(0)\<cr>" : "\<Left>"
|
|
||||||
|
|
||||||
" Use CTRL-S for selections ranges.
|
|
||||||
" Requires 'textDocument/selectionRange' support of language server.
|
|
||||||
nmap <silent> <C-s> <Plug>(coc-range-select)
|
|
||||||
xmap <silent> <C-s> <Plug>(coc-range-select)
|
|
||||||
|
|
||||||
" Add `:Format` command to format current buffer.
|
|
||||||
command! -nargs=0 Format :call CocAction('format')
|
|
||||||
|
|
||||||
" Add `:Fold` command to fold current buffer.
|
|
||||||
command! -nargs=? Fold :call CocAction('fold', <f-args>)
|
|
||||||
|
|
||||||
" Add `:OR` command for organize imports of the current buffer.
|
|
||||||
command! -nargs=0 OR :call CocAction('runCommand', 'editor.action.organizeImport')
|
|
||||||
|
|
||||||
" Add (Neo)Vim's native statusline support.
|
|
||||||
" NOTE: Please see `:h coc-status` for integrations with external plugins that
|
|
||||||
" provide custom statusline: lightline.vim, vim-airline.
|
|
||||||
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}
|
|
||||||
|
|
||||||
" Mappings for CoCList
|
|
||||||
" Show all diagnostics.
|
|
||||||
nnoremap <silent><nowait> <space>a :<C-u>CocList diagnostics<cr>
|
|
||||||
" Manage extensions.
|
|
||||||
nnoremap <silent><nowait> <space>e :<C-u>CocList extensions<cr>
|
|
||||||
" Show commands.
|
|
||||||
nnoremap <silent><nowait> <space>c :<C-u>CocList commands<cr>
|
|
||||||
" Find symbol of current document.
|
|
||||||
nnoremap <silent><nowait> <space>o :<C-u>CocList outline<cr>
|
|
||||||
" Search workspace symbols.
|
|
||||||
nnoremap <silent><nowait> <space>s :<C-u>CocList -I symbols<cr>
|
|
||||||
" Do default action for next item.
|
|
||||||
nnoremap <silent><nowait> <space>j :<C-u>CocNext<CR>
|
|
||||||
" Do default action for previous item.
|
|
||||||
nnoremap <silent><nowait> <space>k :<C-u>CocPrev<CR>
|
|
||||||
" Resume latest coc list.
|
|
||||||
nnoremap <silent><nowait> <space>p :<C-u>CocListResume<CR>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Articles
|
|
||||||
|
|
||||||
- [coc.nvim 插件体系介绍](https://zhuanlan.zhihu.com/p/65524706)
|
|
||||||
- [CocList 入坑指南](https://zhuanlan.zhihu.com/p/71846145)
|
|
||||||
- [Create coc.nvim extension to improve Vim experience](https://medium.com/@chemzqm/create-coc-nvim-extension-to-improve-vim-experience-4461df269173)
|
|
||||||
- [How to write a coc.nvim extension (and why)](https://samroeca.com/coc-plugin.html)
|
|
||||||
|
|
||||||
## Trouble shooting
|
|
||||||
|
|
||||||
Try these steps when you have problem with coc.nvim.
|
|
||||||
|
|
||||||
- Make sure your Vim version >= 8.0 by command `:version`.
|
|
||||||
- If service failed to start, use command `:CocInfo` or `:checkhealth` on Neovim.
|
|
||||||
- Checkout the log of coc.nvim by command `:CocOpenLog`.
|
|
||||||
- When you have issues with the language server, it's recommended to [checkout
|
|
||||||
the output](https://github.com/neoclide/coc.nvim/wiki/Debug-language-server#using-output-channel).
|
|
||||||
|
|
||||||
## Feedback
|
|
||||||
|
|
||||||
- If you think Coc is useful, consider giving it a star.
|
|
||||||
- If you have a question, [ask on gitter](https://gitter.im/neoclide/coc.nvim)
|
|
||||||
- 中文用户请到 [中文 gitter](https://gitter.im/neoclide/coc-cn) 讨论
|
|
||||||
- If something is not working, [create an
|
|
||||||
issue](https://github.com/neoclide/coc.nvim/issues/new).
|
|
||||||
|
|
||||||
<img src="https://user-images.githubusercontent.com/251450/57566955-fb850200-7404-11e9-960f-711673f1a461.png" width="593" height="574">
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
|
@ -1,199 +0,0 @@
|
||||||
let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
|
|
||||||
let g:coc_user_config = get(g:, 'coc_user_config', {})
|
|
||||||
let g:coc_global_extensions = get(g:, 'coc_global_extensions', [])
|
|
||||||
let g:coc_cygqwin_path_prefixes = get(g:, 'coc_cygqwin_path_prefixes', {})
|
|
||||||
let g:coc_selected_text = ''
|
|
||||||
let g:coc_vim_commands = []
|
|
||||||
let s:watched_keys = []
|
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:error_sign = get(g:, 'coc_status_error_sign', has('mac') ? '❌ ' : 'E')
|
|
||||||
let s:warning_sign = get(g:, 'coc_status_warning_sign', has('mac') ? '⚠️ ' : 'W')
|
|
||||||
let s:select_api = exists('*nvim_select_popupmenu_item')
|
|
||||||
let s:callbacks = {}
|
|
||||||
|
|
||||||
function! coc#expandable() abort
|
|
||||||
return coc#rpc#request('snippetCheck', [1, 0])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#jumpable() abort
|
|
||||||
return coc#rpc#request('snippetCheck', [0, 1])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#expandableOrJumpable() abort
|
|
||||||
return coc#rpc#request('snippetCheck', [1, 1])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" add vim command to CocCommand list
|
|
||||||
function! coc#add_command(id, cmd, ...)
|
|
||||||
let config = {'id':a:id, 'cmd':a:cmd, 'title': get(a:,1,'')}
|
|
||||||
call add(g:coc_vim_commands, config)
|
|
||||||
if !coc#rpc#ready() | return | endif
|
|
||||||
call coc#rpc#notify('addCommand', [config])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#refresh() abort
|
|
||||||
return "\<c-r>=coc#start()\<CR>"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#on_enter()
|
|
||||||
if !coc#rpc#ready()
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
if s:is_vim
|
|
||||||
call coc#rpc#notify('CocAutocmd', ['Enter', bufnr('%')])
|
|
||||||
else
|
|
||||||
call coc#rpc#request('CocAutocmd', ['Enter', bufnr('%')])
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_insert_key(method, key, ...) abort
|
|
||||||
if get(a:, 1, 1)
|
|
||||||
call coc#_cancel()
|
|
||||||
endif
|
|
||||||
return "\<c-r>=coc#rpc#".a:method."('doKeymap', ['".a:key."'])\<CR>"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_complete() abort
|
|
||||||
let items = get(g:coc#_context, 'candidates', [])
|
|
||||||
let preselect = get(g:coc#_context, 'preselect', -1)
|
|
||||||
call complete(
|
|
||||||
\ g:coc#_context.start + 1,
|
|
||||||
\ items)
|
|
||||||
if s:select_api && len(items) && preselect != -1
|
|
||||||
call nvim_select_popupmenu_item(preselect, v:false, v:false, {})
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_do_complete(start, items, preselect)
|
|
||||||
let g:coc#_context = {
|
|
||||||
\ 'start': a:start,
|
|
||||||
\ 'candidates': a:items,
|
|
||||||
\ 'preselect': a:preselect
|
|
||||||
\}
|
|
||||||
if mode() =~# 'i' && &paste != 1
|
|
||||||
call feedkeys("\<Plug>CocRefresh", 'i')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_select_confirm() abort
|
|
||||||
if !exists('*complete_info')
|
|
||||||
throw 'coc#_select_confirm requires complete_info function to work'
|
|
||||||
endif
|
|
||||||
let selected = complete_info()['selected']
|
|
||||||
if selected != -1
|
|
||||||
return "\<C-y>"
|
|
||||||
elseif pumvisible()
|
|
||||||
return "\<down>\<C-y>"
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_selected()
|
|
||||||
if !pumvisible() | return 0 | endif
|
|
||||||
return coc#rpc#request('hasSelected', [])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_hide() abort
|
|
||||||
if !pumvisible() | return | endif
|
|
||||||
call feedkeys("\<C-e>", 'in')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_cancel()
|
|
||||||
" hack for close pum
|
|
||||||
if pumvisible() && &paste != 1
|
|
||||||
let g:coc#_context = {'start': 0, 'preselect': -1,'candidates': []}
|
|
||||||
call feedkeys("\<Plug>CocRefresh", 'i')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_select() abort
|
|
||||||
if !pumvisible() | return | endif
|
|
||||||
call feedkeys("\<C-y>", 'in')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#start(...)
|
|
||||||
let opt = coc#util#get_complete_option()
|
|
||||||
call CocActionAsync('startCompletion', extend(opt, get(a:, 1, {})))
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" used for statusline
|
|
||||||
function! coc#status()
|
|
||||||
let info = get(b:, 'coc_diagnostic_info', {})
|
|
||||||
let msgs = []
|
|
||||||
if get(info, 'error', 0)
|
|
||||||
call add(msgs, s:error_sign . info['error'])
|
|
||||||
endif
|
|
||||||
if get(info, 'warning', 0)
|
|
||||||
call add(msgs, s:warning_sign . info['warning'])
|
|
||||||
endif
|
|
||||||
return s:trim(join(msgs, ' ') . ' ' . get(g:, 'coc_status', ''))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:trim(str)
|
|
||||||
if exists('*trim')
|
|
||||||
return trim(a:str)
|
|
||||||
endif
|
|
||||||
return substitute(a:str, '\s\+$', '', '')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#config(section, value)
|
|
||||||
let g:coc_user_config[a:section] = a:value
|
|
||||||
call coc#rpc#notify('updateConfig', [a:section, a:value])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#add_extension(...)
|
|
||||||
if a:0 == 0 | return | endif
|
|
||||||
call extend(g:coc_global_extensions, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_watch(key)
|
|
||||||
if s:is_vim | return | endif
|
|
||||||
if index(s:watched_keys, a:key) == -1
|
|
||||||
call add(s:watched_keys, a:key)
|
|
||||||
call dictwatcheradd(g:, a:key, function('s:GlobalChange'))
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_unwatch(key)
|
|
||||||
if s:is_vim | return | endif
|
|
||||||
let idx = index(s:watched_keys, a:key)
|
|
||||||
if idx != -1
|
|
||||||
call remove(s:watched_keys, idx)
|
|
||||||
call dictwatcherdel(g:, a:key, function('s:GlobalChange'))
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:GlobalChange(dict, key, val)
|
|
||||||
call coc#rpc#notify('GlobalChange', [a:key, get(a:val, 'old', v:null), get(a:val, 'new', v:null)])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_map()
|
|
||||||
if !s:select_api | return | endif
|
|
||||||
for i in range(1, 9)
|
|
||||||
exe 'inoremap <buffer> '.i.' <Cmd>call nvim_select_popupmenu_item('.(i - 1).', v:true, v:true, {})<cr>'
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#_unmap()
|
|
||||||
if !s:select_api | return | endif
|
|
||||||
for i in range(1, 9)
|
|
||||||
exe 'silent! iunmap <buffer> '.i
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#on_notify(id, method, Cb)
|
|
||||||
let key = a:id. '-'.a:method
|
|
||||||
let s:callbacks[key] = a:Cb
|
|
||||||
call coc#rpc#notify('registNotification', [a:id, a:method])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#do_notify(id, method, result)
|
|
||||||
let key = a:id. '-'.a:method
|
|
||||||
let Fn = s:callbacks[key]
|
|
||||||
if !empty(Fn)
|
|
||||||
call Fn(a:result)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
|
@ -1,580 +0,0 @@
|
||||||
" ============================================================================
|
|
||||||
" Description: Client api used by vim8
|
|
||||||
" Author: Qiming Zhao <chemzqm@gmail.com>
|
|
||||||
" Licence: MIT licence
|
|
||||||
" Last Modified: June 28, 2019
|
|
||||||
" ============================================================================
|
|
||||||
if has('nvim') | finish | endif
|
|
||||||
let s:funcs = {}
|
|
||||||
let s:prop_id = 1000
|
|
||||||
let s:namespace_id = 1
|
|
||||||
let s:namespace_cache = {}
|
|
||||||
|
|
||||||
" helper {{
|
|
||||||
function! s:buf_line_count(bufnr) abort
|
|
||||||
if bufnr('%') == a:bufnr
|
|
||||||
return line('$')
|
|
||||||
endif
|
|
||||||
if exists('*getbufline')
|
|
||||||
let lines = getbufline(a:bufnr, 1, '$')
|
|
||||||
return len(lines)
|
|
||||||
endif
|
|
||||||
let curr = bufnr('%')
|
|
||||||
execute 'buffer '.a:bufnr
|
|
||||||
let n = line('$')
|
|
||||||
execute 'buffer '.curr
|
|
||||||
return n
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:execute(cmd)
|
|
||||||
if a:cmd =~# '^echo'
|
|
||||||
execute a:cmd
|
|
||||||
else
|
|
||||||
silent! execute a:cmd
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
" }}"
|
|
||||||
|
|
||||||
" nvim client methods {{
|
|
||||||
function! s:funcs.set_current_dir(dir) abort
|
|
||||||
execute 'cd '.a:dir
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.set_var(name, value) abort
|
|
||||||
execute 'let g:'.a:name.'= a:value'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.del_var(name) abort
|
|
||||||
execute 'unlet g:'.a:name
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.set_option(name, value) abort
|
|
||||||
execute 'let &'.a:name.' = a:value'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.set_current_buf(bufnr) abort
|
|
||||||
if !bufexists(a:bufnr) | return | endif
|
|
||||||
execute 'buffer '.a:bufnr
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.set_current_win(win_id) abort
|
|
||||||
let [tabnr, winnr] = win_id2tabwin(a:win_id)
|
|
||||||
if tabnr == 0 | return | endif
|
|
||||||
execute 'normal! '.tabnr.'gt'
|
|
||||||
execute winnr.' wincmd w'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.set_current_tabpage(tabnr) abort
|
|
||||||
execute 'normal! '.a:tabnr.'gt'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.list_wins() abort
|
|
||||||
return map(getwininfo(), 'v:val["winid"]')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.call_atomic(calls)
|
|
||||||
let res = []
|
|
||||||
for [key, arglist] in a:calls
|
|
||||||
let name = key[5:]
|
|
||||||
try
|
|
||||||
call add(res, call(s:funcs[name], arglist))
|
|
||||||
catch /.*/
|
|
||||||
return [res, v:exception]
|
|
||||||
endtry
|
|
||||||
endfor
|
|
||||||
return [res, v:null]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.set_client_info(...) abort
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.subscribe(...) abort
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.unsubscribe(...) abort
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.call_function(method, args) abort
|
|
||||||
return call(a:method, a:args)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.call_dict_function(dict, method, args) abort
|
|
||||||
return call(a:method, a:args, a:dict)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.command(command) abort
|
|
||||||
" command that could cause cursor vanish
|
|
||||||
if a:command =~# '^echo' || a:command =~# '^redraw' || a:command =~# '^sign place'
|
|
||||||
call timer_start(0, {-> s:execute(a:command)})
|
|
||||||
else
|
|
||||||
execute a:command
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.eval(expr) abort
|
|
||||||
return eval(a:expr)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_api_info()
|
|
||||||
let names = coc#api#func_names()
|
|
||||||
return [1, {'functions': map(names, '{"name": "nvim_".v:val}')}]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.list_bufs()
|
|
||||||
return map(getbufinfo({'buflisted': 1}), 'v:val["bufnr"]')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.feedkeys(keys, mode, escape_csi)
|
|
||||||
call feedkeys(a:keys, a:mode)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.list_runtime_paths()
|
|
||||||
return split(&runtimepath, ',')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.command_output(cmd)
|
|
||||||
return execute(a:cmd)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_current_line()
|
|
||||||
return getline('.')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.set_current_line(line)
|
|
||||||
call setline('.', a:line)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.del_current_line(line)
|
|
||||||
execute 'normal! dd'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_var(var)
|
|
||||||
return get(g:, a:var, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_vvar(var)
|
|
||||||
return get(v:, a:var, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_option(name)
|
|
||||||
return eval('&'.a:name)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_current_buf()
|
|
||||||
return bufnr('%')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_current_win()
|
|
||||||
return win_getid()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_current_tabpage()
|
|
||||||
return tabpagenr()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.list_tabpages()
|
|
||||||
return range(1, tabpagenr('$'))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.get_mode()
|
|
||||||
return {'blocking': v:false, 'mode': mode()}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.strwidth(str)
|
|
||||||
return strwidth(a:str)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.out_write(str)
|
|
||||||
echon a:str
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.err_write(str)
|
|
||||||
echoerr a:str
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.err_writeln(str)
|
|
||||||
echoerr a:str
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.create_namespace(name) abort
|
|
||||||
if empty(a:name)
|
|
||||||
let id = s:namespace_id
|
|
||||||
let s:namespace_id = s:namespace_id + 1
|
|
||||||
return id
|
|
||||||
endif
|
|
||||||
let id = get(s:namespace_cache, a:name, 0)
|
|
||||||
if !id
|
|
||||||
let id = s:namespace_id
|
|
||||||
let s:namespace_id = s:namespace_id + 1
|
|
||||||
let s:namespace_cache[a:name] = id
|
|
||||||
endif
|
|
||||||
return id
|
|
||||||
endfunction
|
|
||||||
" }}
|
|
||||||
|
|
||||||
" buffer methods {{
|
|
||||||
function! s:funcs.buf_set_option(bufnr, name, val)
|
|
||||||
let val = a:val
|
|
||||||
if val is v:true
|
|
||||||
let val = 1
|
|
||||||
elseif val is v:false
|
|
||||||
let val = 0
|
|
||||||
endif
|
|
||||||
return setbufvar(a:bufnr, '&'.a:name, val)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_get_changedtick(bufnr)
|
|
||||||
return getbufvar(a:bufnr, 'changedtick')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_is_valid(bufnr)
|
|
||||||
return bufloaded(a:bufnr) ? v:true : v:false
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_get_mark(bufnr, name)
|
|
||||||
let nr = bufnr('%')
|
|
||||||
if a:bufnr != 0 || a:bufnr != nr
|
|
||||||
throw 'buf_get_mark support current buffer only'
|
|
||||||
endif
|
|
||||||
return [line("'" . a:name), col("'" . a:name)]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_add_highlight(bufnr, srcId, hlGroup, line, colStart, colEnd) abort
|
|
||||||
if !has('textprop')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let bufnr = a:bufnr == 0 ? bufnr('%') : a:bufnr
|
|
||||||
let key = 'Coc'.a:hlGroup.(a:srcId != -1 ? a:srcId : '')
|
|
||||||
if empty(prop_type_get(key, {'bufnr': a:bufnr}))
|
|
||||||
call prop_type_add(key, {'highlight': a:hlGroup, 'combine': 1, 'bufnr': a:bufnr})
|
|
||||||
if a:srcId != -1
|
|
||||||
let cached = getbufvar(bufnr, 'prop_namespace_'.a:srcId, [])
|
|
||||||
call add(cached, key)
|
|
||||||
call setbufvar(bufnr, 'prop_namespace_'.a:srcId, cached)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let total = strlen(getbufline(bufnr, a:line + 1)[0])
|
|
||||||
let end = a:colEnd
|
|
||||||
if end == -1
|
|
||||||
let end = total
|
|
||||||
else
|
|
||||||
let end = min([end, total])
|
|
||||||
endif
|
|
||||||
if end <= a:colStart
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let id = s:prop_id
|
|
||||||
let s:prop_id = id + 1
|
|
||||||
try
|
|
||||||
call prop_add(a:line + 1, a:colStart + 1, {'length': end - a:colStart, 'bufnr': bufnr, 'type': key, 'id': id})
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E967/
|
|
||||||
" ignore 967
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort
|
|
||||||
if !has('textprop')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if a:srcId == -1
|
|
||||||
if a:endLine == -1
|
|
||||||
call prop_clear(a:startLine + 1, {'bufnr': a:bufnr})
|
|
||||||
else
|
|
||||||
call prop_clear(a:startLine + 1, a:endLine + 1, {'bufnr': a:bufnr})
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let cached = getbufvar(a:bufnr, 'prop_namespace_'.a:srcId, [])
|
|
||||||
if empty(cached)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
for key in cached
|
|
||||||
call prop_remove({'type': key, 'bufnr': a:bufnr, 'all': 1})
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_line_count(bufnr) abort
|
|
||||||
return s:buf_line_count(a:bufnr)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_attach(...)
|
|
||||||
" not supported
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_detach()
|
|
||||||
" not supported
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_get_lines(bufnr, start, end, strict) abort
|
|
||||||
let lines = getbufline(a:bufnr, 1, '$')
|
|
||||||
let start = a:start < 0 ? a:start + 1 : a:start
|
|
||||||
let end = a:end < 0 ? a:end + 1 : a:end
|
|
||||||
if a:strict && end > len(lines)
|
|
||||||
throw 'line number out of range: '. end
|
|
||||||
endif
|
|
||||||
return lines[start : end - 1]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_set_lines(bufnr, start, end, strict, ...) abort
|
|
||||||
if !bufloaded(a:bufnr)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let replacement = get(a:, 1, [])
|
|
||||||
let lineCount = s:buf_line_count(a:bufnr)
|
|
||||||
let startLnum = a:start >= 0 ? a:start + 1 : lineCount + a:start + 1
|
|
||||||
let end = a:end >= 0 ? a:end : lineCount + a:end + 1
|
|
||||||
if end == lineCount + 1
|
|
||||||
let end = lineCount
|
|
||||||
endif
|
|
||||||
let delCount = end - (startLnum - 1)
|
|
||||||
let changeBuffer = 0
|
|
||||||
let curr = bufnr('%')
|
|
||||||
if a:bufnr != curr && !exists('*setbufline')
|
|
||||||
let changeBuffer = 1
|
|
||||||
exe 'buffer '.a:bufnr
|
|
||||||
endif
|
|
||||||
if a:bufnr == curr || changeBuffer
|
|
||||||
" replace
|
|
||||||
let storeView = winsaveview()
|
|
||||||
if delCount == len(replacement)
|
|
||||||
call setline(startLnum, replacement)
|
|
||||||
else
|
|
||||||
if len(replacement)
|
|
||||||
call append(startLnum - 1, replacement)
|
|
||||||
endif
|
|
||||||
if delCount
|
|
||||||
let start = startLnum + len(replacement)
|
|
||||||
let saved_reg = @"
|
|
||||||
silent execute start . ','.(start + delCount - 1).'d'
|
|
||||||
let @" = saved_reg
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
call winrestview(storeView)
|
|
||||||
if changeBuffer
|
|
||||||
exe 'buffer '.curr
|
|
||||||
endif
|
|
||||||
elseif exists('*setbufline')
|
|
||||||
" replace
|
|
||||||
if delCount == len(replacement)
|
|
||||||
" 8.0.1039
|
|
||||||
call setbufline(a:bufnr, startLnum, replacement)
|
|
||||||
else
|
|
||||||
if len(replacement)
|
|
||||||
" 8.10037
|
|
||||||
call appendbufline(a:bufnr, startLnum - 1, replacement)
|
|
||||||
endif
|
|
||||||
if delCount
|
|
||||||
let start = startLnum + len(replacement)
|
|
||||||
"8.1.0039
|
|
||||||
call deletebufline(a:bufnr, start, start + delCount - 1)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_set_name(bufnr, name) abort
|
|
||||||
let nr = bufnr('%')
|
|
||||||
if a:bufnr != nr
|
|
||||||
throw 'buf_set_name support current buffer only'
|
|
||||||
else
|
|
||||||
execute '0f'
|
|
||||||
execute 'file '.fnameescape(a:name)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_get_var(bufnr, name)
|
|
||||||
return getbufvar(a:bufnr, a:name)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_set_var(bufnr, name, val)
|
|
||||||
if !bufloaded(a:bufnr) | return | endif
|
|
||||||
call setbufvar(a:bufnr, a:name, a:val)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_del_var(bufnr, name)
|
|
||||||
call setbufvar(a:bufnr, a:name, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_get_option(bufnr, name)
|
|
||||||
return getbufvar(a:bufnr, '&'.a:name)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.buf_get_name(bufnr)
|
|
||||||
return bufname(a:bufnr)
|
|
||||||
endfunction
|
|
||||||
" }}
|
|
||||||
|
|
||||||
" window methods {{
|
|
||||||
function! s:funcs.win_get_buf(winid)
|
|
||||||
return winbufnr(a:winid)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_get_position(win_id) abort
|
|
||||||
let [row, col] = win_screenpos(a:win_id)
|
|
||||||
if row == 0 && col == 0
|
|
||||||
throw 'Invalid window '.a:win_id
|
|
||||||
endif
|
|
||||||
return [row - 1, col - 1]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_get_height(win_id) abort
|
|
||||||
return winheight(a:win_id)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_get_width(win_id) abort
|
|
||||||
return winwidth(a:win_id)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
if exists('*win_execute')
|
|
||||||
function! s:win_execute(win_id, cmd, ...) abort
|
|
||||||
let ref = get(a:000, 0, v:null)
|
|
||||||
let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
|
|
||||||
call win_execute(a:win_id, cmd)
|
|
||||||
endfunction
|
|
||||||
else
|
|
||||||
function! s:win_execute(win_id, cmd, ...) abort
|
|
||||||
let ref = get(a:000, 0, v:null)
|
|
||||||
let cmd = ref is v:null ? a:cmd : 'let ref["out"] = ' . a:cmd
|
|
||||||
let winid = win_getid()
|
|
||||||
if winid == a:win_id
|
|
||||||
execute cmd
|
|
||||||
else
|
|
||||||
let goto_status = win_gotoid(a:win_id)
|
|
||||||
if !goto_status
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
execute cmd
|
|
||||||
call win_gotoid(winid)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! s:funcs.win_get_cursor(win_id) abort
|
|
||||||
let ref = {}
|
|
||||||
call s:win_execute(a:win_id, "[line('.'), col('.')-1]", ref)
|
|
||||||
return ref['out']
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_get_var(win_id, name) abort
|
|
||||||
return gettabwinvar(0, a:win_id, a:name)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_set_width(win_id, width) abort
|
|
||||||
return s:win_execute(a:win_id, 'vertical resize '.a:width)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_set_buf(win_id, buf_id) abort
|
|
||||||
return s:win_execute(a:win_id, 'buffer '.a:buf_id)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_get_option(win_id, name) abort
|
|
||||||
return gettabwinvar(0, a:win_id, '&'.a:name)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_set_height(win_id, height) abort
|
|
||||||
return s:win_execute(a:win_id, 'resize '.a:height)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_set_option(win_id, name, value) abort
|
|
||||||
let val = a:value
|
|
||||||
if val is v:true
|
|
||||||
let val = 1
|
|
||||||
elseif val is v:false
|
|
||||||
let val = 0
|
|
||||||
endif
|
|
||||||
call setwinvar(a:win_id, '&'.a:name, val)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_set_var(win_id, name, value) abort
|
|
||||||
call setwinvar(a:win_id, a:name, a:value)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_del_var(win_id, name) abort
|
|
||||||
call settabwinvar(0, a:win_id, a:name, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_is_valid(win_id) abort
|
|
||||||
let info = getwininfo(a:win_id)
|
|
||||||
return !empty(info)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_get_number(win_id) abort
|
|
||||||
let info = getwininfo(a:win_id)
|
|
||||||
if empty(info)
|
|
||||||
throw 'Invalid window id '.a:win_id
|
|
||||||
endif
|
|
||||||
return info[0]['winnr']
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_set_cursor(win_id, pos) abort
|
|
||||||
let [line, col] = a:pos
|
|
||||||
call s:win_execute(a:win_id, 'call cursor('.line.','.(col + 1).')')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_close(win_id, ...) abort
|
|
||||||
call s:win_execute(a:win_id, 'close!')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.win_get_tabpage(win_id) abort
|
|
||||||
let info = getwininfo(a:win_id)
|
|
||||||
if !info
|
|
||||||
throw 'Invalid window id '.a:win_id
|
|
||||||
endif
|
|
||||||
return info[0]['tabnr']
|
|
||||||
endfunction
|
|
||||||
" }}
|
|
||||||
|
|
||||||
" tabpage methods {{
|
|
||||||
function! s:funcs.tabpage_get_number(id)
|
|
||||||
return a:id
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.tabpage_list_wins(tabnr)
|
|
||||||
let info = getwininfo()
|
|
||||||
return map(filter(info, 'v:val["tabnr"] == a:tabnr'), 'v:val["winid"]')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.tabpage_get_var(tabnr, name)
|
|
||||||
return gettabvar(a:tabnr, a:name, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.tabpage_set_var(tabnr, name, value)
|
|
||||||
call settabvar(a:tabnr, a:name, a:value)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.tabpage_del_var(tabnr, name)
|
|
||||||
call settabvar(a:tabnr, a:name, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.tabpage_is_valid(tabnr)
|
|
||||||
let max = tabpagenr('$')
|
|
||||||
return a:tabnr <= max
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:funcs.tabpage_get_win(tabnr)
|
|
||||||
let wnr = tabpagewinnr(a:tabnr)
|
|
||||||
return win_getid(wnr, a:tabnr)
|
|
||||||
endfunction
|
|
||||||
" }}
|
|
||||||
|
|
||||||
function! coc#api#func_names() abort
|
|
||||||
return keys(s:funcs)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#api#call(method, args) abort
|
|
||||||
let err = v:null
|
|
||||||
let res = v:null
|
|
||||||
try
|
|
||||||
let res = call(s:funcs[a:method], a:args)
|
|
||||||
catch /.*/
|
|
||||||
let err = v:exception
|
|
||||||
endtry
|
|
||||||
return [err, res]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#api#notify(method, args) abort
|
|
||||||
call call(s:funcs[a:method], a:args)
|
|
||||||
endfunction
|
|
||||||
" vim: set sw=2 ts=2 sts=2 et tw=78 foldmarker={{,}} foldmethod=marker foldlevel=0:
|
|
|
@ -1,313 +0,0 @@
|
||||||
let s:root = expand('<sfile>:h:h:h')
|
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:is_win = has("win32") || has("win64")
|
|
||||||
let s:clients = {}
|
|
||||||
|
|
||||||
if get(g:, 'node_client_debug', 0)
|
|
||||||
let $NODE_CLIENT_LOG_LEVEL = 'debug'
|
|
||||||
if exists('$NODE_CLIENT_LOG_FILE')
|
|
||||||
let s:logfile = resolve($NODE_CLIENT_LOG_FILE)
|
|
||||||
else
|
|
||||||
let s:logfile = tempname()
|
|
||||||
let $NODE_CLIENT_LOG_FILE = s:logfile
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" create a client
|
|
||||||
function! coc#client#create(name, command)
|
|
||||||
let client = {}
|
|
||||||
let client['command'] = a:command
|
|
||||||
let client['name'] = a:name
|
|
||||||
let client['running'] = 0
|
|
||||||
let client['async_req_id'] = 1
|
|
||||||
let client['async_callbacks'] = {}
|
|
||||||
" vim only
|
|
||||||
let client['channel'] = v:null
|
|
||||||
" neovim only
|
|
||||||
let client['chan_id'] = 0
|
|
||||||
let client['start'] = function('s:start', [], client)
|
|
||||||
let client['request'] = function('s:request', [], client)
|
|
||||||
let client['notify'] = function('s:notify', [], client)
|
|
||||||
let client['request_async'] = function('s:request_async', [], client)
|
|
||||||
let client['on_async_response'] = function('s:on_async_response', [], client)
|
|
||||||
let s:clients[a:name] = client
|
|
||||||
return client
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:start() dict
|
|
||||||
if self.running | return | endif
|
|
||||||
if !isdirectory(getcwd())
|
|
||||||
echohl Error | echon '[coc.nvim] Current cwd is not a valid directory.' | echohl None
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let timeout = string(get(g:, 'coc_channel_timeout', 30))
|
|
||||||
let disable_warning = string(get(g:, 'coc_disable_startup_warning', 0))
|
|
||||||
let tmpdir = fnamemodify(tempname(), ':p:h')
|
|
||||||
if s:is_vim
|
|
||||||
let options = {
|
|
||||||
\ 'in_mode': 'json',
|
|
||||||
\ 'out_mode': 'json',
|
|
||||||
\ 'err_mode': 'nl',
|
|
||||||
\ 'err_cb': {channel, message -> s:on_stderr(self.name, split(message, "\n"))},
|
|
||||||
\ 'exit_cb': {channel, code -> s:on_exit(self.name, code)},
|
|
||||||
\ 'env': {
|
|
||||||
\ 'NODE_NO_WARNINGS': '1',
|
|
||||||
\ 'VIM_NODE_RPC': '1',
|
|
||||||
\ 'COC_NVIM': '1',
|
|
||||||
\ 'COC_CHANNEL_TIMEOUT': timeout,
|
|
||||||
\ 'COC_NO_WARNINGS': disable_warning,
|
|
||||||
\ 'TMPDIR': tmpdir,
|
|
||||||
\ }
|
|
||||||
\}
|
|
||||||
if has("patch-8.1.350")
|
|
||||||
let options['noblock'] = 1
|
|
||||||
endif
|
|
||||||
let job = job_start(self.command, options)
|
|
||||||
let status = job_status(job)
|
|
||||||
if status !=# 'run'
|
|
||||||
let self.running = 0
|
|
||||||
echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let self['running'] = 1
|
|
||||||
let self['channel'] = job_getchannel(job)
|
|
||||||
else
|
|
||||||
let original = {
|
|
||||||
\ 'NODE_NO_WARNINGS': getenv('NODE_NO_WARNINGS'),
|
|
||||||
\ 'COC_CHANNEL_TIMEOUT': getenv('COC_CHANNEL_TIMEOUT'),
|
|
||||||
\ 'COC_NO_WARNINGS': getenv('COC_NO_WARNINGS'),
|
|
||||||
\ 'TMPDIR': getenv('TMPDIR'),
|
|
||||||
\ }
|
|
||||||
" env option not work on neovim
|
|
||||||
call setenv('NODE_NO_WARNINGS', '1')
|
|
||||||
call setenv('COC_CHANNEL_TIMEOUT', timeout)
|
|
||||||
call setenv('COC_NO_WARNINGS', disable_warning)
|
|
||||||
call setenv('TMPDIR', tmpdir)
|
|
||||||
let chan_id = jobstart(self.command, {
|
|
||||||
\ 'rpc': 1,
|
|
||||||
\ 'on_stderr': {channel, msgs -> s:on_stderr(self.name, msgs)},
|
|
||||||
\ 'on_exit': {channel, code -> s:on_exit(self.name, code)},
|
|
||||||
\})
|
|
||||||
for key in keys(original)
|
|
||||||
call setenv(key, original[key])
|
|
||||||
endfor
|
|
||||||
if chan_id <= 0
|
|
||||||
echohl Error | echom 'Failed to start '.self.name.' service' | echohl None
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let self['chan_id'] = chan_id
|
|
||||||
let self['running'] = 1
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:on_stderr(name, msgs)
|
|
||||||
if get(g:, 'coc_vim_leaving', 0) | return | endif
|
|
||||||
if get(g:, 'coc_disable_uncaught_error', 0) | return | endif
|
|
||||||
let data = filter(copy(a:msgs), '!empty(v:val)')
|
|
||||||
if empty(data) | return | endif
|
|
||||||
let client = a:name ==# 'coc' ? '[coc.nvim]' : '['.a:name.']'
|
|
||||||
let data[0] = client.': '.data[0]
|
|
||||||
call coc#util#echo_messages('Error', data)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:on_exit(name, code) abort
|
|
||||||
if get(g:, 'coc_vim_leaving', 0) | return | endif
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if empty(client) | return | endif
|
|
||||||
if client['running'] != 1 | return | endif
|
|
||||||
let client['running'] = 0
|
|
||||||
let client['chan_id'] = 0
|
|
||||||
let client['channel'] = v:null
|
|
||||||
let client['async_req_id'] = 1
|
|
||||||
if a:code != 0 && a:code != 143
|
|
||||||
echohl Error | echom 'client '.a:name. ' abnormal exit with: '.a:code | echohl None
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#get_client(name) abort
|
|
||||||
return get(s:clients, a:name, v:null)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#get_channel(client)
|
|
||||||
if s:is_vim
|
|
||||||
return a:client['channel']
|
|
||||||
endif
|
|
||||||
return a:client['chan_id']
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:request(method, args) dict
|
|
||||||
let channel = coc#client#get_channel(self)
|
|
||||||
if empty(channel) | return '' | endif
|
|
||||||
try
|
|
||||||
if s:is_vim
|
|
||||||
let res = ch_evalexpr(channel, [a:method, a:args], {'timeout': 60 * 1000})
|
|
||||||
if type(res) == 1 && res ==# ''
|
|
||||||
throw 'request '.a:method. ' '.string(a:args).' timeout after 60s'
|
|
||||||
endif
|
|
||||||
let [l:errmsg, res] = res
|
|
||||||
if !empty(l:errmsg)
|
|
||||||
throw l:errmsg
|
|
||||||
else
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
return call('rpcrequest', [channel, a:method] + a:args)
|
|
||||||
endif
|
|
||||||
catch /.*/
|
|
||||||
if v:exception =~# 'E475'
|
|
||||||
if get(g:, 'coc_vim_leaving', 0) | return | endif
|
|
||||||
echohl Error | echom '['.self.name.'] server connection lost' | echohl None
|
|
||||||
let name = self.name
|
|
||||||
call s:on_exit(name, 0)
|
|
||||||
execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
|
|
||||||
elseif v:exception =~# 'E12'
|
|
||||||
" neovim's bug, ignore it
|
|
||||||
else
|
|
||||||
echohl Error | echo 'Error on request ('.a:method.'): '.v:exception | echohl None
|
|
||||||
endif
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:notify(method, args) dict
|
|
||||||
let channel = coc#client#get_channel(self)
|
|
||||||
if empty(channel)
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
if s:is_vim
|
|
||||||
call ch_sendraw(channel, json_encode([0, [a:method, a:args]])."\n")
|
|
||||||
else
|
|
||||||
call call('rpcnotify', [channel, a:method] + a:args)
|
|
||||||
endif
|
|
||||||
catch /.*/
|
|
||||||
if v:exception =~# 'E475'
|
|
||||||
if get(g:, 'coc_vim_leaving', 0)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
echohl Error | echom '['.self.name.'] server connection lost' | echohl None
|
|
||||||
let name = self.name
|
|
||||||
call s:on_exit(name, 0)
|
|
||||||
execute 'silent do User ConnectionLost'.toupper(name[0]).name[1:]
|
|
||||||
elseif v:exception =~# 'E12'
|
|
||||||
" neovim's bug, ignore it
|
|
||||||
else
|
|
||||||
echohl Error | echo 'Error on notify ('.a:method.'): '.v:exception | echohl None
|
|
||||||
endif
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:request_async(method, args, cb) dict
|
|
||||||
let channel = coc#client#get_channel(self)
|
|
||||||
if empty(channel) | return '' | endif
|
|
||||||
if type(a:cb) != 2
|
|
||||||
echohl Error | echom '['.self['name'].'] Callback should be function' | echohl None
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let id = self.async_req_id
|
|
||||||
let self.async_req_id = id + 1
|
|
||||||
let self.async_callbacks[id] = a:cb
|
|
||||||
call self['notify']('nvim_async_request_event', [id, a:method, a:args])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:on_async_response(id, resp, isErr) dict
|
|
||||||
let Callback = get(self.async_callbacks, a:id, v:null)
|
|
||||||
if empty(Callback)
|
|
||||||
" should not happen
|
|
||||||
echohl Error | echom 'callback not found' | echohl None
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call remove(self.async_callbacks, a:id)
|
|
||||||
if a:isErr
|
|
||||||
call call(Callback, [a:resp, v:null])
|
|
||||||
else
|
|
||||||
call call(Callback, [v:null, a:resp])
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#is_running(name) abort
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if empty(client) | return 0 | endif
|
|
||||||
if !client['running'] | return 0 | endif
|
|
||||||
if s:is_vim
|
|
||||||
let status = job_status(ch_getjob(client['channel']))
|
|
||||||
return status ==# 'run'
|
|
||||||
else
|
|
||||||
let chan_id = client['chan_id']
|
|
||||||
let [code] = jobwait([chan_id], 10)
|
|
||||||
return code == -1
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#stop(name) abort
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if empty(client) | return 1 | endif
|
|
||||||
let running = coc#client#is_running(a:name)
|
|
||||||
if !running
|
|
||||||
echohl WarningMsg | echom 'client '.a:name. ' not running.' | echohl None
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
if s:is_vim
|
|
||||||
call job_stop(ch_getjob(client['channel']), 'term')
|
|
||||||
else
|
|
||||||
call jobstop(client['chan_id'])
|
|
||||||
endif
|
|
||||||
sleep 200m
|
|
||||||
if coc#client#is_running(a:name)
|
|
||||||
echohl Error | echom 'client '.a:name. ' stop failed.' | echohl None
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
call s:on_exit(a:name, 0)
|
|
||||||
echohl MoreMsg | echom 'client '.a:name.' stopped!' | echohl None
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#request(name, method, args)
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if !empty(client)
|
|
||||||
return client['request'](a:method, a:args)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#notify(name, method, args)
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if !empty(client)
|
|
||||||
call client['notify'](a:method, a:args)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#request_async(name, method, args, cb)
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if !empty(client)
|
|
||||||
call client['request_async'](a:method, a:args, a:cb)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#on_response(name, id, resp, isErr)
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if !empty(client)
|
|
||||||
call client['on_async_response'](a:id, a:resp, a:isErr)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#restart(name) abort
|
|
||||||
let stopped = coc#client#stop(a:name)
|
|
||||||
if !stopped | return | endif
|
|
||||||
let client = get(s:clients, a:name, v:null)
|
|
||||||
if !empty(client)
|
|
||||||
call client['start']()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#restart_all()
|
|
||||||
for key in keys(s:clients)
|
|
||||||
call coc#client#restart(key)
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#client#open_log()
|
|
||||||
if !get(g:, 'node_client_debug', 0)
|
|
||||||
echohl Error | echon '[coc.nvim] use let g:node_client_debug = 1 in your vimrc to enabled debug mode.' | echohl None
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
execute 'vs '.s:logfile
|
|
||||||
endfunction
|
|
|
@ -1,942 +0,0 @@
|
||||||
" Related to float window create
|
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:borderchars = get(g:, 'coc_borderchars',
|
|
||||||
\ ['─', '│', '─', '│', '┌', '┐', '┘', '└'])
|
|
||||||
let s:prompt_win_width = get(g:, 'coc_prompt_win_width', 32)
|
|
||||||
let s:scrollbar_ns = exists('*nvim_create_namespace') ? nvim_create_namespace('coc-scrollbar') : 0
|
|
||||||
" winvar: border array of numbers, button boolean
|
|
||||||
|
|
||||||
" detect if there's float window/popup created by coc.nvim
|
|
||||||
function! coc#float#has_float() abort
|
|
||||||
if s:is_vim
|
|
||||||
if !exists('*popup_list')
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
let arr = filter(popup_list(), 'getwinvar(v:val,"float",0)&&popup_getpos(v:val)["visible"]')
|
|
||||||
return !empty(arr)
|
|
||||||
endif
|
|
||||||
for i in range(1, winnr('$'))
|
|
||||||
if getwinvar(i, 'float')
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#close_all() abort
|
|
||||||
if !has('nvim') && exists('*popup_clear')
|
|
||||||
call popup_clear()
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let winids = coc#float#get_float_win_list()
|
|
||||||
for id in winids
|
|
||||||
call coc#float#close(id)
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#jump() abort
|
|
||||||
if s:is_vim
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let winids = coc#float#get_float_win_list()
|
|
||||||
if !empty(winids)
|
|
||||||
call win_gotoid(winids[0])
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#get_float_mode(lines, config) abort
|
|
||||||
let allowSelection = get(a:config, 'allowSelection', 0)
|
|
||||||
let pumAlignTop = get(a:config, 'pumAlignTop', 0)
|
|
||||||
let mode = mode()
|
|
||||||
let checked = (mode == 's' && allowSelection) || index(['i', 'n', 'ic'], mode) != -1
|
|
||||||
if !checked
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
if !s:is_vim && mode ==# 'i'
|
|
||||||
" helps to fix undo issue, don't know why.
|
|
||||||
call feedkeys("\<C-g>u", 'n')
|
|
||||||
endif
|
|
||||||
let dimension = coc#float#get_config_cursor(a:lines, a:config)
|
|
||||||
if empty(dimension)
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
if pumvisible() && ((pumAlignTop && dimension['row'] <0)|| (!pumAlignTop && dimension['row'] > 0))
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
return [mode, bufnr('%'), [line('.'), col('.')], dimension]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" create/reuse float window for config position, config including:
|
|
||||||
" - line: line count relative to cursor, nagetive number means abover cursor.
|
|
||||||
" - col: column count relative to cursor, nagetive number means left of cursor.
|
|
||||||
" - width: content width without border and title.
|
|
||||||
" - height: content height without border and title.
|
|
||||||
" - title: (optional) title.
|
|
||||||
" - border: (optional) border as number list, like [1, 1, 1 ,1].
|
|
||||||
" - cursorline: (optional) enable cursorline when is 1.
|
|
||||||
" - autohide: (optional) window should be closed on CursorMoved when is 1.
|
|
||||||
function! coc#float#create_float_win(winid, bufnr, config) abort
|
|
||||||
call coc#float#close_auto_hide_wins(a:winid)
|
|
||||||
" use exists
|
|
||||||
if a:winid && coc#float#valid(a:winid)
|
|
||||||
if s:is_vim
|
|
||||||
let [line, col] = s:popup_position(a:config)
|
|
||||||
call popup_move(a:winid, {
|
|
||||||
\ 'line': line,
|
|
||||||
\ 'col': col,
|
|
||||||
\ 'minwidth': a:config['width'],
|
|
||||||
\ 'minheight': a:config['height'],
|
|
||||||
\ 'maxwidth': a:config['width'],
|
|
||||||
\ 'maxheight': a:config['height'],
|
|
||||||
\ })
|
|
||||||
let opts = {
|
|
||||||
\ 'cursorline': get(a:config, 'cursorline', 0),
|
|
||||||
\ 'title': get(a:config, 'title', ''),
|
|
||||||
\ }
|
|
||||||
if !s:empty_border(get(a:config, 'border', []))
|
|
||||||
let opts['border'] = a:config['border']
|
|
||||||
endif
|
|
||||||
call popup_setoptions(a:winid, opts)
|
|
||||||
return [a:winid, winbufnr(a:winid)]
|
|
||||||
else
|
|
||||||
let config = s:convert_config_nvim(a:config)
|
|
||||||
" not reuse related windows
|
|
||||||
call coc#float#nvim_close_related(a:winid)
|
|
||||||
call nvim_win_set_config(a:winid, config)
|
|
||||||
call coc#float#nvim_create_related(a:winid, config, a:config)
|
|
||||||
return [a:winid, winbufnr(a:winid)]
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let winid = 0
|
|
||||||
if s:is_vim
|
|
||||||
let [line, col] = s:popup_position(a:config)
|
|
||||||
let bufnr = coc#float#create_float_buf(a:bufnr)
|
|
||||||
let title = get(a:config, 'title', '')
|
|
||||||
let opts = {
|
|
||||||
\ 'title': title,
|
|
||||||
\ 'line': line,
|
|
||||||
\ 'col': col,
|
|
||||||
\ 'padding': empty(title) ? [0, 1, 0, 1] : [0, 0, 0, 0],
|
|
||||||
\ 'borderchars': s:borderchars,
|
|
||||||
\ 'highlight': 'CocFloating',
|
|
||||||
\ 'fixed': 1,
|
|
||||||
\ 'cursorline': get(a:config, 'cursorline', 0),
|
|
||||||
\ 'minwidth': a:config['width'],
|
|
||||||
\ 'minheight': a:config['height'],
|
|
||||||
\ 'maxwidth': a:config['width'],
|
|
||||||
\ 'maxheight': a:config['height']
|
|
||||||
\ }
|
|
||||||
if get(a:config, 'close', 0)
|
|
||||||
let opts['close'] = 'button'
|
|
||||||
endif
|
|
||||||
if !s:empty_border(get(a:config, 'border', []))
|
|
||||||
let opts['border'] = a:config['border']
|
|
||||||
endif
|
|
||||||
let winid = popup_create(bufnr, opts)
|
|
||||||
if winid == 0
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
if has("patch-8.1.2281")
|
|
||||||
call setwinvar(winid, '&showbreak', 'NONE')
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let config = s:convert_config_nvim(a:config)
|
|
||||||
let bufnr = coc#float#create_float_buf(a:bufnr)
|
|
||||||
let winid = nvim_open_win(bufnr, 0, config)
|
|
||||||
if winid == 0
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
call setwinvar(winid, '&winhl', 'Normal:CocFloating,NormalNC:CocFloating,FoldColumn:CocFloating,CursorLine:CocMenuSel')
|
|
||||||
call setwinvar(winid, '&signcolumn', 'no')
|
|
||||||
" no left border
|
|
||||||
if s:empty_border(get(a:config, 'border', [])) || a:config['border'][3] == 0
|
|
||||||
call setwinvar(winid, '&foldcolumn', 1)
|
|
||||||
endif
|
|
||||||
call coc#float#nvim_create_related(winid, config, a:config)
|
|
||||||
endif
|
|
||||||
if !s:is_vim
|
|
||||||
" change cursorline option affects vim's own highlight
|
|
||||||
call setwinvar(winid, '&cursorline', get(a:config, 'cursorline', 0))
|
|
||||||
call setwinvar(winid, 'border', get(a:config, 'border', []))
|
|
||||||
endif
|
|
||||||
if get(a:config, 'autohide', 0)
|
|
||||||
call setwinvar(winid, 'autohide', 1)
|
|
||||||
endif
|
|
||||||
if s:is_vim || has('nvim-0.5.0')
|
|
||||||
call setwinvar(winid, '&scrolloff', 0)
|
|
||||||
endif
|
|
||||||
call setwinvar(winid, '&list', 0)
|
|
||||||
call setwinvar(winid, '&number', 0)
|
|
||||||
call setwinvar(winid, '&relativenumber', 0)
|
|
||||||
call setwinvar(winid, '&cursorcolumn', 0)
|
|
||||||
call setwinvar(winid, '&colorcolumn', 0)
|
|
||||||
call setwinvar(winid, 'float', 1)
|
|
||||||
call setwinvar(winid, '&wrap', 1)
|
|
||||||
call setwinvar(winid, '&linebreak', 1)
|
|
||||||
call setwinvar(winid, '&conceallevel', 2)
|
|
||||||
let g:coc_last_float_win = winid
|
|
||||||
call coc#util#do_autocmd('CocOpenFloat')
|
|
||||||
return [winid, winbufnr(winid)]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#valid(winid) abort
|
|
||||||
if a:winid == 0 || type(a:winid) != 0
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
if s:is_vim
|
|
||||||
return s:popup_visible(a:winid)
|
|
||||||
endif
|
|
||||||
if exists('*nvim_win_is_valid') && nvim_win_is_valid(a:winid)
|
|
||||||
let config = nvim_win_get_config(a:winid)
|
|
||||||
return !empty(get(config, 'relative', ''))
|
|
||||||
endif
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" create buffer for popup/float window
|
|
||||||
function! coc#float#create_float_buf(bufnr) abort
|
|
||||||
" reuse buffer cause error on vim8
|
|
||||||
if a:bufnr && bufloaded(a:bufnr)
|
|
||||||
return a:bufnr
|
|
||||||
endif
|
|
||||||
if s:is_vim
|
|
||||||
noa let bufnr = bufadd('')
|
|
||||||
noa call bufload(bufnr)
|
|
||||||
else
|
|
||||||
noa let bufnr = nvim_create_buf(v:false, v:true)
|
|
||||||
endif
|
|
||||||
" Don't use popup filetype, it would crash on reuse!
|
|
||||||
call setbufvar(bufnr, '&buftype', 'nofile')
|
|
||||||
call setbufvar(bufnr, '&bufhidden', 'hide')
|
|
||||||
call setbufvar(bufnr, '&swapfile', 0)
|
|
||||||
call setbufvar(bufnr, '&tabstop', 2)
|
|
||||||
call setbufvar(bufnr, '&undolevels', -1)
|
|
||||||
return bufnr
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" border window for neovim, content config with border
|
|
||||||
function! coc#float#nvim_border_win(config, border, title, related) abort
|
|
||||||
if s:empty_border(a:border)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
" width height col row relative
|
|
||||||
noa let bufnr = nvim_create_buf(v:false, v:true)
|
|
||||||
call setbufvar(bufnr, '&bufhidden', 'wipe')
|
|
||||||
let row = a:border[0] ? a:config['row'] - 1 : a:config['row']
|
|
||||||
let col = a:border[3] ? a:config['col'] - 1 : a:config['col']
|
|
||||||
let width = a:config['width'] + a:border[1] + a:border[3]
|
|
||||||
let height = a:config['height'] + a:border[0] + a:border[2]
|
|
||||||
let opt = {
|
|
||||||
\ 'relative': a:config['relative'],
|
|
||||||
\ 'width': width,
|
|
||||||
\ 'height': height,
|
|
||||||
\ 'row': row,
|
|
||||||
\ 'col': col,
|
|
||||||
\ 'focusable': v:false,
|
|
||||||
\ 'style': 'minimal',
|
|
||||||
\ }
|
|
||||||
let winid = nvim_open_win(bufnr, 0, opt)
|
|
||||||
if !winid
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call setwinvar(winid, '&winhl', 'Normal:CocFloating,NormalNC:CocFloating')
|
|
||||||
let lines = coc#float#create_border_lines(a:border, a:title, a:config['width'], a:config['height'])
|
|
||||||
call nvim_buf_set_lines(bufnr, 0, -1, v:false, lines)
|
|
||||||
call add(a:related, winid)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#create_border_lines(border, title, width, height) abort
|
|
||||||
let list = []
|
|
||||||
if a:border[0]
|
|
||||||
let top = (a:border[3] ? s:borderchars[4]: '')
|
|
||||||
\.repeat(s:borderchars[0], a:width)
|
|
||||||
\.(a:border[1] ? s:borderchars[5] : '')
|
|
||||||
if !empty(a:title)
|
|
||||||
let top = coc#helper#str_compose(top, 1, a:title.' ')
|
|
||||||
endif
|
|
||||||
call add(list, top)
|
|
||||||
endif
|
|
||||||
let mid = (a:border[3] ? s:borderchars[3]: '')
|
|
||||||
\.repeat(' ', a:width)
|
|
||||||
\.(a:border[1] ? s:borderchars[1] : '')
|
|
||||||
call extend(list, repeat([mid], a:height))
|
|
||||||
if a:border[2]
|
|
||||||
let bot = (a:border[3] ? s:borderchars[7]: '')
|
|
||||||
\.repeat(s:borderchars[2], a:width)
|
|
||||||
\.(a:border[1] ? s:borderchars[6] : '')
|
|
||||||
call add(list, bot)
|
|
||||||
endif
|
|
||||||
return list
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Create float window for input
|
|
||||||
function! coc#float#create_prompt_win(title, default) abort
|
|
||||||
call coc#float#close_auto_hide_wins()
|
|
||||||
noa let bufnr = nvim_create_buf(v:false, v:true)
|
|
||||||
call nvim_buf_set_lines(bufnr, 0, -1, v:false, [a:default])
|
|
||||||
call setbufvar(bufnr, '&bufhidden', 'wipe')
|
|
||||||
" Calculate col
|
|
||||||
let curr = win_screenpos(winnr())[1] + wincol() - 2
|
|
||||||
let width = min([max([strdisplaywidth(a:title) + 2, s:prompt_win_width]), &columns - 2])
|
|
||||||
if width == &columns - 2
|
|
||||||
let col = 0 - curr
|
|
||||||
else
|
|
||||||
let col = curr + width <= &columns - 2 ? 0 : &columns - s:prompt_win_width
|
|
||||||
endif
|
|
||||||
let config = {
|
|
||||||
\ 'relative': 'cursor',
|
|
||||||
\ 'width': width,
|
|
||||||
\ 'height': 1,
|
|
||||||
\ 'row': 0,
|
|
||||||
\ 'col': col,
|
|
||||||
\ 'style': 'minimal',
|
|
||||||
\ }
|
|
||||||
let winid = nvim_open_win(bufnr, 0, config)
|
|
||||||
if winid == 0
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
call setwinvar(winid, '&winhl', 'Normal:CocFloating,NormalNC:CocFloating')
|
|
||||||
let related = []
|
|
||||||
call coc#float#nvim_border_win(config, [1,1,1,1], a:title, related)
|
|
||||||
call setwinvar(winid, 'related', related)
|
|
||||||
call win_gotoid(winid)
|
|
||||||
inoremap <buffer> <C-a> <Home>
|
|
||||||
inoremap <buffer><expr><C-e> pumvisible() ? "\<C-e>" : "\<End>"
|
|
||||||
exe 'inoremap <silent><buffer> <esc> <C-r>=coc#float#close_i('.winid.')<CR><esc>'
|
|
||||||
exe 'nnoremap <silent><buffer> <esc> :call coc#float#close('.winid.')<CR>'
|
|
||||||
exe 'inoremap <expr><nowait><buffer> <cr> "\<c-r>=coc#float#prompt_insert('.winid.')\<cr>\<esc>"'
|
|
||||||
call feedkeys('A', 'in')
|
|
||||||
return [bufnr, winid]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#close_i(winid) abort
|
|
||||||
call coc#float#close(a:winid)
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#prompt_insert(winid) abort
|
|
||||||
let text = getline('.')
|
|
||||||
let bufnr = winbufnr(a:winid)
|
|
||||||
call coc#rpc#notify('PromptInsert',[text, bufnr])
|
|
||||||
call timer_start(50, { -> coc#float#close(a:winid)})
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Position of cursor relative to editor
|
|
||||||
function! s:win_position() abort
|
|
||||||
let nr = winnr()
|
|
||||||
let [row, col] = win_screenpos(nr)
|
|
||||||
return [row + winline() - 2, col + wincol() - 2]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" get popup position for vim8 based on config of neovim float window
|
|
||||||
function! s:popup_position(config) abort
|
|
||||||
let relative = get(a:config, 'relative', 'editor')
|
|
||||||
if relative ==# 'cursor'
|
|
||||||
return [s:popup_cursor(a:config['row']), s:popup_cursor(a:config['col'])]
|
|
||||||
endif
|
|
||||||
return [a:config['row'] + 1, a:config['col'] + 1]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:popup_cursor(n) abort
|
|
||||||
if a:n == 0
|
|
||||||
return 'cursor'
|
|
||||||
endif
|
|
||||||
if a:n < 0
|
|
||||||
return 'cursor'.a:n
|
|
||||||
endif
|
|
||||||
return 'cursor+'.a:n
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Close float window by id
|
|
||||||
function! coc#float#close(winid) abort
|
|
||||||
if !coc#float#valid(a:winid)
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
if s:is_vim
|
|
||||||
call popup_close(a:winid)
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
call coc#float#nvim_close_related(a:winid)
|
|
||||||
call nvim_win_close(a:winid, 1)
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Float window id on current tab.
|
|
||||||
" return 0 if not found
|
|
||||||
function! coc#float#get_float_win() abort
|
|
||||||
if has('nvim')
|
|
||||||
for i in range(1, winnr('$'))
|
|
||||||
let id = win_getid(i)
|
|
||||||
let config = nvim_win_get_config(id)
|
|
||||||
if (!empty(config) && config['focusable'] == v:true && !empty(config['relative']))
|
|
||||||
if !getwinvar(id, 'button', 0)
|
|
||||||
return id
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
elseif exists('*popup_list')
|
|
||||||
let arr = filter(popup_list(), 'popup_getpos(v:val)["visible"]')
|
|
||||||
if !empty(arr)
|
|
||||||
return arr[0]
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#get_float_win_list() abort
|
|
||||||
if s:is_vim && exists('*popup_list')
|
|
||||||
return filter(popup_list(), 'popup_getpos(v:val)["visible"]')
|
|
||||||
elseif has('nvim') && exists('*nvim_win_get_config')
|
|
||||||
let res = []
|
|
||||||
for i in range(1, winnr('$'))
|
|
||||||
let id = win_getid(i)
|
|
||||||
let config = nvim_win_get_config(id)
|
|
||||||
" ignore border & button window
|
|
||||||
if (!empty(config) && config['focusable'] == v:true && !empty(config['relative']))
|
|
||||||
if !getwinvar(id, 'button', 0)
|
|
||||||
call add(res, id)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
return []
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Check if a float window is scrollable
|
|
||||||
function! coc#float#scrollable(winid) abort
|
|
||||||
let bufnr = winbufnr(a:winid)
|
|
||||||
if bufnr == -1
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
if s:is_vim
|
|
||||||
let pos = popup_getpos(a:winid)
|
|
||||||
" scrollbar enabled
|
|
||||||
if get(popup_getoptions(a:winid), 'scrollbar', 0)
|
|
||||||
return get(pos, 'scrollbar', 0)
|
|
||||||
endif
|
|
||||||
let ch = coc#float#content_height(bufnr, pos['core_width'], getwinvar(a:winid, '&wrap'))
|
|
||||||
return ch > pos['core_height']
|
|
||||||
else
|
|
||||||
let height = nvim_win_get_height(a:winid)
|
|
||||||
let width = nvim_win_get_width(a:winid)
|
|
||||||
if width > 1 && getwinvar(a:winid, '&foldcolumn', 0)
|
|
||||||
" since we use foldcolumn for left pading
|
|
||||||
let width = width - 1
|
|
||||||
endif
|
|
||||||
let ch = coc#float#content_height(bufnr, width, getwinvar(a:winid, '&wrap'))
|
|
||||||
return ch > height
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#has_scroll() abort
|
|
||||||
let win_ids = filter(coc#float#get_float_win_list(), 'coc#float#scrollable(v:val)')
|
|
||||||
return !empty(win_ids)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#scroll(forward, ...)
|
|
||||||
if !has('nvim-0.4.3') && !has('patch-8.2.0750')
|
|
||||||
throw 'coc#float#scroll() requires nvim >= 0.4.3 or vim >= 8.2.0750'
|
|
||||||
endif
|
|
||||||
let amount = get(a:, 1, 0)
|
|
||||||
let win_ids = filter(coc#float#get_float_win_list(), 'coc#float#scrollable(v:val)')
|
|
||||||
if empty(win_ids)
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
if has('nvim')
|
|
||||||
call timer_start(10, { -> s:scroll_nvim(win_ids, a:forward, amount)})
|
|
||||||
else
|
|
||||||
call timer_start(10, { -> s:scroll_vim(win_ids, a:forward, amount)})
|
|
||||||
endif
|
|
||||||
return mode() =~ '^i' ? "" : "\<Ignore>"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:scroll_nvim(win_ids, forward, amount) abort
|
|
||||||
let curr = win_getid()
|
|
||||||
for id in a:win_ids
|
|
||||||
if nvim_win_is_valid(id)
|
|
||||||
let wrapped = 0
|
|
||||||
let width = nvim_win_get_width(id)
|
|
||||||
if getwinvar(id, '&wrap', 0)
|
|
||||||
if width > 1 && getwinvar(id, '&foldcolumn', 0)
|
|
||||||
let width = width - 1
|
|
||||||
endif
|
|
||||||
for line in nvim_buf_get_lines(winbufnr(id), 0, -1, v:false)
|
|
||||||
if strdisplaywidth(line) > width
|
|
||||||
let wrapped = 1
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
noa call win_gotoid(id)
|
|
||||||
let height = nvim_win_get_height(id)
|
|
||||||
let firstline = line('w0')
|
|
||||||
let lastline = line('w$')
|
|
||||||
let linecount = line('$')
|
|
||||||
let delta = a:amount ? a:amount : max([1, height - 1])
|
|
||||||
if a:forward
|
|
||||||
if lastline == linecount && strdisplaywidth(line('$')) <= width
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
if !a:amount && firstline != lastline
|
|
||||||
execute 'noa normal! Lzt'
|
|
||||||
else
|
|
||||||
execute 'noa normal! H'.delta.'jzt'
|
|
||||||
endif
|
|
||||||
let lnum = line('.')
|
|
||||||
while lnum < linecount && line('w0') == firstline && line('w$') == lastline
|
|
||||||
execute 'noa normal! jzt'
|
|
||||||
let lnum = lnum + 1
|
|
||||||
endwhile
|
|
||||||
else
|
|
||||||
if !a:amount && firstline != lastline
|
|
||||||
execute 'noa normal! Hzb'
|
|
||||||
else
|
|
||||||
execute 'noa normal! L'.delta.'kzb'
|
|
||||||
endif
|
|
||||||
let lnum = line('.')
|
|
||||||
while lnum > 1 && line('w0') == firstline && line('w$') == lastline
|
|
||||||
execute 'noa normal! kzb'
|
|
||||||
let lnum = lnum - 1
|
|
||||||
endwhile
|
|
||||||
endif
|
|
||||||
call coc#float#nvim_scrollbar(id)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
noa call win_gotoid(curr)
|
|
||||||
redraw
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:scroll_vim(win_ids, forward, amount) abort
|
|
||||||
for id in a:win_ids
|
|
||||||
if s:popup_visible(id)
|
|
||||||
let pos = popup_getpos(id)
|
|
||||||
let bufnr = winbufnr(id)
|
|
||||||
let linecount = get(getbufinfo(bufnr)[0], 'linecount', 0)
|
|
||||||
" for forward use last line (or last line + 1) as first line
|
|
||||||
if a:forward
|
|
||||||
if pos['firstline'] == pos['lastline']
|
|
||||||
call popup_setoptions(id, {'firstline': min([pos['firstline'] + 1, linecount])})
|
|
||||||
else
|
|
||||||
if pos['lastline'] == linecount
|
|
||||||
let win_width = pos['core_width']
|
|
||||||
let text = getbufline(bufnr, '$')[0]
|
|
||||||
if strdisplaywidth(text) <= win_width
|
|
||||||
" last line shown
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let lnum = a:amount ? min([linecount, pos['firstline'] + a:amount]) : pos['lastline']
|
|
||||||
call popup_setoptions(id, {'firstline': lnum})
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
if pos['firstline'] == 1
|
|
||||||
call win_execute(id, 'normal! gg0')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
" we could only change firstline
|
|
||||||
" iterate lines before last lines to fill content height - 1
|
|
||||||
let total_height = a:amount ? min([a:amount, pos['core_height']]) : pos['core_height'] - 1
|
|
||||||
if total_height == 0
|
|
||||||
call popup_setoptions(id, {'firstline': pos['firstline'] - 1})
|
|
||||||
else
|
|
||||||
let lines = getbufline(bufnr, 1, '$')
|
|
||||||
let curr = pos['firstline'] - 1
|
|
||||||
let width = pos['core_width']
|
|
||||||
let used = 0
|
|
||||||
while v:true
|
|
||||||
if curr == 1
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
let w = max([1, strdisplaywidth(lines[curr - 1])])
|
|
||||||
let used += float2nr(ceil(str2float(string(w))/width))
|
|
||||||
if used > total_height
|
|
||||||
let curr = curr == pos['firstline'] -1 ? curr : curr + 1
|
|
||||||
break
|
|
||||||
elseif used == total_height
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
let curr = curr - 1
|
|
||||||
endwhile
|
|
||||||
call popup_setoptions(id, {'firstline': curr})
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
redraw
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:popup_visible(id) abort
|
|
||||||
let pos = popup_getpos(a:id)
|
|
||||||
if !empty(pos) && get(pos, 'visible', 0)
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:convert_config_nvim(config) abort
|
|
||||||
let result = coc#helper#dict_omit(a:config, ['title', 'border', 'cursorline', 'autohide', 'close'])
|
|
||||||
let border = get(a:config, 'border', [])
|
|
||||||
if !s:empty_border(border)
|
|
||||||
if result['relative'] ==# 'cursor' && result['row'] < 0
|
|
||||||
" move top when has bottom border
|
|
||||||
if get(border, 2, 0)
|
|
||||||
let result['row'] = result['row'] - 1
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
" move down when has top border
|
|
||||||
if get(border, 0, 0)
|
|
||||||
let result['row'] = result['row'] + 1
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
" move right when has left border
|
|
||||||
if get(border, 3, 0)
|
|
||||||
let result['col'] = result['col'] + 1
|
|
||||||
endif
|
|
||||||
let result['width'] = result['width'] + 1 - get(border,3, 0)
|
|
||||||
else
|
|
||||||
let result['width'] = result['width'] + 1
|
|
||||||
endif
|
|
||||||
return result
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Close windows that could auto hide
|
|
||||||
function! coc#float#close_auto_hide_wins(...) abort
|
|
||||||
let winids = coc#float#get_float_win_list()
|
|
||||||
let except = get(a:, 1, 0)
|
|
||||||
for id in winids
|
|
||||||
if except && id == except
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
if getwinvar(id, 'autohide', 0)
|
|
||||||
call coc#float#close(id)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" neovim only
|
|
||||||
function! coc#float#nvim_close_btn(config, winid, close, border, related) abort
|
|
||||||
if !a:close
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let config = {
|
|
||||||
\ 'relative': a:config['relative'],
|
|
||||||
\ 'width': 1,
|
|
||||||
\ 'height': 1,
|
|
||||||
\ 'row': get(a:border, 0, 0) ? a:config['row'] - 1 : a:config['row'],
|
|
||||||
\ 'col': a:config['col'] + a:config['width'],
|
|
||||||
\ 'focusable': v:true,
|
|
||||||
\ 'style': 'minimal',
|
|
||||||
\ }
|
|
||||||
noa let bufnr = nvim_create_buf(v:false, v:true)
|
|
||||||
call setbufvar(bufnr, '&bufhidden', 'wipe')
|
|
||||||
call nvim_buf_set_lines(bufnr, 0, -1, v:false, ['X'])
|
|
||||||
let winid = nvim_open_win(bufnr, 0, config)
|
|
||||||
" map for winid & close_winid
|
|
||||||
if winid
|
|
||||||
call setwinvar(winid, 'button', 1)
|
|
||||||
call setwinvar(a:winid, 'close_winid', winid)
|
|
||||||
call setwinvar(winid, '&winhl', 'Normal:CocFloating,NormalNC:CocFloating')
|
|
||||||
call add(a:related, winid)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#nvim_check_close(winid) abort
|
|
||||||
let target = getwinvar(a:winid, 'target_winid', 0)
|
|
||||||
if target
|
|
||||||
call coc#float#close(target)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Create padding window by config of current window & border config
|
|
||||||
function! coc#float#nvim_right_pad(config, border, related) abort
|
|
||||||
" Check right border
|
|
||||||
if !empty(a:border) && get(a:border, 1, 0)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let config = {
|
|
||||||
\ 'relative': a:config['relative'],
|
|
||||||
\ 'width': 1,
|
|
||||||
\ 'height': a:config['height'],
|
|
||||||
\ 'row': a:config['row'],
|
|
||||||
\ 'col': a:config['col'] + a:config['width'],
|
|
||||||
\ 'focusable': v:false,
|
|
||||||
\ 'style': 'minimal',
|
|
||||||
\ }
|
|
||||||
noa let bufnr = nvim_create_buf(v:false, v:true)
|
|
||||||
call setbufvar(bufnr, '&bufhidden', 'wipe')
|
|
||||||
call nvim_buf_set_lines(bufnr, 0, -1, v:false, repeat([' '], a:config['height']))
|
|
||||||
let winid = nvim_open_win(bufnr, 0, config)
|
|
||||||
if winid
|
|
||||||
call setwinvar(winid, 'ispad', 1)
|
|
||||||
call setwinvar(winid, '&winhl', 'Normal:CocFloating,NormalNC:CocFloating')
|
|
||||||
call add(a:related, winid)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#content_height(bufnr, width, wrap) abort
|
|
||||||
if !bufloaded(a:bufnr)
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
if !a:wrap
|
|
||||||
return has('nvim') ? nvim_buf_line_count(a:bufnr) : len(getbufline(a:bufnr, 1, '$'))
|
|
||||||
endif
|
|
||||||
let lines = has('nvim') ? nvim_buf_get_lines(a:bufnr, 0, -1, 0) : getbufline(a:bufnr, 1, '$')
|
|
||||||
let total = 0
|
|
||||||
for line in lines
|
|
||||||
let dw = max([1, strdisplaywidth(line)])
|
|
||||||
let total += float2nr(ceil(str2float(string(dw))/a:width))
|
|
||||||
endfor
|
|
||||||
return total
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:add_related(winid, target) abort
|
|
||||||
let arr = getwinvar(a:target, 'related', [])
|
|
||||||
if index(arr, a:winid) >= 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call add(arr, a:winid)
|
|
||||||
call setwinvar(a:target, 'related', arr)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#nvim_refresh_scrollbar() abort
|
|
||||||
let id = getwinvar(win_getid(), 'scrollbar', 0)
|
|
||||||
if coc#float#valid(id)
|
|
||||||
call coc#float#nvim_scrollbar(win_getid())
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Close related windows for neovim.
|
|
||||||
function! coc#float#nvim_close_related(winid) abort
|
|
||||||
if !has('nvim') || !a:winid
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let winids = getwinvar(a:winid, 'related', [])
|
|
||||||
if !empty(winids)
|
|
||||||
call nvim_win_del_var(a:winid, 'related')
|
|
||||||
endif
|
|
||||||
for id in winids
|
|
||||||
if nvim_win_is_valid(id) && id != a:winid
|
|
||||||
call nvim_win_close(id, 1)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#nvim_create_related(winid, config, opts) abort
|
|
||||||
let related = []
|
|
||||||
call coc#float#nvim_close_btn(a:config, a:winid, get(a:opts, 'close', 0), get(a:opts, 'border', []), related)
|
|
||||||
call coc#float#nvim_border_win(a:config, get(a:opts, 'border', []), get(a:opts, 'title', ''), related)
|
|
||||||
call coc#float#nvim_right_pad(a:config, get(a:opts, 'border', []), related)
|
|
||||||
for id in related
|
|
||||||
call setwinvar(id, 'target_winid', a:winid)
|
|
||||||
endfor
|
|
||||||
call setwinvar(a:winid, 'related', related)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Create scrollbar for winid
|
|
||||||
" Need called on create, config, buffer change, scrolled
|
|
||||||
function! coc#float#nvim_scrollbar(winid) abort
|
|
||||||
if !has('nvim-0.4.3')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if a:winid == 0 || !nvim_win_is_valid(a:winid) || getwinvar(a:winid, 'button', 0)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let config = nvim_win_get_config(a:winid)
|
|
||||||
" ignore border & button window
|
|
||||||
if (!get(config, 'focusable', v:false) || empty(get(config, 'relative', '')))
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let [row, column] = nvim_win_get_position(a:winid)
|
|
||||||
let width = nvim_win_get_width(a:winid)
|
|
||||||
let height = nvim_win_get_height(a:winid)
|
|
||||||
let bufnr = winbufnr(a:winid)
|
|
||||||
let cw = getwinvar(a:winid, '&foldcolumn', 0) ? width - 1 : width
|
|
||||||
let ch = coc#float#content_height(bufnr, cw, getwinvar(a:winid, '&wrap'))
|
|
||||||
let close_winid = getwinvar(a:winid, 'close_winid', 0)
|
|
||||||
let border = getwinvar(a:winid, 'border', [])
|
|
||||||
let move_down = close_winid && !get(border, 0, 0)
|
|
||||||
if move_down
|
|
||||||
let height = height - 1
|
|
||||||
if height == 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let id = 0
|
|
||||||
if nvim_win_is_valid(getwinvar(a:winid, 'scrollbar', 0))
|
|
||||||
let id = getwinvar(a:winid, 'scrollbar', 0)
|
|
||||||
endif
|
|
||||||
if ch <= height || height == 0
|
|
||||||
" no scrollbar, remove exists
|
|
||||||
if id
|
|
||||||
call nvim_win_del_var(a:winid, 'scrollbar')
|
|
||||||
call coc#float#close(id)
|
|
||||||
endif
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if height == 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if id && bufloaded(winbufnr(id))
|
|
||||||
let sbuf = winbufnr(id)
|
|
||||||
else
|
|
||||||
noa let sbuf = nvim_create_buf(v:false, v:true)
|
|
||||||
call setbufvar(sbuf, '&bufhidden', 'wipe')
|
|
||||||
endif
|
|
||||||
call nvim_buf_set_lines(sbuf, 0, -1, v:false, repeat([' '], height))
|
|
||||||
let opts = {
|
|
||||||
\ 'row': move_down ? row + 1 : row,
|
|
||||||
\ 'col': column + width,
|
|
||||||
\ 'relative': 'editor',
|
|
||||||
\ 'width': 1,
|
|
||||||
\ 'height': height,
|
|
||||||
\ 'focusable': v:false,
|
|
||||||
\ 'style': 'minimal',
|
|
||||||
\ }
|
|
||||||
if id
|
|
||||||
call nvim_win_set_config(id, opts)
|
|
||||||
else
|
|
||||||
let id = nvim_open_win(sbuf, 0 , opts)
|
|
||||||
call setwinvar(id, 'isscrollbar', 1)
|
|
||||||
call setwinvar(id, 'target_winid', a:winid)
|
|
||||||
endif
|
|
||||||
let thumb_height = max([1, float2nr(floor(height * (height + 0.0)/ch))])
|
|
||||||
let curr = win_getid()
|
|
||||||
if curr != a:winid
|
|
||||||
noa call win_gotoid(a:winid)
|
|
||||||
endif
|
|
||||||
let firstline = line('w0')
|
|
||||||
let lastline = line('w$')
|
|
||||||
let linecount = line('$')
|
|
||||||
if firstline == 1
|
|
||||||
let start = 0
|
|
||||||
elseif lastline == linecount
|
|
||||||
let start = height - thumb_height
|
|
||||||
else
|
|
||||||
let start = max([1, float2nr(round((height - thumb_height + 0.0)*(firstline - 1.0)/(ch - height)))])
|
|
||||||
endif
|
|
||||||
if curr != a:winid
|
|
||||||
noa call win_gotoid(curr)
|
|
||||||
endif
|
|
||||||
" add highlights
|
|
||||||
call nvim_buf_clear_namespace(sbuf, s:scrollbar_ns, 0, -1)
|
|
||||||
for idx in range(0, height - 1)
|
|
||||||
if idx >= start && idx < start + thumb_height
|
|
||||||
call nvim_buf_add_highlight(sbuf, s:scrollbar_ns, 'PmenuThumb', idx, 0, 1)
|
|
||||||
else
|
|
||||||
call nvim_buf_add_highlight(sbuf, s:scrollbar_ns, 'PmenuSbar', idx, 0, 1)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
" create scrollbar outside window
|
|
||||||
call setwinvar(a:winid, 'scrollbar', id)
|
|
||||||
call s:add_related(id, a:winid)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#nvim_check_related() abort
|
|
||||||
if !has('nvim')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let invalids = []
|
|
||||||
for i in range(1, winnr('$'))
|
|
||||||
let id = win_getid(i)
|
|
||||||
let target = getwinvar(id, 'target_winid', 0)
|
|
||||||
if target && !nvim_win_is_valid(target)
|
|
||||||
call add(invalids, id)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
for id in invalids
|
|
||||||
noa call nvim_win_close(id, 1)
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Dimension of window with lines relative to cursor
|
|
||||||
" Width & height excludes border & padding
|
|
||||||
function! coc#float#get_config_cursor(lines, config) abort
|
|
||||||
let preferTop = get(a:config, 'preferTop', 0)
|
|
||||||
let title = get(a:config, 'title', '')
|
|
||||||
let border = get(a:config, 'border', [0, 0, 0, 0])
|
|
||||||
if s:empty_border(border) && len(title)
|
|
||||||
let border = [1, 1, 1, 1]
|
|
||||||
endif
|
|
||||||
let bh = get(border, 0, 0) + get(border, 2, 0)
|
|
||||||
let vh = &lines - &cmdheight - 1
|
|
||||||
if vh <= 0
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
let maxWidth = min([get(a:config, 'maxWidth', 80), &columns - 1])
|
|
||||||
if maxWidth < 3
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
let maxHeight = min([get(a:config, 'maxHeight', 80), vh])
|
|
||||||
let ch = 0
|
|
||||||
let width = min([40, strdisplaywidth(title)]) + 3
|
|
||||||
for line in a:lines
|
|
||||||
let dw = max([1, strdisplaywidth(line)])
|
|
||||||
let width = max([width, dw + 2])
|
|
||||||
let ch += float2nr(ceil(str2float(string(dw))/(maxWidth - 2)))
|
|
||||||
endfor
|
|
||||||
let width = min([maxWidth, width])
|
|
||||||
let [lineIdx, colIdx] = s:win_position()
|
|
||||||
" How much we should move left
|
|
||||||
let offsetX = min([get(a:config, 'offsetX', 0), colIdx])
|
|
||||||
let showTop = 0
|
|
||||||
let hb = vh - lineIdx -1
|
|
||||||
if lineIdx > bh + 2 && (preferTop || (lineIdx > hb && hb < ch + bh))
|
|
||||||
let showTop = 1
|
|
||||||
endif
|
|
||||||
let height = min([maxHeight, ch + bh, showTop ? lineIdx - 1 : hb])
|
|
||||||
if height <= bh
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
let col = - max([offsetX, colIdx - (&columns - 1 - width)])
|
|
||||||
let row = showTop ? - height : 1
|
|
||||||
return {
|
|
||||||
\ 'row': row,
|
|
||||||
\ 'col': col,
|
|
||||||
\ 'width': width - 2,
|
|
||||||
\ 'height': height - bh
|
|
||||||
\ }
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#float#get_config_pum(lines, pumconfig, maxwidth) abort
|
|
||||||
if !pumvisible()
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
let pw = a:pumconfig['width'] + get(a:pumconfig, 'scrollbar', 0)
|
|
||||||
let rp = &columns - a:pumconfig['col'] - pw
|
|
||||||
let showRight = a:pumconfig['col'] > rp ? 0 : 1
|
|
||||||
let maxWidth = showRight ? min([rp - 1, a:maxwidth]) : min([a:pumconfig['col'] - 1, a:maxwidth])
|
|
||||||
let maxHeight = &lines - a:pumconfig['row'] - &cmdheight - 1
|
|
||||||
if maxWidth <= 2 || maxHeight < 1
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
let ch = 0
|
|
||||||
let width = 0
|
|
||||||
for line in a:lines
|
|
||||||
let dw = max([1, strdisplaywidth(line)])
|
|
||||||
let width = max([width, dw + 2])
|
|
||||||
let ch += float2nr(ceil(str2float(string(dw))/(maxWidth - 2)))
|
|
||||||
endfor
|
|
||||||
let width = min([maxWidth, width])
|
|
||||||
let height = min([maxHeight, ch])
|
|
||||||
return {
|
|
||||||
\ 'col': showRight ? a:pumconfig['col'] + pw : a:pumconfig['col'] - width - 1,
|
|
||||||
\ 'row': a:pumconfig['row'],
|
|
||||||
\ 'height': height,
|
|
||||||
\ 'width': width - 2 + (s:is_vim && ch > height ? -1 : 0),
|
|
||||||
\ 'relative': 'editor'
|
|
||||||
\ }
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:empty_border(border) abort
|
|
||||||
if empty(a:border)
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
if a:border[0] == 0 && a:border[1] == 0 && a:border[2] == 0 && a:border[3] == 0
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
|
@ -1,56 +0,0 @@
|
||||||
" Helper methods for viml
|
|
||||||
|
|
||||||
" insert inserted to line at position, use ... when result is too long
|
|
||||||
" line should only contains character has strwidth equals 1
|
|
||||||
function! coc#helper#str_compose(line, position, inserted) abort
|
|
||||||
let width = strwidth(a:line)
|
|
||||||
let text = a:inserted
|
|
||||||
let res = a:line
|
|
||||||
let need_truncate = a:position + strwidth(text) + 1 > width
|
|
||||||
if need_truncate
|
|
||||||
let remain = width - a:position - 3
|
|
||||||
if remain < 2
|
|
||||||
" use text for full line, use first & end of a:line, ignore position
|
|
||||||
let res = strcharpart(a:line, 0, 1)
|
|
||||||
let w = strwidth(res)
|
|
||||||
for i in range(strchars(text))
|
|
||||||
let c = strcharpart(text, i, 1)
|
|
||||||
let a = strwidth(c)
|
|
||||||
if w + a <= width - 1
|
|
||||||
let w = w + a
|
|
||||||
let res = res.c
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
let res = res.strcharpart(a:line, w)
|
|
||||||
else
|
|
||||||
let res = strcharpart(a:line, 0, a:position)
|
|
||||||
let w = strwidth(res)
|
|
||||||
for i in range(strchars(text))
|
|
||||||
let c = strcharpart(text, i, 1)
|
|
||||||
let a = strwidth(c)
|
|
||||||
if w + a <= width - 3
|
|
||||||
let w = w + a
|
|
||||||
let res = res.c
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
let res = res.'..'
|
|
||||||
let w = w + 2
|
|
||||||
let res = res.strcharpart(a:line, w)
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let first = strcharpart(a:line, 0, a:position)
|
|
||||||
let res = first.text.strcharpart(a:line, a:position + strwidth(text))
|
|
||||||
endif
|
|
||||||
return res
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Return new dict with keys removed
|
|
||||||
function! coc#helper#dict_omit(dict, keys) abort
|
|
||||||
let res = {}
|
|
||||||
for key in keys(a:dict)
|
|
||||||
if index(a:keys, key) == -1
|
|
||||||
let res[key] = a:dict[key]
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return res
|
|
||||||
endfunction
|
|
|
@ -1,292 +0,0 @@
|
||||||
let s:activated = 0
|
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:saved_ve = &t_ve
|
|
||||||
let s:saved_cursor = &guicursor
|
|
||||||
let s:gui = has('gui_running') || has('nvim')
|
|
||||||
|
|
||||||
function! coc#list#get_chars()
|
|
||||||
return {
|
|
||||||
\ '<plug>': "\<Plug>",
|
|
||||||
\ '<esc>': "\<Esc>",
|
|
||||||
\ '<tab>': "\<Tab>",
|
|
||||||
\ '<s-tab>': "\<S-Tab>",
|
|
||||||
\ '<bs>': "\<bs>",
|
|
||||||
\ '<right>': "\<right>",
|
|
||||||
\ '<left>': "\<left>",
|
|
||||||
\ '<up>': "\<up>",
|
|
||||||
\ '<down>': "\<down>",
|
|
||||||
\ '<home>': "\<home>",
|
|
||||||
\ '<end>': "\<end>",
|
|
||||||
\ '<cr>': "\<cr>",
|
|
||||||
\ '<PageUp>' : "\<PageUp>",
|
|
||||||
\ '<PageDown>' : "\<PageDown>",
|
|
||||||
\ '<FocusGained>' : "\<FocusGained>",
|
|
||||||
\ '<ScrollWheelUp>': "\<ScrollWheelUp>",
|
|
||||||
\ '<ScrollWheelDown>': "\<ScrollWheelDown>",
|
|
||||||
\ '<LeftMouse>': "\<LeftMouse>",
|
|
||||||
\ '<LeftDrag>': "\<LeftDrag>",
|
|
||||||
\ '<LeftRelease>': "\<LeftRelease>",
|
|
||||||
\ '<2-LeftMouse>': "\<2-LeftMouse>",
|
|
||||||
\ '<C-a>': "\<C-a>",
|
|
||||||
\ '<C-b>': "\<C-b>",
|
|
||||||
\ '<C-c>': "\<C-c>",
|
|
||||||
\ '<C-d>': "\<C-d>",
|
|
||||||
\ '<C-e>': "\<C-e>",
|
|
||||||
\ '<C-f>': "\<C-f>",
|
|
||||||
\ '<C-g>': "\<C-g>",
|
|
||||||
\ '<C-h>': "\<C-h>",
|
|
||||||
\ '<C-i>': "\<C-i>",
|
|
||||||
\ '<C-j>': "\<C-j>",
|
|
||||||
\ '<C-k>': "\<C-k>",
|
|
||||||
\ '<C-l>': "\<C-l>",
|
|
||||||
\ '<C-m>': "\<C-m>",
|
|
||||||
\ '<C-n>': "\<C-n>",
|
|
||||||
\ '<C-o>': "\<C-o>",
|
|
||||||
\ '<C-p>': "\<C-p>",
|
|
||||||
\ '<C-q>': "\<C-q>",
|
|
||||||
\ '<C-r>': "\<C-r>",
|
|
||||||
\ '<C-s>': "\<C-s>",
|
|
||||||
\ '<C-t>': "\<C-t>",
|
|
||||||
\ '<C-u>': "\<C-u>",
|
|
||||||
\ '<C-v>': "\<C-v>",
|
|
||||||
\ '<C-w>': "\<C-w>",
|
|
||||||
\ '<C-x>': "\<C-x>",
|
|
||||||
\ '<C-y>': "\<C-y>",
|
|
||||||
\ '<C-z>': "\<C-z>",
|
|
||||||
\ '<A-a>': "\<A-a>",
|
|
||||||
\ '<A-b>': "\<A-b>",
|
|
||||||
\ '<A-c>': "\<A-c>",
|
|
||||||
\ '<A-d>': "\<A-d>",
|
|
||||||
\ '<A-e>': "\<A-e>",
|
|
||||||
\ '<A-f>': "\<A-f>",
|
|
||||||
\ '<A-g>': "\<A-g>",
|
|
||||||
\ '<A-h>': "\<A-h>",
|
|
||||||
\ '<A-i>': "\<A-i>",
|
|
||||||
\ '<A-j>': "\<A-j>",
|
|
||||||
\ '<A-k>': "\<A-k>",
|
|
||||||
\ '<A-l>': "\<A-l>",
|
|
||||||
\ '<A-m>': "\<A-m>",
|
|
||||||
\ '<A-n>': "\<A-n>",
|
|
||||||
\ '<A-o>': "\<A-o>",
|
|
||||||
\ '<A-p>': "\<A-p>",
|
|
||||||
\ '<A-q>': "\<A-q>",
|
|
||||||
\ '<A-r>': "\<A-r>",
|
|
||||||
\ '<A-s>': "\<A-s>",
|
|
||||||
\ '<A-t>': "\<A-t>",
|
|
||||||
\ '<A-u>': "\<A-u>",
|
|
||||||
\ '<A-v>': "\<A-v>",
|
|
||||||
\ '<A-w>': "\<A-w>",
|
|
||||||
\ '<A-x>': "\<A-x>",
|
|
||||||
\ '<A-y>': "\<A-y>",
|
|
||||||
\ '<A-z>': "\<A-z>",
|
|
||||||
\}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#getc() abort
|
|
||||||
let c = getchar()
|
|
||||||
return type(c) == type(0) ? nr2char(c) : c
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#getchar() abort
|
|
||||||
let input = coc#list#getc()
|
|
||||||
if 1 != &iminsert
|
|
||||||
return input
|
|
||||||
endif
|
|
||||||
"a language keymap is activated, so input must be resolved to the mapped values.
|
|
||||||
let partial_keymap = mapcheck(input, "l")
|
|
||||||
while partial_keymap !=# ""
|
|
||||||
let full_keymap = maparg(input, "l")
|
|
||||||
if full_keymap ==# "" && len(input) >= 3 "HACK: assume there are no keymaps longer than 3.
|
|
||||||
return input
|
|
||||||
elseif full_keymap ==# partial_keymap
|
|
||||||
return full_keymap
|
|
||||||
endif
|
|
||||||
let c = coc#list#getc()
|
|
||||||
if c ==# "\<Esc>" || c ==# "\<CR>"
|
|
||||||
"if the short sequence has a valid mapping, return that.
|
|
||||||
if !empty(full_keymap)
|
|
||||||
return full_keymap
|
|
||||||
endif
|
|
||||||
return input
|
|
||||||
endif
|
|
||||||
let input .= c
|
|
||||||
let partial_keymap = mapcheck(input, "l")
|
|
||||||
endwhile
|
|
||||||
return input
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#start_prompt(...) abort
|
|
||||||
let eventName = get(a:, 1, 'InputChar')
|
|
||||||
if s:is_vim
|
|
||||||
call s:start_prompt_vim(eventName)
|
|
||||||
else
|
|
||||||
call s:start_prompt(eventName)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:start_prompt_vim(eventName) abort
|
|
||||||
call timer_start(10, {-> s:start_prompt(a:eventName)})
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:start_prompt(eventName)
|
|
||||||
if s:activated | return | endif
|
|
||||||
if !get(g:, 'coc_disable_transparent_cursor', 0)
|
|
||||||
if s:gui
|
|
||||||
if has('nvim-0.5.0') && !empty(s:saved_cursor)
|
|
||||||
set guicursor+=a:ver1-CocCursorTransparent/lCursor
|
|
||||||
endif
|
|
||||||
elseif s:is_vim
|
|
||||||
set t_ve=
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let s:activated = 1
|
|
||||||
try
|
|
||||||
while s:activated
|
|
||||||
let ch = coc#list#getchar()
|
|
||||||
if ch ==# "\u26d4"
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
if ch ==# "\<FocusLost>" || ch ==# "\<FocusGained>" || ch ==# "\<CursorHold>"
|
|
||||||
continue
|
|
||||||
else
|
|
||||||
call coc#rpc#notify(a:eventName, [ch, getcharmod()])
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
catch /^Vim:Interrupt$/
|
|
||||||
let s:activated = 0
|
|
||||||
call coc#rpc#notify(a:eventName, ["\<C-c>"])
|
|
||||||
return
|
|
||||||
endtry
|
|
||||||
let s:activated = 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#setlines(lines, append)
|
|
||||||
if a:append
|
|
||||||
silent call append(line('$'), a:lines)
|
|
||||||
else
|
|
||||||
silent call append(0, a:lines)
|
|
||||||
if exists('*deletebufline')
|
|
||||||
call deletebufline('%', len(a:lines) + 1, '$')
|
|
||||||
else
|
|
||||||
let n = len(a:lines) + 1
|
|
||||||
let saved_reg = @"
|
|
||||||
silent execute n.',$d'
|
|
||||||
let @" = saved_reg
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#options(...)
|
|
||||||
let list = ['--top', '--tab', '--normal', '--no-sort', '--input', '--strict',
|
|
||||||
\ '--regex', '--interactive', '--number-select', '--auto-preview',
|
|
||||||
\ '--ignore-case', '--no-quit', '--first']
|
|
||||||
if get(g:, 'coc_enabled', 0)
|
|
||||||
let names = coc#rpc#request('listNames', [])
|
|
||||||
call extend(list, names)
|
|
||||||
endif
|
|
||||||
return join(list, "\n")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#names(...) abort
|
|
||||||
let names = coc#rpc#request('listNames', [])
|
|
||||||
return join(names, "\n")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#stop_prompt(...)
|
|
||||||
if s:activated
|
|
||||||
let s:activated = 0
|
|
||||||
if get(a:, 1, 0) == 0 && !get(g:, 'coc_disable_transparent_cursor',0)
|
|
||||||
" neovim has bug with revert empty &guicursor
|
|
||||||
if s:gui && !empty(s:saved_cursor)
|
|
||||||
if has('nvim-0.5.0')
|
|
||||||
set guicursor+=a:ver1-Cursor/lCursor
|
|
||||||
let &guicursor = s:saved_cursor
|
|
||||||
endif
|
|
||||||
elseif s:is_vim
|
|
||||||
let &t_ve = s:saved_ve
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
echo ""
|
|
||||||
call feedkeys("\u26d4", 'int')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#status(name)
|
|
||||||
if !exists('b:list_status') | return '' | endif
|
|
||||||
return get(b:list_status, a:name, '')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#create(position, height, name, numberSelect)
|
|
||||||
if a:position ==# 'tab'
|
|
||||||
execute 'silent tabe list:///'.a:name
|
|
||||||
else
|
|
||||||
execute 'silent keepalt '.(a:position ==# 'top' ? '' : 'botright').a:height.'sp list:///'.a:name
|
|
||||||
execute 'resize '.a:height
|
|
||||||
endif
|
|
||||||
if a:numberSelect
|
|
||||||
setl norelativenumber
|
|
||||||
setl number
|
|
||||||
else
|
|
||||||
setl nonumber
|
|
||||||
setl norelativenumber
|
|
||||||
setl signcolumn=yes
|
|
||||||
endif
|
|
||||||
return [bufnr('%'), win_getid()]
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" close list windows
|
|
||||||
function! coc#list#clean_up() abort
|
|
||||||
for i in range(1, winnr('$'))
|
|
||||||
let bufname = bufname(winbufnr(i))
|
|
||||||
if bufname =~# 'list://'
|
|
||||||
execute i.'close!'
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#setup(source)
|
|
||||||
let b:list_status = {}
|
|
||||||
setl buftype=nofile nobuflisted nofen nowrap
|
|
||||||
setl norelativenumber bufhidden=wipe cursorline winfixheight
|
|
||||||
setl tabstop=1 nolist nocursorcolumn undolevels=-1
|
|
||||||
setl signcolumn=auto
|
|
||||||
if has('nvim-0.5.0') || has('patch-8.1.0864')
|
|
||||||
setl scrolloff=0
|
|
||||||
endif
|
|
||||||
if exists('&cursorlineopt')
|
|
||||||
setl cursorlineopt=both
|
|
||||||
endif
|
|
||||||
setl filetype=list
|
|
||||||
syntax case ignore
|
|
||||||
let source = a:source[8:]
|
|
||||||
let name = toupper(source[0]).source[1:]
|
|
||||||
execute 'syntax match Coc'.name.'Line /\v^.*$/'
|
|
||||||
nnoremap <silent><nowait><buffer> <esc> <C-w>c
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#has_preview()
|
|
||||||
for i in range(1, winnr('$'))
|
|
||||||
let preview = getwinvar(i, '&previewwindow')
|
|
||||||
if preview
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#restore(winid, height)
|
|
||||||
let res = win_gotoid(a:winid)
|
|
||||||
if res == 0 | return | endif
|
|
||||||
if winnr('$') == 1
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
execute 'resize '.a:height
|
|
||||||
if s:is_vim
|
|
||||||
redraw
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#list#set_height(height) abort
|
|
||||||
if winnr('$') == 1| return | endif
|
|
||||||
execute 'resize '.a:height
|
|
||||||
endfunction
|
|
|
@ -1,127 +0,0 @@
|
||||||
let s:is_win = has("win32") || has("win64")
|
|
||||||
let s:client = v:null
|
|
||||||
let s:name = 'coc'
|
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
|
|
||||||
function! coc#rpc#start_server()
|
|
||||||
if get(g:, 'coc_node_env', '') ==# 'test'
|
|
||||||
" server already started
|
|
||||||
let s:client = coc#client#create(s:name, [])
|
|
||||||
let s:client['running'] = 1
|
|
||||||
let s:client['chan_id'] = get(g:, 'coc_node_channel_id', 0)
|
|
||||||
call dictwatcheradd(g:, 'coc_node_channel_id', function('s:ChannelSet'))
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if empty(s:client)
|
|
||||||
let cmd = coc#util#job_command()
|
|
||||||
if empty(cmd) | return | endif
|
|
||||||
let $COC_VIMCONFIG = coc#util#get_config_home()
|
|
||||||
let $COC_DATA_HOME = coc#util#get_data_home()
|
|
||||||
let s:client = coc#client#create(s:name, cmd)
|
|
||||||
endif
|
|
||||||
if !coc#client#is_running('coc')
|
|
||||||
call s:client['start']()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#started() abort
|
|
||||||
return !empty(s:client)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#ready()
|
|
||||||
if empty(s:client) || s:client['running'] == 0
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ChannelSet(dict, key, val)
|
|
||||||
let chan_id = get(a:val, 'new', 0)
|
|
||||||
if empty(s:client) | return | endif
|
|
||||||
let s:client['running'] = 1
|
|
||||||
let s:client['chan_id'] = chan_id
|
|
||||||
call dictwatcherdel(g:, 'coc_node_channel_id', function('s:ChannelSet'))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#kill()
|
|
||||||
let pid = get(g:, 'coc_process_pid', 0)
|
|
||||||
if !pid | return | endif
|
|
||||||
if s:is_win
|
|
||||||
call system('taskkill /PID '.pid)
|
|
||||||
else
|
|
||||||
call system('kill -9 '.pid)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#get_errors()
|
|
||||||
return split(execute('messages'), "\n")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#stop()
|
|
||||||
if empty(s:client)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
if s:is_vim
|
|
||||||
call job_stop(ch_getjob(s:client['channel']), 'term')
|
|
||||||
else
|
|
||||||
call jobstop(s:client['chan_id'])
|
|
||||||
endif
|
|
||||||
catch /.*/
|
|
||||||
" ignore
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#restart()
|
|
||||||
if empty(s:client)
|
|
||||||
call coc#rpc#start_server()
|
|
||||||
else
|
|
||||||
call coc#float#close_all()
|
|
||||||
call coc#rpc#request('detach', [])
|
|
||||||
sleep 100m
|
|
||||||
let s:client['command'] = coc#util#job_command()
|
|
||||||
call coc#client#restart(s:name)
|
|
||||||
echohl MoreMsg | echom 'starting coc.nvim service' | echohl None
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#request(method, args) abort
|
|
||||||
if !coc#rpc#ready()
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
return s:client['request'](a:method, a:args)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#notify(method, args) abort
|
|
||||||
if !coc#rpc#ready()
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
call s:client['notify'](a:method, a:args)
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#rpc#request_async(method, args, cb) abort
|
|
||||||
if !coc#rpc#ready()
|
|
||||||
return cb('coc.nvim service not started.')
|
|
||||||
endif
|
|
||||||
call s:client['request_async'](a:method, a:args, a:cb)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" receive async response
|
|
||||||
function! coc#rpc#async_response(id, resp, isErr) abort
|
|
||||||
if empty(s:client)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call coc#client#on_response(s:name, a:id, a:resp, a:isErr)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" send async response to server
|
|
||||||
function! coc#rpc#async_request(id, method, args)
|
|
||||||
let l:Cb = {err, res -> coc#rpc#notify('nvim_async_response_event', [a:id, err, res])}
|
|
||||||
let args = a:args + [l:Cb]
|
|
||||||
try
|
|
||||||
call call(a:method, args)
|
|
||||||
catch /.*/
|
|
||||||
call coc#rpc#notify('nvim_async_response_event', [a:id, v:exception])
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
|
@ -1,68 +0,0 @@
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:map_next = 1
|
|
||||||
|
|
||||||
function! coc#snippet#_select_mappings()
|
|
||||||
if !get(g:, 'coc_selectmode_mapping', 1)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
redir => mappings
|
|
||||||
silent! smap
|
|
||||||
redir END
|
|
||||||
|
|
||||||
for map in map(filter(split(mappings, '\n'),
|
|
||||||
\ "v:val !~# '^s' && v:val !~# '^\\a*\\s*<\\S\\+>'"),
|
|
||||||
\ "matchstr(v:val, '^\\a*\\s*\\zs\\S\\+')")
|
|
||||||
silent! execute 'sunmap' map
|
|
||||||
silent! execute 'sunmap <buffer>' map
|
|
||||||
endfor
|
|
||||||
|
|
||||||
" same behaviour of ultisnips
|
|
||||||
snoremap <silent> <BS> <c-g>c
|
|
||||||
snoremap <silent> <DEL> <c-g>c
|
|
||||||
snoremap <silent> <c-h> <c-g>c
|
|
||||||
snoremap <c-r> <c-g>"_c<c-r>
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#snippet#show_choices(lnum, col, len, values) abort
|
|
||||||
let m = mode()
|
|
||||||
call cursor(a:lnum, a:col + a:len)
|
|
||||||
if m !=# 'i' | startinsert | endif
|
|
||||||
call timer_start(20, { -> coc#_do_complete(a:col - 1, a:values, 0)})
|
|
||||||
redraw
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#snippet#enable()
|
|
||||||
if get(b:, 'coc_snippet_active', 0) == 1
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let b:coc_snippet_active = 1
|
|
||||||
silent! unlet g:coc_selected_text
|
|
||||||
call coc#snippet#_select_mappings()
|
|
||||||
let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
|
|
||||||
let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
|
|
||||||
if maparg(nextkey, 'i') =~# 'expand-jump'
|
|
||||||
let s:map_next = 0
|
|
||||||
endif
|
|
||||||
if s:map_next
|
|
||||||
execute 'inoremap <buffer><nowait><silent>'.nextkey." <C-R>=coc#rpc#request('snippetNext', [])<cr>"
|
|
||||||
endif
|
|
||||||
execute 'inoremap <buffer><nowait><silent>'.prevkey." <C-R>=coc#rpc#request('snippetPrev', [])<cr>"
|
|
||||||
execute 'snoremap <buffer><nowait><silent>'.prevkey." <Esc>:call coc#rpc#request('snippetPrev', [])<cr>"
|
|
||||||
execute 'snoremap <buffer><nowait><silent>'.nextkey." <Esc>:call coc#rpc#request('snippetNext', [])<cr>"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#snippet#disable()
|
|
||||||
if get(b:, 'coc_snippet_active', 0) == 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let b:coc_snippet_active = 0
|
|
||||||
let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
|
|
||||||
let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
|
|
||||||
if s:map_next
|
|
||||||
silent! execute 'iunmap <buffer> <silent> '.nextkey
|
|
||||||
endif
|
|
||||||
silent! execute 'iunmap <buffer> <silent> '.prevkey
|
|
||||||
silent! execute 'sunmap <buffer> <silent> '.prevkey
|
|
||||||
silent! execute 'sunmap <buffer> <silent> '.nextkey
|
|
||||||
endfunction
|
|
|
@ -1,109 +0,0 @@
|
||||||
" ============================================================================
|
|
||||||
" Description: Manage long running tasks.
|
|
||||||
" Author: Qiming Zhao <chemzqm@gmail.com>
|
|
||||||
" Licence: MIT licence
|
|
||||||
" Version: 0.1
|
|
||||||
" Last Modified: April 08, 2019
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:running_task = {}
|
|
||||||
|
|
||||||
function! coc#task#start(id, opts)
|
|
||||||
if coc#task#running(a:id)
|
|
||||||
call coc#task#stop(a:id)
|
|
||||||
endif
|
|
||||||
let cmd = [a:opts['cmd']] + get(a:opts, 'args', [])
|
|
||||||
let cwd = get(a:opts, 'cwd', getcwd())
|
|
||||||
" cmd args cwd pty
|
|
||||||
if s:is_vim
|
|
||||||
let options = {
|
|
||||||
\ 'cwd': cwd,
|
|
||||||
\ 'err_mode': 'nl',
|
|
||||||
\ 'out_mode': 'nl',
|
|
||||||
\ 'err_cb': {channel, message -> s:on_stderr(a:id, [message])},
|
|
||||||
\ 'out_cb': {channel, message -> s:on_stdout(a:id, [message])},
|
|
||||||
\ 'exit_cb': {channel, code -> s:on_exit(a:id, code)},
|
|
||||||
\}
|
|
||||||
if has("patch-8.1.350")
|
|
||||||
let options['noblock'] = 1
|
|
||||||
endif
|
|
||||||
if get(a:opts, 'pty', 0)
|
|
||||||
let options['pty'] = 1
|
|
||||||
endif
|
|
||||||
let job = job_start(cmd, options)
|
|
||||||
let status = job_status(job)
|
|
||||||
if status !=# 'run'
|
|
||||||
echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
|
|
||||||
return v:false
|
|
||||||
endif
|
|
||||||
let s:running_task[a:id] = job
|
|
||||||
else
|
|
||||||
let options = {
|
|
||||||
\ 'cwd': cwd,
|
|
||||||
\ 'on_stderr': {channel, msgs -> s:on_stderr(a:id, filter(msgs, 'v:val !=""'))},
|
|
||||||
\ 'on_stdout': {channel, msgs -> s:on_stdout(a:id, filter(msgs, 'v:val !=""'))},
|
|
||||||
\ 'on_exit': {channel, code -> s:on_exit(a:id, code)},
|
|
||||||
\ 'detach': get(a:opts, 'detach', 0),
|
|
||||||
\}
|
|
||||||
if get(a:opts, 'pty', 0)
|
|
||||||
let options['pty'] = 1
|
|
||||||
endif
|
|
||||||
let chan_id = jobstart(cmd, options)
|
|
||||||
if chan_id <= 0
|
|
||||||
echohl Error | echom 'Failed to start '.a:id.' task' | echohl None
|
|
||||||
return v:false
|
|
||||||
endif
|
|
||||||
let s:running_task[a:id] = chan_id
|
|
||||||
endif
|
|
||||||
return v:true
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#task#stop(id)
|
|
||||||
let job = get(s:running_task, a:id, v:null)
|
|
||||||
if !job | return | endif
|
|
||||||
if s:is_vim
|
|
||||||
call job_stop(job, 'term')
|
|
||||||
else
|
|
||||||
call jobstop(job)
|
|
||||||
endif
|
|
||||||
sleep 50m
|
|
||||||
let running = coc#task#running(a:id)
|
|
||||||
if running
|
|
||||||
echohl Error | echom 'job '.a:id. ' stop failed.' | echohl None
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:on_exit(id, code) abort
|
|
||||||
if get(g:, 'coc_vim_leaving', 0) | return | endif
|
|
||||||
if has_key(s:running_task, a:id)
|
|
||||||
call remove(s:running_task, a:id)
|
|
||||||
endif
|
|
||||||
call coc#rpc#notify('TaskExit', [a:id, a:code])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:on_stderr(id, msgs)
|
|
||||||
if get(g:, 'coc_vim_leaving', 0) | return | endif
|
|
||||||
if len(a:msgs)
|
|
||||||
call coc#rpc#notify('TaskStderr', [a:id, a:msgs])
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:on_stdout(id, msgs)
|
|
||||||
if len(a:msgs)
|
|
||||||
call coc#rpc#notify('TaskStdout', [a:id, a:msgs])
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#task#running(id)
|
|
||||||
if !has_key(s:running_task, a:id) == 1
|
|
||||||
return v:false
|
|
||||||
endif
|
|
||||||
let job = s:running_task[a:id]
|
|
||||||
if s:is_vim
|
|
||||||
let status = job_status(job)
|
|
||||||
return status ==# 'run'
|
|
||||||
endif
|
|
||||||
let [code] = jobwait([job], 10)
|
|
||||||
return code == -1
|
|
||||||
endfunction
|
|
|
@ -1,114 +0,0 @@
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:channel_map = {}
|
|
||||||
let s:is_win = has('win32') || has('win64')
|
|
||||||
|
|
||||||
" start terminal, return [bufnr, pid]
|
|
||||||
function! coc#terminal#start(cmd, cwd, env) abort
|
|
||||||
if s:is_vim && !has('terminal')
|
|
||||||
throw 'terminal feature not supported by current vim.'
|
|
||||||
endif
|
|
||||||
let cwd = empty(a:cwd) ? getcwd() : a:cwd
|
|
||||||
execute 'belowright 8new +setl\ buftype=nofile'
|
|
||||||
setl winfixheight
|
|
||||||
setl norelativenumber
|
|
||||||
setl nonumber
|
|
||||||
setl bufhidden=hide
|
|
||||||
if exists('#User#CocTerminalOpen')
|
|
||||||
exe 'doautocmd <nomodeline> User CocTerminalOpen'
|
|
||||||
endif
|
|
||||||
let bufnr = bufnr('%')
|
|
||||||
let env = {}
|
|
||||||
let original = {}
|
|
||||||
if !empty(a:env)
|
|
||||||
" use env option when possible
|
|
||||||
if s:is_vim
|
|
||||||
let env = copy(a:env)
|
|
||||||
else
|
|
||||||
for key in keys(a:env)
|
|
||||||
let original[key] = getenv(key)
|
|
||||||
call setenv(key, a:env[key])
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! s:OnExit(status) closure
|
|
||||||
if a:status == 0
|
|
||||||
execute 'silent! bd! '.bufnr
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
if has('nvim')
|
|
||||||
let job_id = termopen(a:cmd, {
|
|
||||||
\ 'cwd': cwd,
|
|
||||||
\ 'pty': 1,
|
|
||||||
\ 'on_exit': {job, status -> s:OnExit(status)},
|
|
||||||
\ 'env': env,
|
|
||||||
\ })
|
|
||||||
if !empty(original)
|
|
||||||
for key in keys(original)
|
|
||||||
call setenv(key, original[key])
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
if job_id == 0
|
|
||||||
throw 'create terminal job failed'
|
|
||||||
endif
|
|
||||||
wincmd p
|
|
||||||
let s:channel_map[bufnr] = job_id
|
|
||||||
return [bufnr, jobpid(job_id)]
|
|
||||||
else
|
|
||||||
let cmd = s:is_win ? join(a:cmd, ' ') : a:cmd
|
|
||||||
let res = term_start(cmd, {
|
|
||||||
\ 'cwd': cwd,
|
|
||||||
\ 'term_kill': s:is_win ? 'kill' : 'term',
|
|
||||||
\ 'term_finish': 'close',
|
|
||||||
\ 'exit_cb': {job, status -> s:OnExit(status)},
|
|
||||||
\ 'curwin': 1,
|
|
||||||
\ 'env': env,
|
|
||||||
\})
|
|
||||||
if res == 0
|
|
||||||
throw 'create terminal job failed'
|
|
||||||
endif
|
|
||||||
let job = term_getjob(bufnr)
|
|
||||||
let s:channel_map[bufnr] = job_getchannel(job)
|
|
||||||
wincmd p
|
|
||||||
return [bufnr, job_info(job).process]
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#terminal#send(bufnr, text, add_new_line) abort
|
|
||||||
let chan = get(s:channel_map, a:bufnr, v:null)
|
|
||||||
if empty(chan) | return| endif
|
|
||||||
if has('nvim')
|
|
||||||
let lines = split(a:text, '\v\r?\n')
|
|
||||||
if a:add_new_line && !empty(lines[len(lines) - 1])
|
|
||||||
if s:is_win
|
|
||||||
call add(lines, "\r\n")
|
|
||||||
else
|
|
||||||
call add(lines, '')
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
call chansend(chan, lines)
|
|
||||||
let winnr = bufwinnr(a:bufnr)
|
|
||||||
if winnr != -1
|
|
||||||
exe 'noa '.winnr.'wincmd w'
|
|
||||||
exe 'noa normal! G'
|
|
||||||
exe 'noa '.wincmd p
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
if !a:add_new_line
|
|
||||||
call ch_sendraw(chan, a:text)
|
|
||||||
else
|
|
||||||
call ch_sendraw(chan, a:text.(s:is_win ? "\r\n" : "\n"))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! coc#terminal#close(bufnr) abort
|
|
||||||
if has('nvim')
|
|
||||||
let job_id = get(s:channel_map, a:bufnr, 0)
|
|
||||||
if !empty(job_id)
|
|
||||||
silent! call chanclose(job_id)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
exe 'silent! bd! '.a:bufnr
|
|
||||||
endfunction
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,97 +0,0 @@
|
||||||
let s:root = expand('<sfile>:h:h:h')
|
|
||||||
|
|
||||||
function! s:checkEnvironment() abort
|
|
||||||
let valid = 1
|
|
||||||
if !has('nvim-0.3.0')
|
|
||||||
let valid = 0
|
|
||||||
call health#report_error('Neovim version not satisfied, 0.3.0 and above required')
|
|
||||||
endif
|
|
||||||
let node = get(g:, 'coc_node_path', $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH)
|
|
||||||
if !executable(node)
|
|
||||||
let valid = 0
|
|
||||||
call health#report_error('Executable node.js not found, install node.js from http://nodejs.org/')
|
|
||||||
endif
|
|
||||||
let output = system(node . ' --version')
|
|
||||||
if v:shell_error && output !=# ""
|
|
||||||
let valid = 0
|
|
||||||
call health#report_error(output)
|
|
||||||
endif
|
|
||||||
let ms = matchlist(output, 'v\(\d\+\).\(\d\+\).\(\d\+\)')
|
|
||||||
if empty(ms)
|
|
||||||
let valid = 0
|
|
||||||
call health#report_error('Unable to detect version of node, make sure your node executable is http://nodejs.org/')
|
|
||||||
elseif str2nr(ms[1]) < 8 || (str2nr(ms[1]) == 8 && str2nr(ms[2]) < 10)
|
|
||||||
let valid = 0
|
|
||||||
call health#report_error('Node.js version '.output.' < 8.10.0, please upgrade node.js')
|
|
||||||
elseif str2nr(ms[1]) < 10 || (str2nr(ms[1]) == 10 && str2nr(ms[2]) < 12)
|
|
||||||
let valid = 0
|
|
||||||
call health#report_warn('Node.js version '.trim(output).' < 10.12.0, please upgrade node.js')
|
|
||||||
endif
|
|
||||||
if valid
|
|
||||||
call health#report_ok('Environment check passed')
|
|
||||||
endif
|
|
||||||
if has('pythonx')
|
|
||||||
try
|
|
||||||
silent pyx print("")
|
|
||||||
catch /.*/
|
|
||||||
call health#report_warn('pyx command not work, some extensions may fail to work, checkout ":h pythonx"')
|
|
||||||
endtry
|
|
||||||
endif
|
|
||||||
return valid
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:checkCommand()
|
|
||||||
let file = s:root.'/bin/server.js'
|
|
||||||
if filereadable(file)
|
|
||||||
if !filereadable(s:root.'/lib/attach.js')
|
|
||||||
call health#report_error('Javascript entry not found, run "yarn install --frozen-lockfile" in terminal to fix it.')
|
|
||||||
else
|
|
||||||
call health#report_ok('Javascript entry lib/attach.js found')
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let file = s:root.'/build/index.js'
|
|
||||||
if filereadable(file)
|
|
||||||
call health#report_ok('Javascript bundle build/index.js found')
|
|
||||||
else
|
|
||||||
call health#report_error('Javascript entry not found, reinstall coc.nvim to fix it.')
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:checkAutocmd()
|
|
||||||
let cmds = ['CursorHold', 'CursorHoldI', 'CursorMovedI', 'InsertCharPre', 'TextChangedI']
|
|
||||||
for cmd in cmds
|
|
||||||
let lines = split(execute('verbose autocmd '.cmd), '\n')
|
|
||||||
let n = 0
|
|
||||||
for line in lines
|
|
||||||
if line =~# 'CocAction(' && n < len(lines) - 1
|
|
||||||
let next = lines[n + 1]
|
|
||||||
let ms = matchlist(next, 'Last set from \(.*\)')
|
|
||||||
if !empty(ms)
|
|
||||||
call health#report_warn('Use CocActionAsync to replace CocAction for better performance on '.cmd)
|
|
||||||
call health#report_warn('Checkout the file '.ms[1])
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let n = n + 1
|
|
||||||
endfor
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:checkInitailize() abort
|
|
||||||
if coc#client#is_running('coc')
|
|
||||||
call health#report_ok('Service started')
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
call health#report_error('service could not be initialized', [
|
|
||||||
\ 'Use command ":messages" to get error messages.',
|
|
||||||
\ 'Open a issue at https://github.com/neoclide/coc.nvim/issues for feedback.'
|
|
||||||
\])
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! health#coc#check() abort
|
|
||||||
call s:checkEnvironment()
|
|
||||||
call s:checkCommand()
|
|
||||||
call s:checkInitailize()
|
|
||||||
call s:checkAutocmd()
|
|
||||||
endfunction
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
"name": "coc.nvim",
|
|
||||||
"version": "0.0.79",
|
|
||||||
"description": "LSP based intellisense engine for neovim & vim8.",
|
|
||||||
"main": "./lib/index.js",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.10.0"
|
|
||||||
},
|
|
||||||
"scripts": {},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/neoclide/coc.nvim.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"complete",
|
|
||||||
"neovim"
|
|
||||||
],
|
|
||||||
"author": "Qiming Zhao <chemzqm@gmail.com>",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/neoclide/coc.nvim/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/neoclide/coc.nvim#readme",
|
|
||||||
"jest": {
|
|
||||||
"globals": {
|
|
||||||
"__TEST__": true
|
|
||||||
},
|
|
||||||
"watchman": false,
|
|
||||||
"clearMocks": true,
|
|
||||||
"globalSetup": "./jest.js",
|
|
||||||
"testEnvironment": "node",
|
|
||||||
"moduleFileExtensions": [
|
|
||||||
"ts",
|
|
||||||
"tsx",
|
|
||||||
"json",
|
|
||||||
"js"
|
|
||||||
],
|
|
||||||
"transform": {
|
|
||||||
"^.+\\.tsx?$": "ts-jest"
|
|
||||||
},
|
|
||||||
"testRegex": "src/__tests__/.*\\.(test|spec)\\.ts$",
|
|
||||||
"coverageDirectory": "./coverage/"
|
|
||||||
},
|
|
||||||
"devDependencies": {},
|
|
||||||
"dependencies": {}
|
|
||||||
}
|
|
|
@ -1,477 +0,0 @@
|
||||||
if exists('g:did_coc_loaded') || v:version < 800
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! s:checkVersion() abort
|
|
||||||
let l:unsupported = 0
|
|
||||||
if get(g:, 'coc_disable_startup_warning', 0) != 1
|
|
||||||
if has('nvim')
|
|
||||||
let l:unsupported = !has('nvim-0.3.2')
|
|
||||||
else
|
|
||||||
let l:unsupported = !has('patch-8.0.1453')
|
|
||||||
endif
|
|
||||||
|
|
||||||
if l:unsupported == 1
|
|
||||||
echohl Error
|
|
||||||
echom "coc.nvim requires at least Vim 8.0.1453 or Neovim 0.3.2, but you're using an older version."
|
|
||||||
echom "Please upgrade your (neo)vim."
|
|
||||||
echom "You can add this to your vimrc to avoid this message:"
|
|
||||||
echom " let g:coc_disable_startup_warning = 1"
|
|
||||||
echom "Note that some features may error out or behave incorrectly."
|
|
||||||
echom "Please do not report bugs unless you're using at least Vim 8.0.1453 or Neovim 0.3.2."
|
|
||||||
echohl None
|
|
||||||
sleep 2
|
|
||||||
else
|
|
||||||
if has('nvim') && !has('nvim-0.4.3')
|
|
||||||
echohl WarningMsg
|
|
||||||
echom "coc.nvim works best on neovim >= 0.4.3, consider upgrade your neovim."
|
|
||||||
echom "You can add this to your vimrc to avoid this message:"
|
|
||||||
echom " let g:coc_disable_startup_warning = 1"
|
|
||||||
echom "Note that some features may behave incorrectly."
|
|
||||||
echohl None
|
|
||||||
sleep 2
|
|
||||||
elseif !has('nvim') && !has('patch-8.1.1719')
|
|
||||||
echohl WarningMsg
|
|
||||||
echom "coc.nvim need vim >= 8.1.1719 to support features like popup and text property."
|
|
||||||
echom "Consider upgrade your vim for better experience."
|
|
||||||
echom "You can add this to your vimrc to avoid this message:"
|
|
||||||
echom " let g:coc_disable_startup_warning = 1"
|
|
||||||
echom "Note that some features may behave incorrectly."
|
|
||||||
echohl None
|
|
||||||
sleep 2
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
call s:checkVersion()
|
|
||||||
|
|
||||||
let g:did_coc_loaded = 1
|
|
||||||
let g:coc_workspace_initialized = 0
|
|
||||||
let g:coc_service_initialized = 0
|
|
||||||
let s:is_win = has('win32') || has('win64')
|
|
||||||
let s:root = expand('<sfile>:h:h')
|
|
||||||
let s:is_vim = !has('nvim')
|
|
||||||
let s:is_gvim = get(v:, 'progname', '') ==# 'gvim'
|
|
||||||
|
|
||||||
if get(g:, 'coc_start_at_startup', 1) && !s:is_gvim
|
|
||||||
call coc#rpc#start_server()
|
|
||||||
endif
|
|
||||||
|
|
||||||
function! CocTagFunc(pattern, flags, info) abort
|
|
||||||
if a:flags !=# 'c'
|
|
||||||
" use standard tag search
|
|
||||||
return v:null
|
|
||||||
endif
|
|
||||||
return coc#rpc#request('getTagList', [])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocAction(name, ...) abort
|
|
||||||
return coc#rpc#request(a:name, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocHasProvider(name) abort
|
|
||||||
return coc#rpc#request('hasProvider', [a:name])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocActionAsync(name, ...) abort
|
|
||||||
return s:AsyncRequest(a:name, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocRequest(...) abort
|
|
||||||
return coc#rpc#request('sendRequest', a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocNotify(...) abort
|
|
||||||
return coc#rpc#request('sendNotification', a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocRegistNotification(id, method, cb) abort
|
|
||||||
call coc#on_notify(a:id, a:method, a:cb)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocLocations(id, method, ...) abort
|
|
||||||
let args = [a:id, a:method] + copy(a:000)
|
|
||||||
call coc#rpc#request('findLocations', args)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocLocationsAsync(id, method, ...) abort
|
|
||||||
let args = [a:id, a:method] + copy(a:000)
|
|
||||||
call coc#rpc#notify('findLocations', args)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! CocRequestAsync(...)
|
|
||||||
return s:AsyncRequest('sendRequest', a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:AsyncRequest(name, args) abort
|
|
||||||
let Cb = empty(a:args)? v:null : a:args[len(a:args) - 1]
|
|
||||||
if type(Cb) == 2
|
|
||||||
if !coc#rpc#ready()
|
|
||||||
call Cb('service not started', v:null)
|
|
||||||
else
|
|
||||||
call coc#rpc#request_async(a:name, a:args[0:-2], Cb)
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
call coc#rpc#notify(a:name, a:args)
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:CommandList(...) abort
|
|
||||||
let list = coc#rpc#request('commandList', a:000)
|
|
||||||
return join(list, "\n")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ExtensionList(...) abort
|
|
||||||
let stats = CocAction('extensionStats')
|
|
||||||
call filter(stats, 'v:val["isLocal"] == v:false')
|
|
||||||
let list = map(stats, 'v:val["id"]')
|
|
||||||
return join(list, "\n")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:SearchOptions(...) abort
|
|
||||||
let list = ['-e', '--regexp', '-F', '--fixed-strings', '-L', '--follow',
|
|
||||||
\ '-g', '--glob', '--hidden', '--no-hidden', '--no-ignore-vcs',
|
|
||||||
\ '--word-regexp', '-w', '--smart-case', '-S', '--no-config',
|
|
||||||
\ '--line-regexp', '--no-ignore', '-x']
|
|
||||||
return join(list, "\n")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:InstallOptions(...)abort
|
|
||||||
let list = ['-terminal', '-sync']
|
|
||||||
return join(list, "\n")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:OpenConfig()
|
|
||||||
let home = coc#util#get_config_home()
|
|
||||||
if !isdirectory(home)
|
|
||||||
call mkdir(home, 'p')
|
|
||||||
endif
|
|
||||||
execute 'edit '.home.'/coc-settings.json'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:AddAnsiGroups() abort
|
|
||||||
let color_map = {}
|
|
||||||
let colors = ['#282828', '#cc241d', '#98971a', '#d79921', '#458588', '#b16286', '#689d6a', '#a89984', '#928374']
|
|
||||||
let names = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'grey']
|
|
||||||
for i in range(0, len(names) - 1)
|
|
||||||
let name = names[i]
|
|
||||||
if exists('g:terminal_ansi_colors')
|
|
||||||
let color_map[name] = get(g:terminal_ansi_colors, i, colors[i])
|
|
||||||
else
|
|
||||||
let color_map[name] = get(g:, 'terminal_color_'.i, colors[i])
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
for name in keys(color_map)
|
|
||||||
let foreground = toupper(name[0]).name[1:]
|
|
||||||
let foregroundColor = color_map[name]
|
|
||||||
for key in keys(color_map)
|
|
||||||
let background = toupper(key[0]).key[1:]
|
|
||||||
let backgroundColor = color_map[key]
|
|
||||||
exe 'hi default CocList'.foreground.background.' guifg='.foregroundColor.' guibg='.backgroundColor
|
|
||||||
endfor
|
|
||||||
try
|
|
||||||
exe 'hi default CocListFg'.foreground. ' guifg='.foregroundColor. ' ctermfg='.foreground
|
|
||||||
exe 'hi default CocListBg'.foreground. ' guibg='.foregroundColor. ' ctermbg='.foreground
|
|
||||||
catch /.*/
|
|
||||||
" ignore invalid color
|
|
||||||
endtry
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:CursorRangeFromSelected(type, ...) abort
|
|
||||||
" add range by operator
|
|
||||||
call coc#rpc#request('cursorsSelect', [bufnr('%'), 'operator', a:type])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:OpenDiagnostics(...) abort
|
|
||||||
let height = get(a:, 1, 0)
|
|
||||||
call coc#rpc#request('fillDiagnostics', [bufnr('%')])
|
|
||||||
if height
|
|
||||||
execute ':lopen '.height
|
|
||||||
else
|
|
||||||
lopen
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Disable() abort
|
|
||||||
if get(g:, 'coc_enabled', 0) == 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
augroup coc_nvim
|
|
||||||
autocmd!
|
|
||||||
augroup end
|
|
||||||
call coc#rpc#request('detach', [])
|
|
||||||
echohl MoreMsg
|
|
||||||
echom '[coc.nvim] Event disabled'
|
|
||||||
echohl None
|
|
||||||
let g:coc_enabled = 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Autocmd(...) abort
|
|
||||||
if !g:coc_workspace_initialized
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
call coc#rpc#notify('CocAutocmd', a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:SyncAutocmd(...)
|
|
||||||
if !g:coc_workspace_initialized
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
if g:coc_service_initialized
|
|
||||||
call coc#rpc#request('CocAutocmd', a:000)
|
|
||||||
else
|
|
||||||
call coc#rpc#notify('CocAutocmd', a:000)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Enable(initialize)
|
|
||||||
if get(g:, 'coc_enabled', 0) == 1
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let g:coc_enabled = 1
|
|
||||||
|
|
||||||
augroup coc_nvim
|
|
||||||
autocmd!
|
|
||||||
|
|
||||||
if exists('##MenuPopupChanged') && exists('*nvim_open_win')
|
|
||||||
autocmd MenuPopupChanged * call s:Autocmd('MenuPopupChanged', get(v:, 'event', {}), win_screenpos(winnr())[0] + winline() - 2)
|
|
||||||
endif
|
|
||||||
if exists('##CompleteChanged')
|
|
||||||
autocmd CompleteChanged * call s:Autocmd('MenuPopupChanged', get(v:, 'event', {}), win_screenpos(winnr())[0] + winline() - 2)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if coc#rpc#started()
|
|
||||||
autocmd VimEnter * call coc#rpc#notify('VimEnter', [])
|
|
||||||
elseif get(g:, 'coc_start_at_startup', 1)
|
|
||||||
autocmd VimEnter * call coc#rpc#start_server()
|
|
||||||
endif
|
|
||||||
if s:is_vim
|
|
||||||
if exists('##DirChanged')
|
|
||||||
autocmd DirChanged * call s:Autocmd('DirChanged', getcwd())
|
|
||||||
endif
|
|
||||||
if exists('##TerminalOpen')
|
|
||||||
autocmd TerminalOpen * call s:Autocmd('TermOpen', +expand('<abuf>'))
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
autocmd DirChanged * call s:Autocmd('DirChanged', get(v:event, 'cwd', ''))
|
|
||||||
autocmd TermOpen * call s:Autocmd('TermOpen', +expand('<abuf>'))
|
|
||||||
autocmd TermClose * call s:Autocmd('TermClose', +expand('<abuf>'))
|
|
||||||
autocmd CursorMoved * call coc#float#nvim_refresh_scrollbar()
|
|
||||||
autocmd WinEnter * call coc#float#nvim_check_close(win_getid())
|
|
||||||
autocmd CursorHold * call coc#float#nvim_check_related()
|
|
||||||
if exists('##WinClosed')
|
|
||||||
autocmd WinClosed * call coc#float#nvim_close_related(+expand('<afile>'))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
autocmd WinLeave * call coc#util#clear_highlights()
|
|
||||||
autocmd WinLeave * call s:Autocmd('WinLeave', win_getid())
|
|
||||||
autocmd WinEnter * call s:Autocmd('WinEnter', win_getid())
|
|
||||||
autocmd BufWinLeave * call s:Autocmd('BufWinLeave', +expand('<abuf>'), bufwinid(+expand('<abuf>')))
|
|
||||||
autocmd BufWinEnter * call s:Autocmd('BufWinEnter', +expand('<abuf>'), win_getid())
|
|
||||||
autocmd FileType * call s:Autocmd('FileType', expand('<amatch>'), +expand('<abuf>'))
|
|
||||||
autocmd CompleteDone * call s:Autocmd('CompleteDone', get(v:, 'completed_item', {}))
|
|
||||||
autocmd InsertCharPre * call s:Autocmd('InsertCharPre', v:char)
|
|
||||||
if exists('##TextChangedP')
|
|
||||||
autocmd TextChangedP * call s:Autocmd('TextChangedP', +expand('<abuf>'), {'lnum': line('.'), 'col': col('.'), 'pre': strpart(getline('.'), 0, col('.') - 1), 'changedtick': b:changedtick})
|
|
||||||
endif
|
|
||||||
autocmd TextChangedI * call s:Autocmd('TextChangedI', +expand('<abuf>'), {'lnum': line('.'), 'col': col('.'), 'pre': strpart(getline('.'), 0, col('.') - 1), 'changedtick': b:changedtick})
|
|
||||||
autocmd InsertLeave * call s:Autocmd('InsertLeave', +expand('<abuf>'))
|
|
||||||
autocmd InsertEnter * call s:Autocmd('InsertEnter', +expand('<abuf>'))
|
|
||||||
autocmd BufHidden * call s:Autocmd('BufHidden', +expand('<abuf>'))
|
|
||||||
autocmd BufEnter * call s:Autocmd('BufEnter', +expand('<abuf>'))
|
|
||||||
autocmd TextChanged * call s:Autocmd('TextChanged', +expand('<abuf>'), getbufvar(+expand('<abuf>'), 'changedtick'))
|
|
||||||
autocmd BufWritePost * call s:Autocmd('BufWritePost', +expand('<abuf>'))
|
|
||||||
autocmd CursorMoved * call s:Autocmd('CursorMoved', +expand('<abuf>'), [line('.'), col('.')])
|
|
||||||
autocmd CursorMovedI * call s:Autocmd('CursorMovedI', +expand('<abuf>'), [line('.'), col('.')])
|
|
||||||
autocmd CursorHold * call s:Autocmd('CursorHold', +expand('<abuf>'))
|
|
||||||
autocmd CursorHoldI * call s:Autocmd('CursorHoldI', +expand('<abuf>'))
|
|
||||||
autocmd BufNewFile,BufReadPost * call s:Autocmd('BufCreate', +expand('<abuf>'))
|
|
||||||
autocmd BufUnload * call s:SyncAutocmd('BufUnload', +expand('<abuf>'))
|
|
||||||
autocmd BufWritePre * call s:SyncAutocmd('BufWritePre', +expand('<abuf>'))
|
|
||||||
autocmd FocusGained * if mode() !~# '^c' | call s:Autocmd('FocusGained') | endif
|
|
||||||
autocmd VimResized * call s:Autocmd('VimResized', &columns, &lines)
|
|
||||||
autocmd VimLeavePre * let g:coc_vim_leaving = 1
|
|
||||||
autocmd BufReadCmd,FileReadCmd,SourceCmd list://* call coc#list#setup(expand('<amatch>'))
|
|
||||||
autocmd BufWriteCmd __coc_refactor__* :call coc#rpc#notify('saveRefactor', [+expand('<abuf>')])
|
|
||||||
autocmd ColorScheme * call s:Hi()
|
|
||||||
augroup end
|
|
||||||
if a:initialize == 0
|
|
||||||
call coc#rpc#request('attach', [])
|
|
||||||
echohl MoreMsg
|
|
||||||
echom '[coc.nvim] Event enabled'
|
|
||||||
echohl None
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Hi() abort
|
|
||||||
hi default CocUnderline cterm=underline gui=underline
|
|
||||||
hi default CocBold term=bold cterm=bold gui=bold
|
|
||||||
hi default CocErrorSign ctermfg=Red guifg=#ff0000
|
|
||||||
hi default CocWarningSign ctermfg=Brown guifg=#ff922b
|
|
||||||
hi default CocInfoSign ctermfg=Yellow guifg=#fab005
|
|
||||||
hi default CocHintSign ctermfg=Blue guifg=#15aabf
|
|
||||||
hi default CocSelectedText ctermfg=Red guifg=#fb4934
|
|
||||||
hi default CocCodeLens ctermfg=Gray guifg=#999999
|
|
||||||
hi default link CocMenuSel PmenuSel
|
|
||||||
hi default link CocErrorFloat CocErrorSign
|
|
||||||
hi default link CocWarningFloat CocWarningSign
|
|
||||||
hi default link CocInfoFloat CocInfoSign
|
|
||||||
hi default link CocHintFloat CocHintSign
|
|
||||||
hi default link CocErrorHighlight CocUnderline
|
|
||||||
hi default link CocWarningHighlight CocUnderline
|
|
||||||
hi default link CocInfoHighlight CocUnderline
|
|
||||||
hi default link CocHintHighlight CocUnderline
|
|
||||||
hi default link CocListMode ModeMsg
|
|
||||||
hi default link CocListPath Comment
|
|
||||||
hi default link CocHighlightText CursorColumn
|
|
||||||
hi default link CocHoverRange Search
|
|
||||||
hi default link CocCursorRange Search
|
|
||||||
hi default link CocHighlightRead CocHighlightText
|
|
||||||
hi default link CocHighlightWrite CocHighlightText
|
|
||||||
if has('nvim')
|
|
||||||
hi default link CocFloating NormalFloat
|
|
||||||
else
|
|
||||||
hi default link CocFloating Pmenu
|
|
||||||
endif
|
|
||||||
if has('nvim-0.5.0')
|
|
||||||
hi default CocCursorTransparent gui=strikethrough blend=100
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has('nvim')
|
|
||||||
let names = ['Error', 'Warning', 'Info', 'Hint']
|
|
||||||
for name in names
|
|
||||||
if !hlexists('Coc'.name.'VirtualText')
|
|
||||||
exe 'hi default link Coc'.name.'VirtualText Coc'.name.'Sign'
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
call s:AddAnsiGroups()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:FormatFromSelected(type)
|
|
||||||
call CocActionAsync('formatSelected', a:type)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:CodeActionFromSelected(type)
|
|
||||||
call CocActionAsync('codeAction', a:type)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ShowInfo()
|
|
||||||
if coc#rpc#ready()
|
|
||||||
call coc#rpc#notify('showInfo', [])
|
|
||||||
else
|
|
||||||
let lines = []
|
|
||||||
echomsg 'coc.nvim service not started, checking environment...'
|
|
||||||
let node = get(g:, 'coc_node_path', $COC_NODE_PATH == '' ? 'node' : $COC_NODE_PATH)
|
|
||||||
if !executable(node)
|
|
||||||
call add(lines, 'Error: '.node.' is not executable!')
|
|
||||||
else
|
|
||||||
let output = trim(system(node . ' --version'))
|
|
||||||
let ms = matchlist(output, 'v\(\d\+\).\(\d\+\).\(\d\+\)')
|
|
||||||
if empty(ms) || str2nr(ms[1]) < 10 || (str2nr(ms[1]) == 10 && str2nr(ms[2]) < 12)
|
|
||||||
call add(lines, 'Error: Node version '.output.' < 10.12.0, please upgrade node.js')
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
" check bundle
|
|
||||||
let file = s:root.'/bin/server.js'
|
|
||||||
if filereadable(file)
|
|
||||||
let file = s:root.'/lib/attach.js'
|
|
||||||
if !filereadable(file)
|
|
||||||
call add(lines, 'Error: javascript bundle not found, please compile the code of coc.nvim.')
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let file = s:root.'/build/index.js'
|
|
||||||
if !filereadable(file)
|
|
||||||
call add(lines, 'Error: javascript bundle not found, please remove coc.nvim folder and reinstall it.')
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
if !empty(lines)
|
|
||||||
belowright vnew
|
|
||||||
setl filetype=nofile
|
|
||||||
call setline(1, lines)
|
|
||||||
else
|
|
||||||
if get(g:, 'coc_start_at_startup',1)
|
|
||||||
echohl MoreMsg | echon 'Service stopped for some unknown reason, try :CocStart' | echohl None
|
|
||||||
else
|
|
||||||
echohl MoreMsg | echon 'Start on startup is disabled, try :CocStart' | echohl None
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
command! -nargs=? CocDiagnostics :call s:OpenDiagnostics(<f-args>)
|
|
||||||
command! -nargs=0 CocInfo :call s:ShowInfo()
|
|
||||||
command! -nargs=0 CocOpenLog :call coc#rpc#notify('openLog', [])
|
|
||||||
command! -nargs=0 CocDisable :call s:Disable()
|
|
||||||
command! -nargs=0 CocEnable :call s:Enable(0)
|
|
||||||
command! -nargs=0 CocConfig :call s:OpenConfig()
|
|
||||||
command! -nargs=0 CocLocalConfig :call coc#rpc#notify('openLocalConfig', [])
|
|
||||||
command! -nargs=0 CocRestart :call coc#rpc#restart()
|
|
||||||
command! -nargs=0 CocStart :call coc#rpc#start_server()
|
|
||||||
command! -nargs=0 CocRebuild :call coc#util#rebuild()
|
|
||||||
command! -nargs=+ -complete=custom,s:SearchOptions CocSearch :call coc#rpc#notify('search', [<f-args>])
|
|
||||||
command! -nargs=+ -complete=custom,s:ExtensionList CocUninstall :call CocActionAsync('uninstallExtension', <f-args>)
|
|
||||||
command! -nargs=* -complete=custom,s:CommandList -range CocCommand :call coc#rpc#notify('runCommand', [<f-args>])
|
|
||||||
command! -nargs=* -complete=custom,coc#list#options CocList :call coc#rpc#notify('openList', [<f-args>])
|
|
||||||
command! -nargs=? -complete=custom,coc#list#names CocListResume :call coc#rpc#notify('listResume', [<f-args>])
|
|
||||||
command! -nargs=? -complete=custom,coc#list#names CocPrev :call coc#rpc#notify('listPrev', [<f-args>])
|
|
||||||
command! -nargs=? -complete=custom,coc#list#names CocNext :call coc#rpc#notify('listNext', [<f-args>])
|
|
||||||
command! -nargs=? -complete=custom,coc#list#names CocFirst :call coc#rpc#notify('listFirst', [<f-args>])
|
|
||||||
command! -nargs=? -complete=custom,coc#list#names CocLast :call coc#rpc#notify('listLast', [<f-args>])
|
|
||||||
command! -nargs=* -range CocAction :call coc#rpc#notify('codeActionRange', [<line1>, <line2>, <f-args>])
|
|
||||||
command! -nargs=* -range CocFix :call coc#rpc#notify('codeActionRange', [<line1>, <line2>, 'quickfix'])
|
|
||||||
command! -nargs=0 CocUpdate :call coc#util#update_extensions(1)
|
|
||||||
command! -nargs=0 -bar CocUpdateSync :call coc#util#update_extensions()
|
|
||||||
command! -nargs=* -bar -complete=custom,s:InstallOptions CocInstall :call coc#util#install_extension([<f-args>])
|
|
||||||
|
|
||||||
call s:Enable(1)
|
|
||||||
call s:Hi()
|
|
||||||
|
|
||||||
vnoremap <silent> <Plug>(coc-range-select) :<C-u>call CocActionAsync('rangeSelect', visualmode(), v:true)<CR>
|
|
||||||
vnoremap <silent> <Plug>(coc-range-select-backward) :<C-u>call CocActionAsync('rangeSelect', visualmode(), v:false)<CR>
|
|
||||||
nnoremap <Plug>(coc-range-select) :<C-u>call CocActionAsync('rangeSelect', '', v:true)<CR>
|
|
||||||
nnoremap <Plug>(coc-codelens-action) :<C-u>call CocActionAsync('codeLensAction')<CR>
|
|
||||||
vnoremap <silent> <Plug>(coc-format-selected) :<C-u>call CocActionAsync('formatSelected', visualmode())<CR>
|
|
||||||
vnoremap <silent> <Plug>(coc-codeaction-selected) :<C-u>call CocActionAsync('codeAction', visualmode())<CR>
|
|
||||||
nnoremap <Plug>(coc-codeaction-selected) :<C-u>set operatorfunc=<SID>CodeActionFromSelected<CR>g@
|
|
||||||
nnoremap <Plug>(coc-codeaction) :<C-u>call CocActionAsync('codeAction', '')<CR>
|
|
||||||
nnoremap <Plug>(coc-codeaction-line) :<C-u>call CocActionAsync('codeAction', 'n')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-rename) :<C-u>call CocActionAsync('rename')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-format-selected) :<C-u>set operatorfunc=<SID>FormatFromSelected<CR>g@
|
|
||||||
nnoremap <silent> <Plug>(coc-format) :<C-u>call CocActionAsync('format')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-diagnostic-info) :<C-u>call CocActionAsync('diagnosticInfo')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-diagnostic-next) :<C-u>call CocActionAsync('diagnosticNext')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-diagnostic-prev) :<C-u>call CocActionAsync('diagnosticPrevious')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-diagnostic-next-error) :<C-u>call CocActionAsync('diagnosticNext', 'error')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-diagnostic-prev-error) :<C-u>call CocActionAsync('diagnosticPrevious', 'error')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-definition) :<C-u>call CocActionAsync('jumpDefinition')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-declaration) :<C-u>call CocActionAsync('jumpDeclaration')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-implementation) :<C-u>call CocActionAsync('jumpImplementation')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-type-definition) :<C-u>call CocActionAsync('jumpTypeDefinition')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-references) :<C-u>call CocActionAsync('jumpReferences')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-references-used) :<C-u>call CocActionAsync('jumpUsed')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-openlink) :<C-u>call CocActionAsync('openLink')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-fix-current) :<C-u>call CocActionAsync('doQuickfix')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-float-hide) :<C-u>call coc#float#close_all()<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-float-jump) :<c-u>call coc#float#jump()<cr>
|
|
||||||
nnoremap <silent> <Plug>(coc-command-repeat) :<C-u>call CocAction('repeatCommand')<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-refactor) :<C-u>call CocActionAsync('refactor')<CR>
|
|
||||||
inoremap <silent> <Plug>CocRefresh <C-r>=coc#_complete()<CR>
|
|
||||||
|
|
||||||
nnoremap <silent> <Plug>(coc-cursors-operator) :<C-u>set operatorfunc=<SID>CursorRangeFromSelected<CR>g@
|
|
||||||
vnoremap <silent> <Plug>(coc-cursors-range) :<C-u>call coc#rpc#request('cursorsSelect', [bufnr('%'), 'range', visualmode()])<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-cursors-word) :<C-u>call coc#rpc#request('cursorsSelect', [bufnr('%'), 'word', 'n'])<CR>
|
|
||||||
nnoremap <silent> <Plug>(coc-cursors-position) :<C-u>call coc#rpc#request('cursorsSelect', [bufnr('%'), 'position', 'n'])<CR>
|
|
||||||
|
|
||||||
vnoremap <silent> <Plug>(coc-funcobj-i) :<C-U>call coc#rpc#request('selectSymbolRange', [v:true, visualmode(), ['Method', 'Function']])<CR>
|
|
||||||
vnoremap <silent> <Plug>(coc-funcobj-a) :<C-U>call coc#rpc#request('selectSymbolRange', [v:false, visualmode(), ['Method', 'Function']])<CR>
|
|
||||||
onoremap <silent> <Plug>(coc-funcobj-i) :<C-U>call coc#rpc#request('selectSymbolRange', [v:true, '', ['Method', 'Function']])<CR>
|
|
||||||
onoremap <silent> <Plug>(coc-funcobj-a) :<C-U>call coc#rpc#request('selectSymbolRange', [v:false, '', ['Method', 'Function']])<CR>
|
|
||||||
|
|
||||||
vnoremap <silent> <Plug>(coc-classobj-i) :<C-U>call coc#rpc#request('selectSymbolRange', [v:true, visualmode(), ['Interface', 'Struct', 'Class']])<CR>
|
|
||||||
vnoremap <silent> <Plug>(coc-classobj-a) :<C-U>call coc#rpc#request('selectSymbolRange', [v:false, visualmode(), ['Interface', 'Struct', 'Class']])<CR>
|
|
||||||
onoremap <silent> <Plug>(coc-classobj-i) :<C-U>call coc#rpc#request('selectSymbolRange', [v:true, '', ['Interface', 'Struct', 'Class']])<CR>
|
|
||||||
onoremap <silent> <Plug>(coc-classobj-a) :<C-U>call coc#rpc#request('selectSymbolRange', [v:false, '', ['Interface', 'Struct', 'Class']])<CR>
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
terminateTree() {
|
|
||||||
for cpid in $(pgrep -P $1); do
|
|
||||||
terminateTree $cpid
|
|
||||||
done
|
|
||||||
kill -9 $1 > /dev/null 2>&1
|
|
||||||
}
|
|
||||||
|
|
||||||
for pid in $*; do
|
|
||||||
terminateTree $pid
|
|
||||||
done
|
|
||||||
|
|
20
vimrc
20
vimrc
|
@ -161,26 +161,6 @@ else
|
||||||
set signcolumn=yes
|
set signcolumn=yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if has("patch-8.1.1719") && (executable("nodejs") || executable("node"))
|
|
||||||
packadd coc.nvim
|
|
||||||
" Use tab for trigger completion with characters ahead and navigate.
|
|
||||||
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
|
|
||||||
" other plugin before putting this into your config.
|
|
||||||
inoremap <silent><expr> <TAB>
|
|
||||||
\ pumvisible() ? "\<C-n>" :
|
|
||||||
\ <SID>check_back_space() ? "\<TAB>" :
|
|
||||||
\ coc#refresh()
|
|
||||||
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
|
|
||||||
|
|
||||||
function! s:check_back_space() abort
|
|
||||||
let col = col('.') - 1
|
|
||||||
return !col || getline('.')[col - 1] =~# '\s'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
|
|
||||||
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has("printer")
|
if has("printer")
|
||||||
set printheader=%t%h%m%=Page\ %N
|
set printheader=%t%h%m%=Page\ %N
|
||||||
set printoptions=paper:A4,number:y,syntax:n
|
set printoptions=paper:A4,number:y,syntax:n
|
||||||
|
|
Loading…
Reference in a new issue