diff --git a/etc/soft/nvim/+plugins/vista.vim/CHANGELOG.md b/etc/soft/nvim/+plugins/vista.vim/CHANGELOG.md new file mode 100644 index 0000000..50ee1c2 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/CHANGELOG.md @@ -0,0 +1,4 @@ +# CHANGELOG + +- Impl logging feature and fix some auto update disorders. #319 +- Change `t:vista` to `g:vista` as `t:vista` causes too many issues and I don't have time to make it work as initially designed. #269 diff --git a/etc/soft/nvim/+plugins/vista.vim/Dockerfile b/etc/soft/nvim/+plugins/vista.vim/Dockerfile new file mode 100644 index 0000000..6807966 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/Dockerfile @@ -0,0 +1,8 @@ +FROM tweekmonster/vim-testbed:latest + +ENV PACKAGES="bash git python py-pip" + +RUN apk --update add $PACKAGES && \ + rm -rf /var/cache/apk/* /tmp/* /var/tmp/* + +RUN pip install vim-vint==0.3.15 diff --git a/etc/soft/nvim/+plugins/vista.vim/LICENSE b/etc/soft/nvim/+plugins/vista.vim/LICENSE new file mode 100644 index 0000000..605b09f --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Liu-Cheng Xu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/etc/soft/nvim/+plugins/vista.vim/README.md b/etc/soft/nvim/+plugins/vista.vim/README.md new file mode 100644 index 0000000..bb897c7 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/README.md @@ -0,0 +1,274 @@ +# Vista.vim + +[![CI](https://github.com/liuchengxu/vista.vim/workflows/ci/badge.svg)](https://github.com/liuchengxu/vista.vim/actions?workflow=ci) + +View and search LSP symbols, tags in Vim/NeoVim. + +

+ +

Vista ctags

+

