aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2018-08-10 00:20:51 +1200
committerTom Ryder <tom@sanctum.geek.nz>2018-08-10 00:20:51 +1200
commit192af8c7f52d0b9ab3660f83fd5605653a979bef (patch)
tree77908a6596f96e5dfb25276e5a60fe7b06f5c3f2
parentMerge branch 'release/v1.51.0' into develop (diff)
downloaddotfiles-192af8c7f52d0b9ab3660f83fd5605653a979bef.tar.gz
dotfiles-192af8c7f52d0b9ab3660f83fd5605653a979bef.zip
Add vertical_region.vim plugin
-rw-r--r--vim/plugin/vertical_region.vim67
-rw-r--r--vim/vimrc10
2 files changed, 77 insertions, 0 deletions
diff --git a/vim/plugin/vertical_region.vim b/vim/plugin/vertical_region.vim
new file mode 100644
index 00000000..edd5731a
--- /dev/null
+++ b/vim/plugin/vertical_region.vim
@@ -0,0 +1,67 @@
+"
+" vertical_region.vim: Move to a line that has non-space characters before or
+" in the current column, usually to find lines that begin or end blocks in
+" languages where indenting is used to show or specify structure.
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+if exists('g:loaded_vertical_region') || &compatible
+ finish
+endif
+if v:version < 700
+ finish
+endif
+let g:loaded_vertical_region = 1
+
+" Function for expression maps returning navigaton keys to press
+function! s:VerticalRegion(count, up, mode) abort
+
+ " Get line and column number
+ let l:num = line('.')
+ let l:col = col('.')
+
+ " Move up or down through buffer, counting hits as we go
+ let l:hits = 0
+ while a:up ? l:num > 1 : l:num < line('$')
+
+ " Increment or decrement line number
+ let l:num += a:up ? -1 : 1
+
+ " If the line has any non-space characters up to the current column, we
+ " have a hit; break the loop as soon as we have the count we need
+ let l:line = getline(l:num)
+ if strpart(l:line, 0, l:col) =~# '\S'
+ let l:hits += 1
+ if l:hits == a:count
+ break
+ endif
+ endif
+
+ endwhile
+
+ " If not moving linewise for operator mode and not in first column, move to
+ " same column after line jump; is there a way to do this in one jump?
+ let l:keys = l:num . 'G'
+ if a:mode !=# 'o' && l:col > 1
+ let l:keys .= l:col - 1 . 'l'
+ endif
+
+ " Return normal mode commands
+ return l:keys
+
+endfunction
+
+" Define plugin maps
+nnoremap <expr> <Plug>(VerticalRegionUpNormal)
+ \ <SID>VerticalRegion(v:count1, 1, 'n')
+nnoremap <expr> <Plug>(VerticalRegionDownNormal)
+ \ <SID>VerticalRegion(v:count1, 0, 'n')
+onoremap <expr> <Plug>(VerticalRegionUpOperator)
+ \ <SID>VerticalRegion(v:count1, 1, 'o')
+onoremap <expr> <Plug>(VerticalRegionDownOperator)
+ \ <SID>VerticalRegion(v:count1, 0, 'o')
+xnoremap <expr> <Plug>(VerticalRegionUpVisual)
+ \ <SID>VerticalRegion(v:count1, 1, 'x')
+xnoremap <expr> <Plug>(VerticalRegionDownVisual)
+ \ <SID>VerticalRegion(v:count1, 0, 'x')
diff --git a/vim/vimrc b/vim/vimrc
index be9c63ab..2531327d 100644
--- a/vim/vimrc
+++ b/vim/vimrc
@@ -318,6 +318,16 @@ nnoremap <Bslash>. :<C-U>lmake!<CR>
nnoremap <Bslash><lt> :<C-U>'[,']<lt><CR>
nnoremap <Bslash>> :<C-U>'[,']><CR>
+" \{ and \} move to lines with non-space chars before current column
+nmap <Bslash>{ <Plug>(VerticalRegionUpNormal)
+nmap <Bslash>} <Plug>(VerticalRegionDownNormal)
+omap <Bslash>{ <Plug>(VerticalRegionUpOperator)
+omap <Bslash>} <Plug>(VerticalRegionDownOperator)
+if exists(':xmap')
+ xmap <Bslash>{ <Plug>(VerticalRegionUpVisual)
+ xmap <Bslash>} <Plug>(VerticalRegionDownVisual)
+endif
+
" \/ types :vimgrep for me ready to enter a search pattern
nnoremap <Bslash>/ :<C-U>vimgrep /\c/ **<S-Left><S-Left><Right>
" \? types :helpgrep for me ready to enter a search pattern