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
# TODO
@ -42,7 +42,7 @@ Nim support for Neovim
- [ ] Autocompletion with deoplete
- [ ] REPL interaction
- [ ] Add tests
- [ ] CI integration
- [x] CI integration
- [ ] Test nimsuggest for surprises
- [ ] Unit tests

View file

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

View file

@ -6,18 +6,67 @@ 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 [_, ctype, name, type, filename, l, c, doc] = split(a:data.lines[0], " ")
echohl Function | echon "Type"
echohl Comment | echon ": "
echohl Typedef | echon type
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 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
endfunction
function! features#info#run()
call util#StartQuery()
call suggest#New("def", 0, s:InfoImpl)
endfunction

View file

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

View file

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

View file

@ -19,16 +19,20 @@ function! s:NimSuggest.on_stderr()
endfunction
function! s:NimSuggest.on_exit()
call self.handler.run(self)
if len(self.lines) > 0
call self.handler.run(self)
else
echo ""
endif
endfunction
function! suggest#New(command, useV2, handler)
function! suggest#NewKnown(command, useV2, file, line, col, handler)
let result = copy(s:NimSuggest)
let result.lines = []
let result.file = expand("%:p")
let result.file = a:file
let result.tempfile = result.file . ".temp"
let result.line = line(".")
let result.col = col(".")
let result.line = a:line
let result.col = a:col
let result.handler = a:handler
" if a:useTempFile
" 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")
return result
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
endif
execute ":" . a:line
execute ":norm " . (a:col - 1) . "|"
execute ":norm " . (a:col) . "|"
endfunction
@ -35,8 +35,55 @@ function! util#JumpFromQuickfix(shouldReturn)
let [file, location, _] = split(getline(line(".")), "|")
let [l, c] = split(location, " col ")
wincmd p
call s:JumpToLocation(file, l, c)
call util#JumpToLocation(file, l, c)
if a:shouldReturn
norm zt
wincmd p
endif
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
let s:loaded = 1
au BufNewFile,BufRead *.nim set filetype=nim
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> gd :NimDefinition<cr>
nnoremap <buffer> gt :NimInfo<cr>
nnoremap <buffer> gT :NimInfoVerbose<cr>
autocmd! CursorHold,InsertLeave,TextChanged,InsertEnter *.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()

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 varargs with without yield
" syntax keyword nimOperator for while
syntax keyword nimRepeat for while
syntax keyword nimBoolean true false
syntax keyword nimConditional if elif else case continue break
syntax keyword nimDefine from as
@ -109,6 +109,9 @@ syntax match nimToken "(\."
syntax match nimToken "\.)"
" String
syntax region nimString start=/\v"/ skip=/\v\\./ end=/\v"/
" Linking
highlight link nimBuiltinIterators Typedef
highlight link nimBuiltinFunction Function
@ -135,6 +138,7 @@ highlight link nimFloat Float
highlight link nimString String
highlight link nimChar Char
highlight link nimNumber Number
highlight link nimString String
highlight link nimConditional Conditional
highlight link nimConstant Constant