371 lines
10 KiB
VimL
371 lines
10 KiB
VimL
" Sane vim defaults for ArchLabs
|
||
|
||
scriptencoding utf8
|
||
|
||
" Arch defaults
|
||
runtime! archlinux.vim
|
||
|
||
" leader key
|
||
let g:mapleader = "\<Space>"
|
||
|
||
" system clipboard (requires +clipboard)
|
||
set clipboard^=unnamed,unnamedplus
|
||
|
||
" additional settings
|
||
syntax enable
|
||
set number " enable line numbers
|
||
set backup " create backup files in runtimepath/backup/
|
||
set undofile " persistent undo files in runtimepath/undo/
|
||
set modeline " enable vim modelines
|
||
set hlsearch " highlight search items
|
||
set incsearch " searches are performed as you type
|
||
set confirm " ask confirmation like save before quit.
|
||
set tabstop=4 " tab is equivalent to how many spaces
|
||
set softtabstop=4 " tab is equivalent to how many spaces
|
||
set shiftwidth=4 " amount of spaces for indentation
|
||
set shortmess+=aAcws " hide or shorten certain messages
|
||
set wildmenu " tab completion menu when using command mode
|
||
set wildignore+=*~,*.pyc,*/.git/*,*.so,*.swp,*.o,*.zip,*.zwc,*.png,*.jpg
|
||
set ttimeout
|
||
set ttimeoutlen=10
|
||
set timeoutlen=600
|
||
set updatecount=80
|
||
set linebreak breakindent
|
||
set list listchars=tab:>>,trail:~
|
||
set mouse=niv " use the terminal mouse in command mode (:)
|
||
if has('mouse_sgr')
|
||
" sgr mouse is better but not every term supports it
|
||
set ttymouse=sgr
|
||
endif
|
||
|
||
let g:netrw_altv = 1
|
||
let g:netrw_liststyle = 3
|
||
let g:netrw_browse_split = 3
|
||
|
||
if $TERM !=? 'linux'
|
||
set termguicolors
|
||
" true colors in terminals (neovim doesn't need this)
|
||
if !has('nvim') && !($TERM =~? 'xterm' || &term =~? 'xterm')
|
||
let $TERM = 'xterm-256color'
|
||
let &term = 'xterm-256color'
|
||
endif
|
||
if has('multi_byte') && $TERM !=? 'linux'
|
||
" ▏│ ┆ ┃ › »»
|
||
set list listchars=tab:▏\ ,extends:❯,precedes:❮
|
||
set fillchars=vert:┃ showbreak=↪
|
||
endif
|
||
endif
|
||
|
||
" set the colorscheme variant.. midnight, night, or day
|
||
let g:jinx_theme = 'midnight'
|
||
try
|
||
colorscheme jinx
|
||
catch
|
||
colorscheme evening
|
||
endtry
|
||
|
||
" change cursor shape for different editing modes, neovim does this by default
|
||
if !has('nvim')
|
||
if exists('$TMUX')
|
||
let &t_SI = "\<Esc>Ptmux;\<Esc>\e[5 q\<Esc>\\"
|
||
let &t_SR = "\<Esc>Ptmux;\<Esc>\e[4 q\<Esc>\\"
|
||
let &t_EI = "\<Esc>Ptmux;\<Esc>\e[2 q\<Esc>\\"
|
||
elseif $TERM ==# 'linux'
|
||
let &t_SI = "\e[?0c"
|
||
let &t_EI = "\e[?8c"
|
||
else
|
||
let &t_SI = "\e[6 q"
|
||
let &t_SR = "\e[4 q"
|
||
let &t_EI = "\e[2 q"
|
||
endif
|
||
endif
|
||
|
||
" ------ commands ------
|
||
|
||
command! D Explore
|
||
command! R call <SID>ranger()
|
||
command! -bang -complete=buffer -nargs=? Bclose call Bclose(<bang>, <args>)
|
||
command! -complete=buffer -nargs=? Bselect call Bselect(<args>)
|
||
command! W exec 'silent w !sudo tee % >/dev/null'|edit!
|
||
|
||
" ------ basic maps ------
|
||
|
||
" visually select the whole file
|
||
vnoremap aa VGo1G
|
||
|
||
" yank the entire file
|
||
nnoremap gyy gg"+yG''
|
||
vnoremap gyy <Esc>gg"+yG''
|
||
|
||
" open ranger as a file chooser using the function below
|
||
nnoremap <leader>r :call <SID>ranger()<CR>
|
||
|
||
" select buffer from a list
|
||
nnoremap <Leader>b :Bselect<CR>
|
||
|
||
" close current buffer (and tab if needed)
|
||
nnoremap <Leader>q :Bclose<CR>:silent tabclose<CR>gT
|
||
|
||
" change windows with ctrl+(hjkl)
|
||
nnoremap <C-J> <C-W><C-J>
|
||
nnoremap <C-K> <C-W><C-K>
|
||
nnoremap <C-L> <C-W><C-L>
|
||
nnoremap <C-H> <C-W><C-H>
|
||
|
||
" alt defaults
|
||
nnoremap 0 ^
|
||
nnoremap Y y$
|
||
nnoremap n nzzzv
|
||
nnoremap N Nzzzv
|
||
nnoremap <Tab> ==1j
|
||
vnoremap <Tab> ==
|
||
|
||
" re-visual text after changing indent
|
||
vnoremap > >gv
|
||
vnoremap < <gv
|
||
|
||
" toggle line numbers, nn (no number)
|
||
nnoremap <silent> <Leader>nn :set number!
|
||
|
||
" gj/k but preserve numbered jumps ie: 12j or 45k
|
||
nmap <buffer><silent><expr>j v:count ? 'j' : 'gj'
|
||
nmap <buffer><silent><expr>k v:count ? 'k' : 'gk'
|
||
|
||
" open a terminal in $PWD
|
||
nnoremap <silent> <Leader>tt :terminal<CR>
|
||
|
||
" toggle folding
|
||
nnoremap <leader>za :set foldenable!<CR>
|
||
|
||
" tab control
|
||
nnoremap <silent> <M-j> :tabmove -1<CR>
|
||
nnoremap <silent> <M-k> :tabmove +1<CR>
|
||
nnoremap <silent> <Leader>te :tabnew<CR>
|
||
nnoremap <silent> <Leader>tn :tabnext<CR>
|
||
nnoremap <silent> <Leader>tf :tabfirst<CR>
|
||
nnoremap <silent> <Leader>tp :tabprevious<CR>
|
||
|
||
" open a new tab in the current directory with netrw (file browser)
|
||
nnoremap <silent> <Leader>- :tabedit <C-R>=expand("%:p:h")<CR><CR>
|
||
|
||
" fix syntax highlighting issues
|
||
nnoremap U :syntax sync fromstart<CR>:redraw!<CR>
|
||
|
||
|
||
" ------ autocmd ------
|
||
|
||
" when quitting a file save the cursor position and reload if file changed
|
||
augroup load_changed_file
|
||
autocmd!
|
||
autocmd BufReadPost * call setpos(".", getpos("'\""))
|
||
autocmd FocusGained,BufEnter * if mode() !=? 'c' | checktime | endif
|
||
autocmd FileChangedShellPost * echo "Changes loaded from source file"
|
||
augroup END
|
||
|
||
" make the built-in terminal behave a bit better
|
||
if has('nvim')
|
||
augroup open_terminal
|
||
autocmd!
|
||
autocmd TermOpen * setlocal nonumber norelativenumber modifiable | startinsert
|
||
autocmd TermClose * buffer #
|
||
augroup END
|
||
elseif has('terminal')
|
||
augroup open_terminal
|
||
autocmd!
|
||
autocmd TerminalOpen * setlocal nonumber norelativenumber
|
||
augroup END
|
||
endif
|
||
|
||
" when not running in a linux console toggle some things when in insert mode
|
||
if $TERM !=# 'linux'
|
||
augroup active_cursorline
|
||
autocmd!
|
||
autocmd InsertEnter * setlocal cursorline listchars-=trail:•
|
||
autocmd InsertLeave * setlocal nocursorline listchars+=trail:•
|
||
augroup END
|
||
else
|
||
" otherwise disable cursorline
|
||
set nocursorline
|
||
endif
|
||
|
||
" ------ adv maps ------
|
||
|
||
|
||
" strip trailing whitespace, ss (strip space)
|
||
nnoremap <silent> <Leader>ss
|
||
\ :let b:_p = getpos(".") <Bar>
|
||
\ let b:_s = (@/ != '') ? @/ : '' <Bar>
|
||
\ %s/\s\+$//e <Bar>
|
||
\ let @/ = b:_s <Bar>
|
||
\ nohlsearch <Bar>
|
||
\ unlet b:_s <Bar>
|
||
\ call setpos('.', b:_p) <Bar>
|
||
\ unlet b:_p <CR>
|
||
|
||
" global replace
|
||
vnoremap <Leader>sw "hy
|
||
\ :let b:sub = input('global replacement: ') <Bar>
|
||
\ if b:sub !=? '' <Bar>
|
||
\ let b:rep = substitute(getreg('h'), '/', '\\/', 'g') <Bar>
|
||
\ execute '%s/'.b:rep."/".b:sub.'/g' <Bar>
|
||
\ unlet b:sub b:rep <Bar>
|
||
\ endif <CR>
|
||
nnoremap <Leader>sw
|
||
\ :let b:sub = input('global replacement: ') <Bar>
|
||
\ if b:sub !=? '' <Bar>
|
||
\ execute "%s/<C-r><C-w>/".b:sub.'/g' <Bar>
|
||
\ unlet b:sub <Bar>
|
||
\ endif <CR>
|
||
|
||
" prompt before each replace
|
||
vnoremap <Leader>cw "hy
|
||
\ :let b:sub = input('interactive replacement: ') <Bar>
|
||
\ if b:sub !=? '' <Bar>
|
||
\ let b:rep = substitute(getreg('h'), '/', '\\/', 'g') <Bar>
|
||
\ execute '%s/'.b:rep.'/'.b:sub.'/gc' <Bar>
|
||
\ unlet b:sub b:rep <Bar>
|
||
\ endif <CR>
|
||
|
||
nnoremap <Leader>cw
|
||
\ :let b:sub = input('interactive replacement: ') <Bar>
|
||
\ if b:sub !=? '' <Bar>
|
||
\ execute "%s/<C-r><C-w>/".b:sub.'/gc' <Bar>
|
||
\ unlet b:sub <Bar>
|
||
\ endif <CR>
|
||
|
||
" highlight long lines, ll (long lines)
|
||
let w:longlines = matchadd('ColorColumn', '\%'.&textwidth.'v', &textwidth)
|
||
nnoremap <silent> <Leader>ll
|
||
\ :if exists('w:longlines') <Bar>
|
||
\ silent! call matchdelete(w:longlines) <Bar>
|
||
\ echo 'Long line highlighting disabled'
|
||
\ <Bar> unlet w:longlines <Bar>
|
||
\ elseif &textwidth > 0 <Bar>
|
||
\ let w:longlines = matchadd('ColorColumn', '\%'.&textwidth.'v', &textwidth) <Bar>
|
||
\ echo 'Long line highlighting enabled'
|
||
\ <Bar> else <Bar>
|
||
\ let w:longlines = matchadd('ColorColumn', '\%80v', 81) <Bar>
|
||
\ echo 'Long line highlighting enabled'
|
||
\ <Bar> endif <CR>
|
||
|
||
" local keyword jump
|
||
nnoremap <Leader>fw
|
||
\ [I:let b:jump = input('Go To: ') <Bar>
|
||
\ if b:jump !=? '' <Bar>
|
||
\ execute "normal! ".b:jump."[\t" <Bar>
|
||
\ unlet b:jump <Bar>
|
||
\ endif <CR>
|
||
|
||
|
||
function! Bclose(bang, buffer) abort
|
||
if empty(a:buffer)
|
||
let l:target = bufnr('%')
|
||
elseif a:buffer =~? '^\d\+$'
|
||
let l:target = bufnr(str2nr(a:buffer))
|
||
else
|
||
let l:target = bufnr(a:buffer)
|
||
endif
|
||
|
||
if l:target < 0
|
||
call WarningMsg('No matching buffer for '.a:buffer)
|
||
return
|
||
endif
|
||
|
||
if empty(a:bang) && getbufvar(l:target, '&modified')
|
||
call WarningMsg('No write since last change for buffer '.l:target.' (use :Bclose!)')
|
||
return
|
||
endif
|
||
|
||
" Numbers of windows that view target buffer which we will delete.
|
||
let l:num_wins = filter(range(1, winnr('$')), 'winbufnr(v:val) == l:target')
|
||
|
||
if empty(a:bang) && len(l:num_wins) > 1
|
||
call WarningMsg('Buffer is open in multiple windows (use :Bclose!)')
|
||
return
|
||
endif
|
||
|
||
let l:cur_win = winnr()
|
||
|
||
for w in l:num_wins
|
||
execute w.'wincmd w'
|
||
let prevbuf = bufnr('#')
|
||
if prevbuf > 0 && buflisted(prevbuf) && prevbuf != w
|
||
buffer #
|
||
else
|
||
bprevious
|
||
endif
|
||
if l:target == bufnr('%')
|
||
" Numbers of listed buffers which are not the target to be deleted.
|
||
let blisted = filter(range(1, bufnr('$')), 'buflisted(v:val) && v:val != l:target')
|
||
" Listed, not target, and not displayed.
|
||
let bhidden = filter(copy(blisted), 'bufwinnr(v:val) < 0')
|
||
" Take the first buffer, if any (could be more intelligent).
|
||
let bjump = (bhidden + blisted + [-1])[0]
|
||
if bjump > 0
|
||
execute 'buffer '.bjump
|
||
else
|
||
execute 'enew'.a:bang
|
||
endif
|
||
endif
|
||
endfor
|
||
|
||
execute 'bdelete'.a:bang.' '.l:target
|
||
execute l:cur_win.'wincmd w'
|
||
endfunction
|
||
|
||
function! Bselect(...) abort
|
||
let l:pattern = a:0 >= 1 ? a:1 : ''
|
||
if l:pattern ==? ''
|
||
let l:pattern = input('String match: ')
|
||
redraw!
|
||
endif
|
||
if l:pattern !=# ''
|
||
let l:bufcount = bufnr('$')
|
||
let l:currbufnr = 1
|
||
let l:nummatches = 0
|
||
let l:matchingbufnr = 0
|
||
|
||
while l:currbufnr <= l:bufcount
|
||
if bufexists(l:currbufnr)
|
||
let l:currbufname = bufname(l:currbufnr)
|
||
if (match(l:currbufname, l:pattern) > -1)
|
||
echo l:currbufnr . ': ' . l:currbufname
|
||
let l:nummatches += 1
|
||
let l:matchingbufnr = l:currbufnr
|
||
endif
|
||
endif
|
||
let l:currbufnr += 1
|
||
endwhile
|
||
|
||
if (l:nummatches == 1)
|
||
execute ':buffer '.l:matchingbufnr
|
||
elseif (l:nummatches > 1)
|
||
let l:desiredbufnr = input('Enter buffer number: ')
|
||
if (strlen(l:desiredbufnr) != 0)
|
||
execute ':buffer ' . l:desiredbufnr
|
||
endif
|
||
else
|
||
call WarningMsg('No matching buffers')
|
||
endif
|
||
endif
|
||
endfunction
|
||
|
||
function! <SID>ranger()
|
||
let l:temp = tempname()
|
||
execute 'silent !xterm -e ranger --choosefiles='.shellescape(l:temp).' $PWD'
|
||
if !filereadable(temp)
|
||
redraw!
|
||
return
|
||
endif
|
||
let l:names = readfile(l:temp)
|
||
if empty(l:names)
|
||
redraw!
|
||
return
|
||
endif
|
||
execute 'edit '.fnameescape(l:names[0])
|
||
for l:name in l:names[1:]
|
||
execute 'argadd '.fnameescape(l:name)
|
||
endfor
|
||
redraw!
|
||
endfunction
|