diff --git a/README b/README new file mode 100644 index 0000000..0e4f5cb --- /dev/null +++ b/README @@ -0,0 +1,20 @@ +This is a mirror of http://www.vim.org/scripts/script.php?script_id=3724 + +indent-motion is a Vim plugin which maps `[` and `]` in normal, visual, and operator-pending modes to move to the beginning and end (respectively) of your current indentation-delimited block (`` refers to your current user-defined "mapleader", which is `\` by default). + +For example (using JavaScript): + + function foo(a, b, c) { + var x = 1; + var y = 2; + if (x == y) { + alert("This will never happen!"); + ++y; + } + } + +In the above snippet, if the cursor is positioned on the `var x = 1;` line, then `]` will move the cursor to the next-to-last line (closing brace of the conditional block) and `[` will move it back to the original location. If the cursor is positioned on the `alert` call, then `]` will move down 1 line to `++y;`. + +If one of the mappings is executed on an empty line (containing no characters, not even whitespace), then the assumed indentation will be that of the next non-empty line, where "next" is in the direction of the requested motion. + +Currently, the mappings are not configurable, but this can easily be changed upon request. diff --git a/plugin/indent-motion.vim b/plugin/indent-motion.vim new file mode 100644 index 0000000..21472a5 --- /dev/null +++ b/plugin/indent-motion.vim @@ -0,0 +1,47 @@ +function! s:next_line(l, up) + let nl = a:l + (a:up ? -1 : 1) + if nl < 1 || nl > line('$') + throw 'buf_bound' + endif + return nl +endfunction + +function! to_indent_end(up, vis) + + let ln = line('.') + if indent(ln) == 0 && getline(ln) =~ '^$' + while getline(ln) =~ '^$' + try + let ln = s:next_line(ln, a:up) + catch 'buf_bound' + break + endtry + endwhile + endif + let orig_ind = indent(ln) + + try + let ln = s:next_line(line('.'), a:up) + catch 'buf_bound' + return + endtry + if a:vis + normal! gv + endif + while indent(ln) >= orig_ind || getline(ln) =~ '^$' + execute 'normal! ' . (a:up ? 'k' : 'j') + try + let ln = s:next_line(ln, a:up) + catch 'buf_bound' + return + endtry + endwhile + +endfunction + +nnoremap ] :call to_indent_end(0, 0) +nnoremap [ :call to_indent_end(1, 0) +onoremap ] :call to_indent_end(0, 0) +onoremap [ :call to_indent_end(1, 0) +vnoremap ] :call to_indent_end(0, 1) +vnoremap [ :call to_indent_end(1, 1)