inital checkin using existing vim and preparing for use of bash_magic

This commit is contained in:
2012-05-06 12:17:04 -07:00
commit 064a074ddf
1555 changed files with 361845 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
.*.sw[a-z]
.*.un~
doc/tags

View File

@@ -0,0 +1,15 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2010 to 2011 Mick Koch <kchmck@gmail.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View File

@@ -0,0 +1,25 @@
REF = HEAD
VERSION = $(shell git describe --always $(REF))
ARCHIVE = vim-coffee-script-$(VERSION).zip
ARCHIVE_DIRS = after compiler ftdetect ftplugin indent syntax
# Don't do anything by default.
all:
# Make vim.org zipball.
archive:
git archive $(REF) -o $(ARCHIVE) -- $(ARCHIVE_DIRS)
# Remove zipball.
clean:
-rm -f $(ARCHIVE)
# Build the list of syntaxes for @coffeeAll.
coffeeAll:
@grep -E 'syn (match|region)' syntax/coffee.vim |\
grep -v 'contained' |\
awk '{print $$3}' |\
uniq
.PHONY: all archive clean hash coffeeAll

View File

@@ -0,0 +1,14 @@
### Version 001 (October 18, 2011)
Removed deprecated `coffee_folding` option, added `coffee_compile_vert` option,
split out compiler, fixed indentation and syntax bugs, and added Haml support
and omnicompletion.
- The coffee compiler is now a proper vim compiler that can be loaded with
`:compiler coffee`.
- The `coffee_compile_vert` option can now be set to split the CoffeeCompile
buffer vertically by default.
- CoffeeScript is now highlighted inside the `:coffeescript` filter in Haml.
- Omnicompletion (`:help compl-omni`) now uses JavaScript's dictionary to
complete words.
- We now have a fancy version number.

View File

