Fixed vim and zsh

This commit is contained in:
Tobias Manske 2018-04-05 13:06:54 +02:00
parent f9db886bd3
commit 0331f6518a
No known key found for this signature in database
GPG Key ID: 978D99F12D4E041F
2009 changed files with 256303 additions and 0 deletions

53
vim/.vimrc Executable file
View File

@ -0,0 +1,53 @@
set encoding=utf-8
execute pathogen#infect('plugins/{}')
execute pathogen#infect('snippets/{}')
autocmd vimenter * Helptags
syntax on
filetype plugin on
filetype plugin indent on
set number
set relativenumber
set autochdir
set expandtab
let &undodir = expand('~/.vim/.undo')
let &backupdir = expand('~/.vim/.backup//')
let &directory = expand('~/.vim/.swp//')
set undofile
colorscheme new-railscasts
source ~/.vim/config/plugin.vim
source ~/.vim/config/keybindings.vim
set tabstop=4
set shiftwidth=4
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()
let curWin = winnr()
for winnr in range(1, winnr('$'))
if getwinvar(winnr, '&ft')=="netrw"
if curWin != winnr
silent noautocmd exec winnr 'wincmd w'
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()
" autocmd VimEnter * Vex
autocmd BufNew * call ForceResizeNetrw()
" Transparency
hi Normal guibg=NONE ctermbg=NONE

266
vim/autoload/pathogen.vim Executable file
View File

@ -0,0 +1,266 @@
" 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'\:'=':

View File

@ -0,0 +1,361 @@
" # Happy Hacking
"
" Happy Hacking is a color scheme heavily inspired by Autumn
" (https://github.com/yorickpeterse/autumn.vim). The main differences between
" the two themes are various small tweaks to the colors, an easier to maintain
" codebase and a much wider range of supported languages. On top of that
" various inconsistencies that were present in Autumn have been resolved.
"
" As with any Vim color scheme the overall look and feel heavily depends on how
" accurate a syntax highlighter for a language is. For example, the Ruby syntax
" highlighter is fairly accurate and allows you to customize a lot whereas for
" example C has a more generic highlighting setup. At worst this will result in
" a bit more heavy use of red as it's one of the base colors of this theme.
"
" Author: Yorick Peterse
" License: MIT
" Website: https://github.com/yorickpeterse/happy_hacking.vim
"
set background=dark
set t_Co=256
hi clear
if exists("syntax_on")
syntax reset
end
let colors_name = "happy_hacking"
" ============================================================================
" GUI Colors
"
" This section defines all the colors to use when running Vim as a GUI (Gvim,
" Macvim, etc). These colors are *not* used when Vim is run in a terminal.
let s:white = "#F3F2CC"
let s:black1 = "#000000"
let s:black2 = "#202020"
let s:yellow = "#FAD566"
let s:blue = "#81A2C7"
let s:green = "#8daf67"
let s:turqoise = "#B3EBBF"
let s:orange = "#FAA166"
let s:pink = "#F77EBD"
let s:red = "#F05E48"
let s:gray1 = "#292929"
let s:gray2 = "#525252"
let s:gray3 = "#6c6c6c"
let s:gray4 = "#7c7c7c"
let s:gray5 = "#aaaaaa"
let s:gray6 = "#393939"
" ============================================================================
" Terminal Colors
"
" This section defines all the colors that are used when Vim is run inside a
" terminal instead of a GUI.
let s:t_white = "230"
let s:t_black1 = "16"
let s:t_black2 = "16"
let s:t_yellow = "221"
let s:t_blue = "103"
let s:t_green = "107"
let s:t_turqoise = "157"
let s:t_orange = "179"
let s:t_pink = "211"
let s:t_gold = "186"
let s:t_red = "203"
let s:t_gray1 = "235"
let s:t_gray2 = "59"
let s:t_gray3 = "59"
let s:t_gray4 = "102"
let s:t_gray5 = "145"
let s:t_gray6 = "237"
" ============================================================================
" Color Functions
" Function for creating a highlight group with a GUI/Terminal foreground and
" background. No font styling is applied.
function! s:Color(group, fg, bg, t_fg, t_bg, ...)
if empty(a:0)
let style = "NONE"
else
let style = a:1
end
exe "hi " . a:group . " guifg=" . a:fg . " guibg=" . a:bg
\ . " ctermfg=" . a:t_fg
\ . " ctermbg=" . a:t_bg
\ . " gui=" . style
\ . " cterm=" . style
endfunction
" ============================================================================
" General Syntax Elements
"
" Definitions for generic syntax elements such as strings and numbers.
call s:Color("Pmenu", s:white, s:black2, s:t_white, s:t_gray6)
" Modified Pmenu! original white black2 t_white t_black
" ~rad4day
call s:Color("PmenuSel", s:white, s:gray2, s:t_white, s:t_gray2)
call s:Color("Cursor", "NONE", s:gray2, "NONE", s:t_gray2)
call s:Color("Normal", s:white, s:gray1, s:t_white, s:t_gray1)
call s:Color("Search", s:yellow, "NONE", s:t_yellow, "NONE", "bold")
call s:Color("Title", s:white, "NONE", s:t_white, "NONE", "bold")
call s:Color("LineNr", s:gray3, "NONE", s:t_gray3, "NONE")
call s:Color("StatusLine", s:white, s:gray6, s:t_white, s:t_gray6)
call s:Color("StatusLineNC", s:gray4, s:gray6, s:t_gray4, s:t_gray6)
call s:Color("VertSplit", s:gray3, "NONE", s:t_gray3, "NONE")
call s:Color("ColorColumn", "NONE", s:gray6, "NONE", s:t_gray6)
call s:Color("Folded", s:gray4, "NONE", s:t_gray4, "NONE")
call s:Color("FoldColumn", s:gray3, s:gray1, s:t_gray3, s:t_gray1)
call s:Color("ErrorMsg", s:red, "NONE", s:t_red, "NONE", "bold")
call s:Color("WarningMsg", s:yellow, "NONE", s:t_yellow, "NONE", "bold")
call s:Color("Question", s:white, "NONE", s:t_white, "NONE")
call s:Color("SpecialKey", s:white, s:gray2, s:t_white, s:t_gray2)
call s:Color("Directory", s:blue, "NONE", s:t_blue, "NONE")
call s:Color("Comment", s:gray4, "NONE", s:t_gray4, "NONE")
call s:Color("Todo", s:gray5, "NONE", s:t_gray5, "NONE")
call s:Color("String", s:green, "NONE", s:t_green, "NONE")
call s:Color("Keyword", s:red, "NONE", s:t_red, "NONE")
call s:Color("Number", s:turqoise, "NONE", s:t_turqoise, "NONE")
call s:Color("Regexp", s:orange, "NONE", s:t_orange, "NONE")
call s:Color("Macro", s:orange, "NONE", s:t_orange, "NONE")
call s:Color("Function", s:yellow, "NONE", s:t_yellow, "NONE")
call s:Color("Notice", s:yellow, "NONE", s:t_yellow, "NONE")
call s:Color("MatchParen", "NONE", "NONE", "NONE", "NONE", "bold")
hi! link CursorLine Cursor
hi! link Identifier Normal
hi! link Constant Normal
hi! link Operator Normal
hi! link Type Keyword
hi! link Statement Keyword
hi! link PmenuThumb PmenuSel
hi! link Visual Cursor
hi! link SignColumn FoldColumn
hi! link Error ErrorMsg
hi! link NonText LineNr
hi! link PreProc Normal
hi! link Special Normal
hi! link Boolean Keyword
hi! link StorageClass Keyword
hi! link MoreMsg Normal
hi! link Character String
hi! link Label Special
hi! link PreCondit Macro
" ============================================================================
" Specific Languages
"
" Language specific settings that would otherwise be too generic. These
" definitions are sorted in alphabetical order.
" Coffeescript
hi! link coffeeRegex Regexp
hi! link coffeeSpecialIdent Directory
" CSS
hi! link cssIdentifier Title
hi! link cssClassName Directory
hi! link cssMedia Notice
hi! link cssColor Number
hi! link cssTagName Normal
hi! link cssImportant Notice
" CtrlP
hi! link CtrlPBufferHid Todo
hi! link CtrlPBufferPath Todo
call s:Color("CtrlPMode1", s:white, s:gray1, s:t_white, s:t_gray1, "bold")
" D
hi! link dDebug Notice
hi! link dOperator Operator
hi! link dStorageClass Keyword
hi! link dAnnotation Directory
hi! link dAttribute dAnnotation
" Diffs
hi! link diffFile WarningMsg
hi! link diffLine Number
hi! link diffAdded String
hi! link diffRemoved Keyword
hi! link DiffChange Notice
hi! link DiffAdd diffAdded
hi! link DiffDelete diffRemoved
hi! link DiffText diffLine
" Dot (GraphViz)
hi! link dotKeyChar Normal
" Git commits
hi! link gitCommitSummary String
hi! link gitCommitOverflow ErrorMsg
" HAML
hi! link hamlId Title
hi! link hamlClass Directory
hi! link htmlArg Normal
hi! link hamlDocType Comment
" HTML
hi! link htmlLink Directory
hi! link htmlSpecialTagName htmlTag
hi! link htmlTagName htmlTag
hi! link htmlScriptTag htmlTag
" Javascript
hi! link javaScriptBraces Normal
hi! link javaScriptMember Normal
hi! link javaScriptIdentifier Keyword
hi! link javaScriptFunction Keyword
hi! link JavaScriptNumber Number
" Java
hi! link javaCommentTitle javaComment
hi! link javaDocTags Todo
hi! link javaDocParam Todo
hi! link javaStorageClass Keyword
hi! link javaAnnotation Directory
hi! link javaExternal Keyword
" JSON
hi! link jsonKeyword String
" Less
hi! link lessClass cssClassName
" Make
hi! link makeTarget Function
" Markdown
hi! link markdownCodeBlock Todo
hi! link markdownCode markdownCodeBlock
hi! link markdownListMarker Keyword
hi! link markdownOrderedListMarker Keyword
" NERDTree
hi! link NERDTreeRO Notice
hi! link NERDTreeCWD Title
hi! link NERDTreeLink Number
hi! link NERDTreeDir Directory
hi! link NERDTreeOpenable NERDTreeDir
hi! link NERDTreeClosable NERDTreeDir
" Perl
hi! link podCommand Comment
hi! link podCmdText Todo
hi! link podVerbatimLine Todo
hi! link perlStatementInclude Statement
hi! link perlStatementPackage Statement
hi! link perlPackageDecl Normal
" Ragel
hi! link rlAugmentOps Operator
" Ruby
hi! link rubySymbol Regexp
hi! link rubyConstant Constant
hi! link rubyInstanceVariable Directory
hi! link rubyClassVariable rubyInstancevariable
hi! link rubyClass Keyword
hi! link rubyModule rubyClass
hi! link rubyFunction Function
hi! link rubyDefine Keyword
hi! link rubyRegexp Regexp
hi! link rubyRegexpSpecial Regexp
hi! link rubyRegexpCharClass Normal
hi! link rubyRegexpQuantifier Normal
" Rust
hi! link rustFuncCall Identifier
hi! link rustCommentBlockDoc Comment
hi! link rustCommentLineDoc Comment
" SASS
hi! link sassClass cssClassName
hi! link sassId cssIdentifier
hi! link sassInclude cssMedia
" Shell
hi! link shFunctionKey Keyword
hi! link shTestOpr Operator
hi! link bashStatement Normal
" SQL
hi! link sqlKeyword Keyword
" TypeScript
hi! link typescriptBraces Normal
hi! link typescriptEndColons Normal
hi! link typescriptFunction Function
hi! link typescriptFuncKeyword Keyword
hi! link typescriptLogicSymbols Operator
hi! link typescriptIdentifier Keyword
hi! link typescriptExceptions Keyword
" Vimscript
hi! link vimGroup Constant
hi! link vimHiGroup Constant
hi! link VimIsCommand Constant
hi! link VimCommentTitle Todo
" YAML
hi! link yamlPlainScalar String
" YARD
hi! link yardType Todo
hi! link yardTypeList Todo
hi! link yardComment Comment
" XML
hi! link xmlTagName Normal
hi! link xmlTag Normal
hi! link xmlAttrib Normal
" Neomake
hi! link NeomakeWarningSign WarningMsg
hi! link NeomakeErrorSign Error
hi! link NeomakeWarning WarningMsg
" Wild menu completion
hi! link WildMenu PmenuSel
" Vim tabline
hi! link TabLine StatusLine
hi! link TabLineFill StatusLine
call s:Color("TabLineSel", s:white, s:gray2, s:t_white, s:t_gray2, "bold")
" Line numbers
call s:Color("CursorLineNR", s:yellow, "NONE", s:t_yellow, "NONE", "bold")
" Neovim terminal colors
let g:terminal_color_0 = s:black1
let g:terminal_color_1 = s:red
let g:terminal_color_2 = s:green
let g:terminal_color_3 = s:yellow
let g:terminal_color_4 = s:blue
let g:terminal_color_5 = s:pink
let g:terminal_color_6 = s:turqoise
let g:terminal_color_7 = s:white
let g:terminal_color_8 = s:black1
let g:terminal_color_9 = s:red
let g:terminal_color_10 = s:green
let g:terminal_color_11 = s:yellow
let g:terminal_color_12 = s:blue
let g:terminal_color_13 = s:pink
let g:terminal_color_14 = s:turqoise
let g:terminal_color_15 = s:white

