diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2018-10-08 19:00:59 +0200 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2018-10-08 19:00:59 +0200 |
commit | fd74d8b2b170b540680a9bbf6c64990f8ebafd08 (patch) | |
tree | b1fdef6203a78a21053d1b8e0666ab7a38c36df2 /autoload/julia | |
parent | 055f7710b65dfa2df52fc0b5be2486ae36ac5751 (diff) | |
download | vim-polyglot-3.3.3.tar.gz vim-polyglot-3.3.3.zip |
Updatev3.3.3
Diffstat (limited to 'autoload/julia')
-rw-r--r-- | autoload/julia/doc.vim | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/autoload/julia/doc.vim b/autoload/julia/doc.vim new file mode 100644 index 00000000..8a9cab52 --- /dev/null +++ b/autoload/julia/doc.vim @@ -0,0 +1,246 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'julia') == -1 + +" path to the julia binary to communicate with +if has('win32') || has('win64') + if exists('g:julia#doc#juliapath') + " use assigned g:julia#doc#juliapath + elseif executable('julia') + " use julia command in PATH + let g:julia#doc#juliapath = 'julia' + else + " search julia binary in the default installation paths + let pathlist = sort(glob($LOCALAPPDATA . '\Julia-*\bin\julia.exe', 1, 1)) + let g:julia#doc#juliapath = get(pathlist, -1, 'julia') + endif +else + let g:julia#doc#juliapath = get(g:, 'julia#doc#juliapath', 'julia') +endif + +function! s:version() abort + let VERSION = {'major': 0, 'minor': 0} + if !executable(g:julia#doc#juliapath) + return VERSION + endif + + let cmd = printf('%s -v', g:julia#doc#juliapath) + let output = system(cmd) + let versionstr = matchstr(output, '\C^julia version \zs\d\+\.\d\+\ze') + let [major, minor] = map(split(versionstr, '\.'), 'str2nr(v:val)') + let VERSION.major = major + let VERSION.minor = minor + return VERSION +endfunction + +let s:VERSION = s:version() +let s:NODOCPATTERN = '\C\VNo documentation found.' + +function! julia#doc#lookup(keyword, ...) abort + let juliapath = get(a:000, 0, g:julia#doc#juliapath) + let keyword = escape(a:keyword, '"\') + let cmd = printf('%s -E "@doc %s"', juliapath, keyword) + return systemlist(cmd) +endfunction + +function! julia#doc#open(keyword) abort + if empty(a:keyword) + call s:warn('Not an appropriate keyword.') + return + endif + + if !executable(g:julia#doc#juliapath) + call s:warn('%s command is not executable', g:julia#doc#juliapath) + return + endif + + let doc = julia#doc#lookup(a:keyword, g:julia#doc#juliapath) + if empty(doc) || match(doc[0], s:NODOCPATTERN) > -1 + call s:warn('No documentation found for "%s".', a:keyword) + return + endif + + " workaround for * and ? since a buffername cannot include them + let keyword = a:keyword + let keyword = substitute(keyword, '\*', ':asterisk:', 'g') + let keyword = substitute(keyword, '?', ':question:', 'g') + let buffername = printf('juliadoc: %s', keyword) + + call s:write_to_preview_window(doc, "juliadoc", buffername) + + call filter(s:HELPHISTORY, 'v:val isnot# a:keyword') + call add(s:HELPHISTORY, a:keyword) +endfunction + +function! s:write_to_preview_window(content, ftype, buffername) + " Are we in the preview window from the outset? If not, best to close any + " preview windows that might exist. + let pvw = &previewwindow + if !pvw + silent! pclose! + endif + execute "silent! pedit +setlocal\\ nobuflisted\\ noswapfile\\" + \ "buftype=nofile\\ bufhidden=wipe" a:buffername + silent! wincmd P + if &previewwindow + setlocal modifiable noreadonly + silent! %delete _ + call append(0, a:content) + silent! $delete _ + normal! ggj + setlocal nomodified readonly nomodifiable + execute "setfiletype" a:ftype + " Only return to a normal window if we didn't start in a preview window. + if !pvw + silent! wincmd p + endif + else + " We couldn't make it to the preview window, so as a fallback we dump the + " contents in the status area. + execute printf("echo '%s'", join(a:content, "\n")) + endif +endfunction + +function! s:warn(...) abort + if a:0 == 0 + return + endif + + echohl WarningMsg + try + if a:0 == 1 + echo a:1 + else + echo call('printf', a:000) + endif + finally + echohl None + endtry +endfunction + + + +let s:KEYWORDPATTERN = '\m@\?\h\k*!\?' + +" This function is called in normal mode or visual mode. +function! julia#doc#keywordprg(word) abort + if a:word is# '' + return + endif + + let word = s:unfnameescape(a:word) + if word is# expand('<cword>') + " 'K' in normal mode + " NOTE: Because ! and @ is not in 'iskeyword' option, this func ignore + " the argument to recognize keywords like "@time" and "push!" + let view = winsaveview() + let lnum = line('.') + let tail = searchpos(s:KEYWORDPATTERN, 'ce', lnum) + let head = searchpos(s:KEYWORDPATTERN, 'bc', lnum) + call winrestview(view) + if head == [0, 0] || tail == [0, 0] + return + else + let start = head[1] - 1 + let end = tail[1] - 1 + let word = getline(lnum)[start : end] + endif + endif + call julia#doc#open(word) +endfunction + +if exists('+shellslash') + let s:ESCAPEDCHARS = " \t\n\"#%'*<?`|" +else + let s:ESCAPEDCHARS = " \t\n*?[{`$\\%#'\"|!<" +endif +let s:FNAMEESCAPEPATTERN = '\\\ze[' . escape(s:ESCAPEDCHARS, ']^-\') . ']' + +" this function reproduces an original string escaped by fnameescape() +function! s:unfnameescape(str) abort + if a:str is# '' + return '' + endif + + " NOTE: We cannot determine the original string if a:str starts from '\-', + " '\+' or '\>' because fnameescape('-') ==# fnameescape('\-'). + if a:str is# '\-' + " Remove escape anyway. + return '-' + endif + + if a:str =~# '^\\[+>]' + let str = a:str[1:] + else + let str = a:str + endif + return substitute(str, s:FNAMEESCAPEPATTERN, '', 'g') +endfunction + + + +let s:HELPPROMPT = 'help?> ' +let s:HELPHISTORY = [] + +function! julia#doc#prompt() abort + let inputhist = s:savehistory('input') + echohl MoreMsg + try + call s:restorehistory('input', s:HELPHISTORY) + let keyword = input(s:HELPPROMPT, '', 'customlist,julia#doc#complete') + + " Clear the last prompt + normal! : + finally + echohl None + call s:restorehistory('input', inputhist) + endtry + + if empty(keyword) + return + endif + + call julia#doc#open(keyword) +endfunction + +function! s:savehistory(name) abort + if histnr(a:name) == -1 + return [] + endif + + let history = [] + for i in range(1, histnr(a:name)) + let item = histget(a:name, i) + if !empty(item) + call add(history, item) + endif + endfor + return history +endfunction + +function! s:restorehistory(name, history) abort + call histdel(a:name) + for item in a:history + call histadd(a:name, item) + endfor +endfunction + + + +if s:VERSION.major == 0 && s:VERSION.minor <= 6 + let s:REPL_SEARCH = 'Base.Docs.repl_search' +else + let s:REPL_SEARCH = 'import REPL.repl_search; repl_search' +endif + +function! julia#doc#complete(ArgLead, CmdLine, CursorPos) abort + return s:likely(a:ArgLead) +endfunction + +function! s:likely(str) abort + " escape twice + let str = escape(escape(a:str, '"\'), '"\') + let cmd = printf('%s -E "%s(\"%s\")"', g:julia#doc#juliapath, s:REPL_SEARCH, str) + let output = systemlist(cmd) + return split(matchstr(output[0], '\C^search: \zs.*')) +endfunction + +endif |