" This gives us better results for Nit
set noignorecase
- set completeopt=longest,menuone,preview
+ set completeopt=longest,menuone
" Do not predict small 3 letters keywords (or their prefix), they slow down
" prediction and some also require double-enter on end of line.
let g:acp_behaviorKeywordIgnores = ['new', 'var', 'in', 'do', 'els', 'end', 'ret', 'for', 'fun']
" Use nitls to compute all interesting files from the current directory and the standard library
- for file in split(system('nitls -M standard .', '\n'))
+ for file in split(system('nitls -M core .', '\n'))
silent let &complete = &complete . ',s' . file
silent set complete?
endfor
" Get path to the best metadata file named `name`
"
" Returns an empty string if not found.
-fun NitMetadataFile(name)
+fun s:NitMetadataFile(name)
" Where are the generated metadata files?
if empty($NIT_VIM_DIR)
let metadata_dir = $HOME . '/.vim/nit'
" Internal function to search for lines in `path` corresponding to the partial
" word `base`. Adds found and formated match to `matches`.
"
-" Will order the results in 3 levels:
+" Will order the results in 5 levels:
" 1. Exact matches
" 2. Common prefix matches
" 3. Substring matches
+" 4. Synopsis matches
+" 5. Doc matches
fun NitOmnifuncAddFromFile(base, matches, path)
let prefix_matches = []
let substring_matches = []
+ let synopsis_matches = []
+ let doc_matches = []
- let path = NitMetadataFile(a:path)
+ let path = s:NitMetadataFile(a:path)
if empty(path)
return
endif
" Add?
if name == a:base
" Exact match
- call NitOmnifuncAddAMatch(a:matches, words, name)
- elseif name =~ '^'.a:base
+ call s:NitOmnifuncAddAMatch(a:matches, words, name)
+ elseif name =~? '^'.a:base
" Common-prefix match
- call NitOmnifuncAddAMatch(prefix_matches, words, name)
- elseif name =~ a:base
+ call s:NitOmnifuncAddAMatch(prefix_matches, words, name)
+ elseif name =~? a:base
" Substring match
- call NitOmnifuncAddAMatch(substring_matches, words, name)
+ call s:NitOmnifuncAddAMatch(substring_matches, words, name)
+ elseif get(words, 2, '') =~? a:base
+ " Match in the synopsis
+ call s:NitOmnifuncAddAMatch(synopsis_matches, words, name)
+ elseif get(words, 3, '') =~? a:base
+ " Match in the longer doc
+ call s:NitOmnifuncAddAMatch(doc_matches, words, name)
endif
endfor
" Assemble the final match list
call extend(a:matches, sort(prefix_matches))
call extend(a:matches, sort(substring_matches))
+ call extend(a:matches, sort(synopsis_matches))
+ call extend(a:matches, sort(doc_matches))
endfun
" Internal function to search parse the information from a metadata line
-fun NitOmnifuncAddAMatch(matches, words, name)
+fun s:NitOmnifuncAddAMatch(matches, words, name)
let pretty = get(a:words, 1, '')
let synopsis = get(a:words, 2, '')
let desc = get(a:words, 3, '')
endif
endfun
-" Activate the omnifunc on Nit files
-autocmd FileType nit set omnifunc=NitOmnifunc
+" Show doc for the entity under the cursor in the preview window
+fun Nitdoc(...)
+ if a:0 == 0 || empty(a:1)
+ " Word under cursor
+ let word = expand("<cword>")
+ else
+ let word = join(a:000, ' ')
+ endif
+
+ " All possible docs (there may be more than one entity with the same name)
+ let docs = []
+ let prefix_matches = []
+ let substring_matches = []
+ let synopsis_matches = []
+ let doc_matches = []
+
+ " Search in all metadata files
+ for file in ['modules', 'classes', 'properties']
+ let path = s:NitMetadataFile(file.'.txt')
+ if empty(path)
+ continue
+ endif
+
+ for line in readfile(path)
+ let words = split(line, '#====#', 1)
+ let name = get(words, 0, '')
+ if name =~ '^'.word.'\>'
+ " Exact match
+ call s:NitdocAdd(docs, words)
+ elseif name =~? '^'.word
+ " Common-prefix match
+ call s:NitdocAdd(prefix_matches, words)
+ elseif name =~? word
+ " Substring match
+ call s:NitdocAdd(substring_matches, words)
+ elseif get(words, 2, '') =~? word
+ " Match in the synopsis
+ call s:NitdocAdd(synopsis_matches, words)
+ elseif get(words, 3, '') =~? word
+ " Match in the longer doc
+ call s:NitdocAdd(doc_matches, words)
+ endif
+ endfor
+ endfor
+
+ " Unite all results in prefered order
+ call extend(docs, sort(prefix_matches))
+ call extend(docs, sort(substring_matches))
+ call extend(docs, sort(synopsis_matches))
+ call extend(docs, sort(doc_matches))
+
+ " Found no doc, give up
+ if empty(docs) || !(join(docs, '') =~ '\w')
+ echo 'Nitdoc found nothing for "' . word . '"'
+ return
+ endif
+
+ " Open the preview window on a temp file
+ execute "silent pedit " . tempname()
+
+ " Change to preview window
+ wincmd P
+
+ " Show all found doc one after another
+ for doc in docs
+ if doc =~ '\w'
+ silent put = doc
+ silent put = ''
+ endif
+ endfor
+ execute 0
+ delete " the first empty line
+
+ " Set options
+ setlocal buftype=nofile
+ setlocal noswapfile
+ setlocal syntax=none
+ setlocal bufhidden=delete
+
+ " Change back to the source buffer
+ wincmd p
+ redraw!
+endfun
+
+" Internal function to search parse the information from a metadata line
+fun s:NitdocAdd(matches, words)
+ let desc = get(a:words, 3, '')
+ let desc = join(split(desc, '#nnnn#', 1), "\n")
+ call add(a:matches, desc)
+endfun
+
+" Call `git grep` on the word under the cursor
+"
+" In the preview window, list introductions, declarations and then all matches.
+fun NitGitGrep()
+ let word = expand("<cword>")
+ let out = tempname()
+ execute 'silent !(git grep -n -e "\<\\(module\\|class\\|universal\\|interface\\|subset\\|var\\|fun\\)\> \<'.word.'\>" --and --not -e redef -- ''*.nit'';'.
+ \'git grep -n "redef \<\\(class\\|universal\\|interface\\|subset\\|var\\|fun\\)\> \<'.word.'\>" -- ''*.nit'';'.
+ \'echo; git grep -n -e "\<'.word.'\>" --and --not -e "\<\\(module\\|class\\|universal\\|interface\\|subset\\|var\\|fun\\)\> \<'.word.'\>" -- ''*.nit'') > '.out
+
+ " Open the preview window on a temp file
+ execute "silent pedit " . out
+
+ " Change to preview window
+ wincmd P
+
+ " Set options
+ setlocal buftype=nofile
+ setlocal noswapfile
+ setlocal syntax=none
+ setlocal bufhidden=delete
+
+ " Change back to the source buffer
+ wincmd p
+ redraw!
+endfun
+
+" Call `nit` on the current file
+fun NitExecute()
+ let path = expand('%')
+
+ if &modified
+ let path = tempname() . '.nit'
+ execute '%write '. path
+ endif
+
+ execute '!nit "' . path . '"'
+endfun
+command NitExecute call NitExecute()
+
+if !exists("g:nit_disable_omnifunc") || !g:nit_disable_omnifunc
+ " Activate the omnifunc on Nit files
+ autocmd FileType nit set omnifunc=NitOmnifunc
+endif
+
+" Define the user command Nitdoc for ease of use
+command -nargs=* Nitdoc call Nitdoc("<args>")
let s:script_dir = fnamemodify(resolve(expand('<sfile>:p')), ':h')