@@ -0,0 +1,241 @@
This project adds [CoffeeScript] support to the vim editor. It handles syntax,
indenting, and compiling. Also included is an [eco] syntax and support for
CoffeeScript in Haml and HTML.
![Screenshot](http://i.imgur.com/BV29H.png)
[CoffeeScript]: http://jashkenas.github.com/coffee-script/
[eco]: https://github.com/sstephenson/eco
### Install from a Zipball
This is the quickest way to get things running.
1. Download the latest zipball from [vim.org][zipball-vim] or
[github][zipball-github]. The latest version on github is under Download
Packages (don't use the Download buttons.)
2. Extract the archive into `~/.vim/`:
unzip -od ~/.vim vim-coffee-script-HASH.zip
These steps are also used to update the plugin.
[zipball-vim]: http://www.vim.org/scripts/script.php?script_id=3590
[zipball-github]: https://github.com/kchmck/vim-coffee-script/downloads
### Install with Pathogen
Since this plugin has rolling versions based on git commits, using pathogen and
git is the preferred way to install. The plugin ends up contained in its own
directory and updates are just a `git pull` away.
1. Install tpope's [pathogen] into `~/.vim/autoload/` and add this line to your
`vimrc`:
call pathogen#infect()
To get the all the features of this plugin, make sure you also have a
`filetype plugin indent on` line in there.
[pathogen]: http://www.vim.org/scripts/script.php?script_id=2332
2. Create and change into `~/.vim/bundle/`:
$ mkdir ~/.vim/bundle
$ cd ~/.vim/bundle
3. Make a clone of the `vim-coffee-script` repository:
$ git clone https://github.com/kchmck/vim-coffee-script.git
#### Updating
1. Change into `~/.vim/bundle/vim-coffee-script/`:
$ cd ~/.vim/bundle/vim-coffee-script
2. Pull in the latest changes:
$ git pull
### CoffeeMake: Compile the Current File
The `CoffeeMake` command compiles the current file and parses any errors:
![CoffeeMake](http://i.imgur.com/OKRKE.png)
![CoffeeMake](http://i.imgur.com/PQ6ed.png)
![CoffeeMake](http://i.imgur.com/Jp6NI.png)
The full signature of the command is:
:[silent] CoffeeMake[!] [COFFEE-OPTIONS]...
By default, `CoffeeMake` shows all compiler output and jumps to the first line
reported as an error by `coffee`:
:CoffeeMake
Compiler output can be hidden with `silent`:
:silent CoffeeMake
Line-jumping can be turned off by adding a bang:
:CoffeeMake!
Options given to `CoffeeMake` are passed along to `coffee`:
:CoffeeMake --bare
`CoffeeMake` can be manually loaded for a file with:
:compiler coffee
#### Recompile on write
To recompile a file when it's written, add an `autocmd` like this to your
`vimrc`:
au BufWritePost *.coffee silent CoffeeMake!
All of the customizations above can be used, too. This one compiles silently
and with the `-b` option, but shows any errors:
au BufWritePost *.coffee silent CoffeeMake! -b | cwindow | redraw!
The `redraw!` command is needed to fix a redrawing quirk in terminal vim, but
can removed for gVim.
#### Default compiler options
The `CoffeeMake` command passes any options in the `coffee_make_options`
variable along to the compiler. You can use this to set default options:
let coffee_make_options = "--bare"
### CoffeeCompile: Compile Snippets of CoffeeScript
The `CoffeeCompile` command shows how the current file or a snippet of
CoffeeScript is compiled to JavaScript. The full signature of the command is:
:[RANGE] CoffeeCompile [watch|unwatch] [vert[ical]] [WINDOW-SIZE]
Calling `CoffeeCompile` without a range compiles the whole file:
![CoffeeCompile](http://i.imgur.com/pTesp.png)
![Compiled](http://i.imgur.com/81QMf.png)
Calling `CoffeeCompile` with a range, like in visual mode, compiles the selected
snippet of CoffeeScript:
![CoffeeCompile Snippet](http://i.imgur.com/Rm7iu.png)
![Compiled Snippet](http://i.imgur.com/KmrG8.png)
This scratch buffer can be quickly closed by hitting the `q` key.
Using `vert` splits the CoffeeCompile buffer vertically instead of horizontally:
:CoffeeCompile vert
Set the `coffee_compile_vert` variable to split the buffer vertically by
default:
let coffee_compile_vert = 1
The initial size of the CoffeeCompile buffer can be given as a number:
:CoffeeCompile 4
#### Watch (live preview) mode
Watch mode is like the Try CoffeeScript preview box on the CoffeeScript
homepage:
![Watch Mode](http://i.imgur.com/wIN6h.png)
![Watch Mode](http://i.imgur.com/GgdCo.png)
![Watch Mode](http://i.imgur.com/QdpAP.png)
Writing some code and then exiting insert mode automatically updates the
compiled JavaScript buffer.
Use `watch` to start watching a buffer (`vert` is also recommended):
:CoffeeCompile watch vert
After making some changes in insert mode, hit escape and the CoffeeScript will
be recompiled. Changes made outside of insert mode don't trigger this recompile,
but calling `CoffeeCompile` will compile these changes without any bad effects.
To get synchronized scrolling of a CoffeeScript and CoffeeCompile buffer, set
`scrollbind` on each:
:setl scrollbind
Use `unwatch` to stop watching a buffer:
:CoffeeCompile unwatch
### CoffeeRun: Run some CoffeeScript
The `CoffeeRun` command compiles the current file or selected snippet and runs
the resulting JavaScript. Output is shown at the bottom of the screen:
![CoffeeRun](http://i.imgur.com/d4yXC.png)
![CoffeeRun Output](http://i.imgur.com/m6UID.png)
### Configure Syntax Highlighting
Add these lines to your `vimrc` to disable the relevant syntax group.
#### Disable trailing whitespace error
Trailing whitespace is highlighted as an error by default. This can be disabled
with:
hi link coffeeSpaceError NONE
#### Disable trailing semicolon error
Trailing semicolons are also considered an error (for help transitioning from
JavaScript.) This can be disabled with:
hi link coffeeSemicolonError NONE
#### Disable reserved words error
Reserved words like `function` and `var` are highlighted as an error where
they're not allowed in CoffeeScript. This can be disabled with:
hi link coffeeReservedError NONE
### Tune Vim for CoffeeScript
Changing these core settings can make vim more CoffeeScript friendly.
#### Fold by indentation
Folding by indentation works well for CoffeeScript functions and classes:
![Folding](http://i.imgur.com/lpDWo.png)
To fold by indentation in CoffeeScript files, add this line to your `vimrc`:
au BufNewFile,BufReadPost *.coffee setl foldmethod=indent nofoldenable
With this, folding is disabled by default but can be quickly toggled per-file
by hitting `zi`. To enable folding by default, remove `nofoldenable`:
au BufNewFile,BufReadPost *.coffee setl foldmethod=indent
#### Two-space indentation
To get standard two-space indentation in CoffeeScript files, add this line to
your `vimrc`:
au BufNewFile,BufReadPost *.coffee setl shiftwidth=2 expandtab

View File

@@ -0,0 +1,44 @@
Thanks to all bug reporters, and special thanks to those who have contributed
code:
Brian Egan (brianegan):
Initial compiling support
Ches Martin (ches):
Initial vim docs
Chris Hoffman (cehoffman):
Add new keywoards from, to, and do
Highlight the - in negative integers
Add here regex highlighting, increase fold level for here docs
David Wilhelm (bigfish):
CoffeeRun command
Jay Adkisson (jayferd):
Support for eco templates
Karl Guertin (grayrest)
Cakefiles are coffeescript
Maciej Konieczny (narfdotpl):
Fix funny typo
Matt Sacks (mattsa):
Javascript omni-completion
coffee_compile_vert option
Nick Stenning (nickstenning):
Fold by indentation for coffeescript
Simon Lipp (sloonz):
Trailing spaces are not error on lines containing only spaces
Stéphan Kochen (stephank):
Initial HTML CoffeeScript highlighting
Sven Felix Oberquelle (Svelix):
Haml CoffeeScript highlighting
Wei Dai (clvv):
Fix the use of Vim built-in make command.

View File

@@ -0,0 +1 @@
- Don't highlight bad operator combinations

View File

@@ -0,0 +1,9 @@
" Language: CoffeeScript
" Maintainer: Sven Felix Oberquelle <Svelix.Github@gmail.com>
" URL: http://github.com/kchmck/vim-coffee-script
" License: WTFPL
" Inherit coffee from html so coffeeComment isn't redefined and given higher
" priority than hamlInterpolation.
syn cluster hamlCoffeescript contains=@htmlCoffeeScript
syn region hamlCoffeescriptFilter matchgroup=hamlFilter start="^\z(\s*\):coffeescript\s*$" end="^\%(\z1 \| *$\)\@!" contains=@hamlCoffeeScript,hamlInterpolation keepend

View File

@@ -0,0 +1,10 @@
" Language: CoffeeScript
" Maintainer: Mick Koch <kchmck@gmail.com>
" URL: http://github.com/kchmck/vim-coffee-script
" License: WTFPL
" Syntax highlighting for text/coffeescript script tags
syn include @htmlCoffeeScript syntax/coffee.vim
syn region coffeeScript start=+<script [^>]*type *=[^>]*text/coffeescript[^>]*>+
\ end=+</script>+me=s-1 keepend
\ contains=@htmlCoffeeScript,htmlScriptTag,@htmlPreproc

View File

@@ -0,0 +1,68 @@
" Language: CoffeeScript
" Maintainer: Mick Koch <kchmck@gmail.com>
" URL: http://github.com/kchmck/vim-coffee-script
" License: WTFPL
if exists('current_compiler')
finish
endif
let current_compiler = 'coffee'
" Pattern to check if coffee is the compiler
let s:pat = '^' . current_compiler
" Extra options passed to CoffeeMake
if !exists("coffee_make_options")
let coffee_make_options = ""
endif
" Get a `makeprg` for the current filename. This is needed to support filenames
" with spaces and quotes, but also not break generic `make`.
function! s:GetMakePrg()
return 'coffee -c ' . g:coffee_make_options . ' $* ' . fnameescape(expand('%'))
endfunction
" Set `makeprg` and return 1 if coffee is still the compiler, else return 0.
function! s:SetMakePrg()
if &l:makeprg =~ s:pat
let &l:makeprg = s:GetMakePrg()
elseif &g:makeprg =~ s:pat
let &g:makeprg = s:GetMakePrg()
else
return 0
endif
return 1
endfunction
" Set a dummy compiler so we can check whether to set locally or globally.
CompilerSet makeprg=coffee
call s:SetMakePrg()
CompilerSet errorformat=Error:\ In\ %f\\,\ %m\ on\ line\ %l,
\Error:\ In\ %f\\,\ Parse\ error\ on\ line\ %l:\ %m,
\SyntaxError:\ In\ %f\\,\ %m,
\%-G%.%#
" Compile the current file.
command! -bang -bar -nargs=* CoffeeMake make<bang> <args>
" Set `makeprg` on rename since we embed the filename in the setting.
augroup CoffeeUpdateMakePrg
autocmd!
" Update `makeprg` if coffee is still the compiler, else stop running this
" function.
function! s:UpdateMakePrg()
if !s:SetMakePrg()
autocmd! CoffeeUpdateMakePrg
endif
endfunction
" Set autocmd locally if compiler was set locally.
if &l:makeprg =~ s:pat
autocmd BufFilePost,BufWritePost <buffer> call s:UpdateMakePrg()
else
autocmd BufFilePost,BufWritePost call s:UpdateMakePrg()
endif
augroup END

View File

@@ -0,0 +1,116 @@
*coffee-script.txt* For Vim version 7.3
=============================================================================
Author: Mick Koch <kchmck@gmail.com> *coffee-script-author*
License: WTFPL (see |coffee-script-license|)
=============================================================================
CONTENTS *coffee-script-contents*
|coffee-script-introduction| Introduction and Feature Summary
|coffee-script-commands| Commands
|coffee-script-settings| Settings
{Vi does not have any of this}
=============================================================================
INTRODUCTION *coffee-script*
*coffee-script-introduction*
This plugin adds support for CoffeeScript syntax, indenting, and compiling.
Also included is an eco syntax and support for CoffeeScript in Haml and HTML.
COMMANDS *coffee-script-commands*
*:CoffeeMake*
:CoffeeMake[!] {opts} Wrapper around |:make| that also passes options in
|g:coffee_make_options| to the compiler. Use |:silent|
to hide compiler output. See |:make| for more
information about the bang and other helpful commands.
*:CoffeeCompile*
:[range]CoffeeCompile [vertical] [{win-size}]
Shows how the current file or [range] is compiled
to JavaScript. [vertical] (or vert) splits the
compile buffer vertically instead of horizontally, and
{win-size} sets the initial size of the buffer. It can
be closed quickly with the "q" key.
:CoffeeCompile {watch} [vertical] [{win-size}]
The watch mode of :CoffeeCompile emulates the "Try
CoffeeScript" live preview on the CoffeeScript web
site. After making changes to the source file,
exiting insert mode will cause the preview buffer to
update automatically. {watch} should be given as
"watch" or "unwatch," where the latter will stop the
automatic updating. [vertical] is recommended, and
'scrollbind' is useful.
*:CoffeeRun*
:[range]CoffeeRun Compiles the file or [range] and runs the resulting
JavaScript, displaying the output.
SETTINGS *coffee-script-settings*
You can configure plugin behavior using global variables and syntax commands
in your |vimrc|.
Global Settings~
*g:coffee_make_options*
Set default options |CoffeeMake| should pass to the compiler.
>
let coffee_make_options = '--bare'
<
*g:coffee_compile_vert*
Split the CoffeeCompile buffer vertically by default.
>
let coffee_compile_vert = 1
Syntax Highlighting~
*ft-coffee-script-syntax*
Trailing whitespace is highlighted as an error by default. This can be
disabled with:
>
hi link coffeeSpaceError NONE
Trailing semicolons are also considered an error (for help transitioning from
JavaScript.) This can be disabled with:
>
hi link coffeeSemicolonError NONE
Reserved words like {function} and {var} are highlighted where they're not
allowed in CoffeeScript. This can be disabled with:
>
hi link coffeeReservedError NONE
COMPILER *compiler-coffee-script*
A CoffeeScript compiler is provided as a wrapper around {coffee} and can be
loaded with;
>
compiler coffee
This is done automatically when a CoffeeScript file is opened if no other
compiler is loaded.
=============================================================================
LICENSE *coffee-script-license*
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2010 to 2011 Mick Koch <kchmck@gmail.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
vim:tw=78:ts=8:ft=help:norl:

View File

@@ -0,0 +1,8 @@
" Language: CoffeeScript
" Maintainer: Mick Koch <kchmck@gmail.com>
" URL: http://github.com/kchmck/vim-coffee-script
" License: WTFPL
autocmd BufNewFile,BufRead *.coffee set filetype=coffee
autocmd BufNewFile,BufRead *Cakefile set filetype=coffee
autocmd BufNewFile,BufRead *.coffeekup set filetype=coffee

View File

@@ -0,0 +1 @@
autocmd BufNewFile,BufRead *.eco set filetype=eco

View File

@@ -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

View File

@@ -0,0 +1,338 @@
" Language: CoffeeScript
" Maintainer: Mick Koch <kchmck@gmail.com>
" URL: http://github.com/kchmck/vim-coffee-script
" License: WTFPL
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
setlocal autoindent
setlocal indentexpr=GetCoffeeIndent(v:lnum)
" Make sure GetCoffeeIndent is run when these are typed so they can be
" indented or outdented.
setlocal indentkeys+=0],0),0.,=else,=when,=catch,=finally
" Only define the function once.
if exists("*GetCoffeeIndent")
finish
endif
" Keywords to indent after
let s:INDENT_AFTER_KEYWORD = '^\%(if\|unless\|else\|for\|while\|until\|'
\ . 'loop\|switch\|when\|try\|catch\|finally\|'
\ . 'class\)\>'
" Operators to indent after
let s:INDENT_AFTER_OPERATOR = '\%([([{:=]\|[-=]>\)$'
" Keywords and operators that continue a line
let s:CONTINUATION = '\<\%(is\|isnt\|and\|or\)\>$'
\ . '\|'
\ . '\%(-\@<!-\|+\@<!+\|<\|[-=]\@<!>\|\*\|/\@<!/\|%\||\|'
\ . '&\|,\|\.\@<!\.\)$'
" Operators that block continuation indenting
let s:CONTINUATION_BLOCK = '[([{:=]$'
" A continuation dot access
let s:DOT_ACCESS = '^\.'
" Keywords to outdent after
let s:OUTDENT_AFTER = '^\%(return\|break\|continue\|throw\)\>'
" A compound assignment like `... = if ...`
let s:COMPOUND_ASSIGNMENT = '[:=]\s*\%(if\|unless\|for\|while\|until\|'
\ . 'switch\|try\|class\)\>'
" A postfix condition like `return ... if ...`.
let s:POSTFIX_CONDITION = '\S\s\+\zs\<\%(if\|unless\)\>'
" A single-line else statement like `else ...` but not `else if ...
let s:SINGLE_LINE_ELSE = '^else\s\+\%(\<\%(if\|unless\)\>\)\@!'
" Max lines to look back for a match
let s:MAX_LOOKBACK = 50
" Syntax names for strings
let s:SYNTAX_STRING = 'coffee\%(String\|AssignString\|Embed\|Regex\|Heregex\|'
\ . 'Heredoc\)'
" Syntax names for comments
let s:SYNTAX_COMMENT = 'coffee\%(Comment\|BlockComment\|HeregexComment\)'
" Syntax names for strings and comments
let s:SYNTAX_STRING_COMMENT = s:SYNTAX_STRING . '\|' . s:SYNTAX_COMMENT
" Get the linked syntax name of a character.
function! s:SyntaxName(linenum, col)
return synIDattr(synID(a:linenum, a:col, 1), 'name')
endfunction
" Check if a character is in a comment.
function! s:IsComment(linenum, col)
return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_COMMENT
endfunction
" Check if a character is in a string.
function! s:IsString(linenum, col)
return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING
endfunction
" Check if a character is in a comment or string.
function! s:IsCommentOrString(linenum, col)
return s:SyntaxName(a:linenum, a:col) =~ s:SYNTAX_STRING_COMMENT
endfunction
" Check if a whole line is a comment.
function! s:IsCommentLine(linenum)
" Check the first non-whitespace character.
return s:IsComment(a:linenum, indent(a:linenum) + 1)
endfunction
" Repeatedly search a line for a regex until one is found outside a string or
" comment.
function! s:SmartSearch(linenum, regex)
" Start at the first column.
let col = 0
" Search until there are no more matches, unless a good match is found.
while 1
call cursor(a:linenum, col + 1)
let [_, col] = searchpos(a:regex, 'cn', a:linenum)
" No more matches.
if !col
break
endif
if !s:IsCommentOrString(a:linenum, col)
return 1
endif
endwhile
" No good match found.
return 0
endfunction
" Skip a match if it's in a comment or string, is a single-line statement that
" isn't adjacent, or is a postfix condition.
function! s:ShouldSkip(startlinenum, linenum, col)
if s:IsCommentOrString(a:linenum, a:col)
return 1
endif
" Check for a single-line statement that isn't adjacent.
if s:SmartSearch(a:linenum, '\<then\>') && a:startlinenum - a:linenum > 1
return 1
endif
if s:SmartSearch(a:linenum, s:POSTFIX_CONDITION) &&
\ !s:SmartSearch(a:linenum, s:COMPOUND_ASSIGNMENT)
return 1
endif
return 0
endfunction
" Find the farthest line to look back to, capped to line 1 (zero and negative
" numbers cause bad things).
function! s:MaxLookback(startlinenum)
return max([1, a:startlinenum - s:MAX_LOOKBACK])
endfunction
" Get the skip expression for searchpair().
function! s:SkipExpr(startlinenum)
return "s:ShouldSkip(" . a:startlinenum . ", line('.'), col('.'))"
endfunction
" Search for pairs of text.
function! s:SearchPair(start, end)
" The cursor must be in the first column for regexes to match.
call cursor(0, 1)
let startlinenum = line('.')
" Don't need the W flag since MaxLookback caps the search to line 1.
return searchpair(a:start, '', a:end, 'bcn',
\ s:SkipExpr(startlinenum),
\ s:MaxLookback(startlinenum))
endfunction
" Try to find a previous matching line.
function! s:GetMatch(curline)
let firstchar = a:curline[0]
if firstchar == '}'
return s:SearchPair('{', '}')
elseif firstchar == ')'
return s:SearchPair('(', ')')
elseif firstchar == ']'
return s:SearchPair('\[', '\]')
elseif a:curline =~ '^else\>'
return s:SearchPair('\<\%(if\|unless\|when\)\>', '\<else\>')
elseif a:curline =~ '^catch\>'
return s:SearchPair('\<try\>', '\<catch\>')
elseif a:curline =~ '^finally\>'
return s:SearchPair('\<try\>', '\<finally\>')
endif
return 0
endfunction
" Get the nearest previous line that isn't a comment.
function! s:GetPrevNormalLine(startlinenum)
let curlinenum = a:startlinenum
while curlinenum > 0
let curlinenum = prevnonblank(curlinenum - 1)
if !s:IsCommentLine(curlinenum)
return curlinenum
endif
endwhile
return 0
endfunction
" Try to find a comment in a line.
function! s:FindComment(linenum)
let col = 0
while 1
call cursor(a:linenum, col + 1)
let [_, col] = searchpos('#', 'cn', a:linenum)
if !col
break
endif
if s:IsComment(a:linenum, col)
return col
endif
endwhile
return 0
endfunction
" Get a line without comments or surrounding whitespace.
function! s:GetTrimmedLine(linenum)
let comment = s:FindComment(a:linenum)
let line = getline(a:linenum)
if comment
" Subtract 1 to get to the column before the comment and another 1 for
" zero-based indexing.
let line = line[:comment - 2]
endif
return substitute(substitute(line, '^\s\+', '', ''),
\ '\s\+$', '', '')
endfunction
function! s:GetCoffeeIndent(curlinenum)
let prevlinenum = s:GetPrevNormalLine(a:curlinenum)
" Don't do anything if there's no previous line.
if !prevlinenum
return -1
endif
let curline = s:GetTrimmedLine(a:curlinenum)
" Try to find a previous matching statement. This handles outdenting.
let matchlinenum = s:GetMatch(curline)
if matchlinenum
return indent(matchlinenum)
endif
" Try to find a matching `when`.
if curline =~ '^when\>' && !s:SmartSearch(prevlinenum, '\<switch\>')
let linenum = a:curlinenum
while linenum > 0
let linenum = s:GetPrevNormalLine(linenum)
if getline(linenum) =~ '^\s*when\>'
return indent(linenum)
endif
endwhile
return -1
endif
let prevline = s:GetTrimmedLine(prevlinenum)
let previndent = indent(prevlinenum)
" Always indent after these operators.
if prevline =~ s:INDENT_AFTER_OPERATOR
return previndent + &shiftwidth
endif
" Indent after a continuation if it's the first.
if prevline =~ s:CONTINUATION
" If the line ends in a slash, make sure it isn't a regex.
if prevline =~ '/$'
" Move to the line so we can get the last column.
call cursor(prevlinenum)
if s:IsString(prevlinenum, col('$') - 1)
return -1
endif
endif
let prevprevlinenum = s:GetPrevNormalLine(prevlinenum)
" If the continuation is the first in the file, don't run the other checks.
if !prevprevlinenum
return previndent + &shiftwidth
endif
let prevprevline = s:GetTrimmedLine(prevprevlinenum)
if prevprevline !~ s:CONTINUATION && prevprevline !~ s:CONTINUATION_BLOCK
return previndent + &shiftwidth
endif
return -1
endif
" Indent after these keywords and compound assignments if they aren't a
" single-line statement.
if prevline =~ s:INDENT_AFTER_KEYWORD || prevline =~ s:COMPOUND_ASSIGNMENT
if !s:SmartSearch(prevlinenum, '\<then\>') && prevline !~ s:SINGLE_LINE_ELSE
return previndent + &shiftwidth
endif
return -1
endif
" Indent a dot access if it's the first.
if curline =~ s:DOT_ACCESS && prevline !~ s:DOT_ACCESS
return previndent + &shiftwidth
endif
" Outdent after these keywords if they don't have a postfix condition or are
" a single-line statement.
if prevline =~ s:OUTDENT_AFTER
if !s:SmartSearch(prevlinenum, s:POSTFIX_CONDITION) ||
\ s:SmartSearch(prevlinenum, '\<then\>')
return previndent - &shiftwidth
endif
endif
" No indenting or outdenting is needed.
return -1
endfunction
" Wrap s:GetCoffeeIndent to keep the cursor position.
function! GetCoffeeIndent(curlinenum)
let oldcursor = getpos('.')
let indent = s:GetCoffeeIndent(a:curlinenum)
call setpos('.', oldcursor)
return indent
endfunction

View File

@@ -0,0 +1,217 @@
" Language: CoffeeScript
" Maintainer: Mick Koch <kchmck@gmail.com>
" URL: http://github.com/kchmck/vim-coffee-script
" License: WTFPL
" Bail if our syntax is already loaded.
if exists('b:current_syntax') && b:current_syntax == 'coffee'
finish
endif
" Include JavaScript for coffeeEmbed.
syn include @coffeeJS syntax/javascript.vim
" Highlight long strings.
syn sync minlines=100
" CoffeeScript identifiers can have dollar signs.
setlocal isident+=$
" These are `matches` instead of `keywords` because vim's highlighting
" priority for keywords is higher than matches. This causes keywords to be
" highlighted inside matches, even if a match says it shouldn't contain them --
" like with coffeeAssign and coffeeDot.
syn match coffeeStatement /\<\%(return\|break\|continue\|throw\)\>/ display
hi def link coffeeStatement Statement
syn match coffeeRepeat /\<\%(for\|while\|until\|loop\)\>/ display
hi def link coffeeRepeat Repeat
syn match coffeeConditional /\<\%(if\|else\|unless\|switch\|when\|then\)\>/
\ display
hi def link coffeeConditional Conditional
syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display
hi def link coffeeException Exception
syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|do\)\>/
\ display
" The `own` keyword is only a keyword after `for`.
syn match coffeeKeyword /\<for\s\+own\>/ contained containedin=coffeeRepeat
\ display
hi def link coffeeKeyword Keyword
syn match coffeeOperator /\<\%(instanceof\|typeof\|delete\)\>/ display
hi def link coffeeOperator Operator
" The first case matches symbol operators only if they have an operand before.
syn match coffeeExtendedOp /\%(\S\s*\)\@<=[+\-*/%&|\^=!<>?.]\+\|[-=]>\|--\|++\|:/
\ display
syn match coffeeExtendedOp /\<\%(and\|or\)=/ display
hi def link coffeeExtendedOp coffeeOperator
" This is separate from `coffeeExtendedOp` to help differentiate commas from
" dots.
syn match coffeeSpecialOp /[,;]/ display
hi def link coffeeSpecialOp SpecialChar
syn match coffeeBoolean /\<\%(true\|on\|yes\|false\|off\|no\)\>/ display
hi def link coffeeBoolean Boolean
syn match coffeeGlobal /\<\%(null\|undefined\)\>/ display
hi def link coffeeGlobal Type
" A special variable
syn match coffeeSpecialVar /\<\%(this\|prototype\|arguments\)\>/ display
" An @-variable
syn match coffeeSpecialVar /@\%(\I\i*\)\?/ display
hi def link coffeeSpecialVar Special
" A class-like name that starts with a capital letter
syn match coffeeObject /\<\u\w*\>/ display
hi def link coffeeObject Structure
" A constant-like name in SCREAMING_CAPS
syn match coffeeConstant /\<\u[A-Z0-9_]\+\>/ display
hi def link coffeeConstant Constant
" A variable name
syn cluster coffeeIdentifier contains=coffeeSpecialVar,coffeeObject,
\ coffeeConstant
" A non-interpolated string
syn cluster coffeeBasicString contains=@Spell,coffeeEscape
" An interpolated string
syn cluster coffeeInterpString contains=@coffeeBasicString,coffeeInterp
" Regular strings
syn region coffeeString start=/"/ skip=/\\\\\|\\"/ end=/"/
\ contains=@coffeeInterpString
syn region coffeeString start=/'/ skip=/\\\\\|\\'/ end=/'/
\ contains=@coffeeBasicString
hi def link coffeeString String
" A integer, including a leading plus or minus
syn match coffeeNumber /\i\@<![-+]\?\d\+\%([eE][+-]\?\d\+\)\?/ display
" A hex number
syn match coffeeNumber /\<0[xX]\x\+\>/ display
syn match coffeeNumber /\<0b[01]\+\>/ display
hi def link coffeeNumber Number
" A floating-point number, including a leading plus or minus
syn match coffeeFloat /\i\@<![-+]\?\d*\.\@<!\.\d\+\%([eE][+-]\?\d\+\)\?/
\ display
hi def link coffeeFloat Float
" An error for reserved keywords
if !exists("coffee_no_reserved_words_error")
syn match coffeeReservedError /\<\%(case\|default\|function\|var\|void\|with\|const\|let\|enum\|export\|import\|native\|__hasProp\|__extends\|__slice\|__bind\|__indexOf\)\>/
\ display
hi def link coffeeReservedError Error
endif
" A normal object assignment
syn match coffeeObjAssign /@\?\I\i*\s*\ze::\@!/ contains=@coffeeIdentifier display
hi def link coffeeObjAssign Identifier
syn keyword coffeeTodo TODO FIXME XXX contained
hi def link coffeeTodo Todo
syn match coffeeComment /#.*/ contains=@Spell,coffeeTodo
hi def link coffeeComment Comment
syn region coffeeBlockComment start=/####\@!/ end=/###/
\ contains=@Spell,coffeeTodo
hi def link coffeeBlockComment coffeeComment
" A comment in a heregex
syn region coffeeHeregexComment start=/#/ end=/\ze\/\/\/\|$/ contained
\ contains=@Spell,coffeeTodo
hi def link coffeeHeregexComment coffeeComment
" Embedded JavaScript
syn region coffeeEmbed matchgroup=coffeeEmbedDelim
\ start=/`/ skip=/\\\\\|\\`/ end=/`/
\ contains=@coffeeJS
hi def link coffeeEmbedDelim Delimiter
syn region coffeeInterp matchgroup=coffeeInterpDelim start=/#{/ end=/}/ contained
\ contains=@coffeeAll
hi def link coffeeInterpDelim PreProc
" A string escape sequence
syn match coffeeEscape /\\\d\d\d\|\\x\x\{2\}\|\\u\x\{4\}\|\\./ contained display
hi def link coffeeEscape SpecialChar
" A regex -- must not follow a parenthesis, number, or identifier, and must not
" be followed by a number
syn region coffeeRegex start=/\%(\%()\|\i\@<!\d\)\s*\|\i\)\@<!\/=\@!\s\@!/
\ skip=/\[[^\]]\{-}\/[^\]]\{-}\]/
\ end=/\/[gimy]\{,4}\d\@!/
\ oneline contains=@coffeeBasicString
hi def link coffeeRegex String
" A heregex
syn region coffeeHeregex start=/\/\/\// end=/\/\/\/[gimy]\{,4}/
\ contains=@coffeeInterpString,coffeeHeregexComment
\ fold
hi def link coffeeHeregex coffeeRegex
" Heredoc strings
syn region coffeeHeredoc start=/"""/ end=/"""/ contains=@coffeeInterpString
\ fold
syn region coffeeHeredoc start=/'''/ end=/'''/ contains=@coffeeBasicString
\ fold
hi def link coffeeHeredoc String
" An error for trailing whitespace, as long as the line isn't just whitespace
if !exists("coffee_no_trailing_space_error")
syn match coffeeSpaceError /\S\@<=\s\+$/ display
hi def link coffeeSpaceError Error
endif
" An error for trailing semicolons, for help transitioning from JavaScript
if !exists("coffee_no_trailing_semicolon_error")
syn match coffeeSemicolonError /;$/ display
hi def link coffeeSemicolonError Error
endif
" Ignore reserved words in dot accesses.
syn match coffeeDotAccess /\.\@<!\.\s*\I\i*/he=s+1 contains=@coffeeIdentifier
hi def link coffeeDotAccess coffeeExtendedOp
" Ignore reserved words in prototype accesses.
syn match coffeeProtoAccess /::\s*\I\i*/he=s+2 contains=@coffeeIdentifier
hi def link coffeeProtoAccess coffeeExtendedOp
" This is required for interpolations to work.
syn region coffeeCurlies matchgroup=coffeeCurly start=/{/ end=/}/
\ contains=@coffeeAll
syn region coffeeBrackets matchgroup=coffeeBracket start=/\[/ end=/\]/
\ contains=@coffeeAll
syn region coffeeParens matchgroup=coffeeParen start=/(/ end=/)/
\ contains=@coffeeAll
" These are highlighted the same as commas since they tend to go together.
hi def link coffeeBlock coffeeSpecialOp
hi def link coffeeBracket coffeeBlock
hi def link coffeeCurly coffeeBlock
hi def link coffeeParen coffeeBlock
" This is used instead of TOP to keep things coffee-specific for good
" embedding. `contained` groups aren't included.
syn cluster coffeeAll contains=coffeeStatement,coffeeRepeat,coffeeConditional,
\ coffeeException,coffeeKeyword,coffeeOperator,
\ coffeeExtendedOp,coffeeSpecialOp,coffeeBoolean,
\ coffeeGlobal,coffeeSpecialVar,coffeeObject,
\ coffeeConstant,coffeeString,coffeeNumber,
\ coffeeFloat,coffeeReservedError,coffeeObjAssign,
\ coffeeComment,coffeeBlockComment,coffeeEmbed,
\ coffeeRegex,coffeeHeregex,coffeeHeredoc,
\ coffeeSpaceError,coffeeSemicolonError,
\ coffeeDotAccess,coffeeProtoAccess,
\ coffeeCurlies,coffeeBrackets,coffeeParens
if !exists('b:current_syntax')
let b:current_syntax = 'coffee'
endif

View File

@@ -0,0 +1,62 @@
" Vim syntax file
" Language: eco
" Maintainer: Jay Adkisson
" Mostly stolen from eruby.vim
if !exists("g:eco_default_subtype")
let g:eco_default_subtype = "html"
endif
if !exists("b:eco_subtype")
let s:lines = getline(1)."\n".getline(2)."\n".getline(3)."\n".getline(4)."\n".getline(5)."\n".getline("$")
let b:eco_subtype = matchstr(s:lines,'eco_subtype=\zs\w\+')
if b:eco_subtype == ''
let b:eco_subtype = matchstr(substitute(expand("%:t"),'\c\%(\.eco\)\+$','',''),'\.\zs\w\+$')
endif
if b:eco_subtype == 'rhtml'
let b:eco_subtype = 'html'
elseif b:eco_subtype == 'jst'
let b:eco_subtype = 'html'
elseif b:eco_subtype == 'rb'
let b:eco_subtype = 'ruby'
elseif b:eco_subtype == 'yml'
let b:eco_subtype = 'yaml'
elseif b:eco_subtype == 'js' || b:eco_subtype == 'json'
let b:eco_subtype = 'javascript'
elseif b:eco_subtype == 'txt'
" Conventional; not a real file type
let b:eco_subtype = 'text'
elseif b:eco_subtype == ''
if exists('b:current_syntax') && b:current_syntax != ''
let b:eco_subtype = b:current_syntax
else
let b:eco_subtype = g:eco_default_subtype
endif
endif
endif
if exists("b:eco_subtype") && b:eco_subtype != '' && b:eco_subtype != 'eco'
exec "runtime! syntax/".b:eco_subtype.".vim"
syn include @coffeeTop syntax/coffee.vim
endif
syn cluster ecoRegions contains=ecoBlock,ecoExpression,ecoComment
syn region ecoBlock matchgroup=ecoDelimiter start=/<%/ end=/%>/ contains=@coffeeTop containedin=ALLBUT,@ecoRegions keepend
syn region ecoExpression matchgroup=ecoDelimiter start=/<%[=\-]/ end=/%>/ contains=@coffeeTop containedin=ALLBUT,@ecoRegions keepend
syn region ecoComment matchgroup=ecoComment start=/<%#/ end=/%>/ contains=@coffeeTodo,@Spell containedin=ALLBUT,@ecoRegions keepend
" eco features not in coffeescript proper
syn keyword ecoEnd end containedin=@ecoRegions
syn match ecoIndentColon /\s+\w+:/ containedin=@ecoRegions
" Define the default highlighting.
hi def link ecoDelimiter Delimiter
hi def link ecoComment Comment
hi def link ecoEnd coffeeConditional
hi def link ecoIndentColon None
let b:current_syntax = 'eco'
" vim: nowrap sw=2 sts=2 ts=8:

View File

@@ -0,0 +1,12 @@
<html>
<%# comment %>
<%# basic %>
<%- foo = "1" %>
<%# interpolation %>
<%= " == #{ ( -> "LOL" )() } == " %>
<%# interpolation with nested curlies %>
<%= " == #{ { a: 1, b: { c: 3, d: 4 } } } == " %>
</html>

View File

@@ -0,0 +1,3 @@
# Nested curlies
" >> #{ == { { { } } } == } << "
" >> #{ == { abc: { def: 42 } } == } << "

View File

@@ -0,0 +1,90 @@
# Various operators
abc instanceof def
typeof abc
delete abc
abc::def
abc + def
abc - def
abc * def
abc / def
abc % def
abc & def
abc | def
abc ^ def
abc >> def
abc << def
abc >>> def
abc ? def
abc && def
abc and def
abc || def
abc or def
abc += def
abc -= def
abc *= def
abc /= def
abc %= def
abc &= def
abc |= def
abc ^= def
abc >>= def
abc <<= def
abc >>>= def
abc ?= def
abc &&= def
abc ||= def
abc and= def
abc or= def
abc.def.ghi
abc?.def?.ghi
abc < def
abc > def
abc = def
abc == def
abc != def
abc <= def
abc >= def
abc++
abc--
++abc
--abc
# Nested operators
abc[def] = ghi
abc[def[ghi: jkl]] = 42
@abc[def] = ghi
abc["#{def = 42}"] = 42
abc["#{def.ghi = 42}"] = 42
abc["#{def[ghi] = 42}"] = 42
abc["#{def['ghi']}"] = 42
# Object assignments
abc =
def: 123
DEF: 123
@def: 123
Def: 123
'def': 123
42: 123
# Operators shouldn't be highlighted
vector=
wand=
abc+++
abc---
abc ** def
abc &&& def
abc ^^ def
abc ===== def
abc <==== def
abc >==== def
abc +== def
abc =^= def

View File

@@ -0,0 +1,27 @@
# Should be an error
function = 42
var = 42
# Shouldn't be an error
abc.with = 42
function: 42
var: 42
# Keywords shouldn't be highlighted
abc.function
abc.do
abc.break
abc.true
abc::function
abc::do
abc::break
abc::true
abc:: function
abc. function
# Numbers should be highlighted
def.42
def .42
def::42

View File

@@ -0,0 +1,5 @@
<script type="text/coffeescript">
abc = {
def: 42
}
</script>