Rewrite indent/coffee.vim

 - Be much more conservative with non-blank lines, so now running = on an entire
   file hopefully works as expected. Running gg=G on the coffee sources now
   produces this diff:

       diff --git a/src/grammar.coffee b/src/grammar.coffee
       index 0cd5b4d..69d4f8b 100644
       --- a/src/grammar.coffee
       +++ b/src/grammar.coffee
       @@ -219,7 +219,7 @@ grammar =
            o 'ParamVar = Expression',                  -> new Param $1, $3
          ]

       - # Function Parameters
       +  # Function Parameters
          ParamVar: [
            o 'Identifier'
            o 'ThisProperty'
       diff --git a/src/helpers.coffee b/src/helpers.coffee
       index ec5b7a9..8df76b0 100644
       --- a/src/helpers.coffee
       +++ b/src/helpers.coffee
       @@ -99,23 +99,23 @@ buildLocationData = (first, last) ->
        # object is an AST node, updates that object's locationData.
        # The object is returned either way.
        exports.addLocationDataFn = (first, last) ->
       -    (obj) ->
       -      if ((typeof obj) is 'object') and (!!obj['updateLocationDataIfMissing'])
       -        obj.updateLocationDataIfMissing buildLocationData(first, last)
       +  (obj) ->
       +    if ((typeof obj) is 'object') and (!!obj['updateLocationDataIfMissing'])
       +      obj.updateLocationDataIfMissing buildLocationData(first, last)

              return obj

        # Convert jison location data to a string.
        # `obj` can be a token, or a locationData.
        exports.locationDataToString = (obj) ->
       -    if ("2" of obj) and ("first_line" of obj[2]) then locationData = obj[2]
       -    else if "first_line" of obj then locationData = obj
       +  if ("2" of obj) and ("first_line" of obj[2]) then locationData = obj[2]
       +  else if "first_line" of obj then locationData = obj

       -    if locationData
       -      "#{locationData.first_line + 1}:#{locationData.first_column + 1}-" +
       -      "#{locationData.last_line + 1}:#{locationData.last_column + 1}"
       -    else
       -      "No location data"
       +  if locationData
       +    "#{locationData.first_line + 1}:#{locationData.first_column + 1}-" +
       +    "#{locationData.last_line + 1}:#{locationData.last_column + 1}"
       +  else
       +    "No location data"

       # A `.coffee.md` compatible version of `basename`, that returns the file sans-extension.
       exports.baseFileName = (file, stripExt = no, useWinPathSep = no) ->
       diff --git a/src/lexer.coffee b/src/lexer.coffee
       index 6a992b5..8e69720 100644
       --- a/src/lexer.coffee
       +++ b/src/lexer.coffee
       @@ -45,9 +45,9 @@ exports.Lexer = class Lexer
            @tokens     = []             # Stream of parsed tokens in the form `['TYPE', value, location data]`.

            @chunkLine =
       -        opts.line or 0         # The start line for the current @chunk.
       +      opts.line or 0         # The start line for the current @chunk.
            @chunkColumn =
       -        opts.column or 0       # The start column of the current @chunk.
       +      opts.column or 0       # The start column of the current @chunk.
            code = @clean code         # The stripped, cleaned original source code.

            # At every position, run through this list of attempted matches,
       @@ -84,8 +84,8 @@ exports.Lexer = class Lexer
            code = code.slice(1) if code.charCodeAt(0) is BOM
            code = code.replace(/\r/g, '').replace TRAILING_SPACES, ''
            if WHITESPACE.test code
       -        code = "\n#{code}"
       -        @chunkLine--
       +      code = "\n#{code}"
       +      @chunkLine--
            code = invertLiterate code if @literate
            code

       diff --git a/src/rewriter.coffee b/src/rewriter.coffee
       index dc598f1..a702ae1 100644
       --- a/src/rewriter.coffee
       +++ b/src/rewriter.coffee
       @@ -7,9 +7,9 @@

        # Create a generated token: one that exists due to a use of implicit syntax.
        generate = (tag, value) ->
       -    tok = [tag, value]
       -    tok.generated = yes
       -    tok
       +  tok = [tag, value]
       +  tok.generated = yes
       +  tok

        # The **Rewriter** class is used by the [Lexer](lexer.html), directly against
        # its internal array of tokens.
       @@ -341,11 +341,11 @@ class exports.Rewriter
              return 1 if     token[2]
              return 1 unless token.generated or token.explicit
              if token[0] is '{' and nextLocation=tokens[i + 1]?[2]
       -          {first_line: line, first_column: column} = nextLocation
       +        {first_line: line, first_column: column} = nextLocation
              else if prevLocation = tokens[i - 1]?[2]
       -          {last_line: line, last_column: column} = prevLocation
       +        {last_line: line, last_column: column} = prevLocation
              else
       -          line = column = 0
       +        line = column = 0
              token[2] =
                first_line:   line
                first_column: column

   so only lines with incorrect indentation are changed.

 - Optimize SearchCode so it's 16% faster on average
 - Optimize GetTrimmedLine so it's 4% faster on average
 - Use shiftwidth()
 - Fix object keys like class: being indented after
 - Fix not indenting after lines that end in a regex
 - Allow empty function bodies (don't force indenting after -> on non-blank
   lines)
 - Don't force indenting of a when (for nested switch blocks)
 - Don't force indenting to match a comment
 - Don't force indenting after a block-breaking keyword
 - Don't force indenting on non-blank continuations
 - Don't indent when a continuation is preceded by a closing bracket
 - Split up bracket and keyword pair searching so the keyword case is more
   flexible
 - Search for a farthest keyword pair match so that indentation is forced to be
   correct but not aligned to any particular match
 - Don't indent when inside a multiline string
 - Don't indent if the current line begins with then
 - Don't be fooled by a then inside brackets
 - Add a final check if the current line is inside brackets
 - More?