Commits

Josh VanderLinden committed bf0e93e

Finally syncing changes to my .vimrc

Comments (0)

Files changed (13)

.vim/after/syntax/haml.vim

+" 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

.vim/after/syntax/html.vim

+" 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
+\                       containedin=htmlHead

.vim/compiler/coffee.vim

+" 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

.vim/doc/coffee-script.txt

+*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:

.vim/ftdetect/coffee.vim

+" 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

.vim/ftdetect/eco.vim

+autocmd BufNewFile,BufRead *.eco set filetype=eco

.vim/ftplugin/coffee.vim

+" 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

.vim/indent/coffee.vim

+" 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

.vim/plugin/simplenote.vim

-"
-"
-" File: simplenote.vim
-" Author: Daniel Schauenberg <d@unwiredcouch.com>
-" WebPage: http://github.com/mrtazz/simplenote.vim
-" License: MIT
-" Version: 0.3.0
-" Usage:
-"   :Simplenote -l => list all notes
-"   :Simplenote -u => update a note from buffer
-"   :Simplenote -d => move note to trash
-"   :Simplenote -n => create new note from buffer
-"   :Simplenote -D => delete note in current buffer
-"   :Simplenote -t => tag note in current buffer
-"
-"
-
-if &cp || (exists('g:loaded_simplenote_vim') && g:loaded_simplenote_vim)
-  finish
-endif
-let g:loaded_simplenote_vim = 1
-
-" check for python
-if !has("python")
-  echoerr "Simplenote: Plugin needs vim to be compiled with python support."
-  finish
-endif
-
-" user auth settings
-if exists("g:SimplenoteUsername")
-  let s:user = g:SimplenoteUsername
-else
-  let s:user = ""
-endif
-
-if exists("g:SimplenotePassword")
-  let s:password = g:SimplenotePassword
-else
-  let s:password = ""
-endif
-
-if (s:user == "") || (s:password == "")
-  let errmsg = "Simplenote credentials missing. Set g:SimplenoteUsername and "
-  let errmsg = errmsg . "g:SimplenotePassword. If you don't have an account you can "
-  let errmsg = errmsg . "create one at https://simple-note.appspot.com/create/."
-  echoerr errmsg
-  finish
-endif
-
-"
-" Helper functions
-"
-
-" Everything is displayed in a scratch buffer named SimpleNote
-let g:simplenote_scratch_buffer = 'Simplenote'
-
-" Function that opens or navigates to the scratch buffer.
-function! s:ScratchBufferOpen(name)
-
-    let scr_bufnum = bufnr(a:name)
-    if scr_bufnum == -1
-        exe "new " . a:name
-    else
-        let scr_winnum = bufwinnr(scr_bufnum)
-        if scr_winnum != -1
-            if winnr() != scr_winnum
-                exe scr_winnum . "wincmd w"
-            endif
-        else
-            exe "split +buffer" . scr_bufnum
-        endif
-    endif
-    call s:ScratchBuffer()
-endfunction
-
-" After opening the scratch buffer, this sets some properties for it.
-function! s:ScratchBuffer()
-    setlocal buftype=nofile
-    setlocal bufhidden=hide
-    setlocal noswapfile
-    setlocal buflisted
-    setlocal cursorline
-    setlocal filetype=txt
-endfunction
-
-
-"
-" python functions
-"
-
-python << ENDPYTHON
-"""
-    simplenote.py
-    ~~~~~~~~~~~~~~
-
-    Python library for accessing the Simplenote API
-
-    :copyright: (c) 2011 by Daniel Schauenberg
-    :license: MIT, see LICENSE for more details.
-"""
-
-import urllib
-import urllib2
-import base64
-import json
-
-AUTH_URL = 'https://simple-note.appspot.com/api/login'
-DATA_URL = 'https://simple-note.appspot.com/api2/data'
-INDX_URL = 'https://simple-note.appspot.com/api2/index?'
-NOTE_FETCH_LENGTH = 20
-
-class Simplenote(object):
-    """ Class for interacting with the simplenote web service """
-
-    def __init__(self, username, password):
-        """ object constructor """
-        self.username = urllib2.quote(username)
-        self.password = urllib2.quote(password)
-        self.token = None
-
-    def authenticate(self, user, password):
-        """ Method to get simplenote auth token
-
-        Arguments:
-            - user (string):     simplenote email address
-            - password (string): simplenote password
-
-        Returns:
-            Simplenote API token as string
-
-        """
-        auth_params = "email=%s&password=%s" % (user, password)
-        values = base64.encodestring(auth_params)
-        request = Request(AUTH_URL, values)
-        try:
-            res = urllib2.urlopen(request).read()
-            token = urllib2.quote(res)
-        except IOError: # no connection exception
-            token = None
-        return token
-
-    def get_token(self):
-        """ Method to retrieve an auth token.
-
-        The cached global token is looked up and returned if it exists. If it
-        is `None` a new one is requested and returned.
-
-        Returns:
-            Simplenote API token as string
-
-        """
-        if self.token == None:
-            self.token = self.authenticate(self.username, self.password)
-        return self.token
-
-
-    def get_note(self, noteid):
-        """ method to get a specific note
-
-        Arguments:
-            - noteid (string): ID of the note to get
-
-        Returns:
-            A tuple `(note, status)`
-
-            - note (dict): note object
-            - status (int): 0 on sucesss and -1 otherwise
-
-        """
-        # request note
-        params = '/%s?auth=%s&email=%s' % (str(noteid), self.get_token(),
-                                           self.username)
-        request = Request(DATA_URL+params)
-        try:
-            response = urllib2.urlopen(request)
-        except IOError, e:
-            return e, -1
-        note = json.loads(response.read())
-        # use UTF-8 encoding
-        note["content"] = note["content"].encode('utf-8')
-        note["tags"] = [t.encode('utf-8') for t in note["tags"]]
-        return note, 0
-
-    def update_note(self, note):
-        """ function to update a specific note object, if the note object does not
-        have a "key" field, a new note is created
-
-        Arguments
-            - note (dict): note object to update
-
-        Returns:
-            A tuple `(note, status)`
-
-            - note (dict): note object
-            - status (int): 0 on sucesss and -1 otherwise
-
-        """
-        # use UTF-8 encoding
-        note["content"] = unicode(note["content"], 'utf-8')
-        if note.has_key("tags"):
-            note["tags"] = [unicode(t, 'utf-8') for t in note["tags"]]
-
-        # determine whether to create a new note or updated an existing one
-        if note.has_key("key"):
-            url = '%s/%s?auth=%s&email=%s' % (DATA_URL, note["key"],
-                                              self.get_token(), self.username)
-        else:
-            url = '%s?auth=%s&email=%s' % (DATA_URL, self.get_token(), self.username)
-        request = Request(url, urllib.quote(json.dumps(note)))
-        response = ""
-        try:
-            response = urllib2.urlopen(request).read()
-        except IOError, e:
-            return e, -1
-        return json.loads(response), 0
-
-    def add_note(self, note):
-        """wrapper function to add a note
-
-        The function can be passed the note as a dict with the `content`
-        property set, which is then directly send to the web service for
-        creation. Alternatively, only the body as string can also be passed. In
-        this case the parameter is used as `content` for the new note.
-
-        Arguments:
-            - note (dict or string): the note to add
-
-        Returns:
-            A tuple `(note, status)`
-
-            - note (dict): the newly created note
-            - status (int): 0 on sucesss and -1 otherwise
-
-        """
-        if type(note) == str:
-            return self.update_note({"content": note})
-        elif (type(note) == dict) and note.has_key("content"):
-            return self.update_note(note)
-        else:
-            return "No string or valid note.", -1
-
-    def get_note_list(self):
-        """ function to get the note list
-
-        Returns:
-            An array of note objects with all properties set except
-            `content`.
-
-        """
-        # initialize data
-        status = 0
-        ret = []
-        response = {}
-        notes = { "data" : [] }
-
-        # get the full note index
-        params = 'auth=%s&email=%s&length=%s' % (self.get_token(), self.username,
-                                                 NOTE_FETCH_LENGTH)
-        # perform initial HTTP request
-        try:
-            request = Request(INDX_URL+params)
-            response = json.loads(urllib2.urlopen(request).read())
-            notes["data"].extend(response["data"])
-        except IOError:
-            status = -1
-
-        # get additional notes if bookmark was set in response
-        while response.has_key("mark"):
-            vals = (self.get_token(), self.username, response["mark"], NOTE_FETCH_LENGTH)
-            params = 'auth=%s&email=%s&mark=%s&length=%s' % vals
-
-            # perform the actual HTTP request
-            try:
-                request = Request(INDX_URL+params)
-                response = json.loads(urllib2.urlopen(request).read())
-                notes["data"].extend(response["data"])
-            except IOError:
-                status = -1
-
-        # parse data fields in response
-        ret = notes["data"]
-
-        return ret, status
-
-    def trash_note(self, note_id):
-        """ method to move a note to the trash
-
-        Arguments:
-            - note_id (string): key of the note to trash
-
-        Returns:
-            A tuple `(note, status)`
-
-            - note (dict): the newly created note or an error message
-            - status (int): 0 on sucesss and -1 otherwise
-
-        """
-        # get note
-        note, status = self.get_note(note_id)
-        # set deleted property
-        note["deleted"] = 1
-        # update note
-        return self.update_note(note)
-
-    def delete_note(self, note_id):
-        """ method to permanently delete a note
-
-        Arguments:
-            - note_id (string): key of the note to trash
-
-        Returns:
-            A tuple `(note, status)`
-
-            - note (dict): an empty dict or an error message
-            - status (int): 0 on sucesss and -1 otherwise
-
-        """
-        # notes have to be trashed before deletion
-        self.trash_note(note_id)
-
-        params = '/%s?auth=%s&email=%s' % (str(note_id), self.get_token(),
-                                           self.username)
-        request = Request(url=DATA_URL+params, method='DELETE')
-        try:
-            urllib2.urlopen(request)
-        except IOError, e:
-            return e, -1
-        return {}, 0
-
-
-class Request(urllib2.Request):
-    """ monkey patched version of urllib2's Request to support HTTP DELETE
-        Taken from http://python-requests.org, thanks @kennethreitz
-    """
-
-    def __init__(self, url, data=None, headers={}, origin_req_host=None,
-                unverifiable=False, method=None):
-        urllib2.Request.__init__(self, url, data, headers, origin_req_host, unverifiable)
-        self.method = method
-
-    def get_method(self):
-        if self.method:
-            return self.method
-
-        return urllib2.Request.get_method(self)
-
-
-
-
-import vim
-import time
-from threading import Thread
-from Queue import Queue
-
-DEFAULT_SCRATCH_NAME = vim.eval("g:simplenote_scratch_buffer")
-SN_USER = vim.eval("s:user")
-SN_PASSWORD = vim.eval("s:password")
-
-class SimplenoteVimInterface(object):
-    """ Interface class to provide functions for interacting with VIM """
-
-    def __init__(self, username, password):
-        self.simplenote = Simplenote(username, password)
-        self.note_index = []
-
-    def get_current_note(self):
-        """ returns the key of the currently edited note """
-        filename = vim.current.buffer.name
-        key = filename.split("/")
-        return key[-1]
-
-    def set_current_note(self, key):
-        """ sets the key of the currently edited note """
-        vim.command(""" silent exe "file %s" """ % key)
-
-    def transform_to_scratchbuffer(self):
-        """ transforms the current buffer into a scratchbuffer """
-        vim.command("call s:ScratchBuffer()")
-        vim.command("setlocal nocursorline")
-
-    def format_title(self, note):
-        """ function to format the title for a note object
-
-        Arguments:
-        note -- note object to format the title for
-
-        Returns the formatted title
-
-        """
-        # fetch first line and display as title
-        note_lines = note["content"].split("\n")
-        # format date
-        mt = time.localtime(float(note["modifydate"]))
-        mod_time = time.strftime("%a, %d %b %Y %H:%M:%S", mt)
-        if len(note_lines) > 0:
-            title = "%s [%s]" % (note_lines[0], mod_time)
-        else:
-            title = "%s [%s]" % (note["key"], mod_time)
-
-        return (str(title)[0:80])
-
-
-    def get_notes_from_keys(self, key_list):
-        """ fetch all note objects for a list of keys via threads and return
-        them in a list
-
-        Arguments:
-        key_list - list of keys to fetch the key from
-
-        Returns list of fetched notes
-        """
-        queue = Queue()
-        note_list = []
-        for key in key_list:
-            queue.put(key)
-            t = NoteFetcher(queue, note_list, self.simplenote)
-            t.start()
-
-        queue.join()
-        return note_list
-
-    def scratch_buffer(self, sb_name = DEFAULT_SCRATCH_NAME):
-        """ Opens a scratch buffer from python
-
-        Arguments:
-        sb_name - name of the scratch buffer
-        """
-        vim.command("call s:ScratchBufferOpen('%s')" % sb_name)
-
-    def display_note_in_scratch_buffer(self):
-        """ displays the note corresponding to the given key in the scratch
-        buffer
-        """
-        # get the notes id which is shown in brackets in the current line
-        line, col = vim.current.window.cursor
-        note_id = self.note_index[int(line) - 1]
-        # store it as a global script variable
-        note, status = self.simplenote.get_note(note_id)
-        vim.command("""call s:ScratchBufferOpen("%s")""" % note_id)
-        self.set_current_note(note_id)
-        buffer = vim.current.buffer
-        # remove cursorline
-        vim.command("setlocal nocursorline")
-        vim.command("set buftype=acwrite")
-        vim.command("au! BufWriteCmd <buffer> call s:UpdateNoteFromCurrentBuffer()")
-        buffer[:] = map(lambda x: str(x), note["content"].split("\n"))
-
-    def update_note_from_current_buffer(self):
-        """ updates the currently displayed note to the web service """
-        note_id = self.get_current_note()
-        content = "\n".join(str(line) for line in vim.current.buffer[:])
-        note, status = self.simplenote.update_note({"content": content,
-                                                  "key": note_id})
-        if status == 0:
-            print "Update successful."
-        else:
-            print "Update failed.: %s" % note
-
-    def set_tags_for_current_note(self):
-        """ set tags for the current note"""
-        note_id = self.get_current_note()
-        note, status = self.simplenote.get_note(note_id)
-        if status == 0:
-            tags = vim.eval('input("Enter tags: ", "%s")'
-                            % ",".join(note["tags"]))
-            note["tags"] = tags.split(",")
-            n, st = self.simplenote.update_note(note)
-            if st == 0:
-                print "Tags updated."
-            else:
-                print "Tags could not be updated."
-        else:
-            print "Error fetching note data."
-
-
-    def trash_current_note(self):
-        """ trash the currently displayed note """
-        note_id = self.get_current_note()
-        note, status = self.simplenote.trash_note(note_id)
-        if status == 0:
-            print "Note moved to trash."
-            vim.command("quit!")
-        else:
-            print "Moving note to trash failed.: %s" % note
-
-    def delete_current_note(self):
-        """ trash the currently displayed note """
-        note_id = self.get_current_note()
-        note, status = self.simplenote.delete_note(note_id)
-        if status == 0:
-            print "Note deleted."
-            vim.command("quit!")
-        else:
-            print "Deleting note failed.: %s" % note
-
-    def create_new_note_from_current_buffer(self):
-        """ get content of the current buffer and create new note """
-        content = "\n".join(str(line) for line in vim.current.buffer[:])
-        note, status = self.simplenote.update_note({"content": content})
-        if status == 0:
-            self.transform_to_scratchbuffer()
-            self.set_current_note(note["key"])
-            print "New note created."
-        else:
-            print "Update failed.: %s" % note["key"]
-
-    def list_note_index_in_scratch_buffer(self):
-        """ get all available notes and display them in a scratchbuffer """
-        # Initialize the scratch buffer
-        self.scratch_buffer()
-        # clear global note id storage
-        buffer = vim.current.buffer
-        note_list, status = self.simplenote.get_note_list()
-        # set global notes index object to notes
-        if status == 0:
-            note_titles = []
-            notes = self.get_notes_from_keys([n['key'] for n in note_list])
-            notes.sort(key=lambda k: k['modifydate'])
-            notes.reverse()
-            note_titles = [self.format_title(n) for n in notes if n["deleted"] != 1]
-            self.note_index = [n["key"] for n in notes if n["deleted"] != 1]
-            buffer[:] = note_titles
-
-        else:
-            print "Error: Unable to connect to server."
-
-        # map <CR> to call get_note()
-        vim.command("map <buffer> <CR> <Esc>:call <SID>GetNoteToCurrentBuffer()<CR>")
-
-
-class NoteFetcher(Thread):
-    """ class to fetch a note running in a thread
-
-    The note key is fetched from a queue object and
-    the note is then retrieved and put in
-
-    """
-    def __init__(self, queue, note_list, simplenote):
-        Thread.__init__(self)
-        self.queue = queue
-        self.note_list = note_list
-        self.simplenote = simplenote
-
-    def run(self):
-        key = self.queue.get()
-        note, status = self.simplenote.get_note(key)
-        self.note_list.append(note)
-        self.queue.task_done()
-
-interface = SimplenoteVimInterface(SN_USER, SN_PASSWORD)
-
-
-ENDPYTHON
-
-"
-" interface functions
-"
-
-
-" function to get a note and display in current buffer
-function! s:GetNoteToCurrentBuffer()
-python << EOF
-interface.display_note_in_scratch_buffer()
-EOF
-endfunction
-
-" function to update note from buffer content
-function! s:UpdateNoteFromCurrentBuffer()
-python << EOF
-interface.update_note_from_current_buffer()
-EOF
-endfunction
-
-function! s:SimpleNote(param)
-python << EOF
-param = vim.eval("a:param")
-if param == "-l":
-    interface.list_note_index_in_scratch_buffer()
-
-elif param == "-d":
-    interface.trash_current_note()
-
-elif param == "-u":
-    interface.update_note_from_current_buffer()
-
-elif param == "-n":
-    interface.create_new_note_from_current_buffer()
-
-elif param == "-D":
-    interface.delete_current_note()
-
-elif param == "-t":
-    interface.set_tags_for_current_note()
-
-else:
-    print "Unknown argument"
-
-EOF
-endfunction
-
-
-" set the simplenote command
-command! -nargs=1 Simplenote :call <SID>SimpleNote(<f-args>)

