1
0

coffee.vim 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. " Language: CoffeeScript
  2. " Maintainer: Mick Koch <kchmck@gmail.com>
  3. " URL: http://github.com/kchmck/vim-coffee-script
  4. " License: WTFPL
  5. if exists("b:did_ftplugin")
  6. finish
  7. endif
  8. let b:did_ftplugin = 1
  9. setlocal formatoptions-=t formatoptions+=croql
  10. setlocal comments=:#
  11. setlocal commentstring=#\ %s
  12. setlocal omnifunc=javascriptcomplete#CompleteJS
  13. " Enable CoffeeMake if it won't overwrite any settings.
  14. if !len(&l:makeprg)
  15. compiler coffee
  16. endif
  17. " Reset the global variables used by CoffeeCompile.
  18. function! s:CoffeeCompileResetVars()
  19. " Position in the source buffer
  20. let s:coffee_compile_src_buf = -1
  21. let s:coffee_compile_src_pos = []
  22. " Position in the CoffeeCompile buffer
  23. let s:coffee_compile_buf = -1
  24. let s:coffee_compile_win = -1
  25. let s:coffee_compile_pos = []
  26. " If CoffeeCompile is watching a buffer
  27. let s:coffee_compile_watch = 0
  28. endfunction
  29. " Save the cursor position when moving to and from the CoffeeCompile buffer.
  30. function! s:CoffeeCompileSavePos()
  31. let buf = bufnr('%')
  32. let pos = getpos('.')
  33. if buf == s:coffee_compile_buf
  34. let s:coffee_compile_pos = pos
  35. else
  36. let s:coffee_compile_src_buf = buf
  37. let s:coffee_compile_src_pos = pos
  38. endif
  39. endfunction
  40. " Restore the cursor to the source buffer.
  41. function! s:CoffeeCompileRestorePos()
  42. let win = bufwinnr(s:coffee_compile_src_buf)
  43. if win != -1
  44. exec win 'wincmd w'
  45. call setpos('.', s:coffee_compile_src_pos)
  46. endif
  47. endfunction
  48. " Close the CoffeeCompile buffer and clean things up.
  49. function! s:CoffeeCompileClose()
  50. silent! autocmd! CoffeeCompileAuPos
  51. silent! autocmd! CoffeeCompileAuWatch
  52. call s:CoffeeCompileRestorePos()
  53. call s:CoffeeCompileResetVars()
  54. endfunction
  55. " Update the CoffeeCompile buffer given some input lines.
  56. function! s:CoffeeCompileUpdate(startline, endline)
  57. let input = join(getline(a:startline, a:endline), "\n")
  58. " Coffee doesn't like empty input.
  59. if !len(input)
  60. return
  61. endif
  62. " Compile input.
  63. let output = system('coffee -scb 2>&1', input)
  64. " Move to the CoffeeCompile buffer.
  65. exec s:coffee_compile_win 'wincmd w'
  66. " Replace buffer contents with new output and delete the last empty line.
  67. setlocal modifiable
  68. exec '% delete _'
  69. put! =output
  70. exec '$ delete _'
  71. setlocal nomodifiable
  72. " Highlight as JavaScript if there is no compile error.
  73. if v:shell_error
  74. setlocal filetype=
  75. else
  76. setlocal filetype=javascript
  77. endif
  78. " Restore the cursor in the compiled output.
  79. call setpos('.', s:coffee_compile_pos)
  80. endfunction
  81. " Update the CoffeeCompile buffer with the whole source buffer and restore the
  82. " cursor.
  83. function! s:CoffeeCompileWatchUpdate()
  84. call s:CoffeeCompileSavePos()
  85. call s:CoffeeCompileUpdate(1, '$')
  86. call s:CoffeeCompileRestorePos()
  87. endfunction
  88. " Peek at compiled CoffeeScript in a scratch buffer. We handle ranges like this
  89. " to prevent the cursor from being moved (and its position saved) before the
  90. " function is called.
  91. function! s:CoffeeCompile(startline, endline, args)
  92. " Don't compile the CoffeeCompile buffer.
  93. if bufnr('%') == s:coffee_compile_buf
  94. return
  95. endif
  96. " Parse arguments.
  97. let watch = a:args =~ '\<watch\>'
  98. let unwatch = a:args =~ '\<unwatch\>'
  99. let size = str2nr(matchstr(a:args, '\<\d\+\>'))
  100. " Determine default split direction.
  101. if exists("g:coffee_compile_vert")
  102. let vert = 1
  103. else
  104. let vert = a:args =~ '\<vert\%[ical]\>'
  105. endif
  106. " Remove any watch listeners.
  107. silent! autocmd! CoffeeCompileAuWatch
  108. " If just unwatching, don't compile.
  109. if unwatch
  110. let s:coffee_compile_watch = 0
  111. return
  112. endif
  113. if watch
  114. let s:coffee_compile_watch = 1
  115. endif
  116. call s:CoffeeCompileSavePos()
  117. " Build the CoffeeCompile buffer if it doesn't exist.
  118. if s:coffee_compile_buf == -1
  119. let src_win = bufwinnr(s:coffee_compile_src_buf)
  120. " Create the new window and resize it.
  121. if vert
  122. let width = size ? size : winwidth(src_win) / 2
  123. vertical new
  124. exec 'vertical resize' width
  125. else
  126. " Try to guess the compiled output's height.
  127. let height = size ? size : min([winheight(src_win) / 2,
  128. \ a:endline - a:startline + 2])
  129. botright new
  130. exec 'resize' height
  131. endif
  132. " Set up scratch buffer.
  133. setlocal bufhidden=wipe buftype=nofile
  134. setlocal nobuflisted nomodifiable noswapfile nowrap
  135. autocmd BufWipeout <buffer> call s:CoffeeCompileClose()
  136. nnoremap <buffer> <silent> q :hide<CR>
  137. " Save the cursor position on each buffer switch.
  138. augroup CoffeeCompileAuPos
  139. autocmd BufEnter,BufLeave * call s:CoffeeCompileSavePos()
  140. augroup END
  141. let s:coffee_compile_buf = bufnr('%')
  142. let s:coffee_compile_win = bufwinnr(s:coffee_compile_buf)
  143. endif
  144. " Go back to the source buffer and do the initial compile.
  145. call s:CoffeeCompileRestorePos()
  146. if s:coffee_compile_watch
  147. call s:CoffeeCompileWatchUpdate()
  148. augroup CoffeeCompileAuWatch
  149. autocmd InsertLeave <buffer> call s:CoffeeCompileWatchUpdate()
  150. augroup END
  151. else
  152. call s:CoffeeCompileUpdate(a:startline, a:endline)
  153. endif
  154. endfunction
  155. " Complete arguments for the CoffeeCompile command.
  156. function! s:CoffeeCompileComplete(arg, cmdline, cursor)
  157. let args = ['unwatch', 'vertical', 'watch']
  158. if !len(a:arg)
  159. return args
  160. endif
  161. let match = '^' . a:arg
  162. for arg in args
  163. if arg =~ match
  164. return [arg]
  165. endif
  166. endfor
  167. endfunction
  168. " Don't let new windows overwrite the CoffeeCompile variables.
  169. if !exists("s:coffee_compile_buf")
  170. call s:CoffeeCompileResetVars()
  171. endif
  172. " Peek at compiled CoffeeScript.
  173. command! -range=% -bar -nargs=* -complete=customlist,s:CoffeeCompileComplete
  174. \ CoffeeCompile call s:CoffeeCompile(<line1>, <line2>, <q-args>)
  175. " Run some CoffeeScript.
  176. command! -range=% -bar CoffeeRun <line1>,<line2>:w !coffee -s