Support Vim script plugins
This commit is contained in:
10
README.md
10
README.md
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
52
lua/cmp/vim_source.lua
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user