.vim/syntax/coffee.vim

+" 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

.vim/syntax/eco.vim

+" 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:

.vim/syntax/sikuli.vim

+/home/wheaties/repos/vim-sikuli/sikuli.vim
-set expandtab shiftwidth=4 tabstop=4 list hidden nowritebackup nobackup spelllang=en_us spellsuggest=5 ruler textwidth=0 hlsearch wrap cursorline incsearch smartindent paste ignorecase
+set expandtab shiftwidth=4 tabstop=4 list hidden nowritebackup nobackup
+set spelllang=en_us spellsuggest=5 ruler textwidth=0 hlsearch wrap cursorline
+set incsearch smartindent paste ignorecase
 set wildcharm=<Tab> wildmenu wildmode=full
 " set cursorline cursorcolumn
 
 
 " Replace stuff with line number :%s/\v^\[ ?\d+]/\=line(".")/
 
-" Look for templates for the specified file extension
-autocmd BufNewFile * silent! 0r ~/.vim/templates/%:e.tpl
-
 " Trim all trailing whitespace before saving
 autocmd BufWritePre * :%s/[ \t\r]\+$//e
 
 " autocmd FileType html,htm exe ":silent 1,$!tidy --indent yes -q"
 
 " autocmd FocusLost *.inc,*.php,*.html,*.js,*.css :w
