summaryrefslogtreecommitdiffstats
path: root/vim
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2017-10-29 16:01:43 -0400
committerJesse Luehrs <doy@tozt.net>2017-10-29 19:03:53 -0400
commitd9fd53a62b8fe7698400610d81456e5e3d9461ef (patch)
treefb76c6f3a6da79ec38e693ecb10b346afe9557d6 /vim
parentc8b741e677788b77357c47ee1573f9ffd636c368 (diff)
downloadconf-d9fd53a62b8fe7698400610d81456e5e3d9461ef.tar.gz
conf-d9fd53a62b8fe7698400610d81456e5e3d9461ef.zip
pull a bunch of self-contained things out of my vimrc
Diffstat (limited to 'vim')
-rw-r--r--vim/plugin/autobrace.vim141
-rw-r--r--vim/plugin/diff.vim68
-rw-r--r--vim/plugin/dircreate.vim31
-rw-r--r--vim/plugin/eolws.vim6
-rw-r--r--vim/plugin/keywordprg.vim33
-rw-r--r--vim/plugin/nopaste.vim19
-rw-r--r--vim/plugin/zshhistory.vim76
7 files changed, 374 insertions, 0 deletions
diff --git a/vim/plugin/autobrace.vim b/vim/plugin/autobrace.vim
new file mode 100644
index 0000000..f979976
--- /dev/null
+++ b/vim/plugin/autobrace.vim
@@ -0,0 +1,141 @@
+let s:pair_chars = {
+\ '(': ')',
+\ '[': ']',
+\ '{': '}',
+\}
+let s:pair_cr_maps = {
+\ '(': "<SID>go_up()",
+\ '[': "<SID>go_up()",
+\ '{': "<SID>go_up()",
+\}
+let s:pair_bs_maps = {
+\ '"': "<SID>maybe_remove_adjacent_char('\"')",
+\ "'": "<SID>maybe_remove_adjacent_char(\"'\")",
+\ '(': "<SID>maybe_remove_empty_pair(')')",
+\ '[': "<SID>maybe_remove_empty_pair(']')",
+\ '{': "<SID>maybe_remove_empty_pair('}')",
+\ '': "<SID>maybe_collapse_pair()",
+\}
+
+function! s:move_cursor_left()
+ return "\<Esc>i"
+endfunction
+
+function! s:skip_closing_char(char)
+ if s:nextchar() == a:char
+ return "\<Esc>la"
+ else
+ return a:char
+ endif
+endfunction
+
+function! s:has_bs_mapping(char)
+ return has_key(s:pair_bs_maps, a:char)
+endfunction
+
+function! s:run_bs_mapping(char)
+ return eval(s:pair_bs_maps[a:char])
+endfunction
+
+function! s:has_cr_mapping(char)
+ return has_key(s:pair_cr_maps, a:char)
+endfunction
+
+function! s:run_cr_mapping(char)
+ return eval(s:pair_cr_maps[a:char])
+endfunction
+
+function! s:go_up()
+ return "\<CR>\<Esc>O"
+endfunction
+
+function! s:maybe_remove_adjacent_char(char)
+ if s:nextchar() == a:char
+ return "\<BS>\<Del>"
+ else
+ return "\<BS>"
+ endif
+endfunction
+
+function! s:maybe_remove_empty_pair(char)
+ let l:start = [line('.'), col('.')]
+ let l:end = searchpos('[^ \t]', 'cnWz')
+ if l:end == [0, 0]
+ return "\<BS>"
+ endif
+
+ let l:next_nonblank = s:charat(l:end[0], l:end[1])
+ if l:next_nonblank != a:char
+ return "\<BS>"
+ endif
+
+ let l:diff = [l:end[0] - l:start[0], l:end[1] - l:start[1]]
+ if l:diff[0] == 0
+ return "\<BS>" . repeat("\<Del>", l:diff[1] + 1)
+ elseif l:diff[0] == 1
+ return "\<Esc>" . (l:diff[0] + 1) . "Ji" . "\<BS>\<Del>\<Del>"
+ else
+ return "\<Esc>" . (l:diff[0] + 1) . "Ji" . "\<BS>\<BS>\<Del>"
+ endif
+endfunction
+
+function! s:maybe_collapse_pair()
+ let l:prev_line_idx = line('.') - 1
+ if l:prev_line_idx < 1
+ return "\<BS>"
+ endif
+
+ let l:prev_line_char = s:charat(l:prev_line_idx, col([l:prev_line_idx, '$']) - 1)
+ if l:prev_line_char !~ '[([{]'
+ return "\<BS>"
+ endif
+
+ let l:end = searchpos('[^ \t]', 'cnWz')
+ if l:end == [0, 0]
+ return "\<BS>"
+ endif
+
+ let l:next_nonblank = s:charat(l:end[0], l:end[1])
+ if l:next_nonblank != s:pair_chars[l:prev_line_char]
+ return "\<BS>"
+ endif
+
+ return "\<Esc>\<BS>JJi\<BS>"
+endfunction
+
+function! s:prevchar()
+ return s:charat(line('.'), col('.') - 1)
+endfunction
+
+function! s:nextchar()
+ return s:charat(line('.'), col('.'))
+endfunction
+
+function! s:charat(line, col)
+ return getline(a:line)[a:col - 1]
+endfunction
+
+for [s:start, s:end] in [['(', ')'], ['{', '}'], ['[', ']']]
+ exe "inoremap <silent> ".s:start.
+ \ " ".s:start.s:end."<C-R>=<SID>move_cursor_left()<CR>"
+ exe "inoremap <silent> ".s:end.
+ \ " <C-R>=<SID>skip_closing_char('".s:end."')<CR>"
+endfor
+inoremap <silent><expr> '
+ \ <SID>nextchar() == "'"
+ \ ? "\<C-R>=\<SID>skip_closing_char(\"'\")\<CR>"
+ \ : col('.') == 1 \|\| match(<SID>prevchar(), '\W') != -1
+ \ ? "''\<C-R>=\<SID>move_cursor_left()\<CR>"
+ \ : "'"
+inoremap <silent><expr> "
+ \ <SID>nextchar() == '"'
+ \ ? "\<C-R>=\<SID>skip_closing_char('\"')\<CR>"
+ \ : "\"\"\<C-R>=\<SID>move_cursor_left()\<CR>"
+inoremap <silent><expr> <BS>
+ \ <SID>has_bs_mapping(<SID>prevchar())
+ \ ? "\<C-R>=\<SID>run_bs_mapping(\<SID>prevchar())\<CR>"
+ \ : "\<BS>"
+inoremap <silent><expr> <CR>
+ \ <SID>has_cr_mapping(<SID>prevchar())
+ \ ? "\<C-R>=\<SID>run_cr_mapping(\<SID>prevchar())\<CR>"
+ \ : "\<CR>"
diff --git a/vim/plugin/diff.vim b/vim/plugin/diff.vim
new file mode 100644
index 0000000..8c4f44a
--- /dev/null
+++ b/vim/plugin/diff.vim
@@ -0,0 +1,68 @@
+let s:foldmethod = &foldmethod
+let s:foldenable = &foldenable
+let s:diffwindow = 0
+
+function! s:diffstart(read_cmd)
+ if s:diffwindow != 0
+ return
+ endif
+ let s:foldmethod = &foldmethod
+ let s:foldenable = &foldenable
+ let l:filetype = &filetype
+ vert new
+ let s:diffwindow = winnr()
+ set buftype=nofile
+ try
+ exe a:read_cmd
+ catch /.*/
+ echohl ErrorMsg
+ echo v:exception
+ echohl NONE
+ call s:diffstop()
+ return
+ endtry
+ let &filetype = l:filetype
+ diffthis
+ wincmd p
+ diffthis
+ " why does this not happen automatically?
+ normal! zM
+endfunction
+
+function! s:diffstop()
+ if s:diffwindow == 0
+ return
+ endif
+ diffoff!
+ exe s:diffwindow . 'wincmd w'
+ bdelete
+ let &foldmethod = s:foldmethod
+ let &foldenable = s:foldenable
+ if &foldenable
+ normal! zv
+ endif
+ let s:diffwindow = 0
+endfunction
+
+function! s:vcs_orig(file)
+ " XXX: would be nice to use a:file rather than # here...
+ let l:dir = expand('#:p:h')
+ if filewritable(l:dir . '/.svn') == 2
+ return system('svn cat ' . a:file)
+ elseif filewritable(l:dir . '/CVS') == 2
+ return system("AFILE=" . a:file . "; MODFILE=`tempfile`; DIFF=`tempfile`; cp $AFILE $MODFILE && cvs diff -u $AFILE > $DIFF; patch -R $MODFILE $DIFF 2>&1 > /dev/null && cat $MODFILE; rm $MODFILE $DIFF")
+ elseif finddir('_darcs', l:dir . ';') =~# '_darcs'
+ return system('darcs show contents ' . a:file)
+ elseif finddir('.git', l:dir . ';') =~# '.git'
+ let l:prefix = system('git rev-parse --show-prefix')
+ let l:prefix = substitute(l:prefix, '\n', '', 'g')
+ let l:cmd = 'git show HEAD:'.l:prefix.a:file
+ return system(l:cmd)
+ else
+ throw 'No VCS directory found'
+ endif
+endfunction
+
+nnoremap <silent>ds :call <SID>diffstart('read # <bar> normal! ggdd')<CR>
+nnoremap <silent>dc :call <SID>diffstart('call append(0, split(s:vcs_orig(expand("#:.")), "\n", 1)) <bar> normal! Gdddd')<CR>
+nnoremap <silent>de :call <SID>diffstop()<CR>
diff --git a/vim/plugin/dircreate.vim b/vim/plugin/dircreate.vim
new file mode 100644
index 0000000..11da7f9
--- /dev/null
+++ b/vim/plugin/dircreate.vim
@@ -0,0 +1,31 @@
+function! s:ensure_dir_exists()
+ let l:required_dir = expand("%:h")
+ if !isdirectory(l:required_dir)
+ if <SID>ask_quit("Directory '" . l:required_dir . "' doesn't exist.", "&Create it?")
+ return
+ endif
+
+ try
+ call mkdir(l:required_dir, 'p')
+ catch
+ call <SID>ask_quit("Can't create '" . l:required_dir . "'", "&Continue anyway?")
+ endtry
+ endif
+endfunction
+
+function! s:ask_quit(msg, proposed_action)
+ if confirm(a:msg, "&Quit?\n" . a:proposed_action) == 1
+ if len(getbufinfo()) > 1
+ silent bd
+ return 1
+ else
+ exit
+ end
+ endif
+ return 0
+endfunction
+
+augroup dircreate
+ autocmd!
+ autocmd BufNewFile * call <SID>ensure_dir_exists()
+augroup END
diff --git a/vim/plugin/eolws.vim b/vim/plugin/eolws.vim
new file mode 100644
index 0000000..1f1a003
--- /dev/null
+++ b/vim/plugin/eolws.vim
@@ -0,0 +1,6 @@
+augroup eolws
+ autocmd!
+ autocmd InsertEnter * syn clear EOLWS | syn match EOLWS excludenl /\s\+\%#\@!$/
+ autocmd InsertLeave * syn clear EOLWS | syn match EOLWS excludenl /\s\+$/
+augroup END
+highlight EOLWS ctermbg=red guibg=red
diff --git a/vim/plugin/keywordprg.vim b/vim/plugin/keywordprg.vim
new file mode 100644
index 0000000..dfedd80
--- /dev/null
+++ b/vim/plugin/keywordprg.vim
@@ -0,0 +1,33 @@
+function! Help(visual, iskeyword, command)
+ let l:iskeyword = &iskeyword
+ for l:kw in a:iskeyword
+ exe 'set iskeyword+=' . l:kw
+ endfor
+ if a:visual
+ let l:oldreg = @a
+ normal! gv"aygv
+ let l:word = @a
+ let @a = l:oldreg
+ else
+ let l:word = expand('<cword>')
+ endif
+ let &iskeyword = l:iskeyword
+
+ exe 'noswapfile ' . &helpheight . 'new ' . l:word
+ setlocal buftype=nofile
+ setlocal bufhidden=wipe
+ setlocal nobuflisted
+
+ setlocal modifiable
+ exe 'call ' . a:command . '("' . l:word . '")'
+ normal! ggdd
+ setlocal nomodifiable
+endfunction
+
+function! s:man(word)
+ exe 'silent read! man -Pcat ' . a:word
+ setlocal filetype=man
+endfunction
+
+nnoremap <silent>K :call Help(0, [], '<SID>man')<CR>
+xnoremap <silent>K :call Help(1, [], '<SID>man')<CR>
diff --git a/vim/plugin/nopaste.vim b/vim/plugin/nopaste.vim
new file mode 100644
index 0000000..cb904f7
--- /dev/null
+++ b/vim/plugin/nopaste.vim
@@ -0,0 +1,19 @@
+function! s:nopaste(visual)
+ if a:visual
+ silent normal! gv:!nopaste<CR>
+ else
+ let l:pos = getpos('.')
+ silent normal! :%!nopaste<CR>
+ endif
+ silent normal! "+yy
+ let @* = @+
+ silent undo
+ " can't restore visual selection because that will overwrite "*
+ if !a:visual
+ call setpos('.', l:pos)
+ endif
+ echo @+
+endfunction
+
+nnoremap <silent><Leader>p :call <SID>nopaste(0)<CR>
+xnoremap <silent><Leader>p :<C-U>call <SID>nopaste(1)<CR>
diff --git a/vim/plugin/zshhistory.vim b/vim/plugin/zshhistory.vim
new file mode 100644
index 0000000..29b3c67
--- /dev/null
+++ b/vim/plugin/zshhistory.vim
@@ -0,0 +1,76 @@
+" see 'vim' alias in zshrc
+if $SHELL !~# 'zsh' || !exists('g:_zsh_hist_fname')
+ finish
+endif
+
+let s:initial_files = {}
+
+augroup zshhistory
+ autocmd!
+ autocmd VimEnter * call <SID>init_zsh_hist()
+ autocmd BufNewFile,BufRead * call <SID>zsh_hist_append()
+ autocmd BufDelete * call <SID>remove_initial_file(expand("<afile>"))
+ autocmd VimLeave * call <SID>reorder_zsh_hist()
+augroup END
+
+function! s:remove_initial_file (file)
+ if has_key(s:initial_files, a:file)
+ unlet s:initial_files[a:file]
+ endif
+endfunction
+
+function! s:get_buffer_list_text ()
+ redir => l:output
+ ls!
+ redir END
+ return l:output
+endfunction
+
+function! s:get_buffer_list ()
+ silent let l:output = <SID>get_buffer_list_text()
+ let l:buffer_list = []
+ for l:buffer_desc in split(l:output, "\n")
+ let l:name = bufname(str2nr(l:buffer_desc))
+ if l:name != ""
+ call add(l:buffer_list, l:name)
+ endif
+ endfor
+ return l:buffer_list
+endfunction
+
+function! s:init_zsh_hist ()
+ for l:fname in <SID>get_buffer_list()
+ let s:initial_files[l:fname] = 1
+ call histadd(":", "e " . l:fname)
+ endfor
+ call delete(g:_zsh_hist_fname)
+endfunction
+
+function! s:zsh_hist_append ()
+ let l:to_append = expand("%:~:.")
+ " XXX these set buftype too late to be caught by this...
+ " this is broken, but not sure what a better fix is
+ if &buftype == '' && l:to_append !~# '^\(__Gundo\|Startify\|\[denite\]\)'
+ if !has_key(s:initial_files, l:to_append)
+ if filereadable(g:_zsh_hist_fname)
+ let l:hist = readfile(g:_zsh_hist_fname)
+ else
+ let l:hist = []
+ endif
+ call add(l:hist, l:to_append)
+ call writefile(l:hist, g:_zsh_hist_fname)
+ endif
+ endif
+endfunction
+
+function! s:reorder_zsh_hist ()
+ let l:current_file = expand("%:~:.")
+ if filereadable(g:_zsh_hist_fname)
+ let l:hist = readfile(g:_zsh_hist_fname)
+ if !has_key(s:initial_files, l:current_file)
+ call filter(l:hist, 'v:val != l:current_file')
+ endif
+ call add(l:hist, l:current_file)
+ call writefile(l:hist, g:_zsh_hist_fname)
+ endif
+endfunction