Autocompleiton and friends

This commit is contained in:
baabelfish 2016-02-01 09:16:57 +02:00
commit d07c351677
13 changed files with 167 additions and 79 deletions

View file

@ -18,6 +18,7 @@ endfunction
function! features#definition#run()
call suggest#New("def", 0, s:DefinitionImpl)
call suggest#New("def", 1, 0, s:DefinitionImpl)
endfunction

View file

@ -6,66 +6,38 @@ let s:loaded = 1
let s:InfoImpl = {}
let s:idtypes = {
\ 'skProc': "Function",
\ 'skTemplate': "Template",
\ 'skType': "Type",
\ 'skMacro': "Macro",
\ 'skMethod': "Method",
\ 'skField': "Field",
\ 'skAlias': "Alias",
\ 'skConditional': "Conditional",
\ 'skConst': "Constant",
\ 'skConverter': "Converter",
\ 'skDynLib': "Dynamic library",
\ 'skEnumField': "Enum field",
\ 'skForVar': "Loop variable",
\ 'skGenericParam': "Generic parameter",
\ 'skGlobalVar': "Global variable",
\ 'skGlobalLet': "Global constant",
\ 'skIterator': "Iterator",
\ 'skLabel': "Label",
\ 'skLet': "Runtime constant",
\ 'skModule': "Module",
\ 'skPackage': "Package",
\ 'skParam': "Parameter",
\ 'skResult': "Result",
\ 'skStub': "Stub",
\ 'skTemp': "Temporary",
\ 'skUnknown': "Unknown",
\ 'skVar': "Variable"
\ }
function! s:InfoImpl.run(data)
if len(a:data.lines) == 0
echo "No information found"
else
let res = util#ParseV1(a:data.lines[0])
echohl None
let [_, ctype, name, type, filename, l, c, doc] = split(a:data.lines[0], "\\t")
let path = join(split(name, '\.')[0:-2], ".")
let module = split(name, '\.')[0]
let name = split(name, '\.')[-1]
let node_type = s:idtypes[ctype]
echohl Function | echon name
echohl Function | echon res.lname
echohl Comment | echon "\n » "
echohl Type | echon node_type
echohl Type | echon res.kindstr
if len(type) > 0 && name != type
if len(res.name) > 0 && res.lname != res.name
echon "\n"
echohl Comment | echon " » "
echohl Typedef | echon type
echohl Typedef | echon res.name
end
echohl Comment | echon "\n » "
echohl Include | echon path
echohl Include | echon res.location
echohl Comment | echon " ("
echohl String | echon filename
echohl String | echon res.file
echohl Comment | echon ")"
if res.doc != "\"\""
echohl Comment | echon "\n » "
echohl Normal | echon res.doc
endif
endif
endfunction
function! features#info#run()
call suggest#New("def", 0, s:InfoImpl)
call suggest#New("def", 1, 0, s:InfoImpl)
endfunction

View file

@ -27,5 +27,6 @@ endfunction
function! features#outline#run()
cclose
call setqflist([])
call suggest#New("outline", 1, s:OutlineImpl)
call suggest#New("outline", 1, 1, s:OutlineImpl)
endfunction

View file

@ -37,5 +37,6 @@ endfunction
function! features#rename#run(inProject)
let s:findInProject = a:inProject
call suggest#New("use", 1, s:RenameImpl)
call suggest#New("use", 1, 1, s:RenameImpl)
endfunction

View file

@ -46,13 +46,15 @@ endfunction
let s:UsagesDefinitionImpl = {}
function! s:UsagesDefinitionImpl.run(data)
let res = util#ParseV1(a:data.lines[0])
call suggest#NewKnown("use", 1, res.file, res.line, res.col + 1, s:UsagesImpl)
" let res = util#ParseV1(a:data.lines[0])
" call suggest#NewKnown("use", 1, res.file, res.line, res.col + 1, s:UsagesImpl)
call suggest#New("use", 1, 1, s:UsagesImpl)
endfunction
function! features#usages#run(findInProject)
cclose
call setqflist([])
let s:findInProject = a:findInProject
call suggest#New("def", 0, s:UsagesDefinitionImpl)
call suggest#New("def", 1, 0, s:UsagesDefinitionImpl)
endfunction

