diff options
author | Josh Rahm <rahm@google.com> | 2022-08-04 13:16:12 -0600 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-08-04 13:16:12 -0600 |
commit | 3340b11176d467961ae8426091d53c6ad1a01d2c (patch) | |
tree | 49b7d8772081265088e69e7d7d50b747769418b0 /autoload | |
parent | 6f7c03150b25c2895c852e5068d8c890246ba231 (diff) | |
download | fieldmarshal.vim-3340b11176d467961ae8426091d53c6ad1a01d2c.tar.gz fieldmarshal.vim-3340b11176d467961ae8426091d53c6ad1a01d2c.tar.bz2 fieldmarshal.vim-3340b11176d467961ae8426091d53c6ad1a01d2c.zip |
Add Fall.vim
Diffstat (limited to 'autoload')
-rw-r--r-- | autoload/fall.vim | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/autoload/fall.vim b/autoload/fall.vim new file mode 100644 index 0000000..493ded3 --- /dev/null +++ b/autoload/fall.vim @@ -0,0 +1,80 @@ +" Falling motions for Vim. "Falling" means moving the cursor down until it hits +" text that doesn't match a pattern. + +" Returns an expression to be used in normal mode that results in the falling +" motion. The semantics are as follows: +" +" The motion moves in the direction given by a:dir (which must be 'j' or 'k'). +" The motion moves while the character under the cursor does not match the +" pattern, then it moves while the character under the cursor matches the +" pattern stopping when the character under the cursor does not match the +" pattern once again. +" +" ex. +" +" fall#fall('j', '^\s*$') +" +" for +" +" | t⌷is is some text +" | this is some other text +" | +" | +" | this is some bottom text +" | this is some other bottom text +" +" will return an expression to update the cursor position to: +" +" | this is some text +" | this is some other text +" | +" | +" | t⌷is is some bottom text +" | this is some other bottom text +" +" This works pretty well for navigating around languages that use indentation +" and lack braces for bodies, i.e. vimscript, ruby. Less well for python, but +" still okay. +function! fall#fall(dir, pattern) abort + let i = 0 + let n = 0 + + if a:dir == 'j' + let delta = 1 + else + let delta = -1 + endif + + let line = line('.') + let column = col('.') + let c = v:count + if c == 0 + let c = 1 + endif + + while i < c + let match = matchstr(getline(line), '\%' . column . 'c.') + + while ! (match =~ a:pattern) + let n += 1 + let line += delta + if line <= 0 || line >= line('$') + return "m'" . n . a:dir + endif + let match = matchstr(getline(line), '\%' . column . 'c.') + endwhile + + while (match =~ a:pattern) + let n += 1 + let line += delta + if line <= 0 || line >= line('$') + return "m'" . n . a:dir + endif + let match = matchstr(getline(line), '\%' . column . 'c.') + endwhile + + let i += 1 + endwhile + + return "m'" . n . a:dir +endfunction! |