Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@AndrewRadev
Created July 21, 2012 10:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrewRadev/3155336 to your computer and use it in GitHub Desktop.
Save AndrewRadev/3155336 to your computer and use it in GitHub Desktop.
Wrapping and unwrapping coffeescript code blocks
" See http://andrewradev.com/2012/04/03/manipulating-coffeescript-with-vim-part-1-text-objects/
" for details on the implementation
nnoremap ,O : call <SID>OpenWrappingLineAbove('n')<cr>
xnoremap ,O :<c-u>call <SID>OpenWrappingLineAbove('v')<cr>
nnoremap ,dh : call <SID>DeleteWrappingLine('n')<cr>
xnoremap ,dh :<c-u>call <SID>DeleteWrappingLine('v')<cr>
function! s:OpenWrappingLineAbove(mode)
if a:mode ==# 'v'
let start = line("'<")
let end = line("'>")
else
let start = line('.')
let end = s:LowerIndentLimit(start)
endif
let indent = indent(start)
call s:IncreaseIndent(start, end, 1)
normal! O
call s:SetIndent(line('.'), line('.'), indent)
call feedkeys('A')
undojoin
endfunction
function! s:DeleteWrappingLine(mode)
if a:mode ==# 'v'
let start_line = line("'<")
let end_line = line("'>")
let new_current_line = nextnonblank(end_line + 1)
if end_line == line('$')
let indent = 0
else
let indent = indent(new_current_line) - indent(start_line)
endif
let amount = indent / &sw
exe "'<,'>delete"
else
let amount = 1
normal! dd
endif
let start = line('.')
let end = s:LowerIndentLimit(start)
call s:DecreaseIndent(start, end, amount)
endfunction
function! s:LowerIndentLimit(lineno)
let base_indent = indent(a:lineno)
let current_line = a:lineno
let next_line = nextnonblank(current_line + 1)
while current_line < line('$') && indent(next_line) >= base_indent
let current_line = next_line
let next_line = nextnonblank(current_line + 1)
endwhile
return current_line
endfunction
function! s:UpperIndentLimit(lineno)
let base_indent = indent(a:lineno)
let current_line = a:lineno
let prev_line = prevnonblank(current_line - 1)
while current_line > 0 && indent(prev_line) >= base_indent
let current_line = prev_line
let prev_line = prevnonblank(current_line - 1)
endwhile
return current_line
endfunction
function! s:SetIndent(from, to, indent)
let saved_cursor = getpos('.')
exe a:from.','.a:to.'s/^\s*/'.repeat(' ', a:indent)
call setpos('.', saved_cursor)
endfunction
function! s:IncreaseIndent(from, to, amount)
let saved_cursor = getpos('.')
let command = repeat('>', a:amount)
exe a:from.','.a:to.command
call setpos('.', saved_cursor)
endfunction
function! s:DecreaseIndent(from, to, amount)
let saved_cursor = getpos('.')
let command = repeat('<', a:amount)
exe a:from.','.a:to.command
call setpos('.', saved_cursor)
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment