]> git.r.bdr.sh - rbdr/dotfiles/blob - vim/ftplugin/coffee.vim
6af14963d0860feb5f96dfc1e7f8f0e3e9099f33
[rbdr/dotfiles] / vim / ftplugin / coffee.vim
1 " Language: CoffeeScript
2 " Maintainer: Mick Koch <kchmck@gmail.com>
3 " URL: http://github.com/kchmck/vim-coffee-script
4 " License: WTFPL
5
6 if exists("b:did_ftplugin")
7 finish
8 endif
9
10 let b:did_ftplugin = 1
11
12 setlocal formatoptions-=t formatoptions+=croql
13 setlocal comments=:#
14 setlocal commentstring=#\ %s
15
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,
19 \%-G%.%#
20
21 " Extra options passed to CoffeeMake
22 if !exists("coffee_make_options")
23 let coffee_make_options = ""
24 endif
25
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('%'))
31 endfunction
32
33 " Set `makeprg` initially.
34 call s:SetMakePrg()
35 " Set `makeprg` on rename.
36 autocmd BufFilePost,BufWritePost,FileWritePost <buffer> call s:SetMakePrg()
37
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 = []
43
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 = []
48
49 " If CoffeeCompile is watching a buffer
50 let s:coffee_compile_watch = 0
51 endfunction
52
53 " Save the cursor position when moving to and from the CoffeeCompile buffer.
54 function! s:CoffeeCompileSavePos()
55 let buf = bufnr('%')
56 let pos = getpos('.')
57
58 if buf == s:coffee_compile_buf
59 let s:coffee_compile_pos = pos
60 else
61 let s:coffee_compile_src_buf = buf
62 let s:coffee_compile_src_pos = pos
63 endif
64 endfunction
65
66 " Restore the cursor to the source buffer.
67 function! s:CoffeeCompileRestorePos()
68 let win = bufwinnr(s:coffee_compile_src_buf)
69
70 if win != -1
71 exec win 'wincmd w'
72 call setpos('.', s:coffee_compile_src_pos)
73 endif
74 endfunction
75
76 " Close the CoffeeCompile buffer and clean things up.
77 function! s:CoffeeCompileClose()
78 silent! autocmd! CoffeeCompileAuPos
79 silent! autocmd! CoffeeCompileAuWatch
80
81 call s:CoffeeCompileRestorePos()
82 call s:CoffeeCompileResetVars()
83 endfunction
84
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")
88
89 " Coffee doesn't like empty input.
90 if !len(input)
91 return
92 endif
93
94 " Compile input.
95 let output = system('coffee -scb 2>&1', input)
96
97 " Move to the CoffeeCompile buffer.
98 exec s:coffee_compile_win 'wincmd w'
99
100 " Replace buffer contents with new output and delete the last empty line.
101 setlocal modifiable
102 exec '% delete _'
103 put! =output
104 exec '$ delete _'
105 setlocal nomodifiable
106
107 " Highlight as JavaScript if there is no compile error.
108 if v:shell_error
109 setlocal filetype=
110 else
111 setlocal filetype=javascript
112 endif
113
114 " Restore the cursor in the compiled output.
115 call setpos('.', s:coffee_compile_pos)
116 endfunction
117
118 " Update the CoffeeCompile buffer with the whole source buffer and restore the
119 " cursor.
120 function! s:CoffeeCompileWatchUpdate()
121 call s:CoffeeCompileSavePos()
122 call s:CoffeeCompileUpdate(1, '$')
123 call s:CoffeeCompileRestorePos()
124 endfunction
125
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
132 return
133 endif
134
135 " Parse arguments.
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\+\>'))
140
141 " Remove any watch listeners.
142 silent! autocmd! CoffeeCompileAuWatch
143
144 " If just unwatching, don't compile.
145 if unwatch
146 let s:coffee_compile_watch = 0
147 return
148 endif
149
150 if watch
151 let s:coffee_compile_watch = 1
152 endif
153
154 call s:CoffeeCompileSavePos()
155
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)
159
160 " Create the new window and resize it.
161 if vert
162 let width = size ? size : winwidth(src_win) / 2
163
164 vertical new
165 exec 'vertical resize' width
166 else
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])
170
171 botright new
172 exec 'resize' height
173 endif
174
175 " Set up scratch buffer.
176 setlocal bufhidden=wipe buftype=nofile
177 setlocal nobuflisted nomodifiable noswapfile nowrap
178
179 autocmd BufWipeout <buffer> call s:CoffeeCompileClose()
180 nnoremap <buffer> <silent> q :hide<CR>
181
182 " Save the cursor position on each buffer switch.
183 augroup CoffeeCompileAuPos
184 autocmd BufEnter,BufLeave * call s:CoffeeCompileSavePos()
185 augroup END
186
187 let s:coffee_compile_buf = bufnr('%')
188 let s:coffee_compile_win = bufwinnr(s:coffee_compile_buf)
189 endif
190
191 " Go back to the source buffer and do the initial compile.
192 call s:CoffeeCompileRestorePos()
193
194 if s:coffee_compile_watch
195 call s:CoffeeCompileWatchUpdate()
196
197 augroup CoffeeCompileAuWatch
198 autocmd InsertLeave <buffer> call s:CoffeeCompileWatchUpdate()
199 augroup END
200 else
201 call s:CoffeeCompileUpdate(a:startline, a:endline)
202 endif
203 endfunction
204
205 " Complete arguments for the CoffeeCompile command.
206 function! s:CoffeeCompileComplete(arg, cmdline, cursor)
207 let args = ['unwatch', 'vertical', 'watch']
208
209 if !len(a:arg)
210 return args
211 endif
212
213 let match = '^' . a:arg
214
215 for arg in args
216 if arg =~ match
217 return [arg]
218 endif
219 endfor
220 endfunction
221
222 " Don't let new windows overwrite the CoffeeCompile variables.
223 if !exists("s:coffee_compile_buf")
224 call s:CoffeeCompileResetVars()
225 endif
226
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