]> gitweb.factorcode.org Git - factor.git/commitdiff
[misc] vim/syntax: Overhaul syntax highlighting
authorDusk <me@bb010g.com>
Fri, 5 Jun 2020 08:21:55 +0000 (01:21 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Sun, 7 Jun 2020 00:10:18 +0000 (00:10 +0000)
Also fixes comments in a lot more places than a few commits ago.

Syntax like the following is proper, and the comment highlighting fixes
from last commit make the incorrect highlighting here really stand out:

```factor
USE: ! only this line highlights
  kernel
```

.gitattributes
misc/factor.vim.fgen
misc/vim/syntax/factor.vim
misc/vim/syntax/factor/generated.vim [new file with mode: 0644]

index 312f2cfff5e85150d0d81a78d7531048ffcf47ab..62116fabc924fe572418554134d7d28eeb216933 100644 (file)
@@ -1,3 +1,3 @@
 *.factor text eol=lf
 *.html text eol=lf
-misc/vim/ftplugin/factor.vim linguist-generated
+misc/vim/*/*/generated.vim linguist-generated
index 246bd229a8a46c17bd3c9a17592b8bfa3b7a9d97..7a14103177e407fcc82d058949ae7735a060b22c 100644 (file)
-<%
-USING: accessors io kernel multiline prettyprint sequences sorting vocabs ;
+USING: accessors
+    calendar calendar.format
+    io kernel multiline prettyprint sequences sorting
+    splitting tr vocabs ;
 IN: factor.vim.fgen
+ALIAS: wr write
 
-: print-keywords ( vocab -- )
-    vocab-words [ name>> ] sort-with [
-        "syn keyword factorKeyword " write
-        [ bl ] [ pprint ] interleave nl
-    ] when* ;
-
-%>
-" Vim syntax file
+[=[ " Vim syntax file
 " Language: Factor
 " Maintainer: Alex Chapman <chapman.alex@gmail.com>
-" Last Change: 2020 May 29
-" To run: USING: html.templates html.templates.fhtml ; "resource:misc/factor.vim.fgen" <fhtml> call-template
-
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-    syntax clear
-elseif exists("b:current_syntax")
-    finish
-endif
-
-" Factor is case sensitive.
-syn case match
-
-" Make all of these characters part of a word (useful for skipping over words with w, e, and b)
-if version >= 600
-    setlocal iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
-else
-    set iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
+" Last Change: ]=] wr
+    now >gmt { YYYY " " MONTH " " DD } formatted [=[
+" Minimum Version: 600
+" To regenerate: ]=] wr {
+    [=[ USING: io.encodings.utf8 io.files parser ; ]=]
+    [=[ "resource:misc/vim/syntax/factor/generated.vim" utf8 ]=]
+    [=[ "resource:misc/factor.vim.fgen" parse-file ]=]
+    [=[ with-file-writer]=]
+} [ wr ] each [=[
+
+if exists('b:factorsyn_no_generated')
+  finish
 endif
-
-syn cluster factorCluster contains=factorComment,factorFrySpecifier,factorKeyword,factorRepeat,factorConditional,factorBoolean,factorBreakpoint,factorDeclaration,factorCallQuotation,factorExecute,factorCallNextMethod,factorString,factorTriString,factorSbuf,@factorNumber,@factorNumErr,factorDelimiter,factorChar,factorBackslash,factorMBackslash,factorLiteral,factorLiteralBlock,@factorWordOps,factorAlien,factorSlot,factorTuple,factorError,factorStruct
-
-" All syntax patterns are "very magic" (see `:help /\v`).
-" Escape all literal [^0-9a-zA-Z_-!:;] characters in these patterns.
-" (Not escaping [-!:;] characters risks forward-incompatibility,
-"   but fixes if an incompatibile Vim arises would be trivial,
-"   and Factor likes these characters.)
-
-syn match factorTodo /\v(TODO|FIXME|XXX):=/ contained
-syn match factorComment /\v<\#?!>.*/ contains=factorTodo,@Spell
-syn match factorShebang /\v%^\#!.*/ display
-syn match factorShebangErr /\v%^\#!\S+/
-
-syn cluster factorDefnContents contains=@factorCluster,factorStackEffect,factorLiteralStackEffect,factorArray0,factorQuotation0
-syn cluster factorGenericContents contains=factorComment,factorStackEffect
-
-syn region factorDefn matchgroup=factorDefnDelims start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents
-syn region factorMethod matchgroup=factorMethodDelims start=/\v<M::?\s+\S+\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents
-syn region factorGeneric matchgroup=factorGenericDelims start=/\v<%(GENERIC|MATH|PRIMITIVE):\s+\S+>/ end=/\v$/ contains=@factorGenericContents
-syn region factorGenericN matchgroup=factorGenericNDelims start=/\v<GENERIC\#:\s+\S+\s+\d+>/ end=/\v$/ contains=@factorGenericContents
-
-syn region factorPrivateDefn matchgroup=factorPrivateDefnDelims start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents contained
-syn region factorPrivateMethod matchgroup=factorPrivateMethodDelims start=/\v<M::?\s+\S+\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents contained
-syn region factorPGeneric matchgroup=factorPGenericDelims start=/\v<%(GENERIC|MATH|PRIMITIVE):\s+\S+>/ end=/\v$/ contains=@factorGenericContents contained
-syn region factorPGenericN matchgroup=factorPGenericNDelims start=/\v<GENERIC\#:\s+\S+\s+\d+>/ end=/\v$/ contains=@factorGenericContents contained
-
-syn region None matchgroup=factorPrivate start=/\v<\<PRIVATE>/ end=/\v<PRIVATE\>>/ contains=@factorDefnContents,factorPrivateDefn,factorPrivateMethod,factorPGeneric,factorPGenericN
-
-
-syn keyword factorBoolean f t
-syn keyword factorBreakpoint B
-syn keyword factorFrySpecifier @ _ contained
-syn keyword factorDeclaration delimiter deprecated final flushable foldable inline recursive
-syn match factorCallQuotation /\v<call\(\s+%(\S*\s+)*--%(\s+\S*)*\s+\)>/ contained contains=factorStackEffect
-syn match factorExecute /\v<execute\(\s+%(\S*\s+)*--%(\s+\S*)*\s+\)>/ contained contains=factorStackEffect
-syn keyword factorCallNextMethod call-next-method
-
-<%
-
-! uncomment this if you want all words from all vocabularies highlighted. Note
-! that this changes factor.vim from around 8k to around 100k (and is a bit
-! broken)
-
-! vocabs [ print-keywords ] each
-
-    {
-        "kernel" "assocs" "combinators" "math" "sequences"
-        "namespaces" "arrays" "io" "strings" "vectors"
-        "continuations"
-    } [ print-keywords ] each
-%>
-
-syn cluster factorReal          contains=factorInt,factorFloat,factorPosRatio,factorNegRatio,factorBinary,factorHex,factorOctal
-syn cluster factorNumber        contains=@factorReal,factorComplex
-syn cluster factorNumErr        contains=factorBinErr,factorHexErr,factorOctErr
-syn match   factorInt           /\v<[+-]=[0-9]%([0-9,]*[0-9])?%([eE]%([+-])?[0-9]+)?>/
-syn match   factorFloat         /\v<[+-]=%([0-9,]*[0-9])?%(\.%(%([0-9,]*[0-9]+)?%([eE]%([+-])?[0-9]+)?)?)?>/
-syn match   factorPosRatio      /\v<\+=[0-9]%([0-9,]*[0-9])?%(\+[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
-syn match   factorNegRatio      /\v<\-[0-9]%([0-9,]*[0-9])?%(\-[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
-syn region  factorComplex       start=/\v<C\{>/ end=/\v<\}>/ contains=@factorReal
-syn match   factorBinErr        /\v<[+-]=0b[01,]*[^01 ]\S*>/
-syn match   factorBinary        /\v<[+-]=0b[01,]+>/
-syn match   factorHexErr        /\v<[+-]=0x%(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/
-syn match   factorHex           /\v<[+-]=0x[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?%(\.[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?)?%(p-=[0-9]%([0-9,]*[0-9])?)?>/
-syn match   factorOctErr        /\v<[+-]=0o%(,\S*|\S*,|[0-7,]*[^0-7, ]\S*)>/
-syn match   factorOctal         /\v<[+-]=0o[0-7,]+>/
-syn match   factorNan           /\v<NAN:\s+[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?>/ contains=factorComment
-
-syn match   factorIn            /\v<IN:\s+\S+>/    contains=factorComment
-syn match   factorUse           /\v<USE:\s+\S+>/   contains=factorComment
-syn match   factorUnuse         /\v<UNUSE:\s+\S+>/ contains=factorComment
-
-syn match   factorChar          /\v<CHAR:\s+\S+>/
-
-syn match   factorBackslash     /\v<\\>\s+\S+>/               contains=factorComment
-syn match   factorMBackslash    /\v<M\\>\s+\S+\s+\S+>/        contains=factorComment
-syn match   factorLiteral       /\v<\$>\s+\S+>/               contains=factorComment
-syn region  factorLiteralBlock  start=/\v<\$\[>/ end=/\v<\]>/ contains=factorComment
-
-syn region  factorUsing         start=/\v<USING:>/                  end=/\v;/   contains=factorComment
-syn match   factorQualified     /\v<QUALIFIED:\s+\S+>/                          contains=factorComment
-syn match   factorQualifiedWith /\v<QUALIFIED-WITH:\s+\S+\s+\S+>/               contains=factorComment
-syn region  factorExclude       start=/\v<EXCLUDE:>/                end=/\v;/   contains=factorComment
-syn region  factorFrom          start=/\v<FROM:>/                   end=/\v;/   contains=factorComment
-syn match   factorRename        /\v<RENAME:\s+\S+\s+\S+\s\=\>\s+\S+>/           contains=factorComment
-syn region  factorSingletons    start=/\v<SINGLETONS:>/             end=/\v;/   contains=factorComment
-syn match   factorSymbol        /\v<SYMBOL:\s+\S+>/                             contains=factorComment
-syn region  factorSymbols       start=/\v<SYMBOLS:>/                end=/\v;/   contains=factorComment
-syn region  factorConstructor2  start=/\v<CONSTRUCTOR:?/            end=/\v;/   contains=factorComment
-syn region  factorIntersection  start=/\v<INTERSECTION:>/           end=/\v<;>/ contains=factorComment
-syn region  factorTuple         start=/\v<%(TUPLE|BUILTIN):>/       end=/\v<;>/ contains=factorComment
-syn region  factorError         start=/\v<ERROR:>/                  end=/\v<;>/ contains=factorComment
-syn region  factorUnion         start=/\v<UNION:>/                  end=/\v<;>/ contains=factorComment
-syn region  factorStruct        start=/\v<%(UNION-STRUCT|STRUCT):>/ end=/\v<;>/ contains=factorComment
-
-syn match   factorConstant      /\v<CONSTANT:\s+\S+>/       contains=factorComment
-syn match   factorAlias         /\v<ALIAS:\s+\S+\s+\S+>/    contains=factorComment
-syn match   factorSingleton     /\v<SINGLETON:\s+\S+>/      contains=factorComment
-syn match   factorPostpone      /\v<POSTPONE:\s+\S+>/       contains=factorComment
-syn match   factorDefer         /\v<DEFER:\s+\S+>/          contains=factorComment
-syn match   factorForget        /\v<FORGET:\s+\S+>/         contains=factorComment
-syn match   factorMixin         /\v<MIXIN:\s+\S+>/          contains=factorComment
-syn match   factorInstance      /\v<INSTANCE:\s+\S+\s+\S+>/ contains=factorComment
-syn match   factorHook          /\v<HOOK:\s+\S+\s+\S+>/     contains=factorComment nextgroup=factorStackEffect skipwhite skipempty
-syn match   factorMain          /\v<MAIN:\s+\S+>/           contains=factorComment
-syn match   factorConstructor   /\v<C:\s+\S+\s+\S+>/        contains=factorComment
-syn match   factorAlien         /\v<ALIEN:\s+[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?>/ contains=factorComment
-syn match   factorSlot          /\v<SLOT:\s+\S+>/           contains=factorComment
-
-syn cluster factorWordOps       contains=factorConstant,factorAlias,factorSingleton,factorSingletons,factorSymbol,factorSymbols,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
-
-"TODO:
-"misc:
-" HELP:
-" ARTICLE:
-"literals:
-" PRIMITIVE:
-
-"C interface:
-" C-ENUM:
-" FUNCTION:
-" TYPEDEF:
-" LIBRARY:
-"#\ "
-
-syn match factorEscape /\v\\([\\astnrbvf0e\"]|u\x{6}|u\{\S+}|x\x{2})/ contained display
-syn region factorString start=/\v<"/ skip=/\v\\"/ end=/\v"/ contains=factorEscape
-syn region factorTriString start=/\v<"""/ skip=/\v\\"/ end=/\v"""/ contains=factorEscape
-syn region factorSbuf start=/\v<[-a-zA-Z0-9]+">/ skip=/\v\\"/ end=/\v"/
-
-syn region factorMultiString matchgroup=factorMultiStringDelims start=/\v<STRING:\s+\S+>/ end=/\v^;$/ contains=factorMultiStringContents
-syn match factorMultiStringContents /\v.*/ contained
-
-"syn match factorStackEffectErr /\v<\)>/
-"syn region factorStackEffectErr start=/\v<\(>/ end=/\v<\)>/
-"syn region factorStackEffect start=/\v<\(>/ end=/\v<\)>/ contained
-syn match factorStackEffect /\v\(\s+%(\S*\s+)*--%(\s+\S*)*\s+\)>/ contained contains=factorComment,factorStackDelims,factorStackItems,factorStackVariables,factorCallExecuteDelim
-syn match factorLiteralStackEffect /\v\(\(\s+%(\S*\s+)*--%(\s+\S*)*\s+\)\)>/ contained contains=factorComment,factorStackDelims,factorStackItems,factorStackVariables,factorCallExecuteDelim
-syn match factorStackVariables contained "\<\.\.\S\+\>"
-syn match factorStackItems contained "\<\(\.\.\)\@!\S\+\>"
-syn keyword factorStackDelims contained ( ) (( )) --
-syn match factorCallExecuteDelim contained /\v\(\s/
-
-"adapted from lisp.vim
-if exists("g:factor_norainbow")
-    syn region factorQuotation matchgroup=factorDelimiter start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/ matchgroup=factorDelimiter end=/\v<\]>/ contains=ALL
-else
-    syn region factorQuotation0           matchgroup=hlLevel0 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation1,factorArray1
-    syn region factorQuotation1 contained matchgroup=hlLevel1 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation2,factorArray2
-    syn region factorQuotation2 contained matchgroup=hlLevel2 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation3,factorArray3
-    syn region factorQuotation3 contained matchgroup=hlLevel3 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation4,factorArray4
-    syn region factorQuotation4 contained matchgroup=hlLevel4 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation5,factorArray5
-    syn region factorQuotation5 contained matchgroup=hlLevel5 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation6,factorArray6
-    syn region factorQuotation6 contained matchgroup=hlLevel6 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation7,factorArray7
-    syn region factorQuotation7 contained matchgroup=hlLevel7 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation8,factorArray8
-    syn region factorQuotation8 contained matchgroup=hlLevel8 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation9,factorArray9
-    syn region factorQuotation9 contained matchgroup=hlLevel9 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation0,factorArray0
-endif
-
-if exists("g:factor_norainbow")
-    syn region factorArray     matchgroup=factorDelimiter start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ matchgroup=factorDelimiter end=/\v<}>/ contains=ALL
-else
-    syn region factorArray0           matchgroup=hlLevel0 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray1,factorQuotation1
-    syn region factorArray1 contained matchgroup=hlLevel1 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray2,factorQuotation2
-    syn region factorArray2 contained matchgroup=hlLevel2 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray3,factorQuotation3
-    syn region factorArray3 contained matchgroup=hlLevel3 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray4,factorQuotation4
-    syn region factorArray4 contained matchgroup=hlLevel4 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray5,factorQuotation5
-    syn region factorArray5 contained matchgroup=hlLevel5 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray6,factorQuotation6
-    syn region factorArray6 contained matchgroup=hlLevel6 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray7,factorQuotation7
-    syn region factorArray7 contained matchgroup=hlLevel7 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray8,factorQuotation8
-    syn region factorArray8 contained matchgroup=hlLevel8 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray9,factorQuotation9
-    syn region factorArray9 contained matchgroup=hlLevel9 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray0,factorQuotation0
-endif
-
-syn match factorBracketErr /\v<\]>/
-syn match factorBracketErr /\v<}>/
-
-syn sync lines=100
-
-if version >= 508 || !exists("did_factor_syn_inits")
-    if version <= 508
-        let did_factor_syn_inits = 1
-        command -nargs=+ HiLink hi link <args>
-    else
-        command -nargs=+ HiLink hi def link <args>
-    endif
-
-    HiLink factorComment                Comment
-    HiLink factorShebang                PreProc
-    HiLink factorShebangErr             Error
-    HiLink factorStackEffect            Typedef
-    HiLink factorStackDelims            Delimiter
-    HiLink factorCallExecuteDelim       Delimiter
-    HiLink factorStackVariables         Special
-    HiLink factorStackItems             Identifier
-    HiLink factorLiteralStackEffect     Typedef
-    HiLink factorTodo                   Todo
-    HiLink factorInclude                Include
-    HiLink factorRepeat                 Repeat
-    HiLink factorConditional            Conditional
-    HiLink factorKeyword                Keyword
-    HiLink factorCallQuotation          Keyword
-    HiLink factorExecute                Keyword
-    HiLink factorCallNextMethod         Keyword
-    HiLink factorOperator               Operator
-    HiLink factorFrySpecifier           Operator
-    HiLink factorBoolean                Boolean
-    HiLink factorBreakpoint             Debug
-    HiLink factorDefnDelims             Typedef
-    HiLink factorMethodDelims           Typedef
-    HiLink factorGenericDelims          Typedef
-    HiLink factorGenericNDelims         Typedef
-    HiLink factorConstructor            Typedef
-    HiLink factorConstructor2           Typedef
-    HiLink factorPrivate                Special
-    HiLink factorPrivateDefnDelims      Special
-    HiLink factorPrivateMethodDelims    Special
-    HiLink factorPGenericDelims         Special
-    HiLink factorPGenericNDelims        Special
-    HiLink factorEscape                 SpecialChar
-    HiLink factorString                 String
-    HiLink factorTriString              String
-    HiLink factorSbuf                   String
-    HiLink factorMultiStringContents    String
-    HiLink factorMultiStringDelims      Typedef
-    HiLink factorBracketErr             Error
-    HiLink factorComplex                Number
-    HiLink factorPosRatio               Number
-    HiLink factorNegRatio               Number
-    HiLink factorBinary                 Number
-    HiLink factorBinErr                 Error
-    HiLink factorHex                    Number
-    HiLink factorHexErr                 Error
-    HiLink factorNan                    Number
-    HiLink factorOctal                  Number
-    HiLink factorOctErr                 Error
-    HiLink factorFloat                  Float
-    HiLink factorInt                    Number
-    HiLink factorUsing                  Include
-    HiLink factorQualified              Include
-    HiLink factorQualifiedWith          Include
-    HiLink factorExclude                Include
-    HiLink factorFrom                   Include
-    HiLink factorRename                 Include
-    HiLink factorUse                    Include
-    HiLink factorUnuse                  Include
-    HiLink factorIn                     Define
-    HiLink factorChar                   Character
-    HiLink factorDelimiter              Delimiter
-    HiLink factorBackslash              Special
-    HiLink factorMBackslash             Special
-    HiLink factorLiteral                Special
-    HiLink factorLiteralBlock           Special
-    HiLink factorDeclaration            Typedef
-    HiLink factorSymbol                 Define
-    HiLink factorSymbols                Define
-    HiLink factorConstant               Define
-    HiLink factorAlias                  Define
-    HiLink factorSingleton              Define
-    HiLink factorSingletons             Define
-    HiLink factorMixin                  Typedef
-    HiLink factorInstance               Typedef
-    HiLink factorHook                   Typedef
-    HiLink factorMain                   Define
-    HiLink factorPostpone               Define
-    HiLink factorDefer                  Define
-    HiLink factorForget                 Define
-    HiLink factorAlien                  Define
-    HiLink factorSlot                   Define
-    HiLink factorIntersection           Typedef
-    HiLink factorTuple                  Typedef
-    HiLink factorError                  Typedef
-    HiLink factorUnion                  Typedef
-    HiLink factorStruct                 Typedef
-
-    if &bg == "dark"
-        hi   hlLevel0 ctermfg=red         guifg=red1
-        hi   hlLevel1 ctermfg=yellow      guifg=orange1
-        hi   hlLevel2 ctermfg=green       guifg=yellow1
-        hi   hlLevel3 ctermfg=cyan        guifg=greenyellow
-        hi   hlLevel4 ctermfg=magenta     guifg=green1
-        hi   hlLevel5 ctermfg=red         guifg=springgreen1
-        hi   hlLevel6 ctermfg=yellow      guifg=cyan1
-        hi   hlLevel7 ctermfg=green       guifg=slateblue1
-        hi   hlLevel8 ctermfg=cyan        guifg=magenta1
-        hi   hlLevel9 ctermfg=magenta     guifg=purple1
-    else
-        hi   hlLevel0 ctermfg=red         guifg=red3
-        hi   hlLevel1 ctermfg=darkyellow  guifg=orangered3
-        hi   hlLevel2 ctermfg=darkgreen   guifg=orange2
-        hi   hlLevel3 ctermfg=blue        guifg=yellow3
-        hi   hlLevel4 ctermfg=darkmagenta guifg=olivedrab4
-        hi   hlLevel5 ctermfg=red         guifg=green4
-        hi   hlLevel6 ctermfg=darkyellow  guifg=paleturquoise3
-        hi   hlLevel7 ctermfg=darkgreen   guifg=deepskyblue4
-        hi   hlLevel8 ctermfg=blue        guifg=darkslateblue
-        hi   hlLevel9 ctermfg=darkmagenta guifg=darkviolet
-    endif
-
-    delcommand HiLink
-endif
-
-let b:current_syntax = "factor"
-
-" vim:set ft=vim sw=4:
+]=] wr nl
+
+[=[ command -nargs=+ -bar HiLink hi def link <args>
+function s:syn_keyword_factor_word(group, ...)
+  execute 'HiLink' a:group 'factorWord'
+  execute 'syn' 'cluster' 'factorWord' 'add=' . a:group
+endfunction
+command -nargs=+ -bar SynKeywordFactorWord
+      \ call s:syn_keyword_factor_word(<f-args>)
+]=] wr nl
+: (vocab-name>syntax-group-name) ( string -- string )
+    "_" "___" "-" "__" "." "_" [ replace ] 2tri@ ;
+: vocab-name>syntax-group-name ( string -- string )
+    (vocab-name>syntax-group-name) "factorWord_" prepend ;
+: write-syn-keyword ( string seq seq -- )
+    "syn keyword " wr [ wr ] 2dip
+    [ bl [ bl ] [ wr ] interleave ] unless-empty
+    [ bl [ bl ] [ "|" "\\|" replace wr ] interleave ]
+        unless-empty ;
+: write-keywords ( vocab -- )
+    lookup-vocab
+    [ name>> ] [ vocab-words [ name>> ] map ] bi natural-sort [
+        [ vocab-name>syntax-group-name
+            [ "SynKeywordFactorWord " wr wr " | " wr ] keep
+        ] dip
+        { "contained" } write-syn-keyword nl
+    ] [ drop ] if* ;
+
+f
+! Uncomment to highlight all words from all vocabularies.
+! Note that factor/generated.vim grows from ~16k to ~100k.
+! drop t
+[ loaded-vocab-names ] [ {
+    "alien"
+    "arrays"
+    "assocs"
+    "byte-arrays"
+    "classes"
+    "classes.maybe"
+    "combinators"
+    "continuations"
+    "definitions"
+    "destructors"
+    "generic"
+    "growable"
+    "io"
+    "io.encodings"
+    "io.encodings.binary"
+    "io.encodings.utf8"
+    "io.files"
+    "kernel"
+    "layouts"
+    "make"
+    "math"
+    "math.order"
+    "memory"
+    "namespaces"
+    "sequences"
+    "sets"
+    "sorting"
+    "splitting"
+    "strings"
+    "strings.parser"
+    "syntax"
+    "vectors"
+} ] if [ write-keywords ] each nl
+[=[ delcommand HiLink
+delcommand SynKeywordFactorWord
+]=] wr nl
+
+[=[ let b:factor_syn_no_generated = 1
+]=] wr nl
+! Modeline is broken up to prevent detection here.
+[=[ " vim]=] wr [=[ :set ft=vim sw=2:]=] wr nl
+! vim:set ft=factor:
index 9448138d144d5528f0408876a2a1050eb1ab2816..72da847139c639282489f7f095418c56f5d7bf09 100644 (file)
 " Vim syntax file
 " Language: Factor
 " Maintainer: Alex Chapman <chapman.alex@gmail.com>
-" Last Change: 2020 May 29
-" To run: USING: html.templates html.templates.fhtml ; "resource:misc/factor.vim.fgen" <fhtml> call-template
-
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-    syntax clear
-elseif exists("b:current_syntax")
-    finish
+" Last Change: 2020 Jun 05
+" Minimum Version: 600
+
+" Factor |syntax| file guide & conventions:
+"
+" Inside |:comment|s, words in |bars| contain |:help| keywords.
+"   |K| looks these up.
+"
+" Alignment columns should normally occur on multiples of 4.
+" Align Vim syntax alternatives naturally. E.g.:
+"   "syn match   ..."
+"   "syn cluster ..."
+"   "syn region  ..."
+" Align |:syn-start|, |:syn-skip|, and |:syn-end| on their patterns.
+" ":echo (col('.') - 1) % 4" is handy here.
+"
+" All syntax patterns (|:syn-pattern|) are "very magic" (|/\v|).
+" Escape all literal [^0-9a-zA-Z_-!:;] characters in these patterns.
+" (Not escaping [-!:;] characters risks forward-incompatibility,
+"   but fixes if an incompatibile Vim arises would be trivial,
+"   and Factor likes these characters.)
+"
+" Syntax groups ending in "Error" match errors via |:syn-priority|,
+"   and should normally |:hi-link| to "Error".
+"
+" Syntax groups named "{group-name}Trans" are |:syn-transparent|.
+"
+" |:syn-cluster|s named "{group-name}" mean to allow |:syn-contains| use of
+"   |:syn-priority|-based error-detection.
+" This still applies to clusters named "{group-name}Trans".
+"
+" Syntax groups "{group-name}Skip" have the form:
+" "syn match {group-name}Skip /\v%(\_\s+%(!>.*)?)*/ nextgroup={group-name} transparent contained"
+" Specifying "nextgroup={group-name}Skip" works like a Factor-aware
+"   "nextgroup={group-name} skipwhite skipempty"
+"   with required initial space (not optional).
+" "{cluster-name}Skip" works similarly, but with "nextgroup=@{cluster-name}".
+"
+" Vim's syntax highlighting freaks at paired "/\v\(" and "/\v\)". â˜¹
+" Switching into very nomagic (with "/\V(\v/" or "/\V)\v") averts that,
+"   as non-escaped parentheses don't extend pattern regions.
+
+if exists('b:current_syntax')
+  finish
 endif
 
 " Factor is case sensitive.
 syn case match
 
 " Make all of these characters part of a word (useful for skipping over words with w, e, and b)
-if version >= 600
-    setlocal iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
-else
-    set iskeyword=!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255
+let s:iskeyword = '!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255'
+let s:set_iskeyword = has('patch-7.4.1142') ? 'syn iskeyword ' :
+      \ 'setlocal iskeyword='
+execute s:set_iskeyword . s:iskeyword
+
+syn match   factorWord   /\v<\S+>/  contains=@factorWord transparent display
+syn cluster factorClusterNoComment  contains=factorWord,@factorMultilineComment,@factorClusterValue,factorBoolean,factorBreakpoint,factorDeclaration,factorCallQuotation,factorExecute,factorCallNextMethod,@factorWordOps,factorAlien,factorSlot,factorTuple,factorErrorSyn,factorStruct
+syn cluster factorCluster           contains=@factorComment,@factorClusterNoComment
+
+" A crash course on Factor's lexer:
+"
+" The "lexer" vocabulary parses lines (arrays of strings) into tokens.
+" Tokens are non-space strings, effectively words.
+" "[ f skip ] call( i seq -- n )" finds the next space, erroring on tabs.
+"   "t skip" finds the next non-space.
+" The "lexer" class holds lex state.
+" Lexer method "skip-word" advances to the next space (via "f skip"),
+"     while also counting leading double quotation marks as their own words.
+"   I.e., this advances to the end of the current token
+"     (if currently at a token, otherwise nothing changes).
+" Method "skip-blank" advances to the next non-space (via "t skip"),
+"     while also skipping shebangs at the beginning of the first line.
+"   I.e., this advances to the start of the next token
+"     (if one is present, otherwise it advances to the line's end).
+" "(parse-raw)" advances a lexer through an immediate token via "skip-word",
+"   and returns the (sub)token advanced through.
+"   Note that this will not advance a lexer at space,
+"     and an empty string will be returned.
+" "next-line" advances a lexer to the start of the next line,
+"   adding an effectively empty line to the end (as an EOF state).
+" "parse-raw" advances a lexer through the next token,
+"   first via alternating "skip-blank" & "next-line" if the line ended,
+"     then via "(parse-raw)",
+"   and returns it if found, otherwise (i.e. upon EOF) returning "f".
+"     Note that the lexer will be advanced to EOF if "f" is returned.
+" Comments are (unprocessed) remainders of lines, after a "!" word.
+" "parse-token" advances a lexer though the next token via "parse-raw",
+"   then returns it if found, otherwise returning "f".
+"   while also advancing through comments
+"     via mutual recursion with "skip-comment".
+"   "[ skip-comment ] call( lexer str -- str' )" tests if a token is "!",
+"     returning that token if so,
+"     otherwise first advancing a lexer to the next line via "next-line"
+"         (i.e. discarding the rest of the current line)
+"       and then advancing it via "parse-token" & returning that token,
+"     ensuring the return of "parse-token"'s desired non-comment token.
+" The "lexer" dynamic variable holds the ambient lexer.
+" "?scan-token" advances the ambient lexer through the next token
+"     via "parse-token",
+"   and returns it if found, otherwise returning "f".
+" "scan-token" advances the ambient lexer through the next token
+"     via "?scan-token",
+"   and returns it if found, otherwise throwing an exception.
+" All other words in the "lexer" vocabulary read via "scan-token", if at all.
+" So! To know when double quotes & exclamation marks aren't special,
+"   grep for "parse-raw". (Mostly. To be certain, grep for "lexer".)
+
+syn cluster factorComment           contains=factorComment
+syn cluster factorCommentContents   contains=factorTodo,@Spell
+syn match   factorTodo              /\v(TODO|FIXME|XXX):=/ contained
+
+syn cluster factorDefnContents      contains=@factorCluster
+
+syn region  factorDefn            start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ matchgroup=factorDefnDelims     end=/\v<;>/ contains=factorDefnDelims,@factorDefnContents
+syn region  factorMethod          start=/\v<M::?>/                                 skip=/\v<!>/ matchgroup=factorDefnDelims     end=/\v<;>/ contains=factorMethodDelims,@factorDefnContents
+syn region  factorGeneric         start=/\v<%(GENERIC|MATH|PRIMITIVE):>/           skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip
+syn region  factorGenericN        start=/\v<GENERIC\#:>/                           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/ contains=@factorComment nextgroup=factorStackEffectSkip
+
+syn region  factorPDefn           start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ matchgroup=factorPDefnDelims    end=/\v<;>/ contains=factorPDefnDelims,@factorDefnContents contained
+syn region  factorPMethod         start=/\v<M::?>/                                 skip=/\v<!>/ matchgroup=factorPDefnDelims    end=/\v<;>/ contains=factorPMethodDelims,@factorDefnContents contained
+syn region  factorPGeneric        start=/\v<%(GENERIC|MATH|PRIMITIVE):>/           skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
+syn region  factorPGenericN       start=/\v<GENERIC\#:>/                           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
+
+syn region  factorDefnDelims      start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
+syn region  factorMethodDelims    start=/\v<M::?>/                                 skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip contained
+syn region  factorPDefnDelims     start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
+syn region  factorPMethodDelims   start=/\v<M::?>/                                 skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip contained
+
+syn region  None matchgroup=factorPrivate start=/\v<\<PRIVATE>/ end=/\v<PRIVATE\>>/ contains=@factorDefnContents,factorPrivateDefn,factorPrivateMethod,factorPGeneric,factorPGenericN
+
+syn cluster factorClusterValue      contains=factorBreakpoint,factorBoolean,factorFrySpecifier,factorChar,@factorString,@factorNumber,factorBackslash,factorMBackslash,factorLiteral,factorLiteralBlock,@factorStackEffect,@factorQuotation,@factorArray
+syn match   factorClusterValueSkip  /\v%(\_\s+%(!>.*)?)*/ nextgroup=@factorClusterValue transparent contained
+
+syn keyword factorBoolean           f t
+syn keyword factorBreakpoint        B
+syn keyword factorFrySpecifier      @ _ contained
+syn keyword factorDeclaration       delimiter deprecated final flushable foldable inline recursive
+syn match   factorCallQuotation     /\vcall\V(\v/me=e-1    nextgroup=@factorStackEffect
+syn match   factorExecute           /\vexecute\V(\v/me=e-1 nextgroup=@factorStackEffect
+syn keyword factorCallNextMethod    call-next-method
+
+syn region  factorChar        start=/\v<CHAR:>/ end=/\v\S/
+
+syn cluster factorString            contains=factorString,factorTriString,factorPrefixedString
+syn match   factorEscape            /\v\\([\\astnrbvf0e\"]|u\x{6}|u\{\S+}|x\x{2})/  contained display
+syn region  factorString            matchgroup=factorStringDelims         start=/\v<"/                 skip=/\v\\"/ end=/\v"/   contains=factorEscape
+syn region  factorTriString         matchgroup=factorTriStringDelims      start=/\v<"""/               skip=/\v\\"/ end=/\v"""/ contains=factorEscape
+syn region  factorPrefixedString    matchgroup=factorPrefixedStringDelims start=/\v<[^[:blank:]"]+">/  skip=/\v\\"/ end=/\v"/   contains=factorEscape
+
+" Vocabulary: multiline
+" This vocabulary reads the ambient lexer without "parse-raw".
+syn cluster factorString            add=factorMultilineString,factorHereDocString,factorPrefixedMultilineString
+syn region  factorMultilineString   matchgroup=factorMultilineStringDelims    start=/\v<\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
+syn region  factorHereDoc           matchgroup=factorMultilineStringDelims    start=/\v<STRING:\s+\S+>/     end=/\v^;$/
+syn region  factorHereDocString     matchgroup=factorMultilineStringDelims    start=/\v<HEREDOC:\s+\z(.*)>/ end=/\v^\z1$/
+syn region  factorPrefixedMultilineString matchgroup=factorPrefixedMultilineStringDelims  start=/\v<[^[\][:blank:]]+\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
+" These comments are normal syntax words, so no lexer privilege for them.
+" (Hence, no "syn cluster factorComment" membership.)
+syn cluster factorMultilineComment  contains=factorMultilineComment,factorMultilineCComment
+syn region  factorMultilineComment  matchgroup=factorMultilineCommentDelims   start=/\v<!\[\z(\={0,6})\[>/  end=/\v\]\z1\]/ contains=@factorCommentContents keepend
+syn region  factorMultilineCComment matchgroup=factorMultilineCCommentDelims  start=/\v<\/\*>/              end=/\v\*\//    contains=@factorCommentContents keepend
+
+syn cluster factorReal                  contains=factorInt,factorFloat,factorPosRatio,factorNegRatio,@factorBin,@factorHex,@factorOct,factorNan
+syn cluster factorNumber                contains=@factorReal,factorComplex
+syn match   factorInt                   /\v<[+-]=[0-9]%([0-9,]*[0-9])?%([eE]%([+-])?[0-9]+)?>/
+syn match   factorFloat                 /\v<[+-]=%([0-9,]*[0-9])?%(\.%(%([0-9,]*[0-9]+)?%([eE]%([+-])?[0-9]+)?)?)?>/
+syn match   factorPosRatio              /\v<\+=[0-9]%([0-9,]*[0-9])?%(\+[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
+syn match   factorNegRatio              /\v<\-[0-9]%([0-9,]*[0-9])?%(\-[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
+syn region  factorComplex         start=/\v<C\{>/   end=/\v<\}>/    contains=@factorReal
+if !exists('g:factor_syn_no_error')
+  syn match   factorBinError            /\v\<[+-]\=0b[01,]*[^01 ]\S*\>/
+  syn cluster factorBin                 contains=factorBinError
 endif
-
-syn cluster factorCluster contains=factorComment,factorFrySpecifier,factorKeyword,factorRepeat,factorConditional,factorBoolean,factorBreakpoint,factorDeclaration,factorCallQuotation,factorExecute,factorCallNextMethod,factorString,factorTriString,factorSbuf,@factorNumber,@factorNumErr,factorDelimiter,factorChar,factorBackslash,factorMBackslash,factorLiteral,factorLiteralBlock,@factorWordOps,factorAlien,factorSlot,factorTuple,factorError,factorStruct
-
-" All syntax patterns are "very magic" (see `:help /\v`).
-" Escape all literal [^0-9a-zA-Z_-!:;] characters in these patterns.
-" (Not escaping [-!:;] characters risks forward-incompatibility,
-"   but fixes if an incompatibile Vim arises would be trivial,
-"   and Factor likes these characters.)
-
-syn match factorTodo /\v(TODO|FIXME|XXX):=/ contained
-syn match factorComment /\v<\#?!>.*/ contains=factorTodo,@Spell
-syn match factorShebang /\v%^\#!.*/ display
-syn match factorShebangErr /\v%^\#!\S+/
-
-syn cluster factorDefnContents contains=@factorCluster,factorStackEffect,factorLiteralStackEffect,factorArray0,factorQuotation0
-syn cluster factorGenericContents contains=factorComment,factorStackEffect
-
-syn region factorDefn matchgroup=factorDefnDelims start=/\v<(SYNTAX|(MACRO|MEMO|TYPED)?:?):\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents
-syn region factorMethod matchgroup=factorMethodDelims start=/\v<M::?\s+\S+\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents
-syn region factorGeneric matchgroup=factorGenericDelims start=/\v<(GENERIC|MATH|PRIMITIVE):\s+\S+>/ end=/\v$/ contains=@factorGenericContents
-syn region factorGenericN matchgroup=factorGenericNDelims start=/\v<GENERIC\#:\s+\S+\s+\d+>/ end=/\v$/ contains=@factorGenericContents
-
-syn region factorPrivateDefn matchgroup=factorPrivateDefnDelims start=/\v<(SYNTAX|(MACRO|MEMO|TYPED)?:?):\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents contained
-syn region factorPrivateMethod matchgroup=factorPrivateMethodDelims start=/\v<M::?\s+\S+\s+\S+>/ end=/\v<;>/ contains=@factorDefnContents contained
-syn region factorPGeneric matchgroup=factorPGenericDelims start=/\v<(GENERIC|MATH|PRIMITIVE):\s+\S+>/ end=/\v$/ contains=@factorGenericContents contained
-syn region factorPGenericN matchgroup=factorPGenericNDelims start=/\v<GENERIC\#:\s+\S+\s+\d+>/ end=/\v$/ contains=@factorGenericContents contained
-
-syn region None matchgroup=factorPrivate start=/\v<\<PRIVATE>/ end=/\v<PRIVATE\>>/ contains=@factorDefnContents,factorPrivateDefn,factorPrivateMethod,factorPGeneric,factorPGenericN
-
-
-syn keyword factorBoolean f t
-syn keyword factorBreakpoint B
-syn keyword factorFrySpecifier @ _ contained
-syn keyword factorDeclaration delimiter deprecated final flushable foldable inline recursive
-syn match factorCallQuotation /\v<call\(\s+(\S*\s+)*--(\s+\S*)*\s+\)>/ contained contains=factorStackEffect
-syn match factorExecute /\v<execute\(\s+(\S*\s+)*--(\s+\S*)*\s+\)>/ contained contains=factorStackEffect
-syn keyword factorCallNextMethod call-next-method
-
-syn keyword factorKeyword (clone) -roll -rot -rotd 2bi 2bi* 2bi@ 2curry 2dip 2drop 2dup 2keep 2keepd 2nip 2nipd 2over 2tri 2tri* 2tri@ 2with 3bi 3curry 3dip 3drop 3dup 3keep 3nip 3nipd 3tri 4dip 4drop 4dup 4keep 4nip 5drop 5nip <wrapper> = >boolean ? ?if and assert assert= assert? bi bi* bi-curry bi-curry* bi-curry@ bi@ boa boolean boolean? both? build call callstack callstack>array callstack? clear clone compose composed composed? curried curried? curry die dip do drop dup dupd either? eq? equal? execute get-callstack get-datastack get-retainstack hashcode hashcode* identity-hashcode identity-tuple identity-tuple? if if* keep keepd keepdd loop most new nip nipd not null object or over overd pick pickd prepose reach roll rot rotd same? spin swap swapd throw tri tri* tri-curry tri-curry* tri-curry@ tri@ tuck tuple tuple? unless unless* until when when* while while* with wrapper wrapper? xor
-syn keyword factorKeyword 2cache <enumerated> >alist ?at ?delete-at ?of assoc assoc-all? assoc-any? assoc-clone-like assoc-combine assoc-diff assoc-diff! assoc-differ assoc-each assoc-empty? assoc-filter assoc-filter! assoc-filter-as assoc-find assoc-hashcode assoc-intersect assoc-like assoc-map assoc-map-as assoc-partition assoc-refine assoc-reject assoc-reject! assoc-reject-as assoc-size assoc-stack assoc-subset? assoc-union assoc-union! assoc-union-as assoc= assoc>map assoc? at at* at+ cache change-at clear-assoc collect-by delete-at delete-at* enumerated enumerated? extract-keys harvest-keys harvest-values inc-at key? keys map>alist map>assoc maybe-set-at new-assoc of push-at rename-at set-at sift-keys sift-values substitute unzip value-at value-at* value? values zip zip-as zip-index zip-index-as
-syn keyword factorKeyword 2cleave 2cleave>quot 3cleave 3cleave>quot 4cleave 4cleave>quot alist>quot call-effect case case-find case>quot cleave cleave>quot cond cond>quot deep-spread>quot execute-effect linear-case-quot no-case no-case? no-cond no-cond? recursive-hashcode shallow-spread>quot spread to-fixed-point wrong-values wrong-values?
-syn keyword factorKeyword (all-integers?) (each-integer) (find-integer) * + - / /f /i /mod 2/ 2^ < <= <fp-nan> > >= >bignum >fixnum >float >fraction >integer >rect ?1+ abs align all-integers? bignum bignum? bit? bitand bitnot bitor bits>double bits>float bitxor complex complex? denominator double>bits each-integer even? find-integer find-last-integer fixnum fixnum? float float>bits float? fp-bitwise= fp-infinity? fp-nan-payload fp-nan? fp-qnan? fp-sign fp-snan? fp-special? gcd if-zero imaginary-part integer integer>fixnum integer>fixnum-strict integer? log2 log2-expects-positive log2-expects-positive? mod neg neg? next-float next-power-of-2 number number= number? numerator odd? power-of-2? prev-float ratio ratio? rational rational? real real-part real? recip rect> rem sgn shift simple-gcd sq times u< u<= u> u>= unless-zero unordered? when-zero zero?
-syn keyword factorKeyword 1sequence 2all? 2each 2each-from 2map 2map-as 2map-reduce 2reduce 2selector 2sequence 3append 3append-as 3each 3map 3map-as 3sequence 4sequence <iota> <repetition> <reversed> <slice> ?first ?last ?nth ?second ?set-nth accumulate accumulate! accumulate* accumulate*! accumulate*-as accumulate-as all? any? append append! append-as assert-sequence assert-sequence= assert-sequence? binary-reduce bounds-check bounds-check? bounds-error bounds-error? but-last but-last-slice cartesian-each cartesian-find cartesian-map cartesian-product change-nth check-slice clone-like collapse-slice collector collector-as collector-for collector-for-as concat concat-as copy count cut cut* cut-slice delete-all delete-slice drop-prefix each each-from each-index empty? exchange filter filter! filter-as find find-from find-index find-index-from find-last find-last-from first first2 first3 first4 flip follow fourth glue halves harvest head head* head-slice head-slice* head? if-empty immutable immutable-sequence immutable-sequence? immutable? index index-from indices infimum infimum-by insert-nth interleave iota iota? join join-as last last-index last-index-from length lengthen like longer longer? longest map map! map-as map-find map-find-last map-index map-index-as map-integers map-reduce map-sum max-length member-eq? member? midpoint@ min-length mismatch move new-like new-resizable new-sequence non-negative-integer-expected non-negative-integer-expected? none? nth nths pad-head pad-tail padding partition pop pop* prefix prepend prepend-as produce produce-as product push push-all push-either push-if reduce reduce-index reject reject! reject-as remove remove! remove-eq remove-eq! remove-nth remove-nth! repetition repetition? replace-slice replicate replicate-as rest rest-slice reverse reverse! reversed reversed? second selector selector-as sequence sequence-hashcode sequence= sequence? set-first set-fourth set-last set-length set-nth set-second set-third short shorten shorter shorter? shortest sift slice slice-error slice-error? slice? snip snip-slice subseq subseq-as subseq-start subseq-start-from subseq? suffix suffix! sum sum-lengths supremum supremum-by surround tail tail* tail-slice tail-slice* tail? third trim trim-head trim-head-slice trim-slice trim-tail trim-tail-slice unclip unclip-last unclip-last-slice unclip-slice unless-empty virtual-exemplar virtual-sequence virtual-sequence? virtual@ when-empty
-syn keyword factorKeyword +@ change change-global counter dec get get-global get-namestack global inc init-namespaces initialize namespace off on set set-global set-namestack toggle with-global with-scope with-variable with-variable-off with-variable-on with-variables
-syn keyword factorKeyword 1array 2array 3array 4array <array> >array array array? pair pair? resize-array
-syn keyword factorKeyword (each-stream-block) (each-stream-block-slice) (stream-contents-by-block) (stream-contents-by-element) (stream-contents-by-length) (stream-contents-by-length-or-block) +byte+ +character+ bad-seek-type bad-seek-type? bl contents each-block each-block-size each-block-slice each-line each-stream-block each-stream-block-slice each-stream-line error-stream flush input-stream input-stream? invalid-read-buffer invalid-read-buffer? lines nl output-stream output-stream? print read read-into read-partial read-partial-into read-until read1 readln seek-absolute seek-absolute? seek-end seek-end? seek-input seek-output seek-relative seek-relative? stream-bl stream-contents stream-contents* stream-copy stream-copy* stream-element-type stream-flush stream-length stream-lines stream-nl stream-print stream-read stream-read-into stream-read-partial stream-read-partial-into stream-read-partial-unsafe stream-read-unsafe stream-read-until stream-read1 stream-readln stream-seek stream-seekable? stream-tell stream-write stream-write1 tell-input tell-output with-error-stream with-error-stream* with-error>output with-input-output+error-streams with-input-output+error-streams* with-input-stream with-input-stream* with-output+error-stream with-output+error-stream* with-output-stream with-output-stream* with-output>error with-streams with-streams* write write1
-syn keyword factorKeyword 1string <string> >string resize-string string string?
-syn keyword factorKeyword 1vector <vector> >vector ?push vector vector?
-syn keyword factorKeyword <condition> <continuation> <restart> attempt-all attempt-all-error attempt-all-error? callback-error-hook callcc0 callcc1 cleanup compute-restarts condition condition? continuation continuation? continue continue-restart continue-with current-continuation error error-continuation error-in-thread error-thread finally ifcc ignore-error ignore-error/f ignore-errors in-callback? original-error recover restart restart? restarts rethrow rethrow-restarts return return-continuation thread-error-hook throw-continue throw-restarts with-datastack with-return
-
-
-syn cluster factorReal          contains=factorInt,factorFloat,factorPosRatio,factorNegRatio,factorBinary,factorHex,factorOctal
-syn cluster factorNumber        contains=@factorReal,factorComplex
-syn cluster factorNumErr        contains=factorBinErr,factorHexErr,factorOctErr
-syn match   factorInt           /\v<[+-]=[0-9]([0-9,]*[0-9])?([eE]([+-])?[0-9]+)?>/
-syn match   factorFloat         /\v<[+-]=([0-9,]*[0-9])?(\.(([0-9,]*[0-9]+)?([eE]([+-])?[0-9]+)?)?)?>/
-syn match   factorPosRatio      /\v<\+=[0-9]([0-9,]*[0-9])?(\+[0-9]([0-9,]*[0-9]+)?)?\/-=[0-9]([0-9,]*[0-9]+)?\.?>/
-syn match   factorNegRatio      /\v<\-[0-9]([0-9,]*[0-9])?(\-[0-9]([0-9,]*[0-9]+)?)?\/-=[0-9]([0-9,]*[0-9]+)?\.?>/
-syn region  factorComplex       start=/\v<C\{>/ end=/\v<\}>/ contains=@factorReal
-syn match   factorBinErr        /\v<[+-]=0b[01,]*[^01 ]\S*>/
-syn match   factorBinary        /\v<[+-]=0b[01,]+>/
-syn match   factorHexErr        /\v<[+-]=0x(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/
-syn match   factorHex           /\v<[+-]=0x[0-9a-fA-F]([0-9a-fA-F,]*[0-9a-fA-F])?(\.[0-9a-fA-F]([0-9a-fA-F,]*[0-9a-fA-F])?)?(p-=[0-9]([0-9,]*[0-9])?)?>/
-syn match   factorOctErr        /\v<[+-]=0o(,\S*|\S*,|[0-7,]*[^0-7, ]\S*)>/
-syn match   factorOctal         /\v<[+-]=0o[0-7,]+>/
-syn match   factorNan           /\v<NAN:\s+[0-9a-fA-F]([0-9a-fA-F,]*[0-9a-fA-F])?>/ contains=factorComment
-
-syn match   factorIn            /\v<IN:\s+\S+>/    contains=factorComment
-syn match   factorUse           /\v<USE:\s+\S+>/   contains=factorComment
-syn match   factorUnuse         /\v<UNUSE:\s+\S+>/ contains=factorComment
-
-syn match   factorChar          /\v<CHAR:\s+\S+>/
-
-syn match   factorBackslash     /\v<\\>\s+\S+>/               contains=factorComment
-syn match   factorMBackslash    /\v<M\\>\s+\S+\s+\S+>/        contains=factorComment
-syn match   factorLiteral       /\v<\$>\s+\S+>/               contains=factorComment
-syn region  factorLiteralBlock  start=/\v<\$\[>/ end=/\v<\]>/ contains=factorComment
-
-syn region  factorUsing         start=/\v<USING:>/                  end=/\v;/   contains=factorComment
-syn match   factorQualified     /\v<QUALIFIED:\s+\S+>/                          contains=factorComment
-syn match   factorQualifiedWith /\v<QUALIFIED-WITH:\s+\S+\s+\S+>/               contains=factorComment
-syn region  factorExclude       start=/\v<EXCLUDE:>/                end=/\v;/   contains=factorComment
-syn region  factorFrom          start=/\v<FROM:>/                   end=/\v;/   contains=factorComment
-syn match   factorRename        /\v<RENAME:\s+\S+\s+\S+\s\=\>\s+\S+>/           contains=factorComment
-syn region  factorSingletons    start=/\v<SINGLETONS:>/             end=/\v;/   contains=factorComment
-syn match   factorSymbol        /\v<SYMBOL:\s+\S+>/                             contains=factorComment
-syn region  factorSymbols       start=/\v<SYMBOLS:>/                end=/\v;/   contains=factorComment
-syn region  factorConstructor2  start=/\v<CONSTRUCTOR:?/            end=/\v;/   contains=factorComment
-syn region  factorIntersection  start=/\v<INTERSECTION:>/           end=/\v<;>/ contains=factorComment
-syn region  factorTuple         start=/\v<(TUPLE|BUILTIN):>/        end=/\v<;>/ contains=factorComment
-syn region  factorError         start=/\v<ERROR:>/                  end=/\v<;>/ contains=factorComment
-syn region  factorUnion         start=/\v<UNION:>/                  end=/\v<;>/ contains=factorComment
-syn region  factorStruct        start=/\v<(UNION-STRUCT:|STRUCT:)>/ end=/\v<;>/ contains=factorComment
-
-syn match   factorConstant      /\v<CONSTANT:\s+\S+>/       contains=factorComment
-syn match   factorAlias         /\v<ALIAS:\s+\S+\s+\S+>/    contains=factorComment
-syn match   factorSingleton     /\v<SINGLETON:\s+\S+>/      contains=factorComment
-syn match   factorPostpone      /\v<POSTPONE:\s+\S+>/       contains=factorComment
-syn match   factorDefer         /\v<DEFER:\s+\S+>/          contains=factorComment
-syn match   factorForget        /\v<FORGET:\s+\S+>/         contains=factorComment
-syn match   factorMixin         /\v<MIXIN:\s+\S+>/          contains=factorComment
-syn match   factorInstance      /\v<INSTANCE:\s+\S+\s+\S+>/ contains=factorComment
-syn match   factorHook          /\v<HOOK:\s+\S+\s+\S+>/     contains=factorComment nextgroup=factorStackEffect skipwhite skipempty
-syn match   factorMain          /\v<MAIN:\s+\S+>/           contains=factorComment
-syn match   factorConstructor   /\v<C:\s+\S+\s+\S+>/        contains=factorComment
-syn match   factorAlien         /\v<ALIEN:\s+[0-9a-fA-F]([0-9a-fA-F,]*[0-9a-fA-F])?>/ contains=factorComment
-syn match   factorSlot          /\v<SLOT:\s+\S+>/           contains=factorComment
-
-syn cluster factorWordOps       contains=factorConstant,factorAlias,factorSingleton,factorSingletons,factorSymbol,factorSymbols,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
+syn match   factorBin                   /\v\<[+-]\=0b[01,]\+\>/
+syn cluster factorBin                   add=factorBin
+if !exists('g:factor_syn_no_error')
+  syn match   factorHexNoRadixError     /\v<%(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/ contained
+  syn cluster factorHexNoRadixTrans     contains=factorHexNoRadixError
+  syn match   factorHexError            /\v<[+-]=0x%(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/
+  syn cluster factorHex                 contains=factorHexError
+endif
+syn match   factorHexNoRadixTrans       /\v<[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?%(\.[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?)?%(p-=[0-9]%([0-9,]*[0-9])?)?>/ contained transparent
+syn cluster factorHexNoRadixTrans       add=factorHexNoRadixTrans
+syn match   factorHex                   /\v<[+-]=0x[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?%(\.[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?)?%(p-=[0-9]%([0-9,]*[0-9])?)?>/
+syn cluster factorHex                   add=factorHex
+if !exists('g:factor_syn_no_error')
+  syn match   factorOctError             /\v<[+-]=0o%(,\S*|\S*,|[0-7,]*[^0-7, ]\S*)>/
+  syn cluster factorOct                 contains=factorOctError
+endif
+syn match   factorOct                   /\v<[+-]=0o[0-7,]+>/
+syn cluster factorOct                   add=factorOct
+syn region  factorNan matchgroup=factorNan start=/\v<NAN:>/ matchgroup=NONE end=/\v<\S+>/ contains=@factorComment,@factorHexNoRadixTrans
+
+syn region  factorBackslash       start=/\v<\\>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorMBackslash      start=/\v<M\\>/  skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
+syn region  factorLiteral         start=/\v<\$>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorLiteralBlock    start=/\v<\$\[>/              end=/\v<\]>/    contains=@factorComment
+
+syn region  factorIn      start=/\v<IN:>/      skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorUse     start=/\v<USE:>/     skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorUnuse   start=/\v<UNUSE:>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+
+syn region  factorUsing           start=/\v<USING:>/                        end=/\v<;>/     contains=@factorComment
+syn region  factorQualified       start=/\v<QUALIFIED:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorQualifiedWith   start=/\v<QUALIFIED-WITH:>/  skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
+syn region  factorExclude         start=/\v<EXCLUDE:>/                      end=/\v<;>/     contains=@factorComment
+syn region  factorFrom            start=/\v<FROM:>/                         end=/\v<;>/     contains=@factorComment
+syn region  factorRename          start=/\v<RENAME:>/          skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+%(\_\s+%(!>.*)?)+\=\>%(\_\s+%(!>.*)?)+\S+>/  contains=@factorComment
+syn region  factorSingletons      start=/\v<SINGLETONS:>/                   end=/\v<;>/     contains=@factorComment
+syn region  factorSymbol          start=/\v<SYMBOL:>/          skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorSymbols         start=/\v<SYMBOLS:>/                      end=/\v<;>/     contains=@factorComment
+syn region  factorConstructor2    start=/\v<CONSTRUCTOR:?/                  end=/\v<;>/     contains=@factorComment
+syn region  factorIntersection    start=/\v<INTERSECTION:>/                 end=/\v<;>/     contains=@factorComment
+syn cluster factorSlotAttr              contains=factorSlotAttrInitial,factorSlotAttrReadOnly
+syn cluster factorTupleSlotAttr         contains=@factorSlotAttr
+syn match   factorTupleSlotName         /\v<\S+>/ nextgroup=factorTupleSlotClassSkip contained
+syn match   factorTupleSlotNameSkip     /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorTupleSlotName transparent contained
+syn match   factorTupleSlotClass        /\v<\S+>/ contained
+" a class is optional, so let an attribute take priority if present
+syn match   factorTupleSlotClassSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorTupleSlotClass,@factorTupleSlotAttr transparent contained
+syn region  factorTupleSlot matchgroup=factorTupleSlotDelims  start=/\v<\{>/                end=/\v<\}>/   contains=@factorComment,factorTupleSlotName,@factorTupleSlotAttr contained
+syn region  factorTuple matchgroup=factorTupleDelims          start=/\v<%(TUPLE|BUILTIN):>/ end=/\v<;>/ contains=@factorComment,factorTupleSlotName,factorTupleSlot
+" Abnormally named because factor*Error is reserved for syntax errors.
+syn region  factorErrorSyn        start=/\v<ERROR:>/            end=/\v<;>/     contains=@factorComment
+syn region  factorUnion           start=/\v<UNION:>/            end=/\v<;>/     contains=@factorComment
+syn cluster factorStructSlotAttr        contains=@factorSlotAttr,factorStructSlotAttrBits
+syn match   factorStructSlotName        /\v<\S+>/ nextgroup=factorStructSlotTypeSkip contained
+syn match   factorStructSlotNameSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStructSlotName contained transparent
+syn match   factorStructSlotType        /\v<\S+>/ contained
+syn match   factorStructSlotTypeSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStructSlotType contained transparent
+syn region  factorStructSlot matchgroup=factorStructSlotDelims    start=/\v<\{>/     end=/\v<\}>/ contains=@factorComment,factorStructSlotName,@factorStructSlotAttr contained
+syn region  factorStruct matchgroup=factorStructDelims            start=/\v<%(UNION-STRUCT|STRUCT):>/   end=/\v<;>/ contains=@factorComment,factorStructSlot
+
+syn match   factorSlotAttrReadOnly      /\v<read-only>/ contained
+syn match   factorSlotAttrInitial       /\v<initial:>%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=factorWord,@factorClusterValue contained
+syn match   factorStructSlotAttrBits    /\v<bits:>%(\_\s+%(!>.*)?)+/    contains=@factorComment nextgroup=factorWord,@factorReal contained
+
+syn region  factorConstant        start=/\v<CONSTANT:>/    skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorAlias           start=/\v<ALIAS:>/       skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
+syn region  factorSingleton       start=/\v<SINGLETON:>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorPostpone        start=/\v<POSTPONE:>/    skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorDefer           start=/\v<DEFER:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorForget          start=/\v<FORGET:>/      skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorMixin           start=/\v<MIXIN:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorInstance        start=/\v<INSTANCE:>/    skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
+syn region  factorHook            start=/\v<HOOK:>/        skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip
+syn region  factorMain            start=/\v<MAIN:>/        skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorConstructor     start=/\v<C:>/           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
+syn region  factorAlien matchgroup=factorAlien start=/\v<ALIEN:>/ matchgroup=NONE  skip=/\v<!>/ end=/\v<\S+>/  contains=@factorComment,@factorHexNoRadixTrans 
+syn region  factorSlot            start=/\v<SLOT:>/        skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+
+syn cluster factorWordOps   contains=factorConstant,factorAlias,factorSingleton,factorSingletons,factorSymbol,factorSymbols,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
 
 "TODO:
 "misc:
@@ -145,183 +268,244 @@ syn cluster factorWordOps       contains=factorConstant,factorAlias,factorSingle
 " LIBRARY:
 "#\ "
 
-syn match factorEscape /\v\\([\\astnrbvf0e\"]|u\x{6}|u\{\S+}|x\x{2})/ contained display
-syn region factorString start=/\v<"/ skip=/\v\\"/ end=/\v"/ contains=factorEscape
-syn region factorTriString start=/\v<"""/ skip=/\v\\"/ end=/\v"""/ contains=factorEscape
-syn region factorSbuf start=/\v<[-a-zA-Z0-9]+">/ skip=/\v\\"/ end=/\v"/
-
-syn region factorMultiString matchgroup=factorMultiStringDelims start=/\v<STRING:\s+\S+>/ end=/\v^;$/ contains=factorMultiStringContents
-syn match factorMultiStringContents /\v.*/ contained
-
-"syn match factorStackEffectErr /\v<\)>/
-"syn region factorStackEffectErr start=/\v<\(>/ end=/\v<\)>/
-"syn region factorStackEffect start=/\v<\(>/ end=/\v<\)>/ contained
-syn match factorStackEffect /\v\(\s+(\S*\s+)*--(\s+\S*)*\s+\)>/ contained contains=factorComment,factorStackDelims,factorStackItems,factorStackVariables,factorCallExecuteDelim
-syn match factorLiteralStackEffect /\v\(\(\s+(\S*\s+)*--(\s+\S*)*\s+\)\)>/ contained contains=factorComment,factorStackDelims,factorStackItems,factorStackVariables,factorCallExecuteDelim
-syn match factorStackVariables contained "\<\.\.\S\+\>"
-syn match factorStackItems contained "\<\(\.\.\)\@!\S\+\>"
-syn keyword factorStackDelims contained ( ) (( )) --
-syn match factorCallExecuteDelim contained /\v\(\s/
-
-"adapted from lisp.vim
-if exists("g:factor_norainbow")
-    syn region factorQuotation matchgroup=factorDelimiter start=/\v<((('|\$|)\[)|\[(let|\|))>/ matchgroup=factorDelimiter end=/\v<\]>/ contains=ALL
+if !exists('g:factor_syn_no_error')
+  syn match   factorStackEffectRequired /\v<\V(\@!\v\S+>/    contained
+endif
+syn cluster factorStackEffectContents   contains=@factorComment,factorStackEffectDelims,factorStackEffectVar,factorStackEffectType,factorStackEffectRowVar
+syn cluster factorStackEffect           contains=factorStackEffect
+" Erroring on stack effects without a "--" separator would be nice.
+" Unfortunately, that sort of vacuous detection is above Vim's pay-grade,
+"   especially when stack effects can be nested arbitrarily via types.
+syn match   factorStackEffectSkip   /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStackEffectRequired,@factorStackEffect transparent contained
+syn region  factorStackEffect       matchgroup=factorStackEffectDelims    start=/\v\V(\v>/  end=/\v<\V)\v>/ contains=@factorStackEffectContents
+syn match   factorStackEffectVar        /\v<\S+>/           contained
+" Note that ":!" parses to the "!" word and doesn't lex as a comment.
+" Also, even though we take any value, the leading ":" breaking the word
+"   boundary means a lot of our nicer syntax patterns don't match on
+"   "factorStackEffectType".
+" syn cluster factorStackEffectType contains=factorWord,@factorStackEffect
+syn cluster factorStackEffectType       contains=@factorClusterValue
+syn region  factorStackEffectVar    matchgroup=factorStackEffectVar       start=/v<\S+:>/       matchgroup=NONE end=/\v%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=@factorStackEffectType transparent contained
+syn match   factorStackEffectType       /\v<:/              contained nextgroup=@factorStackEffectType
+syn match   factorStackEffectRowVar     /\v<\.\.\S+>/       contained
+syn region  factorStackEffectRowVar matchgroup=factorStackEffectRowVar    start=/v<\.\.\S+:>/   matchgroup=NONE end=/\v%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=@factorStackEffectType transparent contained
+syn match   factorStackEffectDelims     /\v<-->/            contained
+if !exists('g:factor_syn_no_error')
+  syn cluster factorStackEffectContents add=factorStackEffectError
+  syn keyword factorStackEffectError    (                   contained
+endif
+
+" adapted from lisp.vim
+if exists('g:factor_syn_no_rainbow')
+  syn cluster factorQuotation   contains=factorQuotation
+  syn region  factorQuotation      matchgroup=factorDelimiter start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=ALL
 else
-    syn region factorQuotation0           matchgroup=hlLevel0 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation1,factorArray1
-    syn region factorQuotation1 contained matchgroup=hlLevel1 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation2,factorArray2
-    syn region factorQuotation2 contained matchgroup=hlLevel2 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation3,factorArray3
-    syn region factorQuotation3 contained matchgroup=hlLevel3 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation4,factorArray4
-    syn region factorQuotation4 contained matchgroup=hlLevel4 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation5,factorArray5
-    syn region factorQuotation5 contained matchgroup=hlLevel5 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation6,factorArray6
-    syn region factorQuotation6 contained matchgroup=hlLevel6 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation7,factorArray7
-    syn region factorQuotation7 contained matchgroup=hlLevel7 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation8,factorArray8
-    syn region factorQuotation8 contained matchgroup=hlLevel8 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation9,factorArray9
-    syn region factorQuotation9 contained matchgroup=hlLevel9 start=/\v<((('|\$|)\[)|\[(let|\|))>/  end=/\v<\]>/ contains=@factorCluster,factorQuotation0,factorArray0
+  syn cluster factorQuotation   contains=factorQuotation0
+  syn region  factorQuotation0            matchgroup=hlLevel0 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation1,factorArray1
+  syn region  factorQuotation1 contained  matchgroup=hlLevel1 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation2,factorArray2
+  syn region  factorQuotation2 contained  matchgroup=hlLevel2 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation3,factorArray3
+  syn region  factorQuotation3 contained  matchgroup=hlLevel3 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation4,factorArray4
+  syn region  factorQuotation4 contained  matchgroup=hlLevel4 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation5,factorArray5
+  syn region  factorQuotation5 contained  matchgroup=hlLevel5 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation6,factorArray6
+  syn region  factorQuotation6 contained  matchgroup=hlLevel6 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation7,factorArray7
+  syn region  factorQuotation7 contained  matchgroup=hlLevel7 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation8,factorArray8
+  syn region  factorQuotation8 contained  matchgroup=hlLevel8 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation9,factorArray9
+  syn region  factorQuotation9 contained  matchgroup=hlLevel9 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation0,factorArray0
 endif
 
-if exists("g:factor_norainbow")
-    syn region factorArray    matchgroup=factorDelimiter start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/  matchgroup=factorDelimiter end=/\v<}>/ contains=ALL
+if exists('g:factor_syn_no_rainbow')
+  syn cluster factorArray       contains=factorArray
+  syn region  factorArray          matchgroup=factorDelimiter start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/        end=/\v<\}>/    contains=ALL
 else
-    syn region factorArray0           matchgroup=hlLevel0 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray1,factorQuotation1
-    syn region factorArray1 contained matchgroup=hlLevel1 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray2,factorQuotation2
-    syn region factorArray2 contained matchgroup=hlLevel2 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray3,factorQuotation3
-    syn region factorArray3 contained matchgroup=hlLevel3 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray4,factorQuotation4
-    syn region factorArray4 contained matchgroup=hlLevel4 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray5,factorQuotation5
-    syn region factorArray5 contained matchgroup=hlLevel5 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray6,factorQuotation6
-    syn region factorArray6 contained matchgroup=hlLevel6 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray7,factorQuotation7
-    syn region factorArray7 contained matchgroup=hlLevel7 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray8,factorQuotation8
-    syn region factorArray8 contained matchgroup=hlLevel8 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray9,factorQuotation9
-    syn region factorArray9 contained matchgroup=hlLevel9 start=/\v<(\$|[-a-zA-Z0-9]+)?\{>/ end=/\v<}>/ contains=@factorCluster,factorArray0,factorQuotation0
+  syn cluster factorArray       contains=factorArray0
+  syn region  factorArray0               matchgroup=hlLevel0 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray1,factorQuotation1
+  syn region  factorArray1     contained matchgroup=hlLevel1 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray2,factorQuotation2
+  syn region  factorArray2     contained matchgroup=hlLevel2 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray3,factorQuotation3
+  syn region  factorArray3     contained matchgroup=hlLevel3 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray4,factorQuotation4
+  syn region  factorArray4     contained matchgroup=hlLevel4 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray5,factorQuotation5
+  syn region  factorArray5     contained matchgroup=hlLevel5 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray6,factorQuotation6
+  syn region  factorArray6     contained matchgroup=hlLevel6 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray7,factorQuotation7
+  syn region  factorArray7     contained matchgroup=hlLevel7 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray8,factorQuotation8
+  syn region  factorArray8     contained matchgroup=hlLevel8 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray9,factorQuotation9
+  syn region  factorArray9     contained matchgroup=hlLevel9 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray0,factorQuotation0
+endif
+
+if !exists('g:factor_syn_no_error')
+  syn match   factorBracketError    /\v<\]>/
+  syn match   factorBracketError    /\v<\}>/
+endif
+
+function! FactorSynDefineComment() abort
+  syn region  factorComment   start=/\v<!>/ end=/\v$/   keepend oneline contains=@factorCommentContents
+  syn match   factorShebang         /\v%^\#!.*$/ display
+  if !exists('g:factor_syn_no_error')
+    syn match   factorShebangError  /\v%^\#!\S+/
+  endif
+endfunction
+
+if !exists('g:factor_syn_no_comment')
+  call FactorSynDefineComment()
 endif
 
-syn match factorBracketErr /\v<\]>/
-syn match factorBracketErr /\v<}>/
+" Syntax that bypasses comment lexing.
+function! FactorSynDefineAfterComment() abort
+endfunction
+
+if !exists('g:factor_syn_no_after_comment')
+  call FactorSynDefineAfterComment()
+endif
 
 syn sync lines=100
 
-if version >= 508 || !exists("did_factor_syn_inits")
-    if version <= 508
-        let did_factor_syn_inits = 1
-        command -nargs=+ HiLink hi link <args>
-    else
-        command -nargs=+ HiLink hi def link <args>
-    endif
-
-    HiLink factorComment                Comment
-    HiLink factorShebang                PreProc
-    HiLink factorShebangErr             Error
-    HiLink factorStackEffect            Typedef
-    HiLink factorStackDelims            Delimiter
-    HiLink factorCallExecuteDelim       Delimiter
-    HiLink factorStackVariables         Special
-    HiLink factorStackItems             Identifier
-    HiLink factorLiteralStackEffect     Typedef
-    HiLink factorTodo                   Todo
-    HiLink factorInclude                Include
-    HiLink factorRepeat                 Repeat
-    HiLink factorConditional            Conditional
-    HiLink factorKeyword                Keyword
-    HiLink factorCallQuotation          Keyword
-    HiLink factorExecute                Keyword
-    HiLink factorCallNextMethod         Keyword
-    HiLink factorOperator               Operator
-    HiLink factorFrySpecifier           Operator
-    HiLink factorBoolean                Boolean
-    HiLink factorBreakpoint             Debug
-    HiLink factorDefnDelims             Typedef
-    HiLink factorMethodDelims           Typedef
-    HiLink factorGenericDelims          Typedef
-    HiLink factorGenericNDelims         Typedef
-    HiLink factorConstructor            Typedef
-    HiLink factorConstructor2           Typedef
-    HiLink factorPrivate                Special
-    HiLink factorPrivateDefnDelims      Special
-    HiLink factorPrivateMethodDelims    Special
-    HiLink factorPGenericDelims         Special
-    HiLink factorPGenericNDelims        Special
-    HiLink factorEscape                 SpecialChar
-    HiLink factorString                 String
-    HiLink factorTriString              String
-    HiLink factorSbuf                   String
-    HiLink factorMultiStringContents    String
-    HiLink factorMultiStringDelims      Typedef
-    HiLink factorBracketErr             Error
-    HiLink factorComplex                Number
-    HiLink factorPosRatio               Number
-    HiLink factorNegRatio               Number
-    HiLink factorBinary                 Number
-    HiLink factorBinErr                 Error
-    HiLink factorHex                    Number
-    HiLink factorHexErr                 Error
-    HiLink factorNan                    Number
-    HiLink factorOctal                  Number
-    HiLink factorOctErr                 Error
-    HiLink factorFloat                  Float
-    HiLink factorInt                    Number
-    HiLink factorUsing                  Include
-    HiLink factorQualified              Include
-    HiLink factorQualifiedWith          Include
-    HiLink factorExclude                Include
-    HiLink factorFrom                   Include
-    HiLink factorRename                 Include
-    HiLink factorUse                    Include
-    HiLink factorUnuse                  Include
-    HiLink factorIn                     Define
-    HiLink factorChar                   Character
-    HiLink factorDelimiter              Delimiter
-    HiLink factorBackslash              Special
-    HiLink factorMBackslash             Special
-    HiLink factorLiteral                Special
-    HiLink factorLiteralBlock           Special
-    HiLink factorDeclaration            Typedef
-    HiLink factorSymbol                 Define
-    HiLink factorSymbols                Define
-    HiLink factorConstant               Define
-    HiLink factorAlias                  Define
-    HiLink factorSingleton              Define
-    HiLink factorSingletons             Define
-    HiLink factorMixin                  Typedef
-    HiLink factorInstance               Typedef
-    HiLink factorHook                   Typedef
-    HiLink factorMain                   Define
-    HiLink factorPostpone               Define
-    HiLink factorDefer                  Define
-    HiLink factorForget                 Define
-    HiLink factorAlien                  Define
-    HiLink factorSlot                   Define
-    HiLink factorIntersection           Typedef
-    HiLink factorTuple                  Typedef
-    HiLink factorError                  Typedef
-    HiLink factorUnion                  Typedef
-    HiLink factorStruct                 Typedef
-
-    if &bg == "dark"
-        hi   hlLevel0 ctermfg=red         guifg=red1
-        hi   hlLevel1 ctermfg=yellow      guifg=orange1
-        hi   hlLevel2 ctermfg=green       guifg=yellow1
-        hi   hlLevel3 ctermfg=cyan        guifg=greenyellow
-        hi   hlLevel4 ctermfg=magenta     guifg=green1
-        hi   hlLevel5 ctermfg=red         guifg=springgreen1
-        hi   hlLevel6 ctermfg=yellow      guifg=cyan1
-        hi   hlLevel7 ctermfg=green       guifg=slateblue1
-        hi   hlLevel8 ctermfg=cyan        guifg=magenta1
-        hi   hlLevel9 ctermfg=magenta     guifg=purple1
-    else
-        hi   hlLevel0 ctermfg=red         guifg=red3
-        hi   hlLevel1 ctermfg=darkyellow  guifg=orangered3
-        hi   hlLevel2 ctermfg=darkgreen   guifg=orange2
-        hi   hlLevel3 ctermfg=blue        guifg=yellow3
-        hi   hlLevel4 ctermfg=darkmagenta guifg=olivedrab4
-        hi   hlLevel5 ctermfg=red         guifg=green4
-        hi   hlLevel6 ctermfg=darkyellow  guifg=paleturquoise3
-        hi   hlLevel7 ctermfg=darkgreen   guifg=deepskyblue4
-        hi   hlLevel8 ctermfg=blue        guifg=darkslateblue
-        hi   hlLevel9 ctermfg=darkmagenta guifg=darkviolet
-    endif
-
-    delcommand HiLink
+if !exists('g:factor_syn_no_init')
+  command -nargs=+ -bar HiLink hi def link <args>
+
+  if !exists('g:factor_syn_no_error')
+    HiLink factorShebangError           Error
+    HiLink factorBracketError           Error
+    HiLink factorBinError               Error
+    HiLink factorHexNoRadixError        Error
+    HiLink factorHexError               Error
+    HiLink factorOctError               Error
+    HiLink factorStackEffectRequired    Error
+    HiLink factorStackEffectError       Error
+  endif
+
+  HiLink   factorComment                Comment
+  HiLink   factorMultilineComment       factorComment
+  HiLink   factorMultilineCComment      factorComment
+  HiLink   factorShebang                PreProc
+  HiLink   factorStackEffect            Type
+  HiLink   factorStackEffectDelims      Delimiter
+  HiLink   factorStackEffectVar         Identifier
+  HiLink   factorStackEffectRowVar      factorStackEffectVar
+  HiLink   factorStackEffectType        Type
+  HiLink   factorTodo                   Todo
+  HiLink   factorInclude                Include
+  HiLink   factorWord                   Keyword
+  HiLink   factorCallQuotation          Keyword
+  HiLink   factorExecute                Keyword
+  HiLink   factorCallNextMethod         Keyword
+  HiLink   factorOperator               Operator
+  HiLink   factorFrySpecifier           Operator
+  HiLink   factorBoolean                Boolean
+  HiLink   factorBreakpoint             Debug
+  HiLink   factorDefnDelims             Typedef
+  HiLink   factorMethodDelims           Typedef
+  HiLink   factorGeneric                Typedef
+  HiLink   factorGenericN               Typedef
+  HiLink   factorConstructor            Typedef
+  HiLink   factorConstructor2           Typedef
+  HiLink   factorPrivate                Special
+  HiLink   factorPDefnDelims            Special
+  HiLink   factorPMethodDelims          Special
+  HiLink   factorPGenericDelims         Special
+  HiLink   factorPGenericNDelims        Special
+  HiLink   factorEscape                 SpecialChar
+  HiLink   factorString                 String
+  HiLink   factorStringDelims           factorString
+  HiLink   factorTriString              factorString
+  HiLink   factorTriStringDelims        factorTriString
+  HiLink   factorPrefixedString         factorString
+  HiLink   factorPrefixedStringDelims   factorPrefixedString
+  HiLink   factorMultilineString        factorString
+  HiLink   factorMultilineStringDelims  Typedef
+  HiLink   factorHereDocString          factorMultilineString
+  HiLink   factorHereDocStringDelims    factorMultilineStringDelims
+  HiLink   factorPrefixedMultilineString factorString
+  HiLink   factorPrefixedMultilineStringDelims factorMultilineStringDelims
+  HiLink   factorComplex                Number
+  HiLink   factorPosRatio               Number
+  HiLink   factorNegRatio               Number
+  HiLink   factorBin                    Number
+  HiLink   factorHex                    Number
+  HiLink   factorNan                    Number
+  HiLink   factorOct                    Number
+  HiLink   factorFloat                  Float
+  HiLink   factorInt                    Number
+  HiLink   factorUsing                  Include
+  HiLink   factorQualified              Include
+  HiLink   factorQualifiedWith          Include
+  HiLink   factorExclude                Include
+  HiLink   factorFrom                   Include
+  HiLink   factorRename                 Include
+  HiLink   factorUse                    Include
+  HiLink   factorUnuse                  Include
+  HiLink   factorIn                     Define
+  HiLink   factorChar                   Character
+  HiLink   factorDelimiter              Delimiter
+  HiLink   factorBackslash              Special
+  HiLink   factorMBackslash             Special
+  HiLink   factorLiteral                Special
+  HiLink   factorLiteralBlock           Special
+  HiLink   factorDeclaration            Typedef
+  HiLink   factorSymbol                 Define
+  HiLink   factorSymbols                Define
+  HiLink   factorConstant               Define
+  HiLink   factorAlias                  Define
+  HiLink   factorSingleton              Define
+  HiLink   factorSingletons             Define
+  HiLink   factorMixin                  Typedef
+  HiLink   factorInstance               Typedef
+  HiLink   factorHook                   Typedef
+  HiLink   factorMain                   Define
+  HiLink   factorPostpone               Define
+  HiLink   factorDefer                  Define
+  HiLink   factorForget                 Define
+  HiLink   factorAlien                  Define
+  HiLink   factorSlot                   Define
+  HiLink   factorIntersection           Typedef
+  HiLink   factorSlot                   Typedef
+  HiLink   factorSlotDelims             factorSlot
+  HiLink   factorSlotName               Identifier
+  HiLink   factorSlotClass              Type
+  HiLink   factorSlotType               factorSlotClass
+  HiLink   factorSlotAttr               Special
+  HiLink   factorSlotAttrInitial        factorSlotAttr
+  HiLink   factorSlotAttrReadOnly       factorSlotAttr
+  HiLink   factorStructSlotAttr         factorSlotAttr
+  HiLink   factorStructSlotAttrBits     factorStructSlotAttr
+  HiLink   factorTuple                  Typedef
+  HiLink   factorTupleDelims            factorTuple
+  HiLink   factorTupleSlot              factorSlot
+  HiLink   factorTupleSlotDelims        factorSlotDelims
+  HiLink   factorTupleSlotName          factorSlotName
+  HiLink   factorTupleSlotClass         factorSlotClass
+  HiLink   factorErrorSyn               Typedef
+  HiLink   factorUnion                  Typedef
+  HiLink   factorStruct                 Typedef
+  HiLink   factorStructDelims           factorStruct
+  HiLink   factorStructSlot             factorSlot
+  HiLink   factorStructSlotDelims       factorSlotDelims
+  HiLink   factorStructSlotName         factorSlotName
+  HiLink   factorStructSlotType         factorSlotType
+
+  if &bg == 'dark'
+    hi   hlLevel0 ctermfg=red           guifg=red1
+    hi   hlLevel1 ctermfg=yellow        guifg=orange1
+    hi   hlLevel2 ctermfg=green         guifg=yellow1
+    hi   hlLevel3 ctermfg=cyan          guifg=greenyellow
+    hi   hlLevel4 ctermfg=magenta       guifg=green1
+    hi   hlLevel5 ctermfg=red           guifg=springgreen1
+    hi   hlLevel6 ctermfg=yellow        guifg=cyan1
+    hi   hlLevel7 ctermfg=green         guifg=slateblue1
+    hi   hlLevel8 ctermfg=cyan          guifg=magenta1
+    hi   hlLevel9 ctermfg=magenta       guifg=purple1
+  else
+    hi   hlLevel0 ctermfg=red           guifg=red3
+    hi   hlLevel1 ctermfg=darkyellow    guifg=orangered3
+    hi   hlLevel2 ctermfg=darkgreen     guifg=orange2
+    hi   hlLevel3 ctermfg=blue          guifg=yellow3
+    hi   hlLevel4 ctermfg=darkmagenta   guifg=olivedrab4
+    hi   hlLevel5 ctermfg=red           guifg=green4
+    hi   hlLevel6 ctermfg=darkyellow    guifg=paleturquoise3
+    hi   hlLevel7 ctermfg=darkgreen     guifg=deepskyblue4
+    hi   hlLevel8 ctermfg=blue          guifg=darkslateblue
+    hi   hlLevel9 ctermfg=darkmagenta   guifg=darkviolet
+  endif
 endif
+delcommand HiLink
 
-let b:current_syntax = "factor"
+let b:current_syntax = 'factor'
 
-" vim:set ft=vim sw=4:
+" vim: set ft=vim et sw=2 isk+=/,\\ :
diff --git a/misc/vim/syntax/factor/generated.vim b/misc/vim/syntax/factor/generated.vim
new file mode 100644 (file)
index 0000000..3e50b89
--- /dev/null
@@ -0,0 +1,58 @@
+" Vim syntax file
+" Language: Factor
+" Maintainer: Alex Chapman <chapman.alex@gmail.com>
+" Last Change: 2020 Jun 05
+" Minimum Version: 600
+" To regenerate: USING: io.encodings.utf8 io.files parser ; "resource:misc/vim/syntax/factor/generated.vim" utf8 "resource:misc/factor.vim.fgen" parse-file with-file-writer
+
+if exists('b:factorsyn_no_generated')
+  finish
+endif
+
+command -nargs=+ -bar HiLink hi def link <args>
+function s:syn_keyword_factor_word(group, ...)
+  execute 'HiLink' a:group 'factorWord'
+  execute 'syn' 'cluster' 'factorWord' 'add=' . a:group
+endfunction
+command -nargs=+ -bar SynKeywordFactorWord
+      \ call s:syn_keyword_factor_word(<f-args>)
+
+SynKeywordFactorWord factorWord_alien | syn keyword factorWord_alien contained <alien> <bad-alien> <callback> <displaced-alien> >c-ptr abi abi? alien alien-address alien-assembly alien-callback alien-indirect alien-invoke alien? binary-object byte-length c-ptr c-ptr? callee-cleanup? callsite-not-compiled callsite-not-compiled? cdecl cdecl? dll dll? element-size expired? fastcall fastcall? free-callback initialize-alien mingw mingw? pinned-alien pinned-alien? pinned-c-ptr pinned-c-ptr? stdcall stdcall? thiscall thiscall? unregister-and-free-callback with-callback
+SynKeywordFactorWord factorWord_arrays | syn keyword factorWord_arrays contained 1array 2array 3array 4array <array> >array array array? pair pair? resize-array
+SynKeywordFactorWord factorWord_assocs | syn keyword factorWord_assocs contained 2cache <enumerated> >alist ?at ?delete-at ?of assoc assoc-all? assoc-any? assoc-clone-like assoc-combine assoc-diff assoc-diff! assoc-differ assoc-each assoc-empty? assoc-filter assoc-filter! assoc-filter-as assoc-find assoc-hashcode assoc-intersect assoc-like assoc-map assoc-map-as assoc-partition assoc-refine assoc-reject assoc-reject! assoc-reject-as assoc-size assoc-stack assoc-subset? assoc-union assoc-union! assoc-union-as assoc= assoc>map assoc? at at* at+ cache change-at clear-assoc collect-by delete-at delete-at* enumerated enumerated? extract-keys harvest-keys harvest-values inc-at key? keys map>alist map>assoc maybe-set-at new-assoc of push-at rename-at set-at sift-keys sift-values substitute unzip value-at value-at* value? values zip zip-as zip-index zip-index-as
+SynKeywordFactorWord factorWord_byte__arrays | syn keyword factorWord_byte__arrays contained (byte-array) 1byte-array 2byte-array 3byte-array 4byte-array <byte-array> >byte-array byte-array byte-array? byte-sequence byte-sequence? resize-byte-array
+SynKeywordFactorWord factorWord_classes | syn keyword factorWord_classes contained all-contained-classes bad-inheritance bad-inheritance? check-instance class class-members class-of class-participants class-usage class-usages class-uses class? classes classoid classoid? contained-classes create-predicate-word define-predicate defining-class defining-class? forget-class implementors instance? not-an-instance not-an-instance? predicate predicate-def predicate-word predicate? subclass-of? superclass-of superclass-of? superclasses-of
+SynKeywordFactorWord factorWord_classes_maybe | syn keyword factorWord_classes_maybe contained <maybe> maybe maybe-class-or maybe?
+SynKeywordFactorWord factorWord_combinators | syn keyword factorWord_combinators contained 2cleave 2cleave>quot 3cleave 3cleave>quot 4cleave 4cleave>quot alist>quot call-effect case case-find case>quot cleave cleave>quot cond cond>quot deep-spread>quot execute-effect linear-case-quot no-case no-case? no-cond no-cond? recursive-hashcode shallow-spread>quot spread to-fixed-point wrong-values wrong-values?
+SynKeywordFactorWord factorWord_continuations | syn keyword factorWord_continuations contained <condition> <continuation> <restart> attempt-all attempt-all-error attempt-all-error? callback-error-hook callcc0 callcc1 cleanup compute-restarts condition condition? continuation continuation? continue continue-restart continue-with current-continuation error error-continuation error-in-thread error-thread finally ifcc ignore-error ignore-error/f ignore-errors in-callback? original-error recover restart restart? restarts rethrow rethrow-restarts return return-continuation thread-error-hook throw-continue throw-restarts with-datastack with-return
+SynKeywordFactorWord factorWord_definitions | syn keyword factorWord_definitions contained add-to-unit changed-conditionally changed-definition changed-definitions changed-effects definer definition definition-mixin definition-mixin? forget forget* forget-all forgotten-definition forgotten-definitions maybe-changed new-word new-words no-compilation-unit no-compilation-unit? outdated-generics set-where where
+SynKeywordFactorWord factorWord_destructors | syn keyword factorWord_destructors contained &dispose already-disposed already-disposed? already-unregistered already-unregistered? check-disposed debug-leaks? disposable disposable? disposables dispose dispose* dispose-each dispose-to new-disposable unless-disposed with-destructors with-disposal \|dispose
+SynKeywordFactorWord factorWord_generic | syn keyword factorWord_generic contained (call-next-method) <default-method> <method> ?lookup-method check-combination-effect check-method check-method-error check-method-error? create-method default-method default-method? define-default-method define-generic effective-method generic generic? implementor-classes lookup-method make-default-method make-generic method method-classes method-for-class method-lookup-failed method-lookup-failed? method-word-name method-word-props method? nearest-class next-method next-method-class next-method-quot next-method-quot* no-next-method no-next-method? order perform-combination remake-generic remake-generics reveal-method update-generic with-implementors with-methods
+SynKeywordFactorWord factorWord_growable | syn keyword factorWord_growable contained capacity contract ensure expand growable growable? new-size
+SynKeywordFactorWord factorWord_io | syn keyword factorWord_io contained (each-stream-block) (each-stream-block-slice) (stream-contents-by-block) (stream-contents-by-element) (stream-contents-by-length) (stream-contents-by-length-or-block) +byte+ +character+ bad-seek-type bad-seek-type? bl contents each-block each-block-size each-block-slice each-line each-stream-block each-stream-block-slice each-stream-line error-stream flush input-stream input-stream? invalid-read-buffer invalid-read-buffer? lines nl output-stream output-stream? print read read-into read-partial read-partial-into read-until read1 readln seek-absolute seek-absolute? seek-end seek-end? seek-input seek-output seek-relative seek-relative? stream-bl stream-contents stream-contents* stream-copy stream-copy* stream-element-type stream-flush stream-length stream-lines stream-nl stream-print stream-read stream-read-into stream-read-partial stream-read-partial-into stream-read-partial-unsafe stream-read-unsafe stream-read-until stream-read1 stream-readln stream-seek stream-seekable? stream-tell stream-write stream-write1 tell-input tell-output with-error-stream with-error-stream* with-error>output with-input-output+error-streams with-input-output+error-streams* with-input-stream with-input-stream* with-output+error-stream with-output+error-stream* with-output-stream with-output-stream* with-output>error with-streams with-streams* write write1
+SynKeywordFactorWord factorWord_io_encodings | syn keyword factorWord_io_encodings contained (decode-until) <decoder> <encoder> decode-char decode-error decode-error? decode-input decode-until decoder decoder? encode-char encode-error encode-error? encode-output encode-string encoder encoder? guess-decoded-length guess-encoded-length re-decode re-encode replacement-char with-decoded-input with-encoded-output
+SynKeywordFactorWord factorWord_io_encodings_binary | syn keyword factorWord_io_encodings_binary contained binary binary?
+SynKeywordFactorWord factorWord_io_encodings_utf8 | syn keyword factorWord_io_encodings_utf8 contained >utf8-index code-point-length code-point-offsets utf8 utf8-index> utf8?
+SynKeywordFactorWord factorWord_io_files | syn keyword factorWord_io_files contained (file-appender) (file-reader) (file-writer) +input+ +output+ +retry+ <file-appender> <file-reader> <file-writer> change-file-contents change-file-lines drain exists? file-contents file-lines file-reader file-reader? file-writer file-writer? init-resource-path refill set-file-contents set-file-lines wait-for-fd with-file-appender with-file-reader with-file-writer
+SynKeywordFactorWord factorWord_kernel | syn keyword factorWord_kernel contained (clone) -roll -rot -rotd 2bi 2bi* 2bi@ 2curry 2dip 2drop 2dup 2keep 2keepd 2nip 2nipd 2over 2tri 2tri* 2tri@ 2with 3bi 3curry 3dip 3drop 3dup 3keep 3nip 3nipd 3tri 4dip 4drop 4dup 4keep 4nip 5drop 5nip <wrapper> = >boolean ? ?if and assert assert= assert? bi bi* bi-curry bi-curry* bi-curry@ bi@ boa boolean boolean? both? build call callstack callstack>array callstack? clear clone compose composed composed? curried curried? curry die dip do drop dup dupd either? eq? equal? execute get-callstack get-datastack get-retainstack hashcode hashcode* identity-hashcode identity-tuple identity-tuple? if if* keep keepd keepdd loop most new nip nipd not null object or over overd pick pickd prepose reach roll rot rotd same? spin swap swapd throw tri tri* tri-curry tri-curry* tri-curry@ tri@ tuck tuple tuple? unless unless* until when when* while while* with wrapper wrapper? xor
+SynKeywordFactorWord factorWord_layouts | syn keyword factorWord_layouts contained (first-bignum) (fixnum-bits) (max-array-capacity) 32bit? 64bit? bootstrap-cell bootstrap-cell-bits bootstrap-cells bootstrap-first-bignum bootstrap-fixnum-bits bootstrap-max-array-capacity bootstrap-most-negative-fixnum bootstrap-most-positive-fixnum cell cell-bits cells data-alignment first-bignum fixnum-bits hashcode-shift header-bits immediate immediate? leaf-stack-frame-size max-array-capacity mega-cache-size most-negative-fixnum most-positive-fixnum num-types tag-bits tag-fixnum tag-header tag-mask type-number type-numbers untag-fixnum
+SynKeywordFactorWord factorWord_make | syn keyword factorWord_make contained % %% , ,+ ,, building make
+SynKeywordFactorWord factorWord_math | syn keyword factorWord_math contained (all-integers?) (each-integer) (find-integer) * + - / /f /i /mod 2/ 2^ < <= <fp-nan> > >= >bignum >fixnum >float >fraction >integer >rect ?1+ abs align all-integers? bignum bignum? bit? bitand bitnot bitor bits>double bits>float bitxor complex complex? denominator double>bits each-integer even? find-integer find-last-integer fixnum fixnum? float float>bits float? fp-bitwise= fp-infinity? fp-nan-payload fp-nan? fp-qnan? fp-sign fp-snan? fp-special? gcd if-zero imaginary-part integer integer>fixnum integer>fixnum-strict integer? log2 log2-expects-positive log2-expects-positive? mod neg neg? next-float next-power-of-2 number number= number? numerator odd? power-of-2? prev-float ratio ratio? rational rational? real real-part real? recip rect> rem sgn shift simple-gcd sq times u< u<= u> u>= unless-zero unordered? when-zero zero?
+SynKeywordFactorWord factorWord_math_order | syn keyword factorWord_math_order contained +eq+ +gt+ +lt+ <=> >=< [-] after=? after? before=? before? between? clamp compare invert-comparison max min
+SynKeywordFactorWord factorWord_memory | syn keyword factorWord_memory contained all-instances compact-gc gc instances minor-gc save save-image save-image-and-exit saving-path size
+SynKeywordFactorWord factorWord_namespaces | syn keyword factorWord_namespaces contained +@ change change-global counter dec get get-global get-namestack global inc init-namespaces initialize namespace off on set set-global set-namestack toggle with-global with-scope with-variable with-variable-off with-variable-on with-variables
+SynKeywordFactorWord factorWord_sequences | syn keyword factorWord_sequences contained 1sequence 2all? 2each 2each-from 2map 2map-as 2map-reduce 2reduce 2selector 2sequence 3append 3append-as 3each 3map 3map-as 3sequence 4sequence <iota> <repetition> <reversed> <slice> ?first ?last ?nth ?second ?set-nth accumulate accumulate! accumulate* accumulate*! accumulate*-as accumulate-as all? any? append append! append-as assert-sequence assert-sequence= assert-sequence? binary-reduce bounds-check bounds-check? bounds-error bounds-error? but-last but-last-slice cartesian-each cartesian-find cartesian-map cartesian-product change-nth check-slice clone-like collapse-slice collector collector-as collector-for collector-for-as concat concat-as copy count cut cut* cut-slice delete-all delete-slice drop-prefix each each-from each-index empty? exchange filter filter! filter-as find find-from find-index find-index-from find-last find-last-from first first2 first3 first4 flip follow fourth glue halves harvest head head* head-slice head-slice* head? if-empty immutable immutable-sequence immutable-sequence? immutable? index index-from indices infimum infimum-by insert-nth interleave iota iota? join join-as last last-index last-index-from length lengthen like longer longer? longest map map! map-as map-find map-find-last map-index map-index-as map-integers map-reduce map-sum max-length member-eq? member? midpoint@ min-length mismatch move new-like new-resizable new-sequence non-negative-integer-expected non-negative-integer-expected? none? nth nths pad-head pad-tail padding partition pop pop* prefix prepend prepend-as produce produce-as product push push-all push-either push-if reduce reduce-index reject reject! reject-as remove remove! remove-eq remove-eq! remove-nth remove-nth! repetition repetition? replace-slice replicate replicate-as rest rest-slice reverse reverse! reversed reversed? second selector selector-as sequence sequence-hashcode sequence= sequence? set-first set-fourth set-last set-length set-nth set-second set-third short shorten shorter shorter? shortest sift slice slice-error slice-error? slice? snip snip-slice subseq subseq-as subseq-start subseq-start-from subseq? suffix suffix! sum sum-lengths supremum supremum-by surround tail tail* tail-slice tail-slice* tail? third trim trim-head trim-head-slice trim-slice trim-tail trim-tail-slice unclip unclip-last unclip-last-slice unclip-slice unless-empty virtual-exemplar virtual-sequence virtual-sequence? virtual@ when-empty
+SynKeywordFactorWord factorWord_sets | syn keyword factorWord_sets contained ?adjoin ?delete adjoin adjoin-all adjoin-at all-unique? cardinality clear-set combine delete diff diff! duplicates fast-set gather in? intersect intersect! intersection intersects? members null? refine set set-like set= set? subset? union union! within without
+SynKeywordFactorWord factorWord_sorting | syn keyword factorWord_sorting contained inv-sort-with natural-sort sort sort-keys sort-pair sort-values sort-with
+SynKeywordFactorWord factorWord_splitting | syn keyword factorWord_splitting contained ?head ?head-slice ?tail ?tail-slice replace split split-indices split-slice split-subseq split-when split-when-slice split1 split1-last split1-last-slice split1-slice split1-when split1-when-slice string-lines
+SynKeywordFactorWord factorWord_strings | syn keyword factorWord_strings contained 1string <string> >string resize-string string string?
+SynKeywordFactorWord factorWord_strings_parser | syn keyword factorWord_strings_parser contained bad-escape bad-escape? escape hex-escape name>char-hook next-escape parse-string unescape-string unicode-escape
+SynKeywordFactorWord factorWord_syntax | syn keyword factorWord_syntax contained " ( : ; << <<<<<< <<<<<<< <PRIVATE ====== ======= >> >>>>>> >>>>>>> ALIAS: B B: BUILTIN: BV{ B{ C: CHAR: CONSTANT: CS{ C{ DEFER: ERROR: EXCLUDE: FORGET: FROM: GENERIC#: GENERIC: HOOK: HS{ H{ IN: INSTANCE: INTERSECTION: M: MAIN: MATH: MIXIN: M\ NAN: P" POSTPONE: PREDICATE: PRIMITIVE: PRIVATE> QUALIFIED-WITH: QUALIFIED: RENAME: SBUF" SINGLETON: SINGLETONS: SLOT: SYMBOL: SYMBOLS: SYNTAX: TH{ TUPLE: T{ UNION: UNUSE: USE: USING: V{ W{ [ \ ] call( call-next-method delimiter deprecated execute( f final flushable foldable initial: inline intersection{ malformed-complex malformed-complex? maybe{ not{ parse-complex read-only recursive t t? union{ { }
+SynKeywordFactorWord factorWord_vectors | syn keyword factorWord_vectors contained 1vector <vector> >vector ?push vector vector?
+
+delcommand HiLink
+delcommand SynKeywordFactorWord
+
+let b:factor_syn_no_generated = 1
+
+" vim:set ft=vim sw=2: