aboutsummaryrefslogtreecommitdiff
path: root/vim/ftplugin
diff options
context:
space:
mode:
Diffstat (limited to 'vim/ftplugin')
-rwxr-xr-xvim/ftplugin/coffee.vim221
1 files changed, 221 insertions, 0 deletions
diff --git a/vim/ftplugin/coffee.vim b/vim/ftplugin/coffee.vim
new file mode 100755
index 0000000..12ae3f0
--- /dev/null
+++ b/vim/ftplugin/coffee.vim
@@ -0,0 +1,221 @@
+" Language: CoffeeScript
+" Maintainer: Mick Koch <kchmck@gmail.com>
+" URL: http://github.com/kchmck/vim-coffee-script
+" License: WTFPL
+
+if exists("b:did_ftplugin")
+ finish
+endif
+
+let b:did_ftplugin = 1
+
+setlocal formatoptions-=t formatoptions+=croql
+setlocal comments=:#
+setlocal commentstring=#\ %s
+setlocal omnifunc=javascriptcomplete#CompleteJS
+
+" Enable CoffeeMake if it won't overwrite any settings.
+if !len(&l:makeprg)
+ compiler coffee
+endif
+
+" Reset the global variables used by CoffeeCompile.
+function! s:CoffeeCompileResetVars()
+ " Position in the source buffer
+ let s:coffee_compile_src_buf = -1
+ let s:coffee_compile_src_pos = []
+
+ " Position in the CoffeeCompile buffer
+ let s:coffee_compile_buf = -1
+ let s:coffee_compile_win = -1
+ let s:coffee_compile_pos = []
+
+ " If CoffeeCompile is watching a buffer
+ let s:coffee_compile_watch = 0
+endfunction
+
+" Save the cursor position when moving to and from the CoffeeCompile buffer.
+function! s:CoffeeCompileSavePos()
+ let buf = bufnr('%')
+ let pos = getpos('.')
+
+ if buf == s:coffee_compile_buf
+ let s:coffee_compile_pos = pos
+ else
+ let s:coffee_compile_src_buf = buf
+ let s:coffee_compile_src_pos = pos
+ endif
+endfunction
+
+" Restore the cursor to the source buffer.
+function! s:CoffeeCompileRestorePos()
+ let win = bufwinnr(s:coffee_compile_src_buf)
+
+ if win != -1
+ exec win 'wincmd w'
+ call setpos('.', s:coffee_compile_src_pos)
+ endif
+endfunction
+
+" Close the CoffeeCompile buffer and clean things up.
+function! s:CoffeeCompileClose()
+ silent! autocmd! CoffeeCompileAuPos
+ silent! autocmd! CoffeeCompileAuWatch
+
+ call s:CoffeeCompileRestorePos()
+ call s:CoffeeCompileResetVars()
+endfunction
+
+" Update the CoffeeCompile buffer given some input lines.
+function! s:CoffeeCompileUpdate(startline, endline)
+ let input = join(getline(a:startline, a:endline), "\n")
+
+ " Coffee doesn't like empty input.
+ if !len(input)
+ return
+ endif
+
+ " Compile input.
+ let output = system('coffee -scb 2>&1', input)
+
+ " Move to the CoffeeCompile buffer.
+ exec s:coffee_compile_win 'wincmd w'
+
+ " Replace buffer contents with new output and delete the last empty line.
+ setlocal modifiable
+ exec '% delete _'
+ put! =output
+ exec '$ delete _'
+ setlocal nomodifiable
+
+ " Highlight as JavaScript if there is no compile error.
+ if v:shell_error
+ setlocal filetype=
+ else
+ setlocal filetype=javascript
+ endif
+
+ " Restore the cursor in the compiled output.
+ call setpos('.', s:coffee_compile_pos)
+endfunction
+
+" Update the CoffeeCompile buffer with the whole source buffer and restore the
+" cursor.
+function! s:CoffeeCompileWatchUpdate()
+ call s:CoffeeCompileSavePos()
+ call s:CoffeeCompileUpdate(1, '$')
+ call s:CoffeeCompileRestorePos()
+endfunction
+
+" Peek at compiled CoffeeScript in a scratch buffer. We handle ranges like this
+" to prevent the cursor from being moved (and its position saved) before the
+" function is called.
+function! s:CoffeeCompile(startline, endline, args)
+ " Don't compile the CoffeeCompile buffer.
+ if bufnr('%') == s:coffee_compile_buf
+ return
+ endif
+
+ " Parse arguments.
+ let watch = a:args =~ '\<watch\>'
+ let unwatch = a:args =~ '\<unwatch\>'
+ let size = str2nr(matchstr(a:args, '\<\d\+\>'))
+
+ " Determine default split direction.
+ if exists("g:coffee_compile_vert")
+ let vert = 1
+ else
+ let vert = a:args =~ '\<vert\%[ical]\>'
+ endif
+
+ " Remove any watch listeners.
+ silent! autocmd! CoffeeCompileAuWatch
+
+ " If just unwatching, don't compile.
+ if unwatch
+ let s:coffee_compile_watch = 0
+ return
+ endif
+
+ if watch
+ let s:coffee_compile_watch = 1
+ endif
+
+ call s:CoffeeCompileSavePos()
+
+ " Build the CoffeeCompile buffer if it doesn't exist.
+ if s:coffee_compile_buf == -1
+ let src_win = bufwinnr(s:coffee_compile_src_buf)
+
+ " Create the new window and resize it.
+ if vert
+ let width = size ? size : winwidth(src_win) / 2
+
+ vertical new
+ exec 'vertical resize' width
+ else
+ " Try to guess the compiled output's height.
+ let height = size ? size : min([winheight(src_win) / 2,
+ \ a:endline - a:startline + 2])
+
+ botright new
+ exec 'resize' height
+ endif
+
+ " Set up scratch buffer.
+ setlocal bufhidden=wipe buftype=nofile
+ setlocal nobuflisted nomodifiable noswapfile nowrap
+
+ autocmd BufWipeout <buffer> call s:CoffeeCompileClose()
+ nnoremap <buffer> <silent> q :hide<CR>
+
+ " Save the cursor position on each buffer switch.
+ augroup CoffeeCompileAuPos
+ autocmd BufEnter,BufLeave * call s:CoffeeCompileSavePos()
+ augroup END
+
+ let s:coffee_compile_buf = bufnr('%')
+ let s:coffee_compile_win = bufwinnr(s:coffee_compile_buf)
+ endif
+
+ " Go back to the source buffer and do the initial compile.
+ call s:CoffeeCompileRestorePos()
+
+ if s:coffee_compile_watch
+ call s:CoffeeCompileWatchUpdate()
+
+ augroup CoffeeCompileAuWatch
+ autocmd InsertLeave <buffer> call s:CoffeeCompileWatchUpdate()
+ augroup END
+ else
+ call s:CoffeeCompileUpdate(a:startline, a:endline)
+ endif
+endfunction
+
+" Complete arguments for the CoffeeCompile command.
+function! s:CoffeeCompileComplete(arg, cmdline, cursor)
+ let args = ['unwatch', 'vertical', 'watch']
+
+ if !len(a:arg)
+ return args
+ endif
+
+ let match = '^' . a:arg
+
+ for arg in args
+ if arg =~ match
+ return [arg]
+ endif
+ endfor
+endfunction
+
+" Don't let new windows overwrite the CoffeeCompile variables.
+if !exists("s:coffee_compile_buf")
+ call s:CoffeeCompileResetVars()
+endif
+
+" Peek at compiled CoffeeScript.
+command! -range=% -bar -nargs=* -complete=customlist,s:CoffeeCompileComplete
+\ CoffeeCompile call s:CoffeeCompile(<line1>, <line2>, <q-args>)
+" Run some CoffeeScript.
+command! -range=% -bar CoffeeRun <line1>,<line2>:w !coffee -s