1 " Language: CoffeeScript
2 " Maintainer: Mick Koch <kchmck@gmail.com>
3 " URL: http://github.com/kchmck/vim-coffee-script
6 if exists("b:did_ftplugin")
10 let b:did_ftplugin = 1
12 setlocal formatoptions-=t formatoptions+=croql
14 setlocal commentstring=#\ %s
16 setlocal errorformat=Error:\ In\ %f\\,\ %m\ on\ line\ %l,
17 \Error:\ In\ %f\\,\ Parse\ error\ on\ line\ %l:\ %m,
18 \SyntaxError:\ In\ %f\\,\ %m,
21 " Extra options passed to CoffeeMake
22 if !exists("coffee_make_options")
23 let coffee_make_options = ""
26 " Update `makeprg` for the current filename. This is needed to support filenames
27 " with spaces and quotes while also supporting generic `make`.
28 function! s:SetMakePrg()
29 let &l:makeprg = "coffee -c " . g:coffee_make_options . ' $* '
30 \ . fnameescape(expand('%'))
33 " Set `makeprg` initially.
35 " Set `makeprg` on rename.
36 autocmd BufFilePost,BufWritePost,FileWritePost <buffer> call s:SetMakePrg()
38 " Reset the global variables used by CoffeeCompile.
39 function! s:CoffeeCompileResetVars()
40 " Position in the source buffer
41 let s:coffee_compile_src_buf = -1
42 let s:coffee_compile_src_pos = []
44 " Position in the CoffeeCompile buffer
45 let s:coffee_compile_buf = -1
46 let s:coffee_compile_win = -1
47 let s:coffee_compile_pos = []
49 " If CoffeeCompile is watching a buffer
50 let s:coffee_compile_watch = 0
53 " Save the cursor position when moving to and from the CoffeeCompile buffer.
54 function! s:CoffeeCompileSavePos()
58 if buf == s:coffee_compile_buf
59 let s:coffee_compile_pos = pos
61 let s:coffee_compile_src_buf = buf
62 let s:coffee_compile_src_pos = pos
66 " Restore the cursor to the source buffer.
67 function! s:CoffeeCompileRestorePos()
68 let win = bufwinnr(s:coffee_compile_src_buf)
72 call setpos('.', s:coffee_compile_src_pos)
76 " Close the CoffeeCompile buffer and clean things up.
77 function! s:CoffeeCompileClose()
78 silent! autocmd! CoffeeCompileAuPos
79 silent! autocmd! CoffeeCompileAuWatch
81 call s:CoffeeCompileRestorePos()
82 call s:CoffeeCompileResetVars()
85 " Update the CoffeeCompile buffer given some input lines.
86 function! s:CoffeeCompileUpdate(startline, endline)
87 let input = join(getline(a:startline, a:endline), "\n")
89 " Coffee doesn't like empty input.
95 let output = system('coffee -scb 2>&1', input)
97 " Move to the CoffeeCompile buffer.
98 exec s:coffee_compile_win 'wincmd w'
100 " Replace buffer contents with new output and delete the last empty line.
105 setlocal nomodifiable
107 " Highlight as JavaScript if there is no compile error.
111 setlocal filetype=javascript
114 " Restore the cursor in the compiled output.
115 call setpos('.', s:coffee_compile_pos)
118 " Update the CoffeeCompile buffer with the whole source buffer and restore the
120 function! s:CoffeeCompileWatchUpdate()
121 call s:CoffeeCompileSavePos()
122 call s:CoffeeCompileUpdate(1, '$')
123 call s:CoffeeCompileRestorePos()
126 " Peek at compiled CoffeeScript in a scratch buffer. We handle ranges like this
127 " to prevent the cursor from being moved (and its position saved) before the
128 " function is called.
129 function! s:CoffeeCompile(startline, endline, args)
130 " Don't compile the CoffeeCompile buffer.
131 if bufnr('%') == s:coffee_compile_buf
136 let watch = a:args =~ '\<watch\>'
137 let unwatch = a:args =~ '\<unwatch\>'
138 let vert = a:args =~ '\<vert\%[ical]\>'
139 let size = str2nr(matchstr(a:args, '\<\d\+\>'))
141 " Remove any watch listeners.
142 silent! autocmd! CoffeeCompileAuWatch
144 " If just unwatching, don't compile.
146 let s:coffee_compile_watch = 0
151 let s:coffee_compile_watch = 1
154 call s:CoffeeCompileSavePos()
156 " Build the CoffeeCompile buffer if it doesn't exist.
157 if s:coffee_compile_buf == -1
158 let src_win = bufwinnr(s:coffee_compile_src_buf)
160 " Create the new window and resize it.
162 let width = size ? size : winwidth(src_win) / 2
165 exec 'vertical resize' width
167 " Try to guess the compiled output's height.
168 let height = size ? size : min([winheight(src_win) / 2,
169 \ a:endline - a:startline + 2])
175 " Set up scratch buffer.
176 setlocal bufhidden=wipe buftype=nofile
177 setlocal nobuflisted nomodifiable noswapfile nowrap
179 autocmd BufWipeout <buffer> call s:CoffeeCompileClose()
180 nnoremap <buffer> <silent> q :hide<CR>
182 " Save the cursor position on each buffer switch.
183 augroup CoffeeCompileAuPos
184 autocmd BufEnter,BufLeave * call s:CoffeeCompileSavePos()
187 let s:coffee_compile_buf = bufnr('%')
188 let s:coffee_compile_win = bufwinnr(s:coffee_compile_buf)
191 " Go back to the source buffer and do the initial compile.
192 call s:CoffeeCompileRestorePos()
194 if s:coffee_compile_watch
195 call s:CoffeeCompileWatchUpdate()
197 augroup CoffeeCompileAuWatch
198 autocmd InsertLeave <buffer> call s:CoffeeCompileWatchUpdate()
201 call s:CoffeeCompileUpdate(a:startline, a:endline)
205 " Complete arguments for the CoffeeCompile command.
206 function! s:CoffeeCompileComplete(arg, cmdline, cursor)
207 let args = ['unwatch', 'vertical', 'watch']
213 let match = '^' . a:arg
222 " Don't let new windows overwrite the CoffeeCompile variables.
223 if !exists("s:coffee_compile_buf")
224 call s:CoffeeCompileResetVars()
227 " Peek at compiled CoffeeScript.
228 command! -range=% -bar -nargs=* -complete=customlist,s:CoffeeCompileComplete
229 \ CoffeeCompile call s:CoffeeCompile(<line1>, <line2>, <q-args>)
230 " Compile the current file.
231 command! -bang -bar -nargs=* CoffeeMake make<bang> <args>
232 " Run some CoffeeScript.
233 command! -range=% -bar CoffeeRun <line1>,<line2>:w !coffee -s