Support Vim script plugins

This commit is contained in:
hrsh7th
2021-09-13 23:57:34 +09:00
parent 65b759cdab
commit 6173796b2b
4 changed files with 129 additions and 7 deletions

View File

@@ -544,17 +544,17 @@ source.new = function()
return self
end
---Return the source name for some information.
function source:get_debug_name = function()
return 'example'
end
---Return the source is available or not.
---@return boolean
function source:is_available()
return true
end
---Return the source name for some information.
source:get_debug_name = function()
return 'example'
end
---Return keyword pattern which will be used...
--- 1. Trigger keyword completion
--- 2. Detect menu start offset

View File

@@ -1,9 +1,80 @@
let s:TextEdit = vital#cmp#import('VS.LSP.TextEdit')
let s:bridge_id = 0
let s:sources = {}
"
" cmp#apply_text_edits
"
" TODO: Remove this if nvim's apply_text_edits will be improved.
"
function! cmp#apply_text_edits(bufnr, text_edits) abort
if !exists('s:TextEdit')
let s:TextEdit = vital#cmp#import('VS.LSP.TextEdit')
endif
call s:TextEdit.apply(a:bufnr, a:text_edits)
endfunction
"
" cmp#register_source
"
function! cmp#register_source(name, source) abort
let l:methods = []
for l:method in ['is_available', 'get_debug_name', 'get_trigger_characters', 'get_keyword_pattern', 'complete', 'execute', 'resolve']
if has_key(a:source, l:method) && type(a:source[l:method]) == v:t_func
call add(l:methods, l:method)
endif
endfor
let s:bridge_id += 1
let a:source.bridge_id = s:bridge_id
let a:source.id = luaeval('require("cmp").register_source(_A[1], require("cmp.vim_source").new(_A[2], _A[3]))', [a:name, s:bridge_id, l:methods])
let s:sources[s:bridge_id] = a:source
return a:source.id
endfunction
"
" cmp#unregister_source
"
function! cmp#unregister_source(id) abort
for [l:i, l:source] in s:sources
if l:source.id == a:id
call remove(s:sources, index(s:sources, l:source))
break
endif
endfor
call luaeval('require("cmp").unregister_source(_A)', a:id)
endfunction
"
" cmp#_method
"
function! cmp#_method(id, method, args) abort
try
let l:source = s:sources[a:id]
if a:method ==# 'is_available'
return l:source[a:method]()
elseif a:method ==# 'get_debug_name'
return l:source[a:method]()
elseif a:method ==# 'get_keyword_pattern'
return l:source[a:method](a:args[0])
elseif a:method ==# 'get_trigger_characters'
return l:source[a:method](a:args[0])
elseif a:method ==# 'complete'
return l:source[a:method](a:args[0], s:callback(a:args[1]))
elseif a:method ==# 'resolve'
return l:source[a:method](a:args[0], s:callback(a:args[1]))
elseif a:method ==# 'execute'
return l:source[a:method](a:args[0], s:callback(a:args[1]))
endif
catch /.*/
echomsg string({ 'exception': v:exception, 'throwpoint': v:throwpoint })
endtry
return v:null
endfunction
"
" s:callback
"
function! s:callback(id) abort
return { ... -> luaeval('require("cmp.vim_source").on_callback(_A[1], _A[2])', [a:id, a:000]) }
endfunction

View File

@@ -48,7 +48,6 @@ end
---Reset current completion state
---@return boolean
source.reset = function(self)
debug.log(self:get_debug_name(), 'source.reset')
self.cache:clear()
self.revision = self.revision + 1
self.context = context.empty()

52
lua/cmp/vim_source.lua Normal file
View File

@@ -0,0 +1,52 @@
local misc = require('cmp.utils.misc')
local vim_source = {}
---@param id number
---@param args any[]
vim_source.on_callback = function(id, args)
return vim_source.to_callback.callbacks[id](unpack(args))
end
---@param callback function
---@return number
vim_source.to_callback = setmetatable({
callbacks = {}
}, {
__call = function(self, callback)
local id = misc.id('cmp.vim_source.to_callback')
self.callbacks[id] = function(...)
callback(...)
self.callbacks[id] = nil
end
return id
end
})
---Convert to serializable args.
---@param args any[]
vim_source.to_args = function(args)
for i, arg in ipairs(args) do
if type(arg) == 'function' then
args[i] = vim_source.to_callback(arg)
end
end
return args
end
---@param id number
---@param methods string[]
vim_source.new = function (id, methods)
local self = setmetatable({}, { __index = vim_source })
for _, method in ipairs(methods) do
self[method] = (function(m)
return function(_, ...)
return vim.fn['cmp#_method'](id, m, vim_source.to_args({ ... }))
end
end)(method)
end
return self
end
return vim_source