" Set the search path to the folder of the current file and its sub-folders setlocal path=.,** " Exclude Python's compiled files from searches setlocal wildignore=*/__pycache__/*,*.pyc " Resolve Python imports to files, " so that `gf` jumps to the module under the cursor " " Examples, with the cursor on the marked word: " - `from lalib.elements import galois` => lalib/elements/galois.py " - `from lalib.elements import ...` => lalib/elements/__init__.py " - `import lalib.config` => lalib/config.py " if !exists('*s:PyGoToFile') " Build the dotted module path for the word under the cursor function! s:PyModuleUnderCursor() let l:word = expand('') let l:from = matchstr(getline('.'), '^\s*from\s\+\zs[A-Za-z0-9_.]\+') let l:imp = matchstr(getline('.'), '^\s*import\s\+\zs[A-Za-z0-9_.]\+') let l:base = !empty(l:from) ? l:from : l:imp if empty(l:base) return '' endif let l:parts = split(l:base, '\.') let l:idx = index(l:parts, l:word) if l:idx >= 0 " Cursor within the dotted prefix => Truncate there return join(l:parts[0:l:idx], '/') elseif !empty(l:from) " Cursor on an imported name => Append it return join(l:parts, '/') . '/' . l:word endif return '' endfunction function! s:PyFindFile(mod) for l:candidate in [a:mod . '.py', a:mod . '/__init__.py'] let l:found = findfile(l:candidate) " search the `path` if !empty(l:found) return l:found endif endfor return '' endfunction function! s:PyGoToFile() let l:mod = s:PyModuleUnderCursor() let l:file = empty(l:mod) ? '' : s:PyFindFile(l:mod) if empty(l:file) echohl ErrorMsg | echo 'No module file for: ' . l:mod | echohl NONE return endif execute 'edit ' . fnameescape(l:file) endfunction endif " jumps back nnoremap gf :call PyGoToFile() " Find `def`s and `class`es with [d and [D setlocal define=^\\s*\\<\\(def\\|class\\)\\> " Indentation settings come from ~/.config/vim/vimrc, and " `smartindent` is left off as it interferes with VIM's Python indent script " Auto-wrap lines after 88 characters, which is PEP8's limit plus 10%, " a more relaxed boundary which occasionally may be used setlocal textwidth=88 " Make column 80 red to indicate PEP8's maximum allowed line length setlocal colorcolumn=80 " Additionally, give every character beyond 80 columns a red background " (matches are window-local, so re-apply them per buffer) highlight ColorColumn ctermbg=DarkRed augroup python_overlength autocmd! * autocmd BufEnter call matchadd('ErrorMsg', '\%>80v.\+', 100) autocmd BufLeave call clearmatches() augroup END call matchadd('ErrorMsg', '\%>80v.\+', 100) " Show line numbers by default for .py files let g:show_numbers=1 call ShowLineNumbers()