687
vim/colors/jellybeans.vim Executable file
View File

@ -0,0 +1,687 @@
" Vim color file
"
" " __ _ _ _ "
" " \ \ ___| | |_ _| |__ ___ __ _ _ __ ___ "
" " \ \/ _ \ | | | | | _ \ / _ \/ _ | _ \/ __| "
" " /\_/ / __/ | | |_| | |_| | __/ |_| | | | \__ \ "
" " \___/ \___|_|_|\__ |____/ \___|\____|_| |_|___/ "
" " \___/ "
"
" "A colorful, dark color scheme for Vim."
"
" File: jellybeans.vim
" URL: github.com/nanotech/jellybeans.vim
" Scripts URL: vim.org/scripts/script.php?script_id=2555
" Maintainer: NanoTech (nanotech.nanotechcorp.net)
" Version: 1.6
" Last Change: October 18th, 2016
" License: MIT
" Contributors: Andrew Wong (w0ng)
" Brian Marshall (bmars)
" Daniel Herbert (pocketninja)
" David Liang <bmdavll at gmail dot com>
" Henry So, Jr. <henryso@panix.com>
" Joe Doherty (docapotamus)
" Karl Litterfeldt (Litterfeldt)
" Keith Pitt (keithpitt)
" Philipp Rustemeier (12foo)
" Rafael Bicalho (rbika)
" Rich Healey (richo)
" Siwen Yu (yusiwen)
" Tim Willis (willist)
"
" Copyright (c) 2009-2016 NanoTech
"
" Permission is hereby granted, free of charge, to any per
" son obtaining a copy of this software and associated doc
" umentation files (the “Software”), to deal in the Soft
" ware without restriction, including without limitation
" the rights to use, copy, modify, merge, publish, distrib
" ute, 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 PARTICU
" LAR 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 CON
" TRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON
" NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
" THE SOFTWARE.
set background=dark
hi clear
if exists("syntax_on")
syntax reset
endif
let colors_name = "jellybeans"
if has("gui_running") || (has('termguicolors') && &termguicolors) || &t_Co >= 88
let s:low_color = 0
else
let s:low_color = 1
endif
" Configuration Variables:
" - g:jellybeans_overrides (default = {})
" - g:jellybeans_use_lowcolor_black (default = 1)
" - g:jellybeans_use_gui_italics (default = 1)
" - g:jellybeans_use_term_italics (default = 0)
let s:background_color = "151515"
if exists("g:jellybeans_overrides")
let s:overrides = g:jellybeans_overrides
else
let s:overrides = {}
endif
" Backwards compatibility
if exists("g:jellybeans_background_color")
\ || exists("g:jellybeans_background_color_256")
\ || exists("g:jellybeans_use_term_background_color")
let s:overrides = deepcopy(s:overrides)
if !has_key(s:overrides, "background")
let s:overrides["background"] = {}
endif
if exists("g:jellybeans_background_color")
let s:overrides["background"]["guibg"] = g:jellybeans_background_color
endif
if exists("g:jellybeans_background_color_256")
let s:overrides["background"]["256ctermbg"] = g:jellybeans_background_color_256
endif
if exists("g:jellybeans_use_term_background_color")
\ && g:jellybeans_use_term_background_color
let s:overrides["background"]["ctermbg"] = "NONE"
let s:overrides["background"]["256ctermbg"] = "NONE"
endif
endif
if !exists("g:jellybeans_use_lowcolor_black") || g:jellybeans_use_lowcolor_black
let s:termBlack = "Black"
else
let s:termBlack = "Grey"
endif
" When `termguicolors` is set, Vim[^1] ignores `guibg=NONE` after
" `guibg` is already set to a color. See:
"
" - https://github.com/vim/vim/issues/981
" - https://github.com/nanotech/jellybeans.vim/issues/64
"
" To work around this, ensure we don't set the default background
" color before an override changes it to `NONE` by ensuring that the
" background color isn't set to a value different from its override.
"
" [^1]: Tested on 8.0.567. Does not apply to Neovim.
"
" TODO: Enable this behavior for all highlights by applying
" overrides before calling highlight commands.
"
if has_key(s:overrides, "background") && has_key(s:overrides["background"], "guibg")
let s:background_color = s:overrides["background"]["guibg"]
endif
" Color approximation functions by Henry So, Jr. and David Liang {{{
" Added to jellybeans.vim by Daniel Herbert
" returns an approximate grey index for the given grey level
fun! s:grey_number(x)
if &t_Co == 88
if a:x < 23
return 0
elseif a:x < 69
return 1
elseif a:x < 103
return 2
elseif a:x < 127
return 3
elseif a:x < 150
return 4
elseif a:x < 173
return 5
elseif a:x < 196
return 6
elseif a:x < 219
return 7
elseif a:x < 243
return 8
else
return 9
endif
else
if a:x < 14
return 0
else
let l:n = (a:x - 8) / 10
let l:m = (a:x - 8) % 10
if l:m < 5
return l:n
else
return l:n + 1
endif
endif
endif
endfun
" returns the actual grey level represented by the grey index
fun! s:grey_level(n)
if &t_Co == 88
if a:n == 0
return 0
elseif a:n == 1
return 46
elseif a:n == 2
return 92
elseif a:n == 3
return 115
elseif a:n == 4
return 139
elseif a:n == 5
return 162
elseif a:n == 6
return 185
elseif a:n == 7
return 208
elseif a:n == 8
return 231
else
return 255
endif
else
if a:n == 0
return 0
else
return 8 + (a:n * 10)
endif
endif
endfun
" returns the palette index for the given grey index
fun! s:grey_color(n)
if &t_Co == 88
if a:n == 0
return 16
elseif a:n == 9
return 79
else
return 79 + a:n
endif
else
if a:n == 0
return 16
elseif a:n == 25
return 231
else
return 231 + a:n
endif
endif
endfun
" returns an approximate color index for the given color level
fun! s:rgb_number(x)
if &t_Co == 88
if a:x < 69
return 0
elseif a:x < 172
return 1
elseif a:x < 230
return 2
else
return 3
endif
else
if a:x < 75
return 0
else
let l:n = (a:x - 55) / 40
let l:m = (a:x - 55) % 40
if l:m < 20
return l:n
else
return l:n + 1
endif
endif
endif
endfun
" returns the actual color level for the given color index
fun! s:rgb_level(n)
if &t_Co == 88
if a:n == 0
return 0
elseif a:n == 1
return 139
elseif a:n == 2
return 205
else
return 255
endif
else
if a:n == 0
return 0
else
return 55 + (a:n * 40)
endif
endif
endfun
" returns the palette index for the given R/G/B color indices
fun! s:rgb_color(x, y, z)
if &t_Co == 88
return 16 + (a:x * 16) + (a:y * 4) + a:z
else
return 16 + (a:x * 36) + (a:y * 6) + a:z
endif
endfun
" returns the palette index to approximate the given R/G/B color levels
fun! s:color(r, g, b)
" map greys directly (see xterm's 256colres.pl)
if &t_Co == 256 && a:r == a:g && a:g == a:b && a:r > 3 && a:r < 243
return (a:r - 8) / 10 + 232
endif
" get the closest grey
let l:gx = s:grey_number(a:r)
let l:gy = s:grey_number(a:g)
let l:gz = s:grey_number(a:b)
" get the closest color
let l:x = s:rgb_number(a:r)
let l:y = s:rgb_number(a:g)
let l:z = s:rgb_number(a:b)
if l:gx == l:gy && l:gy == l:gz
" there are two possibilities
let l:dgr = s:grey_level(l:gx) - a:r
let l:dgg = s:grey_level(l:gy) - a:g
let l:dgb = s:grey_level(l:gz) - a:b
let l:dgrey = (l:dgr * l:dgr) + (l:dgg * l:dgg) + (l:dgb * l:dgb)
let l:dr = s:rgb_level(l:gx) - a:r
let l:dg = s:rgb_level(l:gy) - a:g
let l:db = s:rgb_level(l:gz) - a:b
let l:drgb = (l:dr * l:dr) + (l:dg * l:dg) + (l:db * l:db)
if l:dgrey < l:drgb
" use the grey
return s:grey_color(l:gx)
else
" use the color
return s:rgb_color(l:x, l:y, l:z)
endif
else
" only one possibility
return s:rgb_color(l:x, l:y, l:z)
endif
endfun
fun! s:is_empty_or_none(str)
return empty(a:str) || a:str ==? "NONE"
endfun
" returns the palette index to approximate the 'rrggbb' hex string
fun! s:rgb(rgb)
if s:is_empty_or_none(a:rgb)
return "NONE"
endif
let l:r = ("0x" . strpart(a:rgb, 0, 2)) + 0
let l:g = ("0x" . strpart(a:rgb, 2, 2)) + 0
let l:b = ("0x" . strpart(a:rgb, 4, 2)) + 0
return s:color(l:r, l:g, l:b)
endfun
fun! s:prefix_highlight_value_with(prefix, color)
if s:is_empty_or_none(a:color)
return "NONE"
else
return a:prefix . a:color
endif
endfun
fun! s:remove_italic_attr(attr)
let l:attr = join(filter(split(a:attr, ","), "v:val !=? 'italic'"), ",")
if empty(l:attr)
let l:attr = "NONE"
endif
return l:attr
endfun
" sets the highlighting for the given group
fun! s:X(group, fg, bg, attr, lcfg, lcbg)
if s:low_color
exec "hi ".a:group.
\ " ctermfg=".s:prefix_highlight_value_with("", a:lcfg).
\ " ctermbg=".s:prefix_highlight_value_with("", a:lcbg)
else
exec "hi ".a:group.
\ " guifg=".s:prefix_highlight_value_with("#", a:fg).
\ " guibg=".s:prefix_highlight_value_with("#", a:bg).
\ " ctermfg=".s:rgb(a:fg).
\ " ctermbg=".s:rgb(a:bg)
endif
let l:attr = s:prefix_highlight_value_with("", a:attr)
if exists("g:jellybeans_use_term_italics") && g:jellybeans_use_term_italics
let l:cterm_attr = l:attr
else
let l:cterm_attr = s:remove_italic_attr(l:attr)
endif
if !exists("g:jellybeans_use_gui_italics") || g:jellybeans_use_gui_italics
let l:gui_attr = l:attr
else
let l:gui_attr = s:remove_italic_attr(l:attr)
endif
exec "hi ".a:group." gui=".l:gui_attr." cterm=".l:cterm_attr
endfun
" }}}
call s:X("Normal","e8e8d3",s:background_color,"","White","")
set background=dark
if version >= 700
call s:X("CursorLine","","1c1c1c","","",s:termBlack)
call s:X("CursorColumn","","1c1c1c","","",s:termBlack)
call s:X("MatchParen","ffffff","556779","bold","","DarkCyan")
call s:X("TabLine","000000","b0b8c0","italic","",s:termBlack)
call s:X("TabLineFill","9098a0","","","",s:termBlack)
call s:X("TabLineSel","000000","f0f0f0","italic,bold",s:termBlack,"White")
" Auto-completion
call s:X("Pmenu","ffffff","606060","","White",s:termBlack)
call s:X("PmenuSel","101010","eeeeee","",s:termBlack,"White")
endif
call s:X("Visual","","404040","","",s:termBlack)
call s:X("Cursor",s:background_color,"b0d0f0","","","")
call s:X("LineNr","605958",s:background_color,"NONE",s:termBlack,"")
call s:X("CursorLineNr","ccc5c4","","NONE","White","")
call s:X("Comment","888888","","italic","Grey","")
call s:X("Todo","c7c7c7","","bold","White",s:termBlack)
call s:X("StatusLine","000000","dddddd","italic","","White")
call s:X("StatusLineNC","ffffff","403c41","italic","White","Black")
call s:X("VertSplit","777777","403c41","",s:termBlack,s:termBlack)
call s:X("WildMenu","f0a0c0","302028","","Magenta","")
call s:X("Folded","a0a8b0","384048","italic",s:termBlack,"")
call s:X("FoldColumn","535D66","1f1f1f","","",s:termBlack)
call s:X("SignColumn","777777","333333","","",s:termBlack)
call s:X("ColorColumn","","000000","","",s:termBlack)
call s:X("Title","70b950","","bold","Green","")
call s:X("Constant","cf6a4c","","","Red","")
call s:X("Special","799d6a","","","Green","")
call s:X("Delimiter","668799","","","Grey","")
call s:X("String","99ad6a","","","Green","")
call s:X("StringDelimiter","556633","","","DarkGreen","")
call s:X("Identifier","c6b6ee","","","LightCyan","")
call s:X("Structure","8fbfdc","","","LightCyan","")
call s:X("Function","fad07a","","","Yellow","")
call s:X("Statement","8197bf","","","DarkBlue","")
call s:X("PreProc","8fbfdc","","","LightBlue","")
hi! link Operator Structure
hi! link Conceal Operator
call s:X("Type","ffb964","","","Yellow","")
call s:X("NonText","606060",s:background_color,"",s:termBlack,"")
call s:X("SpecialKey","444444","1c1c1c","",s:termBlack,"")
call s:X("Search","f0a0c0","302028","underline","Magenta","")
call s:X("Directory","dad085","","","Yellow","")
call s:X("ErrorMsg","","902020","","","DarkRed")
hi! link Error ErrorMsg
hi! link MoreMsg Special
call s:X("Question","65C254","","","Green","")
" Spell Checking
call s:X("SpellBad","","902020","underline","","DarkRed")
call s:X("SpellCap","","0000df","underline","","Blue")
call s:X("SpellRare","","540063","underline","","DarkMagenta")
call s:X("SpellLocal","","2D7067","underline","","Green")
" Diff
hi! link diffRemoved Constant
hi! link diffAdded String
" VimDiff
call s:X("DiffAdd","D2EBBE","437019","","White","DarkGreen")
call s:X("DiffDelete","40000A","700009","","DarkRed","DarkRed")
call s:X("DiffChange","","2B5B77","","White","DarkBlue")
call s:X("DiffText","8fbfdc","000000","reverse","Yellow","")
" PHP
hi! link phpFunctions Function
call s:X("StorageClass","c59f6f","","","Red","")
hi! link phpSuperglobal Identifier
hi! link phpQuoteSingle StringDelimiter
hi! link phpQuoteDouble StringDelimiter
hi! link phpBoolean Constant
hi! link phpNull Constant
hi! link phpArrayPair Operator
hi! link phpOperator Normal
hi! link phpRelation Normal
hi! link phpVarSelector Identifier
" Python
hi! link pythonOperator Statement
" Ruby
hi! link rubySharpBang Comment
call s:X("rubyClass","447799","","","DarkBlue","")
call s:X("rubyIdentifier","c6b6fe","","","Cyan","")
hi! link rubyConstant Type
hi! link rubyFunction Function
call s:X("rubyInstanceVariable","c6b6fe","","","Cyan","")
call s:X("rubySymbol","7697d6","","","Blue","")
hi! link rubyGlobalVariable rubyInstanceVariable
hi! link rubyModule rubyClass
call s:X("rubyControl","7597c6","","","Blue","")
hi! link rubyString String
hi! link rubyStringDelimiter StringDelimiter
hi! link rubyInterpolationDelimiter Identifier
call s:X("rubyRegexpDelimiter","540063","","","Magenta","")
call s:X("rubyRegexp","dd0093","","","DarkMagenta","")
call s:X("rubyRegexpSpecial","a40073","","","Magenta","")
call s:X("rubyPredefinedIdentifier","de5577","","","Red","")
" Erlang
hi! link erlangAtom rubySymbol
hi! link erlangBIF rubyPredefinedIdentifier
hi! link erlangFunction rubyPredefinedIdentifier
hi! link erlangDirective Statement
hi! link erlangNode Identifier
" Elixir
hi! link elixirAtom rubySymbol
" JavaScript
hi! link javaScriptValue Constant
hi! link javaScriptRegexpString rubyRegexp
hi! link javaScriptTemplateVar StringDelim
hi! link javaScriptTemplateDelim Identifier
hi! link javaScriptTemplateString String
" CoffeeScript
hi! link coffeeRegExp javaScriptRegexpString
" Lua
hi! link luaOperator Conditional
" C
hi! link cFormat Identifier
hi! link cOperator Constant
" Objective-C/Cocoa
hi! link objcClass Type
hi! link cocoaClass objcClass
hi! link objcSubclass objcClass
hi! link objcSuperclass objcClass
hi! link objcDirective rubyClass
hi! link objcStatement Constant
hi! link cocoaFunction Function
hi! link objcMethodName Identifier
hi! link objcMethodArg Normal
hi! link objcMessageName Identifier
" Vimscript
hi! link vimOper Normal
" HTML
hi! link htmlTag Statement
hi! link htmlEndTag htmlTag
hi! link htmlTagName htmlTag
" XML
hi! link xmlTag Statement
hi! link xmlEndTag xmlTag
hi! link xmlTagName xmlTag
hi! link xmlEqual xmlTag
hi! link xmlEntity Special
hi! link xmlEntityPunct xmlEntity
hi! link xmlDocTypeDecl PreProc
hi! link xmlDocTypeKeyword PreProc
hi! link xmlProcessingDelim xmlAttrib
" Debugger.vim
call s:X("DbgCurrent","DEEBFE","345FA8","","White","DarkBlue")
call s:X("DbgBreakPt","","4F0037","","","DarkMagenta")
" vim-indent-guides
if !exists("g:indent_guides_auto_colors")
let g:indent_guides_auto_colors = 0
endif
call s:X("IndentGuidesOdd","","232323","","","")
call s:X("IndentGuidesEven","","1b1b1b","","","")
" Plugins, etc.
hi! link TagListFileName Directory
call s:X("PreciseJumpTarget","B9ED67","405026","","White","Green")
" Manual overrides for 256-color terminals. Dark colors auto-map badly.
if !s:low_color
hi StatusLineNC ctermbg=235
hi Folded ctermbg=236
hi DiffText ctermfg=81
hi DbgBreakPt ctermbg=53
hi IndentGuidesOdd ctermbg=235
hi IndentGuidesEven ctermbg=234
endif
if !empty("s:overrides")
fun! s:current_attr(group)
let l:synid = synIDtrans(hlID(a:group))
let l:attrs = []
for l:attr in ["bold", "italic", "reverse", "standout", "underline", "undercurl"]
if synIDattr(l:synid, l:attr, "gui") == 1
call add(l:attrs, l:attr)
endif
endfor
return join(l:attrs, ",")
endfun
fun! s:current_color(group, what, mode)
let l:color = synIDattr(synIDtrans(hlID(a:group)), a:what, a:mode)
if l:color == -1
return ""
else
return substitute(l:color, "^#", "", "")
endif
endfun
fun! s:load_color_def(group, def)
call s:X(a:group, get(a:def, "guifg", s:current_color(a:group, "fg", "gui")),
\ get(a:def, "guibg", s:current_color(a:group, "bg", "gui")),
\ get(a:def, "attr", s:current_attr(a:group)),
\ get(a:def, "ctermfg", s:current_color(a:group, "fg", "cterm")),
\ get(a:def, "ctermbg", s:current_color(a:group, "bg", "cterm")))
if !s:low_color
for l:prop in ["ctermfg", "ctermbg"]
let l:override_key = "256".l:prop
if has_key(a:def, l:override_key)
exec "hi ".a:group." ".l:prop."=".a:def[l:override_key]
endif
endfor
endif
endfun
fun! s:load_colors(defs)
for [l:group, l:def] in items(a:defs)
if l:group == "background"
call s:load_color_def("LineNr", l:def)
call s:load_color_def("NonText", l:def)
call s:load_color_def("Normal", l:def)
else
call s:load_color_def(l:group, l:def)
endif
unlet l:group
unlet l:def
endfor
endfun
call s:load_colors(s:overrides)
delf s:load_colors
delf s:load_color_def
delf s:current_color
delf s:current_attr
endif
" delete functions {{{
delf s:X
delf s:remove_italic_attr
delf s:prefix_highlight_value_with
delf s:rgb
delf s:is_empty_or_none
delf s:color
delf s:rgb_color
delf s:rgb_level
delf s:rgb_number
delf s:grey_color
delf s:grey_level
delf s:grey_number
" }}}

