mirror of
https://github.com/amix/vimrc
synced 2025-07-13 06:35:01 +08:00
Add markdown preview, update rust.vim
This commit is contained in:
@ -0,0 +1,19 @@
|
||||
let s:mkdp_root_dir = expand('<sfile>:h:h:h')
|
||||
|
||||
function! health#mkdp#check() abort
|
||||
call health#report_info('Platform: ' . mkdp#util#get_platform())
|
||||
let l:info = system('nvim --version')
|
||||
call health#report_info('Nvim Version: '. split(l:info, '\n')[0])
|
||||
let l:mkdp_server_script = s:mkdp_root_dir . '/app/bin/markdown-preview-' . mkdp#util#get_platform()
|
||||
if executable(l:mkdp_server_script)
|
||||
call health#report_info('Pre build: ' . l:mkdp_server_script)
|
||||
call health#report_info('Pre build version: ' . mkdp#util#pre_build_version())
|
||||
call health#report_ok('Using pre build')
|
||||
elseif executable('node')
|
||||
call health#report_info('Node version: ' . system('node --version'))
|
||||
let l:mkdp_server_script = s:mkdp_root_dir . '/app/server.js'
|
||||
call health#report_info('Script: ' . l:mkdp_server_script)
|
||||
call health#report_info('Script exists: ' . filereadable(l:mkdp_server_script))
|
||||
call health#report_ok('Using node')
|
||||
endif
|
||||
endfunction
|
@ -0,0 +1,22 @@
|
||||
" init preview key action
|
||||
function! mkdp#autocmd#init() abort
|
||||
execute 'augroup MKDP_REFRESH_INIT' . bufnr('%')
|
||||
autocmd!
|
||||
" refresh autocmd
|
||||
if g:mkdp_refresh_slow
|
||||
autocmd CursorHold,BufWrite,InsertLeave <buffer> call mkdp#rpc#preview_refresh()
|
||||
else
|
||||
autocmd CursorHold,CursorHoldI,CursorMoved,CursorMovedI <buffer> call mkdp#rpc#preview_refresh()
|
||||
endif
|
||||
" autoclose autocmd
|
||||
if g:mkdp_auto_close
|
||||
autocmd BufHidden <buffer> call mkdp#rpc#preview_close()
|
||||
endif
|
||||
" server close autocmd
|
||||
autocmd VimLeave * call mkdp#rpc#stop_server()
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
function! mkdp#autocmd#clear_buf() abort
|
||||
execute 'autocmd! ' . 'MKDP_REFRESH_INIT' . bufnr('%')
|
||||
endfunction
|
155
sources_non_forked/markdown-preview.nvim/autoload/mkdp/rpc.vim
Normal file
155
sources_non_forked/markdown-preview.nvim/autoload/mkdp/rpc.vim
Normal file
@ -0,0 +1,155 @@
|
||||
let s:mkdp_root_dir = expand('<sfile>:h:h:h')
|
||||
let s:mkdp_opts = {}
|
||||
let s:is_vim = !has('nvim')
|
||||
let s:mkdp_channel_id = s:is_vim ? v:null : -1
|
||||
|
||||
function! s:on_stdout(chan_id, msgs, ...) abort
|
||||
call mkdp#util#echo_messages('Error', a:msgs)
|
||||
endfunction
|
||||
function! s:on_stderr(chan_id, msgs, ...) abort
|
||||
call mkdp#util#echo_messages('Error', a:msgs)
|
||||
endfunction
|
||||
function! s:on_exit(chan_id, code, ...) abort
|
||||
let s:mkdp_channel_id = s:is_vim ? v:null : -1
|
||||
endfunction
|
||||
|
||||
function! s:start_vim_server(cmd) abort
|
||||
let options = {
|
||||
\ 'in_mode': 'json',
|
||||
\ 'out_mode': 'json',
|
||||
\ 'err_mode': 'nl',
|
||||
\ 'out_cb': function('s:on_stdout'),
|
||||
\ 'err_cb': function('s:on_stderr'),
|
||||
\ 'exit_cb': function('s:on_exit'),
|
||||
\ 'env': {
|
||||
\ 'VIM_NODE_RPC': 1,
|
||||
\ }
|
||||
\}
|
||||
if has("patch-8.1.350")
|
||||
let options['noblock'] = 1
|
||||
endif
|
||||
let l:job = job_start(a:cmd, options)
|
||||
let l:status = job_status(l:job)
|
||||
if l:status !=# 'run'
|
||||
echohl Error | echon 'Failed to start vim-node-rpc service' | echohl None
|
||||
return
|
||||
endif
|
||||
let s:mkdp_channel_id = l:job
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#start_server() abort
|
||||
let l:mkdp_server_script = s:mkdp_root_dir . '/app/bin/markdown-preview-' . mkdp#util#get_platform()
|
||||
if executable(l:mkdp_server_script)
|
||||
let l:cmd = [l:mkdp_server_script, '--path', s:mkdp_root_dir . '/app/server.js']
|
||||
elseif executable('node')
|
||||
let l:mkdp_server_script = s:mkdp_root_dir . '/app/index.js'
|
||||
let l:cmd = ['node', l:mkdp_server_script, '--path', s:mkdp_root_dir . '/app/server.js']
|
||||
endif
|
||||
if exists('l:cmd')
|
||||
if s:is_vim
|
||||
call s:start_vim_server(l:cmd)
|
||||
else
|
||||
let l:nvim_optons = {
|
||||
\ 'rpc': 1,
|
||||
\ 'on_stdout': function('s:on_stdout'),
|
||||
\ 'on_stderr': function('s:on_stderr'),
|
||||
\ 'on_exit': function('s:on_exit')
|
||||
\ }
|
||||
let s:mkdp_channel_id = jobstart(l:cmd, l:nvim_optons)
|
||||
endif
|
||||
else
|
||||
call mkdp#util#echo_messages('Error', 'Pre build and node is not found')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#stop_server() abort
|
||||
if s:is_vim
|
||||
if s:mkdp_channel_id !=# v:null
|
||||
let l:status = job_status(s:mkdp_channel_id)
|
||||
if l:status ==# 'run'
|
||||
call mkdp#rpc#request(s:mkdp_channel_id, 'close_all_pages')
|
||||
try
|
||||
call job_stop(s:mkdp_channel_id)
|
||||
catch /.*/
|
||||
endtry
|
||||
endif
|
||||
endif
|
||||
let s:mkdp_channel_id = v:null
|
||||
else
|
||||
if s:mkdp_channel_id !=# -1
|
||||
call rpcrequest(s:mkdp_channel_id, 'close_all_pages')
|
||||
try
|
||||
call jobstop(s:mkdp_channel_id)
|
||||
catch /.*/
|
||||
endtry
|
||||
endif
|
||||
let s:mkdp_channel_id = -1
|
||||
endif
|
||||
let b:MarkdownPreviewToggleBool = 0
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#get_server_status() abort
|
||||
if s:is_vim && s:mkdp_channel_id ==# v:null
|
||||
return -1
|
||||
elseif !s:is_vim && s:mkdp_channel_id ==# -1
|
||||
return -1
|
||||
endif
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#preview_refresh() abort
|
||||
if s:is_vim
|
||||
if s:mkdp_channel_id !=# v:null
|
||||
call mkdp#rpc#notify(s:mkdp_channel_id, 'refresh_content', { 'bufnr': bufnr('%') })
|
||||
endif
|
||||
else
|
||||
if s:mkdp_channel_id !=# -1
|
||||
call rpcnotify(s:mkdp_channel_id, 'refresh_content', { 'bufnr': bufnr('%') })
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#preview_close() abort
|
||||
if s:is_vim
|
||||
if s:mkdp_channel_id !=# v:null
|
||||
call mkdp#rpc#notify(s:mkdp_channel_id, 'close_page', { 'bufnr': bufnr('%') })
|
||||
endif
|
||||
else
|
||||
if s:mkdp_channel_id !=# -1
|
||||
call rpcnotify(s:mkdp_channel_id, 'close_page', { 'bufnr': bufnr('%') })
|
||||
endif
|
||||
endif
|
||||
let b:MarkdownPreviewToggleBool = 0
|
||||
call mkdp#autocmd#clear_buf()
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#open_browser() abort
|
||||
if s:is_vim
|
||||
if s:mkdp_channel_id !=# v:null
|
||||
call mkdp#rpc#notify(s:mkdp_channel_id, 'open_browser', { 'bufnr': bufnr('%') })
|
||||
endif
|
||||
else
|
||||
if s:mkdp_channel_id !=# -1
|
||||
call rpcnotify(s:mkdp_channel_id, 'open_browser', { 'bufnr': bufnr('%') })
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#request(clientId, method, ...) abort
|
||||
let args = get(a:, 1, [])
|
||||
let res = ch_evalexpr(a:clientId, [a:method, args], {'timeout': 5000})
|
||||
if type(res) == 1 && res ==# '' | return '' | endif
|
||||
let [l:errmsg, res] = res
|
||||
if l:errmsg
|
||||
echohl Error | echon '[rpc.vim] client error: '.l:errmsg | echohl None
|
||||
else
|
||||
return res
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! mkdp#rpc#notify(clientId, method, ...) abort
|
||||
let args = get(a:000, 0, [])
|
||||
" use 0 as vim request id
|
||||
let data = json_encode([0, [a:method, args]])
|
||||
call ch_sendraw(s:mkdp_channel_id, data."\n")
|
||||
endfunction
|
185
sources_non_forked/markdown-preview.nvim/autoload/mkdp/util.vim
Normal file
185
sources_non_forked/markdown-preview.nvim/autoload/mkdp/util.vim
Normal file
@ -0,0 +1,185 @@
|
||||
let s:mkdp_root_dir = expand('<sfile>:h:h:h')
|
||||
let s:pre_build = s:mkdp_root_dir . '/app/bin/markdown-preview-'
|
||||
let s:package_file = s:mkdp_root_dir . '/package.json'
|
||||
|
||||
" echo message
|
||||
function! mkdp#util#echo_messages(hl, msgs)
|
||||
if empty(a:msgs) | return | endif
|
||||
execute 'echohl '.a:hl
|
||||
if type(a:msgs) ==# 1
|
||||
echomsg a:msgs
|
||||
else
|
||||
for msg in a:msgs
|
||||
echom msg
|
||||
endfor
|
||||
endif
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
" echo url
|
||||
function! mkdp#util#echo_url(url)
|
||||
let l:url = 'Preview page: ' . a:url
|
||||
call mkdp#util#echo_messages('Type', l:url)
|
||||
endfunction
|
||||
|
||||
" try open preview page
|
||||
function! s:try_open_preview_page(timer_id) abort
|
||||
let l:server_status = mkdp#rpc#get_server_status()
|
||||
if l:server_status !=# 1
|
||||
let s:try_id = ''
|
||||
call mkdp#rpc#stop_server()
|
||||
call mkdp#rpc#start_server()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" open preview page
|
||||
function! mkdp#util#open_preview_page() abort
|
||||
if get(s:, 'try_id', '') !=# ''
|
||||
return
|
||||
endif
|
||||
let l:server_status = mkdp#rpc#get_server_status()
|
||||
if l:server_status ==# -1
|
||||
call mkdp#rpc#start_server()
|
||||
elseif l:server_status ==# 0
|
||||
let s:try_id = timer_start(1000, function('s:try_open_preview_page'))
|
||||
else
|
||||
call mkdp#util#open_browser()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" open browser
|
||||
function! mkdp#util#open_browser() abort
|
||||
call mkdp#rpc#open_browser()
|
||||
call mkdp#autocmd#init()
|
||||
endfunction
|
||||
|
||||
function! mkdp#util#stop_preview() abort
|
||||
" TODO: delete autocmd
|
||||
call mkdp#rpc#stop_server()
|
||||
endfunction
|
||||
|
||||
function! mkdp#util#get_platform() abort
|
||||
if has('win32') || has('win64')
|
||||
return 'win'
|
||||
elseif has('mac') || has('macvim')
|
||||
return 'macos'
|
||||
endif
|
||||
return 'linux'
|
||||
endfunction
|
||||
|
||||
function! s:on_exit(autoclose, bufnr, Callback, job_id, status, ...)
|
||||
let content = join(getbufline(a:bufnr, 1, '$'), "\n")
|
||||
if a:status == 0 && a:autoclose == 1
|
||||
execute 'silent! bd! '.a:bufnr
|
||||
endif
|
||||
if !empty(a:Callback)
|
||||
call call(a:Callback, [a:status, a:bufnr, content])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! mkdp#util#open_terminal(opts) abort
|
||||
if get(a:opts, 'position', 'bottom') ==# 'bottom'
|
||||
let p = '5new'
|
||||
else
|
||||
let p = 'vnew'
|
||||
endif
|
||||
execute 'belowright '.p.' +setl\ buftype=nofile '
|
||||
setl buftype=nofile
|
||||
setl winfixheight
|
||||
setl norelativenumber
|
||||
setl nonumber
|
||||
setl bufhidden=wipe
|
||||
let cmd = get(a:opts, 'cmd', '')
|
||||
let autoclose = get(a:opts, 'autoclose', 1)
|
||||
if empty(cmd)
|
||||
throw 'command required!'
|
||||
endif
|
||||
let cwd = get(a:opts, 'cwd', '')
|
||||
if !empty(cwd) | execute 'lcd '.cwd | endif
|
||||
let keepfocus = get(a:opts, 'keepfocus', 0)
|
||||
let bufnr = bufnr('%')
|
||||
let Callback = get(a:opts, 'Callback', v:null)
|
||||
if has('nvim')
|
||||
call termopen(cmd, {
|
||||
\ 'on_exit': function('s:on_exit', [autoclose, bufnr, Callback]),
|
||||
\})
|
||||
else
|
||||
call term_start(cmd, {
|
||||
\ 'exit_cb': function('s:on_exit', [autoclose, bufnr, Callback]),
|
||||
\ 'curwin': 1,
|
||||
\})
|
||||
endif
|
||||
if keepfocus
|
||||
wincmd p
|
||||
endif
|
||||
return bufnr
|
||||
endfunction
|
||||
|
||||
function! s:markdown_preview_installed(status, ...) abort
|
||||
if a:status != 0
|
||||
call mkdp#util#echo_messages('Error', '[markdown-preview]: install fail')
|
||||
return
|
||||
endif
|
||||
echo '[markdown-preview.nvim]: install completed'
|
||||
endfunction
|
||||
|
||||
function! s:trim(str) abort
|
||||
return substitute(a:str, '\v^(\s|\\n)*|(\s|\\n)*$', '', 'g')
|
||||
endfunction
|
||||
|
||||
function! mkdp#util#install(...)
|
||||
let l:version = mkdp#util#pre_build_version()
|
||||
let l:info = json_decode(join(readfile(s:mkdp_root_dir . '/package.json'), ''))
|
||||
if s:trim(l:version) ==# s:trim(l:info.version)
|
||||
return
|
||||
endif
|
||||
let obj = json_decode(join(readfile(s:package_file)))
|
||||
let cmd = (mkdp#util#get_platform() ==# 'win' ? 'install.cmd' : './install.sh') . ' v'.obj['version']
|
||||
if get(a:, '1', v:false) ==# v:true
|
||||
execute 'lcd ' . s:mkdp_root_dir . '/app'
|
||||
execute '!' . cmd
|
||||
else
|
||||
call mkdp#util#open_terminal({
|
||||
\ 'cmd': cmd,
|
||||
\ 'cwd': s:mkdp_root_dir . '/app',
|
||||
\ 'Callback': function('s:markdown_preview_installed')
|
||||
\})
|
||||
wincmd p
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! mkdp#util#install_sync(...)
|
||||
if get(a:, '1', v:false) ==# v:true
|
||||
silent call mkdp#util#install(v:true)
|
||||
else
|
||||
call mkdp#util#install(v:true)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! mkdp#util#pre_build_version() abort
|
||||
let l:pre_build = s:pre_build . mkdp#util#get_platform()
|
||||
if has('win32') || has('win64')
|
||||
let l:pre_build .= '.exe'
|
||||
endif
|
||||
if filereadable(l:pre_build)
|
||||
let l:info = system(l:pre_build . ' --version')
|
||||
if l:info ==# ''
|
||||
call mkdp#util#echo_messages('Type', "[markdown-preview.nvim]: Can not execute pre build binary bundle to get version, will download latest pre build binary bundle")
|
||||
return ''
|
||||
endif
|
||||
let l:info = split(l:info, '\n')
|
||||
return l:info[0]
|
||||
endif
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! mkdp#util#toggle_preview() abort
|
||||
if !get(b:, 'MarkdownPreviewToggleBool')
|
||||
call mkdp#util#open_preview_page()
|
||||
let b:MarkdownPreviewToggleBool=1
|
||||
else
|
||||
call mkdp#util#stop_preview()
|
||||
let b:MarkdownPreviewToggleBool=0
|
||||
endif
|
||||
endfunction
|
||||
|
528
sources_non_forked/markdown-preview.nvim/autoload/nvim/api.vim
Normal file
528
sources_non_forked/markdown-preview.nvim/autoload/nvim/api.vim
Normal file
@ -0,0 +1,528 @@
|
||||
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
|
||||
let lines = getbufline(a:bufnr, 1, '$')
|
||||
return len(lines)
|
||||
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 = nvim#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)
|
||||
return setbufvar(a:bufnr, '&'.a:name, a: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 key = 'Coc'.a:hlGroup
|
||||
if empty(prop_type_get(key))
|
||||
call prop_type_add(key, {'highlight': a:hlGroup, 'combine': 1})
|
||||
endif
|
||||
let end = a:colEnd
|
||||
if end == -1
|
||||
let end = strlen(getbufline(a:bufnr, a:line + 1)[0]) + 1
|
||||
endif
|
||||
let id = 0
|
||||
if a:srcId != 0
|
||||
let cached = getbufvar(a:bufnr, 'prop_namespace_'.a:srcId, [])
|
||||
let id = s:prop_id
|
||||
let s:prop_id = id + 1
|
||||
call add(cached, id)
|
||||
call setbufvar(a:bufnr, 'prop_namespace_'.a:srcId, cached)
|
||||
endif
|
||||
call prop_add(a:line + 1, a:colStart + 1, {'length': end - a:colStart, 'bufnr': a:bufnr, 'type': key, 'id': id})
|
||||
endfunction
|
||||
|
||||
function! s:funcs.buf_clear_namespace(bufnr, srcId, startLine, endLine) abort
|
||||
if !has('textprop')
|
||||
return
|
||||
endif
|
||||
if a:srcId == 0
|
||||
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 id in cached
|
||||
if a:endLine == -1
|
||||
if a:startLine == 0 && a:endLine == -1
|
||||
call prop_remove({'id':id, 'bufnr': a:bufnr})
|
||||
elseif a:endLine != -1
|
||||
call prop_remove({'id':id, 'bufnr': a:bufnr}, a:startLine, a:endLine)
|
||||
else
|
||||
let len = s:buf_line_count(a:bufnr)
|
||||
call prop_remove({'id':id, 'bufnr': a:bufnr}, a:startLine, len)
|
||||
endif
|
||||
else
|
||||
endif
|
||||
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
|
||||
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
|
||||
let delCount = end - (startLnum - 1)
|
||||
if a:bufnr == bufnr('%')
|
||||
" replace
|
||||
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)
|
||||
silent execute start . ','.(start + delCount - 1).'d'
|
||||
endif
|
||||
endif
|
||||
else
|
||||
if exists('*setbufline')
|
||||
" replace
|
||||
if delCount == len(replacement)
|
||||
call setbufline(a:bufnr, startLnum, replacement)
|
||||
else
|
||||
if len(replacement)
|
||||
call appendbufline(a:bufnr, startLnum - 1, replacement)
|
||||
endif
|
||||
if delCount
|
||||
let start = startLnum + len(replacement)
|
||||
call deletebufline(a:bufnr, start, start + delCount - 1)
|
||||
endif
|
||||
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
|
||||
|
||||
function! s:funcs.win_get_cursor(win_id) abort
|
||||
let winid = win_getid()
|
||||
call win_gotoid(a:win_id)
|
||||
let pos = [line('.'), col('.')]
|
||||
call win_gotoid(winid)
|
||||
return pos
|
||||
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
|
||||
let winid = win_getid()
|
||||
call win_gotoid(a:win_id)
|
||||
execute 'vertical resize '.a:width
|
||||
call win_gotoid(winid)
|
||||
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
|
||||
let winnr = win_id2win(a:win_id)
|
||||
if winnr != 0
|
||||
let curr = winnr()
|
||||
if winnr == curr
|
||||
execute 'resize '.a:height
|
||||
else
|
||||
execute winnr.'wincmd w'
|
||||
execute 'resize '.a:height
|
||||
wincmd p
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:funcs.win_set_option(win_id, name, value) abort
|
||||
call setwinvar(a:win_id, '&'.a:name, a:value)
|
||||
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 !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 winnr = win_id2win(a:win_id)
|
||||
if winnr != 0
|
||||
let [line, col] = a:pos
|
||||
let curr = winnr()
|
||||
if winnr == curr
|
||||
call cursor(line, col + 1)
|
||||
else
|
||||
execute winnr.'wincmd w'
|
||||
call cursor(line, col + 1)
|
||||
execute curr.'wincmd w'
|
||||
endif
|
||||
endif
|
||||
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! nvim#api#func_names() abort
|
||||
return keys(s:funcs)
|
||||
endfunction
|
||||
|
||||
function! nvim#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! nvim#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:
|
Reference in New Issue
Block a user