" 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!