-""" vim dir in xdg config
+""" paths
+"" config dir in xdg config
let x = ($XDG_CONFIG_HOME??($HOME.'/.config')).'/vim'
execute 'set runtimepath='.x.','.&runtimepath.','.x.'/after'
execute 'set packpath='.x.','.&packpath.','.x.'/after'
-""" vim-only defaults
-if !has('nvim')
- " neovim defaults are already set
- source $VIMRUNTIME/defaults.vim
-
- " packages
- packadd matchit
- packadd editorconfig
-
- " options
- set hlsearch
- set autoindent
-endif
-
-""" dir for state files in xdg state
+"" state files in xdg state
let x = ($XDG_STATE_HOME??($HOME.'/.local/state')).'/vim'
if !isdirectory(x)
call mkdir(x, 'p', 0700)
endif
-" NOTE: backup files in vim state dir for both vim and neovim
+" backup
+" NOTE: keep backup files in vim state dir for both vim and neovim
let y = x.'/backup'
if !isdirectory(y)
call mkdir(y, 'p', 0700)
set backup backupcopy=yes
" NOTE: neovim uses ShaDa (SHAred DAta) format for viminfo and swap, and uses a
-" different version for undo files, so these types of files when created
-" by vim cannot be used with neovim, and the 'viminfofile', 'directory',
-" and 'undodir' directories cannot be shared.
+" different version of undo file, so these types of files when created by
+" vim cannot be used with neovim, and the 'viminfofile', 'directory', and
+" 'undodir' directories cannot be shared.
" NOTE: neovim has a nice default for these directories and files so
" customizing them is not necessary for it.
if !has('nvim')
+ " viminfo
" NOTE: 'viminfofile' is a deprecated alias for 'shada' in neovim
execute 'set viminfofile='.x.'/.viminfo'
+ " swap
let y = x.'/swap'
if !isdirectory(y)
call mkdir(y, 'p', 0700)
endif
execute 'set directory='.y.'//'
+ " undo
let y = x.'/undo'
if !isdirectory(y)
call mkdir(y, 'p', 0700)
execute 'set undodir='.y.'//'
endif
-autocmd BufNew * set undofile
-
unlet x
unlet y
-""" options
-autocmd VimEnter,WinNew * set number
-autocmd VimEnter,WinNew * set relativenumber
-autocmd InsertEnter * set norelativenumber
-autocmd InsertLeave * set relativenumber
-autocmd FocusLost * set norelativenumber
-autocmd FocusGained * set relativenumber
+""" vim-only defaults
+if !has('nvim')
+ " neovim defaults are already set
+ source $VIMRUNTIME/defaults.vim
+ " disable jumping to last edit, we use vim-lastplace instead
+ autocmd! vimStartup
+
+ " packages
+ packadd! matchit " included with [n]vim but disabled by default
+ packadd! editorconfig " now included with [n]vim but disabled by default
+ packadd! vim-commentary " nvim has this built in now, vim still needs it
+
+ " options
+ set hlsearch
+ autocmd BufRead * set autoindent
+endif
+
+
+""" styling
+" nice default theme
+colorscheme murphy
+
+" always use color column with less intrusive colors
autocmd VimEnter,WinNew * set colorcolumn=80
+" always use cursor line for better visibility
autocmd VimEnter,WinNew * set cursorline
+" unique highlighting for leading spaces and in-line spaces
+" NOTE: this leaves tabs and other special whitespace untouched intentionally
+autocmd VimEnter,ColorScheme * highlight SpaceInner ctermfg=Grey guifg=#686868
+autocmd VimEnter,ColorScheme * highlight link SpaceOuter NonText
+autocmd VimEnter,WinNew * match SpaceInner / /
+autocmd VimEnter,WinNew * 2match SpaceOuter /\(^ \+\)\|\( \+$\)/
+
+" always show statusline
+set laststatus=2
+
+" truncate > lastline; lastline is nvim default, sensible.vim may also set it
+set display=truncate
+
+" more context while scrolling
+set scrolloff=5
+set sidescrolloff=8
+
+" show number column on all buffers
+autocmd VimEnter,WinNew * set number
+" use relative numbers in normal modes when focused, but not if number is off
+function! s:SetRelativeNumber(enable)
+ if !getwinvar(winnr(), '&number')
+ return
+ endif
+ if a:enable
+ set relativenumber
+ else
+ set norelativenumber
+ endif
+endfunction
+autocmd InsertEnter,FocusLost,WinLeave * call s:SetRelativeNumber(0)
+autocmd VimEnter,WinNew,
+ \InsertLeave,FocusGained,WinEnter * call s:SetRelativeNumber(1)
+
+" always show custom listchars
autocmd VimEnter,WinNew * set list
set listchars=tab:├─,extends:»,precedes:«,space:·,trail:∙,nbsp:■
-""" styles
-highlight ColorColumn term=NONE ctermbg=0
-highlight WhiteSpaceMol ctermfg=Black
-autocmd VimEnter,WinNew * match WhiteSpaceMol / /
-highlight WhiteSpaceBol ctermfg=DarkBlue
-autocmd VimEnter,WinNew * 2match WhiteSpaceBol /\(^ \+\)\|\( \+$\)/
+""" editor
+" always save undo file for all file buffers
+autocmd BufReadPre * setlocal undofile
+
+" explicitly use modeline, even on systems where it's disabled by system vimrc
+autocmd BufRead * set modeline
+" should be default disabled but just in case
+set nomodelineexpr
-""" indent
+"" indent
+" always use shiftwidth instead of tabsize
+set smarttab
+" filetype preferences
autocmd FileType python set softtabstop=4 shiftwidth=4 expandtab
autocmd FileType markdown set softtabstop=4 shiftwidth=4 expandtab
autocmd FileType javascript set softtabstop=2 shiftwidth=2 expandtab
autocmd FileType html set softtabstop=2 shiftwidth=2 expandtab
let g:EditorConfig_enable_for_new_buf = 1
-""" syntax
-autocmd FileType todo set colorcolumn=0
+"" syntax
+autocmd Syntax php syn clear phpHereDoc phpNowDoc
-""" mappings
-"" use more accessible escapes, as C-n and C-o are shadowed by some terminals
+"" mappings
+" use more accessible escapes, as C-n and C-o are shadowed by some terminals
if has('nvim')
tnoremap <C-\>n <C-\><C-N>
tnoremap <C-\>o <C-\><C-O>
endif
-"" move windows any time
+" move windows any time
if has('nvim')
" terminal
tnoremap <A-h> <C-\><C-N><C-w>h
nnoremap <A-j> <C-w>j
nnoremap <A-k> <C-w>k
nnoremap <A-l> <C-w>l
+
+"" CTRL-L to clear highlighting and also update diff
+" NOTE: sensible.vim and nvim already do this, so copy sensible.vim
+" functionality if it hasn't been set or we aren't nvim. taken from
+" sensible.vim by Tim Pope, under Vim license; see :help license
+" https://github.com/tpope/vim-sensible/blob/0ce2d843d6f588bb0c8c7eec6449171615dc56d9/plugin/sensible.vim#L57
+if !has('nvim') && maparg('<C-L>', 'n') ==# ''
+ nnoremap <silent> <C-L> :nohlsearch<C-R>=has('diff')?'<Bar>diffupdate':''<CR><CR><C-L>
+endif
+
+
+""" package config
+"" suda
+" https://github.com/lambdalisue/vim-suda/issues/32#issuecomment-829608925
+if ! &diff
+ let g:suda_smart_edit = 1
+endif
+" re-enable backup, swap, undo for suda buffers that we can read
+" https://github.com/lambdalisue/vim-suda/issues/25
+function s:SudaSettingsSave()
+ let b:sev_suda_swapfile = &swapfile
+ let b:sev_suda_undofile = &undofile
+ " fix https://github.com/lambdalisue/vim-suda/issues/87
+ setlocal noswapfile
+endfunction
+function s:SudaSettingsRestore()
+ if filereadable(expand('<afile>')[7:])
+ if exists('b:sev_suda_swapfile') && b:sev_suda_swapfile
+ try
+ setlocal swapfile
+ catch
+ " ignore swapfile errors, they should have been shown already
+ echohl ErrorMsg
+ for line in split(v:exception, '\n')
+ echomsg printf('[suda] %s', line)
+ endfor
+ echohl None
+ endtry
+ endif
+ if exists('b:sev_suda_undofile') && b:sev_suda_undofile
+ setlocal undofile
+ endif
+ endif
+endfunction
+function s:SudaProcessUndo(cmd)
+ let p = expand('<afile>')[7:]
+ if has('win32') || !&undofile || !filereadable(p)
+ return
+ endif
+ let p = resolve(p)
+ " XXX: comments are from :help backupdir to mark implementation details
+ let x = &undodir
+ " For backwards compatibility with Vim version 3.0 a '>' at the start
+ " of the option is removed.
+ if stridx(x, '>') == 0
+ let x = x[1:]
+ endif
+ " To include a comma in a directory name precede it with a backslash.
+ for u in split(x, '\v\\@1<!,')
+ " Spaces after the comma are ignored, other spaces are considered part
+ " of the directory name.
+ let u = trim(u, ' ', 1)
+ " To have a space at the start of a directory name, precede it with a
+ " backslash.
+ if stridx(u, '\ ') == 0
+ let u = u[1:]
+ endif
+ " Empty means that no backup file will be created.
+ if empty(u)
+ continue
+ elseif u == '.'
+ " A directory "." means to put the backup file in the same
+ " directory as the edited file.
+ let d = fnamemodify(p, ':p:h')
+ elseif stridx(u, './') == 0
+ " A directory starting with "./" (or ".\" for MS-Windows) means to
+ " put the backup file relative to where the edited file is.
+ let d = printf('%s%s', fnamemodify(p, ':p:h'), expand(u))
+ else
+ let d = u
+ endif
+ " NOTE: env vars are not expanded, and backslashes are not handled...
+ if u[-2:-1] == '//'
+ let f = fnamemodify(p, ':p:gs?/?%?')
+ else
+ let f = printf('.%s.un~', fnamemodify(p, ':t'))
+ endif
+ " A directory name may end in an '/'.
+ let d = trim(d, '/', 2)
+ if !isdirectory(d)
+ continue
+ endif
+ try
+ execute printf('%s %s/%s', a:cmd, fnameescape(d), fnameescape(f))
+ break
+ catch
+ continue
+ endtry
+ endfor
+endfunction
+autocmd BufReadPre suda://* call s:SudaSettingsSave()
+autocmd BufReadPost suda://* call s:SudaSettingsRestore()
+autocmd BufReadPost suda://* call s:SudaProcessUndo('silent! rundo')
+autocmd BufWritePost suda://* call s:SudaProcessUndo('wundo!')