40
autoload/omni.vim Normal file
View file

@ -0,0 +1,40 @@
" if exists("s:loaded")
" finish
" endif
" let s:loaded = 1
function! omni#item(parsed)
return {
\ 'word': a:parsed.lname,
\ 'menu': a:parsed.module,
\ 'kind': a:parsed.kindshort . " » " . a:parsed.type,
\ 'info': a:parsed.doc,
\ }
endfunction
function! omni#nim(findstart, base)
if a:findstart && empty(a:base)
return col('.')
else
let file = expand("%:p")
let tempfile = file . ".temp"
let l = line(".")
let c = col(".")
call writefile(getline(1, '$'), tempfile)
let query = "sug " . file . ";" . tempfile . ":" . l . ":" . c
let jobcmdstr = g:nvim_nim_exec_nimsuggest . " --v2 --stdin " . file
let fullcmd = 'echo -e ' . shellescape(query, 1) . '|' . jobcmdstr
let completions_raw = split(system(fullcmd), "\n")[4:-2]
let completions = []
for line in completions_raw
call add(completions, omni#item(util#ParseV2(line)))
endfor
return {
\ 'words': completions,
\ 'refresh': 'always' }
endfunction

View file

@ -5,29 +5,44 @@ let s:loaded = 1
let s:findInProject = 1
let s:NimSuggestServer = {}
function! s:NimSuggestServer.on_stdout(job, chunk)
" echoerr join(a:chunk, "\n")
endfunction
function! s:NimSuggestServer.on_stderr(job, chunk)
" echoerr join(a:chunk, "\n")
endfunction
function! s:NimSuggestServer.on_exit()
" call jobstop(self.job_server)
endfunction
" NimSuggest
let s:NimSuggest = {}
function! s:NimSuggest.on_stdout(job, chunk)
if len(a:chunk[0]) != 0 && !(a:chunk[0] =~ "^usage")
call extend(self.lines, a:chunk)
endif
call extend(self.lines, a:chunk)
endfunction
function! s:NimSuggest.on_stderr()
function! s:NimSuggest.on_stderr(job, chunk)
endfunction
function! s:NimSuggest.on_exit()
if self.isAsync
let self.lines = self.lines[5:-1]
else
let self.lines = self.lines[4:-1]
endif
if len(self.lines) > 0
call self.handler.run(self)
else
" Clear cli
echo ""
echo ""
endif
endfunction
function! suggest#NewKnown(command, useV2, file, line, col, handler)
function! suggest#NewKnown(command, sync, useV2, file, line, col, handler)
let result = copy(s:NimSuggest)
let result.lines = []
let result.file = a:file
@ -35,28 +50,35 @@ function! suggest#NewKnown(command, useV2, file, line, col, handler)
let result.line = a:line
let result.col = a:col
let result.handler = a:handler
let result.isAsync = has("nvim") && !a:sync && g:nvim_nim_enable_async
" if a:useTempFile
" call writefile(getline(1, '$'), result.tempfile)
" endif
" let nimcom = completion . " " . file . (a:useTempFile ? (";" . result.tempfile) : "") . ":" . line . ":" . col
let jobcmd = [g:nvim_nim_exec_nimsuggest, (a:useV2 ? '--v2' : ''), '--stdin', result.file]
let jobcmdstr = g:nvim_nim_exec_nimsuggest . " " . (a:useV2 ? '--v2' : '') . " " . '--stdin' . " " . result.file
let jobstdin = a:command . " " . result.file . ":" . result.line . ":" . result.col
let query = a:command . " " . result.file . ":" . result.line . ":" . result.col
if !g:nvim_nim_enable_async || !has("nvim")
let fullcmd = 'echo -e ' . shellescape(jobstdin, 1) . '|' . jobcmdstr
if !result.isAsync
let jobcmdstr = g:nvim_nim_exec_nimsuggest . " " . (a:useV2 ? '--v2' : '') . " " . '--stdin' . " " . result.file
let fullcmd = 'echo -e ' . shellescape(query, 1) . '|' . jobcmdstr
let result.lines = split(system(fullcmd), "\n")[4:-2]
call a:handler.run(result)
else
call util#StartQuery()
let result.job = jobstart([g:nvim_nim_exec_nimsuggest, (a:useV2 ? '--v2' : ''), '--stdin', result.file], result)
call jobsend(result.job, jobcmd)
let result.job_server = jobstart([g:nvim_nim_exec_nimsuggest, '--port:5999', '--address:localhost', (a:useV2 ? '--v2' : ''), result.file], s:NimSuggestServer)
if result.job_server < 1
echoerr "Unable to start server"
else
" FIXME: Telnet is not possibly the best way to communicate :S
let result.job_suggest = jobstart(['telnet', 'localhost', '5999'], result)
call jobsend(result.job_suggest, query . "\n")
endif
endif
return result
endfunction
function! suggest#New(command, useV2, handler)
return suggest#NewKnown(a:command, a:useV2, expand("%:p"), line("."), col("."), a:handler)
function! suggest#New(command, sync, useV2, handler)
return suggest#NewKnown(a:command, a:sync, a:useV2, expand("%:p"), line("."), col("."), a:handler)
endfunction

View file

@ -4,6 +4,37 @@ endif
let s:loaded = 1
let s:idtypes = {
\ 'skProc': ["p", "Function"],
\ 'skTemplate': ["t", "Template"],
\ 'skType': ["T", "Type"],
\ 'skMacro': ["M", "Macro"],
\ 'skMethod': ["m", "Method"],
\ 'skField': ["field", "Field"],
\ 'skAlias': ["a", "Alias"],
\ 'skConditional': ["c", "Conditional"],
\ 'skConst': ["C", "Constant"],
\ 'skConverter': ["c", "Converter"],
\ 'skDynLib': ["d", "Dynamic library"],
\ 'skEnumField': ["e", "Enum field"],
\ 'skForVar': ["l", "Loop variable"],
\ 'skGenericParam': ["g", "Generic parameter"],
\ 'skGlobalVar': ["g", "Global variable"],
\ 'skGlobalLet': ["g", "Global constant"],
\ 'skIterator': ["i", "Iterator"],
\ 'skLabel': ["l", "Label"],
\ 'skLet': ["r", "Runtime constant"],
\ 'skModule': ["m", "Module"],
\ 'skPackage': ["p", "Package"],
\ 'skParam': ["p", "Parameter"],
\ 'skResult': ["r", "Result"],
\ 'skStub': ["s", "Stub"],
\ 'skTemp': ["t", "Temporary"],
\ 'skUnknown': ["u", "Unknown"],
\ 'skVar': ["v", "Variable"],
\ }
function! util#FirstNonEmpty(lines)
for line in a:lines
if len(line) > 0
@ -48,9 +79,15 @@ function! util#StartQuery()
endfunction
function! s:GetModule(path)
return a:path[0]
endfunction
function! util#ParseV1(line)
let res = split(a:line, " ")
let path = split(res[2], "\\.")
let result = {
\ "ctype": res[0],
\ "kind": res[1],
@ -60,9 +97,11 @@ function! util#ParseV1(line)
\ "line": res[5],
\ "col": res[6],
\ "doc": res[7],
\ "module": join(path[0:-3], "."),
\ "module": s:GetModule(path),
\ "location": join(path[0:-2], "."),
\ "lname": path[-1],
\ "kindstr": s:idtypes[res[1]][1],
\ "kindshort": s:idtypes[res[1]][0],
\ }
return result
endfunction
@ -80,10 +119,13 @@ function! util#ParseV2(line)
\ "line": res[5],
\ "col": res[6],
\ "doc": res[7],
\ "module": join(path[0:-3], "."),
\ "quality": res[8],
\ "module": s:GetModule(path),
\ "location": join(path[0:-2], "."),
\ "name": path[-1],
\ "lname": path[-1],
\ "kindstr": s:idtypes[res[1]][1],
\ "kindshort": s:idtypes[res[1]][0],
\ }
return result
endfunction