Added travis script

This commit is contained in:
baabelfish 2016-01-30 20:32:45 +02:00
commit 7953c47a57
16 changed files with 403 additions and 42 deletions

2
.travis.yml Normal file
View file

@ -0,0 +1,2 @@
language: viml
script: ./other/travis.sh

View file

@ -1,4 +1,4 @@
# nvim-nim # nvim-nim [![Build Status](https://travis-ci.org/baabelfish/nvim-nim.svg?branch=master)](https://travis-ci.org/baabelfish/nvim-nim)
Nim support for Neovim Nim support for Neovim
# TODO # TODO
@ -42,7 +42,7 @@ Nim support for Neovim
- [ ] Autocompletion with deoplete - [ ] Autocompletion with deoplete
- [ ] REPL interaction - [ ] REPL interaction
- [ ] Add tests - [ ] Add tests
- [ ] CI integration - [x] CI integration
- [ ] Test nimsuggest for surprises - [ ] Test nimsuggest for surprises
- [ ] Unit tests - [ ] Unit tests

View file

@ -9,12 +9,15 @@ let s:DefinitionImpl = {}
function! s:DefinitionImpl.run(data) function! s:DefinitionImpl.run(data)
if len(a:data.lines) > 0 if len(a:data.lines) > 0
let [_, _, _, _, filename, l, c, _] = split(a:data.lines[0], " ") let res = util#ParseV1(a:data.lines[0])
call util#JumpToLocation(filename, l, c + 2) call util#JumpToLocation(res.file, res.line, res.col + 1)
else
echohl Comment | echo "Not found"
endif endif
endfunction endfunction
function! features#definition#run() function! features#definition#run()
call util#StartQuery()
call suggest#New("def", 0, s:DefinitionImpl) call suggest#New("def", 0, s:DefinitionImpl)
endfunction endfunction

View file

@ -6,18 +6,67 @@ let s:loaded = 1
let s:InfoImpl = {} 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) function! s:InfoImpl.run(data)
if len(a:data.lines) == 0 if len(a:data.lines) == 0
echo "No information found" echo "No information found"
else else
let [_, ctype, name, type, filename, l, c, doc] = split(a:data.lines[0], " ") echohl None
echohl Function | echon "Type" let [_, ctype, name, type, filename, l, c, doc] = split(a:data.lines[0], "\\t")
echohl Comment | echon ": " let path = join(split(name, '\.')[0:-2], ".")
echohl Typedef | echon type let module = split(name, '\.')[0]
let name = split(name, '\.')[-1]
let node_type = s:idtypes[ctype]
echohl Function | echon name
echohl Comment | echon "\n » "
echohl Type | echon node_type
if len(type) > 0 && name != type
echon "\n"
echohl Comment | echon " » "
echohl Typedef | echon type
end
echohl Comment | echon "\n » "
echohl Include | echon path
echohl Comment | echon " ("
echohl String | echon filename
echohl Comment | echon ")"
endif endif
endfunction endfunction
function! features#info#run() function! features#info#run()
call util#StartQuery()
call suggest#New("def", 0, s:InfoImpl) call suggest#New("def", 0, s:InfoImpl)
endfunction endfunction

View file

@ -4,37 +4,56 @@ endif
let s:loaded = 1 let s:loaded = 1
let s:highlights = -1
let s:UsagesImpl = {} let s:UsagesImpl = {}
function! s:UsagesImpl.run(data) function! s:UsagesImpl.run(data)
for line in a:data.lines if s:highlights >= 0
if len(line) == 0 call matchdelete(s:highlights)
continue end
endif let s:highlights = -1
let highlights = []
let [ctype, context, fullname, type, filename, line, column, doc, random] = split(line, " ") if len(a:data.lines) < 1
if !s:findInProject && filename != expand("%:p") echohl Comment | echo "No usages found"
continue else
endif for line in a:data.lines
if len(line) == 0
continue
endif
let module = split(fullname, '\.')[0] let res = util#ParseV2(line)
let name = split(fullname, '\.')[-1] if !s:findInProject && res.file != expand("%:p")
call setqflist([{ continue
\ 'filename': filename, endif
\ 'lnum': line,
\ 'col': column + 1, call setqflist([{
\ 'text': ctype . ": " . name . " (" . fullname . ")"}], \ 'filename': res.file,
\ 'a') \ 'lnum': res.line,
endfor \ 'col': res.col + 1,
copen \ 'text': res.ctype . ": " . res.name . " (" . res.location . ")"}],
nnoremap <buffer><silent> <return> :call util#JumpFromQuickfix(0)<cr> \ 'a')
nnoremap <buffer><silent> o :call util#JumpFromQuickfix(1)<cr> " call add(highlights, [line, column + 1, len(name)])
endfor
" let s:highlights = matchaddpos("Search", highlights)
copen
nnoremap <buffer><silent> <return> :call util#JumpFromQuickfix(0)<cr>
nnoremap <buffer><silent> o :call util#JumpFromQuickfix(1)<cr>
endif
endfunction 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)
endfunction
function! features#usages#run(findInProject) function! features#usages#run(findInProject)
call util#StartQuery()
cclose cclose
call setqflist([]) call setqflist([])
let s:findInProject = a:findInProject let s:findInProject = a:findInProject
call suggest#New("use", 1, s:UsagesImpl) call suggest#New("def", 0, s:UsagesDefinitionImpl)
endfunction endfunction