276
vim/colors/molokai.vim Executable file
View File

@ -0,0 +1,276 @@
" Vim color file
"
" Author: Tomas Restrepo <tomas@winterdom.com>
" https://github.com/tomasr/molokai
"
" Note: Based on the Monokai theme for TextMate
" by Wimer Hazenberg and its darker variant
" by Hamish Stuart Macpherson
"
hi clear
if version > 580
" no guarantees for version 5.8 and below, but this makes it stop
" complaining
hi clear
if exists("syntax_on")
syntax reset
endif
endif
let g:colors_name="molokai"
if exists("g:molokai_original")
let s:molokai_original = g:molokai_original
else
let s:molokai_original = 0
endif
hi Boolean guifg=#AE81FF
hi Character guifg=#E6DB74
hi Number guifg=#AE81FF
hi String guifg=#E6DB74
hi Conditional guifg=#F92672 gui=bold
hi Constant guifg=#AE81FF gui=bold
hi Cursor guifg=#000000 guibg=#F8F8F0
hi iCursor guifg=#000000 guibg=#F8F8F0
hi Debug guifg=#BCA3A3 gui=bold
hi Define guifg=#66D9EF
hi Delimiter guifg=#8F8F8F
hi DiffAdd guibg=#13354A
hi DiffChange guifg=#89807D guibg=#4C4745
hi DiffDelete guifg=#960050 guibg=#1E0010
hi DiffText guibg=#4C4745 gui=italic,bold
hi Directory guifg=#A6E22E gui=bold
hi Error guifg=#E6DB74 guibg=#1E0010
hi ErrorMsg guifg=#F92672 guibg=#232526 gui=bold
hi Exception guifg=#A6E22E gui=bold
hi Float guifg=#AE81FF
hi FoldColumn guifg=#465457 guibg=#000000
hi Folded guifg=#465457 guibg=#000000
hi Function guifg=#A6E22E
hi Identifier guifg=#FD971F
hi Ignore guifg=#808080 guibg=bg
hi IncSearch guifg=#C4BE89 guibg=#000000
hi Keyword guifg=#F92672 gui=bold
hi Label guifg=#E6DB74 gui=none
hi Macro guifg=#C4BE89 gui=italic
hi SpecialKey guifg=#66D9EF gui=italic
hi MatchParen guifg=#000000 guibg=#FD971F gui=bold
hi ModeMsg guifg=#E6DB74
hi MoreMsg guifg=#E6DB74
hi Operator guifg=#F92672
" complete menu
hi Pmenu guifg=#66D9EF guibg=#000000
hi PmenuSel guibg=#808080
hi PmenuSbar guibg=#080808
hi PmenuThumb guifg=#66D9EF
hi PreCondit guifg=#A6E22E gui=bold
hi PreProc guifg=#A6E22E
hi Question guifg=#66D9EF
hi Repeat guifg=#F92672 gui=bold
hi Search guifg=#000000 guibg=#FFE792
" marks
hi SignColumn guifg=#A6E22E guibg=#232526
hi SpecialChar guifg=#F92672 gui=bold
hi SpecialComment guifg=#7E8E91 gui=bold
hi Special guifg=#66D9EF guibg=bg gui=italic
if has("spell")
hi SpellBad guisp=#FF0000 gui=undercurl
hi SpellCap guisp=#7070F0 gui=undercurl
hi SpellLocal guisp=#70F0F0 gui=undercurl
hi SpellRare guisp=#FFFFFF gui=undercurl
endif
hi Statement guifg=#F92672 gui=bold
hi StatusLine guifg=#455354 guibg=fg
hi StatusLineNC guifg=#808080 guibg=#080808
hi StorageClass guifg=#FD971F gui=italic
hi Structure guifg=#66D9EF
hi Tag guifg=#F92672 gui=italic
hi Title guifg=#ef5939
hi Todo guifg=#FFFFFF guibg=bg gui=bold
hi Typedef guifg=#66D9EF
hi Type guifg=#66D9EF gui=none
hi Underlined guifg=#808080 gui=underline
hi VertSplit guifg=#808080 guibg=#080808 gui=bold
hi VisualNOS guibg=#403D3D
hi Visual guibg=#403D3D
hi WarningMsg guifg=#FFFFFF guibg=#333333 gui=bold
hi WildMenu guifg=#66D9EF guibg=#000000
hi TabLineFill guifg=#1B1D1E guibg=#1B1D1E
hi TabLine guibg=#1B1D1E guifg=#808080 gui=none
if s:molokai_original == 1
hi Normal guifg=#F8F8F2 guibg=#272822
hi Comment guifg=#75715E
hi CursorLine guibg=#3E3D32
hi CursorLineNr guifg=#FD971F gui=none
hi CursorColumn guibg=#3E3D32
hi ColorColumn guibg=#3B3A32
hi LineNr guifg=#BCBCBC guibg=#3B3A32
hi NonText guifg=#75715E
hi SpecialKey guifg=#75715E
else
hi Normal guifg=#F8F8F2 guibg=#1B1D1E
hi Comment guifg=#7E8E91
hi CursorLine guibg=#293739
hi CursorLineNr guifg=#FD971F gui=none
hi CursorColumn guibg=#293739
hi ColorColumn guibg=#232526
hi LineNr guifg=#465457 guibg=#232526
hi NonText guifg=#465457
hi SpecialKey guifg=#465457
end
"
" Support for 256-color terminal
"
if &t_Co > 255
if s:molokai_original == 1
hi Normal ctermbg=234
hi CursorLine ctermbg=235 cterm=none
hi CursorLineNr ctermfg=208 cterm=none
else
hi Normal ctermfg=252 ctermbg=233
hi CursorLine ctermbg=234 cterm=none
hi CursorLineNr ctermfg=208 cterm=none
endif
hi Boolean ctermfg=135
hi Character ctermfg=144
hi Number ctermfg=135
hi String ctermfg=144
hi Conditional ctermfg=161 cterm=bold
hi Constant ctermfg=135 cterm=bold
hi Cursor ctermfg=16 ctermbg=253
hi Debug ctermfg=225 cterm=bold
hi Define ctermfg=81
hi Delimiter ctermfg=241
hi DiffAdd ctermbg=24
hi DiffChange ctermfg=181 ctermbg=239
hi DiffDelete ctermfg=162 ctermbg=53
hi DiffText ctermbg=102 cterm=bold
hi Directory ctermfg=118 cterm=bold
hi Error ctermfg=219 ctermbg=89
hi ErrorMsg ctermfg=199 ctermbg=16 cterm=bold
hi Exception ctermfg=118 cterm=bold
hi Float ctermfg=135
hi FoldColumn ctermfg=67 ctermbg=16
hi Folded ctermfg=67 ctermbg=16
hi Function ctermfg=118
hi Identifier ctermfg=208 cterm=none
hi Ignore ctermfg=244 ctermbg=232
hi IncSearch ctermfg=193 ctermbg=16
hi keyword ctermfg=161 cterm=bold
hi Label ctermfg=229 cterm=none
hi Macro ctermfg=193
hi SpecialKey ctermfg=81
hi MatchParen ctermfg=233 ctermbg=208 cterm=bold
hi ModeMsg ctermfg=229
hi MoreMsg ctermfg=229
hi Operator ctermfg=161
" complete menu
hi Pmenu ctermfg=81 ctermbg=16
hi PmenuSel ctermfg=255 ctermbg=242
hi PmenuSbar ctermbg=232
hi PmenuThumb ctermfg=81
hi PreCondit ctermfg=118 cterm=bold
hi PreProc ctermfg=118
hi Question ctermfg=81
hi Repeat ctermfg=161 cterm=bold
hi Search ctermfg=0 ctermbg=222 cterm=NONE
" marks column
hi SignColumn ctermfg=118 ctermbg=235
hi SpecialChar ctermfg=161 cterm=bold
hi SpecialComment ctermfg=245 cterm=bold
hi Special ctermfg=81
if has("spell")
hi SpellBad ctermbg=52
hi SpellCap ctermbg=17
hi SpellLocal ctermbg=17
hi SpellRare ctermfg=none ctermbg=none cterm=reverse
endif
hi Statement ctermfg=161 cterm=bold
hi StatusLine ctermfg=238 ctermbg=253
hi StatusLineNC ctermfg=244 ctermbg=232
hi StorageClass ctermfg=208
hi Structure ctermfg=81
hi Tag ctermfg=161
hi Title ctermfg=166
hi Todo ctermfg=231 ctermbg=232 cterm=bold
hi Typedef ctermfg=81
hi Type ctermfg=81 cterm=none
hi Underlined ctermfg=244 cterm=underline
hi VertSplit ctermfg=244 ctermbg=232 cterm=bold
hi VisualNOS ctermbg=238
hi Visual ctermbg=235
hi WarningMsg ctermfg=231 ctermbg=238 cterm=bold
hi WildMenu ctermfg=81 ctermbg=16
hi Comment ctermfg=59
hi CursorColumn ctermbg=236
hi ColorColumn ctermbg=236
hi LineNr ctermfg=250 ctermbg=236
hi NonText ctermfg=59
hi SpecialKey ctermfg=59
if exists("g:rehash256") && g:rehash256 == 1
hi Normal ctermfg=252 ctermbg=234
hi CursorLine ctermbg=236 cterm=none
hi CursorLineNr ctermfg=208 cterm=none
hi Boolean ctermfg=141
hi Character ctermfg=222
hi Number ctermfg=141
hi String ctermfg=222
hi Conditional ctermfg=197 cterm=bold
hi Constant ctermfg=141 cterm=bold
hi DiffDelete ctermfg=125 ctermbg=233
hi Directory ctermfg=154 cterm=bold
hi Error ctermfg=222 ctermbg=233
hi Exception ctermfg=154 cterm=bold
hi Float ctermfg=141
hi Function ctermfg=154
hi Identifier ctermfg=208
hi Keyword ctermfg=197 cterm=bold
hi Operator ctermfg=197
hi PreCondit ctermfg=154 cterm=bold
hi PreProc ctermfg=154
hi Repeat ctermfg=197 cterm=bold
hi Statement ctermfg=197 cterm=bold
hi Tag ctermfg=197
hi Title ctermfg=203
hi Visual ctermbg=238
hi Comment ctermfg=244
hi LineNr ctermfg=239 ctermbg=235
hi NonText ctermfg=239
hi SpecialKey ctermfg=239
endif
end
" Must be at the end, because of ctermbg=234 bug.
" https://groups.google.com/forum/#!msg/vim_dev/afPqwAFNdrU/nqh6tOM87QUJ
set background=dark

