Skip to content

Instantly share code, notes, and snippets.

@inducer
Created September 11, 2017 16:02
Show Gist options
  • Save inducer/6623af757740f8b64baa51961fc1a92d to your computer and use it in GitHub Desktop.
Save inducer/6623af757740f8b64baa51961fc1a92d to your computer and use it in GitHub Desktop.
Block-based navigation in Vim
" {{{ python: block-based navigation
if has("python")
" pyblock.vim
"au FileType python map ( :python move_same_indent(-1)<enter>
"au FileType python map ) :python move_same_indent(1)<enter>
"au FileType python map { :python move_outer_indent(-1)<enter>
"au FileType python map } :python move_outer_indent(1)<enter>
python << EOF
def count_indent(line):
import vim
i = 0
tab_width = int(vim.eval("&tabstop"))
for s in line:
if s == ' ':
i += 1
elif s == '\t':
i += tab_width
else:
return i
return 0
def move_by_indent(end_pred, direction):
import vim
buf = vim.current.buffer
row, col = vim.current.window.cursor
row -= 1
start_indent = count_indent(buf[row])
while True:
row += direction
# bail if we hit the end
if row < 0 or row >= len(buf):
break
# skip over empty lines
if not buf[row].strip():
continue
if end_pred(count_indent(buf[row]), start_indent):
break
row = max(0, min(len(buf)-1, row))
vim.current.window.cursor = row+1, col
def move_same_indent(direction):
move_by_indent(
lambda indent, s_indent: indent <= s_indent,
direction)
def move_outer_indent(direction):
move_by_indent(
lambda indent, s_indent: indent < s_indent,
direction)
EOF
endif
" }}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment