Merge branch 'master' of github.com:rad4day/dotfiles
This commit is contained in:
commit
a426a4ef08
@ -9,5 +9,6 @@
|
|||||||
ignore = "!gi() { curl -L -s https://www.gitignore.io/api/$@ ; } ; gi"
|
ignore = "!gi() { curl -L -s https://www.gitignore.io/api/$@ ; } ; gi"
|
||||||
[commit]
|
[commit]
|
||||||
gpgsign = true
|
gpgsign = true
|
||||||
|
template = ~/.gitmessage
|
||||||
[core]
|
[core]
|
||||||
autocrlf = input
|
autocrlf = input
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -140,3 +140,5 @@ i3/config
|
|||||||
*.sqlite
|
*.sqlite
|
||||||
i3/scripts/dmenu/database.sqlite
|
i3/scripts/dmenu/database.sqlite
|
||||||
albert/*.db
|
albert/*.db
|
||||||
|
vim/plugged/
|
||||||
|
vim/autoload/plug.vim
|
||||||
|
3
.gitmessage
Normal file
3
.gitmessage
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Tobias Manske <tobias.manske@mailbox.org>
|
114
.gitmodules
vendored
114
.gitmodules
vendored
@ -1,90 +1,3 @@
|
|||||||
[submodule "vim/plugins/emmet-vim"]
|
|
||||||
path = vim/plugins/emmet-vim
|
|
||||||
url = https://github.com/mattn/emmet-vim
|
|
||||||
[submodule "vim/plugins/neco-vim"]
|
|
||||||
path = vim/plugins/neco-vim
|
|
||||||
url = https://github.com/Shougo/neco-vim
|
|
||||||
[submodule "vim/plugins/nerdcommenter"]
|
|
||||||
path = vim/plugins/nerdcommenter
|
|
||||||
url = https://github.com/scrooloose/nerdcommenter
|
|
||||||
[submodule "vim/plugins/supertab"]
|
|
||||||
path = vim/plugins/supertab
|
|
||||||
url = https://github.com/ervandew/supertab
|
|
||||||
[submodule "vim/plugins/vim-airline"]
|
|
||||||
path = vim/plugins/vim-airline
|
|
||||||
url = https://github.com/vim-airline/vim-airline.git
|
|
||||||
[submodule "vim/plugins/vim-airline-themes"]
|
|
||||||
path = vim/plugins/vim-airline-themes
|
|
||||||
url = https://github.com/vim-airline/vim-airline-themes.git
|
|
||||||
[submodule "vim/plugins/vim-better-whitespace"]
|
|
||||||
path = vim/plugins/vim-better-whitespace
|
|
||||||
url = git://github.com/ntpeters/vim-better-whitespace.git
|
|
||||||
[submodule "vim/plugins/vim-easymotion"]
|
|
||||||
path = vim/plugins/vim-easymotion
|
|
||||||
url = https://github.com/easymotion/vim-easymotion
|
|
||||||
[submodule "vim/plugins/vim-fugitive"]
|
|
||||||
path = vim/plugins/vim-fugitive
|
|
||||||
url = git://github.com/tpope/vim-fugitive.git
|
|
||||||
[submodule "vim/plugins/vim-yankstack"]
|
|
||||||
path = vim/plugins/vim-yankstack
|
|
||||||
url = https://github.com/maxbrunsfeld/vim-yankstack
|
|
||||||
[submodule "vim/plugins/indentline"]
|
|
||||||
path = vim/plugins/indentline
|
|
||||||
url = https://github.com/yggdroot/indentline
|
|
||||||
[submodule "vim/plugins/simpylfold"]
|
|
||||||
path = vim/plugins/simpylfold
|
|
||||||
url = https://github.com/tmhedberg/simpylfold
|
|
||||||
[submodule "vim/plugins/FastFold"]
|
|
||||||
path = vim/plugins/FastFold
|
|
||||||
url = https://github.com/Konfekt/fastfold.git
|
|
||||||
[submodule "vim/plugins/vim-nerdtree-tabs"]
|
|
||||||
path = vim/plugins/vim-nerdtree-tabs
|
|
||||||
url = https://github.com/jistr/vim-nerdtree-tabs
|
|
||||||
[submodule "vim/plugins/GoldenView"]
|
|
||||||
path = vim/plugins/GoldenView
|
|
||||||
url = git://github.com/zhaocai/GoldenView.Vim.git
|
|
||||||
[submodule "vim/plugins/ultisnips"]
|
|
||||||
path = vim/plugins/ultisnips
|
|
||||||
url = https://github.com/SirVer/ultisnips.git
|
|
||||||
[submodule "vim/snippets/vim-snippets"]
|
|
||||||
path = vim/snippets/vim-snippets
|
|
||||||
url = https://github.com/honza/vim-snippets
|
|
||||||
[submodule "vim/snippets/bootstrap-snippets"]
|
|
||||||
path = vim/snippets/bootstrap-snippets
|
|
||||||
url = https://github.com/bonsaiben/bootstrap-snippets.git
|
|
||||||
[submodule "vim/snippets/snipmate-snippets-bib"]
|
|
||||||
path = vim/snippets/snipmate-snippets-bib
|
|
||||||
url = https://github.com/rbonvall/snipmate-snippets-bib.git
|
|
||||||
[submodule "vim/plugins/singlecompile"]
|
|
||||||
path = vim/plugins/singlecompile
|
|
||||||
url = https://github.com/xuhdev/singlecompile
|
|
||||||
[submodule "vim/plugins/javacomplete"]
|
|
||||||
path = vim/plugins/javacomplete
|
|
||||||
url = https://github.com/vim-scripts/javacomplete
|
|
||||||
[submodule "vim/plugins/vim-python-pep8-indent"]
|
|
||||||
path = vim/plugins/vim-python-pep8-indent
|
|
||||||
url = https://github.com/Vimjas/vim-python-pep8-indent
|
|
||||||
[submodule "vim/plugins/auto-pairs"]
|
|
||||||
path = vim/plugins/auto-pairs
|
|
||||||
url = https://github.com/jiangmiao/auto-pairs.git
|
|
||||||
[submodule "vim/plugins/kotlin-vim"]
|
|
||||||
path = vim/plugins/kotlin-vim
|
|
||||||
url = https://github.com/udalov/kotlin-vim.git
|
|
||||||
[submodule "vim/plugins/vim-hug-neovim-rpc"]
|
|
||||||
path = vim/plugins/vim-hug-neovim-rpc
|
|
||||||
url = https://github.com/roxma/vim-hug-neovim-rpc
|
|
||||||
[submodule "vim/plugins/deoplete.nvim"]
|
|
||||||
path = vim/plugins/deoplete.nvim
|
|
||||||
url = https://github.com/Shougo/deoplete.nvim.git
|
|
||||||
[submodule "vim/plugins/nvim-yarp"]
|
|
||||||
path = vim/plugins/nvim-yarp
|
|
||||||
url = https://github.com/roxma/nvim-yarp
|
|
||||||
[submodule "vim/plugins/deoplete-jedi"]
|
|
||||||
path = vim/plugins/deoplete-jedi
|
|
||||||
url = https://github.com/zchee/deoplete-jedi
|
|
||||||
[submodule "vim/plugins/vim-latex-live-preview"]
|
|
||||||
path = vim/plugins/vim-latex-live-preview
|
|
||||||
url = https://github.com/xuhdev/vim-latex-live-preview
|
|
||||||
[submodule "zsh/modules/history-substring-search/external"]
|
[submodule "zsh/modules/history-substring-search/external"]
|
||||||
path = zsh/modules/history-substring-search/external
|
path = zsh/modules/history-substring-search/external
|
||||||
url = https://github.com/zsh-users/zsh-history-substring-search.git
|
url = https://github.com/zsh-users/zsh-history-substring-search.git
|
||||||
@ -130,30 +43,3 @@
|
|||||||
[submodule "tmux/plugins/tpm"]
|
[submodule "tmux/plugins/tpm"]
|
||||||
path = tmux/plugins/tpm
|
path = tmux/plugins/tpm
|
||||||
url = https://github.com/tmux-plugins/tpm.git
|
url = https://github.com/tmux-plugins/tpm.git
|
||||||
[submodule "vim/plugins/python-mode"]
|
|
||||||
path = vim/plugins/python-mode
|
|
||||||
url = https://github.com/klen/python-mode.git
|
|
||||||
[submodule "vim/plugins/ale"]
|
|
||||||
path = vim/plugins/ale
|
|
||||||
url = https://github.com/w0rp/ale.git
|
|
||||||
[submodule "vim/plugins/pydoc"]
|
|
||||||
path = vim/plugins/pydoc
|
|
||||||
url = https://github.com/fs111/pydoc.vim
|
|
||||||
[submodule "vim/plugins/vim-gitgutter"]
|
|
||||||
path = vim/plugins/vim-gitgutter
|
|
||||||
url = git://github.com/airblade/vim-gitgutter.git
|
|
||||||
[submodule "vim/plugins/fzf"]
|
|
||||||
path = vim/plugins/fzf
|
|
||||||
url = git://github.com/junegunn/fzf.vim
|
|
||||||
[submodule "vim/plugins/vim-markdown"]
|
|
||||||
path = vim/plugins/vim-markdown
|
|
||||||
url = https://github.com/plasticboy/vim-markdown.git
|
|
||||||
[submodule "vim/plugins/ansible-vim"]
|
|
||||||
path = vim/plugins/ansible-vim
|
|
||||||
url = https://github.com/pearofducks/ansible-vim
|
|
||||||
[submodule "vim/plugins/traces.vim"]
|
|
||||||
path = vim/plugins/traces.vim
|
|
||||||
url = https://github.com/markonm/traces.vim
|
|
||||||
[submodule "vim/plugins/vim-window-resize-easy"]
|
|
||||||
path = vim/plugins/vim-window-resize-easy
|
|
||||||
url = https://github.com/roxma/vim-window-resize-easy
|
|
||||||
|
2
Makefile
2
Makefile
@ -15,7 +15,9 @@ vim:
|
|||||||
|
|
||||||
git:
|
git:
|
||||||
rm ~/.gitconfig || echo
|
rm ~/.gitconfig || echo
|
||||||
|
rm ~/.gitmessage || echo
|
||||||
ln -s ~/.dotfiles/.gitconfig ~/.gitconfig
|
ln -s ~/.dotfiles/.gitconfig ~/.gitconfig
|
||||||
|
ln -s ~/.dotfiles/.gitmessage ~/.gitmessage
|
||||||
|
|
||||||
xresources:
|
xresources:
|
||||||
rm ~/.Xresources
|
rm ~/.Xresources
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[General]
|
[General]
|
||||||
frontendId=org.albert.frontend.widgetboxmodel
|
frontendId=org.albert.frontend.qmlboxmodel
|
||||||
hotkey=Alt+Space
|
hotkey=Alt+Space
|
||||||
incrementalSort=true
|
incrementalSort=true
|
||||||
showTray=false
|
showTray=false
|
||||||
@ -11,12 +11,21 @@ enabled=true
|
|||||||
[org.albert.extension.calculator]
|
[org.albert.extension.calculator]
|
||||||
enabled=true
|
enabled=true
|
||||||
|
|
||||||
|
[org.albert.extension.externalextensions]
|
||||||
|
enabled=true
|
||||||
|
|
||||||
[org.albert.extension.firefoxbookmarks]
|
[org.albert.extension.firefoxbookmarks]
|
||||||
enabled=true
|
enabled=true
|
||||||
fuzzy=true
|
fuzzy=true
|
||||||
openWithFirefox=true
|
openWithFirefox=true
|
||||||
profile=Profile0
|
profile=Profile0
|
||||||
|
|
||||||
|
[org.albert.extension.mpris]
|
||||||
|
enabled=true
|
||||||
|
|
||||||
|
[org.albert.extension.python]
|
||||||
|
enabled=true
|
||||||
|
|
||||||
[org.albert.extension.ssh]
|
[org.albert.extension.ssh]
|
||||||
enabled=true
|
enabled=true
|
||||||
|
|
||||||
@ -33,7 +42,7 @@ hideOnClose=false
|
|||||||
hideOnFocusLoss=true
|
hideOnFocusLoss=true
|
||||||
showCentered=true
|
showCentered=true
|
||||||
stylePath=/usr/share/albert/org.albert.frontend.qmlboxmodel/styles/BoxModel/MainComponent.qml
|
stylePath=/usr/share/albert/org.albert.frontend.qmlboxmodel/styles/BoxModel/MainComponent.qml
|
||||||
windowPosition=@Point(609 283)
|
windowPosition=@Point(409 103)
|
||||||
|
|
||||||
[org.albert.frontend.widgetboxmodel]
|
[org.albert.frontend.widgetboxmodel]
|
||||||
alwaysOnTop=true
|
alwaysOnTop=true
|
||||||
|
25
albert/org.albert.frontend.qmlboxmodel/style_properties.ini
Normal file
25
albert/org.albert.frontend.qmlboxmodel/style_properties.ini
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
[BoxModel]
|
||||||
|
animation_duration=200
|
||||||
|
background_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0)
|
||||||
|
border_color=@Variant(\0\0\0\x43\x1\xff\xff\xa0\xa0\xa0\xa0\xa0\xa0\0\0)
|
||||||
|
border_size=6
|
||||||
|
cursor_color=@Variant(\0\0\0\x43\x1\xff\xff\xa0\xa0\xa0\xa0\xa0\xa0\0\0)
|
||||||
|
font_name=Roboto
|
||||||
|
foreground_color=@Variant(\0\0\0\x43\x1\xff\xff\xa0\xa0\xa0\xa0\xa0\xa0\0\0)
|
||||||
|
highlight_color=@Variant(\0\0\0\x43\x1\xff\xff``````\0\0)
|
||||||
|
icon_size=48
|
||||||
|
input_color=@Variant(\0\0\0\x43\x1\xff\xff\xa0\xa0\xa0\xa0\xa0\xa0\0\0)
|
||||||
|
input_fontsize=20
|
||||||
|
item_description_fontsize=12
|
||||||
|
item_title_fontsize=26
|
||||||
|
max_items=5
|
||||||
|
padding=6
|
||||||
|
radius=16
|
||||||
|
selection_color=@Variant(\0\0\0\x43\x1\xff\xff``````\0\0)
|
||||||
|
settingsbutton_color=@Variant(\0\0\0\x43\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0)
|
||||||
|
settingsbutton_hover_color=@Variant(\0\0\0\x43\x1\xff\xff``````\0\0)
|
||||||
|
settingsbutton_size=16
|
||||||
|
shadow_color=@Variant(\0\0\0\x43\x1@@\0\0\0\0\0\0\0\0)
|
||||||
|
shadow_size=30
|
||||||
|
spacing=6
|
||||||
|
window_width=400
|
@ -362,7 +362,7 @@ set -g @sidebar-tree-command 'tree -C'
|
|||||||
# ==============================================
|
# ==============================================
|
||||||
|
|
||||||
# Session is considered to be remote when we ssh into host
|
# Session is considered to be remote when we ssh into host
|
||||||
if-shell -b '[ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]' \
|
if-shell -b '[ -n "$SSH_TTY" ]' \
|
||||||
'source-file ~/.tmux/tmux.remote.conf'
|
'source-file ~/.tmux/tmux.remote.conf'
|
||||||
|
|
||||||
# We want to have single prefix key "C-a", usable both for local and remote session
|
# We want to have single prefix key "C-a", usable both for local and remote session
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# show status bar at bottom for remote session,
|
# show status bar at bottom for remote session,
|
||||||
# so it do not stack together with local session's one
|
# so it do not stack together with local session's one
|
||||||
set -g status-position bottom
|
set -g status-position bottom
|
||||||
|
|
||||||
|
90
vim/.vimrc
90
vim/.vimrc
@ -1,63 +1,59 @@
|
|||||||
set encoding=utf-8
|
" Plugin Manager
|
||||||
execute pathogen#infect('plugins/{}')
|
source ~/.vim/config/plugins.vim
|
||||||
execute pathogen#infect('snippets/{}')
|
|
||||||
autocmd vimenter * Helptags
|
" Make sure plug.vim is present
|
||||||
|
if empty(glob('~/.vim/autoload/plug.vim'))
|
||||||
|
silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
|
||||||
|
\ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
|
||||||
|
source ~/.vim/autoload/plug.vim
|
||||||
|
autocmd VimEnter * PlugInstall --sync
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
" Prepare central backup/swap/undo directory
|
||||||
|
let &undodir = expand('~/.vim/.undo//')
|
||||||
|
let &backupdir = expand('~/.vim/.backup//')
|
||||||
|
let &directory = expand('~/.vim/.swp//')
|
||||||
|
|
||||||
syntax on
|
syntax on
|
||||||
filetype plugin on
|
filetype plugin on
|
||||||
filetype plugin indent on
|
filetype plugin indent on
|
||||||
set number
|
|
||||||
set relativenumber
|
set encoding=utf-8
|
||||||
set autochdir
|
|
||||||
|
" Use whitespace instead of tab
|
||||||
set expandtab
|
set expandtab
|
||||||
|
|
||||||
let &undodir = expand('~/.vim/.undo')
|
" Make a tabulator equal 4 spaces
|
||||||
let &backupdir = expand('~/.vim/.backup//')
|
|
||||||
let &directory = expand('~/.vim/.swp//')
|
|
||||||
set undofile
|
|
||||||
|
|
||||||
colorscheme happy_hacking
|
|
||||||
source ~/.vim/config/plugin.vim
|
|
||||||
source ~/.vim/config/keybindings.vim
|
|
||||||
|
|
||||||
set tabstop=4
|
set tabstop=4
|
||||||
set shiftwidth=4
|
set shiftwidth=4
|
||||||
|
|
||||||
|
" Enable persistent undo
|
||||||
|
set undofile
|
||||||
|
|
||||||
|
" Use relative line numbers
|
||||||
|
set number
|
||||||
|
set relativenumber
|
||||||
|
|
||||||
|
" Set linelength indicator to 120 characters
|
||||||
set cc=120
|
set cc=120
|
||||||
let g:netrw_liststyle = 3
|
|
||||||
let g:netrw_browse_split = 4
|
|
||||||
let g:netrw_winsize = 20
|
|
||||||
let g:netrw_altv = 0
|
|
||||||
let g:netrw_banner = 0
|
|
||||||
let g:tex_conceal = ""
|
|
||||||
|
|
||||||
function! ForceResizeNetrw()
|
" Natural window splitting
|
||||||
let curWin = winnr()
|
set splitbelow
|
||||||
for winnr in range(1, winnr('$'))
|
set splitright
|
||||||
if getwinvar(winnr, '&ft')=="netrw"
|
|
||||||
if curWin != winnr
|
" Set colors
|
||||||
silent noautocmd exec winnr 'wincmd w'
|
colorscheme happy_hacking
|
||||||
silent noautocmd exec 'vertical resize ' . g:netrw_winsize
|
|
||||||
silent noautocmd exec curWin 'wincmd w'
|
|
||||||
else
|
|
||||||
silent noautocmd exec 'vertical resize ' . g:netrw_winsize
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
autocmd WinEnter * call ForceResizeNetrw()
|
" Apply plugin configurations
|
||||||
autocmd BufNew * call ForceResizeNetrw()
|
source ~/.vim/config/pluginconfig.vim
|
||||||
|
|
||||||
" R Markdown
|
" Apply custom keybindings
|
||||||
function Rmarkdown()
|
source ~/.vim/config/keybindings.vim
|
||||||
set filetype=markdown
|
|
||||||
set conceallevel=0
|
|
||||||
let g:markdown_syntax_conceal=0
|
|
||||||
let g:markdown_fenced_languages=['r', 'python', 'html', 'sql', 'bash=sh']
|
|
||||||
endfunction
|
|
||||||
autocmd BufNewFile,BufReadPost *.Rmd call Rmarkdown()
|
|
||||||
autocmd BufNewFile,BufReadPost *.rmd call Rmarkdown()
|
|
||||||
|
|
||||||
|
" Apply settings for custom filetypes
|
||||||
|
source ~/.vim/config/filetypes.vim
|
||||||
|
|
||||||
" Transparency
|
" Transparency
|
||||||
hi Normal guibg=NONE ctermbg=NONE
|
hi Normal guibg=NONE ctermbg=NONE
|
||||||
|
@ -1,266 +0,0 @@
|
|||||||
" pathogen.vim - path option manipulation
|
|
||||||
" Maintainer: Tim Pope <http://tpo.pe/>
|
|
||||||
" Version: 2.4
|
|
||||||
|
|
||||||
" Install in ~/.vim/autoload (or ~\vimfiles\autoload).
|
|
||||||
"
|
|
||||||
" For management of individually installed plugins in ~/.vim/bundle (or
|
|
||||||
" ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your
|
|
||||||
" .vimrc is the only other setup necessary.
|
|
||||||
"
|
|
||||||
" The API is documented inline below.
|
|
||||||
|
|
||||||
if exists("g:loaded_pathogen") || &cp
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
let g:loaded_pathogen = 1
|
|
||||||
|
|
||||||
" Point of entry for basic default usage. Give a relative path to invoke
|
|
||||||
" pathogen#interpose() or an absolute path to invoke pathogen#surround().
|
|
||||||
" Curly braces are expanded with pathogen#expand(): "bundle/{}" finds all
|
|
||||||
" subdirectories inside "bundle" inside all directories in the runtime path.
|
|
||||||
" If no arguments are given, defaults "bundle/{}", and also "pack/{}/start/{}"
|
|
||||||
" on versions of Vim without native package support.
|
|
||||||
function! pathogen#infect(...) abort
|
|
||||||
if a:0
|
|
||||||
let paths = filter(reverse(copy(a:000)), 'type(v:val) == type("")')
|
|
||||||
else
|
|
||||||
let paths = ['bundle/{}', 'pack/{}/start/{}']
|
|
||||||
endif
|
|
||||||
if has('packages')
|
|
||||||
call filter(paths, 'v:val !~# "^pack/[^/]*/start/[^/]*$"')
|
|
||||||
endif
|
|
||||||
let static = '^\%([$~\\/]\|\w:[\\/]\)[^{}*]*$'
|
|
||||||
for path in filter(copy(paths), 'v:val =~# static')
|
|
||||||
call pathogen#surround(path)
|
|
||||||
endfor
|
|
||||||
for path in filter(copy(paths), 'v:val !~# static')
|
|
||||||
if path =~# '^\%([$~\\/]\|\w:[\\/]\)'
|
|
||||||
call pathogen#surround(path)
|
|
||||||
else
|
|
||||||
call pathogen#interpose(path)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
call pathogen#cycle_filetype()
|
|
||||||
if pathogen#is_disabled($MYVIMRC)
|
|
||||||
return 'finish'
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Split a path into a list.
|
|
||||||
function! pathogen#split(path) abort
|
|
||||||
if type(a:path) == type([]) | return a:path | endif
|
|
||||||
if empty(a:path) | return [] | endif
|
|
||||||
let split = split(a:path,'\\\@<!\%(\\\\\)*\zs,')
|
|
||||||
return map(split,'substitute(v:val,''\\\([\\,]\)'',''\1'',"g")')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Convert a list to a path.
|
|
||||||
function! pathogen#join(...) abort
|
|
||||||
if type(a:1) == type(1) && a:1
|
|
||||||
let i = 1
|
|
||||||
let space = ' '
|
|
||||||
else
|
|
||||||
let i = 0
|
|
||||||
let space = ''
|
|
||||||
endif
|
|
||||||
let path = ""
|
|
||||||
while i < a:0
|
|
||||||
if type(a:000[i]) == type([])
|
|
||||||
let list = a:000[i]
|
|
||||||
let j = 0
|
|
||||||
while j < len(list)
|
|
||||||
let escaped = substitute(list[j],'[,'.space.']\|\\[\,'.space.']\@=','\\&','g')
|
|
||||||
let path .= ',' . escaped
|
|
||||||
let j += 1
|
|
||||||
endwhile
|
|
||||||
else
|
|
||||||
let path .= "," . a:000[i]
|
|
||||||
endif
|
|
||||||
let i += 1
|
|
||||||
endwhile
|
|
||||||
return substitute(path,'^,','','')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Convert a list to a path with escaped spaces for 'path', 'tag', etc.
|
|
||||||
function! pathogen#legacyjoin(...) abort
|
|
||||||
return call('pathogen#join',[1] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Turn filetype detection off and back on again if it was already enabled.
|
|
||||||
function! pathogen#cycle_filetype() abort
|
|
||||||
if exists('g:did_load_filetypes')
|
|
||||||
filetype off
|
|
||||||
filetype on
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Check if a bundle is disabled. A bundle is considered disabled if its
|
|
||||||
" basename or full name is included in the list g:pathogen_blacklist or the
|
|
||||||
" comma delimited environment variable $VIMBLACKLIST.
|
|
||||||
function! pathogen#is_disabled(path) abort
|
|
||||||
if a:path =~# '\~$'
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
let sep = pathogen#slash()
|
|
||||||
let blacklist =
|
|
||||||
\ get(g:, 'pathogen_blacklist', get(g:, 'pathogen_disabled', [])) +
|
|
||||||
\ pathogen#split($VIMBLACKLIST)
|
|
||||||
if !empty(blacklist)
|
|
||||||
call map(blacklist, 'substitute(v:val, "[\\/]$", "", "")')
|
|
||||||
endif
|
|
||||||
return index(blacklist, fnamemodify(a:path, ':t')) != -1 || index(blacklist, a:path) != -1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Prepend the given directory to the runtime path and append its corresponding
|
|
||||||
" after directory. Curly braces are expanded with pathogen#expand().
|
|
||||||
function! pathogen#surround(path) abort
|
|
||||||
let sep = pathogen#slash()
|
|
||||||
let rtp = pathogen#split(&rtp)
|
|
||||||
let path = fnamemodify(a:path, ':s?[\\/]\=$??')
|
|
||||||
let before = filter(pathogen#expand(path), '!pathogen#is_disabled(v:val)')
|
|
||||||
let after = filter(reverse(pathogen#expand(path, sep.'after')), '!pathogen#is_disabled(v:val[0:-7])')
|
|
||||||
call filter(rtp, 'index(before + after, v:val) == -1')
|
|
||||||
let &rtp = pathogen#join(before, rtp, after)
|
|
||||||
return &rtp
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" For each directory in the runtime path, add a second entry with the given
|
|
||||||
" argument appended. Curly braces are expanded with pathogen#expand().
|
|
||||||
function! pathogen#interpose(name) abort
|
|
||||||
let sep = pathogen#slash()
|
|
||||||
let name = a:name
|
|
||||||
if has_key(s:done_bundles, name)
|
|
||||||
return ""
|
|
||||||
endif
|
|
||||||
let s:done_bundles[name] = 1
|
|
||||||
let list = []
|
|
||||||
for dir in pathogen#split(&rtp)
|
|
||||||
if dir =~# '\<after$'
|
|
||||||
let list += reverse(filter(pathogen#expand(dir[0:-6].name, sep.'after'), '!pathogen#is_disabled(v:val[0:-7])')) + [dir]
|
|
||||||
else
|
|
||||||
let list += [dir] + filter(pathogen#expand(dir.sep.name), '!pathogen#is_disabled(v:val)')
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
let &rtp = pathogen#join(pathogen#uniq(list))
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:done_bundles = {}
|
|
||||||
|
|
||||||
" Invoke :helptags on all non-$VIM doc directories in runtimepath.
|
|
||||||
function! pathogen#helptags() abort
|
|
||||||
let sep = pathogen#slash()
|
|
||||||
for glob in pathogen#split(&rtp)
|
|
||||||
for dir in map(split(glob(glob), "\n"), 'v:val.sep."/doc/".sep')
|
|
||||||
if (dir)[0 : strlen($VIMRUNTIME)] !=# $VIMRUNTIME.sep && filewritable(dir) == 2 && !empty(split(glob(dir.'*.txt'))) && (!filereadable(dir.'tags') || filewritable(dir.'tags'))
|
|
||||||
silent! execute 'helptags' pathogen#fnameescape(dir)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endfor
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
command! -bar Helptags :call pathogen#helptags()
|
|
||||||
|
|
||||||
" Execute the given command. This is basically a backdoor for --remote-expr.
|
|
||||||
function! pathogen#execute(...) abort
|
|
||||||
for command in a:000
|
|
||||||
execute command
|
|
||||||
endfor
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Section: Unofficial
|
|
||||||
|
|
||||||
function! pathogen#is_absolute(path) abort
|
|
||||||
return a:path =~# (has('win32') ? '^\%([\\/]\|\w:\)[\\/]\|^[~$]' : '^[/~$]')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Given a string, returns all possible permutations of comma delimited braced
|
|
||||||
" alternatives of that string. pathogen#expand('/{a,b}/{c,d}') yields
|
|
||||||
" ['/a/c', '/a/d', '/b/c', '/b/d']. Empty braces are treated as a wildcard
|
|
||||||
" and globbed. Actual globs are preserved.
|
|
||||||
function! pathogen#expand(pattern, ...) abort
|
|
||||||
let after = a:0 ? a:1 : ''
|
|
||||||
let pattern = substitute(a:pattern, '^[~$][^\/]*', '\=expand(submatch(0))', '')
|
|
||||||
if pattern =~# '{[^{}]\+}'
|
|
||||||
let [pre, pat, post] = split(substitute(pattern, '\(.\{-\}\){\([^{}]\+\)}\(.*\)', "\\1\001\\2\001\\3", ''), "\001", 1)
|
|
||||||
let found = map(split(pat, ',', 1), 'pre.v:val.post')
|
|
||||||
let results = []
|
|
||||||
for pattern in found
|
|
||||||
call extend(results, pathogen#expand(pattern))
|
|
||||||
endfor
|
|
||||||
elseif pattern =~# '{}'
|
|
||||||
let pat = matchstr(pattern, '^.*{}[^*]*\%($\|[\\/]\)')
|
|
||||||
let post = pattern[strlen(pat) : -1]
|
|
||||||
let results = map(split(glob(substitute(pat, '{}', '*', 'g')), "\n"), 'v:val.post')
|
|
||||||
else
|
|
||||||
let results = [pattern]
|
|
||||||
endif
|
|
||||||
let vf = pathogen#slash() . 'vimfiles'
|
|
||||||
call map(results, 'v:val =~# "\\*" ? v:val.after : isdirectory(v:val.vf.after) ? v:val.vf.after : isdirectory(v:val.after) ? v:val.after : ""')
|
|
||||||
return filter(results, '!empty(v:val)')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" \ on Windows unless shellslash is set, / everywhere else.
|
|
||||||
function! pathogen#slash() abort
|
|
||||||
return !exists("+shellslash") || &shellslash ? '/' : '\'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! pathogen#separator() abort
|
|
||||||
return pathogen#slash()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Convenience wrapper around glob() which returns a list.
|
|
||||||
function! pathogen#glob(pattern) abort
|
|
||||||
let files = split(glob(a:pattern),"\n")
|
|
||||||
return map(files,'substitute(v:val,"[".pathogen#slash()."/]$","","")')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Like pathogen#glob(), only limit the results to directories.
|
|
||||||
function! pathogen#glob_directories(pattern) abort
|
|
||||||
return filter(pathogen#glob(a:pattern),'isdirectory(v:val)')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Remove duplicates from a list.
|
|
||||||
function! pathogen#uniq(list) abort
|
|
||||||
let i = 0
|
|
||||||
let seen = {}
|
|
||||||
while i < len(a:list)
|
|
||||||
if (a:list[i] ==# '' && exists('empty')) || has_key(seen,a:list[i])
|
|
||||||
call remove(a:list,i)
|
|
||||||
elseif a:list[i] ==# ''
|
|
||||||
let i += 1
|
|
||||||
let empty = 1
|
|
||||||
else
|
|
||||||
let seen[a:list[i]] = 1
|
|
||||||
let i += 1
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
return a:list
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Backport of fnameescape().
|
|
||||||
function! pathogen#fnameescape(string) abort
|
|
||||||
if exists('*fnameescape')
|
|
||||||
return fnameescape(a:string)
|
|
||||||
elseif a:string ==# '-'
|
|
||||||
return '\-'
|
|
||||||
else
|
|
||||||
return substitute(escape(a:string," \t\n*?[{`$\\%#'\"|!<"),'^[+>]','\\&','')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Like findfile(), but hardcoded to use the runtimepath.
|
|
||||||
function! pathogen#runtime_findfile(file,count) abort
|
|
||||||
let rtp = pathogen#join(1,pathogen#split(&rtp))
|
|
||||||
let file = findfile(a:file,rtp,a:count)
|
|
||||||
if file ==# ''
|
|
||||||
return ''
|
|
||||||
else
|
|
||||||
return fnamemodify(file,':p')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=':
|
|
13
vim/config/filetypes.vim
Normal file
13
vim/config/filetypes.vim
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
" This config includes custom settings for special filetypes
|
||||||
|
|
||||||
|
|
||||||
|
" Rmarkdown / .rmd
|
||||||
|
function Rmarkdown()
|
||||||
|
set filetype=markdown
|
||||||
|
set conceallevel=0
|
||||||
|
let g:markdown_syntax_conceal=0
|
||||||
|
let g:markdown_fenced_languages=['r', 'python', 'html', 'sql', 'bash=sh']
|
||||||
|
endfunction
|
||||||
|
autocmd BufNewFile,BufReadPost *.Rmd call Rmarkdown()
|
||||||
|
autocmd BufNewFile,BufReadPost *.rmd call Rmarkdown()
|
||||||
|
|
@ -15,12 +15,27 @@ vno <right> <NOP>
|
|||||||
" Misc Keybindings
|
" Misc Keybindings
|
||||||
let mapleader = ","
|
let mapleader = ","
|
||||||
|
|
||||||
|
" Buffers
|
||||||
|
nmap <F3> :Buffers<CR>
|
||||||
|
imap <F3> <ESC><ESC>:Buffers<CR>
|
||||||
|
vmap <F3> <ESC><ESC>:Buffers<CR>
|
||||||
|
|
||||||
|
" Nerdtree
|
||||||
|
nmap <silent> <F4> <ESC>:NERDTreeToggle<CR>
|
||||||
|
|
||||||
|
" SingleCompile
|
||||||
|
nmap <F8> :SCChooseCompiler<CR>
|
||||||
|
nmap <F9> :SCCompile<cr>
|
||||||
|
nmap <F10> :SCCompileRun<cr>
|
||||||
|
|
||||||
|
|
||||||
" Window Movement
|
" Window Movement
|
||||||
nnoremap <silent> <C-H> <C-W><C-H>
|
nnoremap <silent> <C-H> <C-W><C-H>
|
||||||
nnoremap <silent> <C-J> <C-W><C-J>
|
nnoremap <silent> <C-J> <C-W><C-J>
|
||||||
nnoremap <silent> <C-K> <C-W><C-K>
|
nnoremap <silent> <C-K> <C-W><C-K>
|
||||||
nnoremap <silent> <C-L> <C-W><C-L>
|
nnoremap <silent> <C-L> <C-W><C-L>
|
||||||
|
|
||||||
|
|
||||||
" Yankstack
|
" Yankstack
|
||||||
nmap <silent> <S-P> <Plug>yankstack_substitute_newer_paste
|
nmap <silent> <S-P> <Plug>yankstack_substitute_newer_paste
|
||||||
nmap <silent> <C-P> <Plug>yankstack_substitute_older_paste
|
nmap <silent> <C-P> <Plug>yankstack_substitute_older_paste
|
||||||
@ -29,13 +44,6 @@ nmap <silent> <C-P> <Plug>yankstack_substitute_older_paste
|
|||||||
inoremap <C-space> <C-N>
|
inoremap <C-space> <C-N>
|
||||||
imap <C-@> <C-Space>
|
imap <C-@> <C-Space>
|
||||||
|
|
||||||
" Syntastic
|
|
||||||
nnoremap <F2> :SyntasticToggleMode<CR>
|
|
||||||
|
|
||||||
" SingleCompile
|
|
||||||
nmap <F8> :SCChooseCompiler<CR>
|
|
||||||
nmap <F9> :SCCompile<cr>
|
|
||||||
nmap <F10> :SCCompileRun<cr>
|
|
||||||
|
|
||||||
nmap <C-c> g~iw
|
nmap <C-c> g~iw
|
||||||
|
|
||||||
|
@ -21,37 +21,6 @@ let g:airline_theme="minimalist"
|
|||||||
autocmd TextChanged * GitGutter
|
autocmd TextChanged * GitGutter
|
||||||
|
|
||||||
|
|
||||||
" GoldenView
|
|
||||||
let g:goldenview__enable_default_mapping = 0
|
|
||||||
let g:goldenview__ignore_urule = {
|
|
||||||
\ 'filetype' : [
|
|
||||||
\ '' ,
|
|
||||||
\ 'qf' , 'vimpager', 'undotree', 'tagbar',
|
|
||||||
\ 'nerdtree', 'vimshell', 'vimfiler', 'voom' ,
|
|
||||||
\ 'tabman' , 'unite' , 'quickrun', 'Decho' ,
|
|
||||||
\ 'netrw' ,
|
|
||||||
\ ],
|
|
||||||
\ 'buftype' : [
|
|
||||||
\ 'nofile' ,
|
|
||||||
\ ],
|
|
||||||
\ 'bufname' : [
|
|
||||||
\ 'GoToFile' , 'diffpanel_\d\+' ,
|
|
||||||
\ '__Gundo_Preview__' , '__Gundo__' ,
|
|
||||||
\ '\[LustyExplorer-Buffers\]' , '\-MiniBufExplorer\-' ,
|
|
||||||
\ '_VOOM\d\+$' , '__Urannotate_\d\+__' ,
|
|
||||||
\ '__MRU_Files__' ,
|
|
||||||
\ ],
|
|
||||||
\}
|
|
||||||
let g:goldenview__restore_urule = {
|
|
||||||
\ 'filetype' : [
|
|
||||||
\ 'nerdtree', 'vimfiler', 'netrw',
|
|
||||||
\ ],
|
|
||||||
\ 'bufname' : [
|
|
||||||
\ '__MRU_Files__' ,
|
|
||||||
\ ],
|
|
||||||
\ }
|
|
||||||
|
|
||||||
|
|
||||||
" JavaComplete
|
" JavaComplete
|
||||||
if has("autocmd")
|
if has("autocmd")
|
||||||
autocmd Filetype java setlocal omnifunc=javacomplete#CompleteParamsInfo
|
autocmd Filetype java setlocal omnifunc=javacomplete#CompleteParamsInfo
|
||||||
@ -70,6 +39,19 @@ let g:NERDCommentEmptyLines = 1
|
|||||||
let g:NERDTrimTrailingWhitespace = 1
|
let g:NERDTrimTrailingWhitespace = 1
|
||||||
|
|
||||||
|
|
||||||
|
" NerdTree
|
||||||
|
let NERDTreeMinimalUI = 1
|
||||||
|
let g:NERDTreeDirArrowExpandable = '🗀'
|
||||||
|
let g:NERDTreeDirArrowCollapsible = '🗁'
|
||||||
|
let g:NERDTreeHighlightFolders = 1
|
||||||
|
let g:NERDTreeHighlightFoldersFullName = 1
|
||||||
|
|
||||||
|
" autoclose if nerdtree is last open window
|
||||||
|
augroup NERDTree
|
||||||
|
autocmd!
|
||||||
|
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
|
||||||
|
augroup end
|
||||||
|
|
||||||
" PyMode
|
" PyMode
|
||||||
let g:pymode_lint = 0
|
let g:pymode_lint = 0
|
||||||
let g:pymode_syntax = 1
|
let g:pymode_syntax = 1
|
49
vim/config/plugins.vim
Normal file
49
vim/config/plugins.vim
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
call plug#begin('~/.vim/plugged')
|
||||||
|
|
||||||
|
Plug 'mattn/emmet-vim'
|
||||||
|
Plug 'Shougo/neco-vim'
|
||||||
|
Plug 'ervandew/supertab'
|
||||||
|
Plug 'vim-airline/vim-airline'
|
||||||
|
Plug 'vim-airline/vim-airline-themes'
|
||||||
|
Plug 'ntpeters/vim-better-whitespace'
|
||||||
|
Plug 'easymotion/vim-easymotion'
|
||||||
|
Plug 'maxbrunsfeld/vim-yankstack'
|
||||||
|
Plug 'yggdroot/indentline'
|
||||||
|
Plug 'tmhedberg/simpylfold'
|
||||||
|
Plug 'Konfekt/fastfold'
|
||||||
|
Plug 'junegunn/fzf.vim'
|
||||||
|
Plug 'plasticboy/vim-markdown'
|
||||||
|
Plug 'roxma/vim-window-resize-easy'
|
||||||
|
Plug 'markonm/traces.vim'
|
||||||
|
|
||||||
|
Plug 'scrooloose/nerdcommenter'
|
||||||
|
Plug 'scrooloose/nerdtree'
|
||||||
|
Plug 'jistr/vim-nerdtree-tabs'
|
||||||
|
Plug 'Xuyuanp/nerdtree-git-plugin'
|
||||||
|
|
||||||
|
Plug 'SirVer/ultisnips'
|
||||||
|
Plug 'honza/vim-snippets'
|
||||||
|
Plug 'bonsaiben/bootstrap-snippets'
|
||||||
|
Plug 'rbonvall/snipmate-snippets-bib'
|
||||||
|
|
||||||
|
Plug 'xuhdev/singlecompile'
|
||||||
|
Plug 'jiangmiao/auto-pairs'
|
||||||
|
Plug 'roxma/vim-hug-neovim-rpc'
|
||||||
|
Plug 'roxma/nvim-yarp'
|
||||||
|
|
||||||
|
Plug 'Shougo/deoplete.nvim'
|
||||||
|
Plug 'zchee/deoplete-jedi'
|
||||||
|
|
||||||
|
Plug 'w0rp/ale'
|
||||||
|
Plug 'klen/python-mode'
|
||||||
|
Plug 'fs111/pydoc.vim'
|
||||||
|
Plug 'Vimjas/vim-python-pep8-indent'
|
||||||
|
Plug 'vim-scripts/javacomplete'
|
||||||
|
Plug 'udalov/kotlin-vim'
|
||||||
|
Plug 'xuhdev/vim-latex-live-preview'
|
||||||
|
Plug 'pearofducks/ansible-vim'
|
||||||
|
|
||||||
|
Plug 'airblade/vim-gitgutter'
|
||||||
|
Plug 'tpope/vim-fugitive'
|
||||||
|
|
||||||
|
call plug#end()
|
1
vim/plugins/FastFold/.gitignore
vendored
1
vim/plugins/FastFold/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
doc/tags
|
|
@ -1,106 +0,0 @@
|
|||||||
# What good will FastFold do?
|
|
||||||
|
|
||||||
Automatic folds (that is, folds generated by a fold method different
|
|
||||||
from `manual`), bog down VIM noticeably in insert mode. They are also often
|
|
||||||
recomputed too early (for example, when inserting an opening fold marker
|
|
||||||
whose closing counterpart is yet missing to complete the fold.)
|
|
||||||
|
|
||||||
See http://vim.wikia.com/wiki/Keep_folds_closed_while_inserting_text
|
|
||||||
for a discussion.
|
|
||||||
|
|
||||||
With this plug-in, the folds in the currently edited buffer are updated by an
|
|
||||||
automatic fold method only
|
|
||||||
|
|
||||||
- when saving the buffer
|
|
||||||
- when closing or opening folds (zo, za, zc, etc...)
|
|
||||||
- when moving or operating fold-wise (zj,zk,[z,]z)
|
|
||||||
- when typing `zuz` in normal mode
|
|
||||||
|
|
||||||
and are kept as is otherwise (by keeping the fold method set to `manual`).
|
|
||||||
|
|
||||||
# Example Setup
|
|
||||||
|
|
||||||
Each of these triggers for updating folds can be modified or disabled by adding
|
|
||||||
the lines
|
|
||||||
|
|
||||||
```vim
|
|
||||||
nmap zuz <Plug>(FastFoldUpdate)
|
|
||||||
let g:fastfold_savehook = 1
|
|
||||||
let g:fastfold_fold_command_suffixes = ['x','X','a','A','o','O','c','C']
|
|
||||||
let g:fastfold_fold_movement_commands = [']z', '[z', 'zj', 'zk']
|
|
||||||
```
|
|
||||||
|
|
||||||
to the file `~/.vimrc` (respectively `%USERPROFILE%/_vimrc` on Microsoft Windows).
|
|
||||||
|
|
||||||
For example, by adding
|
|
||||||
|
|
||||||
```vim
|
|
||||||
let g:tex_fold_enabled=1
|
|
||||||
let g:vimsyn_folding='af'
|
|
||||||
let g:xml_syntax_folding = 1
|
|
||||||
let g:php_folding = 1
|
|
||||||
let g:perl_fold = 1
|
|
||||||
```
|
|
||||||
|
|
||||||
to the `.vimrc` file and installing this plug-in, the folds in a TeX, Vim, XML,
|
|
||||||
PHP or Perl file are updated by the `syntax` fold method when saving the
|
|
||||||
buffer, opening, closing, moving or operating on folds, or typing `zuz` in
|
|
||||||
normal mode and are kept as is otherwise.
|
|
||||||
|
|
||||||
*Set fold methods for every file type only*! Setting it globally risks that FastFold assumes the wrong, global, fold method instead of that intended by the file type plug-in, for example TagList.
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
|
|
||||||
- If you prefer that folds are only updated manually but not when saving the buffer,
|
|
||||||
then add `let g:fastfold_savehook = 0` to your `.vimrc`.
|
|
||||||
|
|
||||||
- If you prefer that folds are updated whenever you close or open folds by a
|
|
||||||
standard keystroke such as `zx`,`zo` or `zc`, then add `let
|
|
||||||
g:fastfold_fold_command_suffixes = []` to your `.vimrc`.
|
|
||||||
|
|
||||||
The exact list of these standard keystrokes is `zx,zX,za,zA,zo,zO,zc,zC` and
|
|
||||||
it can be customized by changing the global variable
|
|
||||||
`g:fastfold_mapsuffixes`. If you wanted to intercept all possible fold
|
|
||||||
commands (such as zr,zm,...), change this to:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
let g:fastfold_fold_command_suffixes =
|
|
||||||
['x','X','a','A','o','O','c','C','r','R','m','M','i','n','N']
|
|
||||||
```
|
|
||||||
|
|
||||||
- If you prefer that this plug-in does not add a normal mode mapping that updates
|
|
||||||
folds (that defaults to `zuz`), then add
|
|
||||||
`nmap <SID>(DisableFastFoldUpdate) <Plug>(FastFoldUpdate) ` to your `.vimrc`.
|
|
||||||
|
|
||||||
You can remap `zuz` to your favorite keystroke, say `<F5>`, by adding
|
|
||||||
`nmap <F5> <Plug>(FastFoldUpdate)` to your `.Vimrc`.
|
|
||||||
|
|
||||||
There is also a command `FastFoldUpdate` that updates all folds and its
|
|
||||||
variant `FastFoldUpdate!` that updates all folds and echos by which fold
|
|
||||||
method the folds were updated.
|
|
||||||
|
|
||||||
# Addons
|
|
||||||
|
|
||||||
## Vim-Stay
|
|
||||||
|
|
||||||
`FastFold` integrates with the plug-in
|
|
||||||
[vim-stay](https://github.com/kopischke/vim-stay/issues) that restores the
|
|
||||||
folds of a file buffer by `:mkview` and `:loadview`.
|
|
||||||
|
|
||||||
## Custom Fold Text
|
|
||||||
|
|
||||||
A `CustomFoldText()` function that displays the percentage of the number of buffer lines that the folded text takes up and indents folds according to their nesting level, similar to [that](http://www.gregsexton.org/2011/03/improving-the-text-displayed-in-a-fold/) by Greg Sexton, is available at
|
|
||||||
|
|
||||||
http://www.github.com/Konfekt/FoldText
|
|
||||||
|
|
||||||
## Fold Text-Object
|
|
||||||
|
|
||||||
Create a fold text object, mapped to `iz` and `az`, by adding the lines
|
|
||||||
|
|
||||||
```vim
|
|
||||||
xnoremap iz :<c-u>FastFoldUpdate<cr><esc>:<c-u>normal! ]zv[z<cr>
|
|
||||||
xnoremap az :<c-u>FastFoldUpdate<cr><esc>:<c-u>normal! ]zV[z<cr>
|
|
||||||
```
|
|
||||||
|
|
||||||
to the file `~/.vimrc` (respectively `%USERPROFILE%/_vimrc` on Microsoft Windows).
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
|||||||
FastFold, folding optimization *FastFold* *fastfold*
|
|
||||||
|
|
||||||
===========================================================================
|
|
||||||
0. Introduction ~
|
|
||||||
*FastFold-intro* *fastfold-intro*
|
|
||||||
|
|
||||||
Automatic folds - that is, folds generated by a fold method different
|
|
||||||
from `manual` - bog down VIM considerably in insert mode. Also, they are often
|
|
||||||
re-evaluated prematurely for example, when inserting an opening fold marker
|
|
||||||
whose closing counterpart has yet to be added to complete the fold.
|
|
||||||
|
|
||||||
See http://vim.wikia.com/wiki/Keep_folds_closed_while_inserting_text
|
|
||||||
for a discussion.
|
|
||||||
|
|
||||||
With this plug-in, the folds in the currently edited buffer are updated when
|
|
||||||
certain triggers are met:
|
|
||||||
|
|
||||||
- when saving the buffer
|
|
||||||
- when closing or opening folds (zo, za, zc, etc...)
|
|
||||||
- when moving or operating fold-wise (zj,zk,[z,]z)
|
|
||||||
- when typing `zuz` in normal mode
|
|
||||||
|
|
||||||
===========================================================================
|
|
||||||
1. Commands ~
|
|
||||||
*FastFold-commands* *fastfold-commands*
|
|
||||||
*FastFoldUpdate!*
|
|
||||||
|
|
||||||
- `:FastFoldUpdate` updates all folds in the current buffer.
|
|
||||||
- `:FastFoldUpdate!` updates all folds & echoes what fold method was used
|
|
||||||
|
|
||||||
- The mapping `zuz` that invokes `:FastFoldUpdate!` can be changed to your
|
|
||||||
favorite keystroke, say `<F5>`, by adding
|
|
||||||
>
|
|
||||||
nmap <F5> <Plug>(FastFoldUpdate)
|
|
||||||
<
|
|
||||||
to your `.vimrc`. It can be disabled by adding
|
|
||||||
>
|
|
||||||
nmap <SID>(DisableFastFoldUpdate) <Plug>(FastFoldUpdate)
|
|
||||||
<
|
|
||||||
===========================================================================
|
|
||||||
2. Config ~
|
|
||||||
*FastFold-config* *fastfold-config*
|
|
||||||
|
|
||||||
Each of the above triggers can be enabled or disabled by setting the
|
|
||||||
matching global flags in your `.vimrc`. Default values are shown.
|
|
||||||
>
|
|
||||||
let g:fastfold_savehook = 1
|
|
||||||
let g:fastfold_fdmhook = 0
|
|
||||||
nmap zuz <Plug>(FastFoldUpdate)
|
|
||||||
let g:fastfold_fold_command_suffixes = ['x','X','a','A','o','O','c','C']
|
|
||||||
let g:fastfold_fold_movement_commands = [']z', '[z', 'zj', 'zk']
|
|
||||||
<
|
|
||||||
For example, by adding the following to your `.vimrc`
|
|
||||||
>
|
|
||||||
let g:tex_fold_enabled=1
|
|
||||||
let g:vimsyn_folding='af'
|
|
||||||
let g:xml_syntax_folding = 1
|
|
||||||
let g:php_folding = 1
|
|
||||||
let g:perl_fold = 1
|
|
||||||
<
|
|
||||||
You will enable tex, vim, xml, php and perl syntax folding.
|
|
||||||
|
|
||||||
Set fold methods for every file type only! Setting it globally risks that
|
|
||||||
FastFold assumes the wrong, global, fold method instead of that intended by the
|
|
||||||
file type plug-in, for example TagList.
|
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
- FastFold updates all folds when you open or close folds by the commands
|
|
||||||
zx, zX, za, zA, zo, zO, zc, zC. This list of commands is configured by
|
|
||||||
>
|
|
||||||
let g:fastfold_fold_command_suffixes = ['x','X','a','A','o','O','c','C']
|
|
||||||
<
|
|
||||||
To intercept all possible fold commands (such as zr,zm,...),change this to
|
|
||||||
>
|
|
||||||
let g:fastfold_fold_command_suffixes =
|
|
||||||
['x','X','a','A','o','O','c','C','r','R','m','M','i','n','N']
|
|
||||||
<
|
|
||||||
To disable all interceptions, change this to
|
|
||||||
>
|
|
||||||
let g:fastfold_fold_command_suffixes = []
|
|
||||||
<
|
|
||||||
- FastFold updates all fold when you move or operate fold-wise by
|
|
||||||
the commands zj,zk,[z or ]z. This list of commands is configured by
|
|
||||||
>
|
|
||||||
let g:fastfold_fold_movement_commands = [']z', '[z', 'zj', 'zk']
|
|
||||||
<
|
|
||||||
It can be disabled by
|
|
||||||
>
|
|
||||||
let g:fastfold_fold_movement_commands = []
|
|
||||||
<
|
|
||||||
- FastFold updates all folds when you save a buffer. This hook is set by
|
|
||||||
>
|
|
||||||
let g:fastfold_savehook = 1
|
|
||||||
<
|
|
||||||
- FastFold intercepts every change of the fold method by
|
|
||||||
>
|
|
||||||
let g:fastfold_fdmhook = 1
|
|
||||||
<
|
|
||||||
This is disabled by default as it could interfere with other plugins such as
|
|
||||||
`easymotion`.
|
|
||||||
|
|
||||||
- To disable FastFold for a list of file types, such as 'taglist', add
|
|
||||||
>
|
|
||||||
` let g:fastfold_skip_filetypes`= [ 'taglist' ]
|
|
||||||
<
|
|
||||||
to your 'vimrc'. Default value is [].
|
|
||||||
|
|
||||||
- Add a fold text-object, mapped to `iz` and `az`, by adding the lines
|
|
||||||
|
|
||||||
xnoremap iz :<c-u>FastFoldUpdate<cr><esc>:<c-u>normal! ]zv[z<cr>
|
|
||||||
xnoremap az :<c-u>FastFoldUpdate<cr><esc>:<c-u>normal! ]zV[z<cr>
|
|
||||||
|
|
||||||
to your 'vimrc'.
|
|
||||||
===========================================================================
|
|
||||||
3. Extra Notes ~
|
|
||||||
|
|
||||||
3.1 Related Plugins ~
|
|
||||||
|
|
||||||
`FastFold` integrates with the plug-in `vim-stay` available at
|
|
||||||
|
|
||||||
https://github.com/kopischke/vim-stay
|
|
||||||
|
|
||||||
that stores and restores the last folds by `:mkview` and `:loadview`.
|
|
||||||
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
A fold-text function `CustomFoldText()` that displays the percentage of the
|
|
||||||
number of buffer lines that the folded text takes up and indents folds
|
|
||||||
according to their nesting level is available at
|
|
||||||
|
|
||||||
http://www.github.com/Konfekt/FoldText
|
|
||||||
|
|
||||||
3.2 Warning ~
|
|
||||||
|
|
||||||
FastFold overwrites your manual folds when saving the currently edited buffer,
|
|
||||||
unless
|
|
||||||
|
|
||||||
- FastFold is disabled for this filetype by `g:fastfold_skip_filetypes`, or
|
|
||||||
- the `foldmethod=manual` since having entered the buffer.
|
|
||||||
|
|
||||||
3.3 API ~
|
|
||||||
|
|
||||||
The last used fold method by which FastFold updates the folds in the current
|
|
||||||
buffer can be read off from the window local variable `w:lastdfm`.
|
|
||||||
|
|
||||||
3.4 Thanks go to... ~
|
|
||||||
|
|
||||||
- starcraftman for providing this documentation, and
|
|
||||||
- blueyed, kopischke, sabauma, willywampa, and many others for reporting
|
|
||||||
issues and suggesting code improvements.
|
|
||||||
|
|
||||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl
|
|
@ -1,224 +0,0 @@
|
|||||||
scriptencoding utf-8
|
|
||||||
|
|
||||||
" LICENCE PUBLIQUE RIEN À BRANLER
|
|
||||||
" Version 1, Mars 2009
|
|
||||||
"
|
|
||||||
" Copyright (C) 2009 Sam Hocevar
|
|
||||||
" 14 rue de Plaisance, 75014 Paris, France
|
|
||||||
"
|
|
||||||
" La copie et la distribution de copies exactes de cette licence sont
|
|
||||||
" autorisées, et toute modification est permise à condition de changer
|
|
||||||
" le nom de la licence.
|
|
||||||
"
|
|
||||||
" CONDITIONS DE COPIE, DISTRIBUTON ET MODIFICATION
|
|
||||||
" DE LA LICENCE PUBLIQUE RIEN À BRANLER
|
|
||||||
"
|
|
||||||
" 0. Faites ce que vous voulez, j’en ai RIEN À BRANLER.
|
|
||||||
|
|
||||||
if exists('g:loaded_fastfold') || &cp
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
let g:loaded_fastfold = 1
|
|
||||||
|
|
||||||
let s:keepcpo = &cpo
|
|
||||||
set cpo&vim
|
|
||||||
" ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if !exists('g:fastfold_fdmhook') | let g:fastfold_fdmhook = 0 | endif
|
|
||||||
if !exists('g:fastfold_savehook') | let g:fastfold_savehook = 1 | endif
|
|
||||||
if !exists('g:fastfold_fold_command_suffixes')
|
|
||||||
let g:fastfold_fold_command_suffixes = ['x','X','a','A','o','O','c','C']
|
|
||||||
endif
|
|
||||||
if !exists('g:fastfold_fold_movement_commands')
|
|
||||||
let g:fastfold_fold_movement_commands = [']z', '[z', 'zj', 'zk']
|
|
||||||
endif
|
|
||||||
if !exists('g:fastfold_skip_filetypes') | let g:fastfold_skip_filetypes = [] | endif
|
|
||||||
|
|
||||||
function! s:EnterWin()
|
|
||||||
if exists('w:unchanged')
|
|
||||||
unlet w:unchanged
|
|
||||||
elseif s:Skip()
|
|
||||||
if exists('w:lastfdm')
|
|
||||||
unlet w:lastfdm
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let w:lastfdm = &l:foldmethod
|
|
||||||
setlocal foldmethod=manual
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:LeaveWin()
|
|
||||||
if exists('w:predifffdm')
|
|
||||||
if empty(&l:foldmethod) || &l:foldmethod is# 'manual'
|
|
||||||
let &l:foldmethod = w:predifffdm
|
|
||||||
unlet w:predifffdm
|
|
||||||
return
|
|
||||||
elseif &l:foldmethod isnot# 'diff'
|
|
||||||
unlet w:predifffdm
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
if exists('w:lastfdm') && &l:foldmethod is# 'diff'
|
|
||||||
let w:predifffdm = w:lastfdm
|
|
||||||
endif
|
|
||||||
|
|
||||||
if exists('w:lastfdm') && &l:foldmethod is# 'manual'
|
|
||||||
if !exists('b:last_changedtick') || b:changedtick > b:last_changedtick
|
|
||||||
let &l:foldmethod = w:lastfdm
|
|
||||||
let b:last_changedtick = b:changedtick
|
|
||||||
else
|
|
||||||
let w:unchanged = 1
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Like windo but restore the current buffer.
|
|
||||||
" See http://vim.wikia.com/wiki/Run_a_command_in_multiple_buffers#Restoring_position
|
|
||||||
function! s:WinDo( command )
|
|
||||||
" avoid errors in CmdWin
|
|
||||||
if exists('*getcmdwintype') && !empty(getcmdwintype())
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
" Work around Vim bug.
|
|
||||||
" See https://groups.google.com/forum/#!topic/vim_dev/LLTw8JV6wKg
|
|
||||||
let curaltwin = winnr('#') ? winnr('#') : 1
|
|
||||||
let currwin=winnr()
|
|
||||||
if &scrollopt =~# '\<jump\>'
|
|
||||||
set scrollopt-=jump
|
|
||||||
let l:restore = 'set scrollopt+=jump'
|
|
||||||
endif
|
|
||||||
silent! execute 'keepjumps noautocmd windo ' . a:command
|
|
||||||
silent! execute 'noautocmd ' . curaltwin . 'wincmd w'
|
|
||||||
silent! execute 'noautocmd ' . currwin . 'wincmd w'
|
|
||||||
if exists('l:restore')
|
|
||||||
exe l:restore
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" WinEnter then TabEnter then BufEnter then BufWinEnter
|
|
||||||
function! s:UpdateWin(check)
|
|
||||||
" skip if another session still loading
|
|
||||||
if a:check && exists('g:SessionLoad') | return | endif
|
|
||||||
|
|
||||||
let s:curwin = winnr()
|
|
||||||
call s:WinDo('if winnr() is s:curwin | call s:LeaveWin() | endif')
|
|
||||||
call s:WinDo('if winnr() is s:curwin | call s:EnterWin() | endif')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UpdateBuf(feedback)
|
|
||||||
let s:curbuf = bufnr('%')
|
|
||||||
call s:WinDo("if bufnr('%') is s:curbuf | call s:LeaveWin() | endif")
|
|
||||||
call s:WinDo("if bufnr('%') is s:curbuf | call s:EnterWin() | endif")
|
|
||||||
|
|
||||||
if !a:feedback | return | endif
|
|
||||||
|
|
||||||
if !exists('w:lastfdm')
|
|
||||||
echomsg "'" . &l:foldmethod . "' folds already continuously updated"
|
|
||||||
else
|
|
||||||
echomsg "updated '" . w:lastfdm . "' folds"
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:UpdateTab()
|
|
||||||
" skip if another session still loading
|
|
||||||
if exists('g:SessionLoad') | return | endif
|
|
||||||
|
|
||||||
call s:WinDo('call s:LeaveWin()')
|
|
||||||
call s:WinDo('call s:EnterWin()')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:Skip()
|
|
||||||
if !s:isReasonable() | return 1 | endif
|
|
||||||
if !&l:modifiable | return 1 | endif
|
|
||||||
if s:inSkipList() | return 1 | endif
|
|
||||||
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:isReasonable()
|
|
||||||
if &l:foldmethod is# 'syntax' || &l:foldmethod is# 'expr'
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:inSkipList()
|
|
||||||
for ifiles in g:fastfold_skip_filetypes
|
|
||||||
if index(g:fastfold_skip_filetypes, &l:filetype) >= 0
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
command! -bar -bang FastFoldUpdate call s:UpdateBuf(<bang>0)
|
|
||||||
|
|
||||||
nnoremap <silent> <Plug>(FastFoldUpdate) :<c-u>FastFoldUpdate!<CR>
|
|
||||||
|
|
||||||
if !hasmapto('<Plug>(FastFoldUpdate)', 'n') && empty(mapcheck('zuz', 'n'))
|
|
||||||
nmap zuz <Plug>(FastFoldUpdate)
|
|
||||||
endif
|
|
||||||
|
|
||||||
for suffix in g:fastfold_fold_command_suffixes
|
|
||||||
execute 'nnoremap <silent> z'.suffix.' :<c-u>call <SID>UpdateWin(0)<CR>z'.suffix
|
|
||||||
endfor
|
|
||||||
|
|
||||||
for cmd in g:fastfold_fold_movement_commands
|
|
||||||
exe "nnoremap <silent><expr> " . cmd. " ':<c-u>call <SID>UpdateWin(0)<CR>'.v:count." . "'".cmd."'"
|
|
||||||
exe "xnoremap <silent><expr> " . cmd. " ':<c-u>call <SID>UpdateWin(0)<CR>gv'.v:count." . "'".cmd."'"
|
|
||||||
exe "onoremap <silent><expr> " . cmd. " '<esc>:<c-u>call <SID>UpdateWin(0)<CR>' . '\"' . v:register . v:operator . v:count1 . " . "'".cmd."'"
|
|
||||||
endfor
|
|
||||||
|
|
||||||
augroup FastFold
|
|
||||||
autocmd!
|
|
||||||
autocmd VimEnter * call s:init()
|
|
||||||
autocmd BufEnter,WinEnter *
|
|
||||||
\ if !exists('b:last_changedtick') | let b:last_changedtick = b:changedtick | endif
|
|
||||||
augroup end
|
|
||||||
|
|
||||||
function! s:init()
|
|
||||||
call s:UpdateTab()
|
|
||||||
augroup FastFoldEnter
|
|
||||||
autocmd!
|
|
||||||
" Make &l:foldmethod local to Buffer and NOT Window.
|
|
||||||
autocmd BufEnter,WinEnter *
|
|
||||||
\ if exists('b:lastfdm') | let w:lastfdm = b:lastfdm | call s:LeaveWin() | call s:EnterWin() | endif
|
|
||||||
autocmd BufLeave,WinLeave *
|
|
||||||
\ call s:LeaveWin() | call s:EnterWin() |
|
|
||||||
\ if exists('w:lastfdm') | let b:lastfdm = w:lastfdm |
|
|
||||||
\ elseif exists('b:lastfdm') | unlet b:lastfdm | endif
|
|
||||||
|
|
||||||
autocmd BufEnter,WinEnter *
|
|
||||||
\ if &l:foldmethod isnot# 'diff' && exists('b:predifffdm') | call s:UpdateBuf(0) | endif
|
|
||||||
autocmd BufLeave,WinLeave *
|
|
||||||
\ if exists('w:predifffdm') | let b:predifffdm = w:predifffdm |
|
|
||||||
\ elseif exists('b:predifffdm') | unlet b:predifffdm | endif
|
|
||||||
|
|
||||||
" UpdateBuf/Win(1) = skip if another session is still loading.
|
|
||||||
autocmd TabEnter * call s:UpdateTab()
|
|
||||||
|
|
||||||
" BufWinEnter = to change &l:foldmethod by modelines.
|
|
||||||
autocmd BufWinEnter,FileType * call s:UpdateWin(1)
|
|
||||||
" So that FastFold functions correctly after :loadview.
|
|
||||||
autocmd SessionLoadPost * call s:UpdateWin(0)
|
|
||||||
|
|
||||||
" Update folds on reload.
|
|
||||||
autocmd BufReadPost *
|
|
||||||
\ if !exists('b:already_loaded') | let b:already_loaded = 1 |
|
|
||||||
\ else | call s:UpdateBuf(0) | endif
|
|
||||||
" Update folds on saving.
|
|
||||||
if g:fastfold_savehook
|
|
||||||
autocmd BufWritePost * call s:UpdateBuf(0)
|
|
||||||
endif
|
|
||||||
if g:fastfold_fdmhook
|
|
||||||
if exists('##OptionSet')
|
|
||||||
autocmd OptionSet foldmethod call s:UpdateBuf(0)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
augroup end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" ------------------------------------------------------------------------------
|
|
||||||
let &cpo= s:keepcpo
|
|
||||||
unlet s:keepcpo
|
|
1
vim/plugins/GoldenView/.gitignore
vendored
1
vim/plugins/GoldenView/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
*.zip
|
|
@ -1,31 +0,0 @@
|
|||||||
# Heuristics used by VCLog itself.
|
|
||||||
|
|
||||||
type :major, 3, "Major Enhancements"
|
|
||||||
type :minor, 2, "Minor Enhancements"
|
|
||||||
type :bug, 1, "Bug Fixes"
|
|
||||||
type :fix, 1, "Bug Fixes"
|
|
||||||
type :update, 0, "Nominal Changes"
|
|
||||||
type :doc, -1, "Documentation Changes"
|
|
||||||
type :test, -1, "Test/Spec Adjustments"
|
|
||||||
type :admin, -2, "Administrative Changes"
|
|
||||||
type :log, -3, "Just a record"
|
|
||||||
|
|
||||||
|
|
||||||
on Regexp.union(/^(?<type> \w+):/, /^\[(?<type>\w+)\]/) do |commit, md|
|
|
||||||
type = md[:type].to_sym
|
|
||||||
commit.type = type
|
|
||||||
commit.message = commit.message.sub(md[0],'').strip
|
|
||||||
end
|
|
||||||
|
|
||||||
on /updated? (README\.md|PROFILE|PACKAGE|VERSION|Manifest\.txt)/ do |commit|
|
|
||||||
commit.type = :admin
|
|
||||||
end
|
|
||||||
|
|
||||||
on /(bump|bumped|prepare) version/ do |commit|
|
|
||||||
commit.type = :admin
|
|
||||||
end
|
|
||||||
|
|
||||||
colors :grey, :blue, :cyan, :green, :yellow, :red, [:red, :bold]
|
|
||||||
|
|
||||||
|
|
||||||
# vim: set ft=ruby ts=2 sw=2 tw=78 fmr=[[[,]]] fdm=syntax :
|
|
@ -1,124 +0,0 @@
|
|||||||
script_name: GoldenView.Vim
|
|
||||||
script_id: '4529'
|
|
||||||
script_type: utility
|
|
||||||
script_package: '{script_name}-{version}.zip'
|
|
||||||
required_vim_version: '7.3'
|
|
||||||
summary: Always have a nice view for vim split windows
|
|
||||||
|
|
||||||
detailed_description: |
|
|
||||||
|
|
||||||
Please goto homepage for a better view of the introduction.
|
|
||||||
|
|
||||||
Homepage: http://zhaocai.github.io/GoldenView.Vim/
|
|
||||||
Screencast: http://dl.dropboxusercontent.com/u/1897501/Screencasts/GoldenView.gif
|
|
||||||
|
|
||||||
|
|
||||||
If you like it, please star or fork in https://github.com/zhaocai/GoldenView.Vim so that more people may find it.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
>>> Introduction:
|
|
||||||
|
|
||||||
The initial motive for GoldenView comes from the frustration of using other vim plugins to autoresize split windows. The idea is deadly simple and very useful: resize the focused window to a proper size. However, in practice, many hiccups makes autoresizing not a smooth experience. Below are a list of issues I am trying to solve:
|
|
||||||
|
|
||||||
First and the most important one, autoresizing should play nicely with existing plugins like tagbar, vimfiler, unite, VOoM, quickfix, undotree, gundo, etc. These windows should manage there own window size.
|
|
||||||
|
|
||||||
Second, autoresizing should take care of the other windows too. Resizing the focused window may cause the other windows become too small. When you have 4+ split windows, autoresizing may just make a mess out of it.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
>>> Features:
|
|
||||||
|
|
||||||
GoldenView has preliminarily solved the issues described above. It also provides other features. Bascally, it does two things:
|
|
||||||
|
|
||||||
1. Autoresizing
|
|
||||||
|
|
||||||
First of all, it automatically resize the focused split window to a "golden" view based on golden ratio and textwidth.
|
|
||||||
|
|
||||||
2. Tiled Windows Management
|
|
||||||
|
|
||||||
Second, it maps a single key (<C-L> by default) to nicely split windows to tiled windows.
|
|
||||||
|
|
||||||
====+==============+============+===+
|
|
||||||
| | | | |
|
|
||||||
| F | | S1 | T |
|
|
||||||
| I | +------------| A |
|
|
||||||
| L | MAIN PANE | S2 | G |
|
|
||||||
| E | +------------+ B |
|
|
||||||
| R | | S3 | A |
|
|
||||||
| | | | |
|
|
||||||
+===+==============+============+===+
|
|
||||||
|
|
||||||
To get this view, just hit <C-L> 4 times. or, if you have a large monitor, you may get tiled windows below.
|
|
||||||
|
|
||||||
+===+==============+==============+============+===+
|
|
||||||
| | | | | |
|
|
||||||
| F | | | S1 | T |
|
|
||||||
| I | | +------------| A |
|
|
||||||
| L | MAIN PANE | M2 | S2 | G |
|
|
||||||
| E | | +------------+ B |
|
|
||||||
| R | | | S3 | A |
|
|
||||||
| | | | | |
|
|
||||||
+===+==============+==============+============+===+
|
|
||||||
|
|
||||||
|
|
||||||
To quickly switch between those windows, a few keys are mapped to
|
|
||||||
|
|
||||||
- Focuse to the main window
|
|
||||||
- Switch with the largest, smallest, etc.
|
|
||||||
- Jump to next and previous window
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
- Vim 7.3 or later
|
|
||||||
|
|
||||||
install_details: |
|
|
||||||
http://zhaocai.github.io/GoldenView.Vim/
|
|
||||||
|
|
||||||
versions:
|
|
||||||
- '1.3.6': |
|
|
||||||
- Maintenance update
|
|
||||||
- '1.3.5': |
|
|
||||||
- Fix for issue #5 (github).
|
|
||||||
- Fix for Dirdiff, FencView
|
|
||||||
- Improve tracing
|
|
||||||
|
|
||||||
- '1.3.0': |
|
|
||||||
- Diff mode auto-resizing
|
|
||||||
- refactor autocmd function: tweak restore behavior
|
|
||||||
|
|
||||||
- '1.2.2': |
|
|
||||||
Improve documents and small bug fixes,
|
|
||||||
Load guard for #4 (github)
|
|
||||||
|
|
||||||
- '1.2.0': |
|
|
||||||
add restore rule for some special buffers, which solves all the hiccups I could identify so far.
|
|
||||||
|
|
||||||
- '1.1.2': |
|
|
||||||
Improve documents, fix load sequence
|
|
||||||
|
|
||||||
- '1.1.1': |
|
|
||||||
Improve documents, fix zl library load
|
|
||||||
|
|
||||||
- '1.1.0': |
|
|
||||||
- 3 Major Enhancements
|
|
||||||
* add WinLeave event into account. This version works perfectly.
|
|
||||||
* fix various hiccups caused by winleave
|
|
||||||
* use ignore rules from zl.vim
|
|
||||||
- 4 Minor Enhancements
|
|
||||||
* add mapping to switch to main pane. [minor] speed up buffer switch with noautocmd
|
|
||||||
* include zl.vim into source code
|
|
||||||
* tune for autocmd sequence
|
|
||||||
* treat winfixwidth and winfixheight separately
|
|
||||||
- 2 Bug Fixes
|
|
||||||
* winleave cause ignored windows resized
|
|
||||||
* cannot let &winminwidth > &winwidth
|
|
||||||
- 2 Nominal Changes
|
|
||||||
* change profile variable scope to s\:
|
|
||||||
* tweak golden ratio for win size
|
|
||||||
|
|
||||||
# __END__
|
|
||||||
# vim: filetype=yaml
|
|
@ -1,102 +0,0 @@
|
|||||||
# RELEASE HISTORY
|
|
||||||
|
|
||||||
## V1.3.0 / 2013-04-22
|
|
||||||
|
|
||||||
Diff Mode auto resizing (Zhao Cai <caizhaoff@gmail.com>)
|
|
||||||
|
|
||||||
Changes:
|
|
||||||
|
|
||||||
* 1 Major Enhancements
|
|
||||||
|
|
||||||
* diff mode auto-resizing.
|
|
||||||
|
|
||||||
* 1 Minor Enhancements
|
|
||||||
|
|
||||||
* refactor autocmd function: tweak restore behavior
|
|
||||||
|
|
||||||
|
|
||||||
## V1.2.2 / 2013-04-21
|
|
||||||
|
|
||||||
Improve documents and small bug fixes,
|
|
||||||
Load guard for #4 (github) (Zhao Cai <caizhaoff@gmail.com>)
|
|
||||||
|
|
||||||
Changes:
|
|
||||||
|
|
||||||
* 1 Minor Enhancements
|
|
||||||
|
|
||||||
* better tracing
|
|
||||||
|
|
||||||
* 1 Bug Fixes
|
|
||||||
|
|
||||||
* load guard for issue #4
|
|
||||||
|
|
||||||
E806: using Float as a String
|
|
||||||
|
|
||||||
|
|
||||||
## V1.2.0 / 2013-04-18
|
|
||||||
|
|
||||||
(Zhao Cai <caizhaoff@gmail.com>)
|
|
||||||
|
|
||||||
Changes:
|
|
||||||
|
|
||||||
* 1 Major Enhancements
|
|
||||||
|
|
||||||
* add restore rule for some special buffers
|
|
||||||
|
|
||||||
* 4 Bug Fixes
|
|
||||||
|
|
||||||
* E36 no enough room to split
|
|
||||||
* issue #2 MRU plugin window
|
|
||||||
* init sequence
|
|
||||||
* zl load guard
|
|
||||||
|
|
||||||
|
|
||||||
## V1.1.2 / 2013-04-18
|
|
||||||
|
|
||||||
Fix init sequence between zl.vim and GoldenVim (Zhao Cai <caizhaoff@gmail.com>)
|
|
||||||
|
|
||||||
|
|
||||||
## HEAD / 2013-04-23
|
|
||||||
|
|
||||||
Current Development (Zhao Cai)
|
|
||||||
|
|
||||||
|
|
||||||
## V1.1.1 / 2013-04-18
|
|
||||||
|
|
||||||
improve documents, fix zl library load (Zhao Cai <caizhaoff@gmail.com>)
|
|
||||||
|
|
||||||
|
|
||||||
## V1.1.0 / 2013-04-18
|
|
||||||
|
|
||||||
(Zhao Cai <caizhaoff@gmail.com>)
|
|
||||||
|
|
||||||
Changes:
|
|
||||||
|
|
||||||
* 3 Major Enhancements
|
|
||||||
|
|
||||||
* add WinLeave event into account. This version works perfectly.
|
|
||||||
* fix various hiccups caused by winleave
|
|
||||||
* use ignore rules from zl.vim
|
|
||||||
|
|
||||||
* 4 Minor Enhancements
|
|
||||||
|
|
||||||
* add mapping to switch to main pane. [minor] speed up buffer switch with noautocmd
|
|
||||||
* include zl.vim into source code
|
|
||||||
* tune for autocmd sequence
|
|
||||||
* treat winfixwidth and winfixheight separately
|
|
||||||
|
|
||||||
* 2 Bug Fixes
|
|
||||||
|
|
||||||
* winleave cause ignored windows resized
|
|
||||||
* cannot let &winminwidth > &winwidth
|
|
||||||
|
|
||||||
* 2 Nominal Changes
|
|
||||||
|
|
||||||
* change profile variable scope to s:
|
|
||||||
* tweak golden ratio for win size
|
|
||||||
|
|
||||||
|
|
||||||
## 1.0 / 2012-09-18
|
|
||||||
|
|
||||||
(Zhao Cai <caizhaoff@gmail.com>)
|
|
||||||
|
|
@ -1,343 +0,0 @@
|
|||||||
# Always have a nice view for vim split windows
|
|
||||||
|
|
||||||
------------- - -----------------------------------------------
|
|
||||||
Plugin : GoldenView.vim
|
|
||||||
Author : Zhao Cai
|
|
||||||
EMail : caizhaoff@gmail.com
|
|
||||||
Homepage : http://zhaocai.github.io/GoldenView.Vim/
|
|
||||||
Vim.org : http://www.vim.org/scripts/script.php?script_id=4529
|
|
||||||
Version : 1.3.6
|
|
||||||
Date Created : Tue 18 Sep 2012 05:23:13 PM EDT
|
|
||||||
Last Modified : Mon 22 Apr 2013 05:55:22 PM EDT
|
|
||||||
------------- - -----------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The initial motive for [GoldenView][GoldenView] comes from the frustration of using other vim plugins to auto-resize split windows. The idea is deadly simple and very useful: **resize the focused window to a proper size.** However, in practice, many hiccups makes **auto-resizing** not a smooth experience. Below are a list of issues [GoldenView][GoldenView] attempts to solve:
|
|
||||||
|
|
||||||
First and the most important one, auto-resizing should play nicely with existing plugins like `tagbar`, `vimfiler`, `unite`, `VOoM`, `quickfix`, `undotree`, `gundo`, etc. These windows should manage there own window size.
|
|
||||||
|
|
||||||
Second, auto-resizing should take care of **the other windows** too. Resizing the focused window may cause the other windows become too small. When you have 4+ split windows, auto-resizing may just make a mess out of it.
|
|
||||||
|
|
||||||
|
|
||||||
![GoldView Screencast]( http://dl.dropboxusercontent.com/u/1897501/Screencasts/GoldenView.gif )
|
|
||||||
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
[GoldenView][GoldenView] has preliminarily solved the issues described above. It also provides other features. Bascally, it does two things:
|
|
||||||
|
|
||||||
### 1. AutoResizing
|
|
||||||
First of all, it automatically resize the focused split window to a "golden" view based on [golden ratio][golden-ratio-wikipedia] and `textwidth`.
|
|
||||||
|
|
||||||
|
|
||||||
### 2. Tiled Windows Management
|
|
||||||
|
|
||||||
Second, it maps a single key (`<C-L>` by default) to nicely split windows to tiled windows.
|
|
||||||
|
|
||||||
```
|
|
||||||
----+----------------+------------+---+
|
|
||||||
| | | | |
|
|
||||||
| F | | S1 | T |
|
|
||||||
| I | +------------| A |
|
|
||||||
| L | | S2 | G |
|
|
||||||
| E | MAIN PANE +------------+ B |
|
|
||||||
| R | | S3 | A |
|
|
||||||
| | | | R |
|
|
||||||
| | | | |
|
|
||||||
+---+----------------+------------+---+
|
|
||||||
```
|
|
||||||
|
|
||||||
To get this view, just hit `<C-L>` 4 times. or, if you have a large monitor, you may get tiled windows below.
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
----+---------------+--------------+------------+---+
|
|
||||||
| | | | | |
|
|
||||||
| F | | | S1 | T |
|
|
||||||
| I | | +------------| A |
|
|
||||||
| L | | M2 | S2 | G |
|
|
||||||
| E | MAIN PANE | +------------+ B |
|
|
||||||
| R | | | S3 | A |
|
|
||||||
| | | | | B |
|
|
||||||
| | | | | |
|
|
||||||
+---+---------------+--------------+------------+---+
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
To quickly switch between those windows, a few keys are mapped to
|
|
||||||
|
|
||||||
- Focus to the main window
|
|
||||||
- Switch with the `MAIN PANE`, the largest, smallest, etc.
|
|
||||||
- Jump to the next and previous window
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Install [GoldenView][GoldenView] is the *same as installing other vim plugins*. If experienced with vim, you can skim the example below and move to [next section](#quick-start).
|
|
||||||
|
|
||||||
|
|
||||||
### **Option A** - With [Plugin Manager][vim-plugin-manager] ( **recommended** )
|
|
||||||
|
|
||||||
If you use plugin managers like *Pathogen*, *vundle*, *neobundle*, *vim-addon-manager*, etc., just unarchive the zip file or clone the [GoldenView][GoldenView] repo from `git://github.com/zhaocai/GoldenView.git` into your local plugin installation directory (most likely `~/.vim/bundle/`). Then add corresponding scripts in .vimrc for the bundle manager you are using.
|
|
||||||
|
|
||||||
**Example**:
|
|
||||||
|
|
||||||
- *neobundle*:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
NeoBundle 'zhaocai/GoldenView.Vim' "Always have a nice view for vim split windows
|
|
||||||
```
|
|
||||||
|
|
||||||
- *vundle*:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
Bundle 'zhaocai/GoldenView.Vim'
|
|
||||||
```
|
|
||||||
|
|
||||||
- *vim-addon-manager*:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
call vam#ActivateAddons(['GoldenView.Vim'], {'auto_install' : 1})
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### **Option B** - Without [Plugin Manager][vim-plugin-manager]
|
|
||||||
|
|
||||||
Unarchive the zip file into a directory that is under `runtimepath` of your vim, `~/.vim` for example.
|
|
||||||
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
[GoldenView][GoldenView] should work out of the box without configuration. It should automatically start to resize focused window to [golden ratio][golden-ratio-wikipedia] based on `textwidth` and vim available size. You may start to play with it now.
|
|
||||||
|
|
||||||
To get you started, a few default keys are mapped as below:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
" 1. split to tiled windows
|
|
||||||
nmap <silent> <C-L> <Plug>GoldenViewSplit
|
|
||||||
|
|
||||||
" 2. quickly switch current window with the main pane
|
|
||||||
" and toggle back
|
|
||||||
nmap <silent> <F8> <Plug>GoldenViewSwitchMain
|
|
||||||
nmap <silent> <S-F8> <Plug>GoldenViewSwitchToggle
|
|
||||||
|
|
||||||
" 3. jump to next and previous window
|
|
||||||
nmap <silent> <C-N> <Plug>GoldenViewNext
|
|
||||||
nmap <silent> <C-P> <Plug>GoldenViewPrevious
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
The meaning of those keys are self-explaining. A general workflow would be `<Plug>GoldenViewSplit` key to quickly and nicely split windows to the layout as below. Then you may open your files.
|
|
||||||
|
|
||||||
```
|
|
||||||
----+----------------+------------+---+
|
|
||||||
| | | | |
|
|
||||||
| F | | S1 | T |
|
|
||||||
| I | +------------| A |
|
|
||||||
| L | | S2 | G |
|
|
||||||
| E | MAIN PANE +------------+ B |
|
|
||||||
| R | | S3 | A |
|
|
||||||
| | | | R |
|
|
||||||
| | | | |
|
|
||||||
+---+----------------+------------+---+
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
To switch `S1` with `MAIN PANE`, in `S1` and hit `<Plug>GoldenViewSwitchMain`. To switch back, hit `<Plug>GoldenViewSwitchToggle` in either `MAIN PAIN` or `S1`
|
|
||||||
|
|
||||||
#### g:goldenview__enable_default_mapping
|
|
||||||
|
|
||||||
Every experienced vim user has a different set of key mappings. If you you are (most likely) unhappy about some of the mappings, map you own keys as below:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
let g:goldenview__enable_default_mapping = 0
|
|
||||||
|
|
||||||
nmap <silent> <MY_KEY> <Plug>GoldenViewSplit
|
|
||||||
" ... and so on
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
#### g:goldenview__enable_at_startup
|
|
||||||
|
|
||||||
if you do not want to start auto-resizing automatically, you can put the following script in your vimrc.
|
|
||||||
|
|
||||||
```vim
|
|
||||||
let g:goldenview__enable_at_startup = 0
|
|
||||||
```
|
|
||||||
|
|
||||||
## More Commands and Mappings
|
|
||||||
|
|
||||||
### `:ToggleGoldenViewAutoResize`
|
|
||||||
### `:DisableGoldenViewAutoResize`
|
|
||||||
### `:EnableGoldenViewAutoResize`
|
|
||||||
|
|
||||||
These commands toggle, enable, and disable GoldenView auto-resizing.
|
|
||||||
|
|
||||||
|
|
||||||
### `:GoldenViewResize`
|
|
||||||
this command do manual resizing of focused window.
|
|
||||||
|
|
||||||
You can also map a key for this as below:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
nmap <silent> <YOUR_KEY> <Plug>GoldenViewResize
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### `:SwitchGoldenViewMain`
|
|
||||||
### `:SwitchGoldenViewLargest`
|
|
||||||
### `:SwitchGoldenViewSmallest`
|
|
||||||
|
|
||||||
these commands do as it named.
|
|
||||||
|
|
||||||
You can also add mappings as below. ( no default keys for these mappings)
|
|
||||||
```vim
|
|
||||||
nmap <silent> <YOUR_KEY> <Plug>GoldenViewSwitchWithLargest
|
|
||||||
nmap <silent> <YOUR_KEY> <Plug>GoldenViewSwitchWithSmallest
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Other switch rules can be easily defined. If you have some ideas, please post to [github issue][GoldenViewIssue] for discussion.
|
|
||||||
|
|
||||||
|
|
||||||
## Rules
|
|
||||||
|
|
||||||
[GoldenView][] defines two rules:
|
|
||||||
|
|
||||||
### `g:goldenview__ignore_urule`
|
|
||||||
is to "ignore" - allow those special buffers to manage their own window size.
|
|
||||||
|
|
||||||
### `g:goldenview__restore_urule`
|
|
||||||
is to "restore" - restore window size of some of special buffers.
|
|
||||||
|
|
||||||
The `urule` (user rules) are like this, which will be normalize at runtime for faster processing.
|
|
||||||
|
|
||||||
```vim
|
|
||||||
\{
|
|
||||||
\ 'filetype' : [
|
|
||||||
\ '' ,
|
|
||||||
\ 'qf' , 'vimpager', 'undotree', 'tagbar',
|
|
||||||
\ 'nerdtree', 'vimshell', 'vimfiler', 'voom' ,
|
|
||||||
\ 'tabman' , 'unite' , 'quickrun', 'Decho' ,
|
|
||||||
\ ],
|
|
||||||
\ 'buftype' : [
|
|
||||||
\ 'nofile' ,
|
|
||||||
\ ],
|
|
||||||
\ 'bufname' : [
|
|
||||||
\ 'GoToFile' , 'diffpanel_\d\+' ,
|
|
||||||
\ '__Gundo_Preview__' , '__Gundo__' ,
|
|
||||||
\ '\[LustyExplorer-Buffers\]' , '\-MiniBufExplorer\-' ,
|
|
||||||
\ '_VOOM\d\+$' , '__Urannotate_\d\+__' ,
|
|
||||||
\ '__MRU_Files__' ,
|
|
||||||
\ ],
|
|
||||||
\},
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Profiles
|
|
||||||
[GoldenView][] defines two profile:
|
|
||||||
|
|
||||||
### `g:goldenview__active_profile`
|
|
||||||
defines the functions and preferences to auto resize windows.
|
|
||||||
|
|
||||||
### `g:goldenview__reset_profile`
|
|
||||||
|
|
||||||
defines reset preferences to restore everything to default.
|
|
||||||
|
|
||||||
|
|
||||||
`function GoldenView#ExtendProfile()` is provided to customize preferences.
|
|
||||||
|
|
||||||
For more details, please read the source code! :)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Troubleshooting:
|
|
||||||
|
|
||||||
### Please do not resize me!
|
|
||||||
|
|
||||||
[GoldenView][] maintains rules for "common" cases. But vim offers a great variety of plugins which defines buffers for special purposes. If you find some special buffers which is supposed to not be auto-resized. Please check `g:goldenview__ignore_urule`. You may extend the `g:goldenview__active_profile` yourself or post the issue to [github issue][GoldenViewIssue] for adding it to builtin support.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### [minibufexpl.vim][] takes 5+ lines
|
|
||||||
|
|
||||||
Check my fork [minibufexpl.vim][] to see if it is working for you. I have send pull request to the origin repo.
|
|
||||||
|
|
||||||
|
|
||||||
### I cannot resize window height to < 7
|
|
||||||
|
|
||||||
This is features. As mentioned in the [Introduction](#always-have-a-nice-view-for-vim-split-windows) section, there is no normal cases to have a normal window too small. For special cases like [minibufexpl.vim][], it can be handled case by case.
|
|
||||||
|
|
||||||
|
|
||||||
However, if you really want to have small windows. It can be done by :
|
|
||||||
|
|
||||||
```vim
|
|
||||||
|
|
||||||
" Extend a new profile named 'small-height' from default profile.
|
|
||||||
"
|
|
||||||
" 1. Change "2" to your desire minimal height
|
|
||||||
" 2. Change "small-height" to the profile name you like
|
|
||||||
" ---------------------------------------------------------------
|
|
||||||
call GoldenView#ExtendProfile('small-height', {
|
|
||||||
\ 'other_window_winheight' : 2 ,
|
|
||||||
\ })
|
|
||||||
|
|
||||||
let g:goldenview__active_profile = 'small-height'
|
|
||||||
```
|
|
||||||
|
|
||||||
(refer to issue #5)
|
|
||||||
|
|
||||||
### I still have Issues:
|
|
||||||
|
|
||||||
If you have any issues, please post it to [github issue][GoldenViewIssue] for discussion.
|
|
||||||
|
|
||||||
Remember to run the following command and post the results.
|
|
||||||
```vim
|
|
||||||
echo GoldenView#Info()
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## RELEASE HISTORY
|
|
||||||
|
|
||||||
Refer to [History.md]( https://github.com/zhaocai/GoldenView.Vim/blob/master/History.md )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## LICENSE:
|
|
||||||
|
|
||||||
Copyright (c) 2013 Zhao Cai \<caizhaoff@gmail.com\>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
|
||||||
Foundation, either version 3 of the License, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[dwm]: http://www.vim.org/scripts/script.php?script_id=4186
|
|
||||||
[golden-ratio-plugin]: http://www.vim.org/scripts/script.php?script_id=3690
|
|
||||||
[golden-ratio-wikipedia]: http://en.wikipedia.org/wiki/Golden_ratio
|
|
||||||
[zl]: https://github.com/zhaocai/zl.vim "zl.vim vim script library"
|
|
||||||
[GoldenView]: http://zhaocai.github.io/GoldenView.Vim/ "GoldenView Homepage"
|
|
||||||
[GoldenViewCode]: https://github.com/zhaocai/GoldenView.Vim "GoldenView Vim Plugin"
|
|
||||||
[vim-plugin-manager]: http://vim-scripts.org/vim/tools.html "Vim Plugin Manangers"
|
|
||||||
[GoldenViewIssue]: https://github.com/zhaocai/GoldenView.Vim/issues "GoldenView Issue Track"
|
|
||||||
[minibufexpl.vim]: https://github.com/zhaocai/minibufexpl.vim
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
require 'facets/string'
|
|
||||||
require 'rake/clean'
|
|
||||||
|
|
||||||
project_name = __FILE__.pathmap("%-1d")
|
|
||||||
|
|
||||||
def version
|
|
||||||
project_readme = FileList['README.*']
|
|
||||||
version_re = /Version \s+ : \s* (?<version> \d\.\d\.\d) $/x
|
|
||||||
|
|
||||||
project_readme.each { |f|
|
|
||||||
File.read(f).mscan(version_re).each { |m|
|
|
||||||
return m[:version]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "version"
|
|
||||||
task :version => [] do
|
|
||||||
puts version
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
desc "zip for distribution"
|
|
||||||
task :zip => [] do
|
|
||||||
sh "zip -r #{project_name}-#{version}.zip autoload plugin doc README.md --exclude='*/.DS_Store'"
|
|
||||||
end
|
|
||||||
|
|
||||||
CLEAN.include('*.zip')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vimup = File.expand_path('~/Developer/Vim/Bundle/tool/vimup/vimup')
|
|
||||||
vimorg = File.expand_path('~/.apps/vimup/vim.org.yml')
|
|
||||||
|
|
||||||
namespace :vimup do
|
|
||||||
desc "new vim.org script"
|
|
||||||
task :new do
|
|
||||||
sh vimup, 'new-script', project_name, vimorg
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "updae vim.org script"
|
|
||||||
task :release => [:zip] do
|
|
||||||
sh vimup, 'update-script', project_name, vimorg
|
|
||||||
task(:clean).invoke
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "updae vim.org script detail"
|
|
||||||
task :details do
|
|
||||||
sh vimup, 'update-details', project_name, vimorg
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,529 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : GoldenView
|
|
||||||
" Description : Always have a nice view for vim split windows
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/GoldenView.Vim
|
|
||||||
" Date Created : Tue 18 Sep 2012 10:25:23 AM EDT
|
|
||||||
" Last Modified : Fri 19 Oct 2012 05:55:17 PM EDT
|
|
||||||
" Tag : [ vim, window, golden-ratio ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Initialization And Profile: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#ExtendProfile(name, def)
|
|
||||||
let default = get(s:goldenview__profile, a:name,
|
|
||||||
\ copy(s:goldenview__profile['default']))
|
|
||||||
|
|
||||||
let s:goldenview__profile[a:name] = extend(default, a:def)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#Init()
|
|
||||||
if exists('g:goldenview__initialized') && g:goldenview__initialized == 1
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let s:goldenview__golden_ratio = 1.618
|
|
||||||
lockvar s:goldenview__golden_ratio
|
|
||||||
|
|
||||||
set equalalways
|
|
||||||
set eadirection=ver
|
|
||||||
|
|
||||||
|
|
||||||
let s:goldenview__profile = {
|
|
||||||
\ 'reset' : {
|
|
||||||
\ 'focus_window_winheight' : &winheight ,
|
|
||||||
\ 'focus_window_winwidth' : &winwidth ,
|
|
||||||
\ 'other_window_winheight' : &winminheight ,
|
|
||||||
\ 'other_window_winwidth' : &winminwidth ,
|
|
||||||
\ },
|
|
||||||
\ 'default' : {
|
|
||||||
\ 'focus_window_winheight' : function('GoldenView#GoldenHeight') ,
|
|
||||||
\ 'focus_window_winwidth' : function('GoldenView#TextWidth') ,
|
|
||||||
\ 'other_window_winheight' : function('GoldenView#GoldenMinHeight') ,
|
|
||||||
\ 'other_window_winwidth' : function('GoldenView#GoldenMinWidth') ,
|
|
||||||
\ },
|
|
||||||
\
|
|
||||||
\ }
|
|
||||||
|
|
||||||
call GoldenView#ExtendProfile('golden-ratio', {
|
|
||||||
\ 'focus_window_winwidth' : function('GoldenView#GoldenWidth') ,
|
|
||||||
\ })
|
|
||||||
|
|
||||||
let s:goldenview__ignore_nrule = GoldenView#zl#rule#norm(
|
|
||||||
\ g:goldenview__ignore_urule, {
|
|
||||||
\ 'logic' : 'or',
|
|
||||||
\ }
|
|
||||||
\ )
|
|
||||||
|
|
||||||
let s:goldenview__restore_nrule = GoldenView#zl#rule#norm(
|
|
||||||
\ g:goldenview__restore_urule, {
|
|
||||||
\ 'logic' : 'or',
|
|
||||||
\ }
|
|
||||||
\ )
|
|
||||||
let g:goldenview__initialized = 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Auto Resize: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#ToggleAutoResize()
|
|
||||||
if exists('s:goldenview__auto_resize') && s:goldenview__auto_resize == 1
|
|
||||||
call GoldenView#DisableAutoResize()
|
|
||||||
call GoldenView#zl#print#moremsg('GoldenView Auto Resize: Off')
|
|
||||||
else
|
|
||||||
call GoldenView#EnableAutoResize()
|
|
||||||
call GoldenView#zl#print#moremsg('GoldenView Auto Resize: On')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#EnableAutoResize()
|
|
||||||
|
|
||||||
call GoldenView#Init()
|
|
||||||
|
|
||||||
let active_profile = s:goldenview__profile[g:goldenview__active_profile]
|
|
||||||
call s:set_focus_window(active_profile)
|
|
||||||
call s:set_other_window(active_profile)
|
|
||||||
|
|
||||||
augroup GoldenView
|
|
||||||
au!
|
|
||||||
" Enter
|
|
||||||
autocmd VimResized * call GoldenView#Enter({'event' : 'VimResized'})
|
|
||||||
autocmd BufWinEnter * call GoldenView#Enter({'event' : 'BufWinEnter'})
|
|
||||||
autocmd WinEnter * call GoldenView#Enter({'event' : 'WinEnter'})
|
|
||||||
|
|
||||||
" Leave
|
|
||||||
autocmd WinLeave * call GoldenView#Leave()
|
|
||||||
augroup END
|
|
||||||
let s:goldenview__auto_resize = 1
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#DisableAutoResize()
|
|
||||||
au! GoldenView
|
|
||||||
call GoldenView#ResetResize()
|
|
||||||
|
|
||||||
let s:goldenview__auto_resize = 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#Leave(...)
|
|
||||||
|
|
||||||
" GoldenViewTrace 'WinLeave', a:000
|
|
||||||
|
|
||||||
" Do nothing if there is no split window
|
|
||||||
" --------------------------------------
|
|
||||||
if winnr('$') < 2
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
call GoldenView#Diff()
|
|
||||||
|
|
||||||
if GoldenView#IsIgnore()
|
|
||||||
" Record the last size of ignored windows. Restore there sizes if affected
|
|
||||||
" by GoldenView.
|
|
||||||
|
|
||||||
" For new split, the size does not count, which is highly possible
|
|
||||||
" to be resized later. Should use the size with WinLeave event.
|
|
||||||
"
|
|
||||||
call GoldenView#initialize_tab_variable()
|
|
||||||
let t:goldenview['bufs'][bufnr('%')] = {
|
|
||||||
\ 'winnr' : winnr() ,
|
|
||||||
\ 'winwidth' : winwidth(0) ,
|
|
||||||
\ 'winheight' : winheight(0) ,
|
|
||||||
\ }
|
|
||||||
let t:goldenview['cmdheight'] = &cmdheight
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#Diff()
|
|
||||||
" Diff Mode: auto-resize to equal size
|
|
||||||
if ! exists('b:goldenview_diff')
|
|
||||||
let b:goldenview_diff = 0
|
|
||||||
endif
|
|
||||||
if &diff
|
|
||||||
if ! b:goldenview_diff
|
|
||||||
for nr in GoldenView#zl#list#uniq(tabpagebuflist())
|
|
||||||
if getbufvar(nr, '&diff')
|
|
||||||
call setbufvar(nr, 'goldenview_diff', 1)
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
exec 'wincmd ='
|
|
||||||
endif
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
if b:goldenview_diff
|
|
||||||
let b:goldenview_diff = 0
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#Enter(...)
|
|
||||||
|
|
||||||
if GoldenView#Diff()
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if &lazyredraw
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
return call('GoldenView#Resize', a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#Resize(...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : resize focused window
|
|
||||||
"
|
|
||||||
" Args : {'event' : event}
|
|
||||||
" Return : none
|
|
||||||
"
|
|
||||||
" Raise : none from this function
|
|
||||||
"
|
|
||||||
" Pitfall :
|
|
||||||
" - Can not set winminwith > winwidth
|
|
||||||
" - AutoCmd Sequence:
|
|
||||||
" - `:copen` :
|
|
||||||
" 1. WinEnter (&ft inherited from last buffer)
|
|
||||||
" 2. BufWinEnter (&ft == '')
|
|
||||||
" 3. BufWinEnter (&ft == 'qf', set winfixheight)
|
|
||||||
" - `:split`
|
|
||||||
" 1. WinLeave current window
|
|
||||||
" 2. WinEnter new split window with current buffer
|
|
||||||
" 3. `split` return, user script may change the buffer
|
|
||||||
" type, width, etc.
|
|
||||||
"
|
|
||||||
"
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
" GoldenViewTrace 'GoldenView Resize', a:000
|
|
||||||
|
|
||||||
let opts = {'is_force' : 0}
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let winnr_diff = s:winnr_diff()
|
|
||||||
if winnr_diff > 0
|
|
||||||
" Plus Split Window:
|
|
||||||
" ++++++++++++++++++
|
|
||||||
|
|
||||||
" GoldenViewTrace '+++ winnr +++', a:000
|
|
||||||
return
|
|
||||||
|
|
||||||
elseif winnr_diff < 0
|
|
||||||
" Minus Split Window:
|
|
||||||
" -------------------
|
|
||||||
|
|
||||||
call GoldenView#initialize_tab_variable()
|
|
||||||
let saved_lazyredraw = &lazyredraw
|
|
||||||
set lazyredraw
|
|
||||||
let current_winnr = winnr()
|
|
||||||
|
|
||||||
" Restore: original size based on "g:goldenview__restore_urule"
|
|
||||||
" ------------------------------------------------------------
|
|
||||||
for winnr in range(1, winnr('$'))
|
|
||||||
let bufnr = winbufnr(winnr)
|
|
||||||
let bufsaved = get(t:goldenview['bufs'], bufnr, {})
|
|
||||||
|
|
||||||
" Ignored Case: same buffer displayed in multiply windows
|
|
||||||
" -------------------------------------------------------
|
|
||||||
if ! empty(bufsaved) && bufsaved['winnr'] == winnr
|
|
||||||
silent noautocmd exec winnr 'wincmd w'
|
|
||||||
|
|
||||||
if GoldenView#IsRestore()
|
|
||||||
silent exec 'vertical resize ' . bufsaved['winwidth']
|
|
||||||
silent exec 'resize ' . bufsaved['winheight']
|
|
||||||
|
|
||||||
" GoldenViewTrace 'restore buffer:'. nr, a:000
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
if &cmdheight != t:goldenview['cmdheight']
|
|
||||||
exec 'set cmdheight=' . t:goldenview['cmdheight']
|
|
||||||
endif
|
|
||||||
|
|
||||||
silent exec current_winnr 'wincmd w'
|
|
||||||
|
|
||||||
redraw
|
|
||||||
let &lazyredraw = saved_lazyredraw
|
|
||||||
|
|
||||||
" GoldenViewTrace '--- winnr ---', a:000
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if ! opts['is_force']
|
|
||||||
|
|
||||||
" Do nothing if there is no split window
|
|
||||||
if winnr('$') < 2
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if GoldenView#IsIgnore()
|
|
||||||
" GoldenViewTrace 'Ignored', a:000
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
let active_profile = s:goldenview__profile[g:goldenview__active_profile]
|
|
||||||
call s:set_focus_window(active_profile)
|
|
||||||
" GoldenViewTrace 'Set Focuse', a:000
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" reset focus windows minimal size
|
|
||||||
let &winheight = &winminheight
|
|
||||||
let &winwidth = &winminwidth
|
|
||||||
|
|
||||||
" GoldenViewTrace 'Reset Focus', a:000
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#IsIgnore()
|
|
||||||
return GoldenView#zl#rule#is_true(s:goldenview__ignore_nrule)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#IsRestore()
|
|
||||||
return GoldenView#zl#rule#is_true(s:goldenview__restore_nrule)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#ResetResize()
|
|
||||||
let reset_profile = s:goldenview__profile[g:goldenview__reset_profile]
|
|
||||||
call s:set_other_window(reset_profile, {'force' : 1})
|
|
||||||
call s:set_focus_window(reset_profile, {'force' : 1})
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#GoldenHeight(...)
|
|
||||||
return float2nr(&lines / s:goldenview__golden_ratio)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#GoldenWidth(...)
|
|
||||||
return float2nr(&columns / s:goldenview__golden_ratio)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#GoldenMinHeight(...)
|
|
||||||
return float2nr(GoldenView#GoldenHeight()/(5*s:goldenview__golden_ratio))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#GoldenMinWidth(...)
|
|
||||||
return float2nr(GoldenView#GoldenWidth()/(3*s:goldenview__golden_ratio))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#TextWidth(...)
|
|
||||||
let tw = &l:textwidth
|
|
||||||
|
|
||||||
if tw != 0
|
|
||||||
return float2nr(tw * 4/3)
|
|
||||||
else
|
|
||||||
let tw = float2nr(80 * 4/3)
|
|
||||||
let gw = GoldenView#GoldenWidth()
|
|
||||||
return tw > gw ? gw : tw
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! s:set_focus_window(profile,...)
|
|
||||||
let opts = {
|
|
||||||
\ 'force' : 0
|
|
||||||
\ }
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
try
|
|
||||||
if !&winfixwidth || opts['force']
|
|
||||||
let &winwidth =
|
|
||||||
\ s:eval(a:profile, a:profile['focus_window_winwidth'])
|
|
||||||
endif
|
|
||||||
if !&winfixheight || opts['force']
|
|
||||||
let &winheight =
|
|
||||||
\ s:eval(a:profile, a:profile['focus_window_winheight'])
|
|
||||||
endif
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E36/ " Not enough room
|
|
||||||
call GoldenView#zl#print#warning('GoldenView: ' . v:exception)
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:set_other_window(profile,...)
|
|
||||||
let opts = {
|
|
||||||
\ 'force' : 0
|
|
||||||
\ }
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
try
|
|
||||||
if !&winfixwidth || opts['force']
|
|
||||||
let &winminwidth =
|
|
||||||
\ s:eval(a:profile, a:profile['other_window_winwidth'])
|
|
||||||
endif
|
|
||||||
if !&winfixheight || opts['force']
|
|
||||||
let &winminheight =
|
|
||||||
\ s:eval(a:profile, a:profile['other_window_winheight'])
|
|
||||||
endif
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E36/ " Not enough room
|
|
||||||
call GoldenView#zl#print#warning('GoldenView: ' . v:exception)
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Split: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#Split()
|
|
||||||
call GoldenView#zl#window#split_nicely()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Switch: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#SwitchMain(...)
|
|
||||||
let opts = {
|
|
||||||
\ 'from_bufnr' : bufnr('%') ,
|
|
||||||
\}
|
|
||||||
if a:0 >= 1 && type(a:1) == type({})
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let window_count = winnr('$')
|
|
||||||
if window_count < 2
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let current_winnr = winnr()
|
|
||||||
let switched = 0
|
|
||||||
|
|
||||||
let saved_lazyredraw = &lazyredraw
|
|
||||||
set lazyredraw
|
|
||||||
for i in range(1, window_count)
|
|
||||||
silent noautocmd exec i 'wincmd w'
|
|
||||||
|
|
||||||
if ! GoldenView#IsIgnore()
|
|
||||||
let switched = GoldenView#zl#window#switch_buffer(
|
|
||||||
\ opts['from_bufnr'], winbufnr(i))
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
redraw
|
|
||||||
let &lazyredraw = saved_lazyredraw
|
|
||||||
|
|
||||||
if switched
|
|
||||||
call GoldenView#Resize({'event' : 'WinEnter'})
|
|
||||||
else
|
|
||||||
silent noautocmd exec current_winnr 'wincmd w'
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Helper Functions: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! s:eval(profile, val)
|
|
||||||
if GoldenView#zl#var#is_number(a:val)
|
|
||||||
return a:val
|
|
||||||
elseif GoldenView#zl#var#is_funcref(a:val)
|
|
||||||
return a:val(a:profile)
|
|
||||||
else
|
|
||||||
try
|
|
||||||
return eval(a:val)
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E/
|
|
||||||
throw 'GoldenView: invalid profile value type!'
|
|
||||||
endtry
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#initialize_tab_variable()
|
|
||||||
if !exists('t:goldenview')
|
|
||||||
let t:goldenview = {
|
|
||||||
\ 'nrwin' : winnr('$') ,
|
|
||||||
\ 'cmdheight' : &cmdheight ,
|
|
||||||
\ 'bufs' : {} ,
|
|
||||||
\ }
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:winnr_diff()
|
|
||||||
call GoldenView#initialize_tab_variable()
|
|
||||||
|
|
||||||
let nrwin = winnr('$')
|
|
||||||
if nrwin != t:goldenview['nrwin']
|
|
||||||
let diff = nrwin - t:goldenview['nrwin']
|
|
||||||
let t:goldenview['nrwin'] = nrwin
|
|
||||||
return diff
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Debug: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! GoldenView#Info()
|
|
||||||
return {
|
|
||||||
\ 'buffer' : {
|
|
||||||
\ 'filetype' : &ft ,
|
|
||||||
\ 'buftype' : &buftype ,
|
|
||||||
\ 'bufname' : bufname('%') ,
|
|
||||||
\ 'winwidth' : winwidth(0) ,
|
|
||||||
\ 'winheight' : winheight(0) ,
|
|
||||||
\ },
|
|
||||||
\ 'goldenview' : get(t:, 'goldenview', GoldenView#initialize_tab_variable()),
|
|
||||||
\ 'setting' : {
|
|
||||||
\ 'win_count' : winnr('$') ,
|
|
||||||
\ 'lazyredraw' : &lazyredraw ,
|
|
||||||
\ 'cmdheight' : &cmdheight ,
|
|
||||||
\ 'winfixwidth' : &winfixwidth ,
|
|
||||||
\ 'winfixheight' : &winfixheight ,
|
|
||||||
\ 'winwidth' : &winwidth ,
|
|
||||||
\ 'winminwidth' : &winminwidth ,
|
|
||||||
\ 'winheight' : &winheight ,
|
|
||||||
\ 'winminheight' : &winminheight ,
|
|
||||||
\ }
|
|
||||||
\}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#Trace(...)
|
|
||||||
" -------- - -----------------------------------------------
|
|
||||||
" Example : >
|
|
||||||
" GoldenViewTrace 'WinLeave', a:000
|
|
||||||
" -------- - -----------------------------------------------
|
|
||||||
|
|
||||||
call GoldenView#initialize_tab_variable()
|
|
||||||
let info = GoldenView#Info()
|
|
||||||
let info['context'] = get(g:,'GoldenView_zl_context','')
|
|
||||||
let info['args'] = a:000
|
|
||||||
call GoldenView#zl#log#debug(info)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
command! -nargs=* -complete=expression GoldenViewTrace
|
|
||||||
\ exec GoldenView#zl#vim#context() | call GoldenView#Trace(<args>)
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=syntax fmr=⟨⟨⟨,⟩⟩⟩ fdl=1 :
|
|
@ -1,126 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Synopsis : list helper functions
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Version : 0.1
|
|
||||||
" Date Created : Sat 03 Sep 2011 03:54:00 PM EDT
|
|
||||||
" Last Modified : Thu 20 Sep 2012 04:25:10 PM EDT
|
|
||||||
" Tag : [ vim, list ]
|
|
||||||
" Copyright : (c) 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Sort: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! GoldenView#zl#list#unique_sort(list, ...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Args : list, [func]
|
|
||||||
" Return : unique sorted list
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Refer : http://vim.wikia.com/wiki/Unique_sorting
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
let list = copy(a:list)
|
|
||||||
|
|
||||||
if exists('a:1') && type(a:1) == type(function('function'))
|
|
||||||
call sort(list, a:1)
|
|
||||||
else
|
|
||||||
call sort(list)
|
|
||||||
endif
|
|
||||||
if len(list) <= 1 | return list | endif
|
|
||||||
let result = [ list[0] ]
|
|
||||||
let last = list[0]
|
|
||||||
let i = 1
|
|
||||||
while i < len(list)
|
|
||||||
if last != list[i]
|
|
||||||
let last = list[i]
|
|
||||||
call add(result, last)
|
|
||||||
endif
|
|
||||||
let i += 1
|
|
||||||
endwhile
|
|
||||||
return result
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#list#sort_by(list, expr)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : sort list by expr
|
|
||||||
"
|
|
||||||
" Args : v:val is used in {expr}
|
|
||||||
" Return : sroted list
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
" let list = [{'a' : 1}, {'a' : 22}, {'a' : 3}]
|
|
||||||
" echo GoldenView#zl#list#sort_by(list, 'v:val["a"]')
|
|
||||||
"
|
|
||||||
" Refer : vital.vim
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
let pairs = map(a:list, printf('[v:val, %s]', a:expr))
|
|
||||||
return map(GoldenView#zl#list#sort(pairs,
|
|
||||||
\ 'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'),
|
|
||||||
\ 'v:val[0]')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:_compare(a, b)
|
|
||||||
return eval(s:expr)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#list#sort(list, expr)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : sort list with expr to compare two values.
|
|
||||||
"
|
|
||||||
" Args : a:a and a:b can be used in {expr}
|
|
||||||
" Return : sroted list
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Refer : vital.vim
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
if type(a:expr) == type(function('function'))
|
|
||||||
return sort(a:list, a:expr)
|
|
||||||
endif
|
|
||||||
let s:expr = a:expr
|
|
||||||
return sort(a:list, 's:_compare')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#list#uniq(list, ...)
|
|
||||||
let list = a:0
|
|
||||||
\ ? map(copy(a:list), printf('[v:val, %s]', a:1))
|
|
||||||
\ : copy(a:list)
|
|
||||||
let i = 0
|
|
||||||
let seen = {}
|
|
||||||
while i < len(list)
|
|
||||||
let key = string(a:0 ? list[i][1] : list[i])
|
|
||||||
if has_key(seen, key)
|
|
||||||
call remove(list, i)
|
|
||||||
else
|
|
||||||
let seen[key] = 1
|
|
||||||
let i += 1
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
return a:0 ? map(list, 'v:val[0]') : list
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=⟨⟨⟨,⟩⟩⟩ fdl=1 :
|
|
@ -1,310 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : log.vim
|
|
||||||
" Synopsis : vim script library: log
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Sat 03 Sep 2012 03:54:00 PM EDT
|
|
||||||
" Last Modified : Sat 27 Apr 2013 06:58:13 PM EDT
|
|
||||||
" Tag : [ vim, log ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Logger: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
if !has('ruby')
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#info(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#log#level_info(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#debug(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#log#level_debug(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#warn(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#log#level_warn(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#error(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#log#level_error(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#fatal(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#log#level_fatal(...)
|
|
||||||
call GoldenView#zl#print#warning("GoldenView(log): require vim to be built with +ruby.")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
|
|
||||||
function! <SID>get_logfile()
|
|
||||||
if GoldenView#zl#sys#is_mac()
|
|
||||||
let logfile = expand('~/Library/Logs/vim/GoldenView.log')
|
|
||||||
elseif GoldenView#zl#sys#is_win()
|
|
||||||
let logfile = "C:/windows/temp/vim/GoldenView.log"
|
|
||||||
elseif GoldenView#zl#sys#is_linux()
|
|
||||||
let logfile = expand('/var/log/vim/GoldenView.log')
|
|
||||||
else
|
|
||||||
let logfile = input('Please Input logfile: ', '/var/log/vim/GoldenView.log', 'file')
|
|
||||||
endif
|
|
||||||
let log_dir = fnamemodify(logfile, ':p:h')
|
|
||||||
if !isdirectory(log_dir)
|
|
||||||
call mkdir(log_dir, 'p')
|
|
||||||
endif
|
|
||||||
return logfile
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:GoldenView_zl_ruby_loaded = 0
|
|
||||||
function! <SID>setup_ruby()
|
|
||||||
if s:GoldenView_zl_ruby_loaded == 0
|
|
||||||
|
|
||||||
let logfile = <SID>get_logfile()
|
|
||||||
|
|
||||||
ruby << __RUBY__
|
|
||||||
# ($LOAD_PATH << File.join(Vim.evaluate('g:GoldenView_zl_autoload_path'), 'lib')).uniq!
|
|
||||||
require "logger"
|
|
||||||
require "awesome_print"
|
|
||||||
|
|
||||||
$GoldenView_zl_logger = Logger.new(Vim.evaluate('logfile'), 'weekly')
|
|
||||||
__RUBY__
|
|
||||||
|
|
||||||
autocmd VimLeavePre * call <SID>cleanup_ruby()
|
|
||||||
let s:GoldenView_zl_ruby_loaded = 1
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! <SID>cleanup_ruby()
|
|
||||||
if s:GoldenView_zl_ruby_loaded
|
|
||||||
ruby $GoldenView_zl_logger.close
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
" --------------------------------%>--------------------------------
|
|
||||||
" Example:
|
|
||||||
" function! Trace(...) abort
|
|
||||||
" let message = {}
|
|
||||||
" let message['context'] = get(g:,'GoldenView_zl_context','')
|
|
||||||
" let message['args'] = a:000
|
|
||||||
" call GoldenView#zl#log#info(message)
|
|
||||||
" endfunction
|
|
||||||
"
|
|
||||||
" command! -nargs=* -complete=expression Trace
|
|
||||||
" \ exec GoldenView#zl#vim#context() | call GoldenView#zl#log#info(<args>)
|
|
||||||
" --------------------------------%<--------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#info(...)
|
|
||||||
call <SID>setup_ruby()
|
|
||||||
ruby << __RUBY__
|
|
||||||
|
|
||||||
args = Vim.evaluate('a:000')
|
|
||||||
|
|
||||||
case args.size
|
|
||||||
when 0
|
|
||||||
return
|
|
||||||
when 1
|
|
||||||
$GoldenView_zl_logger.info("GoldenView") { args[0].ai(:plain => true) }
|
|
||||||
when 2
|
|
||||||
$GoldenView_zl_logger.info(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
else
|
|
||||||
$GoldenView_zl_logger.info(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
end
|
|
||||||
__RUBY__
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#level_info()
|
|
||||||
ruby $GoldenView_zl_logger.level = Logger::INFO
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#debug(...)
|
|
||||||
call <SID>setup_ruby()
|
|
||||||
ruby << __RUBY__
|
|
||||||
|
|
||||||
args = Vim.evaluate('a:000')
|
|
||||||
|
|
||||||
case args.size
|
|
||||||
when 0
|
|
||||||
return
|
|
||||||
when 1
|
|
||||||
$GoldenView_zl_logger.debug("GoldenView") { args[0].ai(:plain => true) }
|
|
||||||
when 2
|
|
||||||
$GoldenView_zl_logger.debug(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
else
|
|
||||||
$GoldenView_zl_logger.debug(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
end
|
|
||||||
__RUBY__
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#level_debug()
|
|
||||||
ruby $GoldenView_zl_logger.level = Logger::DEBUG
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#warn(...)
|
|
||||||
call <SID>setup_ruby()
|
|
||||||
ruby << __RUBY__
|
|
||||||
|
|
||||||
args = Vim.evaluate('a:000')
|
|
||||||
|
|
||||||
case args.size
|
|
||||||
when 0
|
|
||||||
return
|
|
||||||
when 1
|
|
||||||
$GoldenView_zl_logger.warn("GoldenView") { args[0].ai(:plain => true) }
|
|
||||||
when 2
|
|
||||||
$GoldenView_zl_logger.warn(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
else
|
|
||||||
$GoldenView_zl_logger.warn(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
end
|
|
||||||
__RUBY__
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#level_warn()
|
|
||||||
ruby $GoldenView_zl_logger.level = Logger::WARN
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#error(...)
|
|
||||||
call <SID>setup_ruby()
|
|
||||||
ruby << __RUBY__
|
|
||||||
|
|
||||||
args = Vim.evaluate('a:000')
|
|
||||||
|
|
||||||
case args.size
|
|
||||||
when 0
|
|
||||||
return
|
|
||||||
when 1
|
|
||||||
$GoldenView_zl_logger.error("GoldenView") { args[0].ai(:plain => true) }
|
|
||||||
when 2
|
|
||||||
$GoldenView_zl_logger.error(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
else
|
|
||||||
$GoldenView_zl_logger.error(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
end
|
|
||||||
__RUBY__
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#level_error()
|
|
||||||
ruby $GoldenView_zl_logger.level = Logger::ERROR
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#fatal(...)
|
|
||||||
call <SID>setup_ruby()
|
|
||||||
ruby << __RUBY__
|
|
||||||
|
|
||||||
args = Vim.evaluate('a:000')
|
|
||||||
|
|
||||||
case args.size
|
|
||||||
when 0
|
|
||||||
return
|
|
||||||
when 1
|
|
||||||
$GoldenView_zl_logger.fatal("GoldenView") { args[0].ai(:plain => true) }
|
|
||||||
when 2
|
|
||||||
$GoldenView_zl_logger.fatal(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
else
|
|
||||||
$GoldenView_zl_logger.fatal(args[0]) { args[1].ai(:plain => true) }
|
|
||||||
end
|
|
||||||
__RUBY__
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#log#level_fatal()
|
|
||||||
ruby $GoldenView_zl_logger.level = Logger::FATAL
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ts=4 sw=4 tw=78 fdm=marker fmr=[[[,]]] fdl=1 :
|
|
||||||
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : print.vim
|
|
||||||
" Synopsis : vim script library: print
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Sat 03 Sep 2011 03:54:00 PM EDT
|
|
||||||
" Last Modified : Thu 20 Sep 2012 04:25:11 PM EDT
|
|
||||||
" Tag : [ vim, print ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Echo Message: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! GoldenView#zl#print#echomsg(message, ...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : echomsg wrapper
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
" - message to print
|
|
||||||
" - opts : >
|
|
||||||
" {
|
|
||||||
" 'hl' : 'MoreMsg' ,
|
|
||||||
" }
|
|
||||||
" Return :
|
|
||||||
" Raise :
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
if empty(a:message) | return | endif
|
|
||||||
let opts = {
|
|
||||||
\ 'hl' : 'MoreMsg',
|
|
||||||
\ }
|
|
||||||
if a:0 >= 1 && type(a:1) == type({})
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
execute 'echohl ' . opts.hl
|
|
||||||
for m in split(a:message, "\n")
|
|
||||||
echomsg m
|
|
||||||
endfor
|
|
||||||
echohl NONE
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#print#warning(message)
|
|
||||||
call GoldenView#zl#print#echomsg(a:message, {'hl':'WarningMsg'})
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#print#error(message)
|
|
||||||
call GoldenView#zl#print#echomsg(a:message, {'hl':'ErrorMsg'})
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#print#moremsg(message)
|
|
||||||
call GoldenView#zl#print#echomsg(a:message, {'hl':'MoreMsg'})
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ts=4 sw=4 tw=78 fdm=marker fmr=⟨⟨⟨,⟩⟩⟩ fdl=1 :
|
|
||||||
|
|
||||||
|
|
@ -1,222 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Description : vim script library
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Mon 03 Sep 2012 09:05:14 AM EDT
|
|
||||||
" Last Modified : Thu 18 Apr 2013 03:16:39 PM EDT
|
|
||||||
" Tag : [ vim, library ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Initialization: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
let s:GOLDENVIEW_ZL_VERSION_CURRENT = 140
|
|
||||||
|
|
||||||
let s:VERSION_FACTOR = str2float('0.01')
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#rc#init() abort
|
|
||||||
if exists('g:loaded_GoldenView_zl')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if v:version < 700
|
|
||||||
echoerr "zl.vim: requires Vim >= 7"
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
if !exists("g:GoldenView_zl_force_reload")
|
|
||||||
let g:GoldenView_zl_force_reload = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !exists("g:GoldenView_zl_debug_mode")
|
|
||||||
let g:GoldenView_zl_debug_mode = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
let g:loaded_GoldenView_zl = s:GOLDENVIEW_ZL_VERSION_CURRENT * s:VERSION_FACTOR
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#rc#load_guard(prefix, vim_version, GoldenView_zl_version,exprs,...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : gereric script load guard function
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
" - prefix : to generate loaded_var_name
|
|
||||||
" - vim_version : minmium vim version requirement
|
|
||||||
" - GoldenView_zl_version : minmium zl.vim version requirement.
|
|
||||||
" set 0 to ignore.
|
|
||||||
" - exprs : assert list of expresses to be true
|
|
||||||
" - ... scope : 'g' , 'b', ...
|
|
||||||
"
|
|
||||||
" Return :
|
|
||||||
" - 1 : unloaded
|
|
||||||
" - 0 : already loaded
|
|
||||||
"
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
" try | if !GoldenView#zl#rc#load_guard(expand('<sfile>:t:r'), 703, 140, ['!&cp'])
|
|
||||||
" finish
|
|
||||||
" endif
|
|
||||||
" catch /^Vim\%((\a\+)\)\=:E117/
|
|
||||||
" " E117: Unknown Function
|
|
||||||
" throw 'zl.vim is required!'
|
|
||||||
" endtry
|
|
||||||
"
|
|
||||||
" Details :
|
|
||||||
" g:loaded_{script name} is defined as 1 if:
|
|
||||||
" - vim version > 702
|
|
||||||
" - zl version > 100
|
|
||||||
" - test !&cp is true
|
|
||||||
"
|
|
||||||
" Refer :
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
" call Dfunc('GoldenView#zl#rc#load_guard(' . a:prefix .' '. a:vim_version .' '. a:GoldenView_zl_version .' '. join(a:exprs))
|
|
||||||
|
|
||||||
let l:scope = a:0 >= 1 ? a:1 : 'g'
|
|
||||||
|
|
||||||
let l:loaded_var_name = l:scope . ':loaded_'
|
|
||||||
\ . substitute(a:prefix, '[^0-9a-zA-Z_]', '_', 'g')
|
|
||||||
" call Decho("loaded_var_name: " . l:loaded_var_name)
|
|
||||||
|
|
||||||
if exists(l:loaded_var_name) && g:GoldenView_zl_force_reload == 0
|
|
||||||
" call Decho(l:loaded_var_name . ' loaded: return 0')
|
|
||||||
" call Dret('GoldenView#zl#rc#load_guard')
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
if a:vim_version > 0 && a:vim_version > v:version
|
|
||||||
echoerr l:loaded_var_name . ' requires Vim version '
|
|
||||||
\ . string(a:vim_version * s:VERSION_FACTOR)
|
|
||||||
return 0
|
|
||||||
elseif a:GoldenView_zl_version > 0
|
|
||||||
if !exists("g:loaded_GoldenView_zl")
|
|
||||||
echoerr 'zl.vim is required but not loaded'
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
if (a:GoldenView_zl_version > s:GOLDENVIEW_ZL_VERSION_CURRENT)
|
|
||||||
echoerr l:loaded_var_name . ' requires zl library version '
|
|
||||||
\ . string(a:GoldenView_zl_version * s:VERSION_FACTOR)
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
for expr in a:exprs
|
|
||||||
if !eval(expr)
|
|
||||||
echoerr l:loaded_var_name . ' requires: ' . expr
|
|
||||||
" call Dret('GoldenView#zl#rc#load_guard')
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
let {l:loaded_var_name} = 1
|
|
||||||
" call Dret('GoldenView#zl#rc#load_guard')
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#rc#script_force_reload(...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : Call to ignore GoldenView#zl#rc#load_guard() and source.
|
|
||||||
"
|
|
||||||
" Args : script path or current script by default
|
|
||||||
" Return :
|
|
||||||
" Raise : E484: cannot open file
|
|
||||||
"
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
let script = a:0 >= 1 ? a:1 : '%'
|
|
||||||
|
|
||||||
let l:saved = g:GoldenView_zl_force_reload
|
|
||||||
let g:GoldenView_zl_force_reload = 1
|
|
||||||
|
|
||||||
exec "so " . script
|
|
||||||
|
|
||||||
let g:GoldenView_zl_force_reload = l:saved
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#rc#init_python()
|
|
||||||
if has("python3")
|
|
||||||
let g:GoldenView_zl_py = 'py3'
|
|
||||||
let g:GoldenView_zl_pyeval = 'py3eval'
|
|
||||||
elseif has("python")
|
|
||||||
let g:GoldenView_zl_py = 'py'
|
|
||||||
let g:GoldenView_zl_pyeval = 'pyeval'
|
|
||||||
else
|
|
||||||
let g:GoldenView_zl_py = ''
|
|
||||||
let g:GoldenView_zl_pyeval = ''
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Set Initialization Default Variables: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#zl#rc#set_default(var, ...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : Set Initialization Default Variables
|
|
||||||
"
|
|
||||||
" Args : ('var', val) || ( {dict} )
|
|
||||||
" Return :
|
|
||||||
" Raise : 'zl.vim ***'
|
|
||||||
"
|
|
||||||
" Pitfall : avoid 's:' variables, which will be defined in
|
|
||||||
" this rc.vim script bur your script
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
" call GoldenView#zl#rc#set_default({
|
|
||||||
" \ 'g:xxx_yyy' : {
|
|
||||||
" \ 'abc' : 1,
|
|
||||||
" \ }
|
|
||||||
" \
|
|
||||||
" \ , 'g:yyy_zzz' : 'bcd'
|
|
||||||
" \ })
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
if type(a:var) == type({})
|
|
||||||
for key in keys(a:var)
|
|
||||||
call <SID>set_default(key, a:var[key])
|
|
||||||
endfor
|
|
||||||
elseif type(a:var) == type("")
|
|
||||||
if a:0 >= 1
|
|
||||||
call <SID>set_default(a:var, a:1)
|
|
||||||
else
|
|
||||||
throw "zl.vim should call with default value for " . a:var
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
throw "zl.vim unsupported type: " . type(a:var)
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:set_default(var,val)
|
|
||||||
if !exists(a:var) || type({a:var}) != type(a:val)
|
|
||||||
let {a:var} = a:val
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"
|
|
||||||
" Note:
|
|
||||||
" add this call to other files if they need to check g:loaded_GoldenView_zl
|
|
||||||
" or g:GoldenView_zl_install_path
|
|
||||||
"
|
|
||||||
call GoldenView#zl#rc#init()
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=[[[,]]] fdl=1 :
|
|
@ -1,94 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : regex.vim
|
|
||||||
" Description : vim library: Regular Expression
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Mon 03 Sep 2012 09:05:14 AM EDT
|
|
||||||
" Last Modified : Thu 20 Sep 2012 04:25:12 PM EDT
|
|
||||||
" Tag : [ vim, library, regex ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Regex Escape: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#zl#regex#escape(text, ...) " (text, ?magic='m') ⟨⟨⟨2
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : escape common special characters.
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
"
|
|
||||||
" - text to escape
|
|
||||||
" - magic : one of m, M, v, V. See :help 'magic'
|
|
||||||
"
|
|
||||||
" Return : escaped text
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : echo GoldenView#zl#regex#escape('I|||love&you\\\', 'v')
|
|
||||||
"
|
|
||||||
" Refer :
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
let l:magic = a:0 >= 1 ? a:1 : 'm'
|
|
||||||
|
|
||||||
if l:magic =~# '^\\\?m$'
|
|
||||||
return escape(a:text, '^$.*\[]~')
|
|
||||||
elseif l:magic =~# '^\\\?M$'
|
|
||||||
return escape(a:text, '^$\')
|
|
||||||
elseif l:magic =~# '^\\\?V$'
|
|
||||||
return escape(a:text, '\')
|
|
||||||
elseif l:magic =~# '^\\\?v$'
|
|
||||||
return substitute(a:text, '[^0-9a-zA-Z_]', '\\&', 'g')
|
|
||||||
else
|
|
||||||
throw 'unsupported magic type'
|
|
||||||
return a:text
|
|
||||||
endif
|
|
||||||
endfunction " ⟩⟩⟩
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ----------------------------------------------------------------------------
|
|
||||||
" Regex Builder: ⟨⟨⟨1
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#regex#or(list, ...) "⟨⟨⟨
|
|
||||||
let opts =
|
|
||||||
\ { 'is_capturing' : 0
|
|
||||||
\ , 'magic' : 'm'
|
|
||||||
\ }
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let begin = opts['is_capturing'] ? '\(' : '\%('
|
|
||||||
let or = '\|'
|
|
||||||
let end = '\)'
|
|
||||||
|
|
||||||
if opts['magic'] =~# '^\\\?v$'
|
|
||||||
let begin = opts['is_capturing'] ? '(' : '%('
|
|
||||||
let or = '|'
|
|
||||||
let end = ')'
|
|
||||||
endif
|
|
||||||
|
|
||||||
return begin
|
|
||||||
\ . join(map(
|
|
||||||
\ a:list, 'GoldenView#zl#regex#escape(v:val, "' . opts['magic'] . '")'),
|
|
||||||
\ or)
|
|
||||||
\ . end
|
|
||||||
endfunction "⟩⟩⟩
|
|
||||||
|
|
||||||
" ⟩⟩⟩
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=⟨⟨⟨,⟩⟩⟩ fdl=1 :
|
|
@ -1,331 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : rule.vim
|
|
||||||
" Synopsis : vim script library: rule
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Sat 03 Sep 2011 03:54:00 PM EDT
|
|
||||||
" Last Modified : Sat 29 Sep 2012 01:03:24 AM EDT
|
|
||||||
" Tag : [ vim, rule ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Rule: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
" [TODO]( list for at type ) @zhaocai @start(2012-09-27 08:05)
|
|
||||||
|
|
||||||
let s:rule_types = [
|
|
||||||
\ 'filetype', 'buftype', 'mode' , 'cword',
|
|
||||||
\ 'bufname' , 'at' , 'syntax', 'expr' ,
|
|
||||||
\ ]
|
|
||||||
let s:nrule = {
|
|
||||||
\ 'eval_order' : copy(s:rule_types),
|
|
||||||
\ 'eval_negate' : [] ,
|
|
||||||
\ 'logic' : 'or' ,
|
|
||||||
\ 'rule' : {} ,
|
|
||||||
\ }
|
|
||||||
|
|
||||||
function! GoldenView#zl#rule#norm(urule, ...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : normalize rules
|
|
||||||
"
|
|
||||||
" Rule :
|
|
||||||
" - "urule" : "Unnormalized RULE", rules written by users.
|
|
||||||
" - "nrule" : "Nnormalized RULE", rules completed with
|
|
||||||
" optional items and internal items.
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
" - urule: un-normalized rule
|
|
||||||
" - opts :
|
|
||||||
" - eval_order : order in s:rule_types,
|
|
||||||
" - eval_negate : reverse eval result
|
|
||||||
" - logic :
|
|
||||||
" - {or} : 'v:filetype || v:bufname || ...'
|
|
||||||
" - {and} : 'v:filetype && v:bufname && ...'
|
|
||||||
" - {string} : similar to v:val for filter()
|
|
||||||
"
|
|
||||||
" Return : normalized rules
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
"
|
|
||||||
" Refer :
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
let nrule = deepcopy(s:nrule)
|
|
||||||
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(nrule, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let type_expr = {
|
|
||||||
\ 'buftype' : '&buftype' ,
|
|
||||||
\ 'filetype' : '&ft' ,
|
|
||||||
\ 'bufname' : "bufname('%')" ,
|
|
||||||
\ 'cword' : "expand('<cword>')" ,
|
|
||||||
\ }
|
|
||||||
|
|
||||||
let type_pat = {}
|
|
||||||
for type in ['filetype', 'buftype', 'syntax']
|
|
||||||
if has_key(a:urule, type)
|
|
||||||
let type_pat[type] = '^\%(' . join(a:urule[type], '\|') . '\)$'
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
for type in ['bufname', 'cword']
|
|
||||||
if has_key(a:urule, type)
|
|
||||||
let type_pat[type] = '^\%('
|
|
||||||
\ . join(map(a:urule[type], 'GoldenView#zl#regex#escape(v:val)'), '\|')
|
|
||||||
\ . '\)$'
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
|
|
||||||
" normalize each type of rules
|
|
||||||
for type in ['mode']
|
|
||||||
if has_key(a:urule, type)
|
|
||||||
let nrule.rule[type] = a:urule[type]
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
for type in ['filetype', 'buftype', 'bufname', 'cword']
|
|
||||||
if has_key(a:urule, type)
|
|
||||||
let nrule.rule[type] =
|
|
||||||
\ {
|
|
||||||
\ 'eval_expr' : 1 ,
|
|
||||||
\ 'expr' : type_expr[type] ,
|
|
||||||
\ 'pat' : type_pat[type] ,
|
|
||||||
\ }
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
|
|
||||||
for type in ['syntax']
|
|
||||||
if has_key(a:urule, type)
|
|
||||||
let nrule.rule[type] = type_pat[type]
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
for type in ['mode', 'at']
|
|
||||||
if has_key(a:urule, type)
|
|
||||||
let nrule.rule[type] = a:urule[type]
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
for type in ['expr']
|
|
||||||
if has_key(a:urule, type)
|
|
||||||
try | let nrule.rule[type] =
|
|
||||||
\ join(
|
|
||||||
\ map(
|
|
||||||
\ map(
|
|
||||||
\ copy(a:urule[type])
|
|
||||||
\ ,"join(v:val,' || ')"
|
|
||||||
\ )
|
|
||||||
\ , "'('.v:val.')'"
|
|
||||||
\ )
|
|
||||||
\ ,' && '
|
|
||||||
\ )
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E714/ " E714: List required
|
|
||||||
throw 'zl(rule): expr rule should be written as list of lists.'
|
|
||||||
endtry
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
call filter(
|
|
||||||
\ nrule['eval_order']
|
|
||||||
\ , 'has_key(nrule.rule, v:val) && !empty(nrule.rule[v:val])'
|
|
||||||
\ )
|
|
||||||
|
|
||||||
return nrule
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#rule#is_true(nrule, ...)
|
|
||||||
try
|
|
||||||
return call('GoldenView#zl#rule#logic_'.a:nrule['logic'], [a:nrule] + a:000)
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E129/
|
|
||||||
throw 'zl(rule): undefined logic funcref'
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#rule#is_false(nrule, ...)
|
|
||||||
return !call('GoldenView#zl#rule#is_true', [a:nrule] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
" rule logic
|
|
||||||
function! s:_return(nrule, type, ret)
|
|
||||||
return
|
|
||||||
\ index(a:nrule.eval_negate, a:type) >= 0
|
|
||||||
\ ? !a:ret
|
|
||||||
\ : a:ret
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#rule#logic_or(nrule, ...)
|
|
||||||
let opts = {}
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
for type in a:nrule['eval_order']
|
|
||||||
if s:_return(a:nrule, type, s:eval_{type}(a:nrule['rule'], opts))
|
|
||||||
return 1
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#rule#logic_and(nrule, ...)
|
|
||||||
let opts = {}
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
for type in a:nrule['eval_order']
|
|
||||||
if !s:_return(a:nrule, type, s:eval_{type}(a:nrule['rule'], opts))
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#rule#logic_expr(nrule, ...)
|
|
||||||
let opts = {}
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let str = a:nrule['expr']
|
|
||||||
for type in a:nrule['eval_order']
|
|
||||||
let str = substitute(str
|
|
||||||
\ , 'v:'.type
|
|
||||||
\ , string(
|
|
||||||
\ s:_return(a:nrule, type,
|
|
||||||
\ s:eval_{type}(a:nrule['rule'], opts)
|
|
||||||
\ )
|
|
||||||
\ )
|
|
||||||
\ , 'ge'
|
|
||||||
\ )
|
|
||||||
endfor
|
|
||||||
|
|
||||||
try
|
|
||||||
return eval(str)
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E/
|
|
||||||
throw printf('zl(rule): eval(%s) raises %s', str, v:exception)
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" nrule eval
|
|
||||||
function! s:eval_filetype(nrule, ...)
|
|
||||||
return call('s:_eval_match', ['filetype', a:nrule] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:eval_cword(nrule, ...)
|
|
||||||
return call('s:_eval_match', ['cword', a:nrule] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:eval_buftype(nrule, ...)
|
|
||||||
return call('s:_eval_match', ['buftype', a:nrule] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:eval_bufname(nrule, ...)
|
|
||||||
return call('s:_eval_match', ['bufname', a:nrule] + a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! s:eval_at(nrule, ...)
|
|
||||||
return search(get(a:nrule, 'at', '\%#'), 'bcnW')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:eval_mode(nrule, ...)
|
|
||||||
let mode_pat = get(a:nrule, 'mode', [])
|
|
||||||
let mode_expr =
|
|
||||||
\ a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
\ ? get(a:1, 'mode', mode())
|
|
||||||
\ : mode()
|
|
||||||
|
|
||||||
return
|
|
||||||
\ !empty(
|
|
||||||
\ filter(
|
|
||||||
\ mode_pat
|
|
||||||
\ , 'stridx(mode_expr, v:val) == -1'
|
|
||||||
\ )
|
|
||||||
\ )
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:eval_syntax(nrule, ...)
|
|
||||||
let pat = get(a:nrule, 'syntax', '')
|
|
||||||
|
|
||||||
let opts = {}
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1)
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
let syn_names = GoldenView#zl#syntax#synstack_names(opts)
|
|
||||||
|
|
||||||
return !empty(filter(syn_names, 'match(v:val, pat) != -1'))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:eval_expr(nrule, ...)
|
|
||||||
try
|
|
||||||
return eval(get(a:nrule, 'expr', 1))
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E/
|
|
||||||
return 0
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:_eval_match(type, nrule, ...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : internal match evluation
|
|
||||||
" Rule :
|
|
||||||
" { 'type' :
|
|
||||||
" {
|
|
||||||
" 'eval_expr' : (1|0) ,
|
|
||||||
" 'expr' : {expr} ,
|
|
||||||
" 'pat' : {pat} ,
|
|
||||||
" }
|
|
||||||
" }
|
|
||||||
"
|
|
||||||
" Args : [{type}, {nrule}[, {opts}]]
|
|
||||||
" Return :
|
|
||||||
" - 0 : false
|
|
||||||
" - 1 : true
|
|
||||||
" Raise : zl(rule)
|
|
||||||
"
|
|
||||||
" Refer : vimhelp:match()
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
let rule = copy(get(a:nrule, a:type, {}))
|
|
||||||
if empty(rule)
|
|
||||||
throw 'zl(rule): ' . v:exception
|
|
||||||
endif
|
|
||||||
|
|
||||||
" opt for {expr} from runtime opts
|
|
||||||
if a:0 >= 1 && GoldenView#zl#var#is_dict(a:1) && has_key(a:1, a:type)
|
|
||||||
let rt_rule = a:1[a:type]
|
|
||||||
if GoldenView#zl#var#is_dict(rt_rule)
|
|
||||||
call extend(rule, rt_rule)
|
|
||||||
elseif GoldenView#zl#var#is_string(rt_rule)
|
|
||||||
let rule['expr'] = rt_rule
|
|
||||||
let rule['eval_expr'] = 0
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
if rule['eval_expr']
|
|
||||||
let rule['expr'] = eval(rule['expr'])
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
return call('match', [rule['expr'], rule['pat']]) != -1
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E/
|
|
||||||
throw 'zl(rule): ' . v:exception
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=[[[,]]] fdl=1 :
|
|
@ -1,78 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : sys.vim
|
|
||||||
" Description : vim library
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Mon 03 Sep 2012 09:05:14 AM EDT
|
|
||||||
" Last Modified : Thu 20 Sep 2012 04:25:15 PM EDT
|
|
||||||
" Tag : [ vim, library ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Environment: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! GoldenView#zl#sys#ostype()
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Args :
|
|
||||||
" Return :
|
|
||||||
" - Mac, Windows, Linux, FreeBSD, SunOS, Unix,
|
|
||||||
" - undefined
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
" call GoldenView#zl#rc#set_default('g:os_type', GoldenView#zl#sys#ostype())
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
if (has("win32") || has("win95") || has("win64") || has("win16"))
|
|
||||||
let s:os_type = "Windows"
|
|
||||||
elseif has('mac')
|
|
||||||
let s:os_type="Mac"
|
|
||||||
elseif has('unix')
|
|
||||||
let arch = system("uname | tr -d '\n'")
|
|
||||||
if ( arch=="Linux" )
|
|
||||||
let s:os_type="Linux"
|
|
||||||
elseif ( arch=="FreeBSD" )
|
|
||||||
let s:os_type="FreeBSD"
|
|
||||||
elseif ( arch=="SunOS" )
|
|
||||||
let s:os_type="SunOS"
|
|
||||||
elseif ( arch=="Darwin" )
|
|
||||||
let s:os_type="Mac"
|
|
||||||
else
|
|
||||||
let s:os_type="Unix"
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return s:os_type
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#sys#is_cygwin()
|
|
||||||
return s:is_cygwin
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#sys#is_win()
|
|
||||||
return s:os_type == 'Windows'
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#sys#is_mac()
|
|
||||||
return s:os_type == 'Mac'
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#sys#is_linux()
|
|
||||||
return s:os_type == 'Linux'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let s:os_type = GoldenView#zl#sys#ostype()
|
|
||||||
let s:is_cygwin = has('win32unix')
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=[[[,]]] fdl=1 :
|
|
@ -1,86 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : var.vim
|
|
||||||
" Synopsis : vim script library: variable
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Sat 03 Sep 2011 03:54:00 PM EDT
|
|
||||||
" Last Modified : Thu 20 Sep 2012 04:25:16 PM EDT
|
|
||||||
" Tag : [ vim, variable ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Type: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : Wrapper functions for type()
|
|
||||||
"
|
|
||||||
" Refer : vital.vim
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
let [
|
|
||||||
\ s:__TYPE_NUMBER,
|
|
||||||
\ s:__TYPE_STRING,
|
|
||||||
\ s:__TYPE_FUNCREF,
|
|
||||||
\ s:__TYPE_LIST,
|
|
||||||
\ s:__TYPE_DICT,
|
|
||||||
\ s:__TYPE_FLOAT
|
|
||||||
\] = [
|
|
||||||
\ type(3),
|
|
||||||
\ type(""),
|
|
||||||
\ type(function('tr')),
|
|
||||||
\ type([]),
|
|
||||||
\ type({}),
|
|
||||||
\ has('float') ? type(str2float('0')) : -1
|
|
||||||
\]
|
|
||||||
" __TYPE_FLOAT = -1 when -float
|
|
||||||
" This doesn't match to anything.
|
|
||||||
|
|
||||||
" Number or Float
|
|
||||||
function! GoldenView#zl#var#is_numeric(Value)
|
|
||||||
let _ = type(a:Value)
|
|
||||||
return _ ==# s:__TYPE_NUMBER
|
|
||||||
\ || _ ==# s:__TYPE_FLOAT
|
|
||||||
endfunction
|
|
||||||
" Number
|
|
||||||
function! GoldenView#zl#var#is_integer(Value)
|
|
||||||
return type(a:Value) ==# s:__TYPE_NUMBER
|
|
||||||
endfunction
|
|
||||||
function! GoldenView#zl#var#is_number(Value)
|
|
||||||
return type(a:Value) ==# s:__TYPE_NUMBER
|
|
||||||
endfunction
|
|
||||||
" Float
|
|
||||||
function! GoldenView#zl#var#is_float(Value)
|
|
||||||
return type(a:Value) ==# s:__TYPE_FLOAT
|
|
||||||
endfunction
|
|
||||||
" String
|
|
||||||
function! GoldenView#zl#var#is_string(Value)
|
|
||||||
return type(a:Value) ==# s:__TYPE_STRING
|
|
||||||
endfunction
|
|
||||||
" Funcref
|
|
||||||
function! GoldenView#zl#var#is_funcref(Value)
|
|
||||||
return type(a:Value) ==# s:__TYPE_FUNCREF
|
|
||||||
endfunction
|
|
||||||
" List
|
|
||||||
function! GoldenView#zl#var#is_list(Value)
|
|
||||||
return type(a:Value) ==# s:__TYPE_LIST
|
|
||||||
endfunction
|
|
||||||
" Dictionary
|
|
||||||
function! GoldenView#zl#var#is_dict(Value)
|
|
||||||
return type(a:Value) ==# s:__TYPE_DICT
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=[[[,]]] fdl=1 :
|
|
@ -1,50 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Description : vim library: vim
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Date Created : Mon 03 Sep 2012 09:05:14 AM EDT
|
|
||||||
" Last Modified : Thu 20 Sep 2012 06:01:48 PM EDT
|
|
||||||
" Tag : [ vim, library, debug ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Context: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#zl#vim#context()
|
|
||||||
" -------- - -----------------------------------------------
|
|
||||||
" Desc : generate context
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
" function BeTraced(...)
|
|
||||||
" exec GoldenView#zl#vim#context() | call XXX#Trace(a:000)
|
|
||||||
" endfunction
|
|
||||||
"
|
|
||||||
" function XXX#Trace(...)
|
|
||||||
" let context = g:GoldenView_zl_context
|
|
||||||
" "...
|
|
||||||
" endfunction
|
|
||||||
" Refer :
|
|
||||||
" -------- - -----------------------------------------------
|
|
||||||
return
|
|
||||||
\'try
|
|
||||||
\| throw ""
|
|
||||||
\|catch
|
|
||||||
\| let g:GoldenView_zl_context = v:throwpoint
|
|
||||||
\|endtry
|
|
||||||
\'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: [[[1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=[[[,]]] fdl=1 :
|
|
@ -1,432 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : window.vim
|
|
||||||
" Synopsis : vim script library: window
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/zl.vim
|
|
||||||
" Version : 0.1
|
|
||||||
" Date Created : Sat 03 Sep 2011 03:54:00 PM EDT
|
|
||||||
" Last Modified : Tue 23 Oct 2012 04:59:06 PM EDT
|
|
||||||
" Tag : [ vim, syntax ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Status: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
call GoldenView#zl#rc#set_default({
|
|
||||||
\ 'g:GoldenView_zl_window__ignore_urule' : {
|
|
||||||
\ 'filetype' : [
|
|
||||||
\ '' ,
|
|
||||||
\ 'qf' , 'vimpager', 'undotree', 'tagbar',
|
|
||||||
\ 'nerdtree', 'vimshell', 'vimfiler', 'voom' ,
|
|
||||||
\ 'tabman' , 'unite' , 'quickrun', 'Decho' ,
|
|
||||||
\ ],
|
|
||||||
\ 'buftype' : [
|
|
||||||
\ 'nofile' ,
|
|
||||||
\ ],
|
|
||||||
\ 'bufname' : [
|
|
||||||
\ 'GoToFile' , 'diffpanel_\d\+' ,
|
|
||||||
\ '__Gundo_Preview__' , '__Gundo__' ,
|
|
||||||
\ '\[LustyExplorer-Buffers\]' , '\-MiniBufExplorer\-' ,
|
|
||||||
\ '_VOOM\d\+$' , '__Urannotate_\d\+__' ,
|
|
||||||
\ '__MRU_Files__' ,
|
|
||||||
\ ],
|
|
||||||
\ },
|
|
||||||
\ })
|
|
||||||
|
|
||||||
let s:GoldenView_zl_window__ignore_nrule = GoldenView#zl#rule#norm(
|
|
||||||
\ g:GoldenView_zl_window__ignore_urule, {
|
|
||||||
\ 'logic' : 'or',
|
|
||||||
\ }
|
|
||||||
\ )
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#is_last_visible()
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : check if no visible buffer left
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
"
|
|
||||||
" Return :
|
|
||||||
" - 0 : false
|
|
||||||
" - 1 : true
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
for i in range(tabpagenr('$'))
|
|
||||||
let tabnr = i + 1
|
|
||||||
for bufnr in tabpagebuflist(tabnr)
|
|
||||||
let ft = getbufvar(bufnr, '&ft')
|
|
||||||
let buftype = getbufvar(bufnr, '&buftype')
|
|
||||||
if empty(ft) && empty(buftype)
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
if ! GoldenView#zl#rule#is_true(s:GoldenView_zl_window__ignore_nrule)
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return 1
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Move: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
let s:golden_ratio = 1.618
|
|
||||||
function! GoldenView#zl#window#next_window_or_tab()
|
|
||||||
if tabpagenr('$') == 1 && winnr('$') == 1
|
|
||||||
call GoldenView#zl#window#split_nicely()
|
|
||||||
elseif winnr() < winnr("$")
|
|
||||||
wincmd w
|
|
||||||
else
|
|
||||||
tabnext
|
|
||||||
wincmd w
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#previous_window_or_tab()
|
|
||||||
if winnr() > 1
|
|
||||||
wincmd W
|
|
||||||
else
|
|
||||||
tabprevious
|
|
||||||
execute winnr("$") . "wincmd w"
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Size: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#zl#window#golden_ratio_width()
|
|
||||||
return float2nr(&columns / s:golden_ratio)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#golden_ratio_height()
|
|
||||||
return float2nr(&lines / s:golden_ratio)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#textwidth()
|
|
||||||
return &tw == 0 ? 78 : &tw
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Split: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#nicely_split_cmd(...)
|
|
||||||
let opts = {
|
|
||||||
\ 'winnr' : 0 ,
|
|
||||||
\}
|
|
||||||
if a:0 >= 1 && type(a:1) == type({})
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let ww = winwidth(opts['winnr'])
|
|
||||||
let tw = &textwidth
|
|
||||||
|
|
||||||
if tw != 0 && ww > s:golden_ratio * tw
|
|
||||||
return 'vsplit'
|
|
||||||
endif
|
|
||||||
|
|
||||||
if ww > &columns / s:golden_ratio
|
|
||||||
return 'vsplit'
|
|
||||||
endif
|
|
||||||
|
|
||||||
return 'split'
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#split_nicely()
|
|
||||||
let split_cmd = GoldenView#zl#window#nicely_split_cmd()
|
|
||||||
try
|
|
||||||
exec split_cmd
|
|
||||||
catch /^Vim\%((\a\+)\)\=:E36/
|
|
||||||
if split_cmd == 'split'
|
|
||||||
let &winminheight = &winminheight / 2
|
|
||||||
else
|
|
||||||
let &winminwidth = &winminwidth / 2
|
|
||||||
endif
|
|
||||||
exec split_cmd
|
|
||||||
endtry
|
|
||||||
wincmd p
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#toggle_split()
|
|
||||||
let prev_name = winnr()
|
|
||||||
silent! wincmd w
|
|
||||||
if prev_name == winnr()
|
|
||||||
split
|
|
||||||
else
|
|
||||||
call GoldenView#zl#buf#quit()
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Sort: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#zl#window#sort_by(...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : sort buffer by size, height, or width
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
" - opts : > ↓
|
|
||||||
" {
|
|
||||||
" 'by' : size|height|width|winnr|bufnr ,
|
|
||||||
" 'tabnr' : tabpagenr() ,
|
|
||||||
" 'width_weight' : s:golden_ratio ,
|
|
||||||
" 'height_weight' : 1 ,
|
|
||||||
" }
|
|
||||||
"
|
|
||||||
" Return : sorted list of
|
|
||||||
" {
|
|
||||||
" 'bufnr' : bufnr ,
|
|
||||||
" 'winnr' : winnr ,
|
|
||||||
" 'width' : width ,
|
|
||||||
" 'height' : height ,
|
|
||||||
" 'size' : size ,
|
|
||||||
" }
|
|
||||||
"
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
let opts = {
|
|
||||||
\ 'by' : 'size' ,
|
|
||||||
\ 'tabnr' : tabpagenr() ,
|
|
||||||
\ 'width_weight' : s:golden_ratio ,
|
|
||||||
\ 'height_weight' : 1 ,
|
|
||||||
\}
|
|
||||||
if a:0 >= 1 && type(a:1) == type({})
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let list = []
|
|
||||||
for bufnr in tabpagebuflist(opts['tabnr'])
|
|
||||||
let winnr = bufwinnr(bufnr)
|
|
||||||
let width = winwidth(winnr)
|
|
||||||
let height = winheight(winnr)
|
|
||||||
let size = width * opts['width_weight']
|
|
||||||
\ + height * opts['height_weight']
|
|
||||||
|
|
||||||
call add(list, {
|
|
||||||
\ 'bufnr' : bufnr ,
|
|
||||||
\ 'winnr' : winnr ,
|
|
||||||
\ 'width' : width ,
|
|
||||||
\ 'height' : height ,
|
|
||||||
\ 'size' : size ,
|
|
||||||
\ })
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return GoldenView#zl#list#sort_by(list,'v:val["'.opts['by'].'"]')
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Switch: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#switch_buffer_toggle(...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : toggle buffer switch
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
" - opts : >
|
|
||||||
" {
|
|
||||||
" 'with' : 'largest' ,
|
|
||||||
" }
|
|
||||||
"
|
|
||||||
" Return :
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
" nnoremap <silent> <C-@>
|
|
||||||
" \ :<C-u>call GoldenView#zl#window#switch_buffer_toggle()<CR>
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
let opts = {
|
|
||||||
\ 'with' : 'largest',
|
|
||||||
\}
|
|
||||||
if a:0 >= 1 && type(a:1) == type({})
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let bufnr = bufnr('%')
|
|
||||||
if exists('b:switch_buffer')
|
|
||||||
\ && bufwinnr(b:switch_buffer['bufnr']) == b:switch_buffer['winnr']
|
|
||||||
call GoldenView#zl#window#switch_buffer(bufnr, b:switch_buffer['bufnr'])
|
|
||||||
else
|
|
||||||
try
|
|
||||||
let fn = 'GoldenView#zl#window#switch_buffer_with_'.opts['with']
|
|
||||||
exec 'call ' . fn . '()'
|
|
||||||
catch /^Vim%((a+))=:E700/
|
|
||||||
throw "zl: function " . fn . 'for ' . opts['with']
|
|
||||||
\ . ' is not implemented!'
|
|
||||||
endtry
|
|
||||||
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#switch_buffer_with_sorted_by_size_index(index, ...)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : switch buffer with the largest window
|
|
||||||
"
|
|
||||||
" Args :
|
|
||||||
" - opts : >
|
|
||||||
" {
|
|
||||||
" 'bufnr' : bufnr('%') ,
|
|
||||||
" 'by' : 'size'|'height'|'width' ,
|
|
||||||
" 'tabnr' : tabpagenr() ,
|
|
||||||
" 'width_weight' : s:golden_ratio ,
|
|
||||||
" 'height_weight' : 1 ,
|
|
||||||
" }
|
|
||||||
"
|
|
||||||
" Return :
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
" nnoremap <silent> <C-@>
|
|
||||||
" \ :<C-u>call GoldenView#zl#window#switch_buffer_with_largest()<CR>
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
let opts = {
|
|
||||||
\ 'bufnr' : bufnr('%') ,
|
|
||||||
\ 'by' : 'size' ,
|
|
||||||
\ 'tabnr' : tabpagenr() ,
|
|
||||||
\ 'width_weight' : s:golden_ratio ,
|
|
||||||
\ 'height_weight' : 1 ,
|
|
||||||
\}
|
|
||||||
if a:0 >= 1 && type(a:1) == type({})
|
|
||||||
call extend(opts, a:1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let sorted = GoldenView#zl#window#sort_by(filter(copy(opts),'v:key != "bufnr"'))
|
|
||||||
let bufnr_to = sorted[a:index]['bufnr']
|
|
||||||
call GoldenView#zl#window#switch_buffer(opts['bufnr'], bufnr_to)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#switch_buffer_with_largest(...)
|
|
||||||
call GoldenView#zl#window#switch_buffer_with_sorted_by_size_index(-1, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#switch_buffer_with_smallest(...)
|
|
||||||
call GoldenView#zl#window#switch_buffer_with_sorted_by_size_index(0, a:000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#switch_buffer(bufnr1, bufnr2)
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
" Desc : switch buffer window if both are visible
|
|
||||||
"
|
|
||||||
" Args : bufnr1 <-> bufnr2
|
|
||||||
" Return :
|
|
||||||
" - 0 : fail
|
|
||||||
" - 1 : success
|
|
||||||
" Raise :
|
|
||||||
"
|
|
||||||
" Example : >
|
|
||||||
"
|
|
||||||
" Refer :
|
|
||||||
"--------- ------------------------------------------------
|
|
||||||
let winnr1 = bufwinnr(a:bufnr1)
|
|
||||||
let winnr2 = bufwinnr(a:bufnr2)
|
|
||||||
if winnr1 != -1 && winnr2 != -1
|
|
||||||
|
|
||||||
silent noautocmd exec winnr1 'wincmd w'
|
|
||||||
if bufnr('%') != a:bufnr2
|
|
||||||
silent noautocmd exec 'buffer' a:bufnr2
|
|
||||||
let b:switch_buffer = {
|
|
||||||
\ 'bufnr' : a:bufnr1 ,
|
|
||||||
\ 'winnr' : winnr2 ,
|
|
||||||
\ }
|
|
||||||
endif
|
|
||||||
silent noautocmd exec winnr2 'wincmd w'
|
|
||||||
if bufnr('%') != a:bufnr1
|
|
||||||
silent noautocmd exec 'buffer' a:bufnr1
|
|
||||||
|
|
||||||
" need filetype detect (maybe) because bufnr1 disappears for a
|
|
||||||
" moment
|
|
||||||
silent filetype detect
|
|
||||||
|
|
||||||
let b:switch_buffer = {
|
|
||||||
\ 'bufnr' : a:bufnr2 ,
|
|
||||||
\ 'winnr' : winnr1 ,
|
|
||||||
\ }
|
|
||||||
endif
|
|
||||||
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#alternate_buffer()
|
|
||||||
if bufnr('%') != bufnr('#') && buflisted(bufnr('#'))
|
|
||||||
buffer #
|
|
||||||
else
|
|
||||||
let cnt = 0
|
|
||||||
let pos = 1
|
|
||||||
let current = 0
|
|
||||||
while pos <= bufnr('$')
|
|
||||||
if buflisted(pos)
|
|
||||||
if pos == bufnr('%')
|
|
||||||
let current = cnt
|
|
||||||
endif
|
|
||||||
|
|
||||||
let cnt += 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
let pos += 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
if current > cnt / 2
|
|
||||||
bprevious
|
|
||||||
else
|
|
||||||
bnext
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Scroll: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
function! GoldenView#zl#window#scroll_other_window(direction)
|
|
||||||
execute 'wincmd' (winnr('#') == 0 ? 'w' : 'p')
|
|
||||||
execute (a:direction ? "normal! \<C-d>" : "normal! \<C-u>")
|
|
||||||
wincmd p
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" View: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
function! GoldenView#zl#window#save_view_command(command) range
|
|
||||||
let view = winsaveview()
|
|
||||||
|
|
||||||
let range = ''
|
|
||||||
if a:firstline != a:lastline
|
|
||||||
let range = a:firstline.','.a:lastline
|
|
||||||
endif
|
|
||||||
try
|
|
||||||
keepjumps execute range.a:command
|
|
||||||
finally
|
|
||||||
call winrestview(view)
|
|
||||||
endtry
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=⟨⟨⟨,⟩⟩⟩ fdl=1 :
|
|
||||||
|
|
@ -1,366 +0,0 @@
|
|||||||
*GoldenView.txt* Always have a nice view for vim split windows
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
CONTENTS *goldenview-contents*
|
|
||||||
|
|
||||||
1. Introduction |goldenview-introduction|
|
|
||||||
2. Features |goldenview-features|
|
|
||||||
1. 1. AutoResizing |goldenview-1.-autoresizing|
|
|
||||||
2. 2. Tiled Windows Management |goldenview-2.-tiled-windows-management|
|
|
||||||
3. Installation |goldenview-installation|
|
|
||||||
1. Option A - With Plugin Manager [4] ( recommanded )
|
|
||||||
2. Option B - Without Plugin Manager [4]
|
|
||||||
4. Quick Start |goldenview-quick-start|
|
|
||||||
1. |g:goldenview__enable_default_mapping|
|
|
||||||
2. |g:goldenview__enable_at_startup|
|
|
||||||
5. More Commands and Mappings |goldenview-more-commands-and-mappings|
|
|
||||||
1. |:ToggleGoldenViewAutoResize|
|
|
||||||
2. |:DisableGoldenViewAutoResize|
|
|
||||||
3. |:EnableGoldenViewAutoResize|
|
|
||||||
4. |:GoldenViewResize|
|
|
||||||
5. |:SwitchGoldenViewLargest|
|
|
||||||
6. |:SwitchGoldenViewSmallest|
|
|
||||||
6. Rules |goldenview-rules|
|
|
||||||
1. |g:goldenview__ignore_urule|
|
|
||||||
2. |g:goldenview__restore_urule|
|
|
||||||
7. Profiles |goldenview-profiles|
|
|
||||||
1. |g:goldenview__active_profile|
|
|
||||||
2. |g:goldenview__reset_profile|
|
|
||||||
8. Troubleshooting: |goldenview-troubleshooting:|
|
|
||||||
1. Please do not resize me! |goldenview-please-do-not-resize-me|
|
|
||||||
2. minibufexpl.vim [6] takes 5+ lines |goldenview-minibufexpl.vim-6-takes-5-lines|
|
|
||||||
3. I still have Issues: |goldenview-i-still-have-issues:|
|
|
||||||
9. Contributors |goldenview-contributors|
|
|
||||||
10. RELEASE HISTORY |goldenview-release-history|
|
|
||||||
11. LICENSE: |goldenview-license:|
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
INTRODUCTION *goldenview-introduction*
|
|
||||||
>
|
|
||||||
------------- - -----------------------------------------------
|
|
||||||
Plugin : GoldenView.vim
|
|
||||||
Author : Zhao Cai
|
|
||||||
EMail : caizhaoff@gmail.com
|
|
||||||
URL : http://zhaocai.github.io/GoldenView.Vim/
|
|
||||||
Version : 1.2.2
|
|
||||||
Date Created : Tue 18 Sep 2012 05:23:13 PM EDT
|
|
||||||
Last Modified : Wed 17 Apr 2013 09:52:45 PM EDT
|
|
||||||
------------- - -----------------------------------------------
|
|
||||||
|
|
||||||
The initial motive for GoldenView [1] comes from the frustration of using
|
|
||||||
other vim plugins to auto-resize split windows. The idea is deadly simple and
|
|
||||||
very useful: resize the focused window to a proper size. However, in practice,
|
|
||||||
many hiccups makes auto-resizing not a smooth experience. Below are a list of
|
|
||||||
issues GoldenView [1] attempts to solve:
|
|
||||||
|
|
||||||
First and the most important one, auto-resizing should play nicely with
|
|
||||||
existing plugins like 'tagbar', 'vimfiler', 'unite', 'VOoM', 'quickfix',
|
|
||||||
'undotree', 'gundo', etc. These windows should manage there own window size.
|
|
||||||
|
|
||||||
Second, auto-resizing should take care of the other windows too. Resizing the
|
|
||||||
focused window may cause the other windows become too small. When you have 4+
|
|
||||||
split windows, auto-resizing may just make a mess out of it.
|
|
||||||
|
|
||||||
GoldView Screencast, see reference [2]
|
|
||||||
|
|
||||||
GoldView Screencast
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
FEATURES *goldenview-features*
|
|
||||||
|
|
||||||
GoldenView [1] has preliminarily solved the issues described above. It also
|
|
||||||
provides other features. Bascally, it does two things:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
1. AUTORESIZING *goldenview-1.-autoresizing*
|
|
||||||
|
|
||||||
First of all, it automatically resize the focused split window to a "golden"
|
|
||||||
view based on golden ratio [3] and 'textwidth'.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
2. TILED WINDOWS MANAGEMENT *goldenview-2.-tiled-windows-management*
|
|
||||||
|
|
||||||
Second, it maps a single key ('<C-L>' by default) to nicely split windows to
|
|
||||||
tiled windows.
|
|
||||||
>
|
|
||||||
----+----------------+------------+---+
|
|
||||||
| | | | |
|
|
||||||
| F | | S1 | T |
|
|
||||||
| I | +------------| A |
|
|
||||||
| L | | S2 | G |
|
|
||||||
| E | MAIN PANE +------------+ B |
|
|
||||||
| R | | S3 | A |
|
|
||||||
| | | | R |
|
|
||||||
| | | | |
|
|
||||||
+---+----------------+------------+---+
|
|
||||||
|
|
||||||
To get this view, just hit '<C-L>' 4 times. or, if you have a large monitor,
|
|
||||||
you may get tiled windows below.
|
|
||||||
>
|
|
||||||
----+---------------+--------------+------------+---+
|
|
||||||
| | | | | |
|
|
||||||
| F | | | S1 | T |
|
|
||||||
| I | | +------------| A |
|
|
||||||
| L | | M2 | S2 | G |
|
|
||||||
| E | MAIN PANE | +------------+ B |
|
|
||||||
| R | | | S3 | A |
|
|
||||||
| | | | | B |
|
|
||||||
| | | | | |
|
|
||||||
+---+---------------+--------------+------------+---+
|
|
||||||
|
|
||||||
To quickly switch between those windows, a few keys are mapped to
|
|
||||||
|
|
||||||
- Focus to the main window
|
|
||||||
|
|
||||||
- Switch with the 'MAIN PANE', the largest, smallest, etc.
|
|
||||||
|
|
||||||
- Jump to the next and previous window
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
INSTALLATION *goldenview-installation*
|
|
||||||
|
|
||||||
Install GoldenView [1] is the same as installing other vim plugins. If
|
|
||||||
experienced with vim, you can skim the example below and move to next section.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
OPTION A - WITH PLUGIN MANAGER [4] ( RECOMMANDED )
|
|
||||||
|
|
||||||
If you use plugin managers like Pathogen, vundle, neobundle,
|
|
||||||
vim-addon-manager, etc., just unarchive the zip file or clone the GoldenView
|
|
||||||
[1] repo from 'git://github.com/zhaocai/GoldenView.git' into your local plugin
|
|
||||||
installation directory (most likely '~/.vim/bundle/'). Then add corresponding
|
|
||||||
scripts in .vimrc for the bundle manager you are using.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- neobundle:
|
|
||||||
>
|
|
||||||
NeoBundle 'zhaocai/GoldenView.Vim' "Always have a nice view for vim split windows
|
|
||||||
|
|
||||||
- vundle:
|
|
||||||
>
|
|
||||||
Bundle 'zhaocai/GoldenView.Vim'
|
|
||||||
|
|
||||||
- vim-addon-manager:
|
|
||||||
>
|
|
||||||
call vam#ActivateAddons(['GoldenView.Vim'], {'auto_install' : 1})
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
OPTION B - WITHOUT PLUGIN MANAGER [4]
|
|
||||||
|
|
||||||
Unarchive the zip file into a directory that is under 'runtimepath' of your
|
|
||||||
vim, '~/.vim' for example.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
QUICK START *goldenview-quick-start*
|
|
||||||
|
|
||||||
GoldenView [1] should work out of the box without configuration. It should
|
|
||||||
automatically start to resize focused window to golden ratio [3] based on
|
|
||||||
'textwidth' and vim available size. You may start to play with it now.
|
|
||||||
|
|
||||||
To get you started, a few default keys are mapped as below:
|
|
||||||
>
|
|
||||||
" 1. split to tiled windows
|
|
||||||
nmap <silent> <C-L> <Plug>GoldenViewSplit
|
|
||||||
|
|
||||||
" 2. quickly switch current window with the main pane
|
|
||||||
" and toggle back
|
|
||||||
nmap <silent> <F8> <Plug>GoldenViewSwitchMain
|
|
||||||
nmap <silent> <S-F8> <Plug>GoldenViewSwitchToggle
|
|
||||||
|
|
||||||
" 3. jump to next and previous window
|
|
||||||
nmap <silent> <C-N> <Plug>GoldenViewNext
|
|
||||||
nmap <silent> <C-P> <Plug>GoldenViewPrevious
|
|
||||||
|
|
||||||
The meaning of those keys are self-explaining. A general workflow would be
|
|
||||||
'<Plug>GoldenViewSplit' key to quickly and nicely split windows to the layout
|
|
||||||
as below. Then you may open your files.
|
|
||||||
>
|
|
||||||
----+----------------+------------+---+
|
|
||||||
| | | | |
|
|
||||||
| F | | S1 | T |
|
|
||||||
| I | +------------| A |
|
|
||||||
| L | | S2 | G |
|
|
||||||
| E | MAIN PANE +------------+ B |
|
|
||||||
| R | | S3 | A |
|
|
||||||
| | | | R |
|
|
||||||
| | | | |
|
|
||||||
+---+----------------+------------+---+
|
|
||||||
|
|
||||||
To switch 'S1' with 'MAIN PANE', in 'S1' and hit '<Plug>GoldenViewSwitchMain'.
|
|
||||||
To switch back, hit '<Plug>GoldenViewSwitchToggle' in either 'MAIN PAIN' or
|
|
||||||
'S1'
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*g:goldenview__enable_default_mapping*
|
|
||||||
|
|
||||||
Every experienced vim user has a different set of key mappings. If you you are
|
|
||||||
(most likely) unhappy about some of the mappings, map you own keys as below:
|
|
||||||
>
|
|
||||||
let g:goldenview__enable_default_mapping = 0
|
|
||||||
|
|
||||||
nmap <silent> <MY_KEY> <Plug>GoldenViewSplit
|
|
||||||
" ... and so on
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*g:goldenview__enable_at_startup*
|
|
||||||
|
|
||||||
if you do not want to start auto-resizing automatically, you can put 'let
|
|
||||||
g:goldenview__enable_at_startup = 0' in your vimrc.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
MORE COMMANDS AND MAPPINGS *goldenview-more-commands-and-mappings*
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*:ToggleGoldenViewAutoResize*
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*:DisableGoldenViewAutoResize*
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*:EnableGoldenViewAutoResize*
|
|
||||||
|
|
||||||
These commands toggle, enable, and disable GoldenView auto-resizing.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*:GoldenViewResize*
|
|
||||||
|
|
||||||
this command do manual resizing of focused window.
|
|
||||||
|
|
||||||
You can also map a key for this as below:
|
|
||||||
>
|
|
||||||
nmap <silent> <YOUR_KEY> <Plug>GoldenViewResize
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*:SwitchGoldenViewLargest*
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*:SwitchGoldenViewSmallest*
|
|
||||||
|
|
||||||
these commands do as it named.
|
|
||||||
|
|
||||||
You can also add mappings as below. ( no default keys for these mappings)
|
|
||||||
```vim nmap GoldenViewSwitchWithLargest nmap GoldenViewSwitchWithSmallest
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Other switch rules can be easily defined. If you have some ideas, please post
|
|
||||||
to github issue [5] for discussion.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
RULES *goldenview-rules*
|
|
||||||
|
|
||||||
GoldenView [1] defines two rules:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*g:goldenview__ignore_urule*
|
|
||||||
|
|
||||||
is to "ignore" - allow those special buffers to manage their own window size.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*g:goldenview__restore_urule*
|
|
||||||
|
|
||||||
is to "restore" - restore window size of some of special buffers.
|
|
||||||
|
|
||||||
The 'urule' (user rules) are like this, which will be normalize at runtime for
|
|
||||||
faster processing.
|
|
||||||
>
|
|
||||||
\{
|
|
||||||
\ 'filetype' : [
|
|
||||||
\ '' ,
|
|
||||||
\ 'qf' , 'vimpager', 'undotree', 'tagbar',
|
|
||||||
\ 'nerdtree', 'vimshell', 'vimfiler', 'voom' ,
|
|
||||||
\ 'tabman' , 'unite' , 'quickrun', 'Decho' ,
|
|
||||||
\ ],
|
|
||||||
\ 'buftype' : [
|
|
||||||
\ 'nofile' ,
|
|
||||||
\ ],
|
|
||||||
\ 'bufname' : [
|
|
||||||
\ 'GoToFile' , 'diffpanel_\d\+' ,
|
|
||||||
\ '__Gundo_Preview__' , '__Gundo__' ,
|
|
||||||
\ '\[LustyExplorer-Buffers\]' , '\-MiniBufExplorer\-' ,
|
|
||||||
\ '_VOOM\d\+$' , '__Urannotate_\d\+__' ,
|
|
||||||
\ '__MRU_Files__' ,
|
|
||||||
\ ],
|
|
||||||
\},
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
PROFILES *goldenview-profiles*
|
|
||||||
|
|
||||||
GoldenView [1] defines two profile:
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*g:goldenview__active_profile*
|
|
||||||
|
|
||||||
defines the functions and preferences to auto resize windows.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
*g:goldenview__reset_profile*
|
|
||||||
|
|
||||||
defines reset preferences to restore everything to default.
|
|
||||||
|
|
||||||
'function GoldenView#ExtendProfile()' is provided to customize preferences.
|
|
||||||
|
|
||||||
For more details, please read the source code! :)
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
TROUBLESHOOTING: *goldenview-troubleshooting:*
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
PLEASE DO NOT RESIZE ME! *goldenview-please-do-not-resize-me*
|
|
||||||
|
|
||||||
GoldenView [1] maintains rules for "common" cases. But vim offers a great
|
|
||||||
variety of plugins which defines buffers for special purposes. If you find
|
|
||||||
some special buffers which is supposed to not be auto-resized. Please check
|
|
||||||
|g:goldenview__ignore_urule|. You may extend the |g:goldenview__active_profile|
|
|
||||||
or post the issue to github issue [5] for adding it to builtin support.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
MINIBUFEXPL.VIM [6] TAKES 5+ LINES *goldenview-minibufexpl.vim-6-takes-5-lines*
|
|
||||||
|
|
||||||
Check my fork minibufexpl.vim [6] to see if it is working for you. I have send
|
|
||||||
pull request to the origin repo.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
I STILL HAVE ISSUES: *goldenview-i-still-have-issues:*
|
|
||||||
|
|
||||||
If you have any issues, please post it to github issue [5] for discussion.
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
CONTRIBUTORS *goldenview-contributors*
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
RELEASE HISTORY *goldenview-release-history*
|
|
||||||
|
|
||||||
Refer to History.md [7]
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
LICENSE: *goldenview-license:*
|
|
||||||
|
|
||||||
Copyright (c) 2013 Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
|
||||||
Foundation, either version 3 of the License, or (at your option) any later
|
|
||||||
version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
this program. If not, see 'http://www.gnu.org/licenses/' [8].
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
REFERENCES *goldenview-references*
|
|
||||||
|
|
||||||
[1] http://zhaocai.github.io/GoldenView.Vim/
|
|
||||||
[2] http://dl.dropboxusercontent.com/u/1897501/Screencasts/GoldenView.gif
|
|
||||||
[3] http://en.wikipedia.org/wiki/Golden_ratio
|
|
||||||
[4] http://vim-scripts.org/vim/tools.html
|
|
||||||
[5] https://github.com/zhaocai/GoldenView.Vim/issues
|
|
||||||
[6] https://github.com/zhaocai/minibufexpl.vim
|
|
||||||
[7] https://github.com/zhaocai/GoldenView.Vim/blob/master/History.md
|
|
||||||
[8] http://www.gnu.org/licenses/
|
|
||||||
|
|
||||||
vim: ft=help
|
|
@ -1,177 +0,0 @@
|
|||||||
" =============== ============================================================
|
|
||||||
" Name : GoldenView
|
|
||||||
" Description : Golden view for vim split windows
|
|
||||||
" Author : Zhao Cai <caizhaoff@gmail.com>
|
|
||||||
" HomePage : https://github.com/zhaocai/GoldenView.Vim
|
|
||||||
" Date Created : Tue 18 Sep 2012 10:25:23 AM EDT
|
|
||||||
" Last Modified : Sat 29 Sep 2012 01:23:02 AM EDT
|
|
||||||
" Tag : [ vim, window, size, golden-ratio ]
|
|
||||||
" Copyright : © 2012 by Zhao Cai,
|
|
||||||
" Released under current GPL license.
|
|
||||||
" =============== ============================================================
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Load Guard: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
if !GoldenView#zl#rc#load_guard(
|
|
||||||
\ expand('<sfile>:t:r'), 700, 130, ['!&cp', "has('float')"])
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
let s:save_cpo = &cpo
|
|
||||||
set cpo&vim
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Settings: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
call GoldenView#zl#rc#set_default({
|
|
||||||
\ 'g:goldenview__enable_at_startup' : 1 ,
|
|
||||||
\ 'g:goldenview__enable_default_mapping' : 1 ,
|
|
||||||
\ 'g:goldenview__active_profile' : 'default' ,
|
|
||||||
\ 'g:goldenview__reset_profile' : 'reset' ,
|
|
||||||
\ 'g:goldenview__ignore_urule' : {
|
|
||||||
\ 'filetype' : [
|
|
||||||
\ '' ,
|
|
||||||
\ 'qf' , 'vimpager', 'undotree', 'tagbar',
|
|
||||||
\ 'nerdtree', 'vimshell', 'vimfiler', 'voom' ,
|
|
||||||
\ 'tabman' , 'unite' , 'quickrun', 'Decho' ,
|
|
||||||
\ 'ControlP', 'diff' , 'extradite'
|
|
||||||
\ ],
|
|
||||||
\ 'buftype' : [
|
|
||||||
\ 'nofile' ,
|
|
||||||
\ ],
|
|
||||||
\ 'bufname' : [
|
|
||||||
\ 'GoToFile' , 'diffpanel_\d\+' ,
|
|
||||||
\ '__Gundo_Preview__' , '__Gundo__' ,
|
|
||||||
\ '\[LustyExplorer-Buffers\]' , '\-MiniBufExplorer\-' ,
|
|
||||||
\ '_VOOM\d\+$' , '__Urannotate_\d\+__' ,
|
|
||||||
\ '__MRU_Files__' , 'FencView_\d\+$'
|
|
||||||
\ ],
|
|
||||||
\ },
|
|
||||||
\ 'g:goldenview__restore_urule' : {
|
|
||||||
\ 'filetype' : [
|
|
||||||
\ 'nerdtree', 'vimfiler',
|
|
||||||
\ ],
|
|
||||||
\ 'bufname' : [
|
|
||||||
\ '__MRU_Files__' ,
|
|
||||||
\ ],
|
|
||||||
\ },
|
|
||||||
\
|
|
||||||
\ })
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Public Interface: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" Auto Resize:
|
|
||||||
" ------------
|
|
||||||
command! -nargs=0 ToggleGoldenViewAutoResize
|
|
||||||
\ call GoldenView#ToggleAutoResize()
|
|
||||||
|
|
||||||
command! -nargs=0 DisableGoldenViewAutoResize
|
|
||||||
\ call GoldenView#DisableAutoResize()
|
|
||||||
|
|
||||||
command! -nargs=0 EnableGoldenViewAutoResize
|
|
||||||
\ call GoldenView#EnableAutoResize()
|
|
||||||
|
|
||||||
nnoremap <Plug>ToggleGoldenViewAutoResize
|
|
||||||
\ :<C-U>ToggleGoldenViewAutoResize<CR>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" Manual Resize:
|
|
||||||
" --------------
|
|
||||||
command! -nargs=0 GoldenViewResize
|
|
||||||
\ call GoldenView#EnableAutoResize()
|
|
||||||
\|call GoldenView#DisableAutoResize()
|
|
||||||
|
|
||||||
nnoremap <Plug>GoldenViewResize
|
|
||||||
\ :<C-U>GoldenViewResize<CR>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" Layout Split:
|
|
||||||
" -------------
|
|
||||||
nnoremap <Plug>GoldenViewSplit
|
|
||||||
\ :<C-u>call GoldenView#Split()<CR>
|
|
||||||
" [TODO]( define comfortable width &tw * 4/3) @zhaocai @start(2012-09-29 01:17)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" Goto Window:
|
|
||||||
" ------------
|
|
||||||
nnoremap <Plug>GoldenViewNext
|
|
||||||
\ :<C-u>call GoldenView#zl#window#next_window_or_tab()<CR>
|
|
||||||
|
|
||||||
nnoremap <Plug>GoldenViewPrevious
|
|
||||||
\ :<C-u>call GoldenView#zl#window#previous_window_or_tab()<CR>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" Switch Window:
|
|
||||||
" --------------
|
|
||||||
nnoremap <Plug>GoldenViewSwitchMain
|
|
||||||
\ :<C-u>call GoldenView#SwitchMain()<CR>
|
|
||||||
command! -nargs=0 SwitchGoldenViewMain
|
|
||||||
\ call GoldenView#SwitchMain()
|
|
||||||
|
|
||||||
|
|
||||||
nnoremap <Plug>GoldenViewSwitchToggle
|
|
||||||
\ :<C-u>call GoldenView#zl#window#switch_buffer_toggle()<CR>
|
|
||||||
command! -nargs=0 SwitchGoldenViewToggle
|
|
||||||
\ call GoldenView#zl#window#switch_buffer_toggle()
|
|
||||||
|
|
||||||
|
|
||||||
nnoremap <Plug>GoldenViewSwitchWithLargest
|
|
||||||
\ :<C-u>call GoldenView#zl#window#switch_buffer_with_largest()<CR>
|
|
||||||
command! -nargs=0 SwitchGoldenViewLargest
|
|
||||||
\ call GoldenView#zl#window#switch_buffer_with_largest()
|
|
||||||
|
|
||||||
|
|
||||||
nnoremap <Plug>GoldenViewSwitchWithSmallest
|
|
||||||
\ :<C-u>call GoldenView#zl#window#switch_buffer_with_smallest()<CR>
|
|
||||||
command! -nargs=0 SwitchGoldenViewSmallest
|
|
||||||
\ call GoldenView#zl#window#switch_buffer_with_smallest()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Initialization: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
if g:goldenview__enable_at_startup == 1
|
|
||||||
call GoldenView#EnableAutoResize()
|
|
||||||
endif
|
|
||||||
|
|
||||||
if g:goldenview__enable_default_mapping == 1
|
|
||||||
nmap <silent> <C-N> <Plug>GoldenViewNext
|
|
||||||
nmap <silent> <C-P> <Plug>GoldenViewPrevious
|
|
||||||
|
|
||||||
nmap <silent> <F8> <Plug>GoldenViewSwitchMain
|
|
||||||
nmap <silent> <S-F8> <Plug>GoldenViewSwitchToggle
|
|
||||||
|
|
||||||
nmap <silent> <C-L> <Plug>GoldenViewSplit
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let &cpo = s:save_cpo
|
|
||||||
unlet s:save_cpo
|
|
||||||
|
|
||||||
" ============================================================================
|
|
||||||
" Modeline: ⟨⟨⟨1
|
|
||||||
" ============================================================================
|
|
||||||
" vim: set ft=vim ts=4 sw=4 tw=78 fdm=marker fmr=⟨⟨⟨,⟩⟩⟩ fdl=1 :
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
if !exists('g:GoldenView_zl_bundle_path')
|
|
||||||
let g:GoldenView_zl_bundle_path = fnamemodify(expand("<sfile>"), ":p:h:h:h")
|
|
||||||
let g:GoldenView_zl_autoload_path = expand(g:GoldenView_zl_bundle_path . '/autoload/GoldenView/zl')
|
|
||||||
end
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
Subproject commit 3f0e1cd05dc526b073946ad96c64f6a5e2f9e4e6
|
|
@ -1 +0,0 @@
|
|||||||
Subproject commit f1c9be3cdca55c90cc190f8fc38c6c8ac7e8d371
|
|
1
vim/plugins/auto-pairs/.gitignore
vendored
1
vim/plugins/auto-pairs/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
doc/tags
|
|
@ -1,325 +0,0 @@
|
|||||||
Auto Pairs
|
|
||||||
==========
|
|
||||||
Insert or delete brackets, parens, quotes in pair.
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
copy plugin/auto-pairs.vim to ~/.vim/plugin
|
|
||||||
|
|
||||||
or if you are using `pathogen`:
|
|
||||||
|
|
||||||
```git clone git://github.com/jiangmiao/auto-pairs.git ~/.vim/bundle/auto-pairs```
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
* Insert in pair
|
|
||||||
|
|
||||||
input: [
|
|
||||||
output: [|]
|
|
||||||
|
|
||||||
* Delete in pair
|
|
||||||
|
|
||||||
input: foo[<BS>]
|
|
||||||
output: foo
|
|
||||||
|
|
||||||
* Insert new indented line after Return
|
|
||||||
|
|
||||||
input: {|} (press <CR> at |)
|
|
||||||
output: {
|
|
||||||
|
|
|
||||||
}
|
|
||||||
|
|
||||||
* Insert spaces before closing characters, only for [], (), {}
|
|
||||||
|
|
||||||
input: {|} (press <SPACE> at |)
|
|
||||||
output: { | }
|
|
||||||
|
|
||||||
input: {|} (press <SPACE>foo} at |)
|
|
||||||
output: { foo }|
|
|
||||||
|
|
||||||
input: '|' (press <SPACE> at |)
|
|
||||||
output: ' |'
|
|
||||||
|
|
||||||
* Skip ' when inside a word
|
|
||||||
|
|
||||||
input: foo| (press ' at |)
|
|
||||||
output: foo'
|
|
||||||
|
|
||||||
* Skip closed bracket.
|
|
||||||
|
|
||||||
input: []
|
|
||||||
output: []
|
|
||||||
|
|
||||||
* Ignore auto pair when previous character is \
|
|
||||||
|
|
||||||
input: "\'
|
|
||||||
output: "\'"
|
|
||||||
|
|
||||||
* Fast Wrap
|
|
||||||
|
|
||||||
input: |'hello' (press (<M-e> at |)
|
|
||||||
output: ('hello')
|
|
||||||
|
|
||||||
wrap string, only support c style string
|
|
||||||
input: |'h\\el\'lo' (press (<M-e> at |)
|
|
||||||
output ('h\\ello\'')
|
|
||||||
|
|
||||||
input: |[foo, bar()] (press (<M-e> at |)
|
|
||||||
output: ([foo, bar()])
|
|
||||||
|
|
||||||
* Quick move char to closed pair
|
|
||||||
|
|
||||||
input: (|){["foo"]} (press <M-}> at |)
|
|
||||||
output: ({["foo"]}|)
|
|
||||||
|
|
||||||
input: |[foo, bar()] (press (<M-]> at |)
|
|
||||||
output: ([foo, bar()]|)
|
|
||||||
|
|
||||||
* Quick jump to closed pair.
|
|
||||||
|
|
||||||
input:
|
|
||||||
{
|
|
||||||
something;|
|
|
||||||
}
|
|
||||||
|
|
||||||
(press } at |)
|
|
||||||
|
|
||||||
output:
|
|
||||||
{
|
|
||||||
|
|
||||||
}|
|
|
||||||
|
|
||||||
* Support ``` ''' and """
|
|
||||||
|
|
||||||
input:
|
|
||||||
'''
|
|
||||||
|
|
||||||
output:
|
|
||||||
'''|'''
|
|
||||||
|
|
||||||
* Delete Repeated Pairs in one time
|
|
||||||
|
|
||||||
input: """|""" (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
input: {{|}} (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
input: [[[[[[|]]]]]] (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
* Fly Mode
|
|
||||||
|
|
||||||
input: if(a[3)
|
|
||||||
output: if(a[3])| (In Fly Mode)
|
|
||||||
output: if(a[3)]) (Without Fly Mode)
|
|
||||||
|
|
||||||
input:
|
|
||||||
{
|
|
||||||
hello();|
|
|
||||||
world();
|
|
||||||
}
|
|
||||||
|
|
||||||
(press } at |)
|
|
||||||
|
|
||||||
output:
|
|
||||||
{
|
|
||||||
hello();
|
|
||||||
world();
|
|
||||||
}|
|
|
||||||
|
|
||||||
(then press <M-b> at | to do backinsert)
|
|
||||||
output:
|
|
||||||
{
|
|
||||||
hello();}|
|
|
||||||
world();
|
|
||||||
}
|
|
||||||
|
|
||||||
See Fly Mode section for details
|
|
||||||
|
|
||||||
Fly Mode
|
|
||||||
--------
|
|
||||||
Fly Mode will always force closed-pair jumping instead of inserting. only for ")", "}", "]"
|
|
||||||
|
|
||||||
If jumps in mistake, could use AutoPairsBackInsert(Default Key: `<M-b>`) to jump back and insert closed pair.
|
|
||||||
|
|
||||||
the most situation maybe want to insert single closed pair in the string, eg ")"
|
|
||||||
|
|
||||||
Fly Mode is DISABLED by default.
|
|
||||||
|
|
||||||
add **let g:AutoPairsFlyMode = 1** .vimrc to turn it on
|
|
||||||
|
|
||||||
Default Options:
|
|
||||||
|
|
||||||
let g:AutoPairsFlyMode = 0
|
|
||||||
let g:AutoPairsShortcutBackInsert = '<M-b>'
|
|
||||||
|
|
||||||
Shortcuts
|
|
||||||
---------
|
|
||||||
|
|
||||||
System Shortcuts:
|
|
||||||
<CR> : Insert new indented line after return if cursor in blank brackets or quotes.
|
|
||||||
<BS> : Delete brackets in pair
|
|
||||||
<M-p> : Toggle Autopairs (g:AutoPairsShortcutToggle)
|
|
||||||
<M-e> : Fast Wrap (g:AutoPairsShortcutFastWrap)
|
|
||||||
<M-n> : Jump to next closed pair (g:AutoPairsShortcutJump)
|
|
||||||
<M-b> : BackInsert (g:AutoPairsShortcutBackInsert)
|
|
||||||
|
|
||||||
If <M-p> <M-e> or <M-n> conflict with another keys or want to bind to another keys, add
|
|
||||||
|
|
||||||
let g:AutoPairsShortcutToggle = '<another key>'
|
|
||||||
|
|
||||||
to .vimrc, if the key is empty string '', then the shortcut will be disabled.
|
|
||||||
|
|
||||||
Options
|
|
||||||
-------
|
|
||||||
* g:AutoPairs
|
|
||||||
|
|
||||||
Default: {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
|
||||||
|
|
||||||
* b:AutoPairs
|
|
||||||
|
|
||||||
Default: g:AutoPairs
|
|
||||||
|
|
||||||
Buffer level pairs set.
|
|
||||||
|
|
||||||
* g:AutoPairsShortcutToggle
|
|
||||||
|
|
||||||
Default: '<M-p>'
|
|
||||||
|
|
||||||
The shortcut to toggle autopairs.
|
|
||||||
|
|
||||||
* g:AutoPairsShortcutFastWrap
|
|
||||||
|
|
||||||
Default: '<M-e>'
|
|
||||||
|
|
||||||
Fast wrap the word. all pairs will be consider as a block (include <>).
|
|
||||||
(|)'hello' after fast wrap at |, the word will be ('hello')
|
|
||||||
(|)<hello> after fast wrap at |, the word will be (<hello>)
|
|
||||||
|
|
||||||
* g:AutoPairsShortcutJump
|
|
||||||
|
|
||||||
Default: '<M-n>'
|
|
||||||
|
|
||||||
Jump to the next closed pair
|
|
||||||
|
|
||||||
* g:AutoPairsMapBS
|
|
||||||
|
|
||||||
Default : 1
|
|
||||||
|
|
||||||
Map <BS> to delete brackets, quotes in pair
|
|
||||||
execute 'inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>'
|
|
||||||
|
|
||||||
* g:AutoPairsMapCh
|
|
||||||
|
|
||||||
Default : 1
|
|
||||||
|
|
||||||
Map <C-h> to delete brackets, quotes in pair
|
|
||||||
|
|
||||||
* g:AutoPairsMapCR
|
|
||||||
|
|
||||||
Default : 1
|
|
||||||
|
|
||||||
Map <CR> to insert a new indented line if cursor in (|), {|} [|], '|', "|"
|
|
||||||
execute 'inoremap <buffer> <silent> <CR> <C-R>=AutoPairsReturn()<CR>'
|
|
||||||
|
|
||||||
* g:AutoPairsCenterLine
|
|
||||||
|
|
||||||
Default : 1
|
|
||||||
|
|
||||||
When g:AutoPairsMapCR is on, center current line after return if the line is at the bottom 1/3 of the window.
|
|
||||||
|
|
||||||
* g:AutoPairsMapSpace
|
|
||||||
|
|
||||||
Default : 1
|
|
||||||
|
|
||||||
Map <space> to insert a space after the opening character and before the closing one.
|
|
||||||
execute 'inoremap <buffer> <silent> <CR> <C-R>=AutoPairsSpace()<CR>'
|
|
||||||
|
|
||||||
* g:AutoPairsFlyMode
|
|
||||||
|
|
||||||
Default : 0
|
|
||||||
|
|
||||||
set it to 1 to enable FlyMode.
|
|
||||||
see FlyMode section for details.
|
|
||||||
|
|
||||||
* g:AutoPairsMultilineClose
|
|
||||||
|
|
||||||
Default : 1
|
|
||||||
|
|
||||||
When you press the key for the closing pair (e.g. `)`) it jumps past it.
|
|
||||||
If set to 1, then it'll jump to the next line, if there is only whitespace.
|
|
||||||
If set to 0, then it'll only jump to a closing pair on the same line.
|
|
||||||
|
|
||||||
* g:AutoPairsShortcutBackInsert
|
|
||||||
|
|
||||||
Default : <M-b>
|
|
||||||
|
|
||||||
Work with FlyMode, insert the key at the Fly Mode jumped postion
|
|
||||||
|
|
||||||
* g:AutoPairsMoveCharacter
|
|
||||||
|
|
||||||
Default: "()[]{}\"'"
|
|
||||||
|
|
||||||
Map <M-(> <M-)> <M-[> <M-]> <M-{> <M-}> <M-"> <M-'> to
|
|
||||||
move character under the cursor to the pair.
|
|
||||||
|
|
||||||
Buffer Level Pairs Setting
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
Set b:AutoPairs before BufEnter
|
|
||||||
|
|
||||||
eg:
|
|
||||||
|
|
||||||
" When the filetype is FILETYPE then make AutoPairs only match for parenthesis
|
|
||||||
au Filetype FILETYPE let b:AutoPairs = {"(": ")"}
|
|
||||||
|
|
||||||
TroubleShooting
|
|
||||||
---------------
|
|
||||||
The script will remap keys ([{'"}]) <BS>,
|
|
||||||
If auto pairs cannot work, use :imap ( to check if the map is corrected.
|
|
||||||
The correct map should be <C-R>=AutoPairsInsert("\(")<CR>
|
|
||||||
Or the plugin conflict with some other plugins.
|
|
||||||
use command :call AutoPairsInit() to remap the keys.
|
|
||||||
|
|
||||||
|
|
||||||
* How to insert parens purely
|
|
||||||
|
|
||||||
There are 3 ways
|
|
||||||
|
|
||||||
1. use Ctrl-V ) to insert paren without trigger the plugin.
|
|
||||||
|
|
||||||
2. use Alt-P to turn off the plugin.
|
|
||||||
|
|
||||||
3. use DEL or <C-O>x to delete the character insert by plugin.
|
|
||||||
|
|
||||||
* Swedish Character Conflict
|
|
||||||
|
|
||||||
Because AutoPairs uses Meta(Alt) key as shortcut, it is conflict with some Swedish character such as å.
|
|
||||||
To fix the issue, you need remap or disable the related shortcut.
|
|
||||||
|
|
||||||
Known Issues
|
|
||||||
-----------------------
|
|
||||||
Breaks '.' - [issue #3](https://github.com/jiangmiao/auto-pairs/issues/3)
|
|
||||||
|
|
||||||
Description: After entering insert mode and inputing `[hello` then leave insert
|
|
||||||
mode by `<ESC>`. press '.' will insert 'hello' instead of '[hello]'.
|
|
||||||
Reason: `[` actually equals `[]\<LEFT>` and \<LEFT> will break '.'.
|
|
||||||
After version 7.4.849, Vim implements new keyword <C-G>U to avoid the break
|
|
||||||
Solution: Update Vim to 7.4.849+
|
|
||||||
|
|
||||||
Contributors
|
|
||||||
------------
|
|
||||||
* [camthompson](https://github.com/camthompson)
|
|
||||||
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
Copyright (C) 2011-2013 Miao Jiang
|
|
||||||
|
|
||||||
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.
|
|
@ -1,356 +0,0 @@
|
|||||||
*AutoPairs.txt* Insert or delete brackets, parens, quotes in pair
|
|
||||||
|
|
||||||
Author: jiangmiao
|
|
||||||
License: MIT
|
|
||||||
URL: https://github.com/jiangmiao/auto-pairs
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
CONTENTS *autopairs-contents*
|
|
||||||
|
|
||||||
1. Installation ............................. |autopairs-installation|
|
|
||||||
2. Features ..................................... |autopairs-features|
|
|
||||||
3. Fly Mode ..................................... |autopairs-fly-mode|
|
|
||||||
4. Shortcuts ................................... |autopairs-shortcuts|
|
|
||||||
5. Options ....................................... |autopairs-options|
|
|
||||||
6. Troubleshooting ...................... |autopairs-troubleshooting|
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
1. Introduction *autopairs-installation*
|
|
||||||
|
|
||||||
Copy `plugin/auto-pairs.vim` to `~/.vim/plugin`.
|
|
||||||
|
|
||||||
Or if you are using `pathogen`: >
|
|
||||||
|
|
||||||
git clone git://github.com/jiangmiao/auto-pairs.git ~/.vim/bundle/auto-pairs
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
2. Features *autopairs-features*
|
|
||||||
|
|
||||||
Insert in pair: >
|
|
||||||
|
|
||||||
input: [
|
|
||||||
output: [|]
|
|
||||||
|
|
||||||
Delete in pair: >
|
|
||||||
|
|
||||||
input: foo[<BS>]
|
|
||||||
output: foo
|
|
||||||
|
|
||||||
Insert new indented line after Return: >
|
|
||||||
|
|
||||||
input: {|} (press <CR> at |)
|
|
||||||
output: {
|
|
||||||
|
|
|
||||||
}
|
|
||||||
|
|
||||||
Insert spaces before closing characters, only for [], (), {}: >
|
|
||||||
|
|
||||||
input: {|} (press <SPACE> at |)
|
|
||||||
output: { | }
|
|
||||||
|
|
||||||
input: {|} (press <SPACE>foo} at |)
|
|
||||||
output: { foo }|
|
|
||||||
|
|
||||||
input: '|' (press <SPACE> at |)
|
|
||||||
output: ' |'
|
|
||||||
|
|
||||||
Skip ' when inside a word: >
|
|
||||||
|
|
||||||
input: foo| (press ' at |)
|
|
||||||
output: foo'
|
|
||||||
|
|
||||||
Skip closed bracket: >
|
|
||||||
|
|
||||||
input: []
|
|
||||||
output: []
|
|
||||||
|
|
||||||
Ignore auto pair when previous character is '\': >
|
|
||||||
|
|
||||||
input: "\'
|
|
||||||
output: "\'"
|
|
||||||
|
|
||||||
Fast Wrap: >
|
|
||||||
|
|
||||||
input: |'hello' (press (<M-e> at |)
|
|
||||||
output: ('hello')
|
|
||||||
|
|
||||||
Wrap string, only support c style string.
|
|
||||||
input: |'h\\el\'lo' (press (<M-e> at |)
|
|
||||||
output ('h\\ello\'')
|
|
||||||
|
|
||||||
input: |[foo, bar()] (press (<M-e> at |)
|
|
||||||
output: ([foo, bar()])
|
|
||||||
|
|
||||||
Quick jump to closed pair: >
|
|
||||||
|
|
||||||
input:
|
|
||||||
{
|
|
||||||
something;|
|
|
||||||
}
|
|
||||||
|
|
||||||
(press } at |)
|
|
||||||
|
|
||||||
output:
|
|
||||||
{
|
|
||||||
|
|
||||||
}|
|
|
||||||
|
|
||||||
Support ```, ''' and """: >
|
|
||||||
|
|
||||||
input:
|
|
||||||
'''
|
|
||||||
|
|
||||||
output:
|
|
||||||
'''|'''
|
|
||||||
|
|
||||||
Delete Repeated Pairs in one time: >
|
|
||||||
|
|
||||||
input: """|""" (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
input: {{|}} (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
input: [[[[[[|]]]]]] (press <BS> at |)
|
|
||||||
output: |
|
|
||||||
|
|
||||||
Fly Mode (|autopairs-flymode|): >
|
|
||||||
|
|
||||||
input: if(a[3)
|
|
||||||
output: if(a[3])| (In Fly Mode)
|
|
||||||
output: if(a[3)]) (Without Fly Mode)
|
|
||||||
|
|
||||||
input:
|
|
||||||
{
|
|
||||||
hello();|
|
|
||||||
world();
|
|
||||||
}
|
|
||||||
|
|
||||||
(press } at |)
|
|
||||||
|
|
||||||
output:
|
|
||||||
{
|
|
||||||
hello();
|
|
||||||
world();
|
|
||||||
}|
|
|
||||||
|
|
||||||
(then press <M-b> at | to do backinsert)
|
|
||||||
output:
|
|
||||||
{
|
|
||||||
hello();}|
|
|
||||||
world();
|
|
||||||
}
|
|
||||||
|
|
||||||
See |Fly Mode| section for details
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
3. Fly Mode *autopairs-flymode*
|
|
||||||
|
|
||||||
Fly Mode will always force closed-pair jumping instead of inserting. Only for
|
|
||||||
")", "}", "]". If jumps in mistake, you can use |g:AutoPairsBackInsert| (default
|
|
||||||
Key: <M-b>) to jump back and insert closed pair.
|
|
||||||
|
|
||||||
The most situation maybe you want to insert single closed pair in the string,
|
|
||||||
eg: >
|
|
||||||
|
|
||||||
")"
|
|
||||||
|
|
||||||
Fly Mode is DISABLED by default. To enable Fly Mode add following to your
|
|
||||||
'.vimrc': >
|
|
||||||
|
|
||||||
let g:AutoPairsFlyMode = 1
|
|
||||||
|
|
||||||
Default Options: >
|
|
||||||
|
|
||||||
let g:AutoPairsFlyMode = 0
|
|
||||||
let g:AutoPairsShortcutBackInsert = '<M-b>'
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
4. Shortcuts *autopairs-shortcuts*
|
|
||||||
|
|
||||||
System Shortcuts:
|
|
||||||
<CR> : Insert new indented line after return if cursor in blank brackets
|
|
||||||
or quotes.
|
|
||||||
<BS> : Delete brackets in pair
|
|
||||||
<M-p>: Toggle Autopairs (|g:AutoPairsShortcutToggle|)
|
|
||||||
<M-e>: Fast Wrap (|g:AutoPairsShortcutFastWrap|)
|
|
||||||
<M-n>: Jump to next closed pair (|g:AutoPairsShortcutJump|)
|
|
||||||
<M-b>: BackInsert (|g:AutoPairsShortcutBackInsert|)
|
|
||||||
|
|
||||||
|
|
||||||
To rebind keys <M-p>, <M-e> or <M-n> or in case of conflicts conflicts with
|
|
||||||
another keys:
|
|
||||||
|
|
||||||
let g:AutoPairsShortcutToggle = '<another key>'
|
|
||||||
|
|
||||||
If the key is empty string '', then the shortcut will be disabled.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
5. Options *autopairs-options*
|
|
||||||
|
|
||||||
*g:AutoPairs*
|
|
||||||
|g:AutoPairs| dict
|
|
||||||
|
|
||||||
Default: >
|
|
||||||
{'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
|
||||||
|
|
||||||
Specifies which symbols should be automatically paired.
|
|
||||||
|
|
||||||
To append new pairs without overwriting defaults, add values in your `.vimrc`.:
|
|
||||||
|
|
||||||
let g:AutoPairs['<']='>'
|
|
||||||
|
|
||||||
This example will enable matching of `<` with `>`.
|
|
||||||
|
|
||||||
|
|
||||||
*b:AutoPairs*
|
|
||||||
|b:AutoPairs| dict
|
|
||||||
|
|
||||||
Default: |g:AutoPairs|
|
|
||||||
|
|
||||||
Buffer level pairs set.
|
|
||||||
|
|
||||||
You can set |b:AutoPairs| before |BufEnter|: >
|
|
||||||
|
|
||||||
au Filetype FILETYPE let b:AutoPairs = {"(": ")"}
|
|
||||||
|
|
||||||
This sets |AutoPairs| to only match for parenthesis for 'FILETYPE'.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsShortcutToggle*
|
|
||||||
|g:AutoPairsShortcutToggle| string
|
|
||||||
|
|
||||||
Default: <M-p>
|
|
||||||
|
|
||||||
The shortcut to toggle autopairs.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsShortcutFastWrap*
|
|
||||||
|g:AutoPairsShortcutFastWrap| string
|
|
||||||
|
|
||||||
Default: <M-e>
|
|
||||||
|
|
||||||
Fast wrap the word. All pairs will be considered as a block (including <>).
|
|
||||||
|
|
||||||
(|)'hello' after fast wrap at |, the word will be ('hello')
|
|
||||||
(|)<hello> after fast wrap at |, the word will be (<hello>)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsShortcutJump*
|
|
||||||
|g:AutoPairsShortcutJump| string
|
|
||||||
|
|
||||||
Default: <M-n>
|
|
||||||
|
|
||||||
Jump to the next closed pair.
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsShortcutBackInsert*
|
|
||||||
|g:AutoPairsShortcutBackInsert| string
|
|
||||||
|
|
||||||
Default: <M-b>
|
|
||||||
|
|
||||||
Work with |autopairs-flymode|, insert the key at the Fly Mode jumped position.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsMapBS*
|
|
||||||
|g:AutoPairsMapBS| int
|
|
||||||
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
Map <BS> to delete brackets and quotes in pair, executes:
|
|
||||||
|
|
||||||
inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsMapCh*
|
|
||||||
|g:AutoPairsMapCh| int
|
|
||||||
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
Map <C-h> to delete brackets and quotes in pair.
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsMapCR*
|
|
||||||
|g:AutoPairsMapCR| int
|
|
||||||
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
Map <CR> to insert a new indented line if cursor in (|), {|} [|], '|', "|".
|
|
||||||
Executes:
|
|
||||||
|
|
||||||
inoremap <buffer> <silent> <CR> <C-R>=AutoPairsReturn()<CR>
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsCenterLine*
|
|
||||||
|g:AutoPairsCenterLine| int
|
|
||||||
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
When |g:AutoPairsMapCR| is on, center current line after return if the line
|
|
||||||
is at the bottom 1/3 of the window.
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsMapSpace*
|
|
||||||
|g:AutoPairsMapSpace| int
|
|
||||||
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
Map <space> to insert a space after the opening character and before the
|
|
||||||
closing one.
|
|
||||||
|
|
||||||
Executes:
|
|
||||||
|
|
||||||
inoremap <buffer> <silent> <CR> <C-R>=AutoPairsSpace()<CR>
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsFlyMode*
|
|
||||||
|g:AutoPairsFlyMode| int
|
|
||||||
|
|
||||||
Default: 0
|
|
||||||
|
|
||||||
Set it to 1 to enable |autopairs-flymode|.
|
|
||||||
|
|
||||||
|
|
||||||
*g:AutoPairsMultilineClose*
|
|
||||||
|g:AutoPairsMultilineClose| int
|
|
||||||
|
|
||||||
Default: 1
|
|
||||||
|
|
||||||
When you press the key for the closing pair (e.g. `)`) it jumps past it.
|
|
||||||
If set to 1, then it'll jump to the next line, if there is only 'whitespace'.
|
|
||||||
If set to 0, then it'll only jump to a closing pair on the same line.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
6. Troubleshooting *autopairs-troubleshooting*
|
|
||||||
|
|
||||||
This plugin remaps keys `([{'"}]) <BS>`
|
|
||||||
|
|
||||||
If auto pairs cannot work, use |:imap| to check if the map is corrected.
|
|
||||||
|
|
||||||
The correct map should be: >
|
|
||||||
|
|
||||||
<C-R>=AutoPairsInsert("\(")<CR>
|
|
||||||
|
|
||||||
Or the plugin conflicts with some other plugins. Use command: >
|
|
||||||
|
|
||||||
:call AutoPairsInit() to remap the keys.
|
|
||||||
|
|
||||||
--- How to insert parens purely? ---
|
|
||||||
|
|
||||||
There are 3 ways:
|
|
||||||
|
|
||||||
1. Use Ctrl-V ) to insert paren without trigger the plugin.
|
|
||||||
|
|
||||||
2. Use Alt-P to turn off the plugin.
|
|
||||||
|
|
||||||
3. Use DEL or <C-O>x to delete the character insert by plugin.
|
|
||||||
|
|
||||||
--- Swedish Character Conflict ---
|
|
||||||
|
|
||||||
Because AutoPairs uses Meta(Alt) key as a shortcut, it conflicts with some
|
|
||||||
Swedish character such as å. To fix the issue, you need remap or disable the
|
|
||||||
related shortcut.
|
|
@ -1,582 +0,0 @@
|
|||||||
" Insert or delete brackets, parens, quotes in pairs.
|
|
||||||
" Maintainer: JiangMiao <jiangfriend@gmail.com>
|
|
||||||
" Contributor: camthompson
|
|
||||||
" Last Change: 2017-06-17
|
|
||||||
" Version: 1.3.3
|
|
||||||
" Homepage: http://www.vim.org/scripts/script.php?script_id=3599
|
|
||||||
" Repository: https://github.com/jiangmiao/auto-pairs
|
|
||||||
" License: MIT
|
|
||||||
|
|
||||||
if exists('g:AutoPairsLoaded') || &cp
|
|
||||||
finish
|
|
||||||
end
|
|
||||||
let g:AutoPairsLoaded = 1
|
|
||||||
|
|
||||||
if !exists('g:AutoPairs')
|
|
||||||
let g:AutoPairs = {'(':')', '[':']', '{':'}',"'":"'",'"':'"', '`':'`'}
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsParens')
|
|
||||||
let g:AutoPairsParens = {'(':')', '[':']', '{':'}'}
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsMapBS')
|
|
||||||
let g:AutoPairsMapBS = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
" Map <C-h> as the same BS
|
|
||||||
if !exists('g:AutoPairsMapCh')
|
|
||||||
let g:AutoPairsMapCh = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsMapCR')
|
|
||||||
let g:AutoPairsMapCR = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsMapSpace')
|
|
||||||
let g:AutoPairsMapSpace = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsCenterLine')
|
|
||||||
let g:AutoPairsCenterLine = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsShortcutToggle')
|
|
||||||
let g:AutoPairsShortcutToggle = '<M-p>'
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsShortcutFastWrap')
|
|
||||||
let g:AutoPairsShortcutFastWrap = '<M-e>'
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsMoveCharacter')
|
|
||||||
let g:AutoPairsMoveCharacter = "()[]{}\"'"
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsShortcutJump')
|
|
||||||
let g:AutoPairsShortcutJump = '<M-n>'
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Fly mode will for closed pair to jump to closed pair instead of insert.
|
|
||||||
" also support AutoPairsBackInsert to insert pairs where jumped.
|
|
||||||
if !exists('g:AutoPairsFlyMode')
|
|
||||||
let g:AutoPairsFlyMode = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
" When skipping the closed pair, look at the current and
|
|
||||||
" next line as well.
|
|
||||||
if !exists('g:AutoPairsMultilineClose')
|
|
||||||
let g:AutoPairsMultilineClose = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Work with Fly Mode, insert pair where jumped
|
|
||||||
if !exists('g:AutoPairsShortcutBackInsert')
|
|
||||||
let g:AutoPairsShortcutBackInsert = '<M-b>'
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !exists('g:AutoPairsSmartQuotes')
|
|
||||||
let g:AutoPairsSmartQuotes = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
" 7.4.849 support <C-G>U to avoid breaking '.'
|
|
||||||
" Issue talk: https://github.com/jiangmiao/auto-pairs/issues/3
|
|
||||||
" Vim note: https://github.com/vim/vim/releases/tag/v7.4.849
|
|
||||||
if v:version > 704 || v:version == 704 && has("patch849")
|
|
||||||
let s:Go = "\<C-G>U"
|
|
||||||
else
|
|
||||||
let s:Go = ""
|
|
||||||
endif
|
|
||||||
|
|
||||||
let s:Left = s:Go."\<LEFT>"
|
|
||||||
let s:Right = s:Go."\<RIGHT>"
|
|
||||||
|
|
||||||
|
|
||||||
" Will auto generated {']' => '[', ..., '}' => '{'}in initialize.
|
|
||||||
let g:AutoPairsClosedPairs = {}
|
|
||||||
|
|
||||||
|
|
||||||
function! AutoPairsInsert(key)
|
|
||||||
if !b:autopairs_enabled
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
|
|
||||||
let line = getline('.')
|
|
||||||
let pos = col('.') - 1
|
|
||||||
let before = strpart(line, 0, pos)
|
|
||||||
let after = strpart(line, pos)
|
|
||||||
let next_chars = split(after, '\zs')
|
|
||||||
let current_char = get(next_chars, 0, '')
|
|
||||||
let next_char = get(next_chars, 1, '')
|
|
||||||
let prev_chars = split(before, '\zs')
|
|
||||||
let prev_char = get(prev_chars, -1, '')
|
|
||||||
|
|
||||||
let eol = 0
|
|
||||||
if col('$') - col('.') <= 1
|
|
||||||
let eol = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
" Ignore auto close if prev character is \
|
|
||||||
if prev_char == '\'
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
|
|
||||||
" The key is difference open-pair, then it means only for ) ] } by default
|
|
||||||
if !has_key(b:AutoPairs, a:key)
|
|
||||||
let b:autopairs_saved_pair = [a:key, getpos('.')]
|
|
||||||
|
|
||||||
" Skip the character if current character is the same as input
|
|
||||||
if current_char == a:key
|
|
||||||
return s:Right
|
|
||||||
end
|
|
||||||
|
|
||||||
if !g:AutoPairsFlyMode
|
|
||||||
" Skip the character if next character is space
|
|
||||||
if current_char == ' ' && next_char == a:key
|
|
||||||
return s:Right.s:Right
|
|
||||||
end
|
|
||||||
|
|
||||||
" Skip the character if closed pair is next character
|
|
||||||
if current_char == ''
|
|
||||||
if g:AutoPairsMultilineClose
|
|
||||||
let next_lineno = line('.')+1
|
|
||||||
let next_line = getline(nextnonblank(next_lineno))
|
|
||||||
let next_char = matchstr(next_line, '\s*\zs.')
|
|
||||||
else
|
|
||||||
let next_char = matchstr(line, '\s*\zs.')
|
|
||||||
end
|
|
||||||
if next_char == a:key
|
|
||||||
return "\<ESC>e^a"
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Fly Mode, and the key is closed-pairs, search closed-pair and jump
|
|
||||||
if g:AutoPairsFlyMode && has_key(b:AutoPairsClosedPairs, a:key)
|
|
||||||
let n = stridx(after, a:key)
|
|
||||||
if n != -1
|
|
||||||
return repeat(s:Right, n+1)
|
|
||||||
end
|
|
||||||
if search(a:key, 'W')
|
|
||||||
" force break the '.' when jump to different line
|
|
||||||
return "\<Right>"
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Insert directly if the key is not an open key
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
|
|
||||||
let open = a:key
|
|
||||||
let close = b:AutoPairs[open]
|
|
||||||
|
|
||||||
if current_char == close && open == close
|
|
||||||
return s:Right
|
|
||||||
end
|
|
||||||
|
|
||||||
" Ignore auto close ' if follows a word
|
|
||||||
" MUST after closed check. 'hello|'
|
|
||||||
if a:key == "'" && prev_char =~ '\v\w'
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
|
|
||||||
" support for ''' ``` and """
|
|
||||||
if open == close
|
|
||||||
" The key must be ' " `
|
|
||||||
let pprev_char = line[col('.')-3]
|
|
||||||
if pprev_char == open && prev_char == open
|
|
||||||
" Double pair found
|
|
||||||
return repeat(a:key, 4) . repeat(s:Left, 3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
let quotes_num = 0
|
|
||||||
" Ignore comment line for vim file
|
|
||||||
if &filetype == 'vim' && a:key == '"'
|
|
||||||
if before =~ '^\s*$'
|
|
||||||
return a:key
|
|
||||||
end
|
|
||||||
if before =~ '^\s*"'
|
|
||||||
let quotes_num = -1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
" Keep quote number is odd.
|
|
||||||
" Because quotes should be matched in the same line in most of situation
|
|
||||||
if g:AutoPairsSmartQuotes && open == close
|
|
||||||
" Remove \\ \" \'
|
|
||||||
let cleaned_line = substitute(line, '\v(\\.)', '', 'g')
|
|
||||||
let n = quotes_num
|
|
||||||
let pos = 0
|
|
||||||
while 1
|
|
||||||
let pos = stridx(cleaned_line, open, pos)
|
|
||||||
if pos == -1
|
|
||||||
break
|
|
||||||
end
|
|
||||||
let n = n + 1
|
|
||||||
let pos = pos + 1
|
|
||||||
endwhile
|
|
||||||
if n % 2 == 1
|
|
||||||
return a:key
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
return open.close.s:Left
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsDelete()
|
|
||||||
if !b:autopairs_enabled
|
|
||||||
return "\<BS>"
|
|
||||||
end
|
|
||||||
|
|
||||||
let line = getline('.')
|
|
||||||
let pos = col('.') - 1
|
|
||||||
let current_char = get(split(strpart(line, pos), '\zs'), 0, '')
|
|
||||||
let prev_chars = split(strpart(line, 0, pos), '\zs')
|
|
||||||
let prev_char = get(prev_chars, -1, '')
|
|
||||||
let pprev_char = get(prev_chars, -2, '')
|
|
||||||
|
|
||||||
if pprev_char == '\'
|
|
||||||
return "\<BS>"
|
|
||||||
end
|
|
||||||
|
|
||||||
" Delete last two spaces in parens, work with MapSpace
|
|
||||||
if has_key(b:AutoPairs, pprev_char) && prev_char == ' ' && current_char == ' '
|
|
||||||
return "\<BS>\<DEL>"
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Delete Repeated Pair eg: '''|''' [[|]] {{|}}
|
|
||||||
if has_key(b:AutoPairs, prev_char)
|
|
||||||
let times = 0
|
|
||||||
let p = -1
|
|
||||||
while get(prev_chars, p, '') == prev_char
|
|
||||||
let p = p - 1
|
|
||||||
let times = times + 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
let close = b:AutoPairs[prev_char]
|
|
||||||
let left = repeat(prev_char, times)
|
|
||||||
let right = repeat(close, times)
|
|
||||||
|
|
||||||
let before = strpart(line, pos-times, times)
|
|
||||||
let after = strpart(line, pos, times)
|
|
||||||
if left == before && right == after
|
|
||||||
return repeat("\<BS>\<DEL>", times)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if has_key(b:AutoPairs, prev_char)
|
|
||||||
let close = b:AutoPairs[prev_char]
|
|
||||||
if match(line,'^\s*'.close, col('.')-1) != -1
|
|
||||||
" Delete (|___)
|
|
||||||
let space = matchstr(line, '^\s*', col('.')-1)
|
|
||||||
return "\<BS>". repeat("\<DEL>", len(space)+1)
|
|
||||||
elseif match(line, '^\s*$', col('.')-1) != -1
|
|
||||||
" Delete (|__\n___)
|
|
||||||
let nline = getline(line('.')+1)
|
|
||||||
if nline =~ '^\s*'.close
|
|
||||||
if &filetype == 'vim' && prev_char == '"'
|
|
||||||
" Keep next line's comment
|
|
||||||
return "\<BS>"
|
|
||||||
end
|
|
||||||
|
|
||||||
let space = matchstr(nline, '^\s*')
|
|
||||||
return "\<BS>\<DEL>". repeat("\<DEL>", len(space)+1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return "\<BS>"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsJump()
|
|
||||||
call search('["\]'')}]','W')
|
|
||||||
endfunction
|
|
||||||
" string_chunk cannot use standalone
|
|
||||||
let s:string_chunk = '\v%(\\\_.|[^\1]|[\r\n]){-}'
|
|
||||||
let s:ss_pattern = '\v''' . s:string_chunk . ''''
|
|
||||||
let s:ds_pattern = '\v"' . s:string_chunk . '"'
|
|
||||||
|
|
||||||
func! s:RegexpQuote(str)
|
|
||||||
return substitute(a:str, '\v[\[\{\(\<\>\)\}\]]', '\\&', 'g')
|
|
||||||
endf
|
|
||||||
|
|
||||||
func! s:RegexpQuoteInSquare(str)
|
|
||||||
return substitute(a:str, '\v[\[\]]', '\\&', 'g')
|
|
||||||
endf
|
|
||||||
|
|
||||||
" Search next open or close pair
|
|
||||||
func! s:FormatChunk(open, close)
|
|
||||||
let open = s:RegexpQuote(a:open)
|
|
||||||
let close = s:RegexpQuote(a:close)
|
|
||||||
let open2 = s:RegexpQuoteInSquare(a:open)
|
|
||||||
let close2 = s:RegexpQuoteInSquare(a:close)
|
|
||||||
if open == close
|
|
||||||
return '\v'.open.s:string_chunk.close
|
|
||||||
else
|
|
||||||
return '\v%(' . s:ss_pattern . '|' . s:ds_pattern . '|' . '[^'.open2.close2.']|[\r\n]' . '){-}(['.open2.close2.'])'
|
|
||||||
end
|
|
||||||
endf
|
|
||||||
|
|
||||||
" Fast wrap the word in brackets
|
|
||||||
function! AutoPairsFastWrap()
|
|
||||||
let line = getline('.')
|
|
||||||
let current_char = line[col('.')-1]
|
|
||||||
let next_char = line[col('.')]
|
|
||||||
let open_pair_pattern = '\v[({\[''"]'
|
|
||||||
let at_end = col('.') >= col('$') - 1
|
|
||||||
normal! x
|
|
||||||
" Skip blank
|
|
||||||
if next_char =~ '\v\s' || at_end
|
|
||||||
call search('\v\S', 'W')
|
|
||||||
let line = getline('.')
|
|
||||||
let next_char = line[col('.')-1]
|
|
||||||
end
|
|
||||||
|
|
||||||
if has_key(b:AutoPairs, next_char)
|
|
||||||
let followed_open_pair = next_char
|
|
||||||
let inputed_close_pair = current_char
|
|
||||||
let followed_close_pair = b:AutoPairs[next_char]
|
|
||||||
if followed_close_pair != followed_open_pair
|
|
||||||
" TODO replace system searchpair to skip string and nested pair.
|
|
||||||
" eg: (|){"hello}world"} will transform to ({"hello})world"}
|
|
||||||
call searchpair('\V'.followed_open_pair, '', '\V'.followed_close_pair, 'W')
|
|
||||||
else
|
|
||||||
call search(s:FormatChunk(followed_open_pair, followed_close_pair), 'We')
|
|
||||||
end
|
|
||||||
return s:Right.inputed_close_pair.s:Left
|
|
||||||
else
|
|
||||||
normal! he
|
|
||||||
return s:Right.current_char.s:Left
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsMap(key)
|
|
||||||
" | is special key which separate map command from text
|
|
||||||
let key = a:key
|
|
||||||
if key == '|'
|
|
||||||
let key = '<BAR>'
|
|
||||||
end
|
|
||||||
let escaped_key = substitute(key, "'", "''", 'g')
|
|
||||||
" use expr will cause search() doesn't work
|
|
||||||
execute 'inoremap <buffer> <silent> '.key." <C-R>=AutoPairsInsert('".escaped_key."')<CR>"
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsToggle()
|
|
||||||
if b:autopairs_enabled
|
|
||||||
let b:autopairs_enabled = 0
|
|
||||||
echo 'AutoPairs Disabled.'
|
|
||||||
else
|
|
||||||
let b:autopairs_enabled = 1
|
|
||||||
echo 'AutoPairs Enabled.'
|
|
||||||
end
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsMoveCharacter(key)
|
|
||||||
let c = getline(".")[col(".")-1]
|
|
||||||
let escaped_key = substitute(a:key, "'", "''", 'g')
|
|
||||||
return "\<DEL>\<ESC>:call search("."'".escaped_key."'".")\<CR>a".c."\<LEFT>"
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsReturn()
|
|
||||||
if b:autopairs_enabled == 0
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
let line = getline('.')
|
|
||||||
let pline = getline(line('.')-1)
|
|
||||||
let prev_char = pline[strlen(pline)-1]
|
|
||||||
let cmd = ''
|
|
||||||
let cur_char = line[col('.')-1]
|
|
||||||
if has_key(b:AutoPairs, prev_char) && b:AutoPairs[prev_char] == cur_char
|
|
||||||
if g:AutoPairsCenterLine && winline() * 3 >= winheight(0) * 2
|
|
||||||
" Recenter before adding new line to avoid replacing line content
|
|
||||||
let cmd = "zz"
|
|
||||||
end
|
|
||||||
|
|
||||||
" If equalprg has been set, then avoid call =
|
|
||||||
" https://github.com/jiangmiao/auto-pairs/issues/24
|
|
||||||
if &equalprg != ''
|
|
||||||
return "\<ESC>".cmd."O"
|
|
||||||
endif
|
|
||||||
|
|
||||||
" conflict with javascript and coffee
|
|
||||||
" javascript need indent new line
|
|
||||||
" coffeescript forbid indent new line
|
|
||||||
if &filetype == 'coffeescript' || &filetype == 'coffee'
|
|
||||||
return "\<ESC>".cmd."k==o"
|
|
||||||
else
|
|
||||||
return "\<ESC>".cmd."=ko"
|
|
||||||
endif
|
|
||||||
end
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsSpace()
|
|
||||||
let line = getline('.')
|
|
||||||
let prev_char = line[col('.')-2]
|
|
||||||
let cmd = ''
|
|
||||||
let cur_char =line[col('.')-1]
|
|
||||||
if has_key(g:AutoPairsParens, prev_char) && g:AutoPairsParens[prev_char] == cur_char
|
|
||||||
let cmd = "\<SPACE>".s:Left
|
|
||||||
endif
|
|
||||||
return "\<SPACE>".cmd
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsBackInsert()
|
|
||||||
if exists('b:autopairs_saved_pair')
|
|
||||||
let pair = b:autopairs_saved_pair[0]
|
|
||||||
let pos = b:autopairs_saved_pair[1]
|
|
||||||
call setpos('.', pos)
|
|
||||||
return pair
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsInit()
|
|
||||||
let b:autopairs_loaded = 1
|
|
||||||
if !exists('b:autopairs_enabled')
|
|
||||||
let b:autopairs_enabled = 1
|
|
||||||
end
|
|
||||||
let b:AutoPairsClosedPairs = {}
|
|
||||||
|
|
||||||
if !exists('b:AutoPairs')
|
|
||||||
let b:AutoPairs = g:AutoPairs
|
|
||||||
end
|
|
||||||
|
|
||||||
if !exists('b:AutoPairsMoveCharacter')
|
|
||||||
let b:AutoPairsMoveCharacter = g:AutoPairsMoveCharacter
|
|
||||||
end
|
|
||||||
|
|
||||||
" buffer level map pairs keys
|
|
||||||
for [open, close] in items(b:AutoPairs)
|
|
||||||
call AutoPairsMap(open)
|
|
||||||
if open != close
|
|
||||||
call AutoPairsMap(close)
|
|
||||||
end
|
|
||||||
let b:AutoPairsClosedPairs[close] = open
|
|
||||||
endfor
|
|
||||||
|
|
||||||
for key in split(b:AutoPairsMoveCharacter, '\s*')
|
|
||||||
let escaped_key = substitute(key, "'", "''", 'g')
|
|
||||||
execute 'inoremap <silent> <buffer> <M-'.key."> <C-R>=AutoPairsMoveCharacter('".escaped_key."')<CR>"
|
|
||||||
endfor
|
|
||||||
|
|
||||||
" Still use <buffer> level mapping for <BS> <SPACE>
|
|
||||||
if g:AutoPairsMapBS
|
|
||||||
" Use <C-R> instead of <expr> for issue #14 sometimes press BS output strange words
|
|
||||||
execute 'inoremap <buffer> <silent> <BS> <C-R>=AutoPairsDelete()<CR>'
|
|
||||||
end
|
|
||||||
|
|
||||||
if g:AutoPairsMapCh
|
|
||||||
execute 'inoremap <buffer> <silent> <C-h> <C-R>=AutoPairsDelete()<CR>'
|
|
||||||
endif
|
|
||||||
|
|
||||||
if g:AutoPairsMapSpace
|
|
||||||
" Try to respect abbreviations on a <SPACE>
|
|
||||||
let do_abbrev = ""
|
|
||||||
if v:version == 703 && has("patch489") || v:version > 703
|
|
||||||
let do_abbrev = "<C-]>"
|
|
||||||
endif
|
|
||||||
execute 'inoremap <buffer> <silent> <SPACE> '.do_abbrev.'<C-R>=AutoPairsSpace()<CR>'
|
|
||||||
end
|
|
||||||
|
|
||||||
if g:AutoPairsShortcutFastWrap != ''
|
|
||||||
execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutFastWrap.' <C-R>=AutoPairsFastWrap()<CR>'
|
|
||||||
end
|
|
||||||
|
|
||||||
if g:AutoPairsShortcutBackInsert != ''
|
|
||||||
execute 'inoremap <buffer> <silent> '.g:AutoPairsShortcutBackInsert.' <C-R>=AutoPairsBackInsert()<CR>'
|
|
||||||
end
|
|
||||||
|
|
||||||
if g:AutoPairsShortcutToggle != ''
|
|
||||||
" use <expr> to ensure showing the status when toggle
|
|
||||||
execute 'inoremap <buffer> <silent> <expr> '.g:AutoPairsShortcutToggle.' AutoPairsToggle()'
|
|
||||||
execute 'noremap <buffer> <silent> '.g:AutoPairsShortcutToggle.' :call AutoPairsToggle()<CR>'
|
|
||||||
end
|
|
||||||
|
|
||||||
if g:AutoPairsShortcutJump != ''
|
|
||||||
execute 'inoremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' <ESC>:call AutoPairsJump()<CR>a'
|
|
||||||
execute 'noremap <buffer> <silent> ' . g:AutoPairsShortcutJump. ' :call AutoPairsJump()<CR>'
|
|
||||||
end
|
|
||||||
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ExpandMap(map)
|
|
||||||
let map = a:map
|
|
||||||
let map = substitute(map, '\(<Plug>\w\+\)', '\=maparg(submatch(1), "i")', 'g')
|
|
||||||
return map
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! AutoPairsTryInit()
|
|
||||||
if exists('b:autopairs_loaded')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
" for auto-pairs starts with 'a', so the priority is higher than supertab and vim-endwise
|
|
||||||
"
|
|
||||||
" vim-endwise doesn't support <Plug>AutoPairsReturn
|
|
||||||
" when use <Plug>AutoPairsReturn will cause <Plug> isn't expanded
|
|
||||||
"
|
|
||||||
" supertab doesn't support <SID>AutoPairsReturn
|
|
||||||
" when use <SID>AutoPairsReturn will cause Duplicated <CR>
|
|
||||||
"
|
|
||||||
" and when load after vim-endwise will cause unexpected endwise inserted.
|
|
||||||
" so always load AutoPairs at last
|
|
||||||
|
|
||||||
" Buffer level keys mapping
|
|
||||||
" comptible with other plugin
|
|
||||||
if g:AutoPairsMapCR
|
|
||||||
if v:version == 703 && has('patch32') || v:version > 703
|
|
||||||
" VIM 7.3 supports advancer maparg which could get <expr> info
|
|
||||||
" then auto-pairs could remap <CR> in any case.
|
|
||||||
let info = maparg('<CR>', 'i', 0, 1)
|
|
||||||
if empty(info)
|
|
||||||
let old_cr = '<CR>'
|
|
||||||
let is_expr = 0
|
|
||||||
else
|
|
||||||
let old_cr = info['rhs']
|
|
||||||
let old_cr = s:ExpandMap(old_cr)
|
|
||||||
let old_cr = substitute(old_cr, '<SID>', '<SNR>' . info['sid'] . '_', 'g')
|
|
||||||
let is_expr = info['expr']
|
|
||||||
let wrapper_name = '<SID>AutoPairsOldCRWrapper73'
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
" VIM version less than 7.3
|
|
||||||
" the mapping's <expr> info is lost, so guess it is expr or not, it's
|
|
||||||
" not accurate.
|
|
||||||
let old_cr = maparg('<CR>', 'i')
|
|
||||||
if old_cr == ''
|
|
||||||
let old_cr = '<CR>'
|
|
||||||
let is_expr = 0
|
|
||||||
else
|
|
||||||
let old_cr = s:ExpandMap(old_cr)
|
|
||||||
" old_cr contain (, I guess the old cr is in expr mode
|
|
||||||
let is_expr = old_cr =~ '\V(' && toupper(old_cr) !~ '\V<C-R>'
|
|
||||||
|
|
||||||
" The old_cr start with " it must be in expr mode
|
|
||||||
let is_expr = is_expr || old_cr =~ '\v^"'
|
|
||||||
let wrapper_name = '<SID>AutoPairsOldCRWrapper'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if old_cr !~ 'AutoPairsReturn'
|
|
||||||
if is_expr
|
|
||||||
" remap <expr> to `name` to avoid mix expr and non-expr mode
|
|
||||||
execute 'inoremap <buffer> <expr> <script> '. wrapper_name . ' ' . old_cr
|
|
||||||
let old_cr = wrapper_name
|
|
||||||
end
|
|
||||||
" Always silent mapping
|
|
||||||
execute 'inoremap <script> <buffer> <silent> <CR> '.old_cr.'<SID>AutoPairsReturn'
|
|
||||||
end
|
|
||||||
endif
|
|
||||||
call AutoPairsInit()
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Always silent the command
|
|
||||||
inoremap <silent> <SID>AutoPairsReturn <C-R>=AutoPairsReturn()<CR>
|
|
||||||
imap <script> <Plug>AutoPairsReturn <SID>AutoPairsReturn
|
|
||||||
|
|
||||||
|
|
||||||
au BufEnter * :call AutoPairsTryInit()
|
|
@ -1,44 +0,0 @@
|
|||||||
# Problem summary
|
|
||||||
|
|
||||||
|
|
||||||
## Expected
|
|
||||||
|
|
||||||
|
|
||||||
## Environment Information
|
|
||||||
|
|
||||||
* OS:
|
|
||||||
* Neovim version:
|
|
||||||
|
|
||||||
|
|
||||||
## Provide a minimal init.vim with less than 50 lines (required)
|
|
||||||
|
|
||||||
```vim
|
|
||||||
" Use the following as a template.
|
|
||||||
set runtimepath+=~/path/to/deoplete.nvim/
|
|
||||||
set runtimepath+=~/path/to/deoplete-jedi/
|
|
||||||
let g:deoplete#enable_at_startup = 1
|
|
||||||
call deoplete#custom#set('jedi', 'debug_enabled', 1)
|
|
||||||
call deoplete#enable_logging('DEBUG', '/tmp/deoplete.log')
|
|
||||||
```
|
|
||||||
|
|
||||||
## Generate logfiles if appropriate
|
|
||||||
|
|
||||||
1. export NVIM_PYTHON_LOG_FILE=/tmp/nvim-log
|
|
||||||
2. export NVIM_PYTHON_LOG_LEVEL=DEBUG
|
|
||||||
3. nvim -u minimal.vimrc
|
|
||||||
|
|
||||||
Then look at and attach the files `/tmp/nvim-log_{PID}` and
|
|
||||||
`/tmp/deoplete.log` here.
|
|
||||||
|
|
||||||
|
|
||||||
## Steps to reproduce the issue after starting Neovim (required)
|
|
||||||
|
|
||||||
1.
|
|
||||||
2.
|
|
||||||
3.
|
|
||||||
|
|
||||||
|
|
||||||
## Screen shot (if possible)
|
|
||||||
|
|
||||||
|
|
||||||
## Upload the logfile(s)
|
|
66
vim/plugins/deoplete-jedi/.gitignore
vendored
66
vim/plugins/deoplete-jedi/.gitignore
vendored
@ -1,66 +0,0 @@
|
|||||||
### https://raw.github.com/github/gitignore//Python.gitignore
|
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
*$py.class
|
|
||||||
|
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
.Python
|
|
||||||
env/
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
downloads/
|
|
||||||
eggs/
|
|
||||||
.eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
|
|
||||||
# PyInstaller
|
|
||||||
# Usually these files are written by a python script from a template
|
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
||||||
*.manifest
|
|
||||||
*.spec
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
htmlcov/
|
|
||||||
.tox/
|
|
||||||
.coverage
|
|
||||||
.coverage.*
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
*,cover
|
|
||||||
.hypothesis/
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
*.pot
|
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# PyBuilder
|
|
||||||
target/
|
|
||||||
|
|
||||||
#Ipython Notebook
|
|
||||||
.ipynb_checkpoints
|
|
||||||
|
|
||||||
.-rplugin~
|
|
6
vim/plugins/deoplete-jedi/.gitmodules
vendored
6
vim/plugins/deoplete-jedi/.gitmodules
vendored
@ -1,6 +0,0 @@
|
|||||||
[submodule "rplugin/python3/deoplete/jedi"]
|
|
||||||
path = rplugin/python3/deoplete/vendored/jedi
|
|
||||||
url = https://github.com/davidhalter/jedi.git
|
|
||||||
[submodule "rplugin/python3/deoplete/parso"]
|
|
||||||
path = rplugin/python3/deoplete/vendored/parso
|
|
||||||
url = https://github.com/davidhalter/parso.git
|
|
@ -1,34 +0,0 @@
|
|||||||
language: python
|
|
||||||
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- "$HOME/.cache/pip"
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- sudo: required
|
|
||||||
os: linux
|
|
||||||
dist: trusty
|
|
||||||
compiler: clang
|
|
||||||
python: '3.5'
|
|
||||||
- sudo: required
|
|
||||||
os: linux
|
|
||||||
dist: trusty
|
|
||||||
compiler: clang
|
|
||||||
python: 'nightly'
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- uname -a
|
|
||||||
- cat /etc/lsb-release
|
|
||||||
|
|
||||||
install:
|
|
||||||
- pip3 install -q -U -r ./tests/requirements.txt
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make test
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email: false
|
|
||||||
slack:
|
|
||||||
rooms:
|
|
||||||
secure: Kjl0kgnF4qcnW/wjk++HnmLGD0FeQLHeaFHAlmeN1Iql7z+I7cBaW35I4P0W0sgZPzF4y6LSReGlxtmEFlqNmmYll6SPw4n2BvNv2Ir+sSl6r61plQdTQsh6RlnW4lRQMZ8JSgP/E6jci3cuchCFWnN7miYP08vmJmKTh3MlW5TjksPpNx6B+zC0zr0JqjXNXZwaSXpQYrA0hwKt0pZOQbgPxEeRnUYEAqiJxR30GmSTZ8OxWHNupNWKtSxaYV1e8/6vcaq3iae6fsP6qceVmNZzPc/IUVXA8NNmu+TKZUaQEQAKWkIm8QJVY7cnHMBdfG56L/NgX7lwmv3cRq+1mDOxEGWtOfnQwQIeV3wRKK8yactQ5cCD32WE2cioAUnvwryjOjRG5Vt8aBuFINoxdz7KTcQye1JqrjDU14ob6JAQnLafClLDhTXht+/W6/UeUr9ZOAX1nVWuuLvIJsU1SP1Uvv/PvuLk+XDrBCunDZwWssRwn1q8pBnEubhe6vbOO134hAeF0/SMnWXKuL/knTL5aqICLQOhj+ooNpb+hU3D3phlHIddhufz8cAWSxR/eqnwQ4LkKfZa2L4DMW02dou8HMl973ft/g/DCdFXFGz53VYqD7V8Mpb2DQ7nkvqmsokSDNNs99cMIDV9LVI3QJGW8OR88wUgIlONl+795a0=
|
|
@ -1,14 +0,0 @@
|
|||||||
FROM zchee/neovim:python
|
|
||||||
MAINTAINER zchee <zchee.io@gmail.com>
|
|
||||||
|
|
||||||
RUN pip3 install jedi \
|
|
||||||
&& git clone https://github.com/Shougo/deoplete.nvim /src/deoplete.nvim \
|
|
||||||
\
|
|
||||||
&& echo 'set rtp+=/src/deoplete.nvim' >> /root/.config/nvim/init.vim \
|
|
||||||
&& echo 'set rtp+=/src/deoplete-jedi' >> /root/.config/nvim/init.vim \
|
|
||||||
&& echo 'let g:deoplete#enable_at_startup = 1' >> /root/.config/nvim/init.vim \
|
|
||||||
&& echo 'let g:deoplete#auto_completion_start_length = 1' >> /root/.config/nvim/init.vim
|
|
||||||
|
|
||||||
COPY . /src/deoplete-jedi
|
|
||||||
|
|
||||||
RUN /src/run.sh
|
|
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2016 Koichi Shiraishi
|
|
||||||
|
|
||||||
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.
|
|
@ -1,10 +0,0 @@
|
|||||||
RPLUGIN_PATH := ./rplugin/python3/deoplete/sources
|
|
||||||
|
|
||||||
all: test
|
|
||||||
|
|
||||||
test: flake8
|
|
||||||
|
|
||||||
flake8:
|
|
||||||
flake8 rplugin tests
|
|
||||||
|
|
||||||
.PHONY: test flake8
|
|
@ -1,86 +0,0 @@
|
|||||||
# deoplete-jedi
|
|
||||||
|
|
||||||
|
|
||||||
[deoplete.nvim](https://github.com/Shougo/deoplete.nvim) source for [jedi](https://github.com/davidhalter/jedi).
|
|
||||||
|
|
||||||
|| **Status** |
|
|
||||||
|:---:|:---:|
|
|
||||||
| **Travis CI** |[![Build Status](https://travis-ci.org/zchee/deoplete-jedi.svg?branch=master)](https://travis-ci.org/zchee/deoplete-jedi)|
|
|
||||||
| **Gitter** |[![Join the chat at https://gitter.im/zchee/deoplete-jedi](https://badges.gitter.im/zchee/deoplete-jedi.svg)](https://gitter.im/zchee/deoplete-jedi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)|
|
|
||||||
|
|
||||||
|
|
||||||
## Required
|
|
||||||
|
|
||||||
- Neovim and neovim/python-client
|
|
||||||
- https://github.com/neovim/neovim
|
|
||||||
- https://github.com/neovim/python-client
|
|
||||||
|
|
||||||
- deoplete.nvim
|
|
||||||
- https://github.com/Shougo/deoplete.nvim
|
|
||||||
|
|
||||||
- jedi
|
|
||||||
- https://github.com/davidhalter/jedi
|
|
||||||
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```vim
|
|
||||||
NeoBundle 'zchee/deoplete-jedi'
|
|
||||||
# or
|
|
||||||
Plug 'zchee/deoplete-jedi'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** If you don't want to use a plugin manager, you will need to clone
|
|
||||||
this repo recursively:
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone --recursive https://github.com/zchee/deoplete-jedi
|
|
||||||
```
|
|
||||||
|
|
||||||
When updating the plugin, you will want to be sure that the Jedi submodule is
|
|
||||||
kept up to date with:
|
|
||||||
|
|
||||||
```
|
|
||||||
git submodule update --init
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Options
|
|
||||||
|
|
||||||
- `g:deoplete#sources#jedi#server_timeout`: The timeout (in seconds) for jedi
|
|
||||||
server to workaround endless loop in jedi. Increase it if you cannot get
|
|
||||||
completions for large package such as pandas (see #125). Default: 10
|
|
||||||
- `g:deoplete#sources#jedi#statement_length`: Sets the maximum length of
|
|
||||||
completion description text. If this is exceeded, a simple description is
|
|
||||||
used instead. Default: `50`
|
|
||||||
- `g:deoplete#sources#jedi#enable_cache`: Enables caching of completions for
|
|
||||||
faster results. Default: `1`
|
|
||||||
- `g:deoplete#sources#jedi#show_docstring`: Shows docstring in preview window.
|
|
||||||
Default: `0`
|
|
||||||
- `g:deoplete#sources#jedi#python_path`: Set the Python interpreter path to use
|
|
||||||
for the completion server. deoplete-jedi uses the first available `python`
|
|
||||||
in `$PATH`. Use this only if you want use a specific Python interpreter.
|
|
||||||
This has no effect if `$VIRTUAL_ENV` is present in the environment.
|
|
||||||
**Note**: This is completely unrelated to configuring Neovim.
|
|
||||||
- `g:deoplete#sources#jedi#debug_server`: Enable logging from the server. If
|
|
||||||
set to `1`, server messages are emitted to Deoplete's log file. This can
|
|
||||||
optionally be a string that points to a file for separate logging. The log
|
|
||||||
level will be inherited from `deoplete#enable_logging()`.
|
|
||||||
- `g:deoplete#sources#jedi#extra_path`: A list of extra paths to add to
|
|
||||||
`sys.path` when performing completions.
|
|
||||||
|
|
||||||
|
|
||||||
## Virtual Environments
|
|
||||||
|
|
||||||
If you are using virtualenv, it is recommended that you create environments
|
|
||||||
specifically for Neovim. This way, you will not need to install the neovim
|
|
||||||
package in each virtualenv. Once you have created them, add the following to
|
|
||||||
your vimrc file:
|
|
||||||
|
|
||||||
```vim
|
|
||||||
let g:python_host_prog = '/full/path/to/neovim2/bin/python'
|
|
||||||
let g:python3_host_prog = '/full/path/to/neovim3/bin/python'
|
|
||||||
```
|
|
||||||
|
|
||||||
Deoplete only requires Python 3. See `:h nvim-python-quickstart` for more
|
|
||||||
information.
|
|
@ -1,10 +0,0 @@
|
|||||||
# Colorable output
|
|
||||||
CRESET := \x1b[0m
|
|
||||||
CBLACK := \x1b[30;01m
|
|
||||||
CRED := \x1b[31;01m
|
|
||||||
CGREEN := \x1b[32;01m
|
|
||||||
CYELLOW := \x1b[33;01m
|
|
||||||
CBLUE := \x1b[34;01m
|
|
||||||
CMAGENTA := \x1b[35;01m
|
|
||||||
CCYAN := \x1b[36;01m
|
|
||||||
CWHITE := \x1b[37;01m
|
|
@ -1,13 +0,0 @@
|
|||||||
IMPORT_LOGGER := from logging import getLogger\nlogger = getLogger(__name__)
|
|
||||||
IMPORT_TIMEIT := from profiler import timeit
|
|
||||||
IMPORT_PYVMMONITOR := import sys\nsys.path.append("\/Applications\/PyVmMonitor.app\/Contents\/MacOS\/public_api")\nimport pyvmmonitor
|
|
||||||
|
|
||||||
SET_DEBUG_PREFIX := jedi_settings.cache_directory \= os.path.join\(cache_home, 'jedi'\)
|
|
||||||
SET_DEBUG := try:\n from helper import set_debug\n if self.vim.vars["deoplete\#enable_debug"]:\n log_file \= self.vim.vars["deoplete\#sources\#jedi\#debug\#log_file"]\n set_debug(logger, os.path.expanduser(log_file))\n except Exception:\n pass\n
|
|
||||||
|
|
||||||
TIMEIT_PREFIX := @timeit(logger,
|
|
||||||
TIMEIT_SUFFIX := )
|
|
||||||
TIMEIT_GET_COMPLETE_POSITION := ${TIMEIT_PREFIX}"simple", [0.00003000, 0.00015000]${TIMEIT_SUFFIX}
|
|
||||||
TIMEIT_GATHER_CANDIDATES := ${TIMEIT_PREFIX}"simple", [0.10000000, 0.20000000]${TIMEIT_SUFFIX}
|
|
||||||
|
|
||||||
PYVMMONITOR_DECORATOR := @pyvmmonitor.profile_method()
|
|
@ -1,290 +0,0 @@
|
|||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
from deoplete.util import getlines
|
|
||||||
|
|
||||||
sys.path.insert(1, os.path.dirname(__file__)) # noqa: E261
|
|
||||||
from deoplete_jedi import cache, profiler, utils, worker
|
|
||||||
|
|
||||||
from .base import Base
|
|
||||||
|
|
||||||
|
|
||||||
def sort_key(item):
|
|
||||||
w = item.get('name')
|
|
||||||
z = len(w) - len(w.lstrip('_'))
|
|
||||||
return (('z' * z) + w.lower()[z:], len(w))
|
|
||||||
|
|
||||||
|
|
||||||
class Source(Base):
|
|
||||||
|
|
||||||
def __init__(self, vim):
|
|
||||||
Base.__init__(self, vim)
|
|
||||||
self.name = 'jedi'
|
|
||||||
self.mark = '[jedi]'
|
|
||||||
self.rank = 500
|
|
||||||
self.filetypes = ['python', 'cython', 'pyrex']
|
|
||||||
self.input_pattern = (r'[\w\)\]\}\'\"]+\.\w*$|'
|
|
||||||
r'^\s*@\w*$|'
|
|
||||||
r'^\s*from\s+[\w\.]*(?:\s+import\s+(?:\w*(?:,\s*)?)*)?|'
|
|
||||||
r'^\s*import\s+(?:[\w\.]*(?:,\s*)?)*')
|
|
||||||
self._async_keys = set()
|
|
||||||
self.workers_started = False
|
|
||||||
|
|
||||||
def on_init(self, context):
|
|
||||||
vars = context['vars']
|
|
||||||
|
|
||||||
self.statement_length = vars.get(
|
|
||||||
'deoplete#sources#jedi#statement_length', 0)
|
|
||||||
self.server_timeout = vars.get(
|
|
||||||
'deoplete#sources#jedi#server_timeout', 10)
|
|
||||||
self.use_short_types = vars.get(
|
|
||||||
'deoplete#sources#jedi#short_types', False)
|
|
||||||
self.show_docstring = vars.get(
|
|
||||||
'deoplete#sources#jedi#show_docstring', False)
|
|
||||||
self.debug_server = vars.get(
|
|
||||||
'deoplete#sources#jedi#debug_server', None)
|
|
||||||
# Only one worker is really needed since deoplete-jedi has a pretty
|
|
||||||
# aggressive cache.
|
|
||||||
# Two workers may be needed if working with very large source files.
|
|
||||||
self.worker_threads = vars.get(
|
|
||||||
'deoplete#sources#jedi#worker_threads', 2)
|
|
||||||
# Hard coded python interpreter location
|
|
||||||
self.python_path = vars.get(
|
|
||||||
'deoplete#sources#jedi#python_path', '')
|
|
||||||
self.extra_path = vars.get(
|
|
||||||
'deoplete#sources#jedi#extra_path', [])
|
|
||||||
|
|
||||||
self.boilerplate = [] # Completions that are included in all results
|
|
||||||
|
|
||||||
log_file = ''
|
|
||||||
root_log = logging.getLogger('deoplete')
|
|
||||||
|
|
||||||
if self.debug_server:
|
|
||||||
self.is_debug_enabled = True
|
|
||||||
if isinstance(self.debug_server, str):
|
|
||||||
log_file = self.debug_server
|
|
||||||
else:
|
|
||||||
for handler in root_log.handlers:
|
|
||||||
if isinstance(handler, logging.FileHandler):
|
|
||||||
log_file = handler.baseFilename
|
|
||||||
break
|
|
||||||
|
|
||||||
if not self.is_debug_enabled:
|
|
||||||
child_log = root_log.getChild('jedi')
|
|
||||||
child_log.propagate = False
|
|
||||||
|
|
||||||
if not self.workers_started:
|
|
||||||
if self.python_path and 'VIRTUAL_ENV' not in os.environ:
|
|
||||||
cache.python_path = self.python_path
|
|
||||||
worker.start(max(1, self.worker_threads), self.statement_length,
|
|
||||||
self.server_timeout, self.use_short_types, self.show_docstring,
|
|
||||||
(log_file, root_log.level), self.python_path)
|
|
||||||
cache.start_background(worker.comp_queue)
|
|
||||||
self.workers_started = True
|
|
||||||
|
|
||||||
def get_complete_position(self, context):
|
|
||||||
pattern = r'\w*$'
|
|
||||||
if context['input'].lstrip().startswith(('from ', 'import ')):
|
|
||||||
m = re.search(r'[,\s]$', context['input'])
|
|
||||||
if m:
|
|
||||||
return m.end()
|
|
||||||
m = re.search(pattern, context['input'])
|
|
||||||
return m.start() if m else -1
|
|
||||||
|
|
||||||
def mix_boilerplate(self, completions):
|
|
||||||
seen = set()
|
|
||||||
for item in self.boilerplate + completions:
|
|
||||||
if item['name'] in seen:
|
|
||||||
continue
|
|
||||||
seen.add(item['name'])
|
|
||||||
yield item
|
|
||||||
|
|
||||||
def finalize(self, item):
|
|
||||||
abbr = item['name']
|
|
||||||
|
|
||||||
if self.show_docstring:
|
|
||||||
desc = item['doc']
|
|
||||||
else:
|
|
||||||
desc = ''
|
|
||||||
|
|
||||||
if item['params'] is not None:
|
|
||||||
sig = '{}({})'.format(item['name'], ', '.join(item['params']))
|
|
||||||
sig_len = len(sig)
|
|
||||||
|
|
||||||
desc = sig + '\n\n' + desc
|
|
||||||
|
|
||||||
if self.statement_length > 0 and sig_len > self.statement_length:
|
|
||||||
params = []
|
|
||||||
length = len(item['name']) + 2
|
|
||||||
|
|
||||||
for p in item['params']:
|
|
||||||
p = p.split('=', 1)[0]
|
|
||||||
length += len(p)
|
|
||||||
params.append(p)
|
|
||||||
|
|
||||||
length += 2 * (len(params) - 1)
|
|
||||||
|
|
||||||
# +5 for the ellipsis and separator
|
|
||||||
while length + 5 > self.statement_length and len(params):
|
|
||||||
length -= len(params[-1]) + 2
|
|
||||||
params = params[:-1]
|
|
||||||
|
|
||||||
if len(item['params']) > len(params):
|
|
||||||
params.append('...')
|
|
||||||
|
|
||||||
sig = '{}({})'.format(item['name'], ', '.join(params))
|
|
||||||
|
|
||||||
abbr = sig
|
|
||||||
|
|
||||||
if self.use_short_types:
|
|
||||||
kind = item['short_type'] or item['type']
|
|
||||||
else:
|
|
||||||
kind = item['type']
|
|
||||||
|
|
||||||
return {
|
|
||||||
'word': item['name'],
|
|
||||||
'abbr': abbr,
|
|
||||||
'kind': kind,
|
|
||||||
'info': desc.strip(),
|
|
||||||
'menu': '[jedi] ',
|
|
||||||
'dup': 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
def finalize_cached(self, cache_key, filters, cached):
|
|
||||||
if cached:
|
|
||||||
if cached.completions is None:
|
|
||||||
out = self.mix_boilerplate([])
|
|
||||||
elif cache_key[-1] == 'vars':
|
|
||||||
out = self.mix_boilerplate(cached.completions)
|
|
||||||
else:
|
|
||||||
out = cached.completions
|
|
||||||
if filters:
|
|
||||||
out = (x for x in out if x['type'] in filters)
|
|
||||||
return [self.finalize(x) for x in sorted(out, key=sort_key)]
|
|
||||||
return []
|
|
||||||
|
|
||||||
@profiler.profile
|
|
||||||
def gather_candidates(self, context):
|
|
||||||
refresh_boilerplate = False
|
|
||||||
if not self.boilerplate:
|
|
||||||
bp = cache.retrieve(('boilerplate~',))
|
|
||||||
if bp:
|
|
||||||
self.boilerplate = bp.completions[:]
|
|
||||||
refresh_boilerplate = True
|
|
||||||
else:
|
|
||||||
# This should be the first time any completion happened, so
|
|
||||||
# `wait` will be True.
|
|
||||||
worker.work_queue.put((('boilerplate~',), [], '', 1, 0, '', None))
|
|
||||||
|
|
||||||
line = context['position'][1]
|
|
||||||
col = context['complete_position']
|
|
||||||
buf = self.vim.current.buffer
|
|
||||||
src = getlines(self.vim)
|
|
||||||
|
|
||||||
extra_modules = []
|
|
||||||
cache_key = None
|
|
||||||
cached = None
|
|
||||||
refresh = True
|
|
||||||
wait = False
|
|
||||||
|
|
||||||
# Inclusion filters for the results
|
|
||||||
filters = []
|
|
||||||
|
|
||||||
if re.match('^\s*(from|import)\s+', context['input']) \
|
|
||||||
and not re.match('^\s*from\s+\S+\s+', context['input']):
|
|
||||||
# If starting an import, only show module results
|
|
||||||
filters.append('module')
|
|
||||||
|
|
||||||
cache_key, extra_modules = cache.cache_context(buf.name, context, src,
|
|
||||||
self.extra_path)
|
|
||||||
cached = cache.retrieve(cache_key)
|
|
||||||
if cached and not cached.refresh:
|
|
||||||
modules = cached.modules
|
|
||||||
if all([filename in modules for filename in extra_modules]) \
|
|
||||||
and all([utils.file_mtime(filename) == mtime
|
|
||||||
for filename, mtime in modules.items()]):
|
|
||||||
# The cache is still valid
|
|
||||||
refresh = False
|
|
||||||
|
|
||||||
if cache_key and (cache_key[-1] in ('dot', 'vars', 'import', 'import~') or
|
|
||||||
(cached and cache_key[-1] == 'package' and
|
|
||||||
not len(cached.modules))):
|
|
||||||
# Always refresh scoped variables and module imports. Additionally
|
|
||||||
# refresh cached items that did not have associated module files.
|
|
||||||
refresh = True
|
|
||||||
|
|
||||||
# Extra options to pass to the server.
|
|
||||||
options = {
|
|
||||||
'cwd': context.get('cwd'),
|
|
||||||
'extra_path': self.extra_path,
|
|
||||||
'runtimepath': context.get('runtimepath'),
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not cached or refresh) and cache_key and cache_key[-1] == 'package':
|
|
||||||
# Create a synthetic completion for a module import as a fallback.
|
|
||||||
synthetic_src = ['import {0}; {0}.'.format(cache_key[0])]
|
|
||||||
options.update({
|
|
||||||
'synthetic': {
|
|
||||||
'src': synthetic_src,
|
|
||||||
'line': 1,
|
|
||||||
'col': len(synthetic_src[0]),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if not cached:
|
|
||||||
wait = True
|
|
||||||
|
|
||||||
# Note: This waits a very short amount of time to give the server or
|
|
||||||
# cache a chance to reply. If there's no reply during this period,
|
|
||||||
# empty results are returned and we defer to deoplete's async refresh.
|
|
||||||
# The current requests's async status is tracked in `_async_keys`.
|
|
||||||
# If the async cache result is older than 5 seconds, the completion
|
|
||||||
# request goes back to the default behavior of attempting to refresh as
|
|
||||||
# needed by the `refresh` and `wait` variables above.
|
|
||||||
self.debug('Key: %r, Refresh: %r, Wait: %r, Async: %r', cache_key,
|
|
||||||
refresh, wait, cache_key in self._async_keys)
|
|
||||||
|
|
||||||
context['is_async'] = cache_key in self._async_keys
|
|
||||||
if context['is_async']:
|
|
||||||
if not cached:
|
|
||||||
self.debug('[async] waiting for completions: %r', cache_key)
|
|
||||||
return []
|
|
||||||
else:
|
|
||||||
self._async_keys.remove(cache_key)
|
|
||||||
context['is_async'] = False
|
|
||||||
if time.time() - cached.time < 5:
|
|
||||||
self.debug('[async] finished: %r', cache_key)
|
|
||||||
return self.finalize_cached(cache_key, filters, cached)
|
|
||||||
else:
|
|
||||||
self.debug('[async] outdated: %r', cache_key)
|
|
||||||
|
|
||||||
if cache_key and (not cached or refresh):
|
|
||||||
n = time.time()
|
|
||||||
wait_complete = False
|
|
||||||
worker.work_queue.put((cache_key, extra_modules, '\n'.join(src),
|
|
||||||
line, col, str(buf.name), options))
|
|
||||||
while wait and time.time() - n < 0.25:
|
|
||||||
cached = cache.retrieve(cache_key)
|
|
||||||
if cached and cached.time >= n:
|
|
||||||
self.debug('Got updated cache, stopped waiting.')
|
|
||||||
wait_complete = True
|
|
||||||
break
|
|
||||||
time.sleep(0.01)
|
|
||||||
|
|
||||||
if wait and not wait_complete:
|
|
||||||
self._async_keys.add(cache_key)
|
|
||||||
context['is_async'] = True
|
|
||||||
self.debug('[async] deferred: %r', cache_key)
|
|
||||||
return []
|
|
||||||
|
|
||||||
if refresh_boilerplate:
|
|
||||||
# This should only occur the first time completions happen.
|
|
||||||
# Refresh the boilerplate to ensure it's always up to date (just in
|
|
||||||
# case).
|
|
||||||
self.debug('Refreshing boilerplate')
|
|
||||||
worker.work_queue.put((('boilerplate~',), [], '', 1, 0, '', None))
|
|
||||||
|
|
||||||
return self.finalize_cached(cache_key, filters, cached)
|
|
@ -1,451 +0,0 @@
|
|||||||
import glob
|
|
||||||
import hashlib
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
from itertools import chain
|
|
||||||
from string import whitespace
|
|
||||||
|
|
||||||
from deoplete_jedi import utils
|
|
||||||
|
|
||||||
_paths = []
|
|
||||||
_cache_path = None
|
|
||||||
# List of items in the file system cache. `import~` is a special key for
|
|
||||||
# caching import modules. It should not be cached to disk.
|
|
||||||
_file_cache = set(['import~'])
|
|
||||||
|
|
||||||
# Cache version allows us to invalidate outdated cache data structures.
|
|
||||||
_cache_version = 16
|
|
||||||
_cache_lock = threading.RLock()
|
|
||||||
_cache = {}
|
|
||||||
|
|
||||||
python_path = 'python'
|
|
||||||
|
|
||||||
log = logging.getLogger('deoplete.jedi.cache')
|
|
||||||
|
|
||||||
# This uses [\ \t] to avoid spanning lines
|
|
||||||
_import_re = re.compile(r'''
|
|
||||||
^[\ \t]*(
|
|
||||||
from[\ \t]+[\w\.]+[\ \t]+import\s+\([\s\w,]+\)|
|
|
||||||
from[\ \t]+[\w\.]+[\ \t]+import[\ \t\w,]+|
|
|
||||||
import[\ \t]+\([\s\w,]+\)|
|
|
||||||
import[\ \t]+[\ \t\w,]+
|
|
||||||
)
|
|
||||||
''', re.VERBOSE | re.MULTILINE)
|
|
||||||
|
|
||||||
|
|
||||||
class CacheEntry(object):
|
|
||||||
def __init__(self, dict):
|
|
||||||
self.key = tuple(dict.get('cache_key'))
|
|
||||||
self._touched = time.time()
|
|
||||||
self.time = dict.get('time')
|
|
||||||
self.modules = dict.get('modules')
|
|
||||||
self.completions = dict.get('completions', [])
|
|
||||||
self.refresh = False
|
|
||||||
if self.completions is None:
|
|
||||||
self.refresh = True
|
|
||||||
self.completions = []
|
|
||||||
|
|
||||||
def update_from(self, other):
|
|
||||||
self.key = other.key
|
|
||||||
self.time = other.time
|
|
||||||
self.modules = other.modules
|
|
||||||
self.completions = other.completions
|
|
||||||
|
|
||||||
def touch(self):
|
|
||||||
self._touched = time.time()
|
|
||||||
|
|
||||||
def to_dict(self):
|
|
||||||
return {
|
|
||||||
'version': _cache_version,
|
|
||||||
'cache_key': self.key,
|
|
||||||
'time': self.time,
|
|
||||||
'modules': self.modules,
|
|
||||||
'completions': self.completions,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_cache_path():
|
|
||||||
global _cache_path
|
|
||||||
if not _cache_path or not os.path.isdir(_cache_path):
|
|
||||||
p = subprocess.Popen([python_path, '-V'], stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE)
|
|
||||||
stdout, stderr = p.communicate()
|
|
||||||
version = re.search(r'(\d+\.\d+)\.', (stdout or stderr).decode('utf8')).group(1)
|
|
||||||
cache_dir = os.getenv('XDG_CACHE_HOME', '~/.cache')
|
|
||||||
cache_dir = os.path.join(os.path.expanduser(cache_dir), 'deoplete/jedi',
|
|
||||||
version)
|
|
||||||
if not os.path.exists(cache_dir):
|
|
||||||
umask = os.umask(0)
|
|
||||||
os.makedirs(cache_dir, 0o0700)
|
|
||||||
os.umask(umask)
|
|
||||||
_cache_path = cache_dir
|
|
||||||
return _cache_path
|
|
||||||
|
|
||||||
|
|
||||||
def retrieve(key):
|
|
||||||
if not key:
|
|
||||||
return None
|
|
||||||
|
|
||||||
with _cache_lock:
|
|
||||||
if key[-1] == 'package' and key[0] not in _file_cache:
|
|
||||||
# This will only load the cached item from a file the first time it
|
|
||||||
# was seen.
|
|
||||||
cache_file = os.path.join(get_cache_path(), '{}.json'.format(key[0]))
|
|
||||||
if os.path.isfile(cache_file):
|
|
||||||
with open(cache_file, 'rt') as fp:
|
|
||||||
try:
|
|
||||||
data = json.load(fp)
|
|
||||||
if data.get('version', 0) >= _cache_version:
|
|
||||||
_file_cache.add(key[0])
|
|
||||||
cached = CacheEntry(data)
|
|
||||||
cached.time = time.time()
|
|
||||||
_cache[key] = cached
|
|
||||||
log.debug('Loaded from file: %r', key)
|
|
||||||
return cached
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
cached = _cache.get(key)
|
|
||||||
if cached:
|
|
||||||
cached.touch()
|
|
||||||
return cached
|
|
||||||
|
|
||||||
|
|
||||||
def store(key, value):
|
|
||||||
with _cache_lock:
|
|
||||||
if not isinstance(value, CacheEntry):
|
|
||||||
value = CacheEntry(value)
|
|
||||||
|
|
||||||
if value.refresh:
|
|
||||||
# refresh is set when completions is None. This will be due to
|
|
||||||
# Jedi producing an error and not getting any completions. Use any
|
|
||||||
# previously cached completions while a refresh is attempted.
|
|
||||||
old = _cache.get(key)
|
|
||||||
if old is not None:
|
|
||||||
value.completions = old.completions
|
|
||||||
|
|
||||||
_cache[key] = value
|
|
||||||
|
|
||||||
if key[-1] == 'package' and key[0] not in _file_cache:
|
|
||||||
_file_cache.add(key[0])
|
|
||||||
cache_file = os.path.join(get_cache_path(), '{}.json'.format(key[0]))
|
|
||||||
with open(cache_file, 'wt') as fp:
|
|
||||||
json.dump(value.to_dict(), fp)
|
|
||||||
log.debug('Stored to file: %r', key)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def exists(key):
|
|
||||||
with _cache_lock:
|
|
||||||
return key in _cache
|
|
||||||
|
|
||||||
|
|
||||||
def reap_cache(max_age=300):
|
|
||||||
"""Clear the cache of old items
|
|
||||||
|
|
||||||
Module level completions are exempt from reaping. It is assumed that
|
|
||||||
module level completions will have a key length of 1.
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
time.sleep(300)
|
|
||||||
|
|
||||||
with _cache_lock:
|
|
||||||
now = time.time()
|
|
||||||
cur_len = len(_cache)
|
|
||||||
for cached in list(_cache.values()):
|
|
||||||
if cached.key[-1] not in ('package', 'local', 'boilerplate~',
|
|
||||||
'import~') \
|
|
||||||
and now - cached._touched > max_age:
|
|
||||||
_cache.pop(cached.key)
|
|
||||||
|
|
||||||
if cur_len - len(_cache) > 0:
|
|
||||||
log.debug('Removed %d of %d cache items', len(_cache), cur_len)
|
|
||||||
|
|
||||||
|
|
||||||
def cache_processor_thread(compl_queue):
|
|
||||||
errors = 0
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
compl = compl_queue.get()
|
|
||||||
cache_key = compl.get('cache_key')
|
|
||||||
cached = retrieve(cache_key)
|
|
||||||
if cached is None or cached.time <= compl.get('time'):
|
|
||||||
cached = store(cache_key, compl)
|
|
||||||
log.debug('Processed: %r', cache_key)
|
|
||||||
errors = 0
|
|
||||||
except Exception as e:
|
|
||||||
errors += 1
|
|
||||||
if errors > 3:
|
|
||||||
break
|
|
||||||
log.error('Got exception while processing: %r', e)
|
|
||||||
|
|
||||||
|
|
||||||
def start_background(compl_queue):
|
|
||||||
log.debug('Starting reaper thread')
|
|
||||||
t = threading.Thread(target=cache_processor_thread, args=(compl_queue,))
|
|
||||||
t.daemon = True
|
|
||||||
t.start()
|
|
||||||
t = threading.Thread(target=reap_cache)
|
|
||||||
t.daemon = True
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
|
|
||||||
# balanced() taken from:
|
|
||||||
# http://stackoverflow.com/a/6753172/4932879
|
|
||||||
# Modified to include string delimiters
|
|
||||||
def _balanced():
|
|
||||||
# Doc strings might be an issue, but we don't care.
|
|
||||||
idelim = iter("""(){}[]""''""")
|
|
||||||
delims = dict(zip(idelim, idelim))
|
|
||||||
odelims = {v: k for k, v in delims.items()}
|
|
||||||
closing = delims.values()
|
|
||||||
|
|
||||||
def balanced(astr):
|
|
||||||
"""Test if a string has balanced delimiters.
|
|
||||||
|
|
||||||
Returns a boolean and a string of the opened delimiter.
|
|
||||||
"""
|
|
||||||
stack = []
|
|
||||||
skip = False
|
|
||||||
open_d = ''
|
|
||||||
open_str = ''
|
|
||||||
for c in astr:
|
|
||||||
if c == '\\':
|
|
||||||
skip = True
|
|
||||||
continue
|
|
||||||
if skip:
|
|
||||||
skip = False
|
|
||||||
continue
|
|
||||||
d = delims.get(c, None)
|
|
||||||
if d and not open_str:
|
|
||||||
if d in '"\'':
|
|
||||||
open_str = d
|
|
||||||
open_d = odelims.get(d)
|
|
||||||
stack.append(d)
|
|
||||||
elif c in closing:
|
|
||||||
if c == open_str:
|
|
||||||
open_str = ''
|
|
||||||
if not open_str and (not stack or c != stack.pop()):
|
|
||||||
return False, open_d
|
|
||||||
if stack:
|
|
||||||
open_d = odelims.get(stack[-1])
|
|
||||||
else:
|
|
||||||
open_d = ''
|
|
||||||
return not stack, open_d
|
|
||||||
return balanced
|
|
||||||
balanced = _balanced()
|
|
||||||
|
|
||||||
|
|
||||||
def split_module(text, default_value=None):
|
|
||||||
"""Utility to split the module text.
|
|
||||||
|
|
||||||
If there is nothing to split, return `default_value`.
|
|
||||||
"""
|
|
||||||
b, d = balanced(text)
|
|
||||||
if not b:
|
|
||||||
# Handles cases where the cursor is inside of unclosed delimiters.
|
|
||||||
# If the input is: re.search(x.spl
|
|
||||||
# The returned value should be: x
|
|
||||||
if d and d not in '\'"':
|
|
||||||
di = text.rfind(d)
|
|
||||||
if di != -1:
|
|
||||||
text = text[di+1:]
|
|
||||||
else:
|
|
||||||
return default_value
|
|
||||||
m = re.search('([\S\.]+)$', text)
|
|
||||||
if m and '.' in m.group(1):
|
|
||||||
return m.group(1).rsplit('.', 1)[0]
|
|
||||||
return default_value
|
|
||||||
|
|
||||||
|
|
||||||
def get_parents(source, line, class_only=False):
|
|
||||||
"""Find the parent blocks
|
|
||||||
|
|
||||||
Collects parent blocks that contain the current line to help form a cache
|
|
||||||
key based on variable scope.
|
|
||||||
"""
|
|
||||||
parents = []
|
|
||||||
start = line - 1
|
|
||||||
indent = len(source[start]) - len(source[start].lstrip())
|
|
||||||
if class_only:
|
|
||||||
pattern = r'^\s*class\s+(\w+)'
|
|
||||||
else:
|
|
||||||
pattern = r'^\s*(?:def|class)\s+(\w+)'
|
|
||||||
|
|
||||||
for i in range(start, 0, -1):
|
|
||||||
s_line = source[i].lstrip()
|
|
||||||
l_indent = len(source[i]) - len(s_line)
|
|
||||||
if s_line and l_indent < indent:
|
|
||||||
m = re.search(pattern, s_line)
|
|
||||||
indent = l_indent
|
|
||||||
if m:
|
|
||||||
parents.insert(0, m.group(1))
|
|
||||||
|
|
||||||
return parents
|
|
||||||
|
|
||||||
|
|
||||||
def full_module(source, obj):
|
|
||||||
"""Construct the full module path
|
|
||||||
|
|
||||||
This finds all imports and attempts to reconstruct the full module path.
|
|
||||||
If matched on a standard `import` line, `obj` itself is a full module path.
|
|
||||||
On `from` import lines, the parent module is prepended to `obj`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
module = ''
|
|
||||||
obj_pat = r'(?:(\S+)\s+as\s+)?\b{0}\b'.format(re.escape(obj.split('.', 1)[0]))
|
|
||||||
for match in _import_re.finditer('\n'.join(source)):
|
|
||||||
module = ''
|
|
||||||
imp_line = ' '.join(match.group(0).split())
|
|
||||||
if imp_line.startswith('from '):
|
|
||||||
_, module, imp_line = imp_line.split(' ', 2)
|
|
||||||
m = re.search(obj_pat, imp_line)
|
|
||||||
if m:
|
|
||||||
# If the import is aliased, use the alias as part of the key
|
|
||||||
alias = m.group(1)
|
|
||||||
if alias:
|
|
||||||
obj = obj.split('.')
|
|
||||||
obj[0] = alias
|
|
||||||
obj = '.'.join(obj)
|
|
||||||
if module:
|
|
||||||
return '.'.join((module, obj))
|
|
||||||
return obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def sys_path(refresh=False):
|
|
||||||
global _paths
|
|
||||||
if not _paths or refresh:
|
|
||||||
p = subprocess.Popen([
|
|
||||||
python_path,
|
|
||||||
'-c', r'import sys; print("\n".join(sys.path))',
|
|
||||||
], stdout=subprocess.PIPE)
|
|
||||||
stdout, _ = p.communicate()
|
|
||||||
_paths = [x for x in stdout.decode('utf8').split('\n')
|
|
||||||
if x and os.path.isdir(x)]
|
|
||||||
return _paths
|
|
||||||
|
|
||||||
|
|
||||||
def is_package(module, refresh=False):
|
|
||||||
"""Test if a module path is an installed package
|
|
||||||
|
|
||||||
The current interpreter's sys.path is retrieved on first run.
|
|
||||||
"""
|
|
||||||
if re.search(r'[^\w\.]', module):
|
|
||||||
return False
|
|
||||||
|
|
||||||
paths = sys_path(refresh)
|
|
||||||
|
|
||||||
module = module.split('.', 1)[0]
|
|
||||||
pglobs = [os.path.join(x, module, '__init__.py') for x in paths]
|
|
||||||
pglobs.extend([os.path.join(x, '{}.*'.format(module)) for x in paths])
|
|
||||||
return any(map(glob.glob, pglobs))
|
|
||||||
|
|
||||||
|
|
||||||
def cache_context(filename, context, source, extra_path):
|
|
||||||
"""Caching based on context input.
|
|
||||||
|
|
||||||
If the input is blank, it was triggered with `.` to get module completions.
|
|
||||||
|
|
||||||
The module files as reported by Jedi are stored with their modification
|
|
||||||
times to help detect if a cache needs to be refreshed.
|
|
||||||
|
|
||||||
For scoped variables in the buffer, construct a cache key using the
|
|
||||||
filename. The buffer file's modification time is checked to see if the
|
|
||||||
completion needs to be refreshed. The approximate scope lines are cached
|
|
||||||
to help invalidate the cache based on line position.
|
|
||||||
|
|
||||||
Cache keys are made using tuples to make them easier to interpret later.
|
|
||||||
"""
|
|
||||||
cinput = context['input'].lstrip().lstrip('@')
|
|
||||||
if not re.sub(r'[\s\d\.]+', '', cinput):
|
|
||||||
return None, []
|
|
||||||
filename_hash = hashlib.md5(filename.encode('utf8')).hexdigest()
|
|
||||||
line = context['position'][1]
|
|
||||||
log.debug('Input: "%s"', cinput)
|
|
||||||
cache_key = None
|
|
||||||
extra_modules = []
|
|
||||||
cur_module = os.path.splitext(os.path.basename(filename))[0]
|
|
||||||
|
|
||||||
if cinput.startswith(('import ', 'from ')):
|
|
||||||
# Cache imports with buffer filename as the key prefix.
|
|
||||||
# For `from` imports, the first part of the statement is
|
|
||||||
# considered to be the same as `import` for caching.
|
|
||||||
|
|
||||||
import_key = 'import~'
|
|
||||||
cinput = context['input'].lstrip()
|
|
||||||
m = re.search(r'^from\s+(\S+)(.*)', cinput)
|
|
||||||
if m:
|
|
||||||
if m.group(2).lstrip() in 'import':
|
|
||||||
cache_key = ('importkeyword~', )
|
|
||||||
return cache_key, extra_modules
|
|
||||||
import_key = m.group(1) or 'import~'
|
|
||||||
elif cinput.startswith('import ') and cinput.rstrip().endswith('.'):
|
|
||||||
import_key = re.sub(r'[^\s\w\.]', ' ', cinput.strip()).split()[-1]
|
|
||||||
|
|
||||||
if import_key:
|
|
||||||
if '.' in import_key and import_key[-1] not in whitespace \
|
|
||||||
and not re.search(r'^from\s+\S+\s+import', cinput):
|
|
||||||
# Dot completion on the import line
|
|
||||||
import_key, _ = import_key.rsplit('.', 1)
|
|
||||||
import_key = import_key.rstrip('.')
|
|
||||||
module_file = utils.module_search(
|
|
||||||
import_key,
|
|
||||||
chain(extra_path,
|
|
||||||
[context.get('cwd'), os.path.dirname(filename)],
|
|
||||||
utils.rplugin_runtime_paths(context)))
|
|
||||||
if module_file:
|
|
||||||
cache_key = (import_key, 'local')
|
|
||||||
extra_modules.append(module_file)
|
|
||||||
elif is_package(import_key):
|
|
||||||
cache_key = (import_key, 'package')
|
|
||||||
elif not cinput.endswith('.'):
|
|
||||||
cache_key = ('import~',)
|
|
||||||
else:
|
|
||||||
return None, extra_modules
|
|
||||||
|
|
||||||
if not cache_key:
|
|
||||||
obj = split_module(cinput.strip())
|
|
||||||
if obj:
|
|
||||||
cache_key = (obj, 'package')
|
|
||||||
if obj.startswith('self'):
|
|
||||||
if os.path.exists(filename):
|
|
||||||
extra_modules.append(filename)
|
|
||||||
# `self` is a special case object that needs a scope included
|
|
||||||
# in the cache key.
|
|
||||||
parents = get_parents(source, line, class_only=True)
|
|
||||||
parents.insert(0, cur_module)
|
|
||||||
cache_key = (filename_hash, tuple(parents), obj)
|
|
||||||
else:
|
|
||||||
module_path = full_module(source, obj)
|
|
||||||
if module_path and not module_path.startswith('.') \
|
|
||||||
and is_package(module_path):
|
|
||||||
cache_key = (module_path, 'package')
|
|
||||||
else:
|
|
||||||
# A quick scan revealed that the dot completion doesn't
|
|
||||||
# involve an imported module. Treat it like a scoped
|
|
||||||
# variable and ensure the cache invalidates when the file
|
|
||||||
# is saved.
|
|
||||||
if os.path.exists(filename):
|
|
||||||
extra_modules.append(filename)
|
|
||||||
|
|
||||||
module_file = utils.module_search(module_path,
|
|
||||||
[os.path.dirname(filename)])
|
|
||||||
if module_file:
|
|
||||||
cache_key = (module_path, 'local')
|
|
||||||
else:
|
|
||||||
parents = get_parents(source, line)
|
|
||||||
parents.insert(0, cur_module)
|
|
||||||
cache_key = (filename_hash, tuple(parents), obj, 'dot')
|
|
||||||
elif context.get('complete_str') or cinput.rstrip().endswith('='):
|
|
||||||
parents = get_parents(source, line)
|
|
||||||
parents.insert(0, cur_module)
|
|
||||||
cache_key = (filename_hash, tuple(parents), 'vars')
|
|
||||||
if os.path.exists(filename):
|
|
||||||
extra_modules.append(filename)
|
|
||||||
|
|
||||||
return cache_key, extra_modules
|
|
@ -1,9 +0,0 @@
|
|||||||
def set_debug(logger, path):
|
|
||||||
from logging import FileHandler, Formatter, DEBUG
|
|
||||||
hdlr = FileHandler(path)
|
|
||||||
logger.addHandler(hdlr)
|
|
||||||
datefmt = '%Y/%m/%d %H:%M:%S'
|
|
||||||
fmt = Formatter(
|
|
||||||
"%(levelname)s %(asctime)s %(message)s", datefmt=datefmt)
|
|
||||||
hdlr.setFormatter(fmt)
|
|
||||||
logger.setLevel(DEBUG)
|
|
@ -1,63 +0,0 @@
|
|||||||
import functools
|
|
||||||
import queue
|
|
||||||
|
|
||||||
try:
|
|
||||||
import statistics
|
|
||||||
stdev = statistics.stdev
|
|
||||||
mean = statistics.mean
|
|
||||||
except ImportError:
|
|
||||||
stdev = None
|
|
||||||
|
|
||||||
def mean(l):
|
|
||||||
return sum(l) / len(l)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import time
|
|
||||||
clock = time.perf_counter
|
|
||||||
except Exception:
|
|
||||||
import timeit
|
|
||||||
clock = timeit.default_timer
|
|
||||||
|
|
||||||
|
|
||||||
class tfloat(float):
|
|
||||||
color = 39
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
n = self * 1000
|
|
||||||
return '\x1b[%dm%f\x1b[mms' % (self.color, n)
|
|
||||||
|
|
||||||
|
|
||||||
def profile(func):
|
|
||||||
name = func.__name__
|
|
||||||
samples = queue.deque(maxlen=5)
|
|
||||||
|
|
||||||
@functools.wraps(func)
|
|
||||||
def wrapper(self, *args, **kwargs):
|
|
||||||
if not self.is_debug_enabled:
|
|
||||||
return func(self, *args, **kwargs)
|
|
||||||
start = clock()
|
|
||||||
ret = func(self, *args, **kwargs)
|
|
||||||
n = tfloat(clock() - start)
|
|
||||||
|
|
||||||
if len(samples) < 2:
|
|
||||||
m = 0
|
|
||||||
d = 0
|
|
||||||
n.color = 36
|
|
||||||
else:
|
|
||||||
m = mean(samples)
|
|
||||||
if stdev:
|
|
||||||
d = tfloat(stdev(samples))
|
|
||||||
else:
|
|
||||||
d = 0
|
|
||||||
|
|
||||||
if n <= m + d:
|
|
||||||
n.color = 32
|
|
||||||
elif n > m + d * 2:
|
|
||||||
n.color = 31
|
|
||||||
else:
|
|
||||||
n.color = 33
|
|
||||||
samples.append(n)
|
|
||||||
self.info('\x1b[34m%s\x1b[m t = %s, \u00b5 = %s, \u03c3 = %s)',
|
|
||||||
name, n, m, d)
|
|
||||||
return ret
|
|
||||||
return wrapper
|
|
@ -1,576 +0,0 @@
|
|||||||
"""Jedi mini server for deoplete-jedi
|
|
||||||
|
|
||||||
This script allows Jedi to run using the Python interpreter that is found in
|
|
||||||
the user's environment instead of the one Neovim is using.
|
|
||||||
|
|
||||||
Jedi seems to accumulate latency with each completion. To deal with this, the
|
|
||||||
server is restarted after 50 completions. This threshold is relatively high
|
|
||||||
considering that deoplete-jedi caches completion results. These combined
|
|
||||||
should make deoplete-jedi's completions pretty fast and responsive.
|
|
||||||
"""
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import functools
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import struct
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
from glob import glob
|
|
||||||
|
|
||||||
# This is be possible because the path is inserted in deoplete_jedi.py as well
|
|
||||||
# as set in PYTHONPATH by the Client class.
|
|
||||||
from deoplete_jedi import utils
|
|
||||||
|
|
||||||
log = logging.getLogger('deoplete')
|
|
||||||
nullHandler = logging.NullHandler()
|
|
||||||
|
|
||||||
if not log.handlers:
|
|
||||||
log.addHandler(nullHandler)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import cPickle as pickle
|
|
||||||
except ImportError:
|
|
||||||
import pickle
|
|
||||||
|
|
||||||
libpath = os.path.join(
|
|
||||||
os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'vendored')
|
|
||||||
jedi_path = os.path.join(libpath, 'jedi')
|
|
||||||
parso_path = os.path.join(libpath, 'parso')
|
|
||||||
|
|
||||||
# Type mapping. Empty values will use the key value instead.
|
|
||||||
# Keep them 5 characters max to minimize required space to display.
|
|
||||||
_types = {
|
|
||||||
'import': 'imprt',
|
|
||||||
'class': '',
|
|
||||||
'function': 'def',
|
|
||||||
'globalstmt': 'var',
|
|
||||||
'instance': 'var',
|
|
||||||
'statement': 'var',
|
|
||||||
'keyword': 'keywd',
|
|
||||||
'module': 'mod',
|
|
||||||
'param': 'arg',
|
|
||||||
'property': 'prop',
|
|
||||||
|
|
||||||
'bool': '',
|
|
||||||
'bytes': 'byte',
|
|
||||||
'complex': 'cmplx',
|
|
||||||
'dict': '',
|
|
||||||
'list': '',
|
|
||||||
'float': '',
|
|
||||||
'int': '',
|
|
||||||
'object': 'obj',
|
|
||||||
'set': '',
|
|
||||||
'slice': '',
|
|
||||||
'str': '',
|
|
||||||
'tuple': '',
|
|
||||||
'mappingproxy': 'dict', # cls.__dict__
|
|
||||||
'member_descriptor': 'cattr',
|
|
||||||
'getset_descriptor': 'cprop',
|
|
||||||
'method_descriptor': 'cdef',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class StreamError(Exception):
|
|
||||||
"""Error in reading/writing streams."""
|
|
||||||
|
|
||||||
|
|
||||||
class StreamEmpty(StreamError):
|
|
||||||
"""Empty stream data"""
|
|
||||||
|
|
||||||
|
|
||||||
def stream_read(pipe):
|
|
||||||
"""Read data from the pipe."""
|
|
||||||
buffer = getattr(pipe, 'buffer', pipe)
|
|
||||||
header = buffer.read(4)
|
|
||||||
if not len(header):
|
|
||||||
raise StreamEmpty
|
|
||||||
|
|
||||||
if len(header) < 4:
|
|
||||||
raise StreamError('Incorrect byte length')
|
|
||||||
|
|
||||||
length = struct.unpack('I', header)[0]
|
|
||||||
data = buffer.read(length)
|
|
||||||
if len(data) < length:
|
|
||||||
raise StreamError('Got less data than expected')
|
|
||||||
return pickle.loads(data)
|
|
||||||
|
|
||||||
|
|
||||||
def stream_write(pipe, obj):
|
|
||||||
"""Write data to the pipe."""
|
|
||||||
data = pickle.dumps(obj, 2)
|
|
||||||
header = struct.pack(b'I', len(data))
|
|
||||||
buffer = getattr(pipe, 'buffer', pipe)
|
|
||||||
buffer.write(header + data)
|
|
||||||
pipe.flush()
|
|
||||||
|
|
||||||
|
|
||||||
def strip_decor(source):
|
|
||||||
"""Remove decorators lines
|
|
||||||
|
|
||||||
If the decorator is a function call, this will leave them dangling. Jedi
|
|
||||||
should be fine with this since they'll look like tuples just hanging out
|
|
||||||
not doing anything important.
|
|
||||||
"""
|
|
||||||
return re.sub(r'^(\s*)@\w+', r'\1', source, flags=re.M)
|
|
||||||
|
|
||||||
|
|
||||||
def retry_completion(func):
|
|
||||||
"""Decorator to retry a completion
|
|
||||||
|
|
||||||
A second attempt is made with decorators stripped from the source.
|
|
||||||
"""
|
|
||||||
@functools.wraps(func)
|
|
||||||
def wrapper(self, source, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
return func(self, source, *args, **kwargs)
|
|
||||||
except Exception:
|
|
||||||
if '@' in source:
|
|
||||||
log.warn('Retrying completion %r', func.__name__, exc_info=True)
|
|
||||||
try:
|
|
||||||
return func(self, strip_decor(source), *args, **kwargs)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
log.warn('Failed completion %r', func.__name__, exc_info=True)
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class Server(object):
|
|
||||||
"""Server class
|
|
||||||
|
|
||||||
This is created when this script is ran directly.
|
|
||||||
"""
|
|
||||||
def __init__(self, desc_len=0, short_types=False, show_docstring=False):
|
|
||||||
self.desc_len = desc_len
|
|
||||||
self.use_short_types = short_types
|
|
||||||
self.show_docstring = show_docstring
|
|
||||||
self.unresolved_imports = set()
|
|
||||||
|
|
||||||
from jedi import settings
|
|
||||||
|
|
||||||
settings.use_filesystem_cache = False
|
|
||||||
|
|
||||||
def _loop(self):
|
|
||||||
from jedi.evaluate.sys_path import _get_venv_sitepackages
|
|
||||||
|
|
||||||
while True:
|
|
||||||
data = stream_read(sys.stdin)
|
|
||||||
if not isinstance(data, tuple):
|
|
||||||
continue
|
|
||||||
|
|
||||||
cache_key, source, line, col, filename, options = data
|
|
||||||
orig_path = sys.path[:]
|
|
||||||
venv = os.getenv('VIRTUAL_ENV')
|
|
||||||
if venv:
|
|
||||||
sys.path.insert(0, _get_venv_sitepackages(venv))
|
|
||||||
add_path = self.find_extra_sys_path(filename)
|
|
||||||
if add_path and add_path not in sys.path:
|
|
||||||
# Add the found path to sys.path. I'm not 100% certain if this
|
|
||||||
# is actually helping anything, but it feels like the right
|
|
||||||
# thing to do.
|
|
||||||
sys.path.insert(0, add_path)
|
|
||||||
if filename:
|
|
||||||
sys.path.append(os.path.dirname(filename))
|
|
||||||
|
|
||||||
if isinstance(options, dict):
|
|
||||||
extra = options.get('extra_path')
|
|
||||||
if extra:
|
|
||||||
if not isinstance(extra, list):
|
|
||||||
extra = [extra]
|
|
||||||
sys.path.extend(extra)
|
|
||||||
|
|
||||||
# Add extra paths if working on a Python remote plugin.
|
|
||||||
sys.path.extend(utils.rplugin_runtime_paths(options))
|
|
||||||
|
|
||||||
# Decorators on incomplete functions cause an error to be raised by
|
|
||||||
# Jedi. I assume this is because Jedi is attempting to evaluate
|
|
||||||
# the return value of the wrapped, but broken, function.
|
|
||||||
# Our solution is to simply strip decorators from the source since
|
|
||||||
# we are a completion service, not the syntax police.
|
|
||||||
out = self.script_completion(source, line, col, filename)
|
|
||||||
|
|
||||||
if not out and cache_key[-1] == 'vars':
|
|
||||||
# Attempt scope completion. If it fails, it should fall
|
|
||||||
# through to script completion.
|
|
||||||
log.debug('Fallback to scoped completions')
|
|
||||||
out = self.scoped_completions(source, filename, cache_key[-2])
|
|
||||||
|
|
||||||
if not out and isinstance(options, dict) and 'synthetic' in options:
|
|
||||||
synthetic = options.get('synthetic')
|
|
||||||
log.debug('Using synthetic completion: %r', synthetic)
|
|
||||||
out = self.script_completion(synthetic['src'],
|
|
||||||
synthetic['line'],
|
|
||||||
synthetic['col'], filename)
|
|
||||||
|
|
||||||
if not out and cache_key[-1] in ('package', 'local'):
|
|
||||||
# The backup plan
|
|
||||||
log.debug('Fallback to module completions')
|
|
||||||
try:
|
|
||||||
out = self.module_completions(cache_key[0], sys.path)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
stream_write(sys.stdout, out)
|
|
||||||
sys.path[:] = orig_path
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
log.debug('Starting server. sys.path = %r', sys.path)
|
|
||||||
try:
|
|
||||||
stream_write(sys.stdout, tuple(sys.version_info))
|
|
||||||
self._loop()
|
|
||||||
except StreamEmpty:
|
|
||||||
log.debug('Input closed. Shutting down.')
|
|
||||||
except Exception:
|
|
||||||
log.exception('Server Exception. Shutting down.')
|
|
||||||
|
|
||||||
def find_extra_sys_path(self, filename):
|
|
||||||
"""Find the file's "root"
|
|
||||||
|
|
||||||
This tries to determine the script's root package. The first step is
|
|
||||||
to scan upward until there are no longer __init__.py files. If that
|
|
||||||
fails, check immediate subdirectories to find __init__.py files which
|
|
||||||
could mean that the current script is not part of a package, but has
|
|
||||||
sub-modules.
|
|
||||||
"""
|
|
||||||
add_path = ''
|
|
||||||
dirname = os.path.dirname(filename)
|
|
||||||
scan_dir = dirname
|
|
||||||
while len(scan_dir) \
|
|
||||||
and os.path.isfile(os.path.join(scan_dir, '__init__.py')):
|
|
||||||
scan_dir = os.path.dirname(scan_dir)
|
|
||||||
|
|
||||||
if scan_dir != dirname:
|
|
||||||
add_path = scan_dir
|
|
||||||
elif glob('{}/*/__init__.py'.format(dirname)):
|
|
||||||
add_path = dirname
|
|
||||||
|
|
||||||
return add_path
|
|
||||||
|
|
||||||
def module_completions(self, module, paths):
|
|
||||||
"""Directly get completions from the module file
|
|
||||||
|
|
||||||
This is the fallback if all else fails for module completion.
|
|
||||||
"""
|
|
||||||
found = utils.module_search(module, paths)
|
|
||||||
if not found:
|
|
||||||
return None
|
|
||||||
|
|
||||||
log.debug('Found script for fallback completions: %r', found)
|
|
||||||
mod_parts = tuple(re.sub(r'\.+', '.', module).strip('.').split('.'))
|
|
||||||
path_parts = os.path.splitext(found)[0].split('/')
|
|
||||||
if path_parts[-1] == '__init__':
|
|
||||||
path_parts.pop()
|
|
||||||
path_parts = tuple(path_parts)
|
|
||||||
match_mod = mod_parts
|
|
||||||
ml = len(mod_parts)
|
|
||||||
for i in range(ml):
|
|
||||||
if path_parts[i-ml:] == mod_parts[:ml-i]:
|
|
||||||
match_mod = mod_parts[-i:]
|
|
||||||
break
|
|
||||||
log.debug('Remainder to match: %r', match_mod)
|
|
||||||
|
|
||||||
import jedi
|
|
||||||
|
|
||||||
completions = jedi.api.names(path=found, references=True)
|
|
||||||
completions = utils.jedi_walk(completions)
|
|
||||||
while len(match_mod):
|
|
||||||
for c in completions:
|
|
||||||
if c.name == match_mod[0]:
|
|
||||||
completions = c.defined_names()
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
log.debug('No more matches at %r', match_mod[0])
|
|
||||||
return []
|
|
||||||
match_mod = match_mod[:-1]
|
|
||||||
|
|
||||||
out = []
|
|
||||||
tmp_filecache = {}
|
|
||||||
seen = set()
|
|
||||||
for c in completions:
|
|
||||||
parsed = self.parse_completion(c, tmp_filecache)
|
|
||||||
seen_key = (parsed['type'], parsed['name'])
|
|
||||||
if seen_key in seen:
|
|
||||||
continue
|
|
||||||
seen.add(seen_key)
|
|
||||||
out.append(parsed)
|
|
||||||
return out
|
|
||||||
|
|
||||||
@retry_completion
|
|
||||||
def script_completion(self, source, line, col, filename):
|
|
||||||
"""Standard Jedi completions"""
|
|
||||||
import jedi
|
|
||||||
|
|
||||||
log.debug('Line: %r, Col: %r, Filename: %r', line, col, filename)
|
|
||||||
completions = jedi.Script(source, line, col, filename).completions()
|
|
||||||
out = []
|
|
||||||
tmp_filecache = {}
|
|
||||||
for c in completions:
|
|
||||||
out.append(self.parse_completion(c, tmp_filecache))
|
|
||||||
return out
|
|
||||||
|
|
||||||
def get_parents(self, c):
|
|
||||||
"""Collect parent blocks
|
|
||||||
|
|
||||||
This is for matching a request's cache key when performing scoped
|
|
||||||
completions.
|
|
||||||
"""
|
|
||||||
parents = []
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
c = c.parent()
|
|
||||||
parents.insert(0, c.name)
|
|
||||||
if c.type == 'module':
|
|
||||||
break
|
|
||||||
except AttributeError:
|
|
||||||
break
|
|
||||||
return tuple(parents)
|
|
||||||
|
|
||||||
def resolve_import(self, completion, depth=0, max_depth=10, seen=None):
|
|
||||||
"""Follow import until it no longer is an import type"""
|
|
||||||
if seen is None:
|
|
||||||
seen = []
|
|
||||||
seen.append(completion)
|
|
||||||
log.debug('Resolving: %r', completion)
|
|
||||||
defs = completion.goto_assignments()
|
|
||||||
if not defs:
|
|
||||||
return None
|
|
||||||
resolved = defs[0]
|
|
||||||
if resolved in seen:
|
|
||||||
return None
|
|
||||||
if resolved.type == 'import' and depth < max_depth:
|
|
||||||
return self.resolve_import(resolved, depth + 1, max_depth, seen)
|
|
||||||
log.debug('Resolved: %r', resolved)
|
|
||||||
return resolved
|
|
||||||
|
|
||||||
@retry_completion
|
|
||||||
def scoped_completions(self, source, filename, parent):
|
|
||||||
"""Scoped completion
|
|
||||||
|
|
||||||
This gets all definitions for a specific scope allowing them to be
|
|
||||||
cached without needing to consider the current position in the source.
|
|
||||||
This would be slow in Vim without threading.
|
|
||||||
"""
|
|
||||||
import jedi
|
|
||||||
|
|
||||||
completions = jedi.api.names(source, filename, all_scopes=True)
|
|
||||||
out = []
|
|
||||||
tmp_filecache = {}
|
|
||||||
seen = set()
|
|
||||||
for c in completions:
|
|
||||||
c_parents = self.get_parents(c)
|
|
||||||
if parent and (len(c_parents) > len(parent) or
|
|
||||||
c_parents != parent[:len(c_parents)]):
|
|
||||||
continue
|
|
||||||
if c.type == 'import' and c.full_name not in self.unresolved_imports:
|
|
||||||
resolved = self.resolve_import(c)
|
|
||||||
if resolved is None:
|
|
||||||
log.debug('Could not resolve import: %r', c.full_name)
|
|
||||||
self.unresolved_imports.add(c.full_name)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
c = resolved
|
|
||||||
parsed = self.parse_completion(c, tmp_filecache)
|
|
||||||
seen_key = (parsed['name'], parsed['type'])
|
|
||||||
if seen_key in seen:
|
|
||||||
continue
|
|
||||||
seen.add(seen_key)
|
|
||||||
out.append(parsed)
|
|
||||||
return out
|
|
||||||
|
|
||||||
def completion_dict(self, name, type_, comp):
|
|
||||||
"""Final construction of the completion dict."""
|
|
||||||
doc = comp.docstring()
|
|
||||||
i = doc.find('\n\n')
|
|
||||||
if i != -1:
|
|
||||||
doc = doc[i:]
|
|
||||||
|
|
||||||
params = None
|
|
||||||
try:
|
|
||||||
if type_ in ('function', 'class'):
|
|
||||||
params = []
|
|
||||||
for i, p in enumerate(comp.params):
|
|
||||||
desc = p.description.strip()
|
|
||||||
if i == 0 and desc == 'self':
|
|
||||||
continue
|
|
||||||
if '\\n' in desc:
|
|
||||||
desc = desc.replace('\\n', '\\x0A')
|
|
||||||
# Note: Hack for jedi param bugs
|
|
||||||
if desc.startswith('param ') or desc == 'param':
|
|
||||||
desc = desc[5:].strip()
|
|
||||||
if desc:
|
|
||||||
params.append(desc)
|
|
||||||
except Exception:
|
|
||||||
params = None
|
|
||||||
|
|
||||||
return {
|
|
||||||
'module': comp.module_path,
|
|
||||||
'name': name,
|
|
||||||
'type': type_,
|
|
||||||
'short_type': _types.get(type_),
|
|
||||||
'doc': doc.strip(),
|
|
||||||
'params': params,
|
|
||||||
}
|
|
||||||
|
|
||||||
def parse_completion(self, comp, cache):
|
|
||||||
"""Return a tuple describing the completion.
|
|
||||||
|
|
||||||
Returns (name, type, description, abbreviated)
|
|
||||||
"""
|
|
||||||
name = comp.name
|
|
||||||
|
|
||||||
type_ = comp.type
|
|
||||||
desc = comp.description
|
|
||||||
|
|
||||||
if type_ == 'instance' and desc.startswith(('builtins.', 'posix.')):
|
|
||||||
# Simple description
|
|
||||||
builtin_type = desc.rsplit('.', 1)[-1]
|
|
||||||
if builtin_type in _types:
|
|
||||||
return self.completion_dict(name, builtin_type, comp)
|
|
||||||
|
|
||||||
if type_ == 'class' and desc.startswith('builtins.'):
|
|
||||||
return self.completion_dict(name, type_, comp)
|
|
||||||
|
|
||||||
if type_ == 'function':
|
|
||||||
if comp.module_path not in cache and comp.line and comp.line > 1 \
|
|
||||||
and os.path.exists(comp.module_path):
|
|
||||||
with open(comp.module_path, 'r') as fp:
|
|
||||||
cache[comp.module_path] = fp.readlines()
|
|
||||||
lines = cache.get(comp.module_path)
|
|
||||||
if isinstance(lines, list) and len(lines) > 1 \
|
|
||||||
and comp.line < len(lines) and comp.line > 1:
|
|
||||||
# Check the function's decorators to check if it's decorated
|
|
||||||
# with @property
|
|
||||||
i = comp.line - 2
|
|
||||||
while i >= 0:
|
|
||||||
line = lines[i].lstrip()
|
|
||||||
if not line.startswith('@'):
|
|
||||||
break
|
|
||||||
if line.startswith('@property'):
|
|
||||||
return self.completion_dict(name, 'property', comp)
|
|
||||||
i -= 1
|
|
||||||
return self.completion_dict(name, type_, comp)
|
|
||||||
|
|
||||||
return self.completion_dict(name, type_, comp)
|
|
||||||
|
|
||||||
|
|
||||||
class Client(object):
|
|
||||||
"""Client object
|
|
||||||
|
|
||||||
This will be used by deoplete-jedi to interact with the server.
|
|
||||||
"""
|
|
||||||
max_completion_count = 50
|
|
||||||
|
|
||||||
def __init__(self, desc_len=0, short_types=False, show_docstring=False,
|
|
||||||
debug=False, python_path=None):
|
|
||||||
self._server = None
|
|
||||||
self.restarting = threading.Lock()
|
|
||||||
self.version = (0, 0, 0, 'final', 0)
|
|
||||||
self.env = os.environ.copy()
|
|
||||||
self.env.update({
|
|
||||||
'PYTHONPATH': os.pathsep.join(
|
|
||||||
(parso_path, jedi_path,
|
|
||||||
os.path.dirname(os.path.dirname(__file__)))),
|
|
||||||
})
|
|
||||||
|
|
||||||
if 'VIRTUAL_ENV' in os.environ:
|
|
||||||
self.env['VIRTUAL_ENV'] = os.getenv('VIRTUAL_ENV')
|
|
||||||
prog = os.path.join(self.env['VIRTUAL_ENV'], 'bin', 'python')
|
|
||||||
elif python_path:
|
|
||||||
prog = python_path
|
|
||||||
else:
|
|
||||||
prog = 'python'
|
|
||||||
|
|
||||||
self.cmd = [prog, '-u', __file__, '--desc-length', str(desc_len)]
|
|
||||||
if short_types:
|
|
||||||
self.cmd.append('--short-types')
|
|
||||||
if show_docstring:
|
|
||||||
self.cmd.append('--docstrings')
|
|
||||||
if debug:
|
|
||||||
self.cmd.extend(('--debug', debug[0], '--debug-level',
|
|
||||||
str(debug[1])))
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.restart()
|
|
||||||
except Exception as exc:
|
|
||||||
from deoplete.exceptions import SourceInitError
|
|
||||||
raise SourceInitError('Failed to start server ({}): {}'.format(
|
|
||||||
' '.join(self.cmd), exc))
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
"""Shut down the server."""
|
|
||||||
if self._server is not None and self._server.returncode is None:
|
|
||||||
# Closing the server's stdin will cause it to exit.
|
|
||||||
self._server.stdin.close()
|
|
||||||
self._server.kill()
|
|
||||||
|
|
||||||
def restart(self):
|
|
||||||
"""Start or restart the server
|
|
||||||
|
|
||||||
If a server is already running, shut it down.
|
|
||||||
"""
|
|
||||||
with self.restarting:
|
|
||||||
self.shutdown()
|
|
||||||
self._server = subprocess.Popen(self.cmd, stdin=subprocess.PIPE,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE,
|
|
||||||
env=self.env)
|
|
||||||
# Might result in "pyenv: version `foo' is not installed (set by
|
|
||||||
# /cwd/.python-version)" on stderr.
|
|
||||||
try:
|
|
||||||
self.version = stream_read(self._server.stdout)
|
|
||||||
except StreamEmpty:
|
|
||||||
out, err = self._server.communicate()
|
|
||||||
raise Exception('Server exited with {}: error: {}'.format(
|
|
||||||
err, self._server.returncode))
|
|
||||||
self._count = 0
|
|
||||||
|
|
||||||
def completions(self, *args):
|
|
||||||
"""Get completions from the server.
|
|
||||||
|
|
||||||
If the number of completions already performed reaches a threshold,
|
|
||||||
restart the server.
|
|
||||||
"""
|
|
||||||
if self._count > self.max_completion_count:
|
|
||||||
self.restart()
|
|
||||||
|
|
||||||
self._count += 1
|
|
||||||
try:
|
|
||||||
stream_write(self._server.stdin, args)
|
|
||||||
return stream_read(self._server.stdout)
|
|
||||||
except StreamError as exc:
|
|
||||||
if self.restarting.acquire(False):
|
|
||||||
self.restarting.release()
|
|
||||||
log.error('Caught %s during handling completions(%s), '
|
|
||||||
' restarting server', exc, args)
|
|
||||||
self.restart()
|
|
||||||
time.sleep(0.2)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--desc-length', type=int)
|
|
||||||
parser.add_argument('--short-types', action='store_true')
|
|
||||||
parser.add_argument('--docstrings', action='store_true')
|
|
||||||
parser.add_argument('--debug', default='')
|
|
||||||
parser.add_argument('--debug-level', type=int, default=logging.DEBUG)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
if args.debug:
|
|
||||||
log.removeHandler(nullHandler)
|
|
||||||
formatter = logging.Formatter('%(asctime)s %(levelname)-8s '
|
|
||||||
'(%(name)s) %(message)s')
|
|
||||||
handler = logging.FileHandler(args.debug)
|
|
||||||
handler.setFormatter(formatter)
|
|
||||||
handler.setLevel(args.debug_level)
|
|
||||||
log.addHandler(handler)
|
|
||||||
log.setLevel(logging.DEBUG)
|
|
||||||
log = log.getChild('jedi.server')
|
|
||||||
|
|
||||||
s = Server(args.desc_length, args.short_types, args.docstrings)
|
|
||||||
s.run()
|
|
||||||
else:
|
|
||||||
log = log.getChild('jedi.client')
|
|
@ -1,90 +0,0 @@
|
|||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def file_mtime(filename):
|
|
||||||
"""Get file modification time
|
|
||||||
|
|
||||||
Return 0 if the file does not exist
|
|
||||||
"""
|
|
||||||
if not os.path.exists(filename):
|
|
||||||
return 0
|
|
||||||
return int(os.path.getmtime(filename))
|
|
||||||
|
|
||||||
|
|
||||||
def module_file(dirname, suffix, base):
|
|
||||||
"""Find a script that matches the suffix path."""
|
|
||||||
search = os.path.abspath(os.path.join(dirname, suffix))
|
|
||||||
# dirname = os.path.dirname(dirname)
|
|
||||||
found = ''
|
|
||||||
while True:
|
|
||||||
p = os.path.join(search, '__init__.py')
|
|
||||||
if os.path.isfile(p):
|
|
||||||
found = p
|
|
||||||
break
|
|
||||||
p = search + '.py'
|
|
||||||
if os.path.isfile(p):
|
|
||||||
found = p
|
|
||||||
break
|
|
||||||
if os.path.basename(search) == base or search == dirname:
|
|
||||||
break
|
|
||||||
search = os.path.dirname(search)
|
|
||||||
return found
|
|
||||||
|
|
||||||
|
|
||||||
def module_search(module, paths):
|
|
||||||
"""Search paths for a file matching the module."""
|
|
||||||
if not module:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
base = re.sub(r'\.+', '.', module).strip('.').split('.')[0]
|
|
||||||
module_path = os.path.normpath(re.sub(r'(\.+)', r'/\1/', module).strip('/'))
|
|
||||||
for p in paths:
|
|
||||||
found = module_file(p, module_path, base)
|
|
||||||
if found:
|
|
||||||
return found
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
def rplugin_runtime_paths(context):
|
|
||||||
"""Adds Neovim runtime paths.
|
|
||||||
|
|
||||||
Additional paths are added only if a `rplugin/python*` exists.
|
|
||||||
"""
|
|
||||||
paths = []
|
|
||||||
|
|
||||||
if context and 'cwd' in context:
|
|
||||||
cwd = context.get('cwd')
|
|
||||||
rplugins = ('rplugin/python{}'.format(sys.version_info[0]),
|
|
||||||
'rplugin/pythonx')
|
|
||||||
|
|
||||||
paths.extend(filter(os.path.exists,
|
|
||||||
(os.path.join(cwd, x)
|
|
||||||
for x in rplugins)))
|
|
||||||
|
|
||||||
if paths:
|
|
||||||
for rtp in context.get('runtimepath', '').split(','):
|
|
||||||
if not rtp:
|
|
||||||
continue
|
|
||||||
paths.extend(filter(os.path.exists,
|
|
||||||
(os.path.join(rtp, x)
|
|
||||||
for x in rplugins)))
|
|
||||||
return paths
|
|
||||||
|
|
||||||
|
|
||||||
def jedi_walk(completions, depth=0, max_depth=5):
|
|
||||||
"""Walk through Jedi objects
|
|
||||||
|
|
||||||
The purpose for this is to help find an object with a specific name. Once
|
|
||||||
found, the walking will stop.
|
|
||||||
"""
|
|
||||||
for c in completions:
|
|
||||||
yield c
|
|
||||||
if hasattr(c, 'description') and c.type == 'import':
|
|
||||||
d = c.description
|
|
||||||
if d.startswith('from ') and d.endswith('*') and depth < max_depth:
|
|
||||||
# Haven't determined the lowest Python 3 version required.
|
|
||||||
# If we determine 3.3, we can use `yield from`
|
|
||||||
for sub in jedi_walk(c.defined_names(), depth+1, max_depth):
|
|
||||||
yield sub
|
|
@ -1,85 +0,0 @@
|
|||||||
import logging
|
|
||||||
import os
|
|
||||||
import queue
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
from .server import Client
|
|
||||||
from .utils import file_mtime
|
|
||||||
|
|
||||||
log = logging.getLogger('deoplete.jedi.worker')
|
|
||||||
workers = []
|
|
||||||
work_queue = queue.Queue()
|
|
||||||
comp_queue = queue.Queue()
|
|
||||||
|
|
||||||
|
|
||||||
class Worker(threading.Thread):
|
|
||||||
daemon = True
|
|
||||||
|
|
||||||
def __init__(self, in_queue, out_queue, desc_len=0, server_timeout=10,
|
|
||||||
short_types=False, show_docstring=False, debug=False,
|
|
||||||
python_path=None):
|
|
||||||
self._client = Client(desc_len, short_types, show_docstring, debug,
|
|
||||||
python_path)
|
|
||||||
|
|
||||||
self.server_timeout = server_timeout
|
|
||||||
self.in_queue = in_queue
|
|
||||||
self.out_queue = out_queue
|
|
||||||
super(Worker, self).__init__()
|
|
||||||
self.log = log.getChild(self.name)
|
|
||||||
|
|
||||||
def completion_work(self, cache_key, extra_modules, source, line, col,
|
|
||||||
filename, options):
|
|
||||||
completions = self._client.completions(cache_key, source, line, col,
|
|
||||||
filename, options)
|
|
||||||
modules = {f: file_mtime(f) for f in extra_modules}
|
|
||||||
if completions is not None:
|
|
||||||
for c in completions:
|
|
||||||
m = c['module']
|
|
||||||
if m and m not in modules and os.path.exists(m):
|
|
||||||
modules[m] = file_mtime(m)
|
|
||||||
|
|
||||||
self.results = {
|
|
||||||
'cache_key': cache_key,
|
|
||||||
'time': time.time(),
|
|
||||||
'modules': modules,
|
|
||||||
'completions': completions,
|
|
||||||
}
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
work = self.in_queue.get()
|
|
||||||
self.log.debug('Got work')
|
|
||||||
|
|
||||||
self.results = None
|
|
||||||
t = threading.Thread(target=self.completion_work, args=work)
|
|
||||||
t.start()
|
|
||||||
t.join(timeout=self.server_timeout)
|
|
||||||
|
|
||||||
if self.results:
|
|
||||||
self.out_queue.put(self.results)
|
|
||||||
self.log.debug('Completed work')
|
|
||||||
else:
|
|
||||||
self.log.warn('Restarting server because it\'s taking '
|
|
||||||
'too long')
|
|
||||||
# Kill all but the last queued job since they're most
|
|
||||||
# likely a backlog that are no longer relevant.
|
|
||||||
while self.in_queue.qsize() > 1:
|
|
||||||
self.in_queue.get()
|
|
||||||
self.in_queue.task_done()
|
|
||||||
self._client.restart()
|
|
||||||
self.in_queue.task_done()
|
|
||||||
except Exception:
|
|
||||||
self.log.debug('Worker error', exc_info=True)
|
|
||||||
|
|
||||||
|
|
||||||
def start(count, desc_len=0, server_timeout=10, short_types=False,
|
|
||||||
show_docstring=False, debug=False, python_path=None):
|
|
||||||
while count > 0:
|
|
||||||
t = Worker(work_queue, comp_queue, desc_len, server_timeout, short_types,
|
|
||||||
show_docstring, debug, python_path)
|
|
||||||
workers.append(t)
|
|
||||||
t.start()
|
|
||||||
log.debug('Started worker: %r', t)
|
|
||||||
count -= 1
|
|
@ -1,19 +0,0 @@
|
|||||||
[run]
|
|
||||||
omit =
|
|
||||||
jedi/_compatibility.py
|
|
||||||
jedi/evaluate/site.py
|
|
||||||
|
|
||||||
[report]
|
|
||||||
# Regexes for lines to exclude from consideration
|
|
||||||
exclude_lines =
|
|
||||||
# Don't complain about missing debug-only code:
|
|
||||||
def __repr__
|
|
||||||
if self\.debug
|
|
||||||
|
|
||||||
# Don't complain if tests don't hit defensive assertion code:
|
|
||||||
raise AssertionError
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
# Don't complain if non-runnable code isn't run:
|
|
||||||
if 0:
|
|
||||||
if __name__ == .__main__.:
|
|
@ -1,13 +0,0 @@
|
|||||||
*~
|
|
||||||
*.sw?
|
|
||||||
*.pyc
|
|
||||||
.ropeproject
|
|
||||||
.tox
|
|
||||||
.coveralls.yml
|
|
||||||
.coverage
|
|
||||||
/build/
|
|
||||||
/docs/_build/
|
|
||||||
/dist/
|
|
||||||
jedi.egg-info/
|
|
||||||
record.json
|
|
||||||
/.cache/
|
|
@ -1,30 +0,0 @@
|
|||||||
language: python
|
|
||||||
sudo: false
|
|
||||||
python:
|
|
||||||
- 2.6
|
|
||||||
- 2.7
|
|
||||||
- 3.3
|
|
||||||
- 3.4
|
|
||||||
- 3.5
|
|
||||||
- 3.6
|
|
||||||
- pypy
|
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- python: pypy
|
|
||||||
- env: TOXENV=cov
|
|
||||||
- env: TOXENV=sith
|
|
||||||
include:
|
|
||||||
- python: 3.5
|
|
||||||
env: TOXENV=cov
|
|
||||||
- python: 3.5
|
|
||||||
env: TOXENV=sith
|
|
||||||
install:
|
|
||||||
- pip install --quiet tox-travis
|
|
||||||
script:
|
|
||||||
- tox
|
|
||||||
after_script:
|
|
||||||
- if [ $TOXENV == "cov" ]; then
|
|
||||||
pip install --quiet coveralls;
|
|
||||||
coveralls;
|
|
||||||
fi
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
|||||||
Main Authors
|
|
||||||
============
|
|
||||||
|
|
||||||
David Halter (@davidhalter) <davidhalter88@gmail.com>
|
|
||||||
Takafumi Arakaki (@tkf) <aka.tkf@gmail.com>
|
|
||||||
|
|
||||||
Code Contributors
|
|
||||||
=================
|
|
||||||
|
|
||||||
Danilo Bargen (@dbrgn) <mail@dbrgn.ch>
|
|
||||||
Laurens Van Houtven (@lvh) <_@lvh.cc>
|
|
||||||
Aldo Stracquadanio (@Astrac) <aldo.strac@gmail.com>
|
|
||||||
Jean-Louis Fuchs (@ganwell) <ganwell@fangorn.ch>
|
|
||||||
tek (@tek)
|
|
||||||
Yasha Borevich (@jjay) <j.borevich@gmail.com>
|
|
||||||
Aaron Griffin <aaronmgriffin@gmail.com>
|
|
||||||
andviro (@andviro)
|
|
||||||
Mike Gilbert (@floppym) <floppym@gentoo.org>
|
|
||||||
Aaron Meurer (@asmeurer) <asmeurer@gmail.com>
|
|
||||||
Lubos Trilety <ltrilety@redhat.com>
|
|
||||||
Akinori Hattori (@hattya) <hattya@gmail.com>
|
|
||||||
srusskih (@srusskih)
|
|
||||||
Steven Silvester (@blink1073)
|
|
||||||
Colin Duquesnoy (@ColinDuquesnoy) <colin.duquesnoy@gmail.com>
|
|
||||||
Jorgen Schaefer (@jorgenschaefer) <contact@jorgenschaefer.de>
|
|
||||||
Fredrik Bergroth (@fbergroth)
|
|
||||||
Mathias Fußenegger (@mfussenegger)
|
|
||||||
Syohei Yoshida (@syohex) <syohex@gmail.com>
|
|
||||||
ppalucky (@ppalucky)
|
|
||||||
immerrr (@immerrr) immerrr@gmail.com
|
|
||||||
Albertas Agejevas (@alga)
|
|
||||||
Savor d'Isavano (@KenetJervet) <newelevenken@163.com>
|
|
||||||
Phillip Berndt (@phillipberndt) <phillip.berndt@gmail.com>
|
|
||||||
Ian Lee (@IanLee1521) <IanLee1521@gmail.com>
|
|
||||||
Farkhad Khatamov (@hatamov) <comsgn@gmail.com>
|
|
||||||
Kevin Kelley (@kelleyk) <kelleyk@kelleyk.net>
|
|
||||||
Sid Shanker (@squidarth) <sid.p.shanker@gmail.com>
|
|
||||||
Reinoud Elhorst (@reinhrst)
|
|
||||||
Guido van Rossum (@gvanrossum) <guido@python.org>
|
|
||||||
Dmytro Sadovnychyi (@sadovnychyi) <jedi@dmit.ro>
|
|
||||||
Cristi Burcă (@scribu)
|
|
||||||
bstaint (@bstaint)
|
|
||||||
Mathias Rav (@Mortal) <rav@cs.au.dk>
|
|
||||||
Daniel Fiterman (@dfit99) <fitermandaniel2@gmail.com>
|
|
||||||
Simon Ruggier (@sruggier)
|
|
||||||
Élie Gouzien (@ElieGouzien)
|
|
||||||
|
|
||||||
|
|
||||||
Note: (@user) means a github user name.
|
|
@ -1,87 +0,0 @@
|
|||||||
.. :changelog:
|
|
||||||
|
|
||||||
Changelog
|
|
||||||
---------
|
|
||||||
|
|
||||||
0.11.0 (2017-09-20)
|
|
||||||
+++++++++++++++++++
|
|
||||||
|
|
||||||
- Split Jedi's parser into a separate project called ``parso``.
|
|
||||||
- Avoiding side effects in REPL completion.
|
|
||||||
- Numpy docstring support should be much better.
|
|
||||||
- Moved the `settings.*recursion*` away, they are no longer usable.
|
|
||||||
|
|
||||||
0.10.2 (2017-04-05)
|
|
||||||
+++++++++++++++++++
|
|
||||||
|
|
||||||
- Python Packaging sucks. Some files were not included in 0.10.1.
|
|
||||||
|
|
||||||
0.10.1 (2017-04-05)
|
|
||||||
+++++++++++++++++++
|
|
||||||
|
|
||||||
- Fixed a few very annoying bugs.
|
|
||||||
- Prepared the parser to be factored out of Jedi.
|
|
||||||
|
|
||||||
0.10.0 (2017-02-03)
|
|
||||||
+++++++++++++++++++
|
|
||||||
|
|
||||||
- Actual semantic completions for the complete Python syntax.
|
|
||||||
- Basic type inference for ``yield from`` PEP 380.
|
|
||||||
- PEP 484 support (most of the important features of it). Thanks Claude! (@reinhrst)
|
|
||||||
- Added ``get_line_code`` to ``Definition`` and ``Completion`` objects.
|
|
||||||
- Completely rewritten the type inference engine.
|
|
||||||
- A new and better parser for (fast) parsing diffs of Python code.
|
|
||||||
|
|
||||||
0.9.0 (2015-04-10)
|
|
||||||
++++++++++++++++++
|
|
||||||
|
|
||||||
- The import logic has been rewritten to look more like Python's. There is now
|
|
||||||
an ``Evaluator.modules`` import cache, which resembles ``sys.modules``.
|
|
||||||
- Integrated the parser of 2to3. This will make refactoring possible. It will
|
|
||||||
also be possible to check for error messages (like compiling an AST would give)
|
|
||||||
in the future.
|
|
||||||
- With the new parser, the evaluation also completely changed. It's now simpler
|
|
||||||
and more readable.
|
|
||||||
- Completely rewritten REPL completion.
|
|
||||||
- Added ``jedi.names``, a command to do static analysis. Thanks to that
|
|
||||||
sourcegraph guys for sponsoring this!
|
|
||||||
- Alpha version of the linter.
|
|
||||||
|
|
||||||
|
|
||||||
0.8.1 (2014-07-23)
|
|
||||||
+++++++++++++++++++
|
|
||||||
|
|
||||||
- Bugfix release, the last release forgot to include files that improve
|
|
||||||
autocompletion for builtin libraries. Fixed.
|
|
||||||
|
|
||||||
0.8.0 (2014-05-05)
|
|
||||||
+++++++++++++++++++
|
|
||||||
|
|
||||||
- Memory Consumption for compiled modules (e.g. builtins, sys) has been reduced
|
|
||||||
drastically. Loading times are down as well (it takes basically as long as an
|
|
||||||
import).
|
|
||||||
- REPL completion is starting to become usable.
|
|
||||||
- Various small API changes. Generally this release focuses on stability and
|
|
||||||
refactoring of internal APIs.
|
|
||||||
- Introducing operator precedence, which makes calculating correct Array
|
|
||||||
indices and ``__getattr__`` strings possible.
|
|
||||||
|
|
||||||
0.7.0 (2013-08-09)
|
|
||||||
++++++++++++++++++
|
|
||||||
|
|
||||||
- Switched from LGPL to MIT license.
|
|
||||||
- Added an Interpreter class to the API to make autocompletion in REPL
|
|
||||||
possible.
|
|
||||||
- Added autocompletion support for namespace packages.
|
|
||||||
- Add sith.py, a new random testing method.
|
|
||||||
|
|
||||||
0.6.0 (2013-05-14)
|
|
||||||
++++++++++++++++++
|
|
||||||
|
|
||||||
- Much faster parser with builtin part caching.
|
|
||||||
- A test suite, thanks @tkf.
|
|
||||||
|
|
||||||
0.5 versions (2012)
|
|
||||||
+++++++++++++++++++
|
|
||||||
|
|
||||||
- Initial development.
|
|
@ -1,8 +0,0 @@
|
|||||||
Pull Requests are great.
|
|
||||||
|
|
||||||
1. Fork the Repo on github.
|
|
||||||
2. If you are adding functionality or fixing a bug, please add a test!
|
|
||||||
3. Add your name to AUTHORS.txt
|
|
||||||
4. Push to your fork and submit a pull request.
|
|
||||||
|
|
||||||
**Try to use the PEP8 style guide.**
|
|
@ -1,24 +0,0 @@
|
|||||||
All contributions towards Jedi are MIT licensed.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) <2013> <David Halter and others, see AUTHORS.txt>
|
|
||||||
|
|
||||||
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.
|
|
@ -1,15 +0,0 @@
|
|||||||
include README.rst
|
|
||||||
include CHANGELOG.rst
|
|
||||||
include LICENSE.txt
|
|
||||||
include AUTHORS.txt
|
|
||||||
include .coveragerc
|
|
||||||
include sith.py
|
|
||||||
include conftest.py
|
|
||||||
include pytest.ini
|
|
||||||
include tox.ini
|
|
||||||
include requirements.txt
|
|
||||||
include jedi/evaluate/compiled/fake/*.pym
|
|
||||||
include jedi/parser/python/grammar*.txt
|
|
||||||
recursive-include test *
|
|
||||||
recursive-include docs *
|
|
||||||
recursive-exclude * *.pyc
|
|
@ -1,215 +0,0 @@
|
|||||||
###################################################################
|
|
||||||
Jedi - an awesome autocompletion/static analysis library for Python
|
|
||||||
###################################################################
|
|
||||||
|
|
||||||
.. image:: https://secure.travis-ci.org/davidhalter/jedi.png?branch=master
|
|
||||||
:target: http://travis-ci.org/davidhalter/jedi
|
|
||||||
:alt: Travis-CI build status
|
|
||||||
|
|
||||||
.. image:: https://coveralls.io/repos/davidhalter/jedi/badge.png?branch=master
|
|
||||||
:target: https://coveralls.io/r/davidhalter/jedi
|
|
||||||
:alt: Coverage Status
|
|
||||||
|
|
||||||
|
|
||||||
*If you have specific questions, please add an issue or ask on* `stackoverflow
|
|
||||||
<https://stackoverflow.com/questions/tagged/python-jedi>`_ *with the label* ``python-jedi``.
|
|
||||||
|
|
||||||
|
|
||||||
Jedi is a static analysis tool for Python that can be used in IDEs/editors. Its
|
|
||||||
historic focus is autocompletion, but does static analysis for now as well.
|
|
||||||
Jedi is fast and is very well tested. It understands Python on a deeper level
|
|
||||||
than all other static analysis frameworks for Python.
|
|
||||||
|
|
||||||
Jedi has support for two different goto functions. It's possible to search for
|
|
||||||
related names and to list all names in a Python file and infer them. Jedi
|
|
||||||
understands docstrings and you can use Jedi autocompletion in your REPL as
|
|
||||||
well.
|
|
||||||
|
|
||||||
Jedi uses a very simple API to connect with IDE's. There's a reference
|
|
||||||
implementation as a `VIM-Plugin <https://github.com/davidhalter/jedi-vim>`_,
|
|
||||||
which uses Jedi's autocompletion. We encourage you to use Jedi in your IDEs.
|
|
||||||
It's really easy.
|
|
||||||
|
|
||||||
Jedi can currently be used with the following editors/projects:
|
|
||||||
|
|
||||||
- Vim (jedi-vim_, YouCompleteMe_, deoplete-jedi_, completor.vim_)
|
|
||||||
- Emacs (Jedi.el_, company-mode_, elpy_, anaconda-mode_, ycmd_)
|
|
||||||
- Sublime Text (SublimeJEDI_ [ST2 + ST3], anaconda_ [only ST3])
|
|
||||||
- TextMate_ (Not sure if it's actually working)
|
|
||||||
- Kate_ version 4.13+ supports it natively, you have to enable it, though. [`proof
|
|
||||||
<https://projects.kde.org/projects/kde/applications/kate/repository/show?rev=KDE%2F4.13>`_]
|
|
||||||
- Atom_ (autocomplete-python-jedi_)
|
|
||||||
- SourceLair_
|
|
||||||
- `GNOME Builder`_ (with support for GObject Introspection)
|
|
||||||
- `Visual Studio Code`_ (via `Python Extension <https://marketplace.visualstudio.com/items?itemName=donjayamanne.python>`_)
|
|
||||||
- Gedit (gedi_)
|
|
||||||
- wdb_ - Web Debugger
|
|
||||||
- `Eric IDE`_ (Available as a plugin)
|
|
||||||
- `Ipython 6.0.0+ <http://ipython.readthedocs.io/en/stable/whatsnew/version6.html>`_
|
|
||||||
|
|
||||||
and many more!
|
|
||||||
|
|
||||||
|
|
||||||
Here are some pictures taken from jedi-vim_:
|
|
||||||
|
|
||||||
.. image:: https://github.com/davidhalter/jedi/raw/master/docs/_screenshots/screenshot_complete.png
|
|
||||||
|
|
||||||
Completion for almost anything (Ctrl+Space).
|
|
||||||
|
|
||||||
.. image:: https://github.com/davidhalter/jedi/raw/master/docs/_screenshots/screenshot_function.png
|
|
||||||
|
|
||||||
Display of function/class bodies, docstrings.
|
|
||||||
|
|
||||||
.. image:: https://github.com/davidhalter/jedi/raw/master/docs/_screenshots/screenshot_pydoc.png
|
|
||||||
|
|
||||||
Pydoc support (Shift+k).
|
|
||||||
|
|
||||||
There is also support for goto and renaming.
|
|
||||||
|
|
||||||
Get the latest version from `github <https://github.com/davidhalter/jedi>`_
|
|
||||||
(master branch should always be kind of stable/working).
|
|
||||||
|
|
||||||
Docs are available at `https://jedi.readthedocs.org/en/latest/
|
|
||||||
<https://jedi.readthedocs.org/en/latest/>`_. Pull requests with documentation
|
|
||||||
enhancements and/or fixes are awesome and most welcome. Jedi uses `semantic
|
|
||||||
versioning <http://semver.org/>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
pip install jedi
|
|
||||||
|
|
||||||
Note: This just installs the Jedi library, not the editor plugins. For
|
|
||||||
information about how to make it work with your editor, refer to the
|
|
||||||
corresponding documentation.
|
|
||||||
|
|
||||||
You don't want to use ``pip``? Please refer to the `manual
|
|
||||||
<https://jedi.readthedocs.org/en/latest/docs/installation.html>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Feature Support and Caveats
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Jedi really understands your Python code. For a comprehensive list what Jedi
|
|
||||||
understands, see: `Features
|
|
||||||
<https://jedi.readthedocs.org/en/latest/docs/features.html>`_. A list of
|
|
||||||
caveats can be found on the same page.
|
|
||||||
|
|
||||||
You can run Jedi on cPython 2.6, 2.7, 3.3, 3.4 or 3.5 but it should also
|
|
||||||
understand/parse code older than those versions.
|
|
||||||
|
|
||||||
Tips on how to use Jedi efficiently can be found `here
|
|
||||||
<https://jedi.readthedocs.org/en/latest/docs/features.html#recipes>`_.
|
|
||||||
|
|
||||||
API
|
|
||||||
---
|
|
||||||
|
|
||||||
You can find the documentation for the `API here <https://jedi.readthedocs.org/en/latest/docs/plugin-api.html>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Autocompletion / Goto / Pydoc
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
Please check the API for a good explanation. There are the following commands:
|
|
||||||
|
|
||||||
- ``jedi.Script.goto_assignments``
|
|
||||||
- ``jedi.Script.completions``
|
|
||||||
- ``jedi.Script.usages``
|
|
||||||
|
|
||||||
The returned objects are very powerful and really all you might need.
|
|
||||||
|
|
||||||
|
|
||||||
Autocompletion in your REPL (IPython, etc.)
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
Starting with Ipython `6.0.0` Jedi is a dependency of IPython. Autocompletion
|
|
||||||
in IPython is therefore possible without additional configuration.
|
|
||||||
|
|
||||||
It's possible to have Jedi autocompletion in REPL modes - `example video <https://vimeo.com/122332037>`_.
|
|
||||||
This means that in Python you can enable tab completion in a `REPL
|
|
||||||
<https://jedi.readthedocs.org/en/latest/docs/usage.html#tab-completion-in-the-python-shell>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Static Analysis / Linter
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
To do all forms of static analysis, please try to use ``jedi.names``. It will
|
|
||||||
return a list of names that you can use to infer types and so on.
|
|
||||||
|
|
||||||
Linting is another thing that is going to be part of Jedi. For now you can try
|
|
||||||
an alpha version ``python -m jedi linter``. The API might change though and
|
|
||||||
it's still buggy. It's Jedi's goal to be smarter than classic linter and
|
|
||||||
understand ``AttributeError`` and other code issues.
|
|
||||||
|
|
||||||
|
|
||||||
Refactoring
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Jedi's parser would support refactoring, but there's no API to use it right
|
|
||||||
now. If you're interested in helping out here, let me know. With the latest
|
|
||||||
parser changes, it should be very easy to actually make it work.
|
|
||||||
|
|
||||||
|
|
||||||
Development
|
|
||||||
===========
|
|
||||||
|
|
||||||
There's a pretty good and extensive `development documentation
|
|
||||||
<https://jedi.readthedocs.org/en/latest/docs/development.html>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Testing
|
|
||||||
=======
|
|
||||||
|
|
||||||
The test suite depends on ``tox`` and ``pytest``::
|
|
||||||
|
|
||||||
pip install tox pytest
|
|
||||||
|
|
||||||
To run the tests for all supported Python versions::
|
|
||||||
|
|
||||||
tox
|
|
||||||
|
|
||||||
If you want to test only a specific Python version (e.g. Python 2.7), it's as
|
|
||||||
easy as ::
|
|
||||||
|
|
||||||
tox -e py27
|
|
||||||
|
|
||||||
Tests are also run automatically on `Travis CI
|
|
||||||
<https://travis-ci.org/davidhalter/jedi/>`_.
|
|
||||||
|
|
||||||
For more detailed information visit the `testing documentation
|
|
||||||
<https://jedi.readthedocs.org/en/latest/docs/testing.html>`_
|
|
||||||
|
|
||||||
|
|
||||||
Acknowledgements
|
|
||||||
================
|
|
||||||
|
|
||||||
- Takafumi Arakaki (@tkf) for creating a solid test environment and a lot of
|
|
||||||
other things.
|
|
||||||
- Danilo Bargen (@dbrgn) for general housekeeping and being a good friend :).
|
|
||||||
- Guido van Rossum (@gvanrossum) for creating the parser generator pgen2
|
|
||||||
(originally used in lib2to3).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _jedi-vim: https://github.com/davidhalter/jedi-vim
|
|
||||||
.. _youcompleteme: http://valloric.github.io/YouCompleteMe/
|
|
||||||
.. _deoplete-jedi: https://github.com/zchee/deoplete-jedi
|
|
||||||
.. _completor.vim: https://github.com/maralla/completor.vim
|
|
||||||
.. _Jedi.el: https://github.com/tkf/emacs-jedi
|
|
||||||
.. _company-mode: https://github.com/syohex/emacs-company-jedi
|
|
||||||
.. _elpy: https://github.com/jorgenschaefer/elpy
|
|
||||||
.. _anaconda-mode: https://github.com/proofit404/anaconda-mode
|
|
||||||
.. _ycmd: https://github.com/abingham/emacs-ycmd
|
|
||||||
.. _sublimejedi: https://github.com/srusskih/SublimeJEDI
|
|
||||||
.. _anaconda: https://github.com/DamnWidget/anaconda
|
|
||||||
.. _wdb: https://github.com/Kozea/wdb
|
|
||||||
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
|
|
||||||
.. _Kate: http://kate-editor.org
|
|
||||||
.. _Atom: https://atom.io/
|
|
||||||
.. _autocomplete-python-jedi: https://atom.io/packages/autocomplete-python-jedi
|
|
||||||
.. _SourceLair: https://www.sourcelair.com
|
|
||||||
.. _GNOME Builder: https://wiki.gnome.org/Apps/Builder
|
|
||||||
.. _Visual Studio Code: https://code.visualstudio.com/
|
|
||||||
.. _gedi: https://github.com/isamert/gedi
|
|
||||||
.. _Eric IDE: http://eric-ide.python-projects.org
|
|
@ -1,72 +0,0 @@
|
|||||||
import tempfile
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
import jedi
|
|
||||||
|
|
||||||
collect_ignore = ["setup.py"]
|
|
||||||
|
|
||||||
|
|
||||||
# The following hooks (pytest_configure, pytest_unconfigure) are used
|
|
||||||
# to modify `jedi.settings.cache_directory` because `clean_jedi_cache`
|
|
||||||
# has no effect during doctests. Without these hooks, doctests uses
|
|
||||||
# user's cache (e.g., ~/.cache/jedi/). We should remove this
|
|
||||||
# workaround once the problem is fixed in py.test.
|
|
||||||
#
|
|
||||||
# See:
|
|
||||||
# - https://github.com/davidhalter/jedi/pull/168
|
|
||||||
# - https://bitbucket.org/hpk42/pytest/issue/275/
|
|
||||||
|
|
||||||
jedi_cache_directory_orig = None
|
|
||||||
jedi_cache_directory_temp = None
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
|
||||||
parser.addoption("--jedi-debug", "-D", action='store_true',
|
|
||||||
help="Enables Jedi's debug output.")
|
|
||||||
|
|
||||||
parser.addoption("--warning-is-error", action='store_true',
|
|
||||||
help="Warnings are treated as errors.")
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config):
|
|
||||||
global jedi_cache_directory_orig, jedi_cache_directory_temp
|
|
||||||
jedi_cache_directory_orig = jedi.settings.cache_directory
|
|
||||||
jedi_cache_directory_temp = tempfile.mkdtemp(prefix='jedi-test-')
|
|
||||||
jedi.settings.cache_directory = jedi_cache_directory_temp
|
|
||||||
|
|
||||||
if config.option.jedi_debug:
|
|
||||||
jedi.set_debug_function()
|
|
||||||
|
|
||||||
if config.option.warning_is_error:
|
|
||||||
import warnings
|
|
||||||
warnings.simplefilter("error")
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_unconfigure(config):
|
|
||||||
global jedi_cache_directory_orig, jedi_cache_directory_temp
|
|
||||||
jedi.settings.cache_directory = jedi_cache_directory_orig
|
|
||||||
shutil.rmtree(jedi_cache_directory_temp)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def clean_jedi_cache(request):
|
|
||||||
"""
|
|
||||||
Set `jedi.settings.cache_directory` to a temporary directory during test.
|
|
||||||
|
|
||||||
Note that you can't use built-in `tmpdir` and `monkeypatch`
|
|
||||||
fixture here because their scope is 'function', which is not used
|
|
||||||
in 'session' scope fixture.
|
|
||||||
|
|
||||||
This fixture is activated in ../pytest.ini.
|
|
||||||
"""
|
|
||||||
from jedi import settings
|
|
||||||
old = settings.cache_directory
|
|
||||||
tmp = tempfile.mkdtemp(prefix='jedi-test-')
|
|
||||||
settings.cache_directory = tmp
|
|
||||||
|
|
||||||
@request.addfinalizer
|
|
||||||
def restore():
|
|
||||||
settings.cache_directory = old
|
|
||||||
shutil.rmtree(tmp)
|
|
@ -1,52 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# The script creates a separate folder in build/ and creates tags there, pushes
|
|
||||||
# them and then uploads the package to PyPI.
|
|
||||||
|
|
||||||
set -eu -o pipefail
|
|
||||||
|
|
||||||
BASE_DIR=$(dirname $(readlink -f "$0"))
|
|
||||||
cd $BASE_DIR
|
|
||||||
|
|
||||||
git fetch --tags
|
|
||||||
|
|
||||||
PROJECT_NAME=jedi
|
|
||||||
BRANCH=master
|
|
||||||
BUILD_FOLDER=build
|
|
||||||
|
|
||||||
[ -d $BUILD_FOLDER ] || mkdir $BUILD_FOLDER
|
|
||||||
# Remove the previous deployment first.
|
|
||||||
# Checkout the right branch
|
|
||||||
cd $BUILD_FOLDER
|
|
||||||
rm -rf $PROJECT_NAME
|
|
||||||
git clone .. $PROJECT_NAME
|
|
||||||
cd $PROJECT_NAME
|
|
||||||
git checkout $BRANCH
|
|
||||||
|
|
||||||
# Test first.
|
|
||||||
tox
|
|
||||||
|
|
||||||
# Create tag
|
|
||||||
tag=v$(python -c "import $PROJECT_NAME; print($PROJECT_NAME.__version__)")
|
|
||||||
|
|
||||||
master_ref=$(git show-ref -s heads/$BRANCH)
|
|
||||||
tag_ref=$(git show-ref -s $tag || true)
|
|
||||||
if [[ $tag_ref ]]; then
|
|
||||||
if [[ $tag_ref != $master_ref ]]; then
|
|
||||||
echo 'Cannot tag something that has already been tagged with another commit.'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
git tag $tag
|
|
||||||
git push --tags
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Package and upload to PyPI
|
|
||||||
#rm -rf dist/ - Not needed anymore, because the folder is never reused.
|
|
||||||
echo `pwd`
|
|
||||||
python setup.py sdist bdist_wheel
|
|
||||||
# Maybe do a pip install twine before.
|
|
||||||
twine upload dist/*
|
|
||||||
|
|
||||||
cd $BASE_DIR
|
|
||||||
# The tags have been pushed to this repo. Push the tags to github, now.
|
|
||||||
git push --tags
|
|
@ -1,153 +0,0 @@
|
|||||||
# Makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
SPHINXOPTS =
|
|
||||||
SPHINXBUILD = sphinx-build
|
|
||||||
PAPER =
|
|
||||||
BUILDDIR = _build
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
|
||||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
# the i18n builder cannot share the environment and doctrees with the others
|
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
|
|
||||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
|
||||||
|
|
||||||
help:
|
|
||||||
@echo "Please use \`make <target>' where <target> is one of"
|
|
||||||
@echo " html to make standalone HTML files"
|
|
||||||
@echo " dirhtml to make HTML files named index.html in directories"
|
|
||||||
@echo " singlehtml to make a single large HTML file"
|
|
||||||
@echo " pickle to make pickle files"
|
|
||||||
@echo " json to make JSON files"
|
|
||||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
|
||||||
@echo " qthelp to make HTML files and a qthelp project"
|
|
||||||
@echo " devhelp to make HTML files and a Devhelp project"
|
|
||||||
@echo " epub to make an epub"
|
|
||||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
|
||||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
|
||||||
@echo " text to make text files"
|
|
||||||
@echo " man to make manual pages"
|
|
||||||
@echo " texinfo to make Texinfo files"
|
|
||||||
@echo " info to make Texinfo files and run them through makeinfo"
|
|
||||||
@echo " gettext to make PO message catalogs"
|
|
||||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
|
||||||
@echo " linkcheck to check all external links for integrity"
|
|
||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -rf $(BUILDDIR)/*
|
|
||||||
|
|
||||||
html:
|
|
||||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
|
||||||
|
|
||||||
dirhtml:
|
|
||||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
|
||||||
|
|
||||||
singlehtml:
|
|
||||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
|
||||||
|
|
||||||
pickle:
|
|
||||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the pickle files."
|
|
||||||
|
|
||||||
json:
|
|
||||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the JSON files."
|
|
||||||
|
|
||||||
htmlhelp:
|
|
||||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
|
||||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
|
||||||
|
|
||||||
qthelp:
|
|
||||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
|
||||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
|
||||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Jedi.qhcp"
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Jedi.qhc"
|
|
||||||
|
|
||||||
devhelp:
|
|
||||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished."
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Jedi"
|
|
||||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Jedi"
|
|
||||||
@echo "# devhelp"
|
|
||||||
|
|
||||||
epub:
|
|
||||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
|
||||||
|
|
||||||
latex:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
|
||||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
|
||||||
"(use \`make latexpdf' here to do that automatically)."
|
|
||||||
|
|
||||||
latexpdf:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
text:
|
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
|
||||||
|
|
||||||
man:
|
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
|
||||||
|
|
||||||
texinfo:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
|
||||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
|
||||||
"(use \`make info' here to do that automatically)."
|
|
||||||
|
|
||||||
info:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo "Running Texinfo files through makeinfo..."
|
|
||||||
make -C $(BUILDDIR)/texinfo info
|
|
||||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
|
||||||
|
|
||||||
gettext:
|
|
||||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
|
||||||
|
|
||||||
changes:
|
|
||||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
|
||||||
@echo
|
|
||||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
|
||||||
|
|
||||||
linkcheck:
|
|
||||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
|
||||||
@echo
|
|
||||||
@echo "Link check complete; look for any errors in the above output " \
|
|
||||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
|
||||||
|
|
||||||
doctest:
|
|
||||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
|
||||||
@echo "Testing of doctests in the sources finished, look at the " \
|
|
||||||
"results in $(BUILDDIR)/doctest/output.txt."
|
|
@ -1,14 +0,0 @@
|
|||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
Install the graphviz library::
|
|
||||||
|
|
||||||
sudo apt-get install graphviz
|
|
||||||
|
|
||||||
Install sphinx::
|
|
||||||
|
|
||||||
sudo pip install sphinx
|
|
||||||
|
|
||||||
You might also need to install the Python graphviz interface::
|
|
||||||
|
|
||||||
sudo pip install graphviz
|
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 39 KiB |
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
@ -1,3 +0,0 @@
|
|||||||
The source of the logo is a photoshop file hosted here:
|
|
||||||
|
|
||||||
https://dl.dropboxusercontent.com/u/170011615/Jedi12_Logo.psd.xz
|
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
@ -1,4 +0,0 @@
|
|||||||
<h3>Github</h3>
|
|
||||||
<iframe src="http://ghbtns.com/github-btn.html?user=davidhalter&repo=jedi&type=watch&count=true&size=large"
|
|
||||||
frameborder="0" scrolling="0" width="170" height="30" allowtransparency="true"></iframe>
|
|
||||||
<br><br>
|
|
@ -1,3 +0,0 @@
|
|||||||
<p class="logo"><a href="{{ pathto(master_doc) }}">
|
|
||||||
<img class="logo" src="{{ pathto('_static/logo.png', 1) }}" alt="Logo"/>
|
|
||||||
</a></p>
|
|
@ -1,37 +0,0 @@
|
|||||||
Copyright (c) 2010 by Armin Ronacher.
|
|
||||||
|
|
||||||
Some rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms of the theme, with or
|
|
||||||
without modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials provided
|
|
||||||
with the distribution.
|
|
||||||
|
|
||||||
* The names of the contributors may not be used to endorse or
|
|
||||||
promote products derived from this software without specific
|
|
||||||
prior written permission.
|
|
||||||
|
|
||||||
We kindly ask you to only use these themes in an unmodified manner just
|
|
||||||
for Flask and Flask-related products, not for unrelated projects. If you
|
|
||||||
like the visual style and want to use it for your own projects, please
|
|
||||||
consider making some larger changes to the themes (such as changing
|
|
||||||
font faces, sizes, colors or margins).
|
|
||||||
|
|
||||||
THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,28 +0,0 @@
|
|||||||
{%- extends "basic/layout.html" %}
|
|
||||||
{%- block extrahead %}
|
|
||||||
{{ super() }}
|
|
||||||
{% if theme_touch_icon %}
|
|
||||||
<link rel="apple-touch-icon" href="{{ pathto('_static/' ~ theme_touch_icon, 1) }}" />
|
|
||||||
{% endif %}
|
|
||||||
<link media="only screen and (max-device-width: 480px)" href="{{
|
|
||||||
pathto('_static/small_flask.css', 1) }}" type= "text/css" rel="stylesheet" />
|
|
||||||
<a href="https://github.com/davidhalter/jedi">
|
|
||||||
<img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub">
|
|
||||||
</a>
|
|
||||||
{% endblock %}
|
|
||||||
{%- block relbar2 %}{% endblock %}
|
|
||||||
{% block header %}
|
|
||||||
{{ super() }}
|
|
||||||
{% if pagename == 'index' %}
|
|
||||||
<div class=indexwrapper>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
{%- block footer %}
|
|
||||||
<div class="footer">
|
|
||||||
© Copyright {{ copyright }}.
|
|
||||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
|
|
||||||
</div>
|
|
||||||
{% if pagename == 'index' %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{%- endblock %}
|
|
@ -1,19 +0,0 @@
|
|||||||
<h3>Related Topics</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="{{ pathto(master_doc) }}">Documentation overview</a><ul>
|
|
||||||
{%- for parent in parents %}
|
|
||||||
<li><a href="{{ parent.link|e }}">{{ parent.title }}</a><ul>
|
|
||||||
{%- endfor %}
|
|
||||||
{%- if prev %}
|
|
||||||
<li>Previous: <a href="{{ prev.link|e }}" title="{{ _('previous chapter')
|
|
||||||
}}">{{ prev.title }}</a></li>
|
|
||||||
{%- endif %}
|
|
||||||
{%- if next %}
|
|
||||||
<li>Next: <a href="{{ next.link|e }}" title="{{ _('next chapter')
|
|
||||||
}}">{{ next.title }}</a></li>
|
|
||||||
{%- endif %}
|
|
||||||
{%- for parent in parents %}
|
|
||||||
</ul></li>
|
|
||||||
{%- endfor %}
|
|
||||||
</ul></li>
|
|
||||||
</ul>
|
|
@ -1,394 +0,0 @@
|
|||||||
/*
|
|
||||||
* flasky.css_t
|
|
||||||
* ~~~~~~~~~~~~
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2010 by Armin Ronacher.
|
|
||||||
* :license: Flask Design License, see LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
{% set page_width = '940px' %}
|
|
||||||
{% set sidebar_width = '220px' %}
|
|
||||||
|
|
||||||
@import url("basic.css");
|
|
||||||
|
|
||||||
/* -- page layout ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Georgia', serif;
|
|
||||||
font-size: 17px;
|
|
||||||
background-color: white;
|
|
||||||
color: #000;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.document {
|
|
||||||
width: {{ page_width }};
|
|
||||||
margin: 30px auto 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.documentwrapper {
|
|
||||||
float: left;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bodywrapper {
|
|
||||||
margin: 0 0 0 {{ sidebar_width }};
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar {
|
|
||||||
width: {{ sidebar_width }};
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
border: 1px solid #B1B4B6;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body {
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #3E4349;
|
|
||||||
padding: 0 30px 0 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.floatingflask {
|
|
||||||
padding: 0 0 10px 10px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer {
|
|
||||||
width: {{ page_width }};
|
|
||||||
margin: 20px auto 30px auto;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #888;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer a {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar a {
|
|
||||||
color: #444;
|
|
||||||
text-decoration: none;
|
|
||||||
border-bottom: 1px dotted #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar a:hover {
|
|
||||||
border-bottom: 1px solid #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebarwrapper {
|
|
||||||
padding: 18px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebarwrapper p.logo {
|
|
||||||
padding: 0 0 20px 0;
|
|
||||||
margin: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar h3,
|
|
||||||
div.sphinxsidebar h4 {
|
|
||||||
font-family: 'Garamond', 'Georgia', serif;
|
|
||||||
color: #444;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: normal;
|
|
||||||
margin: 0 0 5px 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar h4 {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar h3 a {
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar p.logo a,
|
|
||||||
div.sphinxsidebar h3 a,
|
|
||||||
div.sphinxsidebar p.logo a:hover,
|
|
||||||
div.sphinxsidebar h3 a:hover {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar p {
|
|
||||||
color: #555;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar ul {
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 0;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar input {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
font-family: 'Georgia', serif;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- body styles ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #004B6B;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: #6D4100;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body h1,
|
|
||||||
div.body h2,
|
|
||||||
div.body h3,
|
|
||||||
div.body h4,
|
|
||||||
div.body h5,
|
|
||||||
div.body h6 {
|
|
||||||
font-family: 'Garamond', 'Georgia', serif;
|
|
||||||
font-weight: normal;
|
|
||||||
margin: 30px 0px 10px 0px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
{% if theme_index_logo %}
|
|
||||||
div.indexwrapper h1 {
|
|
||||||
text-indent: -999999px;
|
|
||||||
background: url({{ theme_index_logo }}) no-repeat center center;
|
|
||||||
height: {{ theme_index_logo_height }};
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
|
|
||||||
div.body h2 { font-size: 180%; }
|
|
||||||
div.body h3 { font-size: 150%; }
|
|
||||||
div.body h4 { font-size: 130%; }
|
|
||||||
div.body h5 { font-size: 100%; }
|
|
||||||
div.body h6 { font-size: 100%; }
|
|
||||||
|
|
||||||
a.headerlink {
|
|
||||||
color: #ddd;
|
|
||||||
padding: 0 4px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.headerlink:hover {
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body p, div.body dd, div.body li {
|
|
||||||
line-height: 1.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition {
|
|
||||||
background: #fafafa;
|
|
||||||
margin: 20px -30px;
|
|
||||||
padding: 10px 30px;
|
|
||||||
border-top: 1px solid #ccc;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition tt.xref, div.admonition a tt {
|
|
||||||
border-bottom: 1px solid #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd div.admonition {
|
|
||||||
margin-left: -60px;
|
|
||||||
padding-left: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition p.admonition-title {
|
|
||||||
font-family: 'Garamond', 'Georgia', serif;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 24px;
|
|
||||||
margin: 0 0 10px 0;
|
|
||||||
padding: 0;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition p.last {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.highlight {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt:target, .highlight {
|
|
||||||
background: #FAF3E8;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note {
|
|
||||||
background-color: #eee;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.seealso {
|
|
||||||
background-color: #ffc;
|
|
||||||
border: 1px solid #ff6;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.topic {
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.admonition-title {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.admonition-title:after {
|
|
||||||
content: ":";
|
|
||||||
}
|
|
||||||
|
|
||||||
pre, tt {
|
|
||||||
font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.screenshot {
|
|
||||||
}
|
|
||||||
|
|
||||||
tt.descname, tt.descclassname {
|
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
|
||||||
|
|
||||||
tt.descname {
|
|
||||||
padding-right: 0.08em;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.screenshot {
|
|
||||||
-moz-box-shadow: 2px 2px 4px #eee;
|
|
||||||
-webkit-box-shadow: 2px 2px 4px #eee;
|
|
||||||
box-shadow: 2px 2px 4px #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.docutils {
|
|
||||||
border: 1px solid #888;
|
|
||||||
-moz-box-shadow: 2px 2px 4px #eee;
|
|
||||||
-webkit-box-shadow: 2px 2px 4px #eee;
|
|
||||||
box-shadow: 2px 2px 4px #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.docutils td, table.docutils th {
|
|
||||||
border: 1px solid #888;
|
|
||||||
padding: 0.25em 0.7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.field-list, table.footnote {
|
|
||||||
border: none;
|
|
||||||
-moz-box-shadow: none;
|
|
||||||
-webkit-box-shadow: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.footnote {
|
|
||||||
margin: 15px 0;
|
|
||||||
width: 100%;
|
|
||||||
border: 1px solid #eee;
|
|
||||||
background: #fdfdfd;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.footnote + table.footnote {
|
|
||||||
margin-top: -15px;
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.field-list th {
|
|
||||||
padding: 0 0.8em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.field-list td {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.footnote td.label {
|
|
||||||
width: 0px;
|
|
||||||
padding: 0.3em 0 0.3em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.footnote td {
|
|
||||||
padding: 0.3em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl dd {
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
margin: 0 0 0 30px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul, ol {
|
|
||||||
margin: 10px 0 10px 30px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
background: #eee;
|
|
||||||
padding: 7px 30px;
|
|
||||||
margin: 15px -30px;
|
|
||||||
line-height: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl pre, blockquote pre, li pre {
|
|
||||||
margin-left: -60px;
|
|
||||||
padding-left: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl dl pre {
|
|
||||||
margin-left: -90px;
|
|
||||||
padding-left: 90px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tt {
|
|
||||||
background-color: #ecf0f3;
|
|
||||||
color: #222;
|
|
||||||
/* padding: 1px 2px; */
|
|
||||||
}
|
|
||||||
|
|
||||||
tt.xref, a tt {
|
|
||||||
background-color: #FBFBFB;
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.reference {
|
|
||||||
text-decoration: none;
|
|
||||||
border-bottom: 1px dotted #004B6B;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.reference:hover {
|
|
||||||
border-bottom: 1px solid #6D4100;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.footnote-reference {
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 0.7em;
|
|
||||||
vertical-align: top;
|
|
||||||
border-bottom: 1px dotted #004B6B;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.footnote-reference:hover {
|
|
||||||
border-bottom: 1px solid #6D4100;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover tt {
|
|
||||||
background: #EEE;
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* small_flask.css_t
|
|
||||||
* ~~~~~~~~~~~~~~~~~
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2010 by Armin Ronacher.
|
|
||||||
* :license: Flask Design License, see LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 20px 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.documentwrapper {
|
|
||||||
float: none;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar {
|
|
||||||
display: block;
|
|
||||||
float: none;
|
|
||||||
width: 102.5%;
|
|
||||||
margin: 50px -30px -20px -30px;
|
|
||||||
padding: 10px 20px;
|
|
||||||
background: #333;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
|
|
||||||
div.sphinxsidebar h3 a {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar a {
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar p.logo {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.document {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related {
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
padding: 10px 0 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related ul,
|
|
||||||
div.related ul li {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bodywrapper {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body {
|
|
||||||
min-height: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
[theme]
|
|
||||||
inherit = basic
|
|
||||||
stylesheet = flasky.css
|
|
||||||
pygments_style = flask_theme_support.FlaskyStyle
|
|
||||||
|
|
||||||
[options]
|
|
||||||
index_logo =
|
|
||||||
index_logo_height = 120px
|
|
||||||
touch_icon =
|
|
@ -1,125 +0,0 @@
|
|||||||
"""
|
|
||||||
Copyright (c) 2010 by Armin Ronacher.
|
|
||||||
|
|
||||||
Some rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms of the theme, with or
|
|
||||||
without modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials provided
|
|
||||||
with the distribution.
|
|
||||||
|
|
||||||
* The names of the contributors may not be used to endorse or
|
|
||||||
promote products derived from this software without specific
|
|
||||||
prior written permission.
|
|
||||||
|
|
||||||
We kindly ask you to only use these themes in an unmodified manner just
|
|
||||||
for Flask and Flask-related products, not for unrelated projects. If you
|
|
||||||
like the visual style and want to use it for your own projects, please
|
|
||||||
consider making some larger changes to the themes (such as changing
|
|
||||||
font faces, sizes, colors or margins).
|
|
||||||
|
|
||||||
THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
"""
|
|
||||||
# flasky extensions. flasky pygments style based on tango style
|
|
||||||
from pygments.style import Style
|
|
||||||
from pygments.token import Keyword, Name, Comment, String, Error, \
|
|
||||||
Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
|
|
||||||
|
|
||||||
|
|
||||||
class FlaskyStyle(Style):
|
|
||||||
background_color = "#f8f8f8"
|
|
||||||
default_style = ""
|
|
||||||
|
|
||||||
styles = {
|
|
||||||
# No corresponding class for the following:
|
|
||||||
#Text: "", # class: ''
|
|
||||||
Whitespace: "underline #f8f8f8", # class: 'w'
|
|
||||||
Error: "#a40000 border:#ef2929", # class: 'err'
|
|
||||||
Other: "#000000", # class 'x'
|
|
||||||
|
|
||||||
Comment: "italic #8f5902", # class: 'c'
|
|
||||||
Comment.Preproc: "noitalic", # class: 'cp'
|
|
||||||
|
|
||||||
Keyword: "bold #004461", # class: 'k'
|
|
||||||
Keyword.Constant: "bold #004461", # class: 'kc'
|
|
||||||
Keyword.Declaration: "bold #004461", # class: 'kd'
|
|
||||||
Keyword.Namespace: "bold #004461", # class: 'kn'
|
|
||||||
Keyword.Pseudo: "bold #004461", # class: 'kp'
|
|
||||||
Keyword.Reserved: "bold #004461", # class: 'kr'
|
|
||||||
Keyword.Type: "bold #004461", # class: 'kt'
|
|
||||||
|
|
||||||
Operator: "#582800", # class: 'o'
|
|
||||||
Operator.Word: "bold #004461", # class: 'ow' - like keywords
|
|
||||||
|
|
||||||
Punctuation: "bold #000000", # class: 'p'
|
|
||||||
|
|
||||||
# because special names such as Name.Class, Name.Function, etc.
|
|
||||||
# are not recognized as such later in the parsing, we choose them
|
|
||||||
# to look the same as ordinary variables.
|
|
||||||
Name: "#000000", # class: 'n'
|
|
||||||
Name.Attribute: "#c4a000", # class: 'na' - to be revised
|
|
||||||
Name.Builtin: "#004461", # class: 'nb'
|
|
||||||
Name.Builtin.Pseudo: "#3465a4", # class: 'bp'
|
|
||||||
Name.Class: "#000000", # class: 'nc' - to be revised
|
|
||||||
Name.Constant: "#000000", # class: 'no' - to be revised
|
|
||||||
Name.Decorator: "#888", # class: 'nd' - to be revised
|
|
||||||
Name.Entity: "#ce5c00", # class: 'ni'
|
|
||||||
Name.Exception: "bold #cc0000", # class: 'ne'
|
|
||||||
Name.Function: "#000000", # class: 'nf'
|
|
||||||
Name.Property: "#000000", # class: 'py'
|
|
||||||
Name.Label: "#f57900", # class: 'nl'
|
|
||||||
Name.Namespace: "#000000", # class: 'nn' - to be revised
|
|
||||||
Name.Other: "#000000", # class: 'nx'
|
|
||||||
Name.Tag: "bold #004461", # class: 'nt' - like a keyword
|
|
||||||
Name.Variable: "#000000", # class: 'nv' - to be revised
|
|
||||||
Name.Variable.Class: "#000000", # class: 'vc' - to be revised
|
|
||||||
Name.Variable.Global: "#000000", # class: 'vg' - to be revised
|
|
||||||
Name.Variable.Instance: "#000000", # class: 'vi' - to be revised
|
|
||||||
|
|
||||||
Number: "#990000", # class: 'm'
|
|
||||||
|
|
||||||
Literal: "#000000", # class: 'l'
|
|
||||||
Literal.Date: "#000000", # class: 'ld'
|
|
||||||
|
|
||||||
String: "#4e9a06", # class: 's'
|
|
||||||
String.Backtick: "#4e9a06", # class: 'sb'
|
|
||||||
String.Char: "#4e9a06", # class: 'sc'
|
|
||||||
String.Doc: "italic #8f5902", # class: 'sd' - like a comment
|
|
||||||
String.Double: "#4e9a06", # class: 's2'
|
|
||||||
String.Escape: "#4e9a06", # class: 'se'
|
|
||||||
String.Heredoc: "#4e9a06", # class: 'sh'
|
|
||||||
String.Interpol: "#4e9a06", # class: 'si'
|
|
||||||
String.Other: "#4e9a06", # class: 'sx'
|
|
||||||
String.Regex: "#4e9a06", # class: 'sr'
|
|
||||||
String.Single: "#4e9a06", # class: 's1'
|
|
||||||
String.Symbol: "#4e9a06", # class: 'ss'
|
|
||||||
|
|
||||||
Generic: "#000000", # class: 'g'
|
|
||||||
Generic.Deleted: "#a40000", # class: 'gd'
|
|
||||||
Generic.Emph: "italic #000000", # class: 'ge'
|
|
||||||
Generic.Error: "#ef2929", # class: 'gr'
|
|
||||||
Generic.Heading: "bold #000080", # class: 'gh'
|
|
||||||
Generic.Inserted: "#00A000", # class: 'gi'
|
|
||||||
Generic.Output: "#888", # class: 'go'
|
|
||||||
Generic.Prompt: "#745334", # class: 'gp'
|
|
||||||
Generic.Strong: "bold #000000", # class: 'gs'
|
|
||||||
Generic.Subheading: "bold #800080", # class: 'gu'
|
|
||||||
Generic.Traceback: "bold #a40000", # class: 'gt'
|
|
||||||
}
|
|
@ -1,291 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Jedi documentation build configuration file, created by
|
|
||||||
# sphinx-quickstart on Wed Dec 26 00:11:34 2012.
|
|
||||||
#
|
|
||||||
# This file is execfile()d with the current directory set to its containing dir.
|
|
||||||
#
|
|
||||||
# Note that not all possible configuration values are present in this
|
|
||||||
# autogenerated file.
|
|
||||||
#
|
|
||||||
# All configuration values have a default; values that are commented out
|
|
||||||
# serve to show the default.
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
sys.path.insert(0, os.path.abspath('..'))
|
|
||||||
sys.path.append(os.path.abspath('_themes'))
|
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
|
||||||
#needs_sphinx = '1.0'
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
|
||||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.todo',
|
|
||||||
'sphinx.ext.intersphinx', 'sphinx.ext.inheritance_diagram']
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
|
||||||
|
|
||||||
# The suffix of source filenames.
|
|
||||||
source_suffix = '.rst'
|
|
||||||
|
|
||||||
# The encoding of source files.
|
|
||||||
source_encoding = 'utf-8'
|
|
||||||
|
|
||||||
# The master toctree document.
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
|
||||||
project = u'Jedi'
|
|
||||||
copyright = u'2012 - {today.year}, Jedi contributors'.format(today=datetime.date.today())
|
|
||||||
|
|
||||||
import jedi
|
|
||||||
from jedi.utils import version_info
|
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
|
||||||
# |version| and |release|, also used in various other places throughout the
|
|
||||||
# built documents.
|
|
||||||
#
|
|
||||||
# The short X.Y version.
|
|
||||||
version = '.'.join(str(x) for x in version_info()[:2])
|
|
||||||
# The full version, including alpha/beta/rc tags.
|
|
||||||
release = jedi.__version__
|
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
||||||
# for a list of supported languages.
|
|
||||||
#language = None
|
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some
|
|
||||||
# non-false value, then it is used:
|
|
||||||
#today = ''
|
|
||||||
# Else, today_fmt is used as the format for a strftime call.
|
|
||||||
#today_fmt = '%B %d, %Y'
|
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
exclude_patterns = []
|
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
|
||||||
#default_role = None
|
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
|
||||||
#add_function_parentheses = True
|
|
||||||
|
|
||||||
# If true, the current module name will be prepended to all description
|
|
||||||
# unit titles (such as .. function::).
|
|
||||||
#add_module_names = True
|
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
|
||||||
# output. They are ignored by default.
|
|
||||||
#show_authors = False
|
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
|
||||||
pygments_style = 'sphinx'
|
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
|
||||||
#modindex_common_prefix = []
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output ---------------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
html_theme = 'flask'
|
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
|
||||||
# further. For a list of options available for each theme, see the
|
|
||||||
# documentation.
|
|
||||||
#html_theme_options = {}
|
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
|
||||||
html_theme_path = ['_themes']
|
|
||||||
|
|
||||||
# The name for this set of Sphinx documents. If None, it defaults to
|
|
||||||
# "<project> v<release> documentation".
|
|
||||||
#html_title = None
|
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
|
||||||
#html_short_title = None
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
|
||||||
# of the sidebar.
|
|
||||||
#html_logo = None
|
|
||||||
|
|
||||||
# The name of an image file (within the static path) to use as favicon of the
|
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
|
||||||
# pixels large.
|
|
||||||
#html_favicon = None
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
|
||||||
# using the given strftime format.
|
|
||||||
#html_last_updated_fmt = '%b %d, %Y'
|
|
||||||
|
|
||||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
|
||||||
# typographically correct entities.
|
|
||||||
#html_use_smartypants = True
|
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
|
||||||
html_sidebars = {
|
|
||||||
'**': [
|
|
||||||
'sidebarlogo.html',
|
|
||||||
'localtoc.html',
|
|
||||||
#'relations.html',
|
|
||||||
'ghbuttons.html',
|
|
||||||
#'sourcelink.html',
|
|
||||||
#'searchbox.html'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to
|
|
||||||
# template names.
|
|
||||||
#html_additional_pages = {}
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#html_domain_indices = True
|
|
||||||
|
|
||||||
# If false, no index is generated.
|
|
||||||
#html_use_index = True
|
|
||||||
|
|
||||||
# If true, the index is split into individual pages for each letter.
|
|
||||||
#html_split_index = False
|
|
||||||
|
|
||||||
# If true, links to the reST sources are added to the pages.
|
|
||||||
#html_show_sourcelink = True
|
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_sphinx = True
|
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_copyright = True
|
|
||||||
|
|
||||||
# If true, an OpenSearch description file will be output, and all pages will
|
|
||||||
# contain a <link> tag referring to it. The value of this option must be the
|
|
||||||
# base URL from which the finished HTML is served.
|
|
||||||
#html_use_opensearch = ''
|
|
||||||
|
|
||||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
|
||||||
#html_file_suffix = None
|
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
|
||||||
htmlhelp_basename = 'Jedidoc'
|
|
||||||
|
|
||||||
#html_style = 'default.css' # Force usage of default template on RTD
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for LaTeX output --------------------------------------------------
|
|
||||||
|
|
||||||
latex_elements = {
|
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
|
||||||
#'papersize': 'letterpaper',
|
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
|
||||||
#'pointsize': '10pt',
|
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
|
||||||
#'preamble': '',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
|
||||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
|
||||||
latex_documents = [
|
|
||||||
('index', 'Jedi.tex', u'Jedi Documentation',
|
|
||||||
u'Jedi contributors', 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
|
||||||
# the title page.
|
|
||||||
#latex_logo = None
|
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
|
||||||
# not chapters.
|
|
||||||
#latex_use_parts = False
|
|
||||||
|
|
||||||
# If true, show page references after internal links.
|
|
||||||
#latex_show_pagerefs = False
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#latex_show_urls = False
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#latex_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#latex_domain_indices = True
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output --------------------------------------------
|
|
||||||
|
|
||||||
# One entry per manual page. List of tuples
|
|
||||||
# (source start file, name, description, authors, manual section).
|
|
||||||
man_pages = [
|
|
||||||
('index', 'jedi', u'Jedi Documentation',
|
|
||||||
[u'Jedi contributors'], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#man_show_urls = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Texinfo output ------------------------------------------------
|
|
||||||
|
|
||||||
# Grouping the document tree into Texinfo files. List of tuples
|
|
||||||
# (source start file, target name, title, author,
|
|
||||||
# dir menu entry, description, category)
|
|
||||||
texinfo_documents = [
|
|
||||||
('index', 'Jedi', u'Jedi Documentation',
|
|
||||||
u'Jedi contributors', 'Jedi', 'Awesome Python autocompletion library.',
|
|
||||||
'Miscellaneous'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#texinfo_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#texinfo_domain_indices = True
|
|
||||||
|
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
|
||||||
#texinfo_show_urls = 'footnote'
|
|
||||||
|
|
||||||
# -- Options for todo module ---------------------------------------------------
|
|
||||||
|
|
||||||
todo_include_todos = False
|
|
||||||
|
|
||||||
# -- Options for autodoc module ------------------------------------------------
|
|
||||||
|
|
||||||
autoclass_content = 'both'
|
|
||||||
autodoc_member_order = 'bysource'
|
|
||||||
autodoc_default_flags = []
|
|
||||||
#autodoc_default_flags = ['members', 'undoc-members']
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for intersphinx module --------------------------------------------
|
|
||||||
|
|
||||||
intersphinx_mapping = {
|
|
||||||
'http://docs.python.org/': None,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def skip_deprecated(app, what, name, obj, skip, options):
|
|
||||||
"""
|
|
||||||
All attributes containing a deprecated note shouldn't be documented
|
|
||||||
anymore. This makes it even clearer that they are not supported anymore.
|
|
||||||
"""
|
|
||||||
doc = obj.__doc__
|
|
||||||
return skip or doc and '.. deprecated::' in doc
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
|
||||||
app.connect('autodoc-skip-member', skip_deprecated)
|
|
@ -1,244 +0,0 @@
|
|||||||
.. include:: ../global.rst
|
|
||||||
|
|
||||||
Jedi Development
|
|
||||||
================
|
|
||||||
|
|
||||||
.. currentmodule:: jedi
|
|
||||||
|
|
||||||
.. note:: This documentation is for Jedi developers who want to improve Jedi
|
|
||||||
itself, but have no idea how Jedi works. If you want to use Jedi for
|
|
||||||
your IDE, look at the `plugin api <plugin-api.html>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
------------
|
|
||||||
|
|
||||||
This page tries to address the fundamental demand for documentation of the
|
|
||||||
|jedi| internals. Understanding a dynamic language is a complex task. Especially
|
|
||||||
because type inference in Python can be a very recursive task. Therefore |jedi|
|
|
||||||
couldn't get rid of complexity. I know that **simple is better than complex**,
|
|
||||||
but unfortunately it sometimes requires complex solutions to understand complex
|
|
||||||
systems.
|
|
||||||
|
|
||||||
Since most of the Jedi internals have been written by me (David Halter), this
|
|
||||||
introduction will be written mostly by me, because no one else understands to
|
|
||||||
the same level how Jedi works. Actually this is also the reason for exactly this
|
|
||||||
part of the documentation. To make multiple people able to edit the Jedi core.
|
|
||||||
|
|
||||||
In five chapters I'm trying to describe the internals of |jedi|:
|
|
||||||
|
|
||||||
- :ref:`The Jedi Core <core>`
|
|
||||||
- :ref:`Core Extensions <core-extensions>`
|
|
||||||
- :ref:`Imports & Modules <imports-modules>`
|
|
||||||
- :ref:`Caching & Recursions <caching-recursions>`
|
|
||||||
- :ref:`Helper modules <dev-helpers>`
|
|
||||||
|
|
||||||
.. note:: Testing is not documented here, you'll find that
|
|
||||||
`right here <testing.html>`_.
|
|
||||||
|
|
||||||
|
|
||||||
.. _core:
|
|
||||||
|
|
||||||
The Jedi Core
|
|
||||||
-------------
|
|
||||||
|
|
||||||
The core of Jedi consists of three parts:
|
|
||||||
|
|
||||||
- :ref:`Parser <parser>`
|
|
||||||
- :ref:`Python code evaluation <evaluate>`
|
|
||||||
- :ref:`API <dev-api>`
|
|
||||||
|
|
||||||
Most people are probably interested in :ref:`code evaluation <evaluate>`,
|
|
||||||
because that's where all the magic happens. I need to introduce the :ref:`parser
|
|
||||||
<parser>` first, because :mod:`jedi.evaluate` uses it extensively.
|
|
||||||
|
|
||||||
.. _parser:
|
|
||||||
|
|
||||||
Parser (parser/__init__.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.parser
|
|
||||||
|
|
||||||
Parser Tree (parser/tree.py)
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
.. automodule:: jedi.parser.tree
|
|
||||||
|
|
||||||
Class inheritance diagram:
|
|
||||||
|
|
||||||
.. inheritance-diagram::
|
|
||||||
Module
|
|
||||||
Class
|
|
||||||
Function
|
|
||||||
Lambda
|
|
||||||
Flow
|
|
||||||
ForStmt
|
|
||||||
Import
|
|
||||||
ExprStmt
|
|
||||||
Param
|
|
||||||
Name
|
|
||||||
CompFor
|
|
||||||
:parts: 1
|
|
||||||
|
|
||||||
.. _evaluate:
|
|
||||||
|
|
||||||
Evaluation of python code (evaluate/__init__.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate
|
|
||||||
|
|
||||||
Evaluation Representation (evaluate/representation.py)
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.representation
|
|
||||||
|
|
||||||
.. inheritance-diagram::
|
|
||||||
jedi.evaluate.instance.TreeInstance
|
|
||||||
jedi.evaluate.representation.ClassContext
|
|
||||||
jedi.evaluate.representation.FunctionContext
|
|
||||||
jedi.evaluate.representation.FunctionExecutionContext
|
|
||||||
:parts: 1
|
|
||||||
|
|
||||||
|
|
||||||
.. _name_resolution:
|
|
||||||
|
|
||||||
Name resolution (evaluate/finder.py)
|
|
||||||
++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.finder
|
|
||||||
|
|
||||||
|
|
||||||
.. _dev-api:
|
|
||||||
|
|
||||||
API (api.py and api_classes.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The API has been designed to be as easy to use as possible. The API
|
|
||||||
documentation can be found `here <plugin-api.html>`_. The API itself contains
|
|
||||||
little code that needs to be mentioned here. Generally I'm trying to be
|
|
||||||
conservative with the API. I'd rather not add new API features if they are not
|
|
||||||
necessary, because it's much harder to deprecate stuff than to add it later.
|
|
||||||
|
|
||||||
|
|
||||||
.. _core-extensions:
|
|
||||||
|
|
||||||
Core Extensions
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Core Extensions is a summary of the following topics:
|
|
||||||
|
|
||||||
- :ref:`Iterables & Dynamic Arrays <iterables>`
|
|
||||||
- :ref:`Dynamic Parameters <dynamic>`
|
|
||||||
- :ref:`Diff Parser <diff-parser>`
|
|
||||||
- :ref:`Docstrings <docstrings>`
|
|
||||||
- :ref:`Refactoring <refactoring>`
|
|
||||||
|
|
||||||
These topics are very important to understand what Jedi additionally does, but
|
|
||||||
they could be removed from Jedi and Jedi would still work. But slower and
|
|
||||||
without some features.
|
|
||||||
|
|
||||||
.. _iterables:
|
|
||||||
|
|
||||||
Iterables & Dynamic Arrays (evaluate/iterable.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
To understand Python on a deeper level, |jedi| needs to understand some of the
|
|
||||||
dynamic features of Python like lists that are filled after creation:
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.iterable
|
|
||||||
|
|
||||||
|
|
||||||
.. _dynamic:
|
|
||||||
|
|
||||||
Parameter completion (evaluate/dynamic.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.dynamic
|
|
||||||
|
|
||||||
|
|
||||||
.. _diff-parser:
|
|
||||||
|
|
||||||
Diff Parser (parser/diff.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.parser.python.diff
|
|
||||||
|
|
||||||
.. _docstrings:
|
|
||||||
|
|
||||||
Docstrings (evaluate/docstrings.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.docstrings
|
|
||||||
|
|
||||||
.. _refactoring:
|
|
||||||
|
|
||||||
Refactoring (evaluate/refactoring.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.refactoring
|
|
||||||
|
|
||||||
|
|
||||||
.. _imports-modules:
|
|
||||||
|
|
||||||
Imports & Modules
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
|
|
||||||
- :ref:`Modules <modules>`
|
|
||||||
- :ref:`Builtin Modules <builtin>`
|
|
||||||
- :ref:`Imports <imports>`
|
|
||||||
|
|
||||||
|
|
||||||
.. _builtin:
|
|
||||||
|
|
||||||
Compiled Modules (evaluate/compiled.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.compiled
|
|
||||||
|
|
||||||
|
|
||||||
.. _imports:
|
|
||||||
|
|
||||||
Imports (evaluate/imports.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.imports
|
|
||||||
|
|
||||||
|
|
||||||
.. _caching-recursions:
|
|
||||||
|
|
||||||
Caching & Recursions
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
|
|
||||||
- :ref:`Caching <cache>`
|
|
||||||
- :ref:`Recursions <recursion>`
|
|
||||||
|
|
||||||
.. _cache:
|
|
||||||
|
|
||||||
Caching (cache.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.cache
|
|
||||||
|
|
||||||
.. _recursion:
|
|
||||||
|
|
||||||
Recursions (recursion.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.evaluate.recursion
|
|
||||||
|
|
||||||
|
|
||||||
.. _dev-helpers:
|
|
||||||
|
|
||||||
Helper Modules
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Most other modules are not really central to how Jedi works. They all contain
|
|
||||||
relevant code, but you if you understand the modules above, you pretty much
|
|
||||||
understand Jedi.
|
|
||||||
|
|
||||||
Python 2/3 compatibility (_compatibility.py)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi._compatibility
|
|
@ -1,263 +0,0 @@
|
|||||||
.. include:: ../global.rst
|
|
||||||
|
|
||||||
Features and Caveats
|
|
||||||
====================
|
|
||||||
|
|
||||||
Jedi obviously supports autocompletion. It's also possible to get it working in
|
|
||||||
(:ref:`your REPL (IPython, etc.) <repl-completion>`).
|
|
||||||
|
|
||||||
Static analysis is also possible by using the command ``jedi.names``.
|
|
||||||
|
|
||||||
The Jedi Linter is currently in an alpha version and can be tested by calling
|
|
||||||
``python -m jedi linter``.
|
|
||||||
|
|
||||||
Jedi would in theory support refactoring, but we have never publicized it,
|
|
||||||
because it's not production ready. If you're interested in helping out here,
|
|
||||||
let me know. With the latest parser changes, it should be very easy to actually
|
|
||||||
make it work.
|
|
||||||
|
|
||||||
|
|
||||||
General Features
|
|
||||||
----------------
|
|
||||||
|
|
||||||
- python 2.6+ and 3.3+ support
|
|
||||||
- ignores syntax errors and wrong indentation
|
|
||||||
- can deal with complex module / function / class structures
|
|
||||||
- virtualenv support
|
|
||||||
- can infer function arguments from sphinx, epydoc and basic numpydoc docstrings,
|
|
||||||
and PEP0484-style type hints (:ref:`type hinting <type-hinting>`)
|
|
||||||
|
|
||||||
|
|
||||||
Supported Python Features
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
|jedi| supports many of the widely used Python features:
|
|
||||||
|
|
||||||
- builtins
|
|
||||||
- returns, yields, yield from
|
|
||||||
- tuple assignments / array indexing / dictionary indexing / star unpacking
|
|
||||||
- with-statement / exception handling
|
|
||||||
- ``*args`` / ``**kwargs``
|
|
||||||
- decorators / lambdas / closures
|
|
||||||
- generators / iterators
|
|
||||||
- some descriptors: property / staticmethod / classmethod
|
|
||||||
- some magic methods: ``__call__``, ``__iter__``, ``__next__``, ``__get__``,
|
|
||||||
``__getitem__``, ``__init__``
|
|
||||||
- ``list.append()``, ``set.add()``, ``list.extend()``, etc.
|
|
||||||
- (nested) list comprehensions / ternary expressions
|
|
||||||
- relative imports
|
|
||||||
- ``getattr()`` / ``__getattr__`` / ``__getattribute__``
|
|
||||||
- function annotations (py3k feature, are ignored right now, but being parsed.
|
|
||||||
I don't know what to do with them.)
|
|
||||||
- class decorators (py3k feature, are being ignored too, until I find a use
|
|
||||||
case, that doesn't work with |jedi|)
|
|
||||||
- simple/usual ``sys.path`` modifications
|
|
||||||
- ``isinstance`` checks for if/while/assert
|
|
||||||
- namespace packages (includes ``pkgutil`` and ``pkg_resources`` namespaces)
|
|
||||||
- Django / Flask / Buildout support
|
|
||||||
|
|
||||||
|
|
||||||
Unsupported Features
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Not yet implemented:
|
|
||||||
|
|
||||||
- manipulations of instances outside the instance variables without using
|
|
||||||
methods
|
|
||||||
- implicit namespace packages (Python 3.3+, `PEP 420 <https://www.python.org/dev/peps/pep-0420/>`_)
|
|
||||||
|
|
||||||
Will probably never be implemented:
|
|
||||||
|
|
||||||
- metaclasses (how could an auto-completion ever support this)
|
|
||||||
- ``setattr()``, ``__import__()``
|
|
||||||
- writing to some dicts: ``globals()``, ``locals()``, ``object.__dict__``
|
|
||||||
- evaluating ``if`` / ``while`` / ``del``
|
|
||||||
|
|
||||||
|
|
||||||
Caveats
|
|
||||||
-------
|
|
||||||
|
|
||||||
**Malformed Syntax**
|
|
||||||
|
|
||||||
Syntax errors and other strange stuff may lead to undefined behaviour of the
|
|
||||||
completion. |jedi| is **NOT** a Python compiler, that tries to correct you. It
|
|
||||||
is a tool that wants to help you. But **YOU** have to know Python, not |jedi|.
|
|
||||||
|
|
||||||
**Legacy Python 2 Features**
|
|
||||||
|
|
||||||
This framework should work for both Python 2/3. However, some things were just
|
|
||||||
not as *pythonic* in Python 2 as things should be. To keep things simple, some
|
|
||||||
older Python 2 features have been left out:
|
|
||||||
|
|
||||||
- Classes: Always Python 3 like, therefore all classes inherit from ``object``.
|
|
||||||
- Generators: No ``next()`` method. The ``__next__()`` method is used instead.
|
|
||||||
|
|
||||||
**Slow Performance**
|
|
||||||
|
|
||||||
Importing ``numpy`` can be quite slow sometimes, as well as loading the
|
|
||||||
builtins the first time. If you want to speed things up, you could write import
|
|
||||||
hooks in |jedi|, which preload stuff. However, once loaded, this is not a
|
|
||||||
problem anymore. The same is true for huge modules like ``PySide``, ``wx``,
|
|
||||||
etc.
|
|
||||||
|
|
||||||
**Security**
|
|
||||||
|
|
||||||
Security is an important issue for |jedi|. Therefore no Python code is
|
|
||||||
executed. As long as you write pure python, everything is evaluated
|
|
||||||
statically. But: If you use builtin modules (``c_builtin``) there is no other
|
|
||||||
option than to execute those modules. However: Execute isn't that critical (as
|
|
||||||
e.g. in pythoncomplete, which used to execute *every* import!), because it
|
|
||||||
means one import and no more. So basically the only dangerous thing is using
|
|
||||||
the import itself. If your ``c_builtin`` uses some strange initializations, it
|
|
||||||
might be dangerous. But if it does you're screwed anyways, because eventually
|
|
||||||
you're going to execute your code, which executes the import.
|
|
||||||
|
|
||||||
|
|
||||||
Recipes
|
|
||||||
-------
|
|
||||||
|
|
||||||
Here are some tips on how to use |jedi| efficiently.
|
|
||||||
|
|
||||||
|
|
||||||
.. _type-hinting:
|
|
||||||
|
|
||||||
Type Hinting
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If |jedi| cannot detect the type of a function argument correctly (due to the
|
|
||||||
dynamic nature of Python), you can help it by hinting the type using
|
|
||||||
one of the following docstring/annotation syntax styles:
|
|
||||||
|
|
||||||
**PEP-0484 style**
|
|
||||||
|
|
||||||
https://www.python.org/dev/peps/pep-0484/
|
|
||||||
|
|
||||||
function annotations (python 3 only; python 2 function annotations with
|
|
||||||
comments in planned but not yet implemented)
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
def myfunction(node: ProgramNode, foo: str) -> None:
|
|
||||||
"""Do something with a ``node``.
|
|
||||||
|
|
||||||
"""
|
|
||||||
node.| # complete here
|
|
||||||
|
|
||||||
|
|
||||||
assignment, for-loop and with-statement type hints (all python versions).
|
|
||||||
Note that the type hints must be on the same line as the statement
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
x = foo() # type: int
|
|
||||||
x, y = 2, 3 # type: typing.Optional[int], typing.Union[int, str] # typing module is mostly supported
|
|
||||||
for key, value in foo.items(): # type: str, Employee # note that Employee must be in scope
|
|
||||||
pass
|
|
||||||
with foo() as f: # type: int
|
|
||||||
print(f + 3)
|
|
||||||
|
|
||||||
Most of the features in PEP-0484 are supported including the typing module
|
|
||||||
(for python < 3.5 you have to do ``pip install typing`` to use these),
|
|
||||||
and forward references.
|
|
||||||
|
|
||||||
Things that are missing (and this is not an exhaustive list; some of these
|
|
||||||
are planned, others might be hard to implement and provide little worth):
|
|
||||||
|
|
||||||
- annotating functions with comments: https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
|
|
||||||
- understanding ``typing.cast()``
|
|
||||||
- stub files: https://www.python.org/dev/peps/pep-0484/#stub-files
|
|
||||||
- ``typing.Callable``
|
|
||||||
- ``typing.TypeVar``
|
|
||||||
- User defined generic types: https://www.python.org/dev/peps/pep-0484/#user-defined-generic-types
|
|
||||||
|
|
||||||
**Sphinx style**
|
|
||||||
|
|
||||||
http://sphinx-doc.org/domains.html#info-field-lists
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
def myfunction(node, foo):
|
|
||||||
"""Do something with a ``node``.
|
|
||||||
|
|
||||||
:type node: ProgramNode
|
|
||||||
:param str foo: foo parameter description
|
|
||||||
|
|
||||||
"""
|
|
||||||
node.| # complete here
|
|
||||||
|
|
||||||
**Epydoc**
|
|
||||||
|
|
||||||
http://epydoc.sourceforge.net/manual-fields.html
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
def myfunction(node):
|
|
||||||
"""Do something with a ``node``.
|
|
||||||
|
|
||||||
@type node: ProgramNode
|
|
||||||
|
|
||||||
"""
|
|
||||||
node.| # complete here
|
|
||||||
|
|
||||||
**Numpydoc**
|
|
||||||
|
|
||||||
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
|
||||||
|
|
||||||
In order to support the numpydoc format, you need to install the `numpydoc
|
|
||||||
<https://pypi.python.org/pypi/numpydoc>`__ package.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
def foo(var1, var2, long_var_name='hi'):
|
|
||||||
r"""A one-line summary that does not use variable names or the
|
|
||||||
function name.
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
var1 : array_like
|
|
||||||
Array_like means all those objects -- lists, nested lists,
|
|
||||||
etc. -- that can be converted to an array. We can also
|
|
||||||
refer to variables like `var1`.
|
|
||||||
var2 : int
|
|
||||||
The type above can either refer to an actual Python type
|
|
||||||
(e.g. ``int``), or describe the type of the variable in more
|
|
||||||
detail, e.g. ``(N,) ndarray`` or ``array_like``.
|
|
||||||
long_variable_name : {'hi', 'ho'}, optional
|
|
||||||
Choices in brackets, default first when optional.
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
"""
|
|
||||||
var2.| # complete here
|
|
||||||
|
|
||||||
A little history
|
|
||||||
----------------
|
|
||||||
|
|
||||||
The Star Wars Jedi are awesome. My Jedi software tries to imitate a little bit
|
|
||||||
of the precognition the Jedi have. There's even an awesome `scene
|
|
||||||
<http://www.youtube.com/watch?v=5BDO3pyavOY>`_ of Monty Python Jedis :-).
|
|
||||||
|
|
||||||
But actually the name hasn't so much to do with Star Wars. It's part of my
|
|
||||||
second name.
|
|
||||||
|
|
||||||
After I explained Guido van Rossum, how some parts of my auto-completion work,
|
|
||||||
he said (we drank a beer or two):
|
|
||||||
|
|
||||||
*"Oh, that worries me..."*
|
|
||||||
|
|
||||||
When it's finished, I hope he'll like it :-)
|
|
||||||
|
|
||||||
I actually started Jedi, because there were no good solutions available for VIM.
|
|
||||||
Most auto-completions just didn't work well. The only good solution was PyCharm.
|
|
||||||
But I like my good old VIM. Rope was never really intended to be an
|
|
||||||
auto-completion (and also I really hate project folders for my Python scripts).
|
|
||||||
It's more of a refactoring suite. So I decided to do my own version of a
|
|
||||||
completion, which would execute non-dangerous code. But I soon realized, that
|
|
||||||
this wouldn't work. So I built an extremely recursive thing which understands
|
|
||||||
many of Python's key features.
|
|
||||||
|
|
||||||
By the way, I really tried to program it as understandable as possible. But I
|
|
||||||
think understanding it might need quite some time, because of its recursive
|
|
||||||
nature.
|
|
@ -1,83 +0,0 @@
|
|||||||
.. include:: ../global.rst
|
|
||||||
|
|
||||||
Installation and Configuration
|
|
||||||
==============================
|
|
||||||
|
|
||||||
You can either include |jedi| as a submodule in your text editor plugin (like
|
|
||||||
jedi-vim_ does by default), or you can install it systemwide.
|
|
||||||
|
|
||||||
.. note:: This just installs the |jedi| library, not the :ref:`editor plugins
|
|
||||||
<editor-plugins>`. For information about how to make it work with your
|
|
||||||
editor, refer to the corresponding documentation.
|
|
||||||
|
|
||||||
|
|
||||||
The preferred way
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
On any system you can install |jedi| directly from the Python package index
|
|
||||||
using pip::
|
|
||||||
|
|
||||||
sudo pip install jedi
|
|
||||||
|
|
||||||
If you want to install the current development version (master branch)::
|
|
||||||
|
|
||||||
sudo pip install -e git://github.com/davidhalter/jedi.git#egg=jedi
|
|
||||||
|
|
||||||
|
|
||||||
System-wide installation via a package manager
|
|
||||||
----------------------------------------------
|
|
||||||
|
|
||||||
Arch Linux
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
You can install |jedi| directly from official Arch Linux packages:
|
|
||||||
|
|
||||||
- `python-jedi <https://www.archlinux.org/packages/community/any/python-jedi/>`__
|
|
||||||
(Python 3)
|
|
||||||
- `python2-jedi <https://www.archlinux.org/packages/community/any/python2-jedi/>`__
|
|
||||||
(Python 2)
|
|
||||||
|
|
||||||
The specified Python version just refers to the *runtime environment* for
|
|
||||||
|jedi|. Use the Python 2 version if you're running vim (or whatever editor you
|
|
||||||
use) under Python 2. Otherwise, use the Python 3 version. But whatever version
|
|
||||||
you choose, both are able to complete both Python 2 and 3 *code*.
|
|
||||||
|
|
||||||
(There is also a packaged version of the vim plugin available:
|
|
||||||
`vim-jedi at Arch Linux <https://www.archlinux.org/packages/community/any/vim-jedi/>`__.)
|
|
||||||
|
|
||||||
Debian
|
|
||||||
~~~~~~
|
|
||||||
|
|
||||||
Debian packages are available in the `unstable repository
|
|
||||||
<http://packages.debian.org/search?keywords=python%20jedi>`__.
|
|
||||||
|
|
||||||
Others
|
|
||||||
~~~~~~
|
|
||||||
|
|
||||||
We are in the discussion of adding |jedi| to the Fedora repositories.
|
|
||||||
|
|
||||||
|
|
||||||
Manual installation from a downloaded package
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
If you prefer not to use an automated package installer, you can `download
|
|
||||||
<https://github.com/davidhalter/jedi/archive/master.zip>`__ a current copy of
|
|
||||||
|jedi| and install it manually.
|
|
||||||
|
|
||||||
To install it, navigate to the directory containing `setup.py` on your console
|
|
||||||
and type::
|
|
||||||
|
|
||||||
sudo python setup.py install
|
|
||||||
|
|
||||||
|
|
||||||
Inclusion as a submodule
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
If you use an editor plugin like jedi-vim_, you can simply include |jedi| as a
|
|
||||||
git submodule of the plugin directory. Vim plugin managers like Vundle_ or
|
|
||||||
Pathogen_ make it very easy to keep submodules up to date.
|
|
||||||
|
|
||||||
|
|
||||||
.. _jedi-vim: https://github.com/davidhalter/jedi-vim
|
|
||||||
.. _vundle: https://github.com/gmarik/vundle
|
|
||||||
.. _pathogen: https://github.com/tpope/vim-pathogen
|
|
@ -1,36 +0,0 @@
|
|||||||
.. _xxx:
|
|
||||||
|
|
||||||
Parser Tree
|
|
||||||
===========
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
.. automodule:: jedi.parser.python
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
|
|
||||||
Parser Tree Base Class
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
All nodes and leaves have these methods/properties:
|
|
||||||
|
|
||||||
.. autoclass:: jedi.parser.tree.NodeOrLeaf
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
|
|
||||||
Python Parser Tree
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. automodule:: jedi.parser.python.tree
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
|
|
||||||
Utility
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. autofunction:: jedi.parser.tree.search_ancestor
|
|
@ -1,10 +0,0 @@
|
|||||||
.. include:: ../global.rst
|
|
||||||
|
|
||||||
.. _plugin-api-classes:
|
|
||||||
|
|
||||||
API Return Classes
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. automodule:: jedi.api.classes
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
@ -1,100 +0,0 @@
|
|||||||
.. include:: ../global.rst
|
|
||||||
|
|
||||||
The Plugin API
|
|
||||||
==============
|
|
||||||
|
|
||||||
.. currentmodule:: jedi
|
|
||||||
|
|
||||||
Note: This documentation is for Plugin developers, who want to improve their
|
|
||||||
editors/IDE autocompletion
|
|
||||||
|
|
||||||
If you want to use |jedi|, you first need to ``import jedi``. You then have
|
|
||||||
direct access to the :class:`.Script`. You can then call the functions
|
|
||||||
documented here. These functions return :ref:`API classes
|
|
||||||
<plugin-api-classes>`.
|
|
||||||
|
|
||||||
|
|
||||||
Deprecations
|
|
||||||
------------
|
|
||||||
|
|
||||||
The deprecation process is as follows:
|
|
||||||
|
|
||||||
1. A deprecation is announced in the next major/minor release.
|
|
||||||
2. We wait either at least a year & at least two minor releases until we remove
|
|
||||||
the deprecated functionality.
|
|
||||||
|
|
||||||
|
|
||||||
API documentation
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
API Interface
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. automodule:: jedi.api
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
|
|
||||||
|
|
||||||
Examples
|
|
||||||
--------
|
|
||||||
|
|
||||||
Completions:
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
>>> import jedi
|
|
||||||
>>> source = '''import json; json.l'''
|
|
||||||
>>> script = jedi.Script(source, 1, 19, '')
|
|
||||||
>>> script
|
|
||||||
<jedi.api.Script object at 0x2121b10>
|
|
||||||
>>> completions = script.completions()
|
|
||||||
>>> completions
|
|
||||||
[<Completion: load>, <Completion: loads>]
|
|
||||||
>>> completions[1]
|
|
||||||
<Completion: loads>
|
|
||||||
>>> completions[1].complete
|
|
||||||
'oads'
|
|
||||||
>>> completions[1].name
|
|
||||||
'loads'
|
|
||||||
|
|
||||||
Definitions / Goto:
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
>>> import jedi
|
|
||||||
>>> source = '''def my_func():
|
|
||||||
... print 'called'
|
|
||||||
...
|
|
||||||
... alias = my_func
|
|
||||||
... my_list = [1, None, alias]
|
|
||||||
... inception = my_list[2]
|
|
||||||
...
|
|
||||||
... inception()'''
|
|
||||||
>>> script = jedi.Script(source, 8, 1, '')
|
|
||||||
>>>
|
|
||||||
>>> script.goto_assignments()
|
|
||||||
[<Definition inception=my_list[2]>]
|
|
||||||
>>>
|
|
||||||
>>> script.goto_definitions()
|
|
||||||
[<Definition def my_func>]
|
|
||||||
|
|
||||||
Related names:
|
|
||||||
|
|
||||||
.. sourcecode:: python
|
|
||||||
|
|
||||||
>>> import jedi
|
|
||||||
>>> source = '''x = 3
|
|
||||||
... if 1 == 2:
|
|
||||||
... x = 4
|
|
||||||
... else:
|
|
||||||
... del x'''
|
|
||||||
>>> script = jedi.Script(source, 5, 8, '')
|
|
||||||
>>> rns = script.related_names()
|
|
||||||
>>> rns
|
|
||||||
[<RelatedName x@3,4>, <RelatedName x@1,0>]
|
|
||||||
>>> rns[0].start_pos
|
|
||||||
(3, 4)
|
|
||||||
>>> rns[0].is_keyword
|
|
||||||
False
|
|
||||||
>>> rns[0].text
|
|
||||||
'x'
|
|
@ -1,6 +0,0 @@
|
|||||||
.. include:: ../global.rst
|
|
||||||
|
|
||||||
Settings
|
|
||||||
========
|
|
||||||
|
|
||||||
.. automodule:: jedi.settings
|
|
@ -1,106 +0,0 @@
|
|||||||
|
|
||||||
This file is the start of the documentation of how static analysis works.
|
|
||||||
|
|
||||||
Below is a list of parser names that are used within nodes_to_execute.
|
|
||||||
|
|
||||||
------------ cared for:
|
|
||||||
global_stmt
|
|
||||||
exec_stmt # no priority
|
|
||||||
assert_stmt
|
|
||||||
if_stmt
|
|
||||||
while_stmt
|
|
||||||
for_stmt
|
|
||||||
try_stmt
|
|
||||||
(except_clause)
|
|
||||||
with_stmt
|
|
||||||
(with_item)
|
|
||||||
(with_var)
|
|
||||||
print_stmt
|
|
||||||
del_stmt
|
|
||||||
return_stmt
|
|
||||||
raise_stmt
|
|
||||||
yield_expr
|
|
||||||
file_input
|
|
||||||
funcdef
|
|
||||||
param
|
|
||||||
old_lambdef
|
|
||||||
lambdef
|
|
||||||
import_name
|
|
||||||
import_from
|
|
||||||
(import_as_name)
|
|
||||||
(dotted_as_name)
|
|
||||||
(import_as_names)
|
|
||||||
(dotted_as_names)
|
|
||||||
(dotted_name)
|
|
||||||
classdef
|
|
||||||
comp_for
|
|
||||||
(comp_if) ?
|
|
||||||
decorator
|
|
||||||
|
|
||||||
----------- add basic
|
|
||||||
test
|
|
||||||
or_test
|
|
||||||
and_test
|
|
||||||
not_test
|
|
||||||
expr
|
|
||||||
xor_expr
|
|
||||||
and_expr
|
|
||||||
shift_expr
|
|
||||||
arith_expr
|
|
||||||
term
|
|
||||||
factor
|
|
||||||
power
|
|
||||||
atom
|
|
||||||
comparison
|
|
||||||
expr_stmt
|
|
||||||
testlist
|
|
||||||
testlist1
|
|
||||||
testlist_safe
|
|
||||||
|
|
||||||
----------- special care:
|
|
||||||
# mostly depends on how we handle the other ones.
|
|
||||||
testlist_star_expr # should probably just work with expr_stmt
|
|
||||||
star_expr
|
|
||||||
exprlist # just ignore? then names are just resolved. Strange anyway, bc expr is not really allowed in the list, typically.
|
|
||||||
|
|
||||||
----------- ignore:
|
|
||||||
suite
|
|
||||||
subscriptlist
|
|
||||||
subscript
|
|
||||||
simple_stmt
|
|
||||||
?? sliceop # can probably just be added.
|
|
||||||
testlist_comp # prob ignore and care about it with atom.
|
|
||||||
dictorsetmaker
|
|
||||||
trailer
|
|
||||||
decorators
|
|
||||||
decorated
|
|
||||||
# always execute function arguments? -> no problem with stars.
|
|
||||||
# Also arglist and argument are different in different grammars.
|
|
||||||
arglist
|
|
||||||
argument
|
|
||||||
|
|
||||||
|
|
||||||
----------- remove:
|
|
||||||
tname # only exists in current Jedi parser. REMOVE!
|
|
||||||
tfpdef # python 2: tuple assignment; python 3: annotation
|
|
||||||
vfpdef # reduced in python 3 and therefore not existing.
|
|
||||||
tfplist # not in 3
|
|
||||||
vfplist # not in 3
|
|
||||||
|
|
||||||
--------- not existing with parser reductions.
|
|
||||||
small_stmt
|
|
||||||
import_stmt
|
|
||||||
flow_stmt
|
|
||||||
compound_stmt
|
|
||||||
stmt
|
|
||||||
pass_stmt
|
|
||||||
break_stmt
|
|
||||||
continue_stmt
|
|
||||||
comp_op
|
|
||||||
augassign
|
|
||||||
old_test
|
|
||||||
typedargslist # afaik becomes [param]
|
|
||||||
varargslist # dito
|
|
||||||
vname
|
|
||||||
comp_iter
|
|
||||||
test_nocond
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user