View File

@ -0,0 +1,229 @@
" Vim color scheme
"
" Name: railscast.vim
" Maintainer: Josh O'Rourke <joshorourke@me.com>
" Modified: Carlos Ramos, carakan
" License: public domain
"
" A GUI Only port of the RailsCasts TextMate theme [1] to Vim.
" Some parts of this theme were borrowed from the well-documented Lucius theme [2].
"
let g:colors_name = "new-railscasts"
hi clear
if exists("syntax_on")
syntax reset
endif
highlight clear SignColumn
set background=dark
hi Normal guifg=#E6E1DC guibg=#212121 ctermfg=white ctermbg=234
hi Cursor guifg=#000000 guibg=#FFFFFF ctermfg=0 ctermbg=15
hi CursorLine guibg=#282828 ctermbg=235 cterm=NONE
hi Search guibg=#072f95 ctermfg=NONE ctermbg=236
hi Visual guibg=#004568 ctermbg=60
hi LineNr guifg=#707070 guibg=#2d2d2d ctermfg=242
hi StatusLine guifg=#e4e4e4 guibg=#606060 gui=NONE ctermfg=254 ctermbg=241 cterm=NONE
hi StatusLineNC guifg=#585858 guibg=#303030 gui=NONE ctermfg=240 ctermbg=236 cterm=NONE
hi! link CursorColumn ColorColumn
hi VertSplit guibg=#212121 gui=bold guifg=#444444 ctermfg=white ctermbg=234
hi CursorLineNr guifg=#d7b0fc guibg=#2d2d2d ctermfg=248
hi ColorColumn guibg=#333435 ctermbg=235
highlight SignColumn guibg=#2d2d2d
" StatusLine
" Bold
hi User1 guifg=#eeeeee guibg=#606060 gui=bold ctermfg=255 ctermbg=241 cterm=bold
" Yellow
hi User2 guifg=#FFAF00 guibg=#606060 gui=bold ctermfg=214 ctermbg=241 cterm=bold
" Green
hi User3 guifg=#15d300 guibg=#606060 gui=bold ctermfg=82 ctermbg=241 cterm=bold
" Red
hi User4 guifg=#870000 guibg=#606060 gui=bold ctermfg=88 ctermbg=241 cterm=bold
hi User5 guifg=#e4e4e4 guibg=#606060 gui=bold ctermfg=254 ctermbg=241 cterm=bold
hi User6 guifg=#e4e4e4 guibg=#606060 gui=bold ctermfg=254 ctermbg=241 cterm=bold
hi User7 guifg=#e4e4e4 guibg=#606060 gui=bold ctermfg=254 ctermbg=241 cterm=bold
hi User8 guifg=#e4e4e4 guibg=#606060 gui=bold ctermfg=254 ctermbg=241 cterm=bold
hi User9 guifg=#e4e4e4 guibg=#606060 gui=bold ctermfg=254 ctermbg=241 cterm=bold
" Folds
" -----
hi Folded guifg=#F6F3E8 guibg=#444444 gui=NONE
" Invisible Characters
" ------------------
hi NonText guifg=#777777 gui=NONE
hi SpecialKey guifg=#777777 gui=NONE
" Misc
" ----
" directory names and other special names in listings
hi Directory guifg=#A5C261 gui=NONE
" Popup Menu
" ----------
" normal item in popup
hi Pmenu guifg=#F6F3E8 guibg=#444444 gui=NONE ctermfg=white ctermbg=237
" selected item in popup
hi PmenuSel guifg=#000000 guibg=#A5C261 gui=NONE
" scrollbar in popup
hi PMenuSbar guibg=#5A647E gui=NONE
" thumb of the scrollbar in the popup
hi PMenuThumb guibg=#AAAAAA gui=NONE
" Comment
hi Comment guifg=#BC9458 guibg=NONE gui=italic ctermfg=137 cterm=italic
hi Todo guifg=#df5f5f guibg=NONE gui=bold ctermfg=94
"rubyPseudoVariable: nil, self, symbols, etc
hi Constant guifg=#6D9CBE ctermfg=73
" rubyClass, rubyModule, rubyDefine def, end, include, etc
hi Define guifg=#CC7833 ctermfg=173
" Interpolation
hi Delimiter guifg=#519F50
hi WarningMsg guifg=#DA4939 guibg=NONE ctermfg=1 ctermbg=NONE
" Error, rubyInvalidVariable
hi Error guifg=#FFFFFF guibg=#990000 ctermfg=221 ctermbg=88
"rubyFunction
hi! Function guifg=#FFC66D guibg=NONE ctermfg=221 cterm=NONE
" Identifier: @var, @@var, $var, etc
hi Identifier guifg=#d7b0fc guibg=NONE ctermfg=73 cterm=NONE
" Include: include, autoload, extend, load, require
hi Include guifg=#CC7833 guibg=NONE ctermfg=173 cterm=NONE
" Keyword, rubyKeywordAsMethod: alias, undef, super, yield, callcc, caller, lambda, proc
hi Keyword guifg=#d8690f ctermfg=172 cterm=NONE
" same as define
hi Macro guifg=#CC7833 guibg=NONE ctermfg=172
"rubyInteger
hi Number guifg=#A5C261 ctermfg=107
hi Boolean guifg=#47a3e5 ctermfg=107 gui=italic
" #if, #else, #endif
hi PreCondit guifg=#CC7833 guibg=NONE ctermfg=172 cterm=NONE
" generic preprocessor
hi PreProc guifg=#CC7833 guibg=NONE ctermfg=103
" Control, Access, Eval: case, begin, do, for, if unless, while, until else, etc.
hi Statement guifg=#CC7833 guibg=NONE ctermfg=172 cterm=NONE
" String
hi String guifg=#74d155 guibg=NONE ctermfg=107
hi! Title guifg=#FFFFFF guibg=NONE ctermfg=15
" Constant
hi Type guifg=#ff5d4f guibg=NONE gui=NONE
hi PreProc guifg=#ff8700 guibg=NONE ctermfg=208
hi Special guifg=#ff8700 guibg=NONE ctermfg=22
hi Operator guifg=#CC7833 guibg=NONE ctermfg=73
hi Tag guifg=#CC7833 guibg=NONE ctermfg=73
hi Label guifg=#6D9CBE ctermfg=221 gui=bold
" Indentation
hi IndentGuidesOdd ctermbg=239 guibg=#282828
hi IndentGuidesEven ctermbg=237 guibg=#332717
" Diffs
hi DiffAdd guifg=#e4e4e4 guibg=#519F50 ctermfg=254 ctermbg=22
hi DiffDelete guifg=#e4e4e4 guibg=#660000 gui=bold ctermfg=16 ctermbg=52 cterm=bold
hi DiffChange guifg=#FFFFFF guibg=#870087 ctermfg=15 ctermbg=90
hi DiffText guifg=#FFC66D guibg=#FF0000 gui=bold ctermfg=15 ctermbg=9 cterm=bold
hi diffAdded guifg=#008700 ctermfg=28
hi diffRemoved guifg=#800000 ctermfg=1
hi diffNewFile guifg=#FFFFFF guibg=NONE gui=bold ctermfg=15 ctermbg=NONE cterm=bold
hi diffFile guifg=#FFFFFF guibg=NONE gui=bold ctermfg=15 ctermbg=NONE cterm=bold
hi javaScriptOperator guifg=#c9d05c ctermfg=185 guibg=NONE ctermbg=NONE gui=NONE cterm=NONE
hi javaScriptBraces guifg=#dd7927 ctermfg=153 guibg=NONE ctermbg=NONE gui=NONE cterm=NONE
hi javaScriptNull guifg=#dd7927 ctermfg=215 guibg=NONE ctermbg=NONE gui=NONE cterm=NONE
" Ruby
" ----
hi rubyTodo guifg=#fc5858 guibg=NONE gui=bold ctermfg=167 ctermbg=NONE cterm=bold
hi rubyClass guifg=#dd7927 ctermfg=15
hi rubyConstant guifg=#fc5858 ctermfg=167
hi rubyInterpolation guifg=#ea8c3f ctermfg=15
hi rubyBlockParameter guifg=#d7b0fc ctermfg=189
hi rubyPseudoVariable guifg=#47a3e5 ctermfg=221 gui=italic
hi rubySymbol guifg=#6D9CBE ctermfg=73 gui=bold
hi rubyStringDelimiter guifg=#87af5f ctermfg=107
hi rubyInstanceVariable guifg=#d7b0fc ctermfg=189
hi rubyPredefinedConstant guifg=#fc5858 ctermfg=167
hi rubyLocalVariableOrMethod guifg=#d7b0fc ctermfg=189
hi rubyBoolean guifg=#47a3e5 gui=italic
" JAVASCRIPT
"
hi jsFunction guifg=#ff8700 ctermfg=221 gui=italic
hi jsFunctionKey guifg=#ff8700 ctermfg=221 gui=italic
hi jsArrowFunction guifg=#ff8700 ctermfg=221
hi jsObjectKey guifg=#6D9CBE ctermfg=73 gui=bold
hi jsThis guifg=#d7b0fc ctermfg=189 gui=italic
hi jsStorageClass guifg=#fc5858 ctermfg=167 gui=italic
hi jsNull guifg=#ff8700 ctermfg=221 gui=italic
" Typescript
"
hi typescriptArrowFunc guifg=#ff8700 ctermfg=221 gui=italic
hi typescriptIdentifier guifg=#d7b0fc ctermfg=189 gui=italic
hi typescriptAsyncFuncKeyword guifg=#47a3e5 gui=italic
hi typescriptType guifg=#ff8700 ctermfg=167 gui=italic
hi typescriptObjectLabel guifg=#6D9CBE ctermfg=73 gui=bold
" Python
" ------
hi pythonExceptions guifg=#ffaf87 ctermfg=216
hi pythonDoctest guifg=#8787ff ctermfg=105
hi pythonDoctestValue guifg=#87d7af ctermfg=115
" Elixir
"
hi elixirAtom guifg=#6D9CBE ctermfg=221 gui=bold
hi elixirTuple guifg=#6D9CBE ctermfg=221 gui=bold
hi elixirDefine guifg=#CC7833 ctermfg=173 gui=bold
hi elixirPrivateDefine guifg=#CC7833 ctermfg=173 gui=bold
hi elixirModuleDefine guifg=#CC7833 ctermfg=173 gui=bold
" Ember.js
"
hi hbsProperty guifg=#ff8700 ctermfg=221 gui=italic
hi mustacheHandlebars guifg=#CC7833 ctermfg=173 gui=bold
" CSS
hi cssClassName guifg=#FFC66D gui=italic
hi cssIdentifier guifg=#47a3e5 gui=italic
" JSON
hi jsonBoolean guifg=#47a3e5 gui=italic
hi jsonNull guifg=#47a3e5 gui=italic
" yaml
hi yamlKey guifg=#d7b0fc ctermfg=189 gui=bold
" Mail
" ----
hi mailEmail guifg=#87af5f ctermfg=107 gui=italic cterm=underline
hi mailHeaderKey guifg=#ffdf5f ctermfg=221
hi! link mailSubject mailHeaderKey
" Spell
" ----
hi! SpellBad guifg=#df5f87 guibg=NONE gui=NONE ctermfg=160 ctermbg=NONE cterm=underline
hi! SpellRare guifg=#df5f87 guibg=NONE gui=NONE ctermfg=168 ctermbg=NONE cterm=underline
hi! SpellCap guifg=#dfdfff guibg=NONE gui=NONE ctermfg=189 ctermbg=NONE cterm=underline
hi! SpellLocal guifg=#00FFFF guibg=NONE gui=NONE ctermfg=51 ctermbg=NONE cterm=underline
hi! MatchParen guifg=#FFFFFF guibg=#005f5f ctermfg=15 ctermbg=23
hi! Question guifg=#df5f87 guibg=NONE gui=NONE ctermfg=168 ctermbg=NONE cterm=underline
" XML
" ---
hi xmlTag guifg=#dfaf5f ctermfg=179
hi xmlTagName guifg=#dfaf5f ctermfg=179
hi xmlEndTag guifg=#dfaf5f ctermfg=179
hi link htmlTag xmlTag
hi link htmlTagName xmlTagName
hi link htmlEndTag xmlEndTag
hi htmlArg guifg=#ff8700 ctermfg=221 gui=italic
hi checkbox guifg=#3a3a3a guibg=NONE gui=NONE ctermfg=237 ctermbg=NONE cterm=NONE
hi checkboxDone guifg=#15d300 guibg=NONE gui=BOLD ctermfg=82 ctermbg=NONE cterm=BOLD
hi checkboxNotDone guifg=#005fdf guibg=NONE gui=BOLD ctermfg=26 ctermbg=NONE cterm=BOLD