View file

@ -15,7 +15,7 @@ function! s:NimHighlighter.on_stderr(job, chunk)
endfunction endfunction
function! s:NimHighlighter.on_exit() function! s:NimHighlighter.on_exit()
if self.file != expand("%:p") if empty(self.lines) && self.file != expand("%:p")
return return
endif endif
let highlights = { let highlights = {
@ -52,7 +52,12 @@ function! s:NimHighlighter.on_exit()
if len(line) == 0 if len(line) == 0
continue continue
endif endif
let p = split(line, " ") let p = split(line, " ")
if len(p) < 5
continue
endif
let line = p[2] + 0 let line = p[2] + 0
let c = p[3] + 1 let c = p[3] + 1
let s = p[4] + 0 let s = p[4] + 0
@ -90,7 +95,9 @@ endfunction
function! highlighter#guard() function! highlighter#guard()
if line("$") + 0 < 500 if g:nvim_nim_enable_highlighter
call highlighter#New() if line("$") + 0 < 500
call highlighter#New()
endif
endif endif
endfunction endfunction

View file

@ -19,16 +19,20 @@ function! s:NimSuggest.on_stderr()
endfunction endfunction
function! s:NimSuggest.on_exit() function! s:NimSuggest.on_exit()
call self.handler.run(self) if len(self.lines) > 0
call self.handler.run(self)
else
echo ""
endif
endfunction endfunction
function! suggest#New(command, useV2, handler) function! suggest#NewKnown(command, useV2, file, line, col, handler)
let result = copy(s:NimSuggest) let result = copy(s:NimSuggest)
let result.lines = [] let result.lines = []
let result.file = expand("%:p") let result.file = a:file
let result.tempfile = result.file . ".temp" let result.tempfile = result.file . ".temp"
let result.line = line(".") let result.line = a:line
let result.col = col(".") let result.col = a:col
let result.handler = a:handler let result.handler = a:handler
" if a:useTempFile " if a:useTempFile
" call writefile(getline(1, '$'), result.tempfile) " call writefile(getline(1, '$'), result.tempfile)
@ -38,3 +42,8 @@ function! suggest#New(command, useV2, handler)
call jobsend(result.job, a:command . " " . result.file . ":" . result.line . ":" . result.col . "\nquit\n") call jobsend(result.job, a:command . " " . result.file . ":" . result.line . ":" . result.col . "\nquit\n")
return result return result
endfunction endfunction
function! suggest#New(command, useV2, handler)
return suggest#NewKnown(a:command, a:useV2, expand("%:p"), line("."), col("."), a:handler)
endfunction

View file

@ -27,7 +27,7 @@ function! util#JumpToLocation(file, line, col)
execute ":e " . a:file execute ":e " . a:file
endif endif
execute ":" . a:line execute ":" . a:line
execute ":norm " . (a:col - 1) . "|" execute ":norm " . (a:col) . "|"
endfunction endfunction
@ -35,8 +35,55 @@ function! util#JumpFromQuickfix(shouldReturn)
let [file, location, _] = split(getline(line(".")), "|") let [file, location, _] = split(getline(line(".")), "|")
let [l, c] = split(location, " col ") let [l, c] = split(location, " col ")
wincmd p wincmd p
call s:JumpToLocation(file, l, c) call util#JumpToLocation(file, l, c)
if a:shouldReturn if a:shouldReturn
norm zt
wincmd p wincmd p
endif endif
endfunction endfunction
function! util#StartQuery()
echohl Comment | echo "..."
endfunction
function! util#ParseV1(line)
let res = split(a:line, " ")
let path = split(res[2], "\\.")
let result = {
\ "ctype": res[0],
\ "kind": res[1],
\ "symbol": res[2],
\ "name": res[3],
\ "file": res[4],
\ "line": res[5],
\ "col": res[6],
\ "doc": res[7],
\ "module": join(path[0:-3], "."),
\ "location": join(path[0:-2], "."),
\ "lname": path[-1],
\ }
return result
endfunction
function! util#ParseV2(line)
let res = split(a:line, " ")
let path = split(res[2], "\\.")
let result = {
\ "ctype": res[0],
\ "kind": res[1],
\ "symbol": res[2],
\ "type": res[3],
\ "file": res[4],
\ "line": res[5],
\ "col": res[6],
\ "doc": res[7],
\ "module": join(path[0:-3], "."),
\ "location": join(path[0:-2], "."),
\ "name": path[-1],
\ "lname": path[-1],
\ }
return result
endfunction

View file

@ -3,6 +3,7 @@ if exists("s:loaded")
endif endif
let s:loaded = 1 let s:loaded = 1
au BufNewFile,BufRead *.nim set filetype=nim au BufNewFile,BufRead *.nim set filetype=nim
au BufNewFile,BufRead *.nims set filetype=nims au BufNewFile,BufRead *.nims set filetype=nims
let g:nvim_nim_enable_highlighter = 0

View file

@ -20,8 +20,11 @@ command! NimOutline :call features#outline#run()
nnoremap <buffer> <c-]> :NimDefinition<cr> nnoremap <buffer> <c-]> :NimDefinition<cr>
nnoremap <buffer> gd :NimDefinition<cr> nnoremap <buffer> gd :NimDefinition<cr>
nnoremap <buffer> gt :NimInfo<cr> nnoremap <buffer> gt :NimInfo<cr>
nnoremap <buffer> gT :NimInfoVerbose<cr>
autocmd! CursorHold,InsertLeave,TextChanged,InsertEnter *.nim call highlighter#guard() autocmd! CursorHold,InsertLeave,TextChanged,InsertEnter *.nim call highlighter#guard()
autocmd! BufReadPost,BufWritePost *.nim call highlighter#guard() autocmd! BufReadPost,BufWritePost *.nim call highlighter#guard()
" autocmd! BufWinEnter quickfix let g:qfix_win = bufnr("$")
" autocmd! BufWinLeave * if exists("g:qfix_win") && expand("<abuf>") == g:qfix_win | call features#usages#clear_matches() | unlet! g:qfix_win | endif
call highlighter#guard() call highlighter#guard()

