Merge branch 'master' of github.com:rad4day/dotfiles

This commit is contained in:
Tobias Manske 2018-09-01 13:07:39 +02:00
commit a426a4ef08
No known key found for this signature in database
GPG Key ID: 978D99F12D4E041F
1075 changed files with 179 additions and 150556 deletions

View File

@ -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
View File

@ -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
View File

@ -0,0 +1,3 @@
Signed-off-by: Tobias Manske <tobias.manske@mailbox.org>

114
.gitmodules vendored
View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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
View 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()

View File

@ -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

View File

@ -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
View 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()

View File

@ -1 +0,0 @@
doc/tags

View File

@ -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).

View File

@ -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

View File

@ -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, jen 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

View File

@ -1 +0,0 @@
*.zip

View File

@ -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 :

View File

@ -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

View File

@ -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>)

View File

@ -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

View File

@ -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

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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

View File

@ -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 :

View File

@ -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

View File

@ -1 +0,0 @@
doc/tags

View File

@ -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.

View File

@ -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.

View File

@ -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()

View File

@ -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)

View File

@ -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~

View File

@ -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

View File

@ -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=

View File

@ -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

View File

@ -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.

View File

@ -1,10 +0,0 @@
RPLUGIN_PATH := ./rplugin/python3/deoplete/sources
all: test
test: flake8
flake8:
flake8 rplugin tests
.PHONY: test flake8

View File

@ -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.

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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

View File

@ -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__.:

View File

@ -1,13 +0,0 @@
*~
*.sw?
*.pyc
.ropeproject
.tox
.coveralls.yml
.coverage
/build/
/docs/_build/
/dist/
jedi.egg-info/
record.json
/.cache/

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.**

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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."

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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.

View File

@ -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">
&copy; Copyright {{ copyright }}.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
</div>
{% if pagename == 'index' %}
</div>
{% endif %}
{%- endblock %}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 =

View File

@ -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'
}

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -1,10 +0,0 @@
.. include:: ../global.rst
.. _plugin-api-classes:
API Return Classes
------------------
.. automodule:: jedi.api.classes
:members:
:undoc-members:

View File

@ -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'

View File

@ -1,6 +0,0 @@
.. include:: ../global.rst
Settings
========
.. automodule:: jedi.settings

View File

@ -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

View File

@ -1,40 +0,0 @@
.. include:: ../global.rst
Jedi 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/>`_.
You want to add a test for |jedi|? Great! We love that. Normally you should
write your tests as :ref:`Blackbox Tests <blackbox>`. Most tests would
fit right in there.
For specific API testing we're using simple unit tests, with a focus on a
simple and readable testing structure.
.. _blackbox:
Blackbox Tests (run.py)
~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: test.run
Refactoring Tests (refactor.py)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: test.refactor

Some files were not shown because too many files have changed in this diff Show More