102
vim/colors/sexy-railscasts.vim Executable file
View File

@ -0,0 +1,102 @@
" Name: sexy-railscast vim colorscheme
" Modifier: Oguz Bilgic <fisyonet@gmail.com>
" Url: https://github.com/oguzbilgic/sexy-railscasts-theme
" License: public domain
"
" A GUI Only port of the RailsCasts TextMate theme [1] to Vim.
" Some parts of this theme were borrowed from the well-documented Lucius theme [2].
" Initial file was written by Josh O'Rourke [3] then improved by Oguz Bilgic
"
" [1] http://railscasts.com/about
" [2] http://www.vim.org/scripts/script.php?script_id=2536
" [3] https://github.com/jpo/vim-railscasts-theme
" -----------------------------------------------------------------------------------
" Settings
" -----------------------------------------------------------------------------------
set background=dark
hi clear
if exists("syntax_on")
syntax reset
endif
let g:colors_name = "sexy-railscasts"
" -----------------------------------------------------------------------------------
" Basics
" -----------------------------------------------------------------------------------
hi Normal guifg=#E6E1DC guibg=#222222
hi Cursor guibg=#FFFFFF
hi CursorLine guibg=#333435
hi LineNr guifg=#383838 guibg=#141414
hi SignColumn guibg=#222222
hi NonText guifg=#383838 guibg=#252525
hi Search guibg=#5A647E
hi VertSplit guifg=#383838 guibg=#383838
hi Visual guibg=#5A647E
hi Title guifg=#FFFFFF
" -----------------------------------------------------------------------------------
" Folds
" -----------------------------------------------------------------------------------
hi Folded guifg=#F6F3E8 guibg=#444444 gui=NONE
" -----------------------------------------------------------------------------------
" Misc
" -----------------------------------------------------------------------------------
hi Directory guifg=#A5C261 gui=NONE
" -----------------------------------------------------------------------------------
" Popup Menu
" -----------------------------------------------------------------------------------
hi Pmenu guifg=#F6F3E8 guibg=#444444 gui=NONE
hi PmenuSel guifg=#000000 guibg=#A5C261 gui=NONE
hi PMenuSbar guibg=#5A647E gui=NONE
hi PMenuThumb guibg=#AAAAAA gui=NONE
" -----------------------------------------------------------------------------------
" Syntax
" -----------------------------------------------------------------------------------
hi Comment guifg=#BC9458 gui=italic
hi Todo guifg=#BC9458 guibg=NONE gui=italic
hi Constant guifg=#6D9CBE
hi Define guifg=#CC7833
hi Delimiter guifg=#519F50
hi Error guifg=#FFFFFF guibg=#990000
hi Function guifg=#FFC66D gui=NONE
hi Identifier guifg=#D0D0FF gui=NONE
hi Include guifg=#CC7833 gui=NONE
hi Keyword guifg=#CC7833
hi Macro guifg=#CC7833 gui=NONE
hi Number guifg=#A5C261
hi PreCondit guifg=#CC7833 gui=NONE
hi PreProc guifg=#CC7833 gui=NONE
hi Statement guifg=#CC7833 gui=NONE
hi String guifg=#A5C261
hi Type guifg=#DA4939 gui=NONE
" -----------------------------------------------------------------------------------
" Ruby
" -----------------------------------------------------------------------------------
hi erubyDelimiter guifg=#DA4939
" -----------------------------------------------------------------------------------
" Git
" -----------------------------------------------------------------------------------
hi DiffAdd guifg=#E6E1DC guibg=#144212
hi DiffDelete guifg=#E6E1DC guibg=#660000
" -----------------------------------------------------------------------------------
" Xml
" -----------------------------------------------------------------------------------
hi xmlTag guifg=#E8BF6A
hi xmlTagName guifg=#E8BF6A
hi xmlEndTag guifg=#E8BF6A
" -----------------------------------------------------------------------------------
" Html
" -----------------------------------------------------------------------------------
hi htmlArg guifg=#FFC66D guibg=#222222
hi link htmlTag xmlTag
hi link htmlTagName xmlTagName
hi link htmlEndTag xmlEndTag