View file

@ -0,0 +1,39 @@
import
strutils,
sequtils,
util
static:
test "outline", "tests/tmodule.nim", CompletionV2, 1, 1:
assert results.len == 10
assert results[1].location == "tmodule.Vec"
assert results[1].module == "tmodule"
assert results[1].lname == "x"
# v1 is broken
test "use", "tests/tmodule.nim", CompletionV1, 14, 8:
assert results.len == 3 # Wrong (only finds results under search)
test "use", "tests/tmodule.nim", CompletionV2, 14, 8:
assert results.len == 9
test "use", "tests/tmodule.nim", CompletionV1, 9, 22:
assert results.len == 1 # Wrong
test("use", "tests/tmodule.nim", CompletionV2, 9, 22):
assert results.len == 9
# v2 is broken
test("def", "tests/tmodule.nim", CompletionV1, 21, 8):
assert results.len == 1
assert results[0].doc == "\"\""
test("def", "tests/tmodule.nim", CompletionV2, 21, 8):
assert results.len == 0 # Wrong (should find one)
test("sug", "tests/tmodule.nim", CompletionV1, 22, 3):
assert results.len == 4
test("sug", "tests/tmodule.nim", CompletionV2, 22, 3):
assert results.len == 4
# con returns the function def??
test("con", "tests/tmodule.nim", CompletionV1, 18, 7):
assert results.len == 1
test("con", "tests/tmodule.nim", CompletionV2, 18, 7):
assert results.len == 1

22
other/tests/tmodule.nim Normal file
View file

