syntax .ruby-esc

# TODO: \unnnn  Unicode codepoint, where nnnn is exactly 4 hex digits
# TODO: \u{nnnn ...}  Unicode codepoint(s), where each nnnn is 1-6 hex digits
state esc special
    char "abefnrstv'\\\"" END special
    char 0-7 oct1
    char x hex0
    char c control
    str 'C-' control
    str 'M-' meta
    noeat END

state oct1 special
    char 0-7 oct2
    noeat END

state oct2 special
    char 0-7 END special
    noeat END

state hex0 special
    char 0-9a-fA-F hex1
    noeat END

state hex1 special
    char 0-9a-fA-F END special
    noeat END

state control special
    str "\\M-" ascii-print
    noeat ascii-print

state meta special
    str "\\c" ascii-print
    str "\\C-" ascii-print
    noeat ascii-print

state ascii-print special
    char "\x21-\x7e" END special
    noeat END

syntax ruby

# TODO: %Q() strings
# TODO: Expression substitution in strings (e.g. "my name is #{$ruby}")
# TODO: Here document strings (e.g. print <<EOF ...)
# TODO: Command output (e.g. `date` or %x{ date })
# TODO: Regular expression literals  (e.g. /^Ruby/i or %r|^/usr/local/.*|)
# TODO: Numeric literals

state line-start code
    char "\n" this
    char = line-start-eq
    noeat start

state start code
    char # comment
    char "\n" line-start
    char -b a-zA-Z_ ident
    char '"' dq
    char "'" sq
    char \$ global-variable
    char -b @ maybe-instance-variable
    char -b : maybe-symbol
    eat this

state global-variable
    char a-zA-Z0-9_- this
    char !@&`\'+~=/\\,\;.<>*\$?:\" start global-variable
    noeat start

state maybe-instance-variable instance-variable
    char -b a-zA-Z_ instance-variable
    recolor code
    noeat start

state instance-variable
    char a-zA-Z0-9_ this
    noeat start

state maybe-symbol symbol
    char -b a-zA-Z_ symbol
    char -b : double-colon
    recolor code
    noeat start

state double-colon
    recolor double-colon
    noeat start

state symbol
    char a-zA-Z0-9_ this
    noeat start

state comment
    char "\n" line-start
    eat this

state line-start-eq comment
    str 'begin' =begin
    recolor code 1
    noeat start

state =begin comment
    char "\n" =begin-line-start
    char " \t" =begin-text
    recolor code 6
    noeat start

state =begin-text comment
    char "\n" =begin-line-start
    eat this

state =begin-line-start comment
    char "\n" this
    str '=end' =begin-maybe-end
    noeat =begin-text

state =begin-maybe-end comment
    char "\n" line-start
    char " \t" =end
    noeat =begin-text

state =end comment
    char "\n" line-start
    eat this

state ident
    char -b a-zA-Z0-9_!? this
    inlist keyword start
    inlist true-false-nil start
    noeat start

state dq string
    char "\"" start string
    char "\n" line-start
    char -b "\\" .ruby-esc:this
    eat this

state sq string
    char "'" start string
    char "\n" line-start
    char -b "\\" .ruby-esc:this
    eat this

list keyword \
    __ENCODING__ __LINE__ __FILE__ BEGIN END \
    alias and begin break case class def defined? do else elsif end \
    ensure for if in module next not or redo rescue retry return self \
    super then undef unless until when while yield

# These keywords could be in the same list as above but they are kept
# separate here to allow the option of highlighting with a different color
list true-false-nil \
    true false nil

default keyword true-false-nil
default numeric symbol
default variable global-variable
default variable instance-variable
default operator double-colon
