call NitComplete()
endfunction
-" Internal function to search for lines in `path` corresponding to the partial
-" word `base`. Adds found and formated match to `matches`.
+" Get path to the best metadata file named `name`
"
-" Will order the results in 3 levels:
-" 1. Exact matches
-" 2. Common prefix matches
-" 3. Substring matches
-fun NitOmnifuncAddFromFile(base, matches, path)
- let prefix_matches = []
- let substring_matches = []
-
+" Returns an empty string if not found.
+fun NitMetadataFile(name)
" Where are the generated metadata files?
if empty($NIT_VIM_DIR)
let metadata_dir = $HOME . '/.vim/nit'
let metadata_dir = $NIT_VIM_DIR
end
- let path = metadata_dir . '/' . a:path
+ let path = metadata_dir . '/' . a:name
+
" Is there generated custom metadata files?
if ! filereadable(path)
- let path = s:script_dir . '/' . a:path
+ let path = s:script_dir . '/' . a:name
" Is there standard metadata files?
if ! filereadable(path)
- return
+ return ''
endif
endif
+ return path
+endfun
+
+" 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:
+" 1. Exact matches
+" 2. Common prefix matches
+" 3. Substring matches
+fun NitOmnifuncAddFromFile(base, matches, path)
+ let prefix_matches = []
+ let substring_matches = []
+
+ let path = NitMetadataFile(a:path)
+ if empty(path)
+ return
+ endif
+
for line in readfile(path)
let words = split(line, '#====#', 1)
let name = get(words, 0, '')
let desc = get(a:words, 3, '')
let desc = join(split(desc, '#nnnn#', 1), "\n")
if strlen(pretty) > 40
- let pretty = pretty[:37] . '...'
+ let pretty = pretty[:39] . '…'
endif
call add(a:matches, {'word': a:name, 'abbr': pretty, 'menu': synopsis, 'info': desc, 'dup': 1})
endfun
" find keyword matching with "a:base"
let matches = []
- " Advanced suggestions
+ " advanced suggestions
let cursor_line = getline('.')
- " Content of the line before the partial word
+ " content of the line before the partial word
let line_prev_cursor = cursor_line[:col('.')-1]
let prev_char_at = strlen(line_prev_cursor) - 1
call NitOmnifuncAddFromFile(a:base, matches, 'modules.txt')
endif
- " Classes
- if count(['new', 'super', 'class', 'nullable'], prev_word) > 0 ||
+ " Classes (instanciable only)
+ if prev_word == 'new'
+ let handled = 1
+ call NitOmnifuncAddFromFile(a:base, matches, 'constructors.txt')
+ endif
+
+ " Other class references
+ if count(['class', 'super'], prev_word) > 0
+ let handled = 1
+ call NitOmnifuncAddFromFile(a:base, matches, 'classes.txt')
+ endif
+
+ " Types
+ if count(['class', 'super', 'nullable', 'isa', 'as'], prev_word) > 0 ||
\ line_prev_cursor =~ '[' || prev_char == ':' ||
\ (line_prev_cursor =~ 'fun' && line_prev_cursor =~ 'import' && (prev_word == 'import' || prev_char == ','))
let handled = 1
- call NitOmnifuncAddFromFile(a:base, matches, 'classes.txt')
+ call NitOmnifuncAddFromFile(a:base, matches, 'types.txt')
endif
" Properties
endif
endfun
+" Show doc for the entity under the cursor in the preview window
+fun Nitdoc()
+ " Word under cursor
+ let word = expand("<cword>")
+
+ " All possible docs (there may be more than one entity with the same name)
+ let docs = []
+
+ " Search in all metadata files
+ for file in ['modules', 'classes', 'properties']
+ let path = 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
+ " It fits our word, get long doc
+ let desc = get(words,3,'')
+ let desc = join(split(desc, '#nnnn#', 1), "\n")
+ call add(docs, desc)
+ endif
+ endfor
+ endfor
+
+ " Found no doc, give up
+ if empty(docs) || !(join(docs, '') =~ '\w')
+ 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
+
+ " Set options
+ setlocal buftype=nofile
+ setlocal noswapfile
+ setlocal syntax=none
+ setlocal bufhidden=delete
+
+ " Change back to the source buffer
+ wincmd p
+ redraw!
+endfun
+
+" Call `git grep` on the word under the cursor
+"
+" Shows declarations first, then all matches, in the preview window.
+fun NitGitGrep()
+ let word = expand("<cword>")
+ let out = tempname()
+ execute 'silent !(git grep "\\(module\\|class\\|universal\\|interface\\|var\\|fun\\) '.word.'";'.
+ \'echo; git grep '.word.') > '.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
+
" Activate the omnifunc on Nit files
autocmd FileType nit set omnifunc=NitOmnifunc