@ -0,0 +1,22 @@
import
tother
type Vec = object
x: int
y: int
proc `$`(x: Vec): string = $x & ":" & $y
proc print(x: Vec) = echo x
proc sum(a, b: Vec): Vec = Vec(
x: a.x + b.x,
y: a.y + b.y)
var a: Vec
var b: Vec
var z: X
a.sum(
asdoifjasdoi # Works after error
var x: Vec
b.

4
other/tests/tother.nim Normal file
View file

@ -0,0 +1,4 @@
## A documentation string
type X* = int
5.echo

91
other/tests/util.nim Normal file
View file

@ -0,0 +1,91 @@
import
sequtils,
strutils
proc last[T](a: seq[T]): T = a[a.len - 1]
proc slice[T](a: seq[T], hi: static[int]): auto = slice(a, 0, hi)
proc slice[T](a: seq[T], lo, hi: static[int]): seq[T] =
result = @[]
let realHi = if hi < 0: a.len + hi else: hi
for idx in lo..min(realHi, a.len - 1):
result.add(a[idx])
type
CompletionV1* = object
values: array[10, string]
CompletionV2* = object
values: array[10, string]
Completion* = CompletionV1 | CompletionV2
proc len*(c: Completion): auto = c.values.len
proc `$`*(c: seq[Completion]): string =
result = ""
for r in c:
result &= $r & "\n"
# Create accessors for array-types
template access(name: expr, idx: static[int]): expr =
proc name*(c: Completion): string = c.values[idx]
access(ctype, 0)
access(kind, 1)
access(symbol, 2)
access(signature, 3)
access(file, 4)
access(line, 5)
access(col, 6)
access(doc, 7)
access(random, 8)
access(`$`, 9)
access(str, 9)
proc lname*(c: Completion): string =
c.symbol.split(".").last
proc location*(c: Completion): string =
c.symbol.split(".").slice(0, -2).join(".")
proc module*(c: Completion): string =
c.symbol.split(".").slice(0, -3).join(".")
proc cmd*(CT: typedesc, source: string, ctype: string, line, col: int): string {.compileTime.} =
when CT is CompletionV1:
let paramsV2 = ""
else:
let paramsV2 = " --v2 "
"echo \"" &
ctype &
" " &
source &
":" & $line & ":" & $col & "\"" &
" | nimsuggest --stdin " & paramsV2 & source & "\n"
proc getResults*[T: Completion](f: string, ctype: string, line, col: int = 1): seq[T] {.compileTime.} =
result = @[]
let command = cmd(T, f, ctype, line, col)
let lines = command.staticExec.split("\n")
for line in lines[4..lines.len - 2]:
var completion: T
let raw = line.split("\t")
for idx in 0..completion.len - 1:
if idx < raw.len:
completion.values[9] = line
completion.values[idx] = raw[idx]
result.add(completion)
template test*(name, file: static[string], t: typedesc, line, col: int, body: expr): expr =
block:
let results {.inject.} = getResults[t](file, name, line, col)
body

61
other/travis.sh Executable file
View file

@ -0,0 +1,61 @@
#!/bin/bash
current=$PWD
install_nim() {
wget "http://nim-lang.org/download/nim-0.13.0.tar.xz" -O nim.tar.xz
mkdir nim
tar -xvf nim.tar.xz -C nim --strip-components=1
cd nim
./build.sh
export PATH=$PATH:$PWD/bin
cd ..
}
install_nimble() {
git clone https://github.com/nim-lang/nimble.git
cd nimble
git clone -b v0.13.0 --depth 1 https://github.com/nim-lang/nim vendor/nim
nim c -r src/nimble
export PATH=$PATH:$PWD/src
cd ..
}
install_nimsuggest() {
git clone https://github.com/nim-lang/nimsuggest
cd nimsuggest
echo "y" | nimble build
export PATH=$PATH:$PWD
cd ..
}
mkdir tmp
cd tmp
echo "Installing nim"
install_nim
echo "Installing nimble"
install_nimble
echo "Installing nimsuggest"
install_nimsuggest
cd ..
echo "================================================================================"
echo -e "\nNim:"
nim --version
echo -e "\nNimble:"
nimble --version
echo -e "\nNimsuggest:"
nimsuggest --version
echo "================================================================================"
echo "Run tests in $PWD"
cd $current/other
nim c tests/suggestions.nim

View file

@ -15,7 +15,7 @@ syntax keyword nimKeyword do expr stmt end generic mixin iterator
syntax keyword nimKeyword typedesc openarray out ptr ref return using syntax keyword nimKeyword typedesc openarray out ptr ref return using
syntax keyword nimKeyword varargs with without yield syntax keyword nimKeyword varargs with without yield
" syntax keyword nimOperator for while syntax keyword nimRepeat for while
syntax keyword nimBoolean true false syntax keyword nimBoolean true false
syntax keyword nimConditional if elif else case continue break syntax keyword nimConditional if elif else case continue break
syntax keyword nimDefine from as syntax keyword nimDefine from as
@ -109,6 +109,9 @@ syntax match nimToken "(\."
syntax match nimToken "\.)" syntax match nimToken "\.)"
" String
syntax region nimString start=/\v"/ skip=/\v\\./ end=/\v"/
" Linking " Linking
highlight link nimBuiltinIterators Typedef highlight link nimBuiltinIterators Typedef
highlight link nimBuiltinFunction Function highlight link nimBuiltinFunction Function
@ -135,6 +138,7 @@ highlight link nimFloat Float
highlight link nimString String highlight link nimString String
highlight link nimChar Char highlight link nimChar Char
highlight link nimNumber Number highlight link nimNumber Number
highlight link nimString String
highlight link nimConditional Conditional highlight link nimConditional Conditional
highlight link nimConstant Constant highlight link nimConstant Constant