View File

@ -0,0 +1,40 @@
" No Arrowkeys
no <up> <NOP>
no <down> <NOP>
no <left> <NOP>
no <right> <NOP>
ino <up> <NOP>
ino <down> <NOP>
ino <left> <NOP>
ino <right> <NOP>
vno <up> <NOP>
vno <down> <NOP>
vno <left> <NOP>
vno <right> <NOP>
" Misc Keybindings
let mapleader = ","
" Window Movement
nnoremap <silent> <C-H> <C-W><C-H>
nnoremap <silent> <C-J> <C-W><C-J>
nnoremap <silent> <C-K> <C-W><C-K>
nnoremap <silent> <C-L> <C-W><C-L>
" Yankstack
nmap <silent> <S-P> <Plug>yankstack_substitute_newer_paste
nmap <silent> <C-P> <Plug>yankstack_substitute_older_paste
" CTRL + Space = Autocomplete
inoremap <C-space> <C-N>
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

106
vim/config/plugin.vim Normal file
View File

@ -0,0 +1,106 @@
" Airline
if !exists('g:airline_symbols')
let g:airline_symbols = {}
endif
let g:airline_left_sep = ''
let g:airline_left_alt_sep = ''
let g:airline_right_sep = ''
let g:airline_right_alt_sep = ''
let g:airline_symbols.branch = ''
let g:airline_symbols.readonly = ''
let g:airline_symbols.linenr = ''
let g:airline#extensions#tabline#left_sep=''
let g:airline#extensions#tabline#left_alt_sep=''
let g:airline_symbols.maxlinenr = ''
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#wordcount#enabled = 1
let g:airline_theme="minimalist"
" 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
if has("autocmd")
autocmd Filetype java setlocal omnifunc=javacomplete#CompleteParamsInfo
endif
" Deoplete
let g:deoplete#enable_at_startup = 1
" NeoComplete
" let g:acp_enableAtStartup = 0
" let g:neocomplete#enable_at_startup = 1
" let g:neocomplete#enable_smart_case = 1
" NerdCommenter
let g:NERDSpaceDelims = 1
let g:NERDCompactSexyComs = 1
let g:NERDDefaultAlign = "left"
let g:NERDCommentEmptyLines = 1
let g:NERDTrimTrailingWhitespace = 1
" NerdTree
" let g:NERDTreeShowHidden = 1
" " let NERDTreeMinimalUI = 1
" let NERDTreeCascadeSingleChildDir = 1
" let NERDTreeCascadeOpenSingleChildDir = 1
" autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
" let g:nerdtree_tabs_open_on_console_startup = 1
" PythonSyntax
let python_highlight_all = 1
" Simpylfold
let g:SimpylFold_docstring_preview = 1
" Supertab
let g:SuperTabDefaultCompletionType = "<c-space>"
" Syntastic
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0
let g:syntastic_mode_map={"mode":"active", "active_filetypes": [], "passive_filetypes": ['tex']}
let g:syntastic_python_checkers=['flake8']
let g:syntastic_python_flake8_args='--ignore=E501,E225'
" UltiSnips
let g:UltiSnipsJumpForwardTrigger="<c-b>"
let g:UltiSnipsJumpBackwardTrigger="<c-z>"
" Whitespace
autocmd BufEnter * EnableStripWhitespaceOnSave
" Yankstack
let g:yankstack_map_keys = 0
call yankstack#setup()

1
vim/plugins/FastFold/.gitignore vendored Normal file
View File

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

View File

@ -0,0 +1,106 @@
# 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

@ -0,0 +1,153 @@
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

@ -0,0 +1,224 @@
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

1
vim/plugins/GoldenView/.gitignore vendored Normal file
View File

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

View File

@ -0,0 +1,31 @@
# 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

@ -0,0 +1,124 @@
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

@ -0,0 +1,102 @@
# 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

@ -0,0 +1,343 @@
# 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

@ -0,0 +1,54 @@
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

@ -0,0 +1,529 @@
" =============== ============================================================
" 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

@ -0,0 +1,126 @@
" =============== ============================================================
" 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

@ -0,0 +1,310 @@
" =============== ============================================================
" 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

@ -0,0 +1,69 @@
" =============== ============================================================
" 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

@ -0,0 +1,222 @@
" =============== ============================================================
" 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

@ -0,0 +1,94 @@
" =============== ============================================================
" 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

@ -0,0 +1,331 @@
" =============== ============================================================
" 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

@ -0,0 +1,78 @@
" =============== ============================================================
" 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

@ -0,0 +1,86 @@
" =============== ============================================================
" 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

@ -0,0 +1,50 @@
" =============== ============================================================
" 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

@ -0,0 +1,432 @@
" =============== ============================================================
" 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

@ -0,0 +1,366 @@
*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

@ -0,0 +1,177 @@
" =============== ============================================================
" 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

@ -0,0 +1,5 @@
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
vim/plugins/auto-pairs/.gitignore vendored Normal file
View File

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

View File

@ -0,0 +1,325 @@
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

@ -0,0 +1,356 @@
*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

@ -0,0 +1,582 @@
" 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

View File

@ -0,0 +1,44 @@
# Problem summary
## Expected
## Environment Information
* OS:
* Neovim version:
## Provide a minimal init.vim with less than 50 lines (required)
```vim
" Use the following as a template.
set runtimepath+=~/path/to/deoplete.nvim/
set runtimepath+=~/path/to/deoplete-jedi/
let g:deoplete#enable_at_startup = 1
call deoplete#custom#set('jedi', 'debug_enabled', 1)
call deoplete#enable_logging('DEBUG', '/tmp/deoplete.log')
```
## Generate logfiles if appropriate
1. export NVIM_PYTHON_LOG_FILE=/tmp/nvim-log
2. export NVIM_PYTHON_LOG_LEVEL=DEBUG
3. nvim -u minimal.vimrc
Then look at and attach the files `/tmp/nvim-log_{PID}` and
`/tmp/deoplete.log` here.
## Steps to reproduce the issue after starting Neovim (required)
1.
2.
3.
## Screen shot (if possible)
## Upload the logfile(s)

66
vim/plugins/deoplete-jedi/.gitignore vendored Normal file
View File

@ -0,0 +1,66 @@
### https://raw.github.com/github/gitignore//Python.gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
#Ipython Notebook
.ipynb_checkpoints
.-rplugin~