+ +[>>>> More screenshots](https://github.com/liuchengxu/vista.vim/issues/257) + +**caveat: There is a major flaw about the tree view renderer of ctags at the moment, see [#320](https://github.com/liuchengxu/vista.vim/issues/320) for more details.** + +## Table Of Contents + + + +* [Introduction](#introduction) +* [Features](#features) +* [Requirement](#requirement) +* [Installation](#installation) + * [Plugin Manager](#plugin-manager) + * [Package management](#package-management) + * [Vim 8](#vim-8) + * [NeoVim](#neovim) +* [Usage](#usage) + * [Show the nearest method/function in the statusline](#show-the-nearest-methodfunction-in-the-statusline) + * [lightline.vim](#lightlinevim) + * [Commands](#commands) + * [Options](#options) + * [Other tips](#other-tips) + * [Compile ctags with JSON format support](#compile-ctags-with-json-format-support) +* [Contributing](#contributing) +* [License](#license) + + + +## Introduction + +I initially started [vista.vim](https://github.com/liuchengxu/vista.vim) with an intention of replacing [tagbar](https://github.com/majutsushi/tagbar) as it seemingly doesn't have a plan to support the promising [Language Server Protocol](https://github.com/Microsoft/language-server-protocol) and async processing. + +In addition to being a tags viewer, vista.vim can also be a symbol navigator similar to [ctrlp-funky](https://github.com/tacahiroy/ctrlp-funky). Last but not least, one important goal of [vista.vim](https://github.com/liuchengxu/vista.vim) is to support LSP symbols, which understands the semantics instead of the regex only. + +## Features + +- [x] View tags and LSP symbols in a sidebar. + - [x] [universal-ctags](https://github.com/universal-ctags/ctags) + - [x] [ale](https://github.com/w0rp/ale) + - [x] [vim-lsp](https://github.com/prabirshrestha/vim-lsp) + - [x] [coc.nvim](https://github.com/neoclide/coc.nvim) + - [x] [LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim) + - [x] [vim-lsc](https://github.com/natebosch/vim-lsc) + - [x] [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) +- [x] Finder for tags and LSP symbols. + - [x] [fzf](https://github.com/junegunn/fzf) + - [x] [skim](https://github.com/lotabout/skim) + - [x] [vim-clap](https://github.com/liuchengxu/vim-clap) +- [x] Nested display for ctags, list display for LSP symbols. +- [x] Highlight the nearby tag in the vista sidebar. +- [x] Builtin support for displaying markdown's TOC. +- [x] Update automatically when switching between buffers. +- [x] Jump to the tag/symbol from vista sidebar with a blink. +- [x] Update asynchonously in the background when `+job` avaliable. +- [x] Find the nearest method or function to the cursor, which could be integrated into the statusline. +- [x] Display decent detailed symbol info in cmdline, also supports previewing the tag via neovim's floating window. + +Notes: + +- Exuberant Ctags is unsupported, ensure you are using [universal-ctags](https://github.com/universal-ctags/ctags). +- The feature of finder in vista.vim `:Vista finder [EXECUTIVE]` is a bit like `:BTags` or `:Tags` in [fzf.vim](https://github.com/junegunn/fzf.vim), `:CocList` in [coc.nvim](https://github.com/neoclide/coc.nvim), `:LeaderfBufTag` in [leaderf.vim](https://github.com/Yggdroot/LeaderF), etc. You can choose whatever you like. +- ~~Due to limitations of the Language Server Protocol, a tree view of nested tags is currently only available for the ctags executive. Other executives will have symbols grouped by modules, classes, functions and variables~~. The tree view support for LSP executives are limited at present, and only `:Vista coc` provider is supported. + +## Requirement + +I don't know the mimimal supported version. But if you only care about the ctags related feature, vim 7.4.1154+ should be enough. If you want to ctags to run asynchonously, Vim 8.0.27+ should be enough. + +Otherwise, if you want to try any LSP related features, then you certainly need some plugins to retrive the LSP symbols, e.g., [coc.nvim](https://github.com/neoclide/coc.nvim). When you have these LSP plugins set up, vista.vim should be ok to go as well. + +In addition, if you want to search the symbols via [fzf](https://github.com/junegunn/fzf), you will have to install it first. Note that fzf 0.22.0 or above is required. + +## Installation + +### Plugin Manager + +- [vim-plug](https://github.com/junegunn/vim-plug) + + ```vim + Plug 'liuchengxu/vista.vim' + ``` + +For other plugin managers please follow their instructions accordingly. + +### Package management + +#### Vim 8 + +```bash +$ mkdir -p ~/.vim/pack/git-plugins/start +$ git clone https://github.com/liuchengxu/vista.vim.git --depth=1 ~/.vim/pack/git-plugins/start/vista.vim +``` + +#### NeoVim + +```bash +$ mkdir -p ~/.local/share/nvim/site/pack/git-plugins/start +$ git clone https://github.com/liuchengxu/vista.vim.git --depth=1 ~/.local/share/nvim/site/pack/git-plugins/start/vista.vim +``` + +## Usage + +### Show the nearest method/function in the statusline + +Note: This is only supported for ctags and coc executive for now. + +You can do the following to show the nearest method/function in your statusline: + +```vim +function! NearestMethodOrFunction() abort + return get(b:, 'vista_nearest_method_or_function', '') +endfunction + +set statusline+=%{NearestMethodOrFunction()} + +" By default vista.vim never run if you don't call it explicitly. +" +" If you want to show the nearest function in your statusline automatically, +" you can add the following line to your vimrc +autocmd VimEnter * call vista#RunForNearestMethodOrFunction() +``` + +Also refer to [liuchengxu/eleline#18](https://github.com/liuchengxu/eleline.vim/pull/18). + +

+ +

+ +#### [lightline.vim](https://github.com/itchyny/lightline.vim) + +```vim +let g:lightline = { + \ 'colorscheme': 'wombat', + \ 'active': { + \ 'left': [ [ 'mode', 'paste' ], + \ [ 'readonly', 'filename', 'modified', 'method' ] ] + \ }, + \ 'component_function': { + \ 'method': 'NearestMethodOrFunction' + \ }, + \ } +``` + +### Commands + +| Command | Description | +| :-------- | :------------------------------------------------------ | +| `Vista` | Open/Close vista window for viewing tags or LSP symbols | +| `Vista!` | Close vista view window if already opened | +| `Vista!!` | Toggle vista view window | + +`:Vista [EXECUTIVE]`: open vista window powered by EXECUTIVE. + +`:Vista finder [EXECUTIVE]`: search tags/symbols generated from EXECUTIVE. + +See `:help vista-commands` for more information. + +### Options + +```vim +" How each level is indented and what to prepend. +" This could make the display more compact or more spacious. +" e.g., more compact: ["▸ ", ""] +" Note: this option only works for the kind renderer, not the tree renderer. +let g:vista_icon_indent = ["╰─▸ ", "├─▸ "] + +" Executive used when opening vista sidebar without specifying it. +" See all the avaliable executives via `:echo g:vista#executives`. +let g:vista_default_executive = 'ctags' + +" Set the executive for some filetypes explicitly. Use the explicit executive +" instead of the default one for these filetypes when using `:Vista` without +" specifying the executive. +let g:vista_executive_for = { + \ 'cpp': 'vim_lsp', + \ 'php': 'vim_lsp', + \ } + +" Declare the command including the executable and options used to generate ctags output +" for some certain filetypes.The file path will be appened to your custom command. +" For example: +let g:vista_ctags_cmd = { + \ 'haskell': 'hasktags -x -o - -c', + \ } + +" To enable fzf's preview window set g:vista_fzf_preview. +" The elements of g:vista_fzf_preview will be passed as arguments to fzf#vim#with_preview() +" For example: +let g:vista_fzf_preview = ['right:50%'] +``` + +```vim +" Ensure you have installed some decent font to show these pretty symbols, then you can enable icon for the kind. +let g:vista#renderer#enable_icon = 1 + +" The default icons can't be suitable for all the filetypes, you can extend it as you wish. +let g:vista#renderer#icons = { +\ "function": "\uf794", +\ "variable": "\uf71b", +\ } +``` + +

+ +

+ +See `:help vista-options` for more information. + +### Other tips + +#### Compile ctags with JSON format support + +First of all, check if your [universal-ctags](https://github.com/universal-ctags/ctags) supports JSON format via `ctags --list-features`. If not, I recommend you to install ctags with JSON format support that would make vista's parser easier and more reliable. And we are able to reduce some overhead in JSON mode by [disabling the fixed fields](https://github.com/universal-ctags/ctags/pull/2080). + +The JSON support for ctags is avaliable if u-ctags is linked to libjansson when compiling. + +- macOS, [included by default since February 23 2021](https://github.com/universal-ctags/homebrew-universal-ctags/commit/82db2cf9cb0cdecf62ca9405e767ec025b5ba8ed) + + ```bash + $ brew tap universal-ctags/universal-ctags + $ brew install --HEAD universal-ctags/universal-ctags/universal-ctags + ``` + +- Ubuntu + + ```bash + # install libjansson first + $ sudo apt-get install libjansson-dev + + # then compile and install universal-ctags. + # + # NOTE: Don't use `sudo apt install ctags`, which will install exuberant-ctags and it's not guaranteed to work with vista.vim. + # + $ git clone https://github.com/universal-ctags/ctags.git --depth=1 + $ cd ctags + $ ./autogen.sh + $ ./configure + $ make + $ sudo make install + ``` + +- Fedora + + ```bash + $ sudo dnf install jansson-devel autoconf automake + $ git clone https://github.com/universal-ctags/ctags.git --depth=1 + $ cd ctags + $ ./autogen.sh + $ ./configure + $ make + $ sudo make install + ``` + +Refer to [Compiling and Installing Jansson](https://jansson.readthedocs.io/en/latest/gettingstarted.html#compiling-and-installing-jansson) as well. + +## Contributing + +Vista.vim is still in beta, please [file an issue](https://github.com/liuchengxu/vista.vim/issues/new) if you run into any trouble or have any sugguestions. + +## License + +MIT + +Copyright (c) 2019 Liu-Cheng Xu diff --git a/etc/soft/nvim/+plugins/vista.vim/_config.yml b/etc/soft/nvim/+plugins/vista.vim/_config.yml new file mode 100644 index 0000000..1885487 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-midnight \ No newline at end of file diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista.vim new file mode 100644 index 0000000..e3c7920 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista.vim @@ -0,0 +1,233 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:cur_dir = fnamemodify(resolve(expand(':p')), ':h') + +function! vista#FindItemsUnderDirectory(dir) abort + return map(split(globpath(a:dir, '*'), '\n'), 'fnamemodify(v:val, '':t:r'')') +endfunction + +let g:vista#finders = vista#FindItemsUnderDirectory(s:cur_dir.'/vista/finder') +let g:vista#executives = vista#FindItemsUnderDirectory(s:cur_dir.'/vista/executive') +let g:vista#extensions = vista#FindItemsUnderDirectory(s:cur_dir.'/vista/extension') + +let s:ignore_list = ['vista', 'vista_kind', 'nerdtree', 'startify', 'tagbar', 'fzf', 'gitcommit', 'coc-explorer'] + +" Skip special buffers, filetypes. +function! vista#ShouldSkip() abort + return !empty(&buftype) + \ || empty(&filetype) + \ || index(s:ignore_list, &filetype) > -1 +endfunction + +" Ignore some kinds of tags/symbols which is done at the parser step. +function! vista#ShouldIgnore(kind) abort + return exists('g:vista_ignore_kinds') && index(g:vista_ignore_kinds, a:kind) != -1 +endfunction + +function! vista#SetProvider(provider) abort + if get(g:vista, 'skip_set_provider', v:false) + let g:vista.skip_set_provider = v:false + return + endif + let g:vista.provider = a:provider + call vista#statusline#Render() +endfunction + +function! vista#OnExecute(provider, AUF) abort + call vista#SetProvider(a:provider) + call vista#autocmd#Init('Vista'.vista#util#ToCamelCase(a:provider), a:AUF) +endfunction + +" Sort the items under some kind alphabetically. +function! vista#Sort() abort + if !has_key(g:vista, 'sort') + let g:vista.sort = v:true + else + let g:vista.sort = !g:vista.sort + endif + + let cache = vista#executive#{g:vista.provider}#Cache() + + let cur_pos = getpos('.') + + call vista#sidebar#Reload(cache) + + if cur_pos != getpos('.') + call setpos('.', cur_pos) + endif +endfunction + +" coc.nvim returns no symbols if you just send the request on the event. +" We use a delayed update instead. +" Maybe also useful for the other LSP clients. +function! vista#AutoUpdateWithDelay(Fn, Args) abort + call timer_start(30, { -> call(a:Fn, a:Args) }) +endfunction + +function! vista#GetExplicitExecutive(filetype) abort + if exists('g:vista_'.a:filetype.'_executive') + return g:vista_{a:filetype}_executive + endif + + if has_key(g:vista_executive_for, a:filetype) + return g:vista_executive_for[a:filetype] + endif + + return v:null +endfunction + +function! vista#GetExplicitExecutiveOrDefault() abort + let explicit_executive = vista#GetExplicitExecutive(&filetype) + + if explicit_executive isnot# v:null + let executive = explicit_executive + else + let executive = g:vista_default_executive + endif + + return executive +endfunction + +function! s:TryInitializeVista() abort + if !exists('g:vista') + call vista#init#Api() + endif +endfunction + +call s:TryInitializeVista() + +" TODO: vista is designed to have an instance per tab, but it does not work as +" expected now. +" augroup VistaInitialize + " autocmd! + " ++once needs 8.1.1113, it's safer but requires newer vim. + " autocmd TabNew * ++once call s:TryInitializeVista() +" augroup END + +" Used for running vista.vim on startup +function! vista#RunForNearestMethodOrFunction() abort + let [bufnr, winnr, fname, fpath] = [bufnr('%'), winnr(), expand('%'), expand('%:p')] + call vista#source#Update(bufnr, winnr, fname, fpath) + call vista#executive#{g:vista_default_executive}#Execute(v:false, v:false) + let g:__vista_initial_run_find_nearest_method = 1 + + if !exists('#VistaMOF') + call vista#autocmd#InitMOF() + endif +endfunction + +let s:logging_enabled = exists('g:vista_log_file') && !empty(g:vista_log_file) + +function! vista#Debug(...) abort + if s:logging_enabled + call writefile([strftime('%Y-%m-%d %H:%M:%S ').json_encode(a:000)], g:vista_log_file, 'a') + endif +endfunction + +function! s:HandleSingleArgument(arg) abort + if index(g:vista#executives, a:arg) > -1 + call vista#executive#{a:arg}#Execute(v:false, v:true) + let g:vista.lnum = line('.') + elseif a:arg ==# 'finder' + call vista#finder#Dispatch(v:false, '', '') + elseif a:arg ==# 'finder!' + call vista#finder#Dispatch(v:true, '', '') + elseif a:arg ==# 'toc' + if vista#toc#IsSupported(&filetype) + call vista#toc#Run() + else + return vista#error#For('Vista toc', &filetype) + endif + elseif a:arg ==# 'focus' + call vista#sidebar#ToggleFocus() + elseif a:arg ==# 'show' + if vista#sidebar#IsOpen() + call vista#cursor#ShowTag() + else + call vista#sidebar#Open() + let g:vista.lnum = line('.') + endif + elseif a:arg ==# 'info' + call vista#debugging#Info() + elseif a:arg ==# 'info+' + call vista#debugging#InfoToClipboard() + else + return vista#error#Expect('Vista [finder] [EXECUTIVE]') + endif +endfunction + +function! s:HandleArguments(fst, snd) abort + if a:fst !~# '^finder' + return vista#error#Expect('Vista finder[!] [EXECUTIVE]') + endif + " Vista finder [finder:executive] + if stridx(a:snd, ':') > -1 + if !exists('s:finder_args_pattern') + let s:finder_args_pattern = '^\('.join(g:vista#finders, '\|').'\):\('.join(g:vista#executives, '\|').'\)$' + endif + if a:snd =~? s:finder_args_pattern + let matched = matchlist(a:snd, s:finder_args_pattern) + let finder = matched[1] + let executive = matched[2] + else + return vista#error#InvalidFinderArgument() + endif + else + " Vista finder [finder]/[executive] + if index(g:vista#finders, a:snd) > -1 + let finder = a:snd + let executive = '' + elseif index(g:vista#executives, a:snd) > -1 + let finder = '' + let executive = a:snd + else + return vista#error#InvalidFinderArgument() + endif + endif + call vista#finder#Dispatch(v:false, finder, executive) +endfunction + +" Main entrance to interact with vista.vim +function! vista#(bang, ...) abort + " `:Vista focus` should be handled before updating the source buffer info. + if a:0 == 1 && a:1 ==# 'focus' + call vista#sidebar#ToggleFocus() + return + endif + + let [bufnr, winnr, fname, fpath] = [bufnr('%'), winnr(), expand('%'), expand('%:p')] + let g:vista.source.winid = win_getid() + call vista#source#Update(bufnr, winnr, fname, fpath) + + if a:bang + if a:0 == 0 + call vista#sidebar#Close() + return + elseif a:0 == 1 + if a:1 ==# '!' + let g:vista.lnum = line('.') + call vista#sidebar#Toggle() + return + else + return vista#error#Expect('Vista!!') + endif + else + return vista#error#Expect('Vista![!]') + endif + endif + + if a:0 == 0 + call vista#sidebar#Open() + return + endif + + if a:0 == 1 + call s:HandleSingleArgument(a:1) + elseif a:0 == 2 + call s:HandleArguments(a:1, a:2) + elseif a:0 > 0 + return vista#error#('Too many arguments for Vista') + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/autocmd.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/autocmd.vim new file mode 100644 index 0000000..1a93cd2 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/autocmd.vim @@ -0,0 +1,156 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:registered = [] +let s:update_timer = -1 +let s:did_open = [] +let s:last_event = [] +let s:did_buf_enter = [] + +function! s:ClearOtherEvents(group) abort + for augroup in s:registered + if augroup != a:group && exists('#'.augroup) + execute 'autocmd!' augroup + endif + endfor +endfunction + +function! s:OnBufEnter(bufnr, fpath) abort + if index(s:did_buf_enter, a:bufnr) == -1 + call add(s:did_buf_enter, a:bufnr) + " Only ignore the first BufEnter event for a new buffer + " + " When reading a new buffer, BufReadPost and BufEnter will both be + " triggered for the same buffer, therefore BufEnter is needless and might + " be problematic. + if s:last_event == ['BufReadPost', a:bufnr] + call vista#Debug('ignored the first event.BufEnter for bufnr '.a:bufnr.' because event.BufReadPost was just triggered for the same buffer') + return + endif + endif + + call vista#Debug('event.BufEnter', a:bufnr, a:fpath) + call s:GenericAutoUpdate('BufEnter', a:bufnr, a:fpath) +endfunction + +function! s:OnBufDelete(bufnr) abort + let idx = index(s:did_open, a:bufnr) + if idx != -1 + unlet s:did_open[idx] + endif + let idx = index(s:did_buf_enter, a:bufnr) + if idx != -1 + unlet s:did_buf_enter[idx] + endif +endfunction + +function! s:GenericAutoUpdate(event, bufnr, fpath) abort + if vista#ShouldSkip() + return + endif + + call vista#Debug('event.'.a:event. ' processing auto update for buffer '. a:bufnr) + let [bufnr, winnr, fname] = [a:bufnr, winnr(), expand('%')] + + call vista#source#Update(bufnr, winnr, fname, a:fpath) + + call s:ApplyAutoUpdate(a:fpath) +endfunction + +function! s:TriggerUpdate(event, bufnr, fpath) abort + if s:last_event == [a:event, a:bufnr] + call vista#Debug('same event for bufnr '.a:bufnr.' was just triggered, ignored for this one') + return + endif + + let s:last_event = [a:event, a:bufnr] + + call vista#Debug('new last_event:', s:last_event) + + if index(s:did_open, a:bufnr) == -1 + call vista#Debug('tracking new buffer '.a:bufnr) + call add(s:did_open, a:bufnr) + endif + + call s:GenericAutoUpdate(a:event, a:bufnr, a:fpath) +endfunction + +function! s:AutoUpdateWithDelay(bufnr, fpath) abort + if !exists('g:vista') + return + endif + + if s:update_timer != -1 + call timer_stop(s:update_timer) + let s:update_timer = -1 + endif + + let g:vista.on_text_changed = 1 + let s:update_timer = timer_start( + \ g:vista_update_on_text_changed_delay, + \ { -> s:GenericAutoUpdate('TextChanged|TextChangedI', a:bufnr, a:fpath)} + \ ) +endfunction + +function! s:ClearTempData() abort + for tmp in g:vista.tmps + if filereadable(tmp) + call delete(tmp) + endif + endfor +endfunction + +" Every time we call :Vista foo, we should clear other autocmd events and only +" keep the current one, otherwise there will be multiple autoupdate events +" interacting with other. +function! vista#autocmd#Init(group_name, AUF) abort + + call s:ClearOtherEvents(a:group_name) + + if index(s:registered, a:group_name) == -1 + call add(s:registered, a:group_name) + endif + + let s:ApplyAutoUpdate = a:AUF + + if exists('#'.a:group_name) + if len(split(execute('autocmd '.a:group_name), '\n')) > 1 + return + endif + endif + + execute 'augroup' a:group_name + autocmd! + + " vint: -ProhibitAutocmdWithNoGroup + autocmd WinEnter,WinLeave __vista__ call vista#statusline#RenderOnWinEvent() + + " BufReadPost is needed for reloading the current buffer if the file + " was changed by an external command; + " + " CursorHold and CursorHoldI event have been removed in order to + " highlight the nearest tag automatically. + + autocmd BufReadPost * call s:TriggerUpdate('BufReadPost', +expand(''), fnamemodify(expand(''), ':p')) + autocmd BufWritePost * call s:TriggerUpdate('BufWritePost', +expand(''), fnamemodify(expand(''), ':p')) + autocmd BufEnter * call s:OnBufEnter(+expand(''), fnamemodify(expand(''), ':p')) + + autocmd BufDelete,BufWipeout * call s:OnBufDelete(+expand('')) + + autocmd VimLeavePre * call s:ClearTempData() + + if g:vista_update_on_text_changed + autocmd TextChanged,TextChangedI * + \ call s:AutoUpdateWithDelay(+expand(''), fnamemodify(expand(''), ':p')) + endif + augroup END +endfunction + + +function! vista#autocmd#InitMOF() abort + augroup VistaMOF + autocmd! + autocmd CursorMoved * call vista#cursor#FindNearestMethodOrFunction() + augroup END +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor.vim new file mode 100644 index 0000000..e9d7b8e --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor.vim @@ -0,0 +1,280 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +scriptencoding utf8 + +let s:find_timer = -1 +let s:cursor_timer = -1 +let s:highlight_timer = -1 + +let s:echo_cursor_opts = ['echo', 'floating_win', 'scroll', 'both'] +let s:echo_strategy = get(g:, 'vista_echo_cursor_strategy', 'echo') + +let s:last_vlnum = v:null + +function! s:GenericStopTimer(timer) abort + execute 'if '.a:timer.' != -1 |'. + \ ' call timer_stop('.a:timer.') |'. + \ ' let 'a:timer.' = -1 |'. + \ 'endif' +endfunction + +function! s:StopFindTimer() abort + call s:GenericStopTimer('s:find_timer') +endfunction + +function! s:StopCursorTimer() abort + call s:GenericStopTimer('s:cursor_timer') +endfunction + +function! s:StopHighlightTimer() abort + call s:GenericStopTimer('s:highlight_timer') +endfunction + +" Get tag and corresponding source line at current cursor position. +" +" Return: [tag, source_line] +function! s:GetInfoUnderCursor() abort + if g:vista.provider ==# 'ctags' + return vista#cursor#ctags#GetInfo() + else + return vista#cursor#lsp#GetInfo() + endif +endfunction + +function! s:Compare(s1, s2) abort + return a:s1.lnum - a:s2.lnum +endfunction + +function! s:FindNearestMethodOrFunction(_timer) abort + if !exists('g:vista') + \ || !has_key(g:vista, 'functions') + \ || !has_key(g:vista, 'source') + return + endif + call sort(g:vista.functions, function('s:Compare')) + let result = vista#util#BinarySearch(g:vista.functions, line('.'), 'lnum', 'text') + if empty(result) + let result = '' + endif + call setbufvar(g:vista.source.bufnr, 'vista_nearest_method_or_function', result) + + call s:StopHighlightTimer() + + if vista#sidebar#IsOpen() + let s:highlight_timer = timer_start(200, function('s:HighlightNearestTag')) + endif +endfunction + +function! s:HasVlnum() abort + return exists('g:vista') + \ && has_key(g:vista, 'raw') + \ && !empty(g:vista.raw) + \ && has_key(g:vista.raw[0], 'vlnum') +endfunction + +" Highlight the nearest tag in the vista window. +function! s:HighlightNearestTag(_timer) abort + if !exists('g:vista') + return + endif + let winnr = g:vista.winnr() + + if winnr == -1 + \ || vista#ShouldSkip() + \ || !s:HasVlnum() + \ || mode() !=# 'n' + return + endif + + let found = vista#util#BinarySearch(g:vista.raw, line('.'), 'line', '') + if empty(found) + return + endif + + let s:vlnum = get(found, 'vlnum', v:null) + " Skip if the vlnum is same with previous one + if empty(s:vlnum) || s:last_vlnum == s:vlnum + return + endif + + let s:last_vlnum = s:vlnum + + let tag = get(found, 'name', v:null) + call vista#win#Execute(winnr, function('vista#highlight#Add'), s:vlnum, v:true, tag) +endfunction + +" Fold or unfold when meets the top level tag line +function! s:TryFoldIsOk() abort + if indent('.') == 0 + if !empty(getline('.')) + if foldclosed('.') != -1 + normal! zo + return v:true + elseif foldlevel('.') != 0 + normal! zc + return v:true + endif + endif + endif + return v:false +endfunction + +" Fold scope based on the indent. +" Jump to the target source line or source file. +function! vista#cursor#FoldOrJump() abort + if line('.') == 1 + call vista#source#GotoWin() + return + elseif s:TryFoldIsOk() + return + endif + + let tag_under_cursor = s:GetInfoUnderCursor()[0] + call vista#jump#TagLine(tag_under_cursor) +endfunction + +" This happens when you are in the window of source file +function! vista#cursor#FindNearestMethodOrFunction() abort + if !exists('g:vista') + \ || !has_key(g:vista, 'functions') + \ || bufnr('') != g:vista.source.bufnr + return + endif + + call s:StopFindTimer() + + if empty(g:vista.functions) + call setbufvar(g:vista.source.bufnr, 'vista_nearest_method_or_function', '') + return + endif + + let s:find_timer = timer_start( + \ g:vista_find_nearest_method_or_function_delay, + \ function('s:FindNearestMethodOrFunction'), + \ ) +endfunction + +function! vista#cursor#NearestSymbol() abort + return vista#util#BinarySearch(g:vista.raw, line('.'), 'line', 'name') +endfunction + +" Show the detail of current tag/symbol under cursor. +function! vista#cursor#ShowDetail(_timer) abort + " Skip if in visual mode + if mode() ==? 'v' || mode() ==# "\" + return + endif + + if empty(getline('.')) + \ || vista#echo#EchoScopeInCmdlineIsOk() + \ || vista#win#ShowFoldedDetailInFloatingIsOk() + return + endif + + let [tag, source_line] = s:GetInfoUnderCursor() + + if empty(tag) || empty(source_line) + echo "\r" + return + endif + + let msg = vista#util#Truncate(source_line) + let lnum = s:GetTrailingLnum() + + if s:echo_strategy ==# s:echo_cursor_opts[0] + call vista#echo#EchoInCmdline(msg, tag) + elseif s:echo_strategy ==# s:echo_cursor_opts[1] + call vista#win#FloatingDisplay(lnum, tag) + elseif s:echo_strategy ==# s:echo_cursor_opts[2] + call vista#source#PeekSymbol(lnum, tag) + elseif s:echo_strategy ==# s:echo_cursor_opts[3] + call vista#echo#EchoInCmdline(msg, tag) + call vista#win#FloatingDisplayOrPeek(lnum, tag) + else + call vista#error#InvalidOption('g:vista_echo_cursor_strategy', s:echo_cursor_opts) + endif + + call vista#highlight#Add(line('.'), v:false, tag) +endfunction + +function! vista#cursor#ShowDetailWithDelay() abort + call s:StopCursorTimer() + + let s:cursor_timer = timer_start( + \ g:vista_cursor_delay, + \ function('vista#cursor#ShowDetail'), + \ ) +endfunction + +" This happens on calling `:Vista show` but the vista window is still invisible. +function! vista#cursor#ShowTagFor(lnum) abort + if !s:HasVlnum() + return + endif + + let found = vista#util#BinarySearch(g:vista.raw, a:lnum, 'line', '') + if empty(found) + return + endif + let s:vlnum = get(found, 'vlnum', v:null) + if empty(s:vlnum) + return + endif + + let tag = get(found, 'name', v:null) + call vista#highlight#Add(s:vlnum, v:true, tag) +endfunction + +function! vista#cursor#ShowTag() abort + if !s:HasVlnum() + return + endif + + let s:vlnum = vista#util#BinarySearch(g:vista.raw, line('.'), 'line', 'vlnum') + + if empty(s:vlnum) + return + endif + + let winnr = g:vista.winnr() + + if winnr() != winnr + execute winnr.'wincmd w' + endif + + call cursor(s:vlnum, 1) + normal! zz +endfunction + +" Extract the line number from last section of cursor line in the vista window +function! s:GetTrailingLnum() abort + return str2nr(matchstr(getline('.'), '\d\+$')) +endfunction + +function! vista#cursor#TogglePreview() abort + if get(g:vista, 'floating_visible', v:false) + \ || get(g:vista, 'popup_visible', v:false) + call vista#win#CloseFloating() + return + endif + + let [tag, source_line] = s:GetInfoUnderCursor() + + if empty(tag) || empty(source_line) + echo "\r" + return + endif + + let lnum = s:GetTrailingLnum() + + call vista#win#FloatingDisplay(lnum, tag) +endfunction + +function! vista#cursor#TryInitialRun() abort + if exists('g:__vista_initial_run_find_nearest_method') + call vista#cursor#FindNearestMethodOrFunction() + unlet g:__vista_initial_run_find_nearest_method + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor/ctags.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor/ctags.vim new file mode 100644 index 0000000..9551554 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor/ctags.vim @@ -0,0 +1,69 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" Try matching the exact tag given the trimmed line in the vista window. +function! s:MatchTag(trimmed_line) abort + " Since we include the space ` `, we need to trim the result later. + " / --> github.com/golang/dep/gps:11 + if g:vista.provider ==# 'markdown' + let matched = matchlist(a:trimmed_line, '\([a-zA-Z:#_.,/<> ]\-\+\)\(H\d:\d\+\)$') + else + let matched = matchlist(a:trimmed_line, '\([a-zA-Z:#_.,/<> ]\-\+\):\(\d\+\)$') + endif + + return get(matched, 1, '') +endfunction + +function! s:RemoveVisibility(tag) abort + if index(['+', '~', '-'], a:tag[0]) > -1 + return a:tag[1:] + else + return a:tag + endif +endfunction + +function! vista#cursor#ctags#GetInfo() abort + let raw_cur_line = getline('.') + + if empty(raw_cur_line) + return [v:null, v:null] + endif + + " tag like s:StopCursorTimer has `:`, so we can't simply use split(tag, ':') + let last_semicoln_idx = strridx(raw_cur_line, ':') + let lnum = raw_cur_line[last_semicoln_idx+1:] + + let source_line = g:vista.source.line_trimmed(lnum) + if empty(source_line) + return [v:null, v:null] + endif + + " For scoped tag + " Currently vlnum_cache is ctags provider only. + if has_key(g:vista, 'vlnum_cache') && g:vista.provider ==# 'ctags' + let tagline = g:vista.get_tagline_under_cursor() + if !empty(tagline) + return [tagline.name, source_line] + endif + endif + + " For scopeless tag + " peer_ilog(PEER,FORMAT,...):90 + let trimmed_line = vista#util#Trim(raw_cur_line) + let left_parenthsis_idx = stridx(trimmed_line, '(') + if left_parenthsis_idx > -1 + " Ignore the visibility symbol, e.g., +test2() + let tag = s:RemoveVisibility(trimmed_line[0 : left_parenthsis_idx-1]) + return [tag, source_line] + endif + + let tag = s:MatchTag(trimmed_line) + if empty(tag) + let tag = raw_cur_line[:last_semicoln_idx-1] + endif + + let tag = s:RemoveVisibility(vista#util#Trim(tag)) + + return [tag, source_line] +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor/lsp.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor/lsp.vim new file mode 100644 index 0000000..0de6473 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/cursor/lsp.vim @@ -0,0 +1,61 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! s:GetInfoFromLSPAndExtension() abort + let raw_cur_line = getline('.') + + " TODO use range info of LSP symbols? + if g:vista.provider ==# 'coc' + if !has_key(g:vista, 'vlnum2tagname') + return v:null + endif + if has_key(g:vista.vlnum2tagname, line('.')) + return g:vista.vlnum2tagname[line('.')] + else + let items = split(raw_cur_line) + if g:vista#renderer#enable_icon + return join(items[1:-2], ' ') + else + return join(items[:-2], ' ') + endif + endif + elseif g:vista.provider ==# 'nvim_lsp' + return substitute(raw_cur_line, '\v.*\s(.*):.*', '\1', '') + elseif g:vista.provider ==# 'markdown' || g:vista.provider ==# 'rst' + if line('.') < 3 + return v:null + endif + " The first two lines are for displaying fpath. the lnum is 1-based, while + " idex is 0-based. + " So it's line('.') - 3 instead of line('.'). + let tag = vista#extension#{g:vista.provider}#GetHeader(line('.')-3) + if tag is# v:null + return v:null + endif + return tag + endif + + return v:null +endfunction + +function! vista#cursor#lsp#GetInfo() abort + let raw_cur_line = getline('.') + + if empty(raw_cur_line) + return [v:null, v:null] + endif + + " tag like s:StopCursorTimer has `:`, so we can't simply use split(tag, ':') + let last_semicoln_idx = strridx(raw_cur_line, ':') + let lnum = raw_cur_line[last_semicoln_idx+1:] + + let source_line = g:vista.source.line_trimmed(lnum) + if empty(source_line) + return [v:null, v:null] + endif + + let tag = s:GetInfoFromLSPAndExtension() + + return [tag, source_line] +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/debugging.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/debugging.vim new file mode 100644 index 0000000..e0690a8 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/debugging.vim @@ -0,0 +1,75 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! s:GetAvaliableExecutives() abort + let avaliable = [] + + if exists('*ale#lsp_linter#SendRequest') + call add(avaliable, 'ale') + endif + + if exists('*CocAction') + call add(avaliable, 'coc') + endif + + if executable('ctags') + call add(avaliable, 'ctags') + endif + + if exists('*LanguageClient#textDocument_documentSymbol') + call add(avaliable, 'lcn') + endif + + if exists('*lsc#server#userCall') + call add(avaliable, 'vim_lsc') + endif + + if exists('*lsp#get_whitelisted_servers') + call add(avaliable, 'vim_lsp') + endif + + return avaliable +endfunction + +function! s:GetGlobalVariables() abort + let variable_list = [] + + for key in keys(g:) + if key =~# '^vista' + call add(variable_list, key) + endif + endfor + + " Ignore the variables of types + call filter(variable_list, 'v:val !~# ''vista#types#''') + + call sort(variable_list) + + return variable_list +endfunction + +function! vista#debugging#Info() abort + let avaliable_executives = string(s:GetAvaliableExecutives()) + let global_variables = s:GetGlobalVariables() + + echohl Type | echo ' Current FileType: ' | echohl NONE + echohl Normal | echon &filetype | echohl NONE + echohl Type | echo 'Avaliable Executives: ' | echohl NONE + echohl Normal | echon avaliable_executives | echohl NONE + echohl Type | echo ' Global Variables:' | echohl NONE + for variable in global_variables + echo ' let g:'.variable.' = '. string(g:[variable]) + endfor +endfunction + +function! vista#debugging#InfoToClipboard() abort + redir => l:output + silent call vista#debugging#Info() + redir END + + let @+ = l:output + echohl Type | echo '[vista.vim] ' | echohl NONE + echohl Function | echon 'Vista info' | echohl NONE + echohl Normal | echon ' copied to your clipboard' | echohl NONE +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/echo.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/echo.vim new file mode 100644 index 0000000..6687dbb --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/echo.vim @@ -0,0 +1,98 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +scriptencoding utf8 + +function! s:EchoScope(scope) abort + if g:vista#renderer#enable_icon + echohl Function | echo ' '.a:scope.': ' | echohl NONE + else + echohl Function | echo '['.a:scope.'] ' | echohl NONE + endif +endfunction + +function! s:TryParseAndEchoScope() abort + let linenr = vista#util#LowerIndentLineNr() + + " Echo the scope of current tag if found + if linenr != 0 + let scope = matchstr(getline(linenr), '\a\+$') + if !empty(scope) + call s:EchoScope(scope) + else + " For the kind renderer + let pieces = split(getline(linenr), ' ') + if !empty(pieces) + let scope = pieces[1] + call s:EchoScope(scope) + endif + endif + endif +endfunction + +function! vista#echo#EchoScopeInCmdlineIsOk() abort + let cur_line = getline('.') + if cur_line[-1:] ==# ']' + let splitted = split(cur_line) + " Join the scope parts in case of they contains spaces, e.g., structure names + let scope = join(splitted[1:-2], ' ') + let cnt = matchstr(splitted[-1], '\d\+') + call s:EchoScope(scope) + echohl Keyword | echon cnt | echohl NONE + return v:true + endif + return v:false +endfunction + +function! s:EchoScopeFromCacheIsOk() abort + if has_key(g:vista, 'vlnum_cache') + " should exclude the first two lines and keep in mind that the 1-based and + " 0-based. + " This is really error prone. + let tagline = get(g:vista.vlnum_cache, line('.') - 3, '') + if !empty(tagline) + if has_key(tagline, 'scope') + call s:EchoScope(tagline.scope) + else + call s:EchoScope(tagline.kind) + endif + return v:true + endif + endif + return v:false +endfunction + +" Echo the tag with detailed info in the cmdline +" Try to echo the scope and then the tag. +function! vista#echo#EchoInCmdline(msg, tag) abort + let [msg, tag] = [a:msg, a:tag] + + " Case II:\@ $R^2 \geq Q^3$ :  paragraph:175 + try + let start = stridx(msg, tag) + + " If couldn't find the tag in the msg + if start == -1 + echohl Function | echo msg | echohl NONE + return + endif + catch /^Vim\%((\a\+)\)\=:E869/ + echohl Function | echo msg | echohl NONE + return + endtry + + " Try highlighting the scope of current tag + if !s:EchoScopeFromCacheIsOk() + call s:TryParseAndEchoScope() + endif + + " if start is 0, msg[0:-1] will display the redundant whole msg. + if start != 0 + echohl Statement | echon msg[0 : start-1] | echohl NONE + endif + + let end = start + strlen(tag) + echohl Search | echon msg[start : end-1] | echohl NONE + echohl Statement | echon msg[end : ] | echohl NONE +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/error.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/error.vim new file mode 100644 index 0000000..5101056 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/error.vim @@ -0,0 +1,71 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! s:Echo(group, msg) abort + execute 'echohl' a:group + echo a:msg + echohl NONE +endfunction + +function! s:Echon(group, msg) abort + execute 'echohl' a:group + echon a:msg + echohl NONE +endfunction + +function! vista#error#Expect(expected) abort + call s:Echo('ErrorMsg', '[vista.vim]') + call s:Echon('Normal', ' Invalid args. expected: ') + call s:Echon('Underlined', a:expected) +endfunction + +function! vista#error#Need(needed) abort + call s:Echo('ErrorMsg', '[vista.vim]') + call s:Echon('Normal', ' You must have ') + call s:Echon('Underlined', a:needed) + call s:Echon('Normal', ' installed to continue.') +endfunction + +function! vista#error#RunCtags(cmd) abort + call s:Echo('ErrorMsg', '[vista.vim]') + call s:Echon('Normal', 'Fail to run ctags given the command: ') + call s:Echon('Underlined', a:cmd) +endfunction + +function! vista#error#For(cmd, filetype) abort + call s:Echo('ErrorMsg', '[vista.vim]') + call s:Echon('Underlined', ' '.a:cmd) + call s:Echon('Normal', ' does not support '.a:filetype.' filetype.') +endfunction + +function! vista#error#InvalidExecutive(exe) abort + call s:Echo('ErrorMsg', '[vista.vim]') + call s:Echon('Normal', ' The executive') + call s:Echon('Underlined', ' '.a:exe.' ') + call s:Echon('Normal', 'does not exist. Avaliable: ') + call s:Echon('Underlined', string(g:vista#executives)) +endfunction + +function! vista#error#InvalidOption(opt, ...) abort + call s:Echo('ErrorMsg', '[vista.vim]') + call s:Echon('Normal', ' Invalid option '.a:opt.'. Avaliable: ') + call s:Echon('Underlined', a:0 > 0 ? string(a:1) : '') +endfunction + +function! vista#error#InvalidFinderArgument() abort + call vista#error#Expect('Vista finder [FINDER|EXECUTIVE|FINDER:EXECUTIVE]') +endfunction + +" Notify the error message when required. +function! vista#error#Notify(msg) abort + if !get(g:vista, 'silent', v:true) + call vista#error#(a:msg) + let g:vista.silent = v:true + endif +endfunction + +function! vista#error#(msg) abort + call s:Echo('ErrorMsg', '[vista.vim]') + call s:Echon('Normal', ' '.a:msg) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/ale.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/ale.vim new file mode 100644 index 0000000..a424409 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/ale.vim @@ -0,0 +1,102 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +let s:reload_only = v:false +let s:should_display = v:false + +function! s:HandleLSPResponse(resp) abort + let s:fetching = v:false + if type(a:resp) != v:t_dict + \ || has_key(a:resp, 'error') + \ || !has_key(a:resp, 'result') + \ || empty(get(a:resp, 'result', {})) + return + endif + + let s:data = vista#renderer#LSPPreprocess(a:resp.result) + + if !empty(s:data) + let [s:reload_only, s:should_display] = vista#renderer#LSPProcess(s:data, s:reload_only, s:should_display) + + " Update cache when new data comes. + let s:cache = get(s:, 'cache', {}) + let s:cache[s:fpath] = s:data + let s:cache.ftime = getftime(s:fpath) + let s:cache.bufnr = bufnr('') + endif + + call vista#cursor#TryInitialRun() +endfunction + +function! s:AutoUpdate(fpath) abort + let s:reload_only = v:true + let s:fpath = a:fpath + call s:RunAsync() +endfunction + +function! s:Run() abort + let s:fetching = v:false + call s:RunAsync() + while s:fetching + sleep 100m + endwhile + return get(s:, 'data', {}) +endfunction + +function! s:RunAsync() abort + let linters = map(filter(ale#linter#Get(&filetype), '!empty(v:val.lsp)'), 'v:val.name') + if empty(linters) + return + endif + + let method = 'textDocument/documentSymbol' + let bufnr = g:vista.source.bufnr + let params = { + \ 'textDocument': { + \ 'uri': ale#path#ToURI(expand('#' . bufnr . ':p')), + \ } + \} + let message = [0, method, params] + let Callback = function('s:HandleLSPResponse') + + for linter in linters + call ale#lsp_linter#SendRequest(bufnr, linter, message, Callback) + let s:fetching = v:true + endfor +endfunction + +function! vista#executive#ale#Run(fpath) abort + if exists('g:loaded_ale_dont_use_this_in_other_plugins_please') + let s:fpath = a:fpath + return s:Run() + endif +endfunction + +function! vista#executive#ale#RunAsync() abort + if exists('g:loaded_ale_dont_use_this_in_other_plugins_please') + call s:RunAsync() + endif +endfunction + +function! vista#executive#ale#Execute(bang, should_display, ...) abort + call vista#source#Update(bufnr('%'), winnr(), expand('%'), expand('%:p')) + let s:fpath = expand('%:p') + + let g:vista.silent = v:false + let s:should_display = a:should_display + + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + + if a:bang + call s:Run() + else + call s:RunAsync() + endif +endfunction + +function! vista#executive#ale#Cache() abort + return get(s:, 'cache', {}) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/coc.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/coc.vim new file mode 100644 index 0000000..8f22477 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/coc.vim @@ -0,0 +1,119 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +let s:reload_only = v:false +let s:should_display = v:false + +" Extract fruitful infomation from raw symbols +function! s:DoHandleResponse(symbols) abort + let s:data = [] + + if empty(a:symbols) + return + endif + + let g:vista.functions = [] + let g:vista.raw = [] + call map(a:symbols, 'vista#parser#lsp#CocSymbols(v:val, s:data)') + + if !empty(s:data) + let [s:reload_only, s:should_display] = vista#renderer#LSPProcess(s:data, s:reload_only, s:should_display) + + " Update cache when new data comes. + let s:cache = get(s:, 'cache', {}) + let s:cache[s:fpath] = s:data + let s:cache.ftime = getftime(s:fpath) + let s:cache.bufnr = bufnr('') + endif + + return s:data +endfunction + +" Deprecated as a lot of people complain the error message. +function! s:HandleLSPResponse(error, response) abort + if empty(a:error) + " Refer to coc.nvim 79cb11e + " No document symbol provider exists when response is null. + if a:response isnot v:null + call s:DoHandleResponse(a:response) + call vista#cursor#TryInitialRun() + endif + else + call vista#error#Notify("Error when calling CocActionAsync('documentSymbols'): ".string(a:error)) + endif +endfunction + +function! s:HandleLSPResponseInSilence(error, response) abort + if empty(a:error) && a:response isnot v:null + call s:DoHandleResponse(a:response) + endif +endfunction + +function! s:AutoUpdate(_fpath) abort + let s:reload_only = v:true + call vista#AutoUpdateWithDelay(function('CocActionAsync'), ['documentSymbols', function('s:HandleLSPResponseInSilence')]) +endfunction + +function! s:Run() abort + return s:DoHandleResponse(CocAction('documentSymbols')) +endfunction + +function! s:RunAsync() abort + call CocActionAsync('documentSymbols', function('s:HandleLSPResponseInSilence')) +endfunction + +function! s:Execute(bang, should_display) abort + call vista#source#Update(bufnr('%'), winnr(), expand('%'), expand('%:p')) + let s:fpath = expand('%:p') + + if a:bang + call s:DoHandleResponse(CocAction('documentSymbols')) + if a:should_display + call vista#renderer#RenderAndDisplay(s:data) + endif + else + let s:should_display = a:should_display + call s:RunAsync() + endif +endfunction + +function! s:Dispatch(F, ...) abort + if !exists('*CocActionAsync') + call vista#error#Need('coc.nvim') + return + endif + + call vista#SetProvider(s:provider) + return call(function(a:F), a:000) +endfunction + +function! vista#executive#coc#Cache() abort + return get(s:, 'cache', {}) +endfunction + +" Internal public APIs +" +" Run and RunAsync is for internal use. +function! vista#executive#coc#Run(fpath) abort + if exists('*CocAction') + call vista#SetProvider(s:provider) + let s:fpath = a:fpath + call vista#win#Execute(g:vista.source.get_winnr(), function('s:Run')) + return s:data + endif +endfunction + +function! vista#executive#coc#RunAsync() abort + call s:Dispatch('s:RunAsync') +endfunction + +" The public Execute function is used for interacting with this plugin from +" outside, where sets the provider and auto update events. +function! vista#executive#coc#Execute(bang, should_display, ...) abort + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + let g:vista.silent = v:false + return s:Dispatch('s:Execute', a:bang, a:should_display) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/ctags.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/ctags.vim new file mode 100644 index 0000000..a9c3451 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/ctags.vim @@ -0,0 +1,429 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +let s:reload_only = v:false +let s:should_display = v:false + +let s:ctags = get(g:, 'vista_ctags_executable', 'ctags') +let s:support_json_format = + \ len(filter(systemlist(s:ctags.' --list-features'), 'v:val =~# ''^json''')) > 0 + +" Expose this variable for debugging +let g:vista#executive#ctags#support_json_format = s:support_json_format + +let s:ctags_project_opts = get(g:, 'vista_ctags_project_opts', '') + +if s:support_json_format + let s:default_cmd_fmt = '%s %s %s --output-format=json --fields=-PF -f- %s' + let s:DefaultTagParser = function('vista#parser#ctags#FromJSON') +else + let s:default_cmd_fmt = '%s %s %s -f- %s' + let s:DefaultTagParser = function('vista#parser#ctags#FromExtendedRaw') +endif + +let s:is_mac = has('macunix') +let s:is_linux = has('unix') && !has('macunix') && !has('win32unix') +let s:can_async = has('patch-8.0.0027') + +function! s:GetCustomCmd(filetype) abort + if exists('g:vista_ctags_cmd') + \ && has_key(g:vista_ctags_cmd, a:filetype) + return g:vista_ctags_cmd[a:filetype] + endif + return v:null +endfunction + +function! s:GetDefaultCmd(file) abort + " Refer to tagbar + let common_opt = '--format=2 --excmd=pattern --fields=+nksSaf --extras=+F --sort=no --append=no' + + " Do not pass --extras for C/CPP in order to let uctags handle the tags for anonymous + " entities correctly. + if g:vista.source.filetype() !=# 'c' && g:vista.source.filetype() !=# 'cpp' + let common_opt .= ' --extras= ' + endif + + let language_specific_opt = s:GetLanguageSpecificOptition(&filetype) + let cmd = printf(s:default_cmd_fmt, s:ctags, common_opt, language_specific_opt, a:file) + + return cmd +endfunction + +function! s:GetLanguageSpecificOptition(filetype) abort + let opt = '' + + try + let types = g:vista#types#uctags#{a:filetype}# + let lang = types.lang + let kinds = join(keys(types.kinds), '') + let opt = printf('--language-force=%s --%s-kinds=%s', lang, lang, kinds) + " Ignore Vim(let):E121: Undefined variable + catch /^Vim\%((\a\+)\)\=:E121/ + endtry + + return opt +endfunction + +function! s:NoteTemp() abort + if exists('s:tmp_file') + call add(g:vista.tmps, s:tmp_file) + unlet s:tmp_file + endif +endfunction + +" FIXME support all languages that ctags does +function! s:BuildCmd(origin_fpath) abort + let s:tmp_file = s:IntoTemp(a:origin_fpath) + if empty(s:tmp_file) + return '' + endif + + call vista#Debug('executive::ctags::s:BuildCmd origin_fpath:'.a:origin_fpath) + let s:fpath = a:origin_fpath + + let custom_cmd = s:GetCustomCmd(&filetype) + + if custom_cmd isnot v:null + let cmd = printf('%s %s', custom_cmd, s:tmp_file) + if stridx(custom_cmd, '--output-format=json') > -1 + let s:TagParser = function('vista#parser#ctags#FromJSON') + else + let s:TagParser = function('vista#parser#ctags#FromExtendedRaw') + endif + else + let cmd = s:GetDefaultCmd(s:tmp_file) + let s:TagParser = s:DefaultTagParser + endif + + let g:vista.ctags_cmd = cmd + + return cmd +endfunction + +function! s:PrepareContainer() abort + let s:data = {} + let g:vista = get(g:, 'vista', {}) + let g:vista.functions = [] + let g:vista.raw = [] + let g:vista.kinds = [] + let g:vista.raw_by_kind = {} + let g:vista.with_scope = [] + let g:vista.without_scope = [] + let g:vista.tree = {} +endfunction + +" Process the preprocessed output by ctags and remove s:jodid. +function! s:ApplyExtracted() abort + " Update cache when new data comes. + let s:cache = get(s:, 'cache', {}) + let s:cache[s:fpath] = s:data + let s:cache.ftime = getftime(s:fpath) + let s:cache.bufnr = bufnr('') + + call vista#Debug('executive::ctags::s:ApplyExtracted s:fpath:'.s:fpath.', s:reload_only:'.s:reload_only.', s:should_display:'.s:should_display) + let [s:reload_only, s:should_display] = vista#renderer#LSPProcess(s:data, s:reload_only, s:should_display) + + if exists('s:jodid') + unlet s:jodid + endif + + call s:NoteTemp() + call vista#cursor#TryInitialRun() +endfunction + +function! s:ExtractLinewise(raw_data) abort + call s:PrepareContainer() + call map(a:raw_data, 's:TagParser(v:val, s:data)') +endfunction + +function! s:AutoUpdate(fpath) abort + call vista#Debug('executive::ctags::s:AutoUpdate '.a:fpath) + if g:vista.source.filetype() ==# 'markdown' + \ && get(g:, 'vista_enable'.&filetype.'_extension', 1) + call vista#extension#{&ft}#AutoUpdate(a:fpath) + else + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + let s:reload_only = v:true + call vista#Debug('executive::ctags::s:AutoUpdate calling s:ApplyExecute '.a:fpath) + call s:ApplyExecute(v:false, a:fpath) + endif +endfunction + +function! vista#executive#ctags#AutoUpdate(fpath) abort + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + call s:AutoUpdate(a:fpath) +endfunction + +" Run ctags synchronously given the cmd +function! s:ApplyRun(cmd) abort + call vista#Debug('executive::ctags::s:ApplyRun:'.a:cmd) + let output = system(a:cmd) + if v:shell_error + return vista#error#('Fail to run ctags: '.a:cmd) + endif + + let s:cache = get(s:, 'cache', {}) + let s:cache.fpath = s:fpath + + call s:ExtractLinewise(split(output, "\n")) +endfunction + +if has('nvim') + function! s:on_exit(_job, _data, _event) abort dict + if !exists('g:vista') || v:dying || !has_key(self, 'stdout') + return + endif + + if self.stdout == [''] + return + endif + + call vista#Debug('ctags::s:on_exit '.string(self.stdout)) + " Second last line is the real last one in neovim + call s:ExtractLinewise(self.stdout[:-2]) + + call s:ApplyExtracted() + endfunction + + " Run ctags asynchronously given the cmd + function! s:ApplyRunAsync(cmd) abort + " job is job id in neovim + let jobid = jobstart(a:cmd, { + \ 'stdout_buffered': 1, + \ 'stderr_buffered': 1, + \ 'on_exit': function('s:on_exit') + \ }) + return jobid > 0 ? jobid : 0 + endfunction +else + + function! s:close_cb(channel) abort + call s:PrepareContainer() + + while ch_status(a:channel, {'part': 'out'}) ==# 'buffered' + let line = ch_read(a:channel) + call s:TagParser(line, s:data) + endwhile + + call s:ApplyExtracted() + endfunction + + if has('win32') + function! s:WrapCmd(cmd) abort + return &shell . ' ' . &shellcmdflag . ' ' . a:cmd + endfunction + else + function! s:WrapCmd(cmd) abort + return split(&shell) + split(&shellcmdflag) + [a:cmd] + endfunction + endif + + function! s:ApplyRunAsync(cmd) abort + let job = job_start(s:WrapCmd(a:cmd), { + \ 'close_cb':function('s:close_cb') + \ }) + let jobid = matchstr(job, '\d\+') + 0 + return jobid > 0 ? jobid : 0 + endfunction +endif + +function! s:TryAppendExtension(tempname) abort + let ext = g:vista.source.extension() + if !empty(ext) + return join([a:tempname, ext], '.') + else + return a:tempname + endif +endfunction + +function! s:BuiltinTempname() abort + let tempname = tempname() + return s:TryAppendExtension(tempname) +endfunction + +function! s:TempnameBasedOnSourceBufname() abort + let tempname = sha256(fnamemodify(bufname(g:vista.source.bufnr), ':p')) + return s:TryAppendExtension(tempname) +endfunction + +function! s:FromTMPDIR() abort + let tmpdir = $TMPDIR + if empty(tmpdir) + let tmpdir = '/tmp/' + elseif tmpdir !~# '/$' + let tmpdir .= '/' + endif + return tmpdir +endfunction + +function! s:GetTempDirectory() abort + if exists('s:tmpdir') + return s:tmpdir + else + if exists('$TMPDIR') + let s:tmpdir = s:FromTMPDIR() + else + let s:tmpdir = vista#util#CacheDirectory() + endif + return s:tmpdir + endif +endfunction + +" Use a temporary files for ctags processing instead of the original one. +" This allows using Tagbar for files accessed with netrw, and also doesn't +" slow down Tagbar for files that sit on slow network drives. +" This idea comes from tagbar. +function! s:IntoTemp(...) abort + " Don't use tempname() if possible since it would cause the changing of the anonymous tag name. + " + " Ref: https://github.com/liuchengxu/vista.vim/issues/122#issuecomment-511115932 + try + let tmp = s:GetTempDirectory().s:TempnameBasedOnSourceBufname() + catch + let tmp = s:BuiltinTempname() + endtry + + if get(g:vista, 'on_text_changed', 0) + let lines = g:vista.source.lines() + let g:vista.on_text_changed = 0 + else + if empty(a:1) + let lines = g:vista.source.lines() + else + try + let lines = readfile(a:1) + " Vim cannot read a temporary file, this may happen when you open vim with + " a file which does not exist yet, e.g., 'vim does_exist_yet.txt' + catch + " catch all readfile exception + return + endtry + endif + endif + + if writefile(lines, tmp) == 0 + return tmp + else + return vista#error#('Fail to write into a temp file.') + endif +endfunction + +function! s:ApplyExecute(bang, fpath) abort + let cmd = s:BuildCmd(a:fpath) + if empty(cmd) + return + endif + + if a:bang || !s:can_async + call s:ApplyRun(cmd) + else + call vista#Debug('executive::ctags::s:ApplyExecute calling s:RunAsyncCommon('.cmd.')') + call s:RunAsyncCommon(cmd) + endif +endfunction + +function! s:Run(fpath) abort + let cmd = s:BuildCmd(a:fpath) + if empty(cmd) + return + endif + + call s:ApplyRun(cmd) + + return s:data +endfunction + +function! s:RunAsyncCommon(cmd) abort + if exists('s:jodid') + call vista#util#JobStop(s:jodid) + call s:NoteTemp() + endif + + let s:jodid = s:ApplyRunAsync(a:cmd) + + if !s:jodid + call vista#error#RunCtags(a:cmd) + endif +endfunction + +function! s:RunAsync(fpath) abort + if s:can_async + let cmd = s:BuildCmd(a:fpath) + if empty(cmd) + return + endif + + call s:RunAsyncCommon(cmd) + endif +endfunction + +function! s:Execute(bang, should_display) abort + let s:should_display = a:should_display + let s:fpath = expand('%:p') + call s:ApplyExecute(a:bang, s:fpath) +endfunction + +function! s:Dispatch(F, ...) abort + let custom_cmd = s:GetCustomCmd(&filetype) + + let exe = custom_cmd isnot v:null ? split(custom_cmd)[0] : s:ctags + + if !executable(exe) + call vista#error#Need(exe) + return + endif + + call vista#SetProvider(s:provider) + return call(function(a:F), a:000) +endfunction + +function! vista#executive#ctags#Cache() abort + return get(s:, 'data', {}) +endfunction + +" Run ctags given the cmd synchronously +function! vista#executive#ctags#Run(fpath) abort + return s:Dispatch('s:Run', a:fpath) +endfunction + +" Run ctags given the cmd asynchronously +function! vista#executive#ctags#RunAsync(fpath) abort + call s:Dispatch('s:RunAsync', a:fpath) +endfunction + +function! vista#executive#ctags#Execute(bang, should_display, ...) abort + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + return s:Dispatch('s:Execute', a:bang, a:should_display) +endfunction + +" Run ctags recursively. +function! vista#executive#ctags#ProjectRun() abort + if !exists('s:recursive_ctags_cmd') + " https://github.com/universal-ctags/ctags/issues/2042 + " + " If ctags has the json format feature, we should use the + " `--output-format=json` option, which is easier to parse and more reliable. + " Otherwise we will use the `--_xformat` option. + if s:support_json_format + let s:recursive_ctags_cmd = s:ctags.' '.s:ctags_project_opts.' -R -x --output-format=json --fields=+n' + let s:RecursiveParser = function('vista#parser#ctags#RecursiveFromJSON') + else + let s:recursive_ctags_cmd = s:ctags.' '.s:ctags_project_opts." -R -x --_xformat='TAGNAME:%N ++++ KIND:%K ++++ LINE:%n ++++ INPUT-FILE:%F ++++ PATTERN:%P'" + let s:RecursiveParser = function('vista#parser#ctags#RecursiveFromXformat') + endif + endif + + let output = system(s:recursive_ctags_cmd) + if v:shell_error + return vista#error#RunCtags(s:recursive_ctags_cmd) + endif + + let s:data = {} + + call map(split(output, "\n"), 's:RecursiveParser(v:val, s:data)') + + return s:data +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/lcn.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/lcn.vim new file mode 100644 index 0000000..094dde4 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/lcn.vim @@ -0,0 +1,88 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +let s:reload_only = v:false +let s:should_display = v:false + +let s:fetching = v:true + +function! s:HandleLSPResponse(output) abort + let s:fetching = v:false + if !has_key(a:output, 'result') + call vista#error#Notify('No result via LanguageClient#textDocument_documentSymbol()') + return + endif + + let s:data = vista#renderer#LSPPreprocess(a:output.result) + let [s:reload_only, s:should_display] = vista#renderer#LSPProcess(s:data, s:reload_only, s:should_display) + + " Update cache when new data comes. + let s:cache = get(s:, 'cache', {}) + let s:cache[s:fpath] = s:data + let s:cache.ftime = getftime(s:fpath) + let s:cache.bufnr = bufnr('') + + call vista#cursor#TryInitialRun() +endfunction + +function! s:AutoUpdate(fpath) abort + let s:reload_only = v:true + let s:fpath = a:fpath + call s:RunAsync() +endfunction + +function! s:Run() abort + if !exists('*LanguageClient#textDocument_documentSymbol') + return + endif + call s:RunAsync() + let s:fetching = v:true + while s:fetching + sleep 100m + endwhile + return get(s:, 'data', {}) +endfunction + +function! s:RunAsync() abort + if exists('*LanguageClient#textDocument_documentSymbol') + call vista#SetProvider(s:provider) + call vista#win#Execute( + \ g:vista.source.get_winnr(), + \ function('LanguageClient#textDocument_documentSymbol'), + \ {'handle': v:false}, + \ function('s:HandleLSPResponse') + \ ) + endif +endfunction + +function! vista#executive#lcn#Run(fpath) abort + let s:fpath = a:fpath + return s:Run() +endfunction + +function! vista#executive#lcn#RunAsync() abort + call s:RunAsync() +endfunction + +function! vista#executive#lcn#Execute(bang, should_display, ...) abort + call vista#source#Update(bufnr('%'), winnr(), expand('%'), expand('%:p')) + let s:fpath = expand('%:p') + + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + + let g:vista.silent = v:false + let s:should_display = a:should_display + + if a:bang + return s:Run() + else + call s:RunAsync() + endif +endfunction + +function! vista#executive#lcn#Cache() abort + return get(s:, 'cache', {}) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/nvim_lsp.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/nvim_lsp.vim new file mode 100644 index 0000000..24851d9 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/nvim_lsp.vim @@ -0,0 +1,89 @@ +" Copyright (c) 2019 Alvaro Muñoz +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +let g:vista_executive_nvim_lsp_reload_only = v:false +let g:vista_executive_nvim_lsp_should_display = v:false +let g:vista_executive_nvim_lsp_fetching = v:true + +function! s:AutoUpdate(fpath) abort + let g:vista_executive_nvim_lsp_reload_only = v:true + let s:fpath = a:fpath + call s:RunAsync() +endfunction + +function! s:Run() abort + if !has('nvim-0.5') + return + endif + call s:RunAsync() + while g:vista_executive_nvim_lsp_fetching + sleep 100m + endwhile + return get(s:, 'data', {}) +endfunction + +function! vista#executive#nvim_lsp#SetData(data) abort + let s:data = a:data + " Update cache when new data comes. + let s:cache = get(s:, 'cache', {}) + let s:cache[s:fpath] = s:data + let s:cache.ftime = getftime(s:fpath) + let s:cache.bufnr = bufnr('') +endfunction + +function! s:RunAsync() abort + if !has('nvim-0.5') + return + endif + call vista#SetProvider(s:provider) + lua << EOF + local params = vim.lsp.util.make_position_params() + local callback = function(err, _, result) + if err then print(tostring(err)) return end + if not result then return end + vim.g.vista_executive_nvim_lsp_fetching = false + data = vim.fn['vista#renderer#LSPPreprocess'](result) + vim.fn['vista#executive#nvim_lsp#SetData'](data) + if next(data) ~= nil then + res = vim.fn['vista#renderer#LSPProcess'](data, vim.g.vista_executive_nvim_lsp_reload_only, vim.g.vista_executive_nvim_lsp_should_display) + vim.g.vista_executive_nvim_lsp_reload_only = res[1] + vim.g.vista_executive_nvim_lsp_should_display = res[2] + vim.fn['vista#cursor#TryInitialRun']() + end + end + vim.lsp.buf_request(0, 'textDocument/documentSymbol', params, callback) +EOF +endfunction + +function! vista#executive#nvim_lsp#Run(fpath) abort + " TODO: check if the LSP service is registered for fpath. + let s:fpath = a:fpath + return s:Run() +endfunction + +function! vista#executive#nvim_lsp#RunAsync() abort + call s:RunAsync() +endfunction + +function! vista#executive#nvim_lsp#Execute(bang, should_display, ...) abort + call vista#source#Update(bufnr('%'), winnr(), expand('%'), expand('%:p')) + let s:fpath = expand('%:p') + + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + + let g:vista.silent = v:false + let g:vista_executive_nvim_lsp_should_display = a:should_display + + if a:bang + return s:Run() + else + call s:RunAsync() + endif +endfunction + +function! vista#executive#nvim_lsp#Cache() abort + return get(s:, 'cache', {}) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/vim_lsc.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/vim_lsc.vim new file mode 100644 index 0000000..8f18988 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/vim_lsc.vim @@ -0,0 +1,89 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +let s:reload_only = v:false +let s:should_display = v:false + +let s:fetching = v:true + +function! s:HandleLSPResponse(results) abort + let s:fetching = v:false + if empty(a:results) + return [] + endif + + let s:data = vista#renderer#LSPPreprocess(a:results) + + if !empty(s:data) + let [s:reload_only, s:should_display] = vista#renderer#LSPProcess(s:data, s:reload_only, s:should_display) + + " Update cache when new data comes. + let s:cache = get(s:, 'cache', {}) + let s:cache[s:fpath] = s:data + let s:cache.ftime = getftime(s:fpath) + let s:cache.bufnr = bufnr('') + endif + + call vista#cursor#TryInitialRun() +endfunction + +function! s:AutoUpdate(fpath) abort + let s:reload_only = v:true + let s:fpath = a:fpath + call s:RunAsync() +endfunction + +function! s:Run() abort + if !exists('*lsc#server#userCall') + return + endif + call s:RunAsync() + while s:fetching + sleep 100m + endwhile + return get(s:, 'data', {}) +endfunction + +function! s:RunAsync() abort + if exists('*lsc#server#userCall') + call vista#SetProvider(s:provider) + + " vim-lsc + call lsc#file#flushChanges() + call lsc#server#userCall('textDocument/documentSymbol', + \ lsc#params#textDocument(), + \ function('s:HandleLSPResponse')) + endif +endfunction + +function! vista#executive#vim_lsc#Run(fpath) abort + let s:fpath = a:fpath + return s:Run() +endfunction + +function! vista#executive#vim_lsc#RunAsync() abort + call s:RunAsync() +endfunction + +function! vista#executive#vim_lsc#Execute(bang, should_display, ...) abort + call vista#source#Update(bufnr('%'), winnr(), expand('%'), expand('%:p')) + let s:fpath = expand('%:p') + + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + + let g:vista.silent = v:false + let s:should_display = a:should_display + + if a:bang + return s:Run() + else + call s:RunAsync() + endif +endfunction + +function! vista#executive#vim_lsc#Cache() abort + return get(s:, 'cache', {}) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/vim_lsp.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/vim_lsp.vim new file mode 100644 index 0000000..6017134 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/executive/vim_lsp.vim @@ -0,0 +1,116 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +let s:reload_only = v:false +let s:should_display = v:false + +let s:last_req_id = 0 + +function! s:HandleLSPResponse(_server, _req_id, _type, data) abort + let s:fetching = v:false + if !has_key(a:data.response, 'result') + return [] + endif + + let result = a:data.response.result + + let s:data = vista#renderer#LSPPreprocess(result) + + if !empty(s:data) + let s:ever_done = v:true + let [s:reload_only, s:should_display] = vista#renderer#LSPProcess(s:data, s:reload_only, s:should_display) + + " Update cache when new data comes. + let s:cache = get(s:, 'cache', {}) + let s:cache[s:fpath] = s:data + let s:cache.ftime = getftime(s:fpath) + let s:cache.bufnr = bufnr('') + endif + + call vista#cursor#TryInitialRun() +endfunction + +function! s:AutoUpdate(fpath) abort + let s:reload_only = v:true + let s:fpath = a:fpath + if s:HasAvaliableServers() + call s:RunAsync() + endif +endfunction + +function! s:HasAvaliableServers() abort + if !exists('*lsp#get_whitelisted_servers') + return 0 + endif + let s:servers = filter(lsp#get_whitelisted_servers(), + \ 'lsp#capabilities#has_document_symbol_provider(v:val)') + return len(s:servers) +endfunction + +function! s:Run() abort + call s:RunAsync() + while s:fetching + sleep 100m + endwhile + return get(s:, 'data', {}) +endfunction + +function! s:RunAsync() abort + call vista#SetProvider(s:provider) + for server in s:servers + call lsp#send_request(server, { + \ 'method': 'textDocument/documentSymbol', + \ 'params': { + \ 'textDocument': lsp#get_text_document_identifier(), + \ }, + \ 'on_notification': function('s:HandleLSPResponse', [server, s:last_req_id, 'documentSymbol']), + \ }) + let s:fetching = v:true + endfor +endfunction + +function! vista#executive#vim_lsp#Run(fpath) abort + if s:HasAvaliableServers() + let s:fpath = a:fpath + return s:Run() + endif +endfunction + +function! vista#executive#vim_lsp#RunAsync() abort + if s:HasAvaliableServers() + call s:RunAsync() + endif +endfunction + +function! vista#executive#vim_lsp#Execute(bang, should_display, ...) abort + if !s:HasAvaliableServers() + if get(a:000, 0, v:true) + return vista#error#('Retrieving symbols is not avaliable') + endif + return + endif + + call vista#source#Update(bufnr('%'), winnr(), expand('%'), expand('%:p')) + let s:fpath = expand('%:p') + + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + + let g:vista.silent = v:false + let s:should_display = a:should_display + + if a:bang + call s:Run() + else + if !exists('s:ever_done') + call vista#util#Retriving(s:provider) + endif + call s:RunAsync() + endif +endfunction + +function! vista#executive#vim_lsp#Cache() abort + return get(s:, 'cache', {}) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/extension/markdown.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/extension/markdown.vim new file mode 100644 index 0000000..0ab10b6 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/extension/markdown.vim @@ -0,0 +1,93 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:provider = fnamemodify(expand(''), ':t:r') + +function! s:IsHeader(cur_line, next_line) abort + return a:cur_line =~# '^#\+' || + \ a:cur_line =~# '^\S' && (a:next_line =~# '^=\+\s*$' || a:next_line =~# '^-\+\s*$') +endfunction + +function! s:GatherHeaderMetadata() abort + let is_fenced_block = 0 + + let s:lnum2tag = {} + + let headers = [] + + let idx = 0 + let lines = g:vista.source.lines() + + for line in lines + let line = substitute(line, '#', "\\\#", 'g') + let next_line = get(lines, idx + 1, '') + + if l:line =~# '````*' || l:line =~# '\~\~\~\~*' + let is_fenced_block = !is_fenced_block + endif + + let is_header = s:IsHeader(l:line, l:next_line) + + if is_header && !is_fenced_block + let matched = matchlist(l:line, '\(\#*\)\(.*\)') + let text = vista#util#Trim(matched[2]) + let s:lnum2tag[len(headers)] = text + call add(headers, {'lnum': idx+1, 'text': text, 'level': strlen(matched[1])}) + endif + + let idx += 1 + endfor + + return headers +endfunction + +" Use s:lnum2tag so that we don't have to extract the header from the rendered line. +function! vista#extension#markdown#GetHeader(lnum) abort + return get(s:lnum2tag, a:lnum, v:null) +endfunction + +function! s:ApplyAutoUpdate() abort + if has_key(g:vista, 'bufnr') && g:vista.winnr() != -1 + call vista#SetProvider(s:provider) + let rendered = vista#renderer#markdown_like#MD(s:GatherHeaderMetadata()) + call vista#util#SetBufline(g:vista.bufnr, rendered) + endif +endfunction + +function! vista#extension#markdown#AutoUpdate(fpath) abort + call s:AutoUpdate(a:fpath) +endfunction + +function! s:ShouldUseMarkdownExtension(source_filetype) abort + if a:source_filetype ==# 'markdown' + return v:true + " vimwiki can reuse the markdown extension. + elseif a:source_filetype ==# 'vimwiki' + \ && vista#GetExplicitExecutive(a:source_filetype) ==# 'markdown' + return v:true + else + return v:false + endif +endfunction + +function! s:AutoUpdate(fpath) abort + let source_filetype = g:vista.source.filetype() + if s:ShouldUseMarkdownExtension(source_filetype) + call s:ApplyAutoUpdate() + elseif source_filetype ==# 'rst' + call vista#extension#rst#AutoUpdate(a:fpath) + else + call vista#executive#ctags#AutoUpdate(a:fpath) + endif +endfunction + +" Credit: originally from `:Toc` of vim-markdown +function! vista#extension#markdown#Execute(_bang, should_display) abort + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + + if a:should_display + let rendered = vista#renderer#markdown_like#MD(s:GatherHeaderMetadata()) + call vista#sidebar#OpenOrUpdate(rendered) + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/extension/rst.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/extension/rst.vim new file mode 100644 index 0000000..7d47c1c --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/extension/rst.vim @@ -0,0 +1,81 @@ +" Copyright (c) 2019 Mathieu Clabaut +" MIT License +" vim: ts=2 sw=2 sts=2 et +" +" Heavily inspired from https://raw.githubusercontent.com/Shougo/unite-outline/master/autoload/unite/sources/outline/defaults/rst.vim + +let s:provider = fnamemodify(expand(''), ':t:r') + +function! s:GatherHeaderMetadata() abort + let headers = [] + + let s:lnum2tag = {} + + let idx = 0 + let adornment_levels = {} + let adornment_id = 2 + + let lines = g:vista.source.lines() + while idx < len(lines) + let line = lines[idx] + let matched_line = get(lines, idx + 1, '') + " Check the matching strictly. + if matched_line =~# '^\([[:punct:]]\)\1\{3,}$' && line !~# '^\s*$' + let text = vista#util#Trim(l:line) + if idx > 1 && lines[idx - 1] == matched_line + " Title + let item = {'lnum': idx+1, 'text': text, 'level': 1} + else + " Sections + let item = {'lnum': idx+1, 'text': text} + let adchar = matched_line[0] + if !has_key(l:adornment_levels, adchar) + let l:adornment_levels[adchar] = l:adornment_id + let l:adornment_id += 1 + endif + let item['level'] = l:adornment_levels[adchar] + endif + let s:lnum2tag[len(headers)] = text + call add(headers, l:item) + let idx += 1 + endif + let idx += 1 + endwhile + + return headers +endfunction + +function! vista#extension#rst#GetHeader(lnum) abort + return get(s:lnum2tag, a:lnum, v:null) +endfunction + +function! s:ApplyAutoUpdate() abort + if has_key(g:vista, 'bufnr') && g:vista.winnr() != -1 + call vista#SetProvider(s:provider) + let rendered = vista#renderer#markdown_like#RST(s:GatherHeaderMetadata()) + call vista#util#SetBufline(g:vista.bufnr, rendered) + endif +endfunction + +function! vista#extension#rst#AutoUpdate(fpath) abort + call s:AutoUpdate(a:fpath) +endfunction + +function! s:AutoUpdate(fpath) abort + if g:vista.source.filetype() ==# 'rst' + call s:ApplyAutoUpdate() + elseif g:vista.source.filetype() ==# 'markdown' + call vista#extension#markdown#AutoUpdate(a:fpath) + else + call vista#executive#ctags#AutoUpdate(a:fpath) + endif +endfunction + +function! vista#extension#rst#Execute(_bang, should_display) abort + call vista#OnExecute(s:provider, function('s:AutoUpdate')) + + if a:should_display + let rendered = vista#renderer#markdown_like#RST(s:GatherHeaderMetadata()) + call vista#sidebar#OpenOrUpdate(rendered) + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder.vim new file mode 100644 index 0000000..c221333 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder.vim @@ -0,0 +1,228 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:is_nvim = has('nvim') + +" Could use the cached data? +function! s:IsUsable(cache, fpath) abort + return !empty(a:cache) + \ && has_key(a:cache, a:fpath) + \ && getftime(a:fpath) == a:cache.ftime + \ && !getbufvar(a:cache.bufnr, '&mod') +endfunction + +" Try other alternative executives when the data given by the specified one is empty. +" Return v:true if some alternative brings us some data, or else v:false. +function! s:TryAlternatives(tried, fpath) abort + " TODO when more executives added allow configuring this list + let executives = get(g:, 'vista_finder_alternative_executives', g:vista#executives) + + if empty(executives) + return v:false + endif + + let alternatives = filter(copy(executives), 'v:val != a:tried') + + for alternative in alternatives + " Do not try nvim_lsp until the related LSP service is registed for nvim_lsp + " otherwise it may cause the neovim hangs. + if s:is_nvim && alternative ==# 'nvim_lsp' + continue + endif + let s:data = vista#executive#{alternative}#Run(a:fpath) + if !empty(s:data) + let s:cur_executive = alternative + let s:using_alternative = v:true + return v:true + endif + endfor + + return v:false +endfunction + +function! vista#finder#GetSymbols(...) abort + let executive = a:0 > 0 ? a:1 : g:vista_default_executive + + " 'toc' is a special executive supported by extension, we should use ctags + " instead for the finder case, ref #255. + if executive ==# 'toc' + let executive = 'ctags' + endif + + if index(g:vista#executives, executive) == -1 + call vista#error#InvalidExecutive(executive) + return + endif + + let should_skip = vista#ShouldSkip() + if should_skip + let fpath = g:vista.source.fpath + else + let fpath = expand('%:p') + endif + + let cache = vista#executive#{executive}#Cache() + " FIXME s:IsUsable is actually useless as provider gives s:data. + if type(cache) == v:t_dict && s:IsUsable(cache, fpath) + let s:data = cache[fpath] + else + if !should_skip + let [bufnr, winnr, fname] = [bufnr('%'), winnr(), expand('%')] + call vista#source#Update(bufnr, winnr, fname, fpath) + endif + let g:vista.skip_set_provider = v:true + " In this case, we normally want to run synchronously IMO. + let s:data = vista#executive#{executive}#Run(fpath) + endif + + let s:cur_executive = executive + let s:using_alternative = v:false + + if empty(s:data) && !s:TryAlternatives(executive, fpath) + return [v:null, s:cur_executive, s:using_alternative] + endif + + return [s:data, s:cur_executive, s:using_alternative] +endfunction + +function! s:GroupByKindForLSPData(lsp_items) abort + let s:grouped = {} + + for item in a:lsp_items + let s:max_len_kind = max([s:max_len_kind, strwidth(item.kind)]) + + let lnum_and_text = printf('%s:%s', item.text, item.lnum) + let s:max_len_lnum_and_text = max([s:max_len_lnum_and_text, strwidth(lnum_and_text)]) + + if has_key(s:grouped, item.kind) + call add(s:grouped[item.kind], item) + else + let s:grouped[item.kind] = [item] + endif + endfor +endfunction + +" Find the maximum length of each column of items to be displayed +function! s:FindColumnBoundary(grouped_data) abort + for [kind, vals] in items(a:grouped_data) + let s:max_len_kind = max([s:max_len_kind, strwidth(kind)]) + + let sub_max = max(map(copy(vals), 'strwidth(printf(''%s:%s'', v:val.text, v:val.lnum))')) + let s:max_len_lnum_and_text = max([s:max_len_lnum_and_text, sub_max]) + endfor +endfunction + +function! s:IntoRow(icon, kind, item) abort + let line = g:vista.source.line_trimmed(a:item.lnum) + let lnum_and_text = printf('%s:%s', a:item.text, a:item.lnum) + let row = printf('%s%s [%s]%s %s', + \ lnum_and_text, repeat(' ', s:max_len_lnum_and_text- strwidth(lnum_and_text)), + \ a:kind, repeat(' ', s:max_len_kind - strwidth(a:kind)), + \ line) + + if a:icon !=# '' + let row = printf('%s %s', a:icon, row) + endif + + return row +endfunction + +function! s:RenderGroupedData(grouped_data) abort + let source = [] + for [kind, vals] in items(a:grouped_data) + let icon = vista#renderer#IconFor(kind) + let rows = [] + for val in vals + call add(rows, s:IntoRow(icon, kind, val)) + endfor + call extend(source, rows) + endfor + return source +endfunction + +" Prepare source for fzf, skim finder +function! vista#finder#PrepareSource(raw_items) abort + let [s:max_len_kind, s:max_len_lnum_and_text] = [-1, -1] + + if type(a:raw_items) == v:t_list + call s:GroupByKindForLSPData(a:raw_items) + return s:RenderGroupedData(s:grouped) + else + call s:FindColumnBoundary(a:raw_items) + return s:RenderGroupedData(a:raw_items) + endif +endfunction + +" Prepare opts for fzf#run(fzf#wrap(opts)) +function! vista#finder#PrepareOpts(source, prompt) abort + let opts = { + \ 'source': a:source, + \ 'sink': function('vista#finder#fzf#sink'), + \ 'options': ['--prompt', a:prompt, '--nth', '1', '--delimiter', ':'] + get(g:, 'vista_fzf_opt', []), + \ } + + if len(g:vista_fzf_preview) > 0 + let idx = 0 + let opt_preview_window_processed = v:false + while idx < len(g:vista_fzf_preview) + if g:vista_fzf_preview[idx] =~# '^\(left\|up\|right\|down\)' + let g:vista_fzf_preview[idx] = g:vista_fzf_preview[idx] . ':+{-1}-5' + let opt_preview_window_processed = v:true + endif + let idx = idx + 1 + endwhile + if !opt_preview_window_processed + call extend(g:vista_fzf_preview, ['right:+{-1}-5']) + endif + let preview_opts = call('fzf#vim#with_preview', g:vista_fzf_preview).options + + if has('win32') + " keeping old code around since we are not sure if / how preview works on windows + let preview_opts[-1] = preview_opts[-1][0:-3] . g:vista.source.fpath . (g:vista#renderer#enable_icon ? ':{2}' : ':{1}') + else + let object_name_index = g:vista#renderer#enable_icon ? '3' : '2' + let extract_line_number = printf(':$(echo {%s})', object_name_index) + let preview_opts[-1] = preview_opts[-1][0:-3] . fnameescape(g:vista.source.fpath) . extract_line_number + endif + + call extend(opts.options, preview_opts) + endif + + return opts +endfunction + +" Actually call fzf#run() with a highlighter given the opts +function! vista#finder#RunFZFOrSkim(apply_run) abort + echo "\r" + + call a:apply_run() + + " Only add highlights when using nvim, since vim has an issue with the highlight. + " Ref #139 + if has('nvim') + call vista#finder#fzf#Highlight() + + " https://unix.stackexchange.com/questions/149209/refresh-changed-content-of-file-opened-in-vim + " Vim Highlight does not work at times + " + " &modifiable is to avoid error in MacVim - E948: Job still running (add ! to end the job) + " if !has('nvim') && &modifiable + " edit + " endif + endif +endfunction + +function! vista#finder#Dispatch(bang, finder, executive) abort + let finder = empty(a:finder) ? 'fzf' : a:finder + if empty(a:executive) + let executive = vista#GetExplicitExecutiveOrDefault() + else + let executive = a:executive + endif + if a:bang + call vista#finder#{finder}#ProjectRun(executive) + else + call vista#finder#{finder}#Run(executive) + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/clap.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/clap.vim new file mode 100644 index 0000000..3835648 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/clap.vim @@ -0,0 +1,10 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! vista#finder#clap#Run(...) abort + if !exists('g:loaded_clap') + return vista#error#Need('https://github.com/liuchengxu/vim-clap') + endif + Clap tags +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/fzf.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/fzf.vim new file mode 100644 index 0000000..e63c679 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/fzf.vim @@ -0,0 +1,217 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +scriptencoding utf-8 + +let s:finder = fnamemodify(expand(''), ':t:r') + +let s:cols_layout = {} +let s:aligner = {} + +function! s:cols_layout.project_ctags() abort + let [max_len_scope, max_len_lnum_and_text, max_len_relpath] = [-1, -1, -1] + + for [kind, v] in items(s:data) + let scope_len = strwidth(kind) + if scope_len > max_len_scope + let max_len_scope = scope_len + endif + + for item in v + let lnum_and_text = printf('%s:%s', item.lnum, item.text) + let len_lnum_and_text = strwidth(lnum_and_text) + if len_lnum_and_text > max_len_lnum_and_text + let max_len_lnum_and_text = len_lnum_and_text + endif + + let relpath = item.tagfile + let len_relpath = strwidth(relpath) + if len_relpath > max_len_relpath + let max_len_relpath = len_relpath + endif + endfor + endfor + + return [max_len_scope, max_len_lnum_and_text, max_len_relpath] +endfunction + +function! s:aligner.project_ctags() abort + let source = [] + + let [max_len_scope, max_len_lnum_and_text, max_len_relpath] = s:cols_layout.project_ctags() + + for [kind, v] in items(s:data) + let icon = vista#renderer#IconFor(kind) + for item in v + " FIXME handle ctags -R better + let lnum_and_text = printf('%s:%s', item.lnum, item.text) + let relpath = item.tagfile + let row = printf('%s %s%s [%s]%s %s%s %s', + \ icon, + \ lnum_and_text, repeat(' ', max_len_lnum_and_text- strwidth(lnum_and_text)), + \ kind, repeat(' ', max_len_scope - strwidth(kind)), + \ relpath, repeat(' ', max_len_relpath - strwidth(relpath)), + \ item.taginfo) + call add(source, row) + endfor + endfor + + return source +endfunction + +function! vista#finder#fzf#extract(line) abort + let icon_tag_lnum = split(a:line, '[')[0] + " [a-zA-Z:#_.,<>] + " matching tag can't contain whitespace, but a tag does have a chance to contain whitespace? + + if g:vista#renderer#enable_icon + " icon tag:lnum + let icon_stripped = join(split(icon_tag_lnum)[1:], ' ') + else + let icon_stripped = icon_tag_lnum + end + + let items = matchlist(icon_stripped, '\([a-zA-Z:#_.,<>]*\):\(\d\+\)') + let tag = items[1] + let lnum = items[2] + + return [lnum, tag] +endfunction + +" Optional argument: winid for the origin tags window +function! vista#finder#fzf#sink(line, ...) abort + let [lnum, tag] = vista#finder#fzf#extract(a:line) + let col = stridx(g:vista.source.line(lnum), tag) + let col = col == -1 ? 1 : col + 1 + if a:0 > 0 + if win_getid() != a:1 + noautocmd call win_gotoid(a:1) + endif + else + call vista#source#GotoWin() + endif + call vista#util#Cursor(lnum, col) + normal! zz + call call('vista#util#Blink', get(g:, 'vista_blink', [2, 100])) +endfunction + +" Actually call fzf#run() with a highlighter given the opts +function! s:ApplyRun() abort + try + " fzf_colors may interfere custom syntax. + " Unlet and restore it later. + if exists('g:fzf_colors') && !get(g:, 'vista_keep_fzf_colors', 0) + let l:old_fzf_colors = g:fzf_colors + unlet g:fzf_colors + endif + + call fzf#run(fzf#wrap(s:opts)) + finally + if exists('l:old_fzf_colors') + let g:fzf_colors = old_fzf_colors + endif + endtry +endfunction + +function! s:Run(...) abort + let source = vista#finder#PrepareSource(s:data) + let using_alternative = get(s:, 'using_alternative', v:false) ? '*' : '' + let prompt = using_alternative.s:finder.':'.s:cur_executive.'> ' + + let s:opts = vista#finder#PrepareOpts(source, prompt) + + call vista#finder#RunFZFOrSkim(function('s:ApplyRun')) +endfunction + +function! s:project_sink(line) abort + let parts = split(a:line) + let lnum = split(parts[1], ':')[0] + let relpath = parts[3] + execute 'edit' relpath + call vista#util#Cursor(lnum, 1) + normal! zz +endfunction + +function! s:ProjectRun(...) abort + let source = s:aligner.project_ctags() + let prompt = (get(s:, 'using_alternative', v:false) ? '*' : '').s:cur_executive.'> ' + let s:opts = { + \ 'source': source, + \ 'sink': function('s:project_sink'), + \ 'options': ['--prompt', prompt] + get(g:, 'vista_fzf_opt', []), + \ } + + call s:ApplyRun() + if has('nvim') + call vista#finder#fzf#Highlight() + endif +endfunction + +function! vista#finder#fzf#Highlight() abort + let groups = ['Character', 'Float', 'Identifier', 'Statement', 'Label', 'Boolean', 'Delimiter', 'Constant', 'String', 'Operator', 'PreCondit', 'Include', 'Conditional', 'PreProc', 'TypeDef',] + let len_groups = len(groups) + + let icons = values(g:vista#renderer#icons) + + let idx = 0 + let hi_idx = 0 + + let icon_groups = [] + for icon in icons + let cur_group = 'FZFVistaIcon'.idx + call add(icon_groups, cur_group) + execute 'syntax match' cur_group '/'.icon.'/' 'contained' + execute 'hi default link' cur_group groups[hi_idx] + let hi_idx += 1 + let hi_idx = hi_idx % len_groups + let idx += 1 + endfor + + execute 'syntax match FZFVistaTag /\s*.*\(:\d\+\s\)\@=/' 'contains=FZFVistaIcon,'.join(icon_groups, ',') + execute 'syntax match FZFVistaNumber /^[^\[]*\(\s\s\[\)\@=/' 'contains=FZFVistaTag,FZFVistaIcon,'.join(icon_groups, ',') + syntax match FZFVistaScope /^[^]│]*]/ contains=FZFVistaNumber,FZFVistaBracket + syntax match FZFVista /^[^│┌└]*/ contains=FZFVistaBracket,FZFVistaTag,FZFVistaNumber,FZFVistaScope + syntax match FZFVistaBracket /\s\s\[\|\]\s\s/ contained + + hi default link FZFVistaBracket SpecialKey + hi default link FZFVistaNumber Number + hi default link FZFVistaTag Tag + hi default link FZFVistaScope Function + hi default link FZFVista Type +endfunction + +" Optional argument: executive, coc or ctags +" Ctags is the default. +function! vista#finder#fzf#Run(...) abort + if g:vista_close_on_fzf_select + call vista#sidebar#Close() + endif + if !exists('*fzf#run') + return vista#error#Need('https://github.com/junegunn/fzf') + endif + + let [s:data, s:cur_executive, s:using_alternative] = call('vista#finder#GetSymbols', a:000) + + if s:data is# v:null + return vista#util#Warning('Empty data for fzf finder') + endif + + call s:Run() +endfunction + +" TODO workspace symbols +function! vista#finder#fzf#ProjectRun(executive) abort + if a:executive !=? 'ctags' + return vista#error#('Only ctags supports Vista finder!') + endif + + let s:data = vista#executive#{a:executive}#ProjectRun() + let s:cur_executive = a:executive + + if empty(s:data) + return vista#util#Warning('Empty data for finder') + endif + + call s:ProjectRun() +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/skim.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/skim.vim new file mode 100644 index 0000000..5306d14 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/finder/skim.vim @@ -0,0 +1,49 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:finder = fnamemodify(expand(''), ':t:r') + +" Actually call skim#run() +function! s:ApplyRun() abort + try + " skim_colors may interfere custom syntax. + " Unlet and restore it later. + if exists('g:skim_colors') + let old_skim_colors = g:skim_colors + unlet g:skim_colors + endif + + call skim#run(skim#wrap(s:opts)) + finally + if exists('l:old_skim_colors') + let g:skim_colors = old_skim_colors + endif + endtry +endfunction + +function! s:Run(...) abort + let source = vista#finder#PrepareSource(s:data) + let using_alternative = get(s:, 'using_alternative', v:false) ? '*' : '' + let prompt = using_alternative.s:finder.':'.s:cur_executive.'> ' + + let s:opts = vista#finder#PrepareOpts(source, prompt) + + call vista#finder#RunFZFOrSkim(function('s:ApplyRun')) +endfunction + +" Optional argument: executive, coc or ctags +" Ctags is the default. +function! vista#finder#skim#Run(...) abort + if !exists('*skim#run') + return vista#error#Need('https://github.com/lotabout/skim') + endif + + let [s:data, s:cur_executive, s:using_alternative] = call('vista#finder#GetSymbols', a:000) + + if s:data is# v:null + return vista#util#Warning('Empty data for skim finder') + endif + + call s:Run() +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/floating.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/floating.vim new file mode 100644 index 0000000..7991389 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/floating.vim @@ -0,0 +1,224 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:floating_timer = -1 +let s:last_lnum = -1 + +let s:floating_delay = get(g:, 'vista_floating_delay', 100) + +" Vista sidebar window usually sits at the right side. +" TODO improve me! +function! s:CalculatePosition(lines) abort + let lines = a:lines + let pos = s:floating_opened_pos + + let width = max(map(copy(a:lines), 'strdisplaywidth(v:val)')) + + let width = max([width, 40]) + let width = min([width, float2nr(&columns * 0.6) ]) + let height = len(lines) + + " Calculate anchor + " North first, fallback to South if there is no enough space. + let bottom_line = line('w0') + winheight(0) - 1 + if pos[1] + height <= bottom_line + let vert = 'N' + let row = 1 + else + let vert = 'S' + let row = 0 + endif + + " TODO should be tweaked accroding to the position of vista sidebar + let hors = ['E', 'W'] + + let [_, _, cur_col, _, _] = getcurpos() + + " West first, fallback into East if there is no enough space. + if pos[2] + width <= &columns + let hor = hors[0] + let col = 0 + else + let hor = hors[1] + let col = 1 + endif + + return [width, height, vert.hor, row-1, col+4-cur_col] +endfunction + +function! s:ApplyClose() abort + if !exists('g:vista') + return + endif + + if exists('#VistaFloatingWin') + autocmd! VistaFloatingWin + endif + + if exists('s:floating_win_id') + let winnr = win_id2win(s:floating_win_id) + + if winnr > 0 + execute winnr.'wincmd c' + endif + endif + + let g:vista.floating_visible = v:false +endfunction + +function! s:CloseOnCursorMoved() abort + " To avoid closing floating window immediately, check the cursor + " was really moved. + if getpos('.') == s:floating_opened_pos + return + endif + + call s:ApplyClose() +endfunction + +function! s:CloseOnWinEnter() abort + let winnr = win_id2win(s:floating_win_id) + + " Floating window has been closed already. + if winnr == 0 + autocmd! VistaFloatingWin + return + endif + + " We are just in the floating window. Do not close it + if winnr == winnr() + return + endif + + autocmd! VistaFloatingWin + execute winnr.'wincmd c' + + let g:vista.floating_visible = v:false +endfunction + +function! s:HighlightTagInFloatinWin() abort + if !nvim_win_is_valid(s:floating_win_id) + return + endif + + if exists('s:floating_lnum') + let target_line = getbufline(s:floating_bufnr, s:floating_lnum) + if empty(target_line) + return + endif + let target_line = target_line[0] + try + let [_, start, end] = matchstrpos(target_line, '\C'.s:cur_tag) + if start != -1 + " {line} is zero-based. + call nvim_buf_add_highlight(s:floating_bufnr, -1, 'Search', s:floating_lnum-1, start, end) + endif + catch /^Vim\%((\a\+)\)\=:E869/ + " If we meet the E869 error, just highlight the whole line. + call nvim_buf_add_highlight(s:floating_bufnr, -1, 'Search', s:floating_lnum-1, 0, -1) + endtry + + unlet s:floating_lnum + endif +endfunction + +function! s:Display(msg, win_id) abort + if a:win_id !=# win_getid() + return + endif + + if !exists('s:floating_bufnr') || !bufexists(s:floating_bufnr) + let s:floating_bufnr = nvim_create_buf(v:false, v:false) + endif + + let s:floating_opened_pos = getpos('.') + let [width, height, anchor, row, col] = s:CalculatePosition(a:msg) + + " silent is neccessary for the both strategy! + silent let s:floating_win_id = nvim_open_win( + \ s:floating_bufnr, v:true, { + \ 'width': width, + \ 'height': height, + \ 'relative': 'cursor', + \ 'anchor': anchor, + \ 'row': row + 0.4, + \ 'col': col - 5, + \ 'focusable': v:false, + \ }) + + call nvim_buf_set_lines(s:floating_bufnr, 0, -1, 0, a:msg) + + call s:HighlightTagInFloatinWin() + + let &l:filetype = getbufvar(g:vista.source.bufnr, '&ft') + setlocal + \ winhl=Normal:VistaFloat + \ buftype=nofile + \ nobuflisted + \ bufhidden=hide + \ nonumber + \ norelativenumber + \ signcolumn=no + \ nofoldenable + \ wrap + + wincmd p + + augroup VistaFloatingWin + autocmd! + autocmd CursorMoved call s:CloseOnCursorMoved() + autocmd BufEnter,WinEnter,WinLeave * call s:CloseOnWinEnter() + augroup END + + let g:vista.floating_visible = v:true +endfunction + +function! vista#floating#Close() abort + call s:ApplyClose() +endfunction + +" See if it's identical to the last lnum to avoid blink. Ref #55 +" +" No need to display again when it's already visible. +function! s:ShouldSkipDisplay(lnum) abort + silent! call timer_stop(s:floating_timer) + + if a:lnum == s:last_lnum + \ && get(g:vista, 'floating_visible', v:false) + return 1 + else + let s:last_lnum = a:lnum + return 0 + endif +endfunction + +function! s:DisplayWithDelay(lines) abort + let win_id = win_getid() + let s:floating_timer = timer_start(s:floating_delay, { -> s:Display(a:lines, win_id)}) +endfunction + +" Display in floating_win given the lnum of source buffer and current tag. +function! vista#floating#DisplayAt(lnum, tag) abort + if s:ShouldSkipDisplay(a:lnum) + return + endif + + " We save the tag info so that it could be used later for adding the tag highlight. + " + " It's problematic when calculating the highlight position here, leading to + " the displacement of current tag highlighting position. + let s:cur_tag = a:tag + + let [lines, s:floating_lnum] = vista#preview#GetLines(a:lnum) + call s:DisplayWithDelay(lines) +endfunction + +" Display in floating_win given the lnum of source buffer and raw lines. +function! vista#floating#DisplayRawAt(lnum, lines) abort + if s:ShouldSkipDisplay(a:lnum) + return + endif + + call s:DisplayWithDelay(a:lines) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/fold.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/fold.vim new file mode 100644 index 0000000..df64fdb --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/fold.vim @@ -0,0 +1,35 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" Treat the number of heading whitespaces as indent level +function! s:HeadingWhitespaces(line) abort + return strlen(matchstr(a:line,'\v^\s+')) +endfunction + +function! vista#fold#Expr() abort + if getline(v:lnum) =~# '^$' + return 0 + endif + + let cur_indent = s:HeadingWhitespaces(getline(v:lnum)) + let next_indent = s:HeadingWhitespaces(getline(v:lnum+1)) + + if cur_indent < next_indent + return '>'.next_indent + else + return cur_indent + endif +endfunction + +function! vista#fold#Text() abort + let line = getline(v:foldstart) + + " Foldtext ignores tabstop and shows tabs as one space, + " so convert tabs to 'tabstop' spaces, then text lines up. + let spaces = repeat(' ', &tabstop) + let line = substitute(line, '\t', spaces, 'g') + let line = substitute(line, g:vista_fold_toggle_icons[0], g:vista_fold_toggle_icons[1], '') + + return line +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/ftplugin.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/ftplugin.vim new file mode 100644 index 0000000..0bee4da --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/ftplugin.vim @@ -0,0 +1,62 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" If we use ftplugin/vista.vim, ftplugin/vista_kind.vim, etc, everytime we'll +" need this: +" +" No usual did_ftplugin check here +" +" So we could just use a function to set the buffer local settings. + +function! vista#ftplugin#Set() abort + setlocal + \ nonumber + \ norelativenumber + \ nopaste + \ nomodeline + \ noswapfile + \ nocursorline + \ nocursorcolumn + \ colorcolumn= + \ nobuflisted + \ buftype=nofile + \ bufhidden=hide + \ nomodifiable + \ signcolumn=no + \ textwidth=0 + \ nolist + \ winfixwidth + \ winfixheight + \ nospell + \ nofoldenable + \ foldcolumn=0 + \ nowrap + + setlocal foldmethod=expr + setlocal foldexpr=vista#fold#Expr() + setlocal foldtext=vista#fold#Text() + + if !vista#statusline#ShouldDisable() + let &l:statusline = vista#statusline#() + endif + + if !g:vista_no_mappings + nnoremap q :close + nnoremap :call vista#cursor#FoldOrJump() + nnoremap s :call vista#Sort() + nnoremap p :call vista#cursor#TogglePreview() + endif + + augroup VistaCursor + autocmd! + if g:vista_echo_cursor + autocmd CursorMoved call vista#cursor#ShowDetailWithDelay() + endif + autocmd BufLeave call vista#floating#Close() + augroup END + + if !exists('#VistaMOF') + call vista#autocmd#InitMOF() + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/highlight.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/highlight.vim new file mode 100644 index 0000000..036f565 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/highlight.vim @@ -0,0 +1,41 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" Highlight the line given the line number and ensure it's visible if required. +" +" lnum - current line number in vista window +" ensure_visible - kepp this line visible +" optional: tag - accurate tag +function! vista#highlight#Add(lnum, ensure_visible, tag) abort + if exists('w:vista_highlight_id') + call matchdelete(w:vista_highlight_id) + unlet w:vista_highlight_id + endif + + if get(g:, 'vista_highlight_whole_line', 0) + let hi_pos = a:lnum + else + let cur_line = getline(a:lnum) + " Current line may contains +,-,~, use `\S` is incorrect to find the right + " starting postion. + let [_, start, _] = matchstrpos(cur_line, '[a-zA-Z0-9_,#:]') + + " If we know the tag, then what we have to do is to use the length of tag + " based on the starting point. + " + " start is 0-based, while the column used in matchstrpos is 1-based. + if !empty(a:tag) + let hi_pos = [a:lnum, start+1, strlen(a:tag)] + else + let [_, end, _] = matchstrpos(cur_line, ':\d\+$') + let hi_pos = [a:lnum, start+1, end - start] + endif + endif + + let w:vista_highlight_id = matchaddpos('IncSearch', [hi_pos]) + + if a:ensure_visible + execute 'normal!' a:lnum.'z.' + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/init.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/init.vim new file mode 100644 index 0000000..8f33e7d --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/init.vim @@ -0,0 +1,84 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! vista#init#Api() abort + let g:vista = {} + let g:vista.tmps = [] + + " ========================================= + " Api for manipulating the vista buffer. + " ========================================= + function! g:vista.winnr() abort + return bufwinnr('__vista__') + endfunction + + function! g:vista.winid() abort + return bufwinid('__vista__') + endfunction + + " Get original tagline given the lnum in vista sidebar + " + " Mind the offset + function! g:vista.get_tagline_under_cursor() abort + return get(g:vista.vlnum_cache, line('.') - g:vista#renderer#default#vlnum_offset, '') + endfunction + + " ========================================= + " Api for manipulating the source buffer. + " ========================================= + let source_handle = {} + + function! source_handle.get_winnr() abort + return bufwinnr(self.bufnr) + endfunction + + function! source_handle.get_winid() abort + if has_key(self, 'winid') + return self.winid + else + " A buffer can exist in two windows at the same time, this could be inaccurate. + return bufwinid(self.bufnr) + endif + endfunction + + function! source_handle.filetype() abort + return getbufvar(self.bufnr, '&filetype') + endfunction + + function! source_handle.lines() abort + return getbufline(self.bufnr, 1, '$') + endfunction + + function! source_handle.line(lnum) abort + let bufline = getbufline(self.bufnr, a:lnum) + return empty(bufline) ? '' : bufline[0] + endfunction + + function! source_handle.line_trimmed(lnum) abort + let bufline = getbufline(self.bufnr, a:lnum) + return empty(bufline) ? '' : vista#util#Trim(bufline[0]) + endfunction + + function! source_handle.extension() abort + " Try the extension first, and then the filetype, for ctags relys on the extension name. + let e = fnamemodify(self.fpath, ':e') + return empty(e) ? getbufvar(self.bufnr, '&ft') : e + endfunction + + function! source_handle.scope_seperator() abort + let filetype = self.filetype() + try + let type = g:vista#types#uctags#{filetype}# + catch /^Vim\%((\a\+)\)\=:E121/ + let type = {} + endtry + + " FIXME use a default value maybe inappropriate. + return get(type, 'sro', '.') + endfunction + + let g:vista.source = source_handle + + hi default link VistaFloat Pmenu +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/jump.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/jump.vim new file mode 100644 index 0000000..188b4db --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/jump.vim @@ -0,0 +1,96 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! s:EscapeForVimRegexp(str) abort + return escape(a:str, '^$.*?/\[]') +endfunction + +" Jump to the source line containing the given tag +function! vista#jump#TagLine(tag) abort + let cur_line = split(getline('.'), ':') + + " Skip if the current line or the target line is empty + if empty(cur_line) + return + endif + + let lnum = cur_line[-1] + let line = getbufline(g:vista.source.bufnr, lnum) + + if empty(line) + return + endif + + try + let [_, start, _] = matchstrpos(line[0], s:EscapeForVimRegexp(a:tag)) + catch /^Vim\%((\a\+)\)\=:E869/ + let start = -1 + endtry + + call vista#source#GotoWin() + " Move cursor to the column of tag located, otherwise the first column + call vista#util#Cursor(lnum, start > -1 ? start+1 : 1) + + if g:vista_enable_centering_jump + normal! zz + endif + + call call('vista#util#Blink', g:vista_blink) + + call vista#win#CloseFloating() + + if g:vista_close_on_jump + call vista#sidebar#Close() + endif +endfunction + +function! s:NextTopLevelLnum() abort + let cur_lnum = line('.') + let ending = line('$') + + while cur_lnum < ending + let cur_lnum += 1 + if indent(cur_lnum) == 0 && !empty(getline(cur_lnum)) + return cur_lnum + endif + endwhile + + return 0 +endfunction + +function! s:PrevTopLevelLnum() abort + let cur_lnum = line('.') + + " The first two lines contain no tags. + while cur_lnum > 2 + let cur_lnum -= 1 + if indent(cur_lnum) == 0 && !empty(getline(cur_lnum)) + return cur_lnum + endif + endwhile + + if cur_lnum == 3 + return 3 + endif + + return 0 +endfunction + +function! s:ApplyJump(lnum) abort + if a:lnum > 0 + call vista#util#Cursor(a:lnum, 1) + normal! zz + call call('vista#util#Blink', g:vista_top_level_blink) + endif +endfunction + +function! vista#jump#NextTopLevel() abort + call vista#win#CloseFloating() + call s:ApplyJump(s:NextTopLevelLnum()) +endfunction + +function! vista#jump#PrevTopLevel() abort + call vista#win#CloseFloating() + call s:ApplyJump(s:PrevTopLevelLnum()) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/parser/ctags.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/parser/ctags.vim new file mode 100644 index 0000000..79f7474 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/parser/ctags.vim @@ -0,0 +1,216 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! s:LoadData(container, line) abort + let line = a:line + + let kind = line.kind + + call vista#util#TryAdd(g:vista.raw_by_kind, kind, line) + + call add(g:vista.raw, line) + + if has_key(line, 'scope') + call add(g:vista.with_scope, line) + else + call add(g:vista.without_scope, line) + endif + + let picked = {'lnum': line.line, 'text': get(line, 'name', '') } + + if kind =~# '^f' || kind =~# '^m' + if has_key(line, 'signature') + let picked.signature = line.signature + endif + call add(g:vista.functions, picked) + endif + + if index(g:vista.kinds, kind) == -1 + call add(g:vista.kinds, kind) + endif + + call vista#util#TryAdd(a:container, kind, picked) +endfunction + +" Parse the output from ctags linewise and feed them into the container +" The parsed result should be compatible with the LSP output. +" +" Currently we only use these fields: +" +" { +" 'lnum': 12, +" 'col': 8, +" 'kind': 'Function', +" 'text': 'testnet_genesis', +" } + +function! s:ShortToLong(short) abort + let ft = getbufvar(g:vista.source.bufnr, '&filetype') + + try + + let types = g:vista#types#uctags#{ft}# + if has_key(types.kinds, a:short) + return types.kinds[a:short]['long'] + endif + + catch /^Vim\%((\a\+)\)\=:E121/ + endtry + + return a:short +endfunction + +function! s:ParseTagfield(tagfields) abort + let fields = {} + + if stridx(a:tagfields[0], ':') > -1 + let colon = stridx(a:tagfields[0], ':') + let value = a:tagfields[0][colon+1:] + let fields.kind = value + else + let kind = s:ShortToLong(a:tagfields[0]) + let fields.kind = kind + if index(g:vista.kinds, kind) == -1 + call add(g:vista.kinds, kind) + endif + endif + + if len(a:tagfields) > 1 + for tagfield in a:tagfields[1:] + let colon = stridx(tagfield, ':') + let name = tagfield[0:colon-1] + let value = tagfield[colon+1:] + let fields[name] = value + endfor + endif + + return fields +endfunction + +" {tagname}{tagfile}{tagaddress}[;"{tagfield}..] +" {tagname}{tagfile}{tagaddress};"{kind}{scope} +" ['vista#executive#ctags#Execute', '/Users/xlc/.vim/plugged/vista.vim/autoload/vista/executive/ctags.vim', '84;"', 'function'] +function! vista#parser#ctags#FromExtendedRaw(line, container) abort + if a:line =~# '^!_TAG' + return + endif + " Prevent bugs when a:line is all whitespace or doesn't contain any tabs + " (can't be parsed). + if a:line =~# '^\s*$' || stridx(a:line, "\t") == -1 + " Useful for debugging + " echom "Vista.vim: Error parsing ctags output: '" . a:line . "'" + return + endif + + let items = split(a:line, '\t') + + let line = {} + + let line.name = items[0] + let line.tagfile = items[1] + + " tagaddress itself possibly contains , so we have to restore the + " original content and then split by `;"` to get the tagaddress and other + " fields. + " tagaddress may also contains `;"`, so we join all the splits except the + " last one as the tagaddress and keep the last split as the other fields. + let rejoined = join(items[2:], "\t") + let resplitted = split(rejoined, ';"') + let splits = len(resplitted) + let line.tagaddress = join(resplitted[:splits-2], ';"') + + let fields = split(resplitted[splits-1], '\t') + let tagfields = s:ParseTagfield(fields) + + call extend(line, tagfields) + + if vista#ShouldIgnore(line.kind) + return + endif + + call s:LoadData(a:container, line) + +endfunction + +function! vista#parser#ctags#FromJSON(line, container) abort + if a:line =~# '^ctags' + return + endif + + try + let line = json_decode(a:line) + catch + call vista#error#('Fail to decode from JSON: '.a:line.', error: '.v:exception) + return + endtry + + if vista#ShouldIgnore(line.kind) + return + endif + + call s:LoadData(a:container, line) + +endfunction + +" ctags -R -x --_xformat='TAGNAME:%N ++++ KIND:%K ++++ LINE:%n ++++ INPUT-FILE:%F ++++ PATTERN:%P'" +" +function! vista#parser#ctags#RecursiveFromXformat(line, container) abort + + if a:line =~# '^ctags: Warning:' + return + endif + + let items = split(a:line, '++++') + + if len(items) != 5 + call vista#error#('Splitted items is not expected: '.string(items)) + return + endif + + call map(items, 'vista#util#Trim(v:val)') + + " TAGNAME: + let tagname = items[0][8:] + " KIND: + let kind = items[1][5:] + if vista#ShouldIgnore(kind) + return + endif + " LINE: + let lnum = items[2][5:] + " INPUT-FILE: + let relpath = items[3][11:] + " PATTERN: + let pattern = items[4][8:] + + let picked = {'lnum': lnum, 'text': tagname, 'tagfile': relpath, 'taginfo': pattern[2:-3]} + + call vista#util#TryAdd(a:container, kind, picked) +endfunction + +function! vista#parser#ctags#RecursiveFromJSON(line, container) abort + " { + " "_type":"tag", + " "name":"vista#source#Update", + " "path":"autoload/vista/source.vim", + " "pattern":"/^function! vista#source#Update(bufnr, winnr, ...) abort$/", + " "line":29, + " "kind":"function" + " } + if a:line =~# '^ctags: Warning: ignoring null tag' + return + endif + + let line = json_decode(a:line) + + let kind = line.kind + + if vista#ShouldIgnore(kind) + return + endif + + let picked = {'lnum': line.line, 'text': line.name, 'tagfile': line.path, 'taginfo': line.pattern[2:-3]} + + call vista#util#TryAdd(a:container, kind, picked) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/parser/lsp.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/parser/lsp.vim new file mode 100644 index 0000000..431758d --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/parser/lsp.vim @@ -0,0 +1,120 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol +" This should be updated periodically according the latest LSP specification. +let s:symbol_kind = { + \ '1': 'File', + \ '2': 'Module', + \ '3': 'Namespace', + \ '4': 'Package', + \ '5': 'Class', + \ '6': 'Method', + \ '7': 'Property', + \ '8': 'Field', + \ '9': 'Constructor', + \ '10': 'Enum', + \ '11': 'Interface', + \ '12': 'Function', + \ '13': 'Variable', + \ '14': 'Constant', + \ '15': 'String', + \ '16': 'Number', + \ '17': 'Boolean', + \ '18': 'Array', + \ '19': 'Object', + \ '20': 'Key', + \ '21': 'Null', + \ '22': 'EnumMember', + \ '23': 'Struct', + \ '24': 'Event', + \ '25': 'Operator', + \ '26': 'TypeParameter', + \ } + +function! s:Kind2Symbol(kind) abort + return has_key(s:symbol_kind, a:kind) ? s:symbol_kind[a:kind] : 'Unknown kind '.a:kind +endfunction + +function! s:IsFileUri(uri) abort + return stridx(a:uri, 'file:///') == 0 +endfunction + +" The kind field in the result is a number instead of a readable text, we +" should transform the number to the symbol text first. +function! vista#parser#lsp#KindToSymbol(line, container) abort + let line = a:line + " SymbolInformation interface + if has_key(line, 'location') + let location = line.location + if s:IsFileUri(location.uri) + let lnum = location.range.start.line + 1 + let col = location.range.start.character + 1 + call add(a:container, { + \ 'lnum': lnum, + \ 'col': col, + \ 'kind': s:Kind2Symbol(line.kind), + \ 'text': line.name, + \ }) + endif + " DocumentSymbol class + elseif has_key(line, 'range') + let range = line.range + let lnum = range.start.line + 1 + let col = range.start.character + 1 + call add(a:container, { + \ 'lnum': lnum, + \ 'col': col, + \ 'kind': s:Kind2Symbol(line.kind), + \ 'text': line.name, + \ }) + if has_key(line, 'children') + for child in line.children + call vista#parser#lsp#KindToSymbol(child, a:container) + endfor + endif + endif +endfunction + +function! vista#parser#lsp#CocSymbols(symbol, container) abort + if vista#ShouldIgnore(a:symbol.kind) + return + endif + + let raw = { 'line': a:symbol.lnum, 'kind': a:symbol.kind, 'name': a:symbol.text } + call add(g:vista.raw, raw) + + if a:symbol.kind ==? 'Method' || a:symbol.kind ==? 'Function' + call add(g:vista.functions, a:symbol) + endif + + call add(a:container, { + \ 'lnum': a:symbol.lnum, + \ 'col': a:symbol.col, + \ 'text': a:symbol.text, + \ 'kind': a:symbol.kind, + \ 'level': a:symbol.level + \ }) +endfunction + +" https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol +function! vista#parser#lsp#ExtractSymbol(symbol, container) abort + let symbol = a:symbol + + if vista#ShouldIgnore(symbol.kind) + return + endif + + if symbol.kind ==? 'Method' || symbol.kind ==? 'Function' + call add(g:vista.functions, symbol) + endif + + let picked = {'lnum': symbol.lnum, 'col': symbol.col, 'text': symbol.text} + + if has_key(a:container, symbol.kind) + call add(a:container[symbol.kind], picked) + else + let a:container[symbol.kind] = [picked] + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/popup.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/popup.vim new file mode 100644 index 0000000..ce0644d --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/popup.vim @@ -0,0 +1,133 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:last_lnum = -1 +let s:popup_timer = -1 +let s:popup_delay = get(g:, 'vista_floating_delay', 100) + +function! s:ClosePopup() abort + if exists('s:popup_winid') + call popup_close(s:popup_winid) + unlet s:popup_winid + autocmd! VistaPopup + endif + let g:vista.popup_visible = v:false +endfunction + +call prop_type_delete('VistaMatch') +call prop_type_add('VistaMatch', { 'highlight': 'Search' }) + +function! s:HiTag() abort + call prop_add(s:popup_lnum, s:popup_start+1, { 'length': s:popup_end - s:popup_start, 'type': 'VistaMatch' }) +endfunction + +function! s:HiTagLine() abort + if exists('w:vista_hi_cur_tag_id') + call matchdelete(w:vista_hi_cur_tag_id) + endif + let w:vista_hi_cur_tag_id = matchaddpos('Search', [s:popup_lnum]) +endfunction + +function! s:OpenPopup(lines) abort + if g:vista_sidebar_position =~# 'right' + let max_length = max(map(copy(a:lines), 'strlen(v:val)')) + 2 + let pos_opts = { + \ 'pos': 'botleft', + \ 'line': 'cursor-2', + \ 'col': 'cursor-'.max_length, + \ 'moved': 'WORD', + \ } + else + let winwidth = winwidth(0) + let cur_length = strlen(getline('.')) + let offset = min([cur_length + 4, winwidth]) + let col = 'cursor+'.offset + let pos_opts = { + \ 'pos': 'botleft', + \ 'line': 'cursor-2', + \ 'col': col, + \ 'moved': 'WORD', + \ } + endif + + if !exists('s:popup_winid') + let s:popup_winid = popup_create(a:lines, pos_opts) + let s:popup_bufnr = winbufnr(s:popup_winid) + + let filetype = getbufvar(g:vista.source.bufnr, '&ft') + call win_execute(s:popup_winid, 'setlocal filetype='.filetype.' nofoldenable') + else + silent call deletebufline(s:popup_bufnr, 1, '$') + call setbufline(s:popup_bufnr, 1, a:lines) + call popup_show(s:popup_winid) + call popup_move(s:popup_winid, pos_opts) + endif + + augroup VistaPopup + autocmd! + autocmd CursorMoved call s:ClosePopup() + autocmd BufEnter,WinEnter,WinLeave * call s:ClosePopup() + augroup END + + let g:vista.popup_visible = v:true +endfunction + +function! s:DisplayRawAt(lnum, lines, vista_winid) abort + if win_getid() != a:vista_winid + return + endif + + call s:OpenPopup(a:lines) +endfunction + +function! s:DisplayAt(lnum, tag, vista_winid) abort + if win_getid() != a:vista_winid + return + endif + + let [lines, s:popup_lnum] = vista#preview#GetLines(a:lnum) + + call s:OpenPopup(lines) + + let target_line = lines[s:popup_lnum - 1] + try + let [_, s:popup_start, s:popup_end] = matchstrpos(target_line, '\C'.a:tag) + + " Highlight the tag in the popup window if found. + if s:popup_start > -1 + call win_execute(s:popup_winid, 'call s:HiTag()') + endif + catch /^Vim\%((\a\+)\)\=:E869/ + call win_execute(s:popup_winid, 'call s:HiTagLine()') + endtry +endfunction + +function! vista#popup#Close() abort + call s:ClosePopup() +endfunction + +function! s:DispatchDisplayer(Displayer, lnum, tag_or_raw_lines) abort + if a:lnum == s:last_lnum + \ || get(g:vista, 'popup_visible', v:false) + return + endif + + silent! call timer_stop(s:popup_timer) + + let s:last_lnum = a:lnum + + let win_id = win_getid() + let s:popup_timer = timer_start( + \ s:popup_delay, + \ { -> a:Displayer(a:lnum, a:tag_or_raw_lines, win_id) } + \ ) +endfunction + +function! vista#popup#DisplayAt(lnum, tag) abort + call s:DispatchDisplayer(function('s:DisplayAt'), a:lnum, a:tag) +endfunction + +function! vista#popup#DisplayRawAt(lnum, lines) abort + call s:DispatchDisplayer(function('s:DisplayRawAt'), a:lnum, a:lines) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/preview.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/preview.vim new file mode 100644 index 0000000..051410a --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/preview.vim @@ -0,0 +1,20 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" Return the lines to preview and the target line number in the preview buffer. +function! vista#preview#GetLines(lnum) abort + " Show 5 lines around the tag source line [lnum-5, lnum+5] + let range = 5 + + if a:lnum - range > 0 + let preview_lnum = range + 1 + else + let preview_lnum = a:lnum + endif + + let begin = max([a:lnum - range, 1]) + let end = begin + range * 2 + + return [getbufline(g:vista.source.bufnr, begin, end), preview_lnum] +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer.vim new file mode 100644 index 0000000..3500278 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer.vim @@ -0,0 +1,119 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +scriptencoding utf-8 + +let s:icons = { +\ 'func': "\uf794", +\ 'function': "\uf794", +\ 'functions': "\uf794", +\ 'var': "\uf71b", +\ 'variable': "\uf71b", +\ 'variables': "\uf71b", +\ 'const': "\uf8ff", +\ 'constant': "\uf8ff", +\ 'constructor': "\uf976", +\ 'method': "\uf6a6", +\ 'package': "\ue612", +\ 'packages': "\ue612", +\ 'enum': "\uf702", +\ 'enummember': "\uf282", +\ 'enumerator': "\uf702", +\ 'module': "\uf136", +\ 'modules': "\uf136", +\ 'type': "\uf7fd", +\ 'typedef': "\uf7fd", +\ 'types': "\uf7fd", +\ 'field': "\uf30b", +\ 'fields': "\uf30b", +\ 'macro': "\uf8a3", +\ 'macros': "\uf8a3", +\ 'map': "\ufb44", +\ 'class': "\uf0e8", +\ 'augroup': "\ufb44", +\ 'struct': "\uf318", +\ 'union': "\ufacd", +\ 'member': "\uf02b", +\ 'target': "\uf893", +\ 'property': "\ufab6", +\ 'interface': "\uf7fe", +\ 'namespace': "\uf475", +\ 'subroutine': "\uf9af", +\ 'implementation': "\uf776", +\ 'typeParameter': "\uf278", +\ 'default': "\uf29c" +\} + +let g:vista#renderer#ctags = get(g:, 'vista#renderer#ctags', 'default') +let g:vista#renderer#icons = map(extend(s:icons, get(g:, 'vista#renderer#icons', {})), 'tolower(v:val)') +let g:vista#renderer#enable_icon = get(g:, 'vista#renderer#enable_icon', + \ exists('g:vista#renderer#icons') || exists('g:airline_powerline_fonts')) + +function! vista#renderer#IconFor(kind) abort + if g:vista#renderer#enable_icon + let key = tolower(a:kind) + if has_key(g:vista#renderer#icons, key) + return g:vista#renderer#icons[key] + else + return get(g:vista#renderer#icons, 'default', '?') + endif + else + return '' + endif +endfunction + +function! vista#renderer#Decorate(kind) abort + if g:vista#renderer#enable_icon + return vista#renderer#IconFor(a:kind).' '.a:kind + else + return a:kind + endif +endfunction + +function! s:Render(data) abort + if g:vista.provider ==# 'coc' && type(a:data) == v:t_list + return vista#renderer#hir#lsp#Coc(a:data) + elseif g:vista.provider ==# 'ctags' && g:vista#renderer#ctags ==# 'default' + return vista#renderer#hir#ctags#Render() + else + " The kind renderer applys to the LSP provider. + return vista#renderer#kind#Render(a:data) + endif +endfunction + +" Render the extracted data to rows +function! vista#renderer#Render(data) abort + return s:Render(a:data) +endfunction + +function! vista#renderer#RenderAndDisplay(data) abort + call vista#sidebar#OpenOrUpdate(s:Render(a:data)) +endfunction + +" Convert the number kind to the text kind, and then +" extract the neccessary info from the raw LSP response. +function! vista#renderer#LSPPreprocess(lsp_result) abort + let lines = [] + call map(a:lsp_result, 'vista#parser#lsp#KindToSymbol(v:val, lines)') + + let processed_data = {} + let g:vista.functions = [] + call map(lines, 'vista#parser#lsp#ExtractSymbol(v:val, processed_data)') + + return processed_data +endfunction + +" React on the preprocessed LSP data +function! vista#renderer#LSPProcess(processed_data, reload_only, should_display) abort + " Always reload the data, display the processed data on demand. + if a:should_display + call vista#Debug('[LSPProcess]should_display, processed_data:'.string(a:processed_data)) + call vista#renderer#RenderAndDisplay(a:processed_data) + return [a:reload_only, v:false] + else + call vista#Debug('[LSPProcess]reload_only, processed_data:'.string(a:processed_data)) + call vista#sidebar#Reload(a:processed_data) + return [v:true, a:should_display] + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/hir/ctags.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/hir/ctags.vim new file mode 100644 index 0000000..3eff480 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/hir/ctags.vim @@ -0,0 +1,297 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +scriptencoding utf-8 + +let s:scope_icon = ['⊕', '⊖'] + +let s:visibility_icon = { + \ 'public': '+', + \ 'protected': '~', + \ 'private': '-', + \ } + +let g:vista#renderer#default#vlnum_offset = 3 + +let s:indent_size = g:vista#renderer#enable_icon ? 2 : 4 + +" Return the rendered row to be displayed given the depth +function! s:Assemble(line, depth) abort + let line = a:line + + let kind = get(line, 'kind', '') + + let row = vista#util#Join( + \ repeat(' ', a:depth * s:indent_size), + \ s:GetVisibility(line), + \ vista#renderer#IconFor(kind).' ', + \ get(line, 'name'), + \ get(line, 'signature', ''), + \ ' '.kind, + \ ':'.get(line, 'line', '') + \ ) + + return row +endfunction + +" Actually append to the rows +function! s:Append(line, rows, depth) abort + let line = a:line + let rows = a:rows + + let row = s:Assemble(line, a:depth) + + call add(rows, row) + call add(s:vlnum_cache, line) +endfunction + +function! s:ApplyAppend(line, row, rows) abort + let line = a:line + let rows = a:rows + + call add(rows, a:row) + call add(s:vlnum_cache, line) +endfunction + +" Return the next root name and line after appending to the rows. +function! s:AppendChild(line, rows, depth) abort + if has_key(a:line, 'scope') + call s:Append(a:line, a:rows, a:depth) + let parent_name = a:line.scope + let next_root_name = parent_name . s:scope_seperator . a:line.name + return [next_root_name, a:line] + endif + + return [v:null, v:null] +endfunction + +function! s:Compare(s1, s2) abort + return a:s1.line - a:s2.line +endfunction + +" This way is more of heuristic. +" +" the line of child should larger than parent's, which partially fixes this issue comment: +" https://github.com/universal-ctags/ctags/issues/2065#issuecomment-485117935 +" +" The previous nearest one should be the exact one. +function! s:RealParentOf(candidate) abort + let candidate = a:candidate + + let name = candidate.scope + let kind = candidate.scopeKind + + let parent_candidates = [] + for pc in g:vista.without_scope + if pc.name ==# name && pc.kind ==# kind && pc.line <= candidate.line + call add(parent_candidates, pc) + endif + endfor + + if !empty(parent_candidates) + call sort(parent_candidates, function('s:Compare')) + return parent_candidates[-1] + endif + + return {} +endfunction + +" Previously we use the regexp to see if the scope of candidate is matched: +" +" \ ' && v:val.scope =~# ''^''.l:scope'. +" +" but it runs into the error like NFA E869 '\@ ' in some cases, so we use this +" now. Ref #161 +function! s:StartWith(candidate_scope, root_scope) abort + return a:candidate_scope[:len(a:root_scope)] == a:root_scope +endfunction + +" Find all descendants of the root +function! s:DescendantsOf(candidates, root_line, scope) abort + let candidates = filter(copy(a:candidates), + \ 'has_key(v:val, ''scope'')'. + \ ' && s:StartWith(v:val.scope, a:scope)'. + \ ' && v:val.scopeKind ==# a:root_line.kind'. + \ ' && v:val.line >= a:root_line.line' + \ ) + + return candidates + " The real parent problem seemingly has been solved? + " return filter(candidates, 's:RealParentOf(v:val) ==# a:root_line') +endfunction + +function! s:DescendantsOfRoot(candidates, root_line) abort + let candidates = filter(copy(a:candidates), + \ 'has_key(v:val, ''scope'')'. + \ ' && s:StartWith(v:val.scope, a:root_line.name)'. + \ ' && v:val.scopeKind ==# a:root_line.kind'. + \ ' && v:val.line >= a:root_line.line' + \ ) + + return filter(candidates, 's:RealParentOf(v:val) ==# a:root_line') +endfunction + +function! s:RenderDescendants(parent_name, parent_line, descendants, rows, depth) abort + let depth = a:depth + let rows = a:rows + + " Clear the previous duplicate parent line that is about to be added. + " + " This is a little bit stupid actually :(. + let about_to_append = s:Assemble(a:parent_line, depth) + let idx = 0 + while idx < len(rows) + if rows[idx] ==# about_to_append + unlet rows[idx] + unlet s:vlnum_cache[idx] + endif + let idx += 1 + endwhile + + " Append the root actually + call s:ApplyAppend(a:parent_line, about_to_append, rows) + + let depth += 1 + + " find all the children + let children = filter(copy(a:descendants), 'v:val.scope ==# a:parent_name') + + let grandchildren = [] + let grandchildren_line = [] + + for child in children + let [next_potentioal_root, next_potentioal_root_line] = s:AppendChild(child, rows, depth) + if !empty(next_potentioal_root) + call add(grandchildren, next_potentioal_root) + call add(grandchildren_line, next_potentioal_root_line) + endif + endfor + + let idx = 0 + while idx < len(grandchildren) + let child_name = grandchildren[idx] + let child_line = grandchildren_line[idx] + + let descendants = s:DescendantsOf(g:vista.with_scope, child_line, child_name) + + if !empty(descendants) + call s:RenderDescendants(child_name, child_line, descendants, a:rows, depth) + endif + + let idx += 1 + endwhile +endfunction + +function! s:GetVisibility(line) abort + return has_key(a:line, 'access') ? get(s:visibility_icon, a:line.access, '?') : '' +endfunction + +function! s:SortCompare(i1, i2) abort + return a:i1.name > a:i2.name +endfunction + +function! s:RenderScopeless(scope_less, rows) abort + let rows = a:rows + let scope_less = a:scope_less + + for kind in keys(scope_less) + let kind_line = vista#renderer#Decorate(kind) + call add(rows, g:vista_fold_toggle_icons[0].' '.kind_line) + + let lines = scope_less[kind] + + if get(g:vista, 'sort', v:false) + let lines = sort(copy(lines), function('s:SortCompare')) + endif + + for line in lines + let row = vista#util#Join( + \ ' '.s:GetVisibility(line), + \ get(line, 'name'), + \ get(line, 'signature', ''), + \ ':'.line.line + \ ) + + call add(rows, row) + + let line.vlnum = len(rows) + 2 + endfor + + call add(rows, '') + call add(s:vlnum_cache, '') + endfor + + " Remove the last line if it's empty, i.e., '' + if !empty(rows) && empty(rows[-1]) + unlet rows[-1] + endif +endfunction + +function! s:Render() abort + let s:scope_seperator = g:vista.source.scope_seperator() + + let rows = [] + + " s:vlnum_cache is a cache for recording which original tagline + " is related to the line in the vista sidebar, for we have to + " remove the duplicate parents which leads to reassign the lnum + " to the original tagline. + " + " The item of s:vlnum_cache is some original tagline dict with + " `vlnum` field added later. + let s:vlnum_cache = [] + + let scope_less = {} + + let without_scope = g:vista.without_scope + + " The root of hierarchy structure doesn't have scope field. + for potential_root_line in without_scope + + let root_name = potential_root_line.name + + let descendants = s:DescendantsOfRoot(g:vista.with_scope, potential_root_line) + + if !empty(descendants) + + call s:RenderDescendants(root_name, potential_root_line, descendants, rows, 0) + + call add(rows, '') + call add(s:vlnum_cache, '') + + else + + if has_key(potential_root_line, 'kind') + call vista#util#TryAdd(scope_less, potential_root_line.kind, potential_root_line) + endif + + endif + + endfor + + call s:RenderScopeless(scope_less, rows) + + " The original tagline is positioned in which line in the vista sidebar. + let idx = 0 + while idx < len(s:vlnum_cache) + if !empty(s:vlnum_cache[idx]) + " idx is 0-based, while the line number is 1-based, and we prepend the + " two lines first, so the final offset is 1+2=3 + let s:vlnum_cache[idx].vlnum = idx + g:vista#renderer#default#vlnum_offset + endif + let idx += 1 + endwhile + + let g:vista.vlnum_cache = s:vlnum_cache + + return rows +endfunction + +function! vista#renderer#hir#ctags#Render() abort + if empty(g:vista.raw) + return [] + endif + + return s:Render() +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/hir/lsp.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/hir/lsp.vim new file mode 100644 index 0000000..daaa571 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/hir/lsp.vim @@ -0,0 +1,91 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:indent_size = g:vista#renderer#enable_icon ? 2 : 4 + +function! s:IntoLSPHirRow(row) abort + let icon = vista#renderer#IconFor(a:row.kind).' ' + let indented = repeat(' ', a:row.level * s:indent_size).icon.a:row.text.' '.a:row.kind + let lnum = ':'.a:row.lnum + return indented.lnum +endfunction + +function! s:IntoLSPNonHirRow(row) abort + let indented = repeat(' ', s:indent_size).a:row.text + let lnum = ':'.a:row.lnum + return indented.lnum +endfunction + +function! s:RenderNonHirRow(vs, rendered) abort + call add(a:rendered, s:IntoLSPNonHirRow(a:vs.row)) + let vlnum = len(a:rendered) + 2 + let g:vista.raw[a:vs.idx].vlnum = vlnum + if has_key(a:vs.row, 'text') + let g:vista.vlnum2tagname[vlnum] = a:vs.row.text + endif +endfunction + +function! s:RenderLSPHirAndThenGroupByKind(data) abort + let rendered = [] + let level0 = {} + + let idx = 0 + let len = len(a:data) + + for row in a:data + if (row.level == 0 && idx+1 < len && a:data[idx+1].level > 0) + \ || row.level > 0 + call add(rendered, s:IntoLSPHirRow(row)) + let g:vista.raw[idx].vlnum = len(rendered) + 2 + if has_key(row, 'text') + let g:vista.vlnum2tagname[len(rendered)+2] = row.text + endif + endif + if row.level > 0 + if idx+1 < len && a:data[idx+1].level == 0 + call add(rendered, '') + endif + else + if idx < len && a:data[idx].level == 0 + if has_key(level0, row.kind) + call add(level0[row.kind], { 'row': row, 'idx': idx }) + else + let level0[row.kind] = [{ 'row': row, 'idx': idx }] + endif + endif + endif + let idx += 1 + endfor + + if len(level0) > 0 && !empty(rendered) && rendered[-1] !=# '' + call add(rendered, '') + endif + + for [kind, vs] in items(level0) + call add(rendered, vista#renderer#Decorate(kind)) + call map(vs, 's:RenderNonHirRow(v:val, rendered)') + call add(rendered, '') + endfor + + if empty(rendered[-1]) + unlet rendered[-1] + endif + + return rendered +endfunction + +" Render the content linewise. +function! s:TransformDirectly(row) abort + let icon = vista#renderer#IconFor(a:row.kind) + let indented = repeat(' ', a:row.level * s:indent_size).icon.a:row.text + let lnum = ':'.a:row.lnum + return indented.kind.lnum +endfunction + +" data is a list of items with the level info for the hierarchy purpose. +function! vista#renderer#hir#lsp#Coc(data) abort + let g:vista.vlnum2tagname = {} + " return map(a:data, 's:Transform(v:val)') + return s:RenderLSPHirAndThenGroupByKind(a:data) +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/kind.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/kind.vim new file mode 100644 index 0000000..ff898e4 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/kind.vim @@ -0,0 +1,90 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et +" +" Render the content by the kind of tag. +scriptencoding utf8 + +let s:viewer = {} + +function! s:viewer.init(data) abort + let self.rows = [] + let self.data = a:data + + let self.prefixes = g:vista_icon_indent + + " TODO improve me! + let up_gap = strwidth(self.prefixes[0]) + " By default the gap is half of the second prefix. + " at least one + if up_gap >= 2 && up_gap < 4 + let self.gap = up_gap + elseif up_gap >= 4 + let self.gap = up_gap / 2 + else + let self.gap = up_gap + strwidth(self.prefixes[1])/2 + endif +endfunction + +function! s:ContainWhitespaceOnly(str) abort + return a:str !~# '\S' +endfunction + +function! s:Compare(i1, i2) abort + return a:i1.text > a:i2.text +endfunction + +function! s:viewer.render() abort + let try_adjust = self.prefixes[0] != self.prefixes[1] + + " prefixes[0] scope [children_num] + " prefixes[1] tag:num + for [kind, v] in items(self.data) + let parent = self.prefixes[0] .vista#renderer#Decorate(kind).' ['.len(v).']' + " Parent + call add(self.rows, parent) + + if !empty(v) + + if get(g:vista, 'sort', v:false) + let v = sort(copy(v), function('s:Compare')) + endif + + " Children + for i in v + if len(i) > 0 + let row = vista#util#Join( + \ repeat(' ', self.gap), + \ self.prefixes[1], + \ i.text, + \ ':'.i.lnum + \ ) + call add(self.rows, row) + endif + endfor + + if !s:ContainWhitespaceOnly(self.prefixes[1]) && try_adjust + " Adjust the prefix of last item in each scope + let tag_colon_num = split(self.rows[-1], ' ')[1:] + let self.rows[-1] = repeat(' ', self.gap) + \ .self.prefixes[0] + \ .join(tag_colon_num, ' ') + endif + endif + + call add(self.rows, '') + endfor + + " Remove the needless last empty line + unlet self.rows[-1] + + return self.rows +endfunction + +function! vista#renderer#kind#Render(data) abort + if empty(a:data) + return [] + endif + call s:viewer.init(a:data) + return s:viewer.render() +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/line.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/line.vim new file mode 100644 index 0000000..0870fef --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/line.vim @@ -0,0 +1,64 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:scope_icon = ['⊕', '⊖'] + +let s:visibility_icon = { + \ 'public': '+', + \ 'protected': '#', + \ 'private': '-', + \ } + +function! s:RenderLinewise() abort + let rows = [] + + " FIXME the same kind tags could be in serveral sections + let idx = 0 + let raw_len = len(g:vista.raw) + + while idx < raw_len + let line = g:vista.raw[idx] + + if has_key(line, 'access') + let access = get(s:visibility_icon, line.access, '?') + else + let access = '' + endif + + if !exists('s:last_kind') || has_key(line, 'kind') && s:last_kind != line.kind + call add(rows, vista#renderer#Decorate(line.kind)) + let s:last_kind = get(line, 'kind') + continue + endif + + let row = vista#util#Join(' '.access, get(line, 'name'), get(line, 'signature', ''), ':'.line.line) + + call add(rows, row) + + " Inject vlnum. + " Since we prepend the fpath and a blank line, the vlnum should plus 2. + let line.vlnum = len(rows) + 2 + + " Append a blank line in the last of a section. + if has_key(line, 'kind') && idx < raw_len - 1 + if line.kind != get(g:vista.raw[idx+1], 'kind') + call add(rows, '') + endif + endif + + let idx += 1 + endwhile + + unlet s:last_kind + + return rows +endfunction + +function! vista#renderer#line#Render() abort + if empty(g:vista.raw) + return [] + endif + + return s:RenderLinewise() +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/markdown_like.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/markdown_like.vim new file mode 100644 index 0000000..ad49ada --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/renderer/markdown_like.vim @@ -0,0 +1,52 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +scriptencoding utf-8 + +function! s:Join(line, icon) abort + let line = a:line + + let text = line.text + let lnum = line.lnum + let level = line.level + let row = repeat(' ', 2 * (level - 1)).a:icon.text.' H'.level.':'.lnum + + return row +endfunction + +function! s:BuildRow(idx, line) abort + if a:idx+1 == len(s:data) || s:data[a:idx+1].level != a:line.level + return s:Join(a:line, g:vista_icon_indent[0]) + else + return s:Join(a:line, g:vista_icon_indent[1]) + endif +endfunction + +" Given the metadata of headers of markdown, return the rendered lines to display. +" +" line.lnum is 1-based. +" +" The metadata of markdown headers is a List of Dict: +" {'lnum': 1, 'level': '4', 'text': 'Vista.vim'} +function! s:MD(idx, line) abort + return s:BuildRow(a:idx, a:line) +endfunction + +" The metadata of rst headers is a List of Dict: +" {'lnum': 1, 'level': '4', 'text': 'Vista.vim'} +function! s:RST(idx, line) abort + return s:BuildRow(a:idx, a:line) +endfunction + +" markdown +function! vista#renderer#markdown_like#MD(data) abort + let s:data = a:data + return map(a:data, 's:MD(v:key, v:val)') +endfunction + +" restructuredText +function! vista#renderer#markdown_like#RST(data) abort + let s:data = a:data + return map(a:data, 's:RST(v:key, v:val)') +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/sidebar.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/sidebar.vim new file mode 100644 index 0000000..9737df0 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/sidebar.vim @@ -0,0 +1,155 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" Which filetype the current sidebar should be. +function! vista#sidebar#WhichFileType() abort + if g:vista.provider ==# 'coc' + \ || (g:vista.provider ==# 'ctags' && g:vista#renderer#ctags ==# 'default') + return 'vista' + elseif g:vista.provider ==# 'markdown' + return 'vista_markdown' + else + return 'vista_kind' + endif +endfunction + +function! s:NewWindow() abort + if exists('g:vista_sidebar_open_cmd') + let open = g:vista_sidebar_open_cmd + else + let open = g:vista_sidebar_position.' '.g:vista_sidebar_width.'new' + endif + + if get(g:, 'vista_sidebar_keepalt', 0) + silent execute 'keepalt '.open '__vista__' + else + silent execute open '__vista__' + endif + + execute 'setlocal filetype='.vista#sidebar#WhichFileType() + + " FIXME when to delete? + if has_key(g:vista.source, 'fpath') + let w:vista_first_line_hi_id = matchaddpos('MoreMsg', [1]) + endif +endfunction + +" Reload vista buffer given the unrendered data +function! vista#sidebar#Reload(data) abort + " empty(a:data): + " May be triggered by autocmd event sometimes + " e.g., unsupported filetypes for ctags or no related language servers. + " + " !has_key(g:vista, 'bufnr'): + " May opening a new tab if bufnr does not exist in g:vista. + " + " g:vista.winnr() == -1: + " vista window is not visible. + if empty(a:data) + \ || !has_key(g:vista, 'bufnr') + \ || g:vista.winnr() == -1 + return + endif + + let rendered = vista#renderer#Render(a:data) + call vista#util#SetBufline(g:vista.bufnr, rendered) +endfunction + +" Open or update vista buffer given the rendered rows. +function! vista#sidebar#OpenOrUpdate(rows) abort + " (Re)open a window and move to it + if !exists('g:vista.bufnr') + call s:NewWindow() + let g:vista = get(g:, 'vista', {}) + let g:vista.bufnr = bufnr('%') + let g:vista.winid = win_getid() + let g:vista.pos = [winsaveview(), winnr(), winrestcmd()] + else + let winnr = g:vista.winnr() + if winnr == -1 + call s:NewWindow() + elseif winnr() != winnr + noautocmd execute winnr.'wincmd w' + endif + endif + + call vista#util#SetBufline(g:vista.bufnr, a:rows) + + if has_key(g:vista, 'lnum') + call vista#cursor#ShowTagFor(g:vista.lnum) + unlet g:vista.lnum + endif + + if !g:vista_stay_on_open + wincmd p + endif +endfunction + +function! vista#sidebar#Close() abort + if exists('g:vista.bufnr') + let winnr = g:vista.winnr() + + " Jump back to the previous window if we are in the vista sidebar atm. + if winnr == winnr() + wincmd p + endif + + if winnr != -1 + noautocmd execute winnr.'wincmd c' + endif + + silent execute g:vista.bufnr.'bwipe!' + unlet g:vista.bufnr + endif + + call s:ClearAugroups('VistaCoc', 'VistaCtags') + + call vista#win#CloseFloating() +endfunction + +function! s:ClearAugroups(...) abort + for aug in a:000 + if exists('#'.aug) + execute 'autocmd!' aug + endif + endfor +endfunction + +function! vista#sidebar#Open() abort + let [bufnr, winnr, fname, fpath] = [bufnr('%'), winnr(), expand('%'), expand('%:p')] + call vista#source#Update(bufnr, winnr, fname, fpath) + + " Support the builtin markdown toc extension as an executive + if vista#toc#IsSupported(&filetype) + call vista#toc#Run() + else + let executive = vista#GetExplicitExecutiveOrDefault() + call vista#executive#{executive}#Execute(v:false, v:true, v:false) + endif +endfunction + +function! vista#sidebar#IsOpen() abort + return bufwinnr('__vista__') != -1 +endfunction + +function! vista#sidebar#ToggleFocus() abort + if !exists('g:vista') || g:vista.winnr() == -1 + call vista#sidebar#Open() + return + endif + let winnr = g:vista.winnr() + if winnr != winnr() + execute winnr.'wincmd w' + else + execute g:vista.source.get_winnr().'wincmd w' + endif +endfunction + +function! vista#sidebar#Toggle() abort + if vista#sidebar#IsOpen() + call vista#sidebar#Close() + else + call vista#sidebar#Open() + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/source.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/source.vim new file mode 100644 index 0000000..c421ddb --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/source.vim @@ -0,0 +1,70 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +if exists('*bufwinid') + function! s:GotoSourceWindow() abort + let winid = g:vista.source.get_winid() + if winid != -1 + if win_getid() != winid + " No use noautocmd here. Ref #362 + call win_gotoid(winid) + endif + else + return vista#error#('Cannot find the source window id') + endif + endfunction +else + function! s:GotoSourceWindow() abort + " g:vista.source.winnr is not always correct. + let winnr = g:vista.source.get_winnr() + if winnr != -1 + execute winnr.'wincmd w' + else + return vista#error#('Cannot find the target window') + endif + endfunction +endif + +function! vista#source#GotoWin() abort + call s:GotoSourceWindow() + + " Floating window relys on BufEnter event to be closed automatically. + if exists('#VistaFloatingWin') + doautocmd BufEnter VistaFloatingWin + endif +endfunction + +" Update the infomation of source file to be processed, +" including whose bufnr, winnr, fname, fpath +function! vista#source#Update(bufnr, winnr, ...) abort + if !exists('g:vista') + call vista#init#Api() + endif + + let g:vista.source.bufnr = a:bufnr + let g:vista.source.winnr = a:winnr + + if a:0 == 1 + let g:vista.source.fname = a:1 + elseif a:0 == 2 + let g:vista.source.fname = a:1 + let g:vista.source.fpath = a:2 + endif +endfunction + +function! s:ApplyPeek(lnum, tag) abort + silent execute 'normal!' a:lnum.'z.' + let [_, start, _] = matchstrpos(getline('.'), a:tag) + call vista#util#Blink(1, 100, [a:lnum, start+1, strlen(a:tag)]) +endfunction + +if exists('*win_execute') + function! vista#source#PeekSymbol(lnum, tag) abort + call win_execute(g:vista.source.winid, 'noautocmd call s:ApplyPeek(a:lnum, a:tag)') + endfunction +else + function! vista#source#PeekSymbol(lnum, tag) abort + call vista#win#Execute(g:vista.source.get_winnr(), function('s:ApplyPeek'), a:lnum, a:tag) + endfunction +endif diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/statusline.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/statusline.vim new file mode 100644 index 0000000..cc2789b --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/statusline.vim @@ -0,0 +1,35 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +function! vista#statusline#ShouldDisable() abort + return g:vista_disable_statusline +endfunction + +function! vista#statusline#Render() abort + if vista#statusline#ShouldDisable() + return + endif + + if has_key(g:vista, 'bufnr') + call setbufvar(g:vista.bufnr, '&statusline', vista#statusline#()) + endif +endfunction + +function! vista#statusline#RenderOnWinEvent() abort + if !exists('g:vista') || vista#statusline#ShouldDisable() + return + endif + + let &l:statusline = vista#statusline#() +endfunction + +function! vista#statusline#() abort + let fname = get(g:vista.source, 'fname', '') + let provider = get(g:vista, 'provider', '') + if !empty(provider) + return '[Vista] '.provider.' %<'.fname + else + return '[Vista] %<'.fname + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/toc.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/toc.vim new file mode 100644 index 0000000..5be0b70 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/toc.vim @@ -0,0 +1,46 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +" vimwiki supports the standard markdown syntax. +" pandoc supports the basic markdown format. +" API Blueprint is a set of semantic assumptions on top of markdown. +let s:toc_supported = ['markdown', 'rst', 'vimwiki', 'pandoc', 'apiblueprint', 'pandoc.markdown', 'markdown.pandoc'] + +" These filestypes all can use the markdown extension. +let s:markdown_common = ['markdown', 'vimwiki', 'pandoc', 'apiblueprint', 'pandoc.markdown', 'markdown.pandoc'] + +function! vista#toc#IsSupported(filetype) abort + return index(s:toc_supported, a:filetype) > -1 +endfunction + +function! s:TryRunExtension(...) abort + if a:0 > 0 + let extension = a:1 + elseif index(s:markdown_common, &filetype) > -1 + let extension = 'markdown' + else + let extension = &filetype + endif + if index(g:vista#extensions, extension) > -1 + call vista#extension#{extension}#Execute(v:false, v:true) + else + call vista#error#('Cannot find vista extension: '.extension) + endif +endfunction + +" toc is the synonym of markdown like extensions. +function! vista#toc#Run() abort + let explicit_executive = vista#GetExplicitExecutive(&filetype) + if explicit_executive isnot v:null + if index(s:markdown_common, explicit_executive) > -1 + call s:TryRunExtension('markdown') + elseif explicit_executive !=# 'toc' + call vista#executive#{explicit_executive}#Execute(v:false, v:true, v:false) + else + call s:TryRunExtension() + endif + else + call s:TryRunExtension() + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags.vim new file mode 100644 index 0000000..9ecc4c8 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags.vim @@ -0,0 +1,56 @@ +let s:language_opt = { + \ 'ant' : ['ant' , 'pt'] , + \ 'asm' : ['asm' , 'dlmt'] , + \ 'aspperl' : ['asp' , 'fsv'] , + \ 'aspvbs' : ['asp' , 'fsv'] , + \ 'awk' : ['awk' , 'f'] , + \ 'beta' : ['beta' , 'fsv'] , + \ 'c' : ['c' , 'dgsutvf'] , + \ 'cpp' : ['c++' , 'nvdtcgsuf'] , + \ 'cs' : ['c#' , 'dtncEgsipm'] , + \ 'cobol' : ['cobol' , 'dfgpPs'] , + \ 'delphi' : ['pascal' , 'fp'] , + \ 'dosbatch' : ['dosbatch' , 'lv'] , + \ 'eiffel' : ['eiffel' , 'cf'] , + \ 'erlang' : ['erlang' , 'drmf'] , + \ 'expect' : ['tcl' , 'cfp'] , + \ 'fortran' : ['fortran' , 'pbceiklmntvfs'] , + \ 'go' : ['go' , 'fctv'] , + \ 'html' : ['html' , 'af'] , + \ 'java' : ['java' , 'pcifm'] , + \ 'javascript' : ['javascript' , 'f'] , + \ 'lisp' : ['lisp' , 'f'] , + \ 'lua' : ['lua' , 'f'] , + \ 'make' : ['make' , 'm'] , + \ 'matlab' : ['matlab' , 'f'] , + \ 'ocaml' : ['ocaml' , 'cmMvtfCre'] , + \ 'pascal' : ['pascal' , 'fp'] , + \ 'perl' : ['perl' , 'clps'] , + \ 'php' : ['php' , 'cdvf'] , + \ 'python' : ['python' , 'cmf'] , + \ 'rexx' : ['rexx' , 's'] , + \ 'ruby' : ['ruby' , 'cfFm'] , + \ 'rust' : ['rust' , 'fgsmcti'] , + \ 'scheme' : ['scheme' , 'sf'] , + \ 'sh' : ['sh' , 'f'] , + \ 'csh' : ['sh' , 'f'] , + \ 'zsh' : ['sh' , 'f'] , + \ 'scala' : ['scala' , 'ctTmlp'] , + \ 'slang' : ['slang' , 'nf'] , + \ 'sml' : ['sml' , 'ecsrtvf'] , + \ 'sql' : ['sql' , 'cFPrstTvfp'] , + \ 'tex' : ['tex' , 'ipcsubPGl'] , + \ 'tcl' : ['tcl' , 'cfmp'] , + \ 'vera' : ['vera' , 'cdefgmpPtTvx'] , + \ 'verilog' : ['verilog' , 'mcPertwpvf'] , + \ 'vhdl' : ['vhdl' , 'PctTrefp'] , + \ 'vim' : ['vim' , 'avf'] , + \ 'yacc' : ['yacc' , 'l'] , + \ } + +let s:language_opt = map(s:language_opt, + \ 'printf(''--language-force=%s --%s-types=%s'', v:val[0], v:val[0], v:val[1])') + +function! vista#types#uctags#KindsFor(filetype) abort + return get(s:language_opt, a:filetype, '') +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ada.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ada.vim new file mode 100644 index 0000000..0000141 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ada.vim @@ -0,0 +1,40 @@ +" Ada +let s:types = {} + +let s:types.lang = 'ada' + +let s:types.kinds = { + \ 'P': {'long' : 'package specifications', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'packages', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ 'u': {'long' : 'subtypes', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'record type components', 'fold' : 0, 'stl' : 1}, + \ 'l': {'long' : 'enum type literals', 'fold' : 0, 'stl' : 0}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'generic formal parameters', 'fold' : 0, 'stl' : 0}, + \ 'n': {'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ 'x': {'long' : 'user defined exceptions', 'fold' : 0, 'stl' : 1}, + \ 'R': {'long' : 'subprogram specifications', 'fold' : 0, 'stl' : 1}, + \ 'r': {'long' : 'subprograms', 'fold' : 0, 'stl' : 1}, + \ 'K': {'long' : 'task specifications', 'fold' : 0, 'stl' : 1}, + \ 'k': {'long' : 'tasks', 'fold' : 0, 'stl' : 1}, + \ 'O': {'long' : 'protected data specifications', 'fold' : 0, 'stl' : 1}, + \ 'o': {'long' : 'protected data', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'task/protected data entries', 'fold' : 0, 'stl' : 1}, + \ 'b': {'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'loop/declare identifiers', 'fold' : 0, 'stl' : 1}, + \ } + +let s:types.sro = '.' " Not sure if possible + +let s:types.kind2scope = { + \ 'P' : 'packspec', + \ 't' : 'type', + \ } + +let s:types.scope2kind = { + \ 'packspec' : 'P', + \ 'type' : 't', + \ } + +let g:vista#types#uctags#ada# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ant.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ant.vim new file mode 100644 index 0000000..0dc2815 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ant.vim @@ -0,0 +1,13 @@ +" Ant {{{1 +let s:types = {} + +let s:types.lang = 'ant' + +let s:types.kinds = { + \ 'p': {'long' : 'projects', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'antfiles', 'fold' : 0, 'stl' : 0}, + \ 'P': {'long' : 'properties', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'targets', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#ant# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/asm.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/asm.vim new file mode 100644 index 0000000..c9b80e1 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/asm.vim @@ -0,0 +1,14 @@ +" Asm {{{1 +let s:types = {} + +let s:types.lang = 'asm' + +let s:types.kinds = { + \ 'm': {'long' : 'macros', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'sections', 'fold' : 0, 'stl' : 1}, + \ 'd': {'long' : 'defines', 'fold' : 0, 'stl' : 1}, + \ 'l': {'long' : 'labels', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#asm# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/aspvbs.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/aspvbs.vim new file mode 100644 index 0000000..abbe2d6 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/aspvbs.vim @@ -0,0 +1,15 @@ +" ASP {{{1 +let s:types = {} + +let s:types.lang = 'asp' + +let s:types.kinds = { + \ 'd': {'long' : 'constants', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'subroutines', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 1} + \ } + +" aspperl aspvbs +let g:vista#types#uctags#aspvbs# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/asy.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/asy.vim new file mode 100644 index 0000000..3140863 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/asy.vim @@ -0,0 +1,34 @@ +" Asymptote {{{1 +" Asymptote gets parsed well using filetype = c +let s:types = {} + +let s:types.lang = 'c' + +let s:types.kinds = { + \ 'd': {'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ 'p': {'long' : 'prototypes', 'fold' : 1, 'stl' : 0}, + \ 'g': {'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'typedefs', 'fold' : 0, 'stl' : 0}, + \ 's': {'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ 'u': {'long' : 'unions', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'members', 'fold' : 0, 'stl' : 0}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '::' + +let s:types.kind2scope = { + \ 'g' : 'enum', + \ 's' : 'struct', + \ 'u' : 'union' + \ } + +let s:types.scope2kind = { + \ 'enum' : 'g', + \ 'struct' : 's', + \ 'union' : 'u' + \ } + +let g:vista#types#uctags#asy# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/automake.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/automake.vim new file mode 100644 index 0000000..2d31712 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/automake.vim @@ -0,0 +1,20 @@ +" Automake {{{1 +let s:types = {} + +let s:types.lang = 'automake' + +let s:types.kinds = { + \ 'I': {'long' : 'makefiles', 'fold' : 0, 'stl' : 1}, + \ 'd': {'long' : 'directories', 'fold' : 0, 'stl' : 1}, + \ 'P': {'long' : 'programs', 'fold' : 0, 'stl' : 1}, + \ 'M': {'long' : 'manuals', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'macros', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'targets', 'fold' : 0, 'stl' : 1}, + \ 'T': {'long' : 'ltlibraries', 'fold' : 0, 'stl' : 1}, + \ 'L': {'long' : 'libraries', 'fold' : 0, 'stl' : 1}, + \ 'S': {'long' : 'scripts', 'fold' : 0, 'stl' : 1}, + \ 'D': {'long' : 'datum', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'conditions', 'fold' : 0, 'stl' : 1}, + \ } + +let g:vista#types#uctags#automake# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/awk.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/awk.vim new file mode 100644 index 0000000..3eb1334 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/awk.vim @@ -0,0 +1,10 @@ +" Awk {{{1 +let s:types = {} + +let s:types.lang = 'awk' + +let s:types.kinds = { + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#awk# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/basic.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/basic.vim new file mode 100644 index 0000000..47daac8 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/basic.vim @@ -0,0 +1,15 @@ +" Basic {{{1 +let s:types = {} + +let s:types.lang = 'basic' + +let s:types.kinds = { + \ 'c': {'long' : 'constants', 'fold' : 0, 'stl' : 1}, + \ 'g': {'long' : 'enumerations', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'l': {'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#basic# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/beta.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/beta.vim new file mode 100644 index 0000000..b38ca95 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/beta.vim @@ -0,0 +1,12 @@ +" BETA {{{1 +let s:types = {} + +let s:types.lang = 'beta' + +let s:types.kinds = { + \ 'f': {'long' : 'fragments', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'slots', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'patterns', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#beta# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/c.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/c.vim new file mode 100644 index 0000000..5d4f1d3 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/c.vim @@ -0,0 +1,34 @@ +" C {{{1 +let s:types = {} + +let s:types.lang = 'c' + +let s:types.kinds = { + \ 'h': {'long' : 'header files', 'fold' : 1, 'stl' : 0}, + \ 'd': {'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ 'p': {'long' : 'prototypes', 'fold' : 1, 'stl' : 0}, + \ 'g': {'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'typedefs', 'fold' : 0, 'stl' : 0}, + \ 's': {'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ 'u': {'long' : 'unions', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'members', 'fold' : 0, 'stl' : 0}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '::' + +let s:types.kind2scope = { + \ 'g' : 'enum', + \ 's' : 'struct', + \ 'u' : 'union' + \ } + +let s:types.scope2kind = { + \ 'enum' : 'g', + \ 'struct' : 's', + \ 'union' : 'u' + \ } + +let g:vista#types#uctags#c# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/clojure.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/clojure.vim new file mode 100644 index 0000000..8d9ad1a --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/clojure.vim @@ -0,0 +1,21 @@ +" Clojure {{{1 +let s:types = {} + +let s:types.lang = 'clojure' + +let s:types.kinds = { + \ 'n': {'long': 'namespace', 'fold': 0, 'stl': 1}, + \ 'f': {'long': 'function', 'fold': 0, 'stl': 1}, + \ } + +let s:types.sro = '.' + +let s:types.kind2scope = { + \ 'n' : 'namespace', + \ } + +let s:types.scope2kind = { + \ 'namespace' : 'n' + \ } + +let g:vista#types#uctags#clojure# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cobol.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cobol.vim new file mode 100644 index 0000000..b672142 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cobol.vim @@ -0,0 +1,17 @@ +" COBOL {{{1 +let s:types = {} + +let s:types.lang = 'cobol' + +let s:types.kinds = { + \ 'd': {'long' : 'data items', 'fold' : 0, 'stl' : 1}, + \ 'D': {'long' : 'divisions', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'file descriptions', 'fold' : 0, 'stl' : 1}, + \ 'g': {'long' : 'group items', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'paragraphs', 'fold' : 0, 'stl' : 1}, + \ 'P': {'long' : 'program ids', 'fold' : 0, 'stl' : 1}, + \ 'S': {'long' : 'source code file', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'sections', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#cobol# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/config.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/config.vim new file mode 100644 index 0000000..dcf9b63 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/config.vim @@ -0,0 +1,17 @@ +" Autoconf {{{1 +let s:types = {} + +let s:types.lang = 'autoconf' + +let s:types.kinds = { + \ 'p': {'long': 'packages', 'fold': 0, 'stl': 1}, + \ 't': {'long': 'templates', 'fold': 0, 'stl': 1}, + \ 'm': {'long': 'autoconf macros', 'fold': 0, 'stl': 1}, + \ 'w': {'long': '"with" options', 'fold': 0, 'stl': 1}, + \ 'e': {'long': '"enable" options', 'fold': 0, 'stl': 1}, + \ 's': {'long': 'substitution keys', 'fold': 0, 'stl': 1}, + \ 'c': {'long': 'automake conditions', 'fold': 0, 'stl': 1}, + \ 'd': {'long': 'definitions', 'fold': 0, 'stl': 1} + \ } + +let g:vista#types#uctags#config# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cpp.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cpp.vim new file mode 100644 index 0000000..6226dd0 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cpp.vim @@ -0,0 +1,42 @@ + +" C++ {{{1 +let s:types = {} + +let s:types.lang = 'c++' + +let s:types.kinds = { + \ 'h': {'long' : 'header files', 'fold' : 1, 'stl' : 0}, + \ 'd': {'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ 'p': {'long' : 'prototypes', 'fold' : 1, 'stl' : 0}, + \ 'g': {'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'typedefs', 'fold' : 0, 'stl' : 0}, + \ 'n': {'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ 'u': {'long' : 'unions', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'members', 'fold' : 0, 'stl' : 0}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0} + \ } + +let s:types.sro = '::' + +let s:types.kind2scope = { + \ 'g' : 'enum', + \ 'n' : 'namespace', + \ 'c' : 'class', + \ 's' : 'struct', + \ 'u' : 'union' + \ } + +let s:types.scope2kind = { + \ 'enum' : 'g', + \ 'namespace' : 'n', + \ 'class' : 'c', + \ 'struct' : 's', + \ 'union' : 'u' + \ } + +" cpp cuda +let g:vista#types#uctags#cpp# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cs.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cs.vim new file mode 100644 index 0000000..5fb648d --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/cs.vim @@ -0,0 +1,40 @@ + +" C# {{{1 +let s:types = {} + +let s:types.lang = 'c#' + +let s:types.kinds = { + \ 'd': {'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ 'f': {'long' : 'fields', 'fold' : 0, 'stl' : 1}, + \ 'g': {'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'typedefs', 'fold' : 0, 'stl' : 1}, + \ 'n': {'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ 'E': {'long' : 'events', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'properties', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '.' + +let s:types.kind2scope = { + \ 'n' : 'namespace', + \ 'i' : 'interface', + \ 'c' : 'class', + \ 's' : 'struct', + \ 'g' : 'enum' + \ } + +let s:types.scope2kind = { + \ 'namespace' : 'n', + \ 'interface' : 'i', + \ 'class' : 'c', + \ 'struct' : 's', + \ 'enum' : 'g' + \ } + +let g:vista#types#uctags#cs# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/css.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/css.vim new file mode 100644 index 0000000..4b7775e --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/css.vim @@ -0,0 +1,13 @@ + +" CSS {{{1 +let s:types = {} + +let s:types.lang = 'css' + +let s:types.kinds = { + \ 's': {'long' : 'selector', 'fold' : 0, 'stl' : 0}, + \ 'i': {'long' : 'identities', 'fold' : 1, 'stl' : 0}, + \ 'c': {'long' : 'classes', 'fold' : 1, 'stl' : 0} + \ } + +let g:vista#types#uctags#css# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ctags.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ctags.vim new file mode 100644 index 0000000..d4eb98c --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ctags.vim @@ -0,0 +1,22 @@ + +" Ctags config {{{1 +let s:types = {} + +let s:types.lang = 'ctags' + +let s:types.kinds = { + \ 'l': {'long' : 'language definitions', 'fold' : 0, 'stl' : 1}, + \ 'k': {'long' : 'kind definitions', 'fold' : 0, 'stl' : 1}, + \ } + +let s:types.sro = '.' " Not actually possible + +let s:types.kind2scope = { + \ 'l' : 'langdef', + \ } + +let s:types.scope2kind = { + \ 'langdef' : 'l', + \ } + +let g:vista#types#uctags#ctags# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/d.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/d.vim new file mode 100644 index 0000000..680eedd --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/d.vim @@ -0,0 +1,46 @@ + +" D {{{1 +let s:types = {} + +let s:types.lang = 'D' + +let s:types.kinds = { + \ 'M': {'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ 'V': {'long' : 'version statements', 'fold' : 1, 'stl' : 0}, + \ 'n': {'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ 'T': {'long' : 'templates', 'fold' : 0, 'stl' : 0}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'structure names', 'fold' : 0, 'stl' : 1}, + \ 'g': {'long' : 'enumeration names', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ 'u': {'long' : 'union names', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'function prototypes', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'function definitions', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'members', 'fold' : 0, 'stl' : 1}, + \ 'a': {'long' : 'aliases', 'fold' : 1, 'stl' : 0}, + \ 'X': {'long' : 'mixins', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variable definitions', 'fold' : 0, 'stl' : 0}, + \ } + +let s:types.sro = '.' + +let s:types.kind2scope = { + \ 'g' : 'enum', + \ 'n' : 'namespace', + \ 'i' : 'interface', + \ 'c' : 'class', + \ 's' : 'struct', + \ 'u' : 'union' + \ } + +let s:types.scope2kind = { + \ 'enum' : 'g', + \ 'namespace' : 'n', + \ 'interface' : 'i', + \ 'class' : 'c', + \ 'struct' : 's', + \ 'union' : 'u' + \ } + +let g:vista#types#uctags#d# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/dosbatch.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/dosbatch.vim new file mode 100644 index 0000000..c2d4c5b --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/dosbatch.vim @@ -0,0 +1,12 @@ + +" DOS Batch {{{1 +let s:types = {} + +let s:types.lang = 'dosbatch' + +let s:types.kinds = { + \ 'l': {'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#dosbatch# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/eiffel.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/eiffel.vim new file mode 100644 index 0000000..2a4e78d --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/eiffel.vim @@ -0,0 +1,24 @@ + +" Eiffel {{{1 +let s:types = {} + +let s:types.lang = 'eiffel' + +let s:types.kinds = { + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'features', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '.' " Not sure, is nesting even possible? + +let s:types.kind2scope = { + \ 'c' : 'class', + \ 'f' : 'feature' + \ } + +let s:types.scope2kind = { + \ 'class' : 'c', + \ 'feature' : 'f' + \ } + +let g:vista#types#uctags#eiffel# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/elm.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/elm.vim new file mode 100644 index 0000000..3c391af --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/elm.vim @@ -0,0 +1,32 @@ + +" Elm {{{1 +" based on https://github.com/bitterjug/vim-tagbar-ctags-elm/blob/master/ftplugin/elm/tagbar-elm.vim +let s:types = {} + +let s:types.lang = 'elm' + +let s:types.kinds = { + \ 'm': {'long' : 'modules', 'fold' : 0, 'stl' : 0}, + \ 'i': {'long' : 'imports', 'fold' : 1, 'stl' : 0}, + \ 't': {'long' : 'types', 'fold' : 1, 'stl' : 0}, + \ 'a': {'long' : 'type aliases', 'fold' : 0, 'stl' : 0}, + \ 'c': {'long' : 'type constructors', 'fold' : 0, 'stl' : 0}, + \ 'p': {'long' : 'ports', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'functions', 'fold' : 1, 'stl' : 0}, + \ } + +let s:types.sro = ':' + +let s:types.kind2scope = { + \ 'f' : 'function', + \ 'm' : 'module', + \ 't' : 'type' + \ } + +let s:types.scope2kind = { + \ 'function' : 'f', + \ 'module' : 'm', + \ 'type' : 't' + \ } + +let g:vista#types#uctags#elm# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/erlang.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/erlang.vim new file mode 100644 index 0000000..ef2e1c8 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/erlang.vim @@ -0,0 +1,25 @@ + +" Erlang {{{1 +let s:types = {} + +let s:types.lang = 'erlang' + +let s:types.kinds = { + \ 'm': {'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ 'd': {'long' : 'macro definitions', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'r': {'long' : 'record definitions', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'type definitions', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '.' " Not sure, is nesting even possible? + +let s:types.kind2scope = { + \ 'm' : 'module' + \ } + +let s:types.scope2kind = { + \ 'module' : 'm' + \ } + +let g:vista#types#uctags#erlang# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/fortran.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/fortran.vim new file mode 100644 index 0000000..8c3381b --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/fortran.vim @@ -0,0 +1,41 @@ + +" Fortran {{{1 +let s:types = {} + +let s:types.lang = 'fortran' + +let s:types.kinds = { + \ 'm': {'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'programs', 'fold' : 0, 'stl' : 1}, + \ 'k': {'long' : 'components', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'derived types and structures', 'fold' : 0,'stl' : 1}, + \ 'c': {'long' : 'common blocks', 'fold' : 0, 'stl' : 1}, + \ 'b': {'long' : 'block data', 'fold' : 0, 'stl' : 0}, + \ 'E': {'long' : 'enumerations', 'fold' : 0, 'stl' : 1}, + \ 'N': {'long' : 'enumeration values', 'fold' : 0, 'stl' : 0}, + \ 'e': {'long' : 'entry points', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'subroutines', 'fold' : 0, 'stl' : 1}, + \ 'M': {'long' : 'type bound procedures', 'fold' : 0,'stl' : 1}, + \ 'l': {'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ 'n': {'long' : 'namelists', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0} + \ } + +let s:types.sro = '.' " Not sure, is nesting even possible? + +let s:types.kind2scope = { + \ 'm' : 'module', + \ 'p' : 'program', + \ 'f' : 'function', + \ 's' : 'subroutine' + \ } + +let s:types.scope2kind = { + \ 'module' : 'm', + \ 'program' : 'p', + \ 'function' : 'f', + \ 'subroutine' : 's' + \ } + +let g:vista#types#uctags#fortran# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/go.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/go.vim new file mode 100644 index 0000000..9e04124 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/go.vim @@ -0,0 +1,30 @@ + +" Go {{{1 +let type_go = {} + +let type_go.lang = 'go' + +let type_go.kinds = { + \ 'p': {'long' : 'packages', 'fold' : 0, 'stl' : 0}, + \ 'i': {'long' : 'imports', 'fold' : 0, 'stl' : 0}, + \ 'n': {'long' : 'interfaces', 'fold' : 0, 'stl' : 0}, + \ 'c': {'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ 's': {'long' : 'structs', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'methods', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ 'w': {'long' : 'struct members', 'fold' : 0, 'stl' : 0} + \ } + +let type_go.sro = '.' + +let type_go.kind2scope = { + \ 's' : 'struct' + \ } + +let type_go.scope2kind = { + \ 'struct' : 's' + \ } + +let g:vista#types#uctags#go# = type_go diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/html.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/html.vim new file mode 100644 index 0000000..4fc2908 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/html.vim @@ -0,0 +1,14 @@ + +" HTML {{{1 +let s:types = {} + +let s:types.lang = 'html' + +let s:types.kinds = { + \ 'a': {'long' : 'named anchors', 'fold' : 0, 'stl' : 1}, + \ 'h': {'long' : 'H1 headings', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'H2 headings', 'fold' : 0, 'stl' : 1}, + \ 'j': {'long' : 'H3 headings', 'fold' : 0, 'stl' : 1}, + \ } + +let g:vista#types#uctags#html# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/java.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/java.vim new file mode 100644 index 0000000..78ce6c8 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/java.vim @@ -0,0 +1,32 @@ + +" Java {{{1 +let s:types = {} + +let s:types.lang = 'java' + +let s:types.kinds = { + \ 'p': {'long' : 'packages', 'fold' : 1, 'stl' : 0}, + \ 'f': {'long' : 'fields', 'fold' : 0, 'stl' : 0}, + \ 'g': {'long' : 'enum types', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enum constants', 'fold' : 0, 'stl' : 0}, + \ 'a': {'long' : 'annotations', 'fold' : 0, 'stl' : 0}, + \ 'i': {'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'methods', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '.' + +let s:types.kind2scope = { + \ 'g' : 'enum', + \ 'i' : 'interface', + \ 'c' : 'class' + \ } + +let s:types.scope2kind = { + \ 'enum' : 'g', + \ 'interface' : 'i', + \ 'class' : 'c' + \ } + +let g:vista#types#uctags#java# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/javascript.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/javascript.vim new file mode 100644 index 0000000..b9591d2 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/javascript.vim @@ -0,0 +1,31 @@ + +" JavaScript {{{1 +let s:types = {} + +let s:types.lang = 'javascript' + +let s:types.kinds = { + \ 'v': {'long': 'global variables', 'fold': 0, 'stl': 0}, + \ 'C': {'long': 'constants', 'fold': 0, 'stl': 0}, + \ 'c': {'long': 'classes', 'fold': 0, 'stl': 1}, + \ 'g': {'long': 'generators', 'fold': 0, 'stl': 0}, + \ 'p': {'long': 'properties', 'fold': 0, 'stl': 0}, + \ 'm': {'long': 'methods', 'fold': 0, 'stl': 1}, + \ 'f': {'long': 'functions', 'fold': 0, 'stl': 1}, + \ } + +let s:types.sro = '.' + +let s:types.kind2scope = { + \ 'c' : 'class', + \ 'f' : 'function', + \ 'm' : 'method', + \ 'p' : 'property', + \ } + +let s:types.scope2kind = { + \ 'class' : 'c', + \ 'function' : 'f', + \ } + +let g:vista#types#uctags#javascript# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/lisp.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/lisp.vim new file mode 100644 index 0000000..92aa6e1 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/lisp.vim @@ -0,0 +1,11 @@ + +" Lisp {{{1 +let s:types = {} + +let s:types.lang = 'lisp' + +let s:types.kinds = { + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#lisp# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/lua.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/lua.vim new file mode 100644 index 0000000..99af557 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/lua.vim @@ -0,0 +1,11 @@ + +" Lua {{{1 +let s:types = {} + +let s:types.lang = 'lua' + +let s:types.kinds = { + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/make.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/make.vim new file mode 100644 index 0000000..389cb40 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/make.vim @@ -0,0 +1,13 @@ + +" Make {{{1 +let s:types = {} + +let s:types.lang = 'make' + +let s:types.kinds = { + \ 'I': {'long' : 'makefiles', 'fold' : 0, 'stl' : 0}, + \ 'm': {'long' : 'macros', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'targets', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#make# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/matlab.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/matlab.vim new file mode 100644 index 0000000..8155725 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/matlab.vim @@ -0,0 +1,12 @@ + +" Matlab {{{1 +let s:types = {} + +let s:types.lang = 'matlab' + +let s:types.kinds = { + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0} + \ } + +let g:vista#types#uctags#matlab# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/mxml.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/mxml.vim new file mode 100644 index 0000000..616afdc --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/mxml.vim @@ -0,0 +1,30 @@ + +" Flex {{{1 +" Vim doesn't support Flex out of the box, this is based on rough +" guesses and probably requires +" http://www.vim.org/scripts/script.php?script_id=2909 +" Improvements welcome! +let s:types = {} + +let s:types.lang = 'flex' + +let s:types.kinds = { + \ 'v': {'long' : 'global variables', 'fold' : 0, 'stl' : 0}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'properties', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'x': {'long' : 'mxtags', 'fold' : 0, 'stl' : 0} + \ } + +let s:types.sro = '.' + +let s:types.kind2scope = { + \ 'c' : 'class' + \ } + +let s:types.scope2kind = { + \ 'class' : 'c' + \ } + +let g:vista#types#uctags#mxml# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/objc.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/objc.vim new file mode 100644 index 0000000..913ec99 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/objc.vim @@ -0,0 +1,39 @@ + +" ObjectiveC {{{1 +let s:types = {} + +let s:types.lang = 'objectivec' + +let s:types.kinds = { + \ 'M': {'long' : 'preprocessor macros', 'fold' : 1, 'stl' : 0}, + \ 't': {'long' : 'type aliases', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'global variables', 'fold' : 0, 'stl' : 0}, + \ 'i': {'long' : 'class interfaces', 'fold' : 0, 'stl' : 1}, + \ 'I': {'long' : 'class implementations', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'class methods', 'fold' : 0, 'stl' : 1}, + \ 'E': {'long' : 'object fields', 'fold' : 0, 'stl' : 0}, + \ 'm': {'long' : 'object methods', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'type structures', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enumerations', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'properties', 'fold' : 0, 'stl' : 0}, + \ 'P': {'long' : 'protocols', 'fold' : 0, 'stl' : 0}, + \ } + +let s:types.sro = ':' + +let s:types.kind2scope = { + \ 'i' : 'interface', + \ 'I' : 'implementation', + \ 's' : 'struct', + \ 'p' : 'protocol', + \ } + +let s:types.scope2kind = { + \ 'interface' : 'i', + \ 'implementation' : 'I', + \ 'struct' : 's', + \ 'protocol' : 'p', + \ } + +let g:vista#types#uctags#objc# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ocaml.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ocaml.vim new file mode 100644 index 0000000..c1ee605 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ocaml.vim @@ -0,0 +1,34 @@ + +" Ocaml {{{1 +let s:types = {} + +let s:types.lang = 'ocaml' + +let s:types.kinds = { + \ 'M': {'long' : 'modules or functors', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'global variables', 'fold' : 0, 'stl' : 0}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'C': {'long' : 'constructors', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'exceptions', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'type names', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'r': {'long' : 'structure fields', 'fold' : 0, 'stl' : 0}, + \ 'p': {'long' : 'signature items', 'fold' : 0, 'stl' : 0} + \ } + +let s:types.sro = '.' " Not sure, is nesting even possible? + +let s:types.kind2scope = { + \ 'M' : 'Module', + \ 'c' : 'class', + \ 't' : 'type' + \ } + +let s:types.scope2kind = { + \ 'Module' : 'M', + \ 'class' : 'c', + \ 'type' : 't' + \ } + +let g:vista#types#uctags#ocaml# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/pascal.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/pascal.vim new file mode 100644 index 0000000..97bd7cb --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/pascal.vim @@ -0,0 +1,12 @@ + +" Pascal {{{1 +let s:types = {} + +let s:types.lang = 'pascal' + +let s:types.kinds = { + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'procedures', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#pascal# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/perl.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/perl.vim new file mode 100644 index 0000000..b0a26ac --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/perl.vim @@ -0,0 +1,15 @@ + +" Perl {{{1 +let s:types = {} + +let s:types.lang = 'perl' + +let s:types.kinds = { + \ 'p': {'long' : 'packages', 'fold' : 1, 'stl' : 0}, + \ 'c': {'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'formats', 'fold' : 0, 'stl' : 0}, + \ 'l': {'long' : 'labels', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'subroutines', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#perl# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/perl6.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/perl6.vim new file mode 100644 index 0000000..cd9331a --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/perl6.vim @@ -0,0 +1,20 @@ + +" Perl 6 {{{1 +let s:types6 = {} + +let s:types6.lang = 'perl6' + +let s:types6.kinds = { + \ 'o': {'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'packages', 'fold' : 1, 'stl' : 0}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'g': {'long' : 'grammars', 'fold' : 0, 'stl' : 0}, + \ 'm': {'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ 'r': {'long' : 'roles', 'fold' : 0, 'stl' : 1}, + \ 'u': {'long' : 'rules', 'fold' : 0, 'stl' : 0}, + \ 'b': {'long' : 'submethods', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'subroutines', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'tokens', 'fold' : 0, 'stl' : 0}, + \ } + +let g:vista#types#uctags#perl6# = s:types6 diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/php.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/php.vim new file mode 100644 index 0000000..7112a2b --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/php.vim @@ -0,0 +1,34 @@ + +" PHP {{{1 +let s:types = {} + +let s:types.lang = 'php' + +let s:types.kinds = { + \ 'n': {'long' : 'namespaces', 'fold' : 0, 'stl' : 0}, + \ 'a': {'long' : 'use aliases', 'fold' : 1, 'stl' : 0}, + \ 'd': {'long' : 'constant definitions', 'fold' : 0, 'stl' : 0}, + \ 'i': {'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'traits', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 1, 'stl' : 0}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '\\' + +let s:types.kind2scope = { + \ 'c' : 'class', + \ 'n' : 'namespace', + \ 'i' : 'interface', + \ 't' : 'trait', + \ } + +let s:types.scope2kind = { + \ 'class' : 'c', + \ 'namespace' : 'n', + \ 'interface' : 'i', + \ 'trait' : 't', + \ } + +let g:vista#types#uctags#php# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/proto.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/proto.vim new file mode 100644 index 0000000..839c3d3 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/proto.vim @@ -0,0 +1,16 @@ + +" Protobuf {{{1 +let s:types = {} + +let s:types.lang = 'Protobuf' + +let s:types.kinds = { + \ 'p': {'long' : 'packages', 'fold' : 0, 'stl' : 0}, + \ 'm': {'long' : 'messages', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'fields', 'fold' : 0, 'stl' : 0}, + \ 'e': {'long' : 'enum constants', 'fold' : 0, 'stl' : 0}, + \ 'g': {'long' : 'enum types', 'fold' : 0, 'stl' : 0}, + \ 's': {'long' : 'services', 'fold' : 0, 'stl' : 0}, + \ } + +let g:vista#types#uctags#proto# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/python.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/python.vim new file mode 100644 index 0000000..372d759 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/python.vim @@ -0,0 +1,28 @@ + +" Python {{{1 +let s:types = {} + +let s:types.lang = 'python' + +let s:types.kinds = { + \ 'i': {'long' : 'modules', 'fold' : 1, 'stl' : 0}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'members', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0} + \ } + +let s:types.sro = '.' +let s:types.kind2scope = { + \ 'c' : 'class', + \ 'f' : 'function', + \ 'm' : 'member' + \ } + +let s:types.scope2kind = { + \ 'class' : 'c', + \ 'function' : 'f', + \ 'member' : 'm' + \ } + +let g:vista#types#uctags#python# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/r.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/r.vim new file mode 100644 index 0000000..fa744f2 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/r.vim @@ -0,0 +1,15 @@ + +" R {{{1 +let s:types = {} + +let s:types.lang = 'R' + +let s:types.kinds = { + \ 'l': {'long' : 'libraries', 'fold' : 1, 'stl' : 0}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'sources', 'fold' : 0, 'stl' : 0}, + \ 'g': {'long' : 'global variables', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'function variables', 'fold' : 0, 'stl' : 0}, + \ } + +let g:vista#types#uctags#r# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/rexx.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/rexx.vim new file mode 100644 index 0000000..dd4f177 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/rexx.vim @@ -0,0 +1,11 @@ + +" REXX {{{1 +let s:types = {} + +let s:types.lang = 'rexx' + +let s:types.kinds = { + \ 's': {'long' : 'subroutines', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#rexx# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ruby.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ruby.vim new file mode 100644 index 0000000..10ffac2 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/ruby.vim @@ -0,0 +1,28 @@ + +" Ruby {{{1 +let s:types = {} + +let s:types.lang = 'ruby' + +let s:types.kinds = { + \ 'm': {'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'methods', 'fold' : 0, 'stl' : 1}, + \ 'S': {'long' : 'singleton methods', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '.' + +let s:types.kind2scope = { + \ 'c' : 'class', + \ 'f' : 'method', + \ 'm' : 'module' + \ } + +let s:types.scope2kind = { + \ 'class' : 'c', + \ 'method' : 'f', + \ 'module' : 'm' + \ } + +let g:vista#types#uctags#ruby# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/rust.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/rust.vim new file mode 100644 index 0000000..62b4cc7 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/rust.vim @@ -0,0 +1,42 @@ +let s:types = {} + +let s:types.lang = 'rust' + +let s:types.kinds = { + \ 'n': {'long' : 'module', 'fold' : 1, 'stl' : 0}, + \ 's': {'long' : 'struct', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'trait', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'implementation', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'function', 'fold' : 0, 'stl' : 1}, + \ 'g': {'long' : 'enum', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'type alias', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'global variable', 'fold' : 0, 'stl' : 1}, + \ 'M': {'long' : 'macro', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'struct field', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enum variant', 'fold' : 0, 'stl' : 1}, + \ 'P': {'long' : 'method', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '::' + +let s:types.kind2scope = { + \ 'n' : 'module', + \ 's' : 'struct', + \ 'i' : 'interface', + \ 'c' : 'implementation', + \ 'f' : 'function', + \ 'g' : 'enum', + \ 'P' : 'method', + \ } + +let s:types.scope2kind = { + \ 'module' : 'n', + \ 'struct' : 's', + \ 'interface' : 'i', + \ 'implementation': 'c', + \ 'function' : 'f', + \ 'enum' : 'g', + \ 'method' : 'P', + \ } + +let g:vista#types#uctags#rust# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/scheme.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/scheme.vim new file mode 100644 index 0000000..9a4d58a --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/scheme.vim @@ -0,0 +1,13 @@ + +" scheme {{{1 +let s:types = {} + +let s:types.lang = 'scheme' + +let s:types.kinds = { + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'sets', 'fold' : 0, 'stl' : 1} + \ } + +" scheme racket +let g:vista#types#uctags#scheme# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sh.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sh.vim new file mode 100644 index 0000000..ccb779f --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sh.vim @@ -0,0 +1,14 @@ + +" Shell script {{{1 +let s:types = {} + +let s:types.lang = 'sh' + +let s:types.kinds = { + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'a': {'long' : 'aliases', 'fold' : 0, 'stl' : 0}, + \ 's': {'long' : 'script files', 'fold' : 0, 'stl' : 0} + \ } + +" sh csh zsh +let g:vista#types#uctags#sh# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/slang.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/slang.vim new file mode 100644 index 0000000..f0d3b0b --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/slang.vim @@ -0,0 +1,12 @@ + +" SLang {{{1 +let s:types = {} + +let s:types.lang = 'slang' + +let s:types.kinds = { + \ 'n': {'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#slang# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sml.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sml.vim new file mode 100644 index 0000000..a25691c --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sml.vim @@ -0,0 +1,17 @@ + +" SML {{{1 +let s:types = {} + +let s:types.lang = 'sml' + +let s:types.kinds = { + \ 'e': {'long' : 'exception declarations', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'function definitions', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'functor definitions', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'signature declarations', 'fold' : 0, 'stl' : 0}, + \ 'r': {'long' : 'structure declarations', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'type definitions', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'value bindings', 'fold' : 0, 'stl' : 0} + \ } + +let g:vista#types#uctags#sml# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sql.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sql.vim new file mode 100644 index 0000000..98229cd --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/sql.vim @@ -0,0 +1,34 @@ + +" SQL {{{1 +" The SQL ctags parser seems to be buggy for me, so this just uses the +" normal kinds even though scopes should be available. Improvements +" welcome! +let s:types = {} + +let s:types.lang = 'sql' + +let s:types.kinds = { + \ 'P': {'long' : 'packages', 'fold' : 1, 'stl' : 1}, + \ 'd': {'long' : 'prototypes', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'cursors', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'E': {'long' : 'record fields', 'fold' : 0, 'stl' : 1}, + \ 'L': {'long' : 'block label', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'procedures', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'subtypes', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'tables', 'fold' : 0, 'stl' : 1}, + \ 'T': {'long' : 'triggers', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'indexes', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'events', 'fold' : 0, 'stl' : 1}, + \ 'U': {'long' : 'publications', 'fold' : 0, 'stl' : 1}, + \ 'R': {'long' : 'services', 'fold' : 0, 'stl' : 1}, + \ 'D': {'long' : 'domains', 'fold' : 0, 'stl' : 1}, + \ 'V': {'long' : 'views', 'fold' : 0, 'stl' : 1}, + \ 'n': {'long' : 'synonyms', 'fold' : 0, 'stl' : 1}, + \ 'x': {'long' : 'MobiLink Table Scripts', 'fold' : 0, 'stl' : 1}, + \ 'y': {'long' : 'MobiLink Conn Scripts', 'fold' : 0, 'stl' : 1}, + \ 'z': {'long' : 'MobiLink Properties', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#sql# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/tcl.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/tcl.vim new file mode 100644 index 0000000..4ee22b8 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/tcl.vim @@ -0,0 +1,12 @@ + +" Tcl {{{1 +let s:types = {} + +let s:types.lang = 'tcl' + +let s:types.kinds = { + \ 'n': {'long' : 'namespaces', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'procedures', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#tcl# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/tex.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/tex.vim new file mode 100644 index 0000000..22a1816 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/tex.vim @@ -0,0 +1,45 @@ + +" LaTeX {{{1 +let s:types = {} + +let s:types.lang = 'tex' + +let s:types.kinds = { + \ 'i': {'long' : 'includes', 'fold' : 1, 'stl' : 0}, + \ 'p': {'long' : 'parts', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'chapters', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'sections', 'fold' : 0, 'stl' : 1}, + \ 'u': {'long' : 'subsections', 'fold' : 0, 'stl' : 1}, + \ 'b': {'long' : 'subsubsections', 'fold' : 0, 'stl' : 1}, + \ 'P': {'long' : 'paragraphs', 'fold' : 0, 'stl' : 0}, + \ 'G': {'long' : 'subparagraphs', 'fold' : 0, 'stl' : 0}, + \ 'l': {'long' : 'labels', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'frame', 'fold' : 0, 'stl' : 0}, + \ 'g': {'long' : 'subframe', 'fold' : 0, 'stl' : 0} + \ } + +let s:types.sro = '""' + +let s:types.kind2scope = { + \ 'p' : 'part', + \ 'c' : 'chapter', + \ 's' : 'section', + \ 'u' : 'subsection', + \ 'b' : 'subsubsection', + \ 'f' : 'frame', + \ 'g' : 'subframe' + \ } + +let s:types.scope2kind = { + \ 'part' : 'p', + \ 'chapter' : 'c', + \ 'section' : 's', + \ 'subsection' : 'u', + \ 'subsubsection' : 'b', + \ 'frame' : 'f', + \ 'subframe' : 'g' + \ } + +let s:types.sort = 0 + +let g:vista#types#uctags#tex# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vala.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vala.vim new file mode 100644 index 0000000..51c74e3 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vala.vim @@ -0,0 +1,46 @@ + +" Vala {{{1 +" Vala is supported by the ctags fork provided by Anjuta, so only add the +" type if the fork is used to prevent error messages otherwise +let s:types = {} + +let s:types.lang = 'vala' + +let s:types.kinds = { + \ 'e': {'long' : 'Enumerations', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'Enumeration values', 'fold' : 0, 'stl' : 0}, + \ 's': {'long' : 'Structures', 'fold' : 0, 'stl' : 1}, + \ 'i': {'long' : 'Interfaces', 'fold' : 0, 'stl' : 1}, + \ 'd': {'long' : 'Delegates', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'Classes', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'Properties', 'fold' : 0, 'stl' : 0}, + \ 'f': {'long' : 'Fields', 'fold' : 0, 'stl' : 0}, + \ 'm': {'long' : 'Methods', 'fold' : 0, 'stl' : 1}, + \ 'E': {'long' : 'Error domains', 'fold' : 0, 'stl' : 1}, + \ 'r': {'long' : 'Error codes', 'fold' : 0, 'stl' : 1}, + \ 'S': {'long' : 'Signals', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '.' + +" 'enum' doesn't seem to be used as a scope, but it can't hurt to have +" it here +let s:types.kind2scope = { + \ 's' : 'struct', + \ 'i' : 'interface', + \ 'c' : 'class', + \ 'e' : 'enum' + \ } + +let s:types.scope2kind = { + \ 'struct' : 's', + \ 'interface' : 'i', + \ 'class' : 'c', + \ 'enum' : 'e' + \ } + +let g:vista#types#uctags#vala# = s:types + +if executable('anjuta-tags') + let g:vista#types#uctags#vala#.ctagsbin = 'anjuta-tags' +endif diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vera.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vera.vim new file mode 100644 index 0000000..6db6652 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vera.vim @@ -0,0 +1,38 @@ + +" Vera {{{1 +" Why are variables 'virtual'? +let s:types = {} + +let s:types.lang = 'vera' + +let s:types.kinds = { + \ 'h': {'long' : 'header files', 'fold' : 1, 'stl' : 0}, + \ 'd': {'long' : 'macros', 'fold' : 1, 'stl' : 0}, + \ 'g': {'long' : 'enums', 'fold' : 0, 'stl' : 1}, + \ 'T': {'long' : 'typedefs', 'fold' : 0, 'stl' : 0}, + \ 'i': {'long' : 'interfaces', 'fold' : 0, 'stl' : 1}, + \ 'c': {'long' : 'classes', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'enumerators', 'fold' : 0, 'stl' : 0}, + \ 'm': {'long' : 'members', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 's': {'long' : 'signals', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'tasks', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 0, 'stl' : 0}, + \ 'p': {'long' : 'programs', 'fold' : 0, 'stl' : 1} + \ } + +let s:types.sro = '.' " Nesting doesn't seem to be possible + +let s:types.kind2scope = { + \ 'g' : 'enum', + \ 'c' : 'class', + \ 'v' : 'virtual' + \ } + +let s:types.scope2kind = { + \ 'enum' : 'g', + \ 'class' : 'c', + \ 'virtual' : 'v' + \ } + +let g:vista#types#uctags#vera# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/verilog.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/verilog.vim new file mode 100644 index 0000000..e560ce7 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/verilog.vim @@ -0,0 +1,19 @@ + +" Verilog {{{1 +let s:types = {} + +let s:types.lang = 'verilog' + +let s:types.kinds = { + \ 'c': {'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ 'e': {'long' : 'events', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'm': {'long' : 'modules', 'fold' : 0, 'stl' : 1}, + \ 'b': {'long' : 'blocks', 'fold' : 0, 'stl' : 1}, + \ 'n': {'long' : 'net data types', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'ports', 'fold' : 0, 'stl' : 1}, + \ 'r': {'long' : 'register data types', 'fold' : 0, 'stl' : 1}, + \ 't': {'long' : 'tasks', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#verilog# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vhdl.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vhdl.vim new file mode 100644 index 0000000..8b328e1 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vhdl.vim @@ -0,0 +1,19 @@ + +" VHDL {{{1 +" The VHDL ctags parser unfortunately doesn't generate proper scopes +let s:types = {} + +let s:types.lang = 'vhdl' + +let s:types.kinds = { + \ 'P': {'long' : 'packages', 'fold' : 1, 'stl' : 0}, + \ 'c': {'long' : 'constants', 'fold' : 0, 'stl' : 0}, + \ 't': {'long' : 'types', 'fold' : 0, 'stl' : 1}, + \ 'T': {'long' : 'subtypes', 'fold' : 0, 'stl' : 1}, + \ 'r': {'long' : 'records', 'fold' : 0, 'stl' : 1}, + \ 'e': {'long' : 'entities', 'fold' : 0, 'stl' : 1}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'p': {'long' : 'procedures', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#vhdl# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vim.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vim.vim new file mode 100644 index 0000000..4d87bc7 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/vim.vim @@ -0,0 +1,14 @@ +let s:types = {} + +let s:types.lang = 'vim' + +let s:types.kinds = { + \ 'n': {'long' : 'vimball filenames', 'fold' : 0, 'stl' : 1}, + \ 'v': {'long' : 'variables', 'fold' : 1, 'stl' : 0}, + \ 'f': {'long' : 'functions', 'fold' : 0, 'stl' : 1}, + \ 'a': {'long' : 'autocommand groups', 'fold' : 1, 'stl' : 1}, + \ 'c': {'long' : 'commands', 'fold' : 0, 'stl' : 0}, + \ 'm': {'long' : 'maps', 'fold' : 1, 'stl' : 0} + \ } + +let g:vista#types#uctags#vim# = s:types diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/yacc.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/yacc.vim new file mode 100644 index 0000000..d46ab3a --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/types/uctags/yacc.vim @@ -0,0 +1,12 @@ + +" YACC {{{1 +let s:types = {} + +let s:types.lang = 'yacc' + +let s:types.kinds = { + \ {'short' : 'l', 'long' : 'labels', 'fold' : 0, 'stl' : 1} + \ } + +let g:vista#types#uctags#yacc# = s:types +" }}}1 diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/util.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/util.vim new file mode 100644 index 0000000..bf50754 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/util.vim @@ -0,0 +1,276 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:path_separator = has('win32') ? '\' : '/' + +function! vista#util#MaxLen() abort + let l:maxlen = &columns * &cmdheight - 2 + let l:maxlen = &showcmd ? l:maxlen - 11 : l:maxlen + let l:maxlen = &ruler ? l:maxlen - 18 : l:maxlen + return l:maxlen +endfunction + +" Avoid hit-enter prompt when the message being echoed is too long. +function! vista#util#Truncate(msg) abort + let maxlen = vista#util#MaxLen() + return len(a:msg) < maxlen ? a:msg : a:msg[:maxlen-3].'...' +endfunction + +if exists('*trim') + function! vista#util#Trim(str) abort + return trim(a:str) + endfunction +else + function! vista#util#Trim(str) abort + return substitute(a:str, '^\s*\(.\{-}\)\s*$', '\1', '') + endfunction +endif + +" Set the file path as the first line if possible. +function! s:PrependFpath(lines) abort + if exists('g:vista.source.fpath') + let width = winwidth(g:vista.winnr()) + let fpath = g:vista.source.fpath + " Make the path relative to current directory. + let fpath = fnamemodify(fpath, ':p:.') + " Shorten the file path if it's too long + if len(fpath) > width + let fpath = '..'.fpath[len(fpath)-width+4 : ] + endif + return [fpath, ''] + a:lines + endif + + return a:lines +endfunction + +if has('nvim') + function! s:SetBufline(bufnr, lines) abort + call nvim_buf_set_lines(a:bufnr, 0, -1, 0, a:lines) + endfunction + + function! vista#util#JobStop(jobid) abort + silent! call jobstop(a:jobid) + endfunction + +else + function! s:SetBufline(bufnr, lines) abort + let cur_lines = getbufline(a:bufnr, 1, '$') + call setbufline(a:bufnr, 1, a:lines) + if len(cur_lines) > len(a:lines) + silent call deletebufline(a:bufnr, len(a:lines)+1, len(cur_lines)+1) + endif + endfunction + + function! vista#util#JobStop(jobid) abort + silent! call job_stop(a:jobid) + endfunction +endif + +" Using s:SetBufline() runes into the internal error E315. +" I don't know why. So we jump to the vista window +" and then replace the lines. +function! s:SafeSetBufline(bufnr, lines) abort + let lines = s:PrependFpath(a:lines) + + let bufnr = bufnr('') + call setbufvar(bufnr, '&readonly', 0) + call setbufvar(bufnr, '&modifiable', 1) + + silent 1,$delete _ + call setline(1, lines) + + call setbufvar(bufnr, '&readonly', 1) + call setbufvar(bufnr, '&modifiable', 0) + + let filetype = vista#sidebar#WhichFileType() + call setbufvar(bufnr, '&filetype', filetype) + + call vista#ftplugin#Set() + " Reload vista syntax as you may switch between serveral + " executives/extensions. + " + " rst shares the same syntax with vista_markdown. + if g:vista.source.filetype() ==# 'rst' + execute 'runtime! syntax/vista_markdown.vim' + else + execute 'runtime! syntax/'.filetype.'vim' + endif +endfunction + +function! vista#util#SetBufline(bufnr, lines) abort + call vista#win#Execute(g:vista.winnr(), function('s:SafeSetBufline'), a:bufnr, a:lines) +endfunction + +function! vista#util#Join(...) abort + return join(a:000, '') +endfunction + +" Change coc, ctags, lcn, vim_lsp to Coc, Ctags, Lcn, VimLsp +function! vista#util#ToCamelCase(s) abort + return substitute(a:s, '\(^\l\+\)\|_\(\l\+\)', '\u\1\2', 'g') +endfunction + +" Blink current line under cursor, from junegunn/vim-slash +function! vista#util#Blink(times, delay, ...) abort + let s:blink = { 'ticks': 2 * a:times, 'delay': a:delay } + let s:hi_pos = get(a:000, 0, line('.')) + + if !exists('#VistaBlink') + augroup VistaBlink + autocmd! + autocmd BufWinEnter * call s:blink.clear() + augroup END + endif + + function! s:blink.tick(_) abort + let self.ticks -= 1 + let active = self == s:blink && self.ticks > 0 + + if !self.clear() && active && &hlsearch + let w:vista_blink_id = matchaddpos('IncSearch', [s:hi_pos]) + endif + if active + call timer_start(self.delay, self.tick) + endif + endfunction + + function! s:blink.clear() abort + if exists('w:vista_blink_id') + call matchdelete(w:vista_blink_id) + unlet w:vista_blink_id + return 1 + endif + endfunction + + call s:blink.clear() + call s:blink.tick(0) + return '' +endfunction + +function! vista#util#Warning(msg) abort + echohl WarningMsg + echom '[vista.vim] '.a:msg + echohl NONE +endfunction + +function! vista#util#Retriving(executive) abort + echohl WarningMsg + echom '[Vista.vim] ' + echohl NONE + + echohl Function + echon a:executive + echohl NONE + + echohl Type + echon ' is retriving symbols ..., please try again later' + echohl NONE +endfunction + +function! vista#util#Complete(A, L, P) abort + let args = split(a:L) + if !empty(args) + if args[-1] ==# 'finder' + return join(g:vista#executives, "\n") + elseif args[-1] ==# 'finder!' + return join(['ctags'], "\n") + endif + endif + return join(g:vista#executives + ['finder', 'finder!'], "\n") +endfunction + +" Return the lower indent line number +function! vista#util#LowerIndentLineNr() abort + let linenr = line('.') + let indent = indent(linenr) + while linenr > 0 + let linenr -= 1 + if indent(linenr) < indent + return linenr + endif + endwhile + return 0 +endfunction + +" Return the nearest method of function. +" +" array: List of Dict, composed of Method or Function symbols +" target: current line number in the source buffer +function! vista#util#BinarySearch(array, target, cmp_key, ret_key) abort + let [array, target] = [a:array, a:target] + + let low = 0 + let high = len(array) - 1 + + while low <= high + let mid = (low + high) / 2 + if array[mid][a:cmp_key] == target + let found = array[mid] + return empty(a:ret_key) ? found : get(found, a:ret_key, v:null) + elseif array[mid][a:cmp_key] > target + let high = mid - 1 + else + let low = mid + 1 + endif + endwhile + + if low == 0 + return v:null + endif + + " If no exact match, prefer the previous nearest one. + if g:vista_find_absolute_nearest_method_or_function + if abs(array[low][a:cmp_key] - target) < abs(array[low - 1][a:cmp_key] - target) + let found = array[low] + else + let found = array[low - 1] + endif + else + let found = array[low - 1] + endif + + return empty(a:ret_key) ? found : get(found, a:ret_key, v:null) +endfunction + +if has('nvim') + let s:cache_dir = stdpath('cache') +elseif exists('$XDG_CACHE_HOME') + let s:cache_dir = $XDG_CACHE_HOME +else + let s:cache_dir = $HOME . s:path_separator . '.cache' +endif + +if s:cache_dir !~# s:path_separator.'$' + let s:cache_dir .= s:path_separator +endif + +let s:vista_cache_dir = s:cache_dir.'vista'.s:path_separator + +" Return the directory for caching the tmp data. +" with the ending /. +function! vista#util#CacheDirectory() abort + if !isdirectory(s:vista_cache_dir) + call mkdir(s:vista_cache_dir, 'p') + endif + + return s:vista_cache_dir +endfunction + +" Wrap the native cursor() function, with current position +" pushed to the jumplist before applying cursor() +function! vista#util#Cursor(...) abort + " Push the current position to the jumplist + normal! m' + silent call call('cursor', a:000) +endfunction + +" Try initializing the key of dict to be list with the value, +" otherwise append the value. +function! vista#util#TryAdd(dict, key, value) abort + if has_key(a:dict, a:key) + call add(a:dict[a:key], a:value) + else + let a:dict[a:key] = [a:value] + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/autoload/vista/win.vim b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/win.vim new file mode 100644 index 0000000..8dd9bcc --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/autoload/vista/win.vim @@ -0,0 +1,74 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +let s:has_floating_win = exists('*nvim_open_win') +let s:has_popup = exists('*popup_create') + +function! vista#win#CloseFloating() abort + if s:has_floating_win + call vista#floating#Close() + elseif s:has_popup + call vista#popup#Close() + endif +endfunction + +function! vista#win#FloatingDisplay(...) abort + if s:has_popup + call call('vista#popup#DisplayAt', a:000) + elseif s:has_floating_win + call call('vista#floating#DisplayAt', a:000) + else + call vista#error#Need('neovim compiled with floating window support or vim compiled with popup feature') + endif +endfunction + +" Show the folded content if in a closed fold. +function! vista#win#ShowFoldedDetailInFloatingIsOk() abort + if foldclosed('.') != -1 + if s:has_floating_win || s:has_popup + let foldclosed_end = foldclosedend('.') + let curlnum = line('.') + let lines = getbufline(g:vista.bufnr, curlnum, foldclosed_end) + + if s:has_floating_win + call vista#floating#DisplayRawAt(curlnum, lines) + elseif s:has_popup + call vista#popup#DisplayRawAt(curlnum, lines) + endif + + return v:true + endif + endif + return v:false +endfunction + +function! vista#win#FloatingDisplayOrPeek(lnum, tag) abort + if s:has_floating_win || s:has_popup + call vista#win#FloatingDisplay(a:lnum, a:tag) + else + call vista#source#PeekSymbol(a:lnum, a:tag) + endif +endfunction + +" call Run in the window win unsilently, unlike win_execute() which uses +" silent by default. +" +" CocAction only fetch symbols for current document, no way for specify the other at the moment. +" workaround for #52 +" +" see also #71 +" +" NOTE: a:winnr is winnr, not winid. Ref https://github.com/liuchengxu/vim-clap/issues/371 +function! vista#win#Execute(winnr, Run, ...) abort + if winnr() != a:winnr + noautocmd execute a:winnr.'wincmd w' + let l:switch_back = 1 + endif + + call call(a:Run, a:000) + + if exists('l:switch_back') + noautocmd wincmd p + endif +endfunction diff --git a/etc/soft/nvim/+plugins/vista.vim/ci/install_docker.sh b/etc/soft/nvim/+plugins/vista.vim/ci/install_docker.sh new file mode 100644 index 0000000..54c1df1 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/ci/install_docker.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +# Install Docker +sudo apt-get update +sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" +sudo apt-get update +sudo apt-get install -y docker-ce docker-ce-cli containerd.io +docker --version diff --git a/etc/soft/nvim/+plugins/vista.vim/ci/run-vint b/etc/soft/nvim/+plugins/vista.vim/ci/run-vint new file mode 100755 index 0000000..c5ad87c --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/ci/run-vint @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -eu + +image=liuchengxu/vista.vim + +exit_code=0 + +docker_flags=(--rm -v "$PWD:/testplugin" -v "$PWD/test:/home" -w /testplugin "$image") + +echo '----------------------------------------' +echo 'Running Vint...' +echo '----------------------------------------' +echo 'Vint warnings/errors follow:' +echo + +set -o pipefail +docker run -a stdout "${docker_flags[@]}" vint -w . || exit_code=$? +set +o pipefail + +echo + +exit $exit_code diff --git a/etc/soft/nvim/+plugins/vista.vim/doc/vista.txt b/etc/soft/nvim/+plugins/vista.vim/doc/vista.txt new file mode 100644 index 0000000..03683b6 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/doc/vista.txt @@ -0,0 +1,564 @@ +*vista.txt* -- View and search LSP symbols, tags in Vim and NeoVim. +*vista* + +================================================================================ +CONTENTS *vista-contents* + +1. Vista.vim.....................................................|vista-vista.vim| + 1.1. Introduction.........................................|vista-introduction| + 1.2. Features.................................................|vista-features| + 1.3. Requirement...........................................|vista-requirement| + 1.4. Usage.......................................................|vista-usage| + 1.4.1. Commands...........................................|vista-commands| + 1.4.2. Options.............................................|vista-options| + 1.4.3. Key Mappings...................................|vista-key-mappings| + 1.5. Contributing.........................................|vista-contributing| + 1.6. License...................................................|vista-license| + +================================================================================ +VISTA.VIM *vista-vista.vim* + +View and search LSP symbols, tags in Vim/NeoVim. + +================================================================================ +INTRODUCTION *vista-introduction* + +I initially started {vista.vim}{1} with an intention of replacing {tagbar}{2} as +it seemingly does not have a plan to support the promising +{Language Server Protocol}{3} and async processing. + +Vista.vim can also be a symbol navigator similar to {ctrlp-funky}{4}. Last but +not least, one important goal of vista.vim is to support LSP symbols, which +understands the semantics instead of the regex only. + +{1} https://github.com/liuchengxu/vista.vim +{2} https://github.com/majutsushi/tagbar +{3} https://github.com/Microsoft/language-server-protocol +{4} https://github.com/tacahiroy/ctrlp-funky + +================================================================================ +FEATURES *vista-features* + +[x] View tags and LSP symbols in a sidebar. + [x] universal-ctags (https://github.com/universal-ctags/ctags) + [x] ale (https://github.com/w0rp/ale) + [x] vim-lsp (https://github.com/prabirshrestha/vim-lsp) + [x] coc.nvim (https://github.com/neoclide/coc.nvim) + [x] LanguageClient-neovim (https://github.com/autozimu/LanguageClient-neovim) + [x] vim-lsc (https://github.com/natebosch/vim-lsc) + [x] nvim-lsp (https://github.com/neovim/neovim) +[x] Finder for tags and LSP symbols. + [x] fzf (https://github.com/junegunn/fzf) +[x] Display decent detailed symbol info in cmdline. +[x] Jump to the tag/symbol from vista sidebar with a blink. +[x] Update automatically when switching between buffers. +[x] Update asynchonously in the background when `+job` avaliable. +[x] Find the nearest method or function to the cursor, which could be + integrated into the statusline. +[x] Highlight current tag/symbol. +[x] Show the visibility (public/private) of tags. +[x] Tree viewer for hierarchy data, only works for ctags for now. + +Notes: + +* The feature of finder in vista.vim is a bit like `:BTags` or `:Tags` in {fzf.vim}{5}, + `:CocList` in coc.nvim, `:LeaderfBufTag` in {leaderf.vim}{6}, etc. You can choose + whichever you like. + +* I personally don't use all the features I have listed. Hence some of them + may be on the TODOs forever :(. + +{5} https://github.com/junegunn/fzf.vim +{6} https://github.com/Yggdroot/LeaderF + +================================================================================ +REQUIREMENT *vista-requirement* + +I don't know the mimimal supported version. But if you only care about the ctags +related feature, vim 7.4.1154+ should be enough. + +Otherwise, if you want to try any LSP related features, then you certainly need +some plugins to retrive the LSP symbols, e.g., coc.nvim. When you have these +LSP plugins setted up, vista.vim should be ok to go as well. + +In addition, if you want to search the symbols via fzf, you will have to install +it first. + +{7} https://github.com/junegunn/fzf + +================================================================================ +USAGE *vista-usage* + +-------------------------------------------------------------------------------- +COMMANDS *vista-commands* + +Vista *Vista* + + Open vista window for viewing tags or LSP symbols. + + `:Vista` same with `:Vista ctags` . + + `:Vista show` jump to the tag nearby the current cursor in vista window. + This is for ctags `default` renderer only. + + `:Vista toc` show table of contents of the markdown file. + + *vista-focus* + + `:Vista focus` jump back and forth between the vista sidebar and the source + code window. + + *vista-executive* + + `:Vista coc` open vista window based on coc.nvim. + + `:Vista ale` open vista window based on ale. + + `:Vista lcn` open vista window based on LanguageClient-neovim. + + `:Vista ctags` open vista window based on ctags. + + `:Vista vim_lsp` open vista window based on vim-lsp. + + `:Vista vim_lsc` open vista window based on vim-lsc. + + `:Vista nvim_lsp` open vista window based on nvim-lsp. + + *vista-finder* + + `:Vista finder` same with `:Vista finder fzf:ctags` . + + `:Vista finder!` search tags recursively. + Note: it's still experimental. + What's more, it may be very slow to generate all tags + in a whole project. + + `:Vista finder [finder:executive]` + You can specify either the finder or the + executive, or the both, e.g., `:Vista finder skim:ctags` . + + Specify the finder or executive, e.g.,: + + `:Vista finder fzf` same with `:Vista finder fzf:ctags` . + + `:Vista finder coc` same with `:Vista finder fzf:coc` . + + `:Vista finder clap` synonysm for `:Clap tags` + *vista-info* + + `:Vista info` print information about vista.vim, including the explicit + global variables, autocmds. + + `:Vista info+` copy the output of `:Vista info` to your clipboard, may + fail in some cases. + +Vista! *Vista!* + + Close the vista view window if already opened. + +Vista!! *Vista!!* + + Toggle the vista view window. + +-------------------------------------------------------------------------------- +OPTIONS *vista-options* + +g:vista_sidebar_position *g:vista_sidebar_position* + + Type: |String| + Default: `vertical botright` + + This variable controls the position to open the vista sidebar only. + On the right by default. Change to `vertical topleft` to open on the left. + + Please use |g:vista_sidebar_open_cmd| if you want to have a full control of + the window opening. + +g:vista_sidebar_width *g:vista_sidebar_width* + + Type: |Number| + Default: `30` + + This variable controls the width of vista sidebar only. + + Please use |g:vista_sidebar_open_cmd| if you want to have a full control of + the window opening. + +g:vista_sidebar_open_cmd *g:vista_sidebar_open_cmd* + + Type: |String| + Default: `undefined` + + This variable controls the command used for openning the vista sidebar + window. + + Open the sidebar in current split with width 30: +> + let g:vista_sidebar_open_cmd = '30vsplit' +< +g:vista_sidebar_keepalt *g:vista_sidebar_keepalt* + + Type: |Number| + Default: `0` + + Set this option to `1` to keep the alternate buffer when opening vista + sidebar. See `:h keepalt` for more information. + +g:vista_fold_toggle_icons *g:vista_fold_toggle_icons* + + Type: |List| + Default: `['▼', '▶']` + + This variable controls the icons used to indicate open or close folds. + +g:vista_echo_cursor *g:vista_echo_cursor* + + Type: |Number| + Default: `1` + + Set this option to `0` to disable echoing when the cursor moves. +> +g:vista_cursor_delay *g:vista_cursor_delay* + + Type: |Number| + Default: `400` + + Time delay for showing detailed symbol info at current cursor. + +g:vista_echo_cursor_strategy *g:vista_echo_cursor_strategy* + + Type: |String| + Default: `echo` + + How to show the detailed formation of current cursor symbol. Avaliable + options: + + `echo` - echo in the cmdline. + `scroll` - make the source line of current tag at the center of the + window. + `floating_win` - display in neovim's floating window or vim's popup window. + See if you have neovim's floating window support via + `:echo exists('*nvim_open_win')` or vim's popup feature + via `:echo exists('*popup_create')` + `both` - both `echo` and `floating_win` if it's avaliable otherwise + `scroll` will be used. + +g:vista_update_on_text_changed *g:vista_update_on_text_changed* + + Type: |Number| + Default: `0` + + Update the vista on |TextChanged| and |TextChangedI|. + +g:vista_update_on_text_changed_delay *g:vista_update_on_text_changed_delay* + + Type: |Number| + Default: `500` + + Time delay for updating the vista on |TextChanged| and |TextChangedI|. + +g:vista_close_on_jump *g:vista_close_on_jump* + + Type: |Number| + Default: `0` + + Set this option to `1` to close the vista window automatically + close when you jump to a symbol. + +g:vista_close_on_fzf_select *g:vista_close_on_fzf_select* + + Type: |Number| + Default: `0` + + Close the vista window when you select an item from the fzf search window. +> +g:vista_stay_on_open *g:vista_stay_on_open* + + Type: |Number| + Default: `1` + + Move to the vista window when it is opened. Set this option to `0` to stay + in current windown when opening the vista sidebar. +> +g:vista_blink *g:vista_blink* + + Type: |List| + Default: `[2, 100]` + + By default blinking cursor 2 times with 100ms interval after jumping to + the source line of tag.Disable blinking by setting it to `[0, 0]` . +> +g:vista_top_level_blink *g:vista_top_level_blink* + + Type: |List| + Default: `[2, 100]` + + By default blinking cursor 2 times with 100ms interval after + jumping to top-level tag. Disable blinking by setting it to `[0, 0]` . +> +g:vista_icon_indent *g:vista_icon_indent* + + Type: |List| + Default: `['└ ', '│ ']` + + How each level is indented and what to prepend. This could make + the display more compact or more spacious. + + Note: this option only works the LSP executives, doesn't work for `:Vista ctags` . +> +g:vista_default_executive *g:vista_default_executive* + + Type: |String| + Default: `ctags` + + Executive used when opening vista sidebar without specifying it. This also + applys to the vista finder. + + See all the avaliable executives via `:echo g:vista#executives` . + +g:vista_executive_for *g:vista_executive_for* + + Type: |Dict| + Default: `{}` + + Set the executive for some filetypes explicitly, which is useful for setting + `ctags` as the default executive, whereas you prefer to use LSP for some + filetypes when you ensure that the related LSP server has been installed. + + The rationale is the LSP server has to be installed first explicitly and + people normally only install a few frequently used ones, but ctags supports + much more languages by default. + > + let g:vista_default_executive = 'ctags' + + let g:vista_executive_for = { + \ 'cpp': 'vim_lsp', + \ 'php': 'vim_lsp', + \ } +< + You can also set `toc` or some extension name for markdown like document to + use the builtin toc extension in vista.vim. For `toc`, it actuallys derives + the extension using the `&filetype`. + > + " Use the markdown extension for vimwiki and pandoc filetype. + let g:vista_executive_for = { + \ 'vimwiki': 'markdown', + \ 'pandoc': 'markdown', + \ 'markdown': 'toc', + \ } + +g:vista_{&filetype}_executive *g:vista_{&filetype}_executive* + + Type: |String| + Default: `''` + + The goal of this option is similar to |g:vista_executive_for|, but with + higher priority if you set the same filetype in `g:vista_executive_for`. + vista.vim will check `g:vista_{&filetype}_executive` first and then + `g:vista_executive_for`. > + + let g:vista_cpp_executive = 'vim_lsp' + + " Use the markdown extension for vimwiki as if you are using the + " standard markdown syntax in vimwiki. + let g:vista_vimwiki_executive = 'markdown' + +g:vista_ctags_executable *g:vista_ctags_executable* + + Type: |String| + Default: `ctags` + + The executable to run ctags. + +g:vista_ctags_cmd *g:vista_ctags_cmd* + + Type: |Dictionary| + Default: `{}` + + Declare the command including the executable and options + used to generate ctags output for some certain filetypes. + The file path will be appened to your custom command. + For example: + > + let g:vista_ctags_cmd = { + \ 'haskell': 'hasktags -o - -c', + \ } + +g:vista_ctags_project_opts *g:vista_ctags_project_opts* + + Type: |String| + Default: '' + + ctags options to use when generating project tags. + Note: it's still experimental. + +g:vista_fzf_preview *g:vista_fzf_preview* + + Type: |List| + Default: `[]` + + To enable fzf's preview window set g:vista_fzf_preview. + The elements of g:vista_fzf_preview will be passed as arguments + to `fzf#vim#with_preview()` . + For example: + > + let g:vista_fzf_preview = ['right:50%'] + +g:vista_fzf_opt *g:vista_fzf_opt* + + Type: |List| + Default: `[]` + + Append options to `fzf#run()`. + +g:vista_keep_fzf_colors *g:vista_keep_fzf_colors* + + Type: |Number| + Default: `0` + + Set this variable to `1` to keep the original |g:fzf_colors| when using fzf + finder in vista.vim. + +g:vista_finder_alternative_executives *g:vista_finder_alternative_executives* + + Type: |List| + Default: `['coc']` + + Fall back to other executives if the specified one gives empty data. + This is useful if you want to switch to `ctags` when LSP is not usable. + By default it's all the provided executives excluding the tried one. + +g:vista_disable_statusline *g:vista_disable_statusline* + + Type: |Number| + Default: `exists('g:loaded_airline') || exists('g:loaded_lightline')` + + Vista.vim has a builtin statusline renderer, which may cause some problems + if you use other statusline plugins at the same time. Hence it's disabled + by default if you have installed airline or lightline. + +g:vista_highlight_whole_line *g:vista_highlight_whole_line* + + Type: |Number| + Default: `0` + + By default vista.vim will try to highlight the tag precisely in the vista window. + Set this to `1` to always higlight the whole line. + +g:vista_floating_delay *g:vista_floating_delay* + + Type: |Number| + Default: 100 + + Given any integer, this option controls the number of milliseconds before + vista will show a popup or floating win of the target line context near the cursor. + +g:vista#renderer#enable_icon *g:vista#renderer#enable_icon* + + Type: |Number| + Default: `exists('g:vista#renderer#icons') || exists('g:airline_powerline_fonts')` + + Add pretty symbols for the kind of tags or LSP symbols. + +g:vista_enable_markdown_extension *g:vista_enable_markdown_extension* + + Type: |Number| + Default: `1` + + Use markdown extension instead of the ctags executive. + +g:vista_ignore_kinds *g:vista_ignore_kinds* + + Type: |List| + Default: `[]` + + Ignore some kinds of tags or symbols. + +g:vista#renderer#icons *g:vista#renderer#icons* + + Type: |Dict| + Default: See `autoload/vista/renderer.vim` . + +g:vista#renderer#ctags *g:vista#renderer#ctags* + + Type: |String| + Default: `default` + + Options: + + `default` - render tags in nested structure. + `kind` - render tags kindwise. + `line` - render tags linewise. + +g:vista_no_mappings *g:vista_no_mappings* + + Type: |Number| + Default: `0` + + Disable the default mappings. + +g:vista_log_file *g:vista_log_file* + + Type: |String| + Default: `Undefined` + + Enable the logging feature for debugging. For example: + > + let g:vista_log_file = expand('~/vista.log') +< + Note: Do not enable this unless you want to debug vista.vim as this may have + a side effect on the performance! + +g:vista_enable_centering_jump *g:vista_enable_centering_jump* + + Type: |Number| + Default: `1` + + Set this variable to `0` to not make the line at center of window when you + jump to the tag. + +-------------------------------------------------------------------------------- +Key Mappings *vista-key-mappings* + +The following mappings are defined by default in the vista window. + + - jump to the tag under the cursor. +p - preview the tag under the context via the floating window if it's + avaliable. +s - sort the symbol alphabetically or the location they are declared. +q - close the vista window. + +You can add a mapping to `/` in order to open the vista finder for +searching by adding the following autocommand in your vimrc: + > + autocmd FileType vista,vista_kind nnoremap \ + / :call vista#finder#fzf#Run() + +-------------------------------------------------------------------------------- +Highlights *vista-highlights* + +Use |:hi| command in your vimrc to change the default highlights in vista.vim, +e.g.: + > + hi VistaFloat ctermbg=237 guibg=#3a3a3a + +VistaFloat *VistaFloat* + + Default: `hi default link VistaFloat Pmenu` + + The highlight used for the floating window. + +================================================================================ +CONTRIBUTING *vista-contributing* + +Vista.vim is still in beta, if you run into any trouble or have any sugguestions, +please file an issue (https://github.com/liuchengxu/vista.vim/issues/new). + +================================================================================ +LICENSE *vista-license* + +MIT + +Copyright (c) 2019 Liu-Cheng Xu + +vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/etc/soft/nvim/+plugins/vista.vim/plugin/vista.vim b/etc/soft/nvim/+plugins/vista.vim/plugin/vista.vim new file mode 100644 index 0000000..b4ab618 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/plugin/vista.vim @@ -0,0 +1,36 @@ +" vista.vim - View and search LSP symbols, tags, etc. +" Author: Liu-Cheng Xu +" Website: https://github.com/liuchengxu/vista.vim +" License: MIT + +if exists('g:loaded_vista') + finish +endif + +let g:loaded_vista = 1 + +let g:vista_sidebar_width = get(g:, 'vista_sidebar_width', 30) +let g:vista_sidebar_position = get(g:, 'vista_sidebar_position', 'vertical botright') +let g:vista_blink = get(g:, 'vista_blink', [2, 100]) +let g:vista_top_level_blink = get(g:, 'vista_top_level_blink', [2, 100]) +let g:vista_icon_indent = get(g:, 'vista_icon_indent', ['└ ', '│ ']) +let g:vista_fold_toggle_icons = get(g:, 'vista_fold_toggle_icons', ['▼', '▶']) +let g:vista_update_on_text_changed = get(g:, 'vista_update_on_text_changed', 0) +let g:vista_update_on_text_changed_delay = get(g:, 'vista_update_on_text_changed_delay', 500) +let g:vista_echo_cursor = get(g:, 'vista_echo_cursor', 1) +let g:vista_no_mappings = get(g:, 'vista_no_mappings', 0) +let g:vista_stay_on_open = get(g:, 'vista_stay_on_open', 1) +let g:vista_close_on_jump = get(g:, 'vista_close_on_jump', 0) +let g:vista_close_on_fzf_select = get(g:, 'vista_close_on_fzf_select', 0) +let g:vista_disable_statusline = get(g:, 'vista_disable_statusline', exists('g:loaded_airline') || exists('g:loaded_lightline')) +let g:vista_cursor_delay = get(g:, 'vista_cursor_delay', 400) +let g:vista_ignore_kinds = get(g:, 'vista_ignore_kinds', []) +let g:vista_executive_for = get(g:, 'vista_executive_for', {}) +let g:vista_default_executive = get(g:, 'vista_default_executive', 'ctags') +let g:vista_enable_centering_jump = get(g:, 'vista_enable_centering_jump', 1) +let g:vista_find_nearest_method_or_function_delay = get(g:, 'vista_find_nearest_method_or_function_delay', 300) +" Select the absolute nearest function when using binary search. +let g:vista_find_absolute_nearest_method_or_function = get(g:, 'vista_find_absolute_nearest_method_or_function', 0) +let g:vista_fzf_preview = get(g:, 'vista_fzf_preview', []) + +command! -bang -nargs=* -bar -complete=custom,vista#util#Complete Vista call vista#(0, ) diff --git a/etc/soft/nvim/+plugins/vista.vim/syntax/vista.vim b/etc/soft/nvim/+plugins/vista.vim/syntax/vista.vim new file mode 100644 index 0000000..9e69d22 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/syntax/vista.vim @@ -0,0 +1,46 @@ +" Copyright (c) 2019 Liu-Cheng Xu +" MIT License +" vim: ts=2 sw=2 sts=2 et + +if exists('b:current_syntax') && b:current_syntax ==# 'vista' + finish +endif + +let s:icons = join(values(g:vista#renderer#icons), '\|') +execute 'syntax match VistaIcon' '/'.s:icons.'/' 'contained' + +syntax match VistaPublic /^\s*+\ + +using std::cout; +using std::endl; + +namespace foo::bar { + static const int x = 1; +}; + +void print_x(void) +{ + cout << foo::bar::x << endl; +} + +namespace foo::bar { + static const int y = 2; +}; + +void print_y(void) +{ + cout << foo::bar::y << endl; +} + +int main(void) +{ + print_x(); + print_y(); + + return 0; +} diff --git a/etc/soft/nvim/+plugins/vista.vim/test/data/175.cpp b/etc/soft/nvim/+plugins/vista.vim/test/data/175.cpp new file mode 100644 index 0000000..3ded4f5 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/test/data/175.cpp @@ -0,0 +1,36 @@ +#include +using namespace std; + +struct { + int bar; +} anon; + +namespace example { + struct { + int foo; + }; + + struct { + int bar; + }; + + enum { + FOO + }; + + enum { + BAR + }; +} + +namespace { + enum { + BAZ + }; +} + +int +main(void) +{ + return 0; +} diff --git a/etc/soft/nvim/+plugins/vista.vim/test/data/70.py b/etc/soft/nvim/+plugins/vista.vim/test/data/70.py new file mode 100644 index 0000000..4d3674f --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/test/data/70.py @@ -0,0 +1,4 @@ +class Foo: + class Bar: + def baz(self): + pass diff --git a/etc/soft/nvim/+plugins/vista.vim/test/data/anonymous_namespace.cpp b/etc/soft/nvim/+plugins/vista.vim/test/data/anonymous_namespace.cpp new file mode 100644 index 0000000..deebd6b --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/test/data/anonymous_namespace.cpp @@ -0,0 +1,12 @@ +namespace { + extern int foo(); + extern int baz(); +} + +namespace { + extern int foo(); +} + +namespace { + extern int foo(); +} diff --git a/etc/soft/nvim/+plugins/vista.vim/test/data/ctags_tree_view.py b/etc/soft/nvim/+plugins/vista.vim/test/data/ctags_tree_view.py new file mode 100644 index 0000000..5d8d356 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/test/data/ctags_tree_view.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +class Foo: + class Bar: + BAR = 12 + + class Baz: + pass + + class Qux: + class Bar: + BAR = 12 + + class Baz: + pass + + class Qux: + pass + + pass + + class Bar1: + BAR = 12 + + class Baz: + pass + + class Qux: + class Bar: + BAR = 12 + + class Baz: + pass + + class Qux: + pass + + pass + + class Bar2: + BAR = 12 + + class Baz: + pass + + class Qux: + class Bar: + BAR = 12 + + class Baz: + pass + + class Qux: + pass + + pass + + def qux(self): + def thing1(): + pass + + if True: + + def thing2(): + pass + else: + + def thing3(): + pass + + def thing4(): + pass + + def qux1(self): + def thing1(): + pass + + if True: + + def thing2(): + pass + else: + + def thing3(): + pass + + def thing4(): + pass diff --git a/etc/soft/nvim/+plugins/vista.vim/test/fetch_testdata.sh b/etc/soft/nvim/+plugins/vista.vim/test/fetch_testdata.sh new file mode 100644 index 0000000..0505453 --- /dev/null +++ b/etc/soft/nvim/+plugins/vista.vim/test/fetch_testdata.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +try_download() { + local testdata=$1 + local source=$2 + if [ -f "$testdata" ]; then + echo "$testdata already exists" + else + echo "$testdata does not exist, downloading..." + curl "$source" -o "$testdata" + fi +} + +try_download data/184.cpp https://raw.githubusercontent.com/PointCloudLibrary/pcl/master/io/src/pcd_io.cpp + +try_download data/190.cpp https://raw.githubusercontent.com/opencv/opencv/master/modules/core/include/opencv2/core/mat.hpp +