diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89026d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +doc/tags \ No newline at end of file diff --git a/autoload/highlighter.vim b/autoload/highlighter.vim index c98073e..2c8c902 100644 --- a/autoload/highlighter.vim +++ b/autoload/highlighter.vim @@ -3,7 +3,40 @@ if exists("s:loaded") endif let s:loaded = 1 -let s:NimHighlighter = {} +let s:highlights = { + \ 'skProc': "Function", + \ 'skTemplate': "PreProc", + \ 'skType': "Type", + \ 'skMacro': "Macro", + \ 'skMethod': "Function", + \ 'skField': "Identifier", + \ 'skAlias': "Type", + \ 'skConditional': "Conditional", + \ 'skConst': "Constant", + \ 'skConverter': "Function", + \ 'skDynLib': "Include", + \ 'skEnumField': "Identifier", + \ 'skForVar': "Special", + \ 'skGenericParam': "Typedef", + \ 'skGlobalVar': "Constant", + \ 'skGlobalLet': "Constant", + \ 'skIterator': "Keyword", + \ 'skLabel': "Identifier", + \ 'skLet': "Constant", + \ 'skModule': "Include", + \ 'skPackage': "Define", + \ 'skParam': "Identifier", + \ 'skResult': "Keyword", + \ 'skStub': "PreCondit", + \ 'skTemp': "Identifier", + \ 'skUnknown': "Error", + \ 'skVar': "Constant", + \ } + + +let s:NimHighlighter = { + \ } + " \ 'pty': 1 function! s:NimHighlighter.on_stdout(job, chunk) if len(a:chunk[0]) != 0 && !(a:chunk[0] =~ "^usage") @@ -19,35 +52,16 @@ function! s:NimHighlighter.on_exit() return endif - let highlights = { - \ 'skProc': ["Function", [], 0], - \ 'skTemplate': ["PreProc", [], 0], - \ 'skType': ["Type", [], 0], - \ 'skMacro': ["Macro", [], 0], - \ 'skMethod': ["Function", [], 0], - \ 'skField': ["Identifier", [], 0], - \ 'skAlias': ["Type", [], 0], - \ 'skConditional': ["Conditional", [], 0], - \ 'skConst': ["Constant", [], 1], - \ 'skConverter': ["Function", [], 0], - \ 'skDynLib': ["Include", [], 0], - \ 'skEnumField': ["Identifier", [], 0], - \ 'skForVar': ["Special", [], 1], - \ 'skGenericParam': ["Typedef", [], 0], - \ 'skGlobalVar': ["Constant", [], 1], - \ 'skGlobalLet': ["Constant", [], 1], - \ 'skIterator': ["Keyword", [], 0], - \ 'skLabel': ["Identifier", [], 0], - \ 'skLet': ["Constant", [], 1], - \ 'skModule': ["Include", [], 1], - \ 'skPackage': ["Define", [], 0], - \ 'skParam': ["Identifier", [], 1], - \ 'skResult': ["Keyword", [], 0], - \ 'skStub': ["PreCondit", [], 0], - \ 'skTemp': ["Identifier", [], 1], - \ 'skUnknown': ["Error", [], 0], - \ 'skVar': ["Constant", [], 1] - \ } + for m in b:highlights + call matchdelete(m) + endfor + + let b:highlights = [] + let semantics_set = {} + + for ctype in g:nvim_nim_highlighter_semantics + let semantics_set[ctype] = 1 + endfor for line in self.lines if len(line) == 0 @@ -59,34 +73,28 @@ function! s:NimHighlighter.on_exit() continue endif - let line = p[2] + 0 - let c = p[3] + 1 - let s = p[4] + 0 - if getline(line)[c - 1] == '*' + let ctype = p[1] + let line = p[2] + 0 + let c = p[3] + 1 + let s = p[4] + 0 + let str = getline(line) + + " Hack because nimsuggest gives wrong place + if str[c - 1] == '*' let c -= s endif - call add(highlights[p[1]][1], [line, c, s]) - endfor - let new_highlights = [] - for [k, v] in items(highlights) - if g:nvim_nim_highlighter_semantic && v[2] - for pos in v[1] - let l = getline(pos[0]) - let c = pos[1] - let class = (char2nr(l[c]) * char2nr(l[c + 1])) % 20 - call add(new_highlights, matchaddpos("Semantic" . class, [pos])) - endfor + if has_key(s:highlights, ctype) + if has_key(semantics_set, ctype) + call add(b:highlights, matchaddpos("Semantic" . util#djb(strpart(str, c - 1, s)) % 20, [[line, c, s]])) + else + call add(b:highlights, matchaddpos(s:highlights[ctype], [[line, c, s]])) + endif else - call add(new_highlights, matchaddpos(v[0], v[1])) + echoerr "No such key: " . p[1] endif endfor - for m in b:old_highlights - call matchdelete(m) - endfor - - let b:old_highlights = new_highlights endfunction function highlighter#New() @@ -97,8 +105,8 @@ function highlighter#New() let tempfile = result.file . ".temp" call writefile(getline(1, '$'), tempfile) call jobsend(result.job, "highlight " . result.file . ";" . tempfile . ":1:1\nquit\n") - if !exists("b:old_highlights") - let b:old_highlights = [] + if !exists("b:highlights") + let b:highlights = [] endif return result endfunction diff --git a/autoload/util.vim b/autoload/util.vim index 2b7cc3e..6903299 100644 --- a/autoload/util.vim +++ b/autoload/util.vim @@ -187,3 +187,11 @@ function! util#SignatureStr(input) let tinfo = util#ParseSignature(a:input) return join(tinfo.params, " -> ") . (tinfo.reval != "" ? (" => " . tinfo.reval) : "") endfunction + +function! util#djb(str) + let hash = 0 + for s:char in split(a:str, '\zs') + let hash = (hash * 11) + char2nr(s:char) + endfor + return float2nr(hash) +endfunction diff --git a/ftdetect/nim.vim b/ftdetect/nim.vim index 04a89ed..d349598 100644 --- a/ftdetect/nim.vim +++ b/ftdetect/nim.vim @@ -13,3 +13,5 @@ let g:nvim_nim_highlight_builtin = 1 let g:nvim_nim_highlight_use_unite = 0 let g:nvim_nim_autocomplete = "omni" " omni, deoplete, ycm let g:nvim_nim_outline = "quickfix" " quickfix, outline + +let g:nvim_nim_highlighter_semantics = ["skConst", "skForVar", "skGlobalVar", "skGlobalLet", "skLet", "skModule", "skParam", "skTemp", "skVar"]