6
vim/plugins/deoplete-jedi/.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[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

@ -0,0 +1,34 @@
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

@ -0,0 +1,14 @@
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

@ -0,0 +1,21 @@
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

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

View File

@ -0,0 +1,86 @@
# 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

@ -0,0 +1,10 @@
# 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

@ -0,0 +1,13 @@
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

@ -0,0 +1,290 @@
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

@ -0,0 +1,451 @@
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

@ -0,0 +1,9 @@
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

@ -0,0 +1,63 @@
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

@ -0,0 +1,576 @@
"""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

@ -0,0 +1,90 @@
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

@ -0,0 +1,85 @@
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

@ -0,0 +1,19 @@
[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

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

View File

@ -0,0 +1,30 @@
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

@ -0,0 +1,49 @@
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

@ -0,0 +1,87 @@
.. :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

@ -0,0 +1,8 @@
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

@ -0,0 +1,24 @@
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

@ -0,0 +1,15 @@
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

@ -0,0 +1,215 @@
###################################################################
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

@ -0,0 +1,72 @@
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

@ -0,0 +1,52 @@
#!/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

@ -0,0 +1,153 @@
# 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

@ -0,0 +1,14 @@
Installation
------------
Install the graphviz library::
sudo apt-get install graphviz
Install sphinx::
sudo pip install sphinx
You might also need to install the Python graphviz interface::
sudo pip install graphviz

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,3 @@
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.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,4 @@
<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

@ -0,0 +1,3 @@
<p class="logo"><a href="{{ pathto(master_doc) }}">
<img class="logo" src="{{ pathto('_static/logo.png', 1) }}" alt="Logo"/>
</a></p>

View File

@ -0,0 +1,37 @@
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

@ -0,0 +1,28 @@
{%- 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

@ -0,0 +1,19 @@
<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

@ -0,0 +1,394 @@
/*
* 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

@ -0,0 +1,70 @@
/*
* 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

@ -0,0 +1,9 @@
[theme]
inherit = basic
stylesheet = flasky.css
pygments_style = flask_theme_support.FlaskyStyle
[options]
index_logo =
index_logo_height = 120px
touch_icon =

View File

@ -0,0 +1,125 @@
"""
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

@ -0,0 +1,291 @@
# -*- 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

@ -0,0 +1,244 @@
.. 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

@ -0,0 +1,263 @@
.. 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

@ -0,0 +1,83 @@
.. 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

@ -0,0 +1,36 @@
.. _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

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

View File

@ -0,0 +1,100 @@
.. 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

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

View File

@ -0,0 +1,106 @@
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

@ -0,0 +1,40 @@
.. 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

View File

@ -0,0 +1,122 @@
.. include:: ../global.rst
End User Usage
==============
If you are a not an IDE Developer, the odds are that you just want to use
|jedi| as a browser plugin or in the shell. Yes that's :ref:`also possible
<repl-completion>`!
|jedi| is relatively young and can be used in a variety of Plugins and
Software. If your Editor/IDE is not among them, recommend |jedi| to your IDE
developers.
.. _editor-plugins:
Editor Plugins
--------------
Vim:
- jedi-vim_
- YouCompleteMe_
- deoplete-jedi_
Emacs:
- Jedi.el_
- elpy_
- anaconda-mode_
Sublime Text 2/3:
- SublimeJEDI_ (ST2 & ST3)
- anaconda_ (only ST3)
SynWrite:
- SynJedi_
TextMate:
- Textmate_ (Not sure if it's actually working)
Kate:
- Kate_ version 4.13+ `supports it natively
<https://projects.kde.org/projects/kde/applications/kate/repository/entry/addons/kate/pate/src/plugins/python_autocomplete_jedi.py?rev=KDE%2F4.13>`__,
you have to enable it, though.
Visual Studio Code:
- `Python Extension`_
Atom:
- autocomplete-python-jedi_
SourceLair:
- SourceLair_
GNOME Builder:
- `GNOME Builder`_ `supports it natively
<https://git.gnome.org/browse/gnome-builder/tree/plugins/jedi>`__,
and is enabled by default.
Gedit:
- gedi_
Eric IDE:
- `Eric IDE`_ (Available as a plugin)
Web Debugger:
- wdb_
and many more!
.. _repl-completion:
Tab Completion in the Python Shell
----------------------------------
Starting with Ipython `6.0.0` Jedi is a dependency of IPython. Autocompletion
in IPython is therefore possible without additional configuration.
There are two different options how you can use Jedi autocompletion in
your Python interpreter. One with your custom ``$HOME/.pythonrc.py`` file
and one that uses ``PYTHONSTARTUP``.
Using ``PYTHONSTARTUP``
~~~~~~~~~~~~~~~~~~~~~~~
.. automodule:: jedi.api.replstartup
Using a custom ``$HOME/.pythonrc.py``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. autofunction:: jedi.utils.setup_readline
.. _jedi-vim: https://github.com/davidhalter/jedi-vim
.. _youcompleteme: http://valloric.github.io/YouCompleteMe/
.. _deoplete-jedi: https://github.com/zchee/deoplete-jedi
.. _Jedi.el: https://github.com/tkf/emacs-jedi
.. _elpy: https://github.com/jorgenschaefer/elpy
.. _anaconda-mode: https://github.com/proofit404/anaconda-mode
.. _sublimejedi: https://github.com/srusskih/SublimeJEDI
.. _anaconda: https://github.com/DamnWidget/anaconda
.. _SynJedi: http://uvviewsoft.com/synjedi/
.. _wdb: https://github.com/Kozea/wdb
.. _TextMate: https://github.com/lawrenceakka/python-jedi.tmbundle
.. _kate: http://kate-editor.org/
.. _autocomplete-python-jedi: https://atom.io/packages/autocomplete-python-jedi
.. _SourceLair: https://www.sourcelair.com
.. _GNOME Builder: https://wiki.gnome.org/Apps/Builder/
.. _gedi: https://github.com/isamert/gedi
.. _Eric IDE: http://eric-ide.python-projects.org
.. _Python Extension: https://marketplace.visualstudio.com/items?itemName=donjayamanne.python

View File

@ -0,0 +1,3 @@
:orphan:
.. |jedi| replace:: *Jedi*

View File

@ -0,0 +1,40 @@
.. include global.rst
Jedi - an awesome autocompletion/static analysis library for Python
===================================================================
Release v\ |release|. (:doc:`Installation <docs/installation>`)
.. automodule:: jedi
Autocompletion can look like this (e.g. VIM plugin):
.. figure:: _screenshots/screenshot_complete.png
.. _toc:
Docs
----
.. toctree::
:maxdepth: 2
docs/usage
docs/installation
docs/features
docs/plugin-api
docs/plugin-api-classes
docs/settings
docs/development
docs/testing
.. _resources:
Resources
---------
- `Source Code on Github <https://github.com/davidhalter/jedi>`_
- `Travis Testing <https://travis-ci.org/davidhalter/jedi>`_
- `Python Package Index <http://pypi.python.org/pypi/jedi/>`_

View File

@ -0,0 +1,43 @@
"""
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.
To give you a simple example how you can use the Jedi library, here is an
example for the autocompletion feature:
>>> import jedi
>>> source = '''
... import datetime
... datetime.da'''
>>> script = jedi.Script(source, 3, len('datetime.da'), 'example.py')
>>> script
<Script: 'example.py'>
>>> completions = script.completions()
>>> completions #doctest: +ELLIPSIS
[<Completion: date>, <Completion: datetime>, ...]
>>> print(completions[0].complete)
te
>>> print(completions[0].name)
date
As you see Jedi is pretty simple and allows you to concentrate on writing a
good text editor, while still having very good IDE features for Python.
"""
__version__ = '0.11.0'
from jedi.api import Script, Interpreter, set_debug_function, \
preload_module, names
from jedi import settings

View File

@ -0,0 +1,48 @@
import sys
from os.path import join, dirname, abspath, isdir
def _start_linter():
"""
This is a pre-alpha API. You're not supposed to use it at all, except for
testing. It will very likely change.
"""
import jedi
if '--debug' in sys.argv:
jedi.set_debug_function()
for path in sys.argv[2:]:
if path.startswith('--'):
continue
if isdir(path):
import fnmatch
import os
paths = []
for root, dirnames, filenames in os.walk(path):
for filename in fnmatch.filter(filenames, '*.py'):
paths.append(os.path.join(root, filename))
else:
paths = [path]
try:
for path in paths:
for error in jedi.Script(path=path)._analysis():
print(error)
except Exception:
if '--pdb' in sys.argv:
import traceback
traceback.print_exc()
import pdb
pdb.post_mortem()
else:
raise
if len(sys.argv) == 2 and sys.argv[1] == 'repl':
# don't want to use __main__ only for repl yet, maybe we want to use it for
# something else. So just use the keyword ``repl`` for now.
print(join(dirname(abspath(__file__)), 'api', 'replstartup.py'))
elif len(sys.argv) > 1 and sys.argv[1] == 'linter':
_start_linter()

View File

@ -0,0 +1,299 @@
"""
To ensure compatibility from Python ``2.6`` - ``3.3``, a module has been
created. Clearly there is huge need to use conforming syntax.
"""
import sys
import imp
import os
import re
import pkgutil
import warnings
try:
import importlib
except ImportError:
pass
# Cannot use sys.version.major and minor names, because in Python 2.6 it's not
# a namedtuple.
is_py3 = sys.version_info[0] >= 3
is_py33 = is_py3 and sys.version_info[1] >= 3
is_py34 = is_py3 and sys.version_info[1] >= 4
is_py35 = is_py3 and sys.version_info[1] >= 5
is_py26 = not is_py3 and sys.version_info[1] < 7
py_version = int(str(sys.version_info[0]) + str(sys.version_info[1]))
class DummyFile(object):
def __init__(self, loader, string):
self.loader = loader
self.string = string
def read(self):
return self.loader.get_source(self.string)
def close(self):
del self.loader
def find_module_py34(string, path=None, fullname=None):
implicit_namespace_pkg = False
spec = None
loader = None
spec = importlib.machinery.PathFinder.find_spec(string, path)
if hasattr(spec, 'origin'):
origin = spec.origin
implicit_namespace_pkg = origin == 'namespace'
# We try to disambiguate implicit namespace pkgs with non implicit namespace pkgs
if implicit_namespace_pkg:
fullname = string if not path else fullname
implicit_ns_info = ImplicitNSInfo(fullname, spec.submodule_search_locations._path)
return None, implicit_ns_info, False
# we have found the tail end of the dotted path
if hasattr(spec, 'loader'):
loader = spec.loader
return find_module_py33(string, path, loader)
def find_module_py33(string, path=None, loader=None, fullname=None):
loader = loader or importlib.machinery.PathFinder.find_module(string, path)
if loader is None and path is None: # Fallback to find builtins
try:
with warnings.catch_warnings(record=True):
# Mute "DeprecationWarning: Use importlib.util.find_spec()
# instead." While we should replace that in the future, it's
# probably good to wait until we deprecate Python 3.3, since
# it was added in Python 3.4 and find_loader hasn't been
# removed in 3.6.
loader = importlib.find_loader(string)
except ValueError as e:
# See #491. Importlib might raise a ValueError, to avoid this, we
# just raise an ImportError to fix the issue.
raise ImportError("Originally " + repr(e))
if loader is None:
raise ImportError("Couldn't find a loader for {0}".format(string))
try:
is_package = loader.is_package(string)
if is_package:
if hasattr(loader, 'path'):
module_path = os.path.dirname(loader.path)
else:
# At least zipimporter does not have path attribute
module_path = os.path.dirname(loader.get_filename(string))
if hasattr(loader, 'archive'):
module_file = DummyFile(loader, string)
else:
module_file = None
else:
module_path = loader.get_filename(string)
module_file = DummyFile(loader, string)
except AttributeError:
# ExtensionLoader has not attribute get_filename, instead it has a
# path attribute that we can use to retrieve the module path
try:
module_path = loader.path
module_file = DummyFile(loader, string)
except AttributeError:
module_path = string
module_file = None
finally:
is_package = False
if hasattr(loader, 'archive'):
module_path = loader.archive
return module_file, module_path, is_package
def find_module_pre_py33(string, path=None, fullname=None):
try:
module_file, module_path, description = imp.find_module(string, path)
module_type = description[2]
return module_file, module_path, module_type is imp.PKG_DIRECTORY
except ImportError:
pass
if path is None:
path = sys.path
for item in path:
loader = pkgutil.get_importer(item)
if loader:
try:
loader = loader.find_module(string)
if loader:
is_package = loader.is_package(string)
is_archive = hasattr(loader, 'archive')
try:
module_path = loader.get_filename(string)
except AttributeError:
# fallback for py26
try:
module_path = loader._get_filename(string)
except AttributeError:
continue
if is_package:
module_path = os.path.dirname(module_path)
if is_archive:
module_path = loader.archive
file = None
if not is_package or is_archive:
file = DummyFile(loader, string)
return (file, module_path, is_package)
except ImportError:
pass
raise ImportError("No module named {0}".format(string))
find_module = find_module_py33 if is_py33 else find_module_pre_py33
find_module = find_module_py34 if is_py34 else find_module
find_module.__doc__ = """
Provides information about a module.
This function isolates the differences in importing libraries introduced with
python 3.3 on; it gets a module name and optionally a path. It will return a
tuple containin an open file for the module (if not builtin), the filename
or the name of the module if it is a builtin one and a boolean indicating
if the module is contained in a package.
"""
class ImplicitNSInfo(object):
"""Stores information returned from an implicit namespace spec"""
def __init__(self, name, paths):
self.name = name
self.paths = paths
# unicode function
try:
unicode = unicode
except NameError:
unicode = str
# exec function
if is_py3:
def exec_function(source, global_map):
exec(source, global_map)
else:
eval(compile("""def exec_function(source, global_map):
exec source in global_map """, 'blub', 'exec'))
# re-raise function
if is_py3:
def reraise(exception, traceback):
raise exception.with_traceback(traceback)
else:
eval(compile("""
def reraise(exception, traceback):
raise exception, None, traceback
""", 'blub', 'exec'))
reraise.__doc__ = """
Re-raise `exception` with a `traceback` object.
Usage::
reraise(Exception, sys.exc_info()[2])
"""
class Python3Method(object):
def __init__(self, func):
self.func = func
def __get__(self, obj, objtype):
if obj is None:
return lambda *args, **kwargs: self.func(*args, **kwargs)
else:
return lambda *args, **kwargs: self.func(obj, *args, **kwargs)
def use_metaclass(meta, *bases):
""" Create a class with a metaclass. """
if not bases:
bases = (object,)
return meta("HackClass", bases, {})
try:
encoding = sys.stdout.encoding
if encoding is None:
encoding = 'utf-8'
except AttributeError:
encoding = 'ascii'
def u(string):
"""Cast to unicode DAMMIT!
Written because Python2 repr always implicitly casts to a string, so we
have to cast back to a unicode (and we now that we always deal with valid
unicode, because we check that in the beginning).
"""
if is_py3:
return str(string)
if not isinstance(string, unicode):
return unicode(str(string), 'UTF-8')
return string
try:
import builtins # module name in python 3
except ImportError:
import __builtin__ as builtins
import ast
def literal_eval(string):
# py3.0, py3.1 and py32 don't support unicode literals. Support those, I
# don't want to write two versions of the tokenizer.
if is_py3 and sys.version_info.minor < 3:
if re.match('[uU][\'"]', string):
string = string[1:]
return ast.literal_eval(string)
try:
from itertools import zip_longest
except ImportError:
from itertools import izip_longest as zip_longest # Python 2
try:
FileNotFoundError = FileNotFoundError
except NameError:
FileNotFoundError = IOError
def no_unicode_pprint(dct):
"""
Python 2/3 dict __repr__ may be different, because of unicode differens
(with or without a `u` prefix). Normally in doctests we could use `pprint`
to sort dicts and check for equality, but here we have to write a separate
function to do that.
"""
import pprint
s = pprint.pformat(dct)
print(re.sub("u'", "'", s))
def utf8_repr(func):
"""
``__repr__`` methods in Python 2 don't allow unicode objects to be
returned. Therefore cast them to utf-8 bytes in this decorator.
"""
def wrapper(self):
result = func(self)
if isinstance(result, unicode):
return result.encode('utf-8')
else:
return result
if is_py3:
return func
else:
return wrapper

View File

@ -0,0 +1,458 @@
"""
The API basically only provides one class. You can create a :class:`Script` and
use its methods.
Additionally you can add a debug function with :func:`set_debug_function`.
Alternatively, if you don't need a custom function and are happy with printing
debug messages to stdout, simply call :func:`set_debug_function` without
arguments.
.. warning:: Please, note that Jedi is **not thread safe**.
"""
import os
import sys
import parso
from parso.python import tree
from parso import python_bytes_to_unicode, split_lines
from jedi.parser_utils import get_executable_nodes, get_statement_of_position
from jedi import debug
from jedi import settings
from jedi import cache
from jedi.api import classes
from jedi.api import interpreter
from jedi.api import usages
from jedi.api import helpers
from jedi.api.completion import Completion
from jedi.evaluate import Evaluator
from jedi.evaluate import representation as er
from jedi.evaluate import imports
from jedi.evaluate.param import try_iter_content
from jedi.evaluate.helpers import get_module_names, evaluate_call_of_leaf
from jedi.evaluate.sys_path import get_venv_path, dotted_path_in_sys_path
from jedi.evaluate.iterable import unpack_tuple_to_dict
from jedi.evaluate.filters import TreeNameDefinition
# Jedi uses lots and lots of recursion. By setting this a little bit higher, we
# can remove some "maximum recursion depth" errors.
sys.setrecursionlimit(3000)
class Script(object):
"""
A Script is the base for completions, goto or whatever you want to do with
|jedi|.
You can either use the ``source`` parameter or ``path`` to read a file.
Usually you're going to want to use both of them (in an editor).
The script might be analyzed in a different ``sys.path`` than |jedi|:
- if `sys_path` parameter is not ``None``, it will be used as ``sys.path``
for the script;
- if `sys_path` parameter is ``None`` and ``VIRTUAL_ENV`` environment
variable is defined, ``sys.path`` for the specified environment will be
guessed (see :func:`jedi.evaluate.sys_path.get_venv_path`) and used for
the script;
- otherwise ``sys.path`` will match that of |jedi|.
:param source: The source code of the current file, separated by newlines.
:type source: str
:param line: The line to perform actions on (starting with 1).
:type line: int
:param column: The column of the cursor (starting with 0).
:type column: int
:param path: The path of the file in the file system, or ``''`` if
it hasn't been saved yet.
:type path: str or None
:param encoding: The encoding of ``source``, if it is not a
``unicode`` object (default ``'utf-8'``).
:type encoding: str
:param source_encoding: The encoding of ``source``, if it is not a
``unicode`` object (default ``'utf-8'``).
:type encoding: str
:param sys_path: ``sys.path`` to use during analysis of the script
:type sys_path: list
"""
def __init__(self, source=None, line=None, column=None, path=None,
encoding='utf-8', sys_path=None):
self._orig_path = path
# An empty path (also empty string) should always result in no path.
self.path = os.path.abspath(path) if path else None
if source is None:
# TODO add a better warning than the traceback!
with open(path, 'rb') as f:
source = f.read()
# TODO do we really want that?
self._source = python_bytes_to_unicode(source, encoding, errors='replace')
self._code_lines = split_lines(self._source)
line = max(len(self._code_lines), 1) if line is None else line
if not (0 < line <= len(self._code_lines)):
raise ValueError('`line` parameter is not in a valid range.')
line_len = len(self._code_lines[line - 1])
column = line_len if column is None else column
if not (0 <= column <= line_len):
raise ValueError('`column` parameter is not in a valid range.')
self._pos = line, column
self._path = path
cache.clear_time_caches()
debug.reset_time()
# Load the Python grammar of the current interpreter.
self._grammar = parso.load_grammar()
if sys_path is None:
venv = os.getenv('VIRTUAL_ENV')
if venv:
sys_path = list(get_venv_path(venv))
self._evaluator = Evaluator(self._grammar, sys_path=sys_path)
debug.speed('init')
@cache.memoize_method
def _get_module_node(self):
return self._grammar.parse(
code=self._source,
path=self.path,
cache=False, # No disk cache, because the current script often changes.
diff_cache=True,
cache_path=settings.cache_directory
)
@cache.memoize_method
def _get_module(self):
module = er.ModuleContext(
self._evaluator,
self._get_module_node(),
self.path
)
if self.path is not None:
name = dotted_path_in_sys_path(self._evaluator.sys_path, self.path)
if name is not None:
imports.add_module(self._evaluator, name, module)
return module
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, repr(self._orig_path))
def completions(self):
"""
Return :class:`classes.Completion` objects. Those objects contain
information about the completions, more than just names.
:return: Completion objects, sorted by name and __ comes last.
:rtype: list of :class:`classes.Completion`
"""
debug.speed('completions start')
completion = Completion(
self._evaluator, self._get_module(), self._code_lines,
self._pos, self.call_signatures
)
completions = completion.completions()
debug.speed('completions end')
return completions
def goto_definitions(self):
"""
Return the definitions of a the path under the cursor. goto function!
This follows complicated paths and returns the end, not the first
definition. The big difference between :meth:`goto_assignments` and
:meth:`goto_definitions` is that :meth:`goto_assignments` doesn't
follow imports and statements. Multiple objects may be returned,
because Python itself is a dynamic language, which means depending on
an option you can have two different versions of a function.
:rtype: list of :class:`classes.Definition`
"""
module_node = self._get_module_node()
leaf = module_node.get_name_of_position(self._pos)
if leaf is None:
leaf = module_node.get_leaf_for_position(self._pos)
if leaf is None:
return []
context = self._evaluator.create_context(self._get_module(), leaf)
definitions = helpers.evaluate_goto_definition(self._evaluator, context, leaf)
names = [s.name for s in definitions]
defs = [classes.Definition(self._evaluator, name) for name in names]
# The additional set here allows the definitions to become unique in an
# API sense. In the internals we want to separate more things than in
# the API.
return helpers.sorted_definitions(set(defs))
def goto_assignments(self, follow_imports=False):
"""
Return the first definition found, while optionally following imports.
Multiple objects may be returned, because Python itself is a
dynamic language, which means depending on an option you can have two
different versions of a function.
:rtype: list of :class:`classes.Definition`
"""
def filter_follow_imports(names, check):
for name in names:
if check(name):
for result in filter_follow_imports(name.goto(), check):
yield result
else:
yield name
names = self._goto()
if follow_imports:
def check(name):
if isinstance(name, er.ModuleName):
return False
return name.api_type == 'module'
else:
def check(name):
return isinstance(name, imports.SubModuleName)
names = filter_follow_imports(names, check)
defs = [classes.Definition(self._evaluator, d) for d in set(names)]
return helpers.sorted_definitions(defs)
def _goto(self):
"""
Used for goto_assignments and usages.
"""
name = self._get_module_node().get_name_of_position(self._pos)
if name is None:
return []
context = self._evaluator.create_context(self._get_module(), name)
return list(self._evaluator.goto(context, name))
def usages(self, additional_module_paths=()):
"""
Return :class:`classes.Definition` objects, which contain all
names that point to the definition of the name under the cursor. This
is very useful for refactoring (renaming), or to show all usages of a
variable.
.. todo:: Implement additional_module_paths
:rtype: list of :class:`classes.Definition`
"""
temp, settings.dynamic_flow_information = \
settings.dynamic_flow_information, False
try:
module_node = self._get_module_node()
user_stmt = get_statement_of_position(module_node, self._pos)
definition_names = self._goto()
if not definition_names and isinstance(user_stmt, tree.Import):
# For not defined imports (goto doesn't find something, we take
# the name as a definition. This is enough, because every name
# points to it.
name = user_stmt.get_name_of_position(self._pos)
if name is None:
# Must be syntax
return []
definition_names = [TreeNameDefinition(self._get_module(), name)]
if not definition_names:
# Without a definition for a name we cannot find references.
return []
definition_names = usages.resolve_potential_imports(self._evaluator,
definition_names)
modules = set([d.get_root_context() for d in definition_names])
modules.add(self._get_module())
definitions = usages.usages(self._evaluator, definition_names, modules)
finally:
settings.dynamic_flow_information = temp
return helpers.sorted_definitions(set(definitions))
def call_signatures(self):
"""
Return the function object of the call you're currently in.
E.g. if the cursor is here::
abs(# <-- cursor is here
This would return the ``abs`` function. On the other hand::
abs()# <-- cursor is here
This would return an empty list..
:rtype: list of :class:`classes.CallSignature`
"""
call_signature_details = \
helpers.get_call_signature_details(self._get_module_node(), self._pos)
if call_signature_details is None:
return []
context = self._evaluator.create_context(
self._get_module(),
call_signature_details.bracket_leaf
)
definitions = helpers.cache_call_signatures(
self._evaluator,
context,
call_signature_details.bracket_leaf,
self._code_lines,
self._pos
)
debug.speed('func_call followed')
return [classes.CallSignature(self._evaluator, d.name,
call_signature_details.bracket_leaf.start_pos,
call_signature_details.call_index,
call_signature_details.keyword_name_str)
for d in definitions if hasattr(d, 'py__call__')]
def _analysis(self):
self._evaluator.is_analysis = True
module_node = self._get_module_node()
self._evaluator.analysis_modules = [module_node]
try:
for node in get_executable_nodes(module_node):
context = self._get_module().create_context(node)
if node.type in ('funcdef', 'classdef'):
# TODO This is stupid, should be private
from jedi.evaluate.finder import _name_to_types
# Resolve the decorators.
_name_to_types(self._evaluator, context, node.children[1])
elif isinstance(node, tree.Import):
import_names = set(node.get_defined_names())
if node.is_nested():
import_names |= set(path[-1] for path in node.get_paths())
for n in import_names:
imports.infer_import(context, n)
elif node.type == 'expr_stmt':
types = context.eval_node(node)
for testlist in node.children[:-1:2]:
# Iterate tuples.
unpack_tuple_to_dict(context, types, testlist)
else:
if node.type == 'name':
defs = self._evaluator.goto_definitions(context, node)
else:
defs = evaluate_call_of_leaf(context, node)
try_iter_content(defs)
self._evaluator.reset_recursion_limitations()
ana = [a for a in self._evaluator.analysis if self.path == a.path]
return sorted(set(ana), key=lambda x: x.line)
finally:
self._evaluator.is_analysis = False
class Interpreter(Script):
"""
Jedi API for Python REPLs.
In addition to completion of simple attribute access, Jedi
supports code completion based on static code analysis.
Jedi can complete attributes of object which is not initialized
yet.
>>> from os.path import join
>>> namespace = locals()
>>> script = Interpreter('join("").up', [namespace])
>>> print(script.completions()[0].name)
upper
"""
def __init__(self, source, namespaces, **kwds):
"""
Parse `source` and mixin interpreted Python objects from `namespaces`.
:type source: str
:arg source: Code to parse.
:type namespaces: list of dict
:arg namespaces: a list of namespace dictionaries such as the one
returned by :func:`locals`.
Other optional arguments are same as the ones for :class:`Script`.
If `line` and `column` are None, they are assumed be at the end of
`source`.
"""
try:
namespaces = [dict(n) for n in namespaces]
except Exception:
raise TypeError("namespaces must be a non-empty list of dicts.")
super(Interpreter, self).__init__(source, **kwds)
self.namespaces = namespaces
def _get_module(self):
parser_module = super(Interpreter, self)._get_module_node()
return interpreter.MixedModuleContext(
self._evaluator,
parser_module,
self.namespaces,
path=self.path
)
def names(source=None, path=None, encoding='utf-8', all_scopes=False,
definitions=True, references=False):
"""
Returns a list of `Definition` objects, containing name parts.
This means you can call ``Definition.goto_assignments()`` and get the
reference of a name.
The parameters are the same as in :py:class:`Script`, except or the
following ones:
:param all_scopes: If True lists the names of all scopes instead of only
the module namespace.
:param definitions: If True lists the names that have been defined by a
class, function or a statement (``a = b`` returns ``a``).
:param references: If True lists all the names that are not listed by
``definitions=True``. E.g. ``a = b`` returns ``b``.
"""
def def_ref_filter(_def):
is_def = _def._name.tree_name.is_definition()
return definitions and is_def or references and not is_def
# Set line/column to a random position, because they don't matter.
script = Script(source, line=1, column=0, path=path, encoding=encoding)
module_context = script._get_module()
defs = [
classes.Definition(
script._evaluator,
TreeNameDefinition(
module_context.create_context(name if name.parent.type == 'file_input' else name.parent),
name
)
) for name in get_module_names(script._get_module_node(), all_scopes)
]
return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column))
def preload_module(*modules):
"""
Preloading modules tells Jedi to load a module now, instead of lazy parsing
of modules. Usful for IDEs, to control which modules to load on startup.
:param modules: different module names, list of string.
"""
for m in modules:
s = "import %s as x; x." % m
Script(s, 1, len(s), None).completions()
def set_debug_function(func_cb=debug.print_to_stdout, warnings=True,
notices=True, speed=True):
"""
Define a callback debug function to get all the debug messages.
If you don't specify any arguments, debug messages will be printed to stdout.
:param func_cb: The callback function for debug messages, with n params.
"""
debug.debug_function = func_cb
debug.enable_warning = warnings
debug.enable_notice = notices
debug.enable_speed = speed

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