summaryrefslogtreecommitdiffstats
path: root/autoload/julia
diff options
context:
space:
mode:
authorAdam Stankiewicz <sheerun@sher.pl>2018-10-08 19:00:59 +0200
committerAdam Stankiewicz <sheerun@sher.pl>2018-10-08 19:00:59 +0200
commitfd74d8b2b170b540680a9bbf6c64990f8ebafd08 (patch)
treeb1fdef6203a78a21053d1b8e0666ab7a38c36df2 /autoload/julia
parent055f7710b65dfa2df52fc0b5be2486ae36ac5751 (diff)
downloadvim-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.vim246
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