-autocmd BufEnter,BufRead,BufNewFile *.inc,*.phtml,*.php setlocal shiftwidth=2 tabstop=2 syntax=php nolist
-autocmd BufEnter,BufRead,BufNewFile *.html setlocal shiftwidth=2 tabstop=2 syntax=html nolist
-autocmd BufEnter,BufRead,BufNewFile *.xml,*.rml setlocal shiftwidth=2 tabstop=2 syntax=xml nolist
-autocmd BufEnter,BufRead,BufNewFile *.css setlocal shiftwidth=2 tabstop=2 syntax=css nolist
-autocmd BufEnter,BufRead,BufNewFile *.js setlocal shiftwidth=2 tabstop=2 syntax=javascript nolist
-autocmd BufEnter,BufRead,BufNewFile *.pde setlocal shiftwidth=2 tabstop=2 syntax=c nolist ft=arduino
+au BufEnter,BufRead,BufNewFile *.inc,*.phtml,*.php setlocal shiftwidth=2 tabstop=2 syntax=php nolist
+au BufEnter,BufRead,BufNewFile *.htm,*.html setlocal shiftwidth=2 tabstop=2 syntax=html nolist
+au BufEnter,BufRead,BufNewFile *.xml,*.rml setlocal shiftwidth=2 tabstop=2 syntax=xml nolist
+au BufEnter,BufRead,BufNewFile *.css setlocal shiftwidth=2 tabstop=2 syntax=css nolist
+au BufEnter,BufRead,BufNewFile *.js setlocal shiftwidth=2 tabstop=2 syntax=javascript nolist
+au BufEnter,BufRead,BufNewFile *.pde setlocal shiftwidth=2 tabstop=2 syntax=c nolist ft=arduino
+au BufEnter,BufRead,BufNewFile *.coffee setlocal shiftwidth=2 tabstop=2 syntax=coffee nolist
+au BufEnter,BufRead,BufNewFile *.rb setlocal shiftwidth=2 tabstop=2 syntax=ruby nolist
+au BufEnter,BufRead,BufNewFile *.hs setlocal shiftwidth=2 tabstop=2 syntax=haskell nolist
+"au BufWritePost *.coffee silent CoffeeMake! | cwindow
 
 " Highlight trailing spaces
 autocmd ColorScheme * highlight ExtraWhitespace ctermbg=darkgreen guibg=darkgreen
 nnoremap <Leader>, :cp<CR>zz
 
 " Handy for adding an IPython interactive shell for debugging
-nnoremap <Leader>d ifrom IPython.Shell import IPShellEmbed; IPShellEmbed()()<Esc>
+nnoremap <Leader>d iimport IPython; IPython.embed()<Esc>
 
 " Space before and after (for math like a+b/c)
 nnoremap <Leader>ba i <Esc>la <Esc>
     let derp = system("xdotool search --name 'Vimperator' windowactivate key Escape key Escape type R")
     let derp = system("xdotool windowactivate ".mywid)
 endfunction
-
-source ~/.simplenoterc