diff options
Diffstat (limited to 'vendor/github.com/alecthomas/chroma/lexers/r')
-rw-r--r-- | vendor/github.com/alecthomas/chroma/lexers/r/raku.go | 771 | ||||
-rw-r--r-- | vendor/github.com/alecthomas/chroma/lexers/r/rust.go | 56 |
2 files changed, 523 insertions, 304 deletions
diff --git a/vendor/github.com/alecthomas/chroma/lexers/r/raku.go b/vendor/github.com/alecthomas/chroma/lexers/r/raku.go index a5f55e1f6e..349cb98c00 100644 --- a/vendor/github.com/alecthomas/chroma/lexers/r/raku.go +++ b/vendor/github.com/alecthomas/chroma/lexers/r/raku.go @@ -33,26 +33,24 @@ func rakuRules() Rules { const ( rakuQuote RakuToken = iota - rakuName rakuNameAttribute rakuPod rakuPodFormatter rakuPodDeclaration rakuMultilineComment - rakuSlashRegex rakuMatchRegex rakuSubstitutionRegex - rakuSubstitutionSingleRegex - rakuRegexInsideToken ) const ( colonPairOpeningBrackets = `(?:<<|<|«|\(|\[|\{)` colonPairClosingBrackets = `(?:>>|>|»|\)|\]|\})` - colonPairPattern = `(?<colon>:)(?<key>\w[\w'-]*)(?<opening_delimiters>` + colonPairOpeningBrackets + `)` - namePattern = `((?:(?!` + colonPairPattern + `)[\w':-])+)` - variablePattern = `[$@%&]+[.^:?=!~]?` + namePattern - globalVariablePattern = `[$@%&]+\*` + namePattern + colonPairPattern = `(?<!:)(?<colon>:)(?<key>\w[\w'-]*)(?<opening_delimiters>` + colonPairOpeningBrackets + `)` + colonPairLookahead = `(?=(:['\w-]+` + + colonPairOpeningBrackets + `.+?` + colonPairClosingBrackets + `)?` + namePattern = `(?:(?!` + colonPairPattern + `)(?:::|[\w':-]))+` + variablePattern = `[$@%&]+[.^:?=!~]?` + namePattern + globalVariablePattern = `[$@%&]+\*` + namePattern ) keywords := []string{ @@ -339,13 +337,11 @@ func rakuRules() Rules { // Finds opening brackets and their closing counterparts (including pod and heredoc) // and modifies state groups and position accordingly - bracketsFinder := func(tokenClass RakuToken) MutatorFunc { + findBrackets := func(tokenClass RakuToken) MutatorFunc { return func(state *LexerState) error { var openingChars []rune var adverbs []rune switch tokenClass { - case rakuRegexInsideToken: - openingChars = []rune("{") case rakuPod: openingChars = []rune(strings.Join(state.Groups[1:5], ``)) default: @@ -363,7 +359,6 @@ func rakuRules() Rules { switch tokenClass { case rakuPod: - closingChars = []rune(state.NamedGroups[`ws`] + `=end ` + state.NamedGroups[`name`]) closingCharExists = true default: closingChar, closingCharExists = brackets[openingChar] @@ -371,17 +366,8 @@ func rakuRules() Rules { switch tokenClass { case rakuPodFormatter: - stack, ok := state.Get("pod_formatter_stack").([]RakuFormatterRules) - if !ok { - stack = []RakuFormatterRules{} - } - popRule := makeRuleAndPushMaybe(RuleMakingConfig{ - delimiter: []rune{closingChar}, - numberOfDelimiterChars: nChars, - tokenType: Punctuation, - mutator: Mutators(Pop(1), MutatorFunc(podFormatterPopper)), - }) - var formatter TokenType = StringOther + formatter := StringOther + switch state.NamedGroups[`keyword`] { case "B": formatter = GenericStrong @@ -390,20 +376,34 @@ func rakuRules() Rules { case "U": formatter = GenericUnderline } - formattingRule := makeRuleAndPushMaybe(RuleMakingConfig{ - pattern: `.+?`, - tokenType: formatter, - mutator: nil, - }) - state.Set("pod_formatter_stack", - append(stack, RakuFormatterRules{popRule, formattingRule})) + + formatterRule := ruleReplacingConfig{ + pattern: `.+?`, + tokenType: formatter, + mutator: nil, + stateName: `pod-formatter`, + rulePosition: bottomRule, + } + + err := replaceRule(formatterRule)(state) + if err != nil { + panic(err) + } + + err = replaceRule(ruleReplacingConfig{ + delimiter: []rune{closingChar}, + tokenType: Punctuation, + stateName: `pod-formatter`, + pushState: true, + numberOfDelimiterChars: nChars, + appendMutator: popRule(formatterRule), + })(state) + if err != nil { + panic(err) + } return nil - case rakuMatchRegex, rakuSubstitutionSingleRegex, rakuRegexInsideToken: - // We're inside a regex - // While matching a regex, the closing chars may have been used inside the regex - // so we have to push to regex state and pop on the matched closing chars - // and return + case rakuMatchRegex: var delimiter []rune if closingCharExists { delimiter = []rune{closingChar} @@ -411,16 +411,32 @@ func rakuRules() Rules { delimiter = openingChars } - makeRuleAndPushMaybe(RuleMakingConfig{ - delimiter: delimiter, - tokenType: Punctuation, - mutator: Pop(1), - rulePosition: topRule, - state: state, - stateName: "regex", - pushToStack: true, - numberOfDelimiterChars: nChars, - }) + err := replaceRule(ruleReplacingConfig{ + delimiter: delimiter, + tokenType: Punctuation, + stateName: `regex`, + popState: true, + pushState: true, + })(state) + if err != nil { + panic(err) + } + + return nil + case rakuSubstitutionRegex: + delimiter := regexp2.Escape(string(openingChars)) + + err := replaceRule(ruleReplacingConfig{ + pattern: `(` + delimiter + `)` + `((?:\\\\|\\/|.)*?)` + `(` + delimiter + `)`, + tokenType: ByGroups(Punctuation, UsingSelf(`qq`), Punctuation), + rulePosition: topRule, + stateName: `regex`, + popState: true, + pushState: true, + })(state) + if err != nil { + panic(err) + } return nil } @@ -434,10 +450,17 @@ func rakuRules() Rules { if !closingCharExists { // it's not a mirrored character, which means we // just need to look for the next occurrence - nonMirroredOpeningCharPosition = indexAt(text, openingChars, state.Pos) + closingChars = openingChars + nonMirroredOpeningCharPosition = indexAt(text, closingChars, state.Pos) endPos = nonMirroredOpeningCharPosition } else { - if tokenClass != rakuPod { + var podRegex *regexp2.Regexp + if tokenClass == rakuPod { + podRegex = regexp2.MustCompile( + state.NamedGroups[`ws`]+`=end`+`\s+`+regexp2.Escape(state.NamedGroups[`name`]), + 0, + ) + } else { closingChars = []rune(strings.Repeat(string(closingChar), nChars)) } @@ -450,8 +473,19 @@ func rakuRules() Rules { var nextClosePos int for nestingLevel > 0 { + if tokenClass == rakuPod { + match, err := podRegex.FindRunesMatchStartingAt(text, searchPos+nChars) + if err == nil { + closingChars = match.Runes() + nextClosePos = match.Index + } else { + nextClosePos = -1 + } + } else { + nextClosePos = indexAt(text, closingChars, searchPos+nChars) + } + nextOpenPos := indexAt(text, openingChars, searchPos+nChars) - nextClosePos = indexAt(text, closingChars, searchPos+nChars) switch { case nextClosePos == -1: @@ -479,14 +513,24 @@ func rakuRules() Rules { adverbre := regexp.MustCompile(`:to\b|:heredoc\b`) var heredocTerminator []rune + var endHeredocPos int if adverbre.MatchString(string(adverbs)) { - heredocTerminator = text[state.Pos:endPos] - if len(heredocTerminator) > 0 { - endHeredocPos := indexAt(text[endPos:], heredocTerminator, 0) + if endPos != len(text) { + heredocTerminator = text[state.Pos:endPos] nChars = len(heredocTerminator) - endPos += endHeredocPos } else { - endPos = len(text) + endPos = state.Pos + 1 + heredocTerminator = []rune{} + nChars = 0 + } + + if nChars > 0 { + endHeredocPos = indexAt(text[endPos:], heredocTerminator, 0) + if endHeredocPos > -1 { + endPos += endHeredocPos + } else { + endPos = len(text) + } } } @@ -498,7 +542,7 @@ func rakuRules() Rules { case rakuQuote: if len(heredocTerminator) > 0 { // Length of heredoc terminator + closing chars + `;` - heredocFristPunctuationLen := len(heredocTerminator) + len(openingChars) + 1 + heredocFristPunctuationLen := nChars + len(openingChars) + 1 state.NamedGroups[`opening_delimiters`] = string(openingChars) + string(text[state.Pos:state.Pos+heredocFristPunctuationLen]) @@ -506,10 +550,14 @@ func rakuRules() Rules { state.NamedGroups[`value`] = string(text[state.Pos+heredocFristPunctuationLen : endPos]) - state.NamedGroups[`closing_delimiters`] = string(heredocTerminator) + if endHeredocPos > -1 { + state.NamedGroups[`closing_delimiters`] = string(heredocTerminator) + } } else { state.NamedGroups[`value`] = textBetweenBrackets - state.NamedGroups[`closing_delimiters`] = string(closingChars) + if nChars > 0 { + state.NamedGroups[`closing_delimiters`] = string(closingChars) + } } default: state.Groups = []string{state.Groups[0] + string(text[state.Pos:endPos+nChars])} @@ -522,12 +570,17 @@ func rakuRules() Rules { } // Raku rules - // Empty capture groups are placeholders and will be replaced by bracketsFinder. + // Empty capture groups are placeholders and will be replaced by mutators // DO NOT REMOVE THEM! return Rules{ "root": { + // Placeholder, will be overwritten by mutators, DO NOT REMOVE! + {`\A\z`, nil, nil}, Include("common"), - {`[{}();]`, Punctuation, nil}, + {`{`, Punctuation, Push(`root`)}, + {`\(`, Punctuation, Push(`root`)}, + {`[)}]`, Punctuation, Pop(1)}, + {`;`, Punctuation, nil}, {`\[|\]`, Operator, nil}, {`.+?`, Text, nil}, }, @@ -538,14 +591,14 @@ func rakuRules() Rules { { "#`(?<opening_delimiters>(?<delimiter>" + bracketsPattern + `)\k<delimiter>*)`, CommentMultiline, - bracketsFinder(rakuMultilineComment), + findBrackets(rakuMultilineComment), }, {`#[^\n]*$`, CommentSingle, nil}, // /regex/ { - `(?<=(?:^|\(|=|:|~~|\[|,|=>)\s*)(/)(?!\]|\))((?:\\\\|\\/|.)*?)((?<!(?<!\\)\\)/(?!'|"))`, + `(?<=(?:^|\(|=|:|~~|\[|{|,|=>)\s*)(/)(?!\]|\))((?:\\\\|\\/|.)*?)((?<!(?<!\\)\\)/(?!'|"))`, ByGroups(Punctuation, UsingSelf("regex"), Punctuation), - MutatorFunc(makeRegexPoppingRule), + nil, }, Include("variable"), // ::?VARIABLE @@ -567,9 +620,9 @@ func rakuRules() Rules { {`(>>)(\S+?)(>>)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, {`(»)(\S+?)(»)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, // <<quoted words>> - {`(?<!(?:\d+|\.(?:Int|Numeric)|[$@%][\w':-]+\s+|[\])}]\s+)\s*)(<<)(?!(?:(?!>>)[^\n])+?[},;] *\n)(?!(?:(?!>>).)+?>>\S+?>>)`, Punctuation, Push("<<")}, + {`(?<!(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+\s+|[\])}]\s+)\s*)(<<)(?!(?:(?!>>)[^\n])+?[},;] *\n)(?!(?:(?!>>).)+?>>\S+?>>)`, Punctuation, Push("<<")}, // «quoted words» - {`(?<!(?:\d+|\.(?:Int|Numeric)|[$@%][\w':-]+\s+|[\])}]\s+)\s*)(«)(?![^»]+?[},;] *\n)(?![^»]+?»\S+?»)`, Punctuation, Push("«")}, + {`(?<!(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+\s+|[\])}]\s+)\s*)(«)(?![^»]+?[},;] *\n)(?![^»]+?»\S+?»)`, Punctuation, Push("«")}, // [<] {`(?<=\[\\?)<(?=\])`, Operator, nil}, // < and > operators | something < onething > something @@ -580,39 +633,25 @@ func rakuRules() Rules { }, // <quoted words> { - `(?<!(?:\d+|\.(?:Int|Numeric)|[$@%][\w':-]+\s+|[\])}]\s+)\s*)(<)((?:(?![,;)}] *(?:#[^\n]+)?\n)[^<>])+?)(>)(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\w[\w':-]*[^(]|\s+\[))`, + `(?<!(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+\s+|[\])}]\s+)\s*)(<)((?:(?![,;)}] *(?:#[^\n]+)?\n)[^<>])+?)(>)(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?\w[\w':-]*[^(]|\s+\[))`, ByGroups(Punctuation, String, Punctuation), nil, }, {`C?X::['\w:-]+`, NameException, nil}, Include("metaoperator"), - // Pair | (key) => value - { - `(\([^)]+\))(\s*)(=>)(\s*)([^,\n]+)(,?\n*)`, - ByGroups(UsingSelf("root"), Text, Operator, Text, UsingSelf("root"), Text), - nil, - }, // Pair | key => value { - `(\w[\w'-]*)(\s*)(=>)(\s*)([^,\n]+)(,?\n*)`, - ByGroups(String, Text, Operator, Text, UsingSelf("root"), Text), + `(\w[\w'-]*)(\s*)(=>)`, + ByGroups(String, Text, Operator), nil, }, Include("colon-pair"), // Token { - // Token with adverbs - `(?<=(?:^|\s)(?:regex|token|rule)(\s+))(['\w:-]+)(?=:['\w-]+` + - colonPairOpeningBrackets + `.+?` + colonPairClosingBrackets + `[({])`, + `(?<=(?:^|\s)(?:regex|token|rule)(\s+))` + namePattern + colonPairLookahead + `\s*[({])`, NameFunction, Push("token", "name-adverb"), }, - { - // Token without adverbs - `(?<=(?:^|\s)(?:regex|token|rule)(?:\s+))(['\w:-]+)`, - NameFunction, - Push("token"), - }, // Substitution {`(?<=^|\b|\s)(?<!\.)(ss|S|s|TR|tr)\b(\s*)`, ByGroups(Keyword, Text), Push("substitution")}, {keywordsPattern, Keyword, nil}, @@ -626,18 +665,10 @@ func rakuRules() Rules { }, // Routine { - // Routine with adverbs - `(?<=(?:^|\s)(?:sub|method|multi sub|multi)\s+)!?['\w:-]+(?=:['\w-]+` + - colonPairOpeningBrackets + `.+?` + colonPairClosingBrackets + `[({])`, + `(?<=(?:^|\s)(?:sub|method|multi sub|multi)\s+)!?` + namePattern + colonPairLookahead + `\s*[({])`, NameFunction, Push("name-adverb"), }, - { - // Routine without adverbs - `(?<=(?:^|\s)(?:sub|submethod|method|multi)\s+)!?['\w:-]+`, - NameFunction, - nil, - }, // Constant {`(?<=\bconstant\s+)` + namePattern, NameConstant, Push("name-adverb")}, // Namespace @@ -651,26 +682,20 @@ func rakuRules() Rules { { `(?<=^|\b|\s)(?<keyword>(?:qq|q|Q))(?<adverbs>(?::?(?:heredoc|to|qq|ww|q|w|s|a|h|f|c|b|to|v|x))*)(?<ws>\s*)(?<opening_delimiters>(?<delimiter>[^0-9a-zA-Z:\s])\k<delimiter>*)`, EmitterFunc(quote), - bracketsFinder(rakuQuote), + findBrackets(rakuQuote), }, // Function { - `\b(?:\w['\w:-]*)(?=:['\w-]+` + - colonPairOpeningBrackets + `.+?` + colonPairClosingBrackets + `\()`, + `\b` + namePattern + colonPairLookahead + `\()`, NameFunction, Push("name-adverb"), }, - {`\b(?:\w['\w:-]*)(?=\()`, NameFunction, nil}, // Method - // Method with adverb { - `(?<!\.\.[?^*+]?)(?<=(?:\.[?^*+&]?)|self!)['\w:-]+(?=:['\w-]+` + - colonPairOpeningBrackets + `.+?` + colonPairClosingBrackets + `$)`, + `(?<!\.\.[?^*+]?)(?<=(?:\.[?^*+&]?)|self!)` + namePattern + colonPairLookahead + `\b)`, NameFunction, Push("name-adverb"), }, - // Method without adverb - {`(?<!\.\.[?^*+]?)(?<=(?:\.[?^*+&]?)|self!)['\w:-]+`, NameFunction, nil}, // Indirect invocant {namePattern + `(?=\s+\W?['\w:-]+:\W)`, NameFunction, Push("name-adverb")}, {`(?<=\W)(?:∅|i|e|𝑒|tau|τ|pi|π|Inf|∞)(?=\W)`, NameConstant, nil}, @@ -688,11 +713,13 @@ func rakuRules() Rules { Include("colon-pair-attribute"), { `(?<opening_delimiters>(?<delimiter>[^\w:\s])\k<delimiter>*)`, - ByGroupNames(map[string]Emitter{ - `opening_delimiters`: Punctuation, - `delimiter`: nil, - }), - Mutators(Pop(1), bracketsFinder(rakuMatchRegex)), + ByGroupNames( + map[string]Emitter{ + `opening_delimiters`: Punctuation, + `delimiter`: nil, + }, + ), + findBrackets(rakuMatchRegex), }, }, "substitution": { @@ -704,15 +731,13 @@ func rakuRules() Rules { `opening_delimiters`: Punctuation, `delimiter`: nil, }), - Mutators(Pop(1), bracketsFinder(rakuSubstitutionSingleRegex)), + findBrackets(rakuMatchRegex), }, // Substitution | s/regex/string/ { - `([^\w:\s])((?:\\\\|\\/|.)*?)(\1)((?:\\\\|\\/|.)*?)(\1)`, - ByGroups( - Punctuation, UsingSelf("regex"), Punctuation, UsingSelf("qq"), Punctuation, - ), - Mutators(Pop(1), MutatorFunc(makeRegexPoppingRule)), + `(?<opening_delimiters>[^\w:\s])`, + Punctuation, + findBrackets(rakuSubstitutionRegex), }, }, "number": { @@ -734,33 +759,33 @@ func rakuRules() Rules { }, "colon-pair": { // :key(value) - {colonPairPattern, colonPair(String), bracketsFinder(rakuNameAttribute)}, + {colonPairPattern, colonPair(String), findBrackets(rakuNameAttribute)}, // :123abc { - `(:)(\d+)(\w[\w'-]*)(\s*[,;)]?\s*$)`, - ByGroups(Punctuation, UsingSelf("number"), String, Text), + `(:)(\d+)(\w[\w'-]*)`, + ByGroups(Punctuation, UsingSelf("number"), String), nil, }, // :key - {`(:!?)(\w[\w'-]*)`, ByGroups(Punctuation, String), nil}, + {`(:)(!?)(\w[\w'-]*)`, ByGroups(Punctuation, Operator, String), nil}, {`\s+`, Text, nil}, }, "colon-pair-attribute": { // :key(value) - {colonPairPattern, colonPair(NameAttribute), bracketsFinder(rakuNameAttribute)}, + {colonPairPattern, colonPair(NameAttribute), findBrackets(rakuNameAttribute)}, // :123abc { - `(:)(\d+)(\w+)(\s*[,;)]?\s*$)`, - ByGroups(Punctuation, UsingSelf("number"), NameAttribute, Text), + `(:)(\d+)(\w[\w'-]*)`, + ByGroups(Punctuation, UsingSelf("number"), NameAttribute), nil, }, // :key - {`(:!?)(\w[\w'-]*)`, ByGroups(Punctuation, NameAttribute), nil}, + {`(:)(!?)(\w[\w'-]*)`, ByGroups(Punctuation, Operator, NameAttribute), nil}, {`\s+`, Text, nil}, }, "colon-pair-attribute-keyvalue": { // :key(value) - {colonPairPattern, colonPair(NameAttribute), bracketsFinder(rakuNameAttribute)}, + {colonPairPattern, colonPair(NameAttribute), findBrackets(rakuNameAttribute)}, }, "escape-qq": { { @@ -769,6 +794,12 @@ func rakuRules() Rules { nil, }, }, + `escape-char`: { + {`(?<!(?<!\\)\\)(\\[abfrnrt])`, StringEscape, nil}, + }, + `escape-single-quote`: { + {`(?<!(?<!\\)\\)(\\)(['\\])`, ByGroups(StringEscape, StringSingle), nil}, + }, "escape-c-name": { { `(?<!(?<!\\)\\)(\\[c|C])(\[)(.+?)(\])`, @@ -785,14 +816,20 @@ func rakuRules() Rules { {`(\\[x|X])([0-9a-fA-F]+)`, ByGroups(StringEscape, NumberHex), nil}, }, "regex": { - // Placeholder, will be overwritten by bracketsFinder, DO NOT REMOVE! - {`^$`, nil, nil}, + // Placeholder, will be overwritten by mutators, DO NOT REMOVE! + {`\A\z`, nil, nil}, Include("regex-escape-class"), + Include(`regex-character-escape`), // $(code) { - `(?<!(?<!\\)\\)([$@])(\()(.*?)(\))`, - ByGroups(Keyword, Punctuation, UsingSelf("root"), Punctuation), - nil, + `([$@])((?<!(?<!\\)\\)\()`, + ByGroups(Keyword, Punctuation), + replaceRule(ruleReplacingConfig{ + delimiter: []rune(`)`), + tokenType: Punctuation, + stateName: `root`, + pushState: true, + }), }, // Exclude $/ from variables, because we can't get out of the end of the slash regex: $/; {`\$(?=/)`, NameEntity, nil}, @@ -805,18 +842,28 @@ func rakuRules() Rules { Include("single-quote"), // :my variable code ... { - `(?<!(?<!\\)\\)(:)(my|our|state|constant|temp|let)(.+?;)`, - ByGroups(Operator, KeywordDeclaration, UsingSelf("root")), - nil, + `(?<!(?<!\\)\\)(:)(my|our|state|constant|temp|let)`, + ByGroups(Operator, KeywordDeclaration), + replaceRule(ruleReplacingConfig{ + delimiter: []rune(`;`), + tokenType: Punctuation, + stateName: `root`, + pushState: true, + }), }, // <{code}> { - `(?<!(?<!\\)\\)(<)([?!])?((?<!(?<!\\)\\){)(.*?)(}>)`, - ByGroups(Punctuation, Operator, Punctuation, UsingSelf("root"), Punctuation), - nil, + `(?<!(?<!\\)\\)(<)([?!.]*)((?<!(?<!\\)\\){)`, + ByGroups(Punctuation, Operator, Punctuation), + replaceRule(ruleReplacingConfig{ + delimiter: []rune(`}>`), + tokenType: Punctuation, + stateName: `root`, + pushState: true, + }), }, // {code} - {`(?<!(?<!\\)\\)({)(.*?)(})`, ByGroups(Punctuation, UsingSelf("root"), Punctuation), nil}, + Include(`closure`), // Properties {`(:)(\w+)`, ByGroups(Punctuation, NameAttribute), nil}, // Operator @@ -827,9 +874,14 @@ func rakuRules() Rules { {`#[^\n]*\n`, CommentSingle, nil}, // Lookaround { - `(?<!(?<!\\)\\)(<)(\s*)([?!.])(\s*)(after|before)`, + `(?<!(?<!\\)\\)(<)(\s*)([?!.]+)(\s*)(after|before)`, ByGroups(Punctuation, Text, Operator, Text, OperatorWord), - Push("regex"), + replaceRule(ruleReplacingConfig{ + delimiter: []rune(`>`), + tokenType: Punctuation, + stateName: `regex`, + pushState: true, + }), }, { `(?<!(?<!\\)\\)(<)([|!?.]*)(wb|ww|ws|w)(>)`, @@ -838,15 +890,25 @@ func rakuRules() Rules { }, // <$variable> { - `(?<!(?<!\\)\\)(<)([$@]\w[\w-:]*)(>)`, - ByGroups(Punctuation, NameVariable, Punctuation), + `(?<!(?<!\\)\\)(<)([?!.]*)([$@]\w[\w:-]*)(>)`, + ByGroups(Punctuation, Operator, NameVariable, Punctuation), nil, }, // Capture markers {`(?<!(?<!\\)\\)<\(|\)>`, Operator, nil}, + { + `(?<!(?<!\\)\\)(<)(\w[\w:-]*)(=\.?)`, + ByGroups(Punctuation, NameVariable, Operator), + Push(`regex-variable`), + }, + { + `(?<!(?<!\\)\\)(<)([|!?.&]*)(\w(?:(?!:\s)[\w':-])*)`, + ByGroups(Punctuation, Operator, NameFunction), + Push(`regex-function`), + }, {`(?<!(?<!\\)\\)<`, Punctuation, Push("regex-property")}, {`(?<!(?<!\\)\\)"`, Punctuation, Push("double-quotes")}, - {`(?<!(?<!\\)\\)(?:\]|\)|>)`, Punctuation, Pop(1)}, + {`(?<!(?<!\\)\\)(?:\]|\))`, Punctuation, Pop(1)}, {`(?<!(?<!\\)\\)(?:\[|\()`, Punctuation, Push("regex")}, {`.+?`, StringRegex, nil}, }, @@ -857,41 +919,85 @@ func rakuRules() Rules { nil, }, }, - "regex-property": { + "regex-function": { + // <function> {`(?<!(?<!\\)\\)>`, Punctuation, Pop(1)}, - Include("regex-class-builtin"), - Include("variable"), - // <regexfunc> | <regexfunc(parameter)> | <variable=regexfunc> + // <function(parameter)> { - `(?:(\w[\w-:]*)(=\.?))?(&?\w[\w'-:]+?)(\(.+?\))?(?=>)`, - ByGroups( - NameVariable, Operator, NameFunction, UsingSelf("root"), - ), - nil, + `\(`, + Punctuation, + replaceRule(ruleReplacingConfig{ + delimiter: []rune(`)>`), + tokenType: Punctuation, + stateName: `root`, + popState: true, + pushState: true, + }), }, - // <func: value> + // <function value> { - `(&?\w[\w':-]*?)(:)((?:.*?(?:\$<\w[\w':-]*>)?.*?)*?)(?=>)`, - ByGroups( - NameFunction, Punctuation, UsingSelf("root"), - ), - nil, + `\s+`, + StringRegex, + replaceRule(ruleReplacingConfig{ + delimiter: []rune(`>`), + tokenType: Punctuation, + stateName: `regex`, + popState: true, + pushState: true, + }), + }, + // <function: value> + { + `:`, + Punctuation, + replaceRule(ruleReplacingConfig{ + delimiter: []rune(`>`), + tokenType: Punctuation, + stateName: `root`, + popState: true, + pushState: true, + }), }, + }, + "regex-variable": { + Include(`regex-starting-operators`), + // <var=function( + { + `(&)?(\w(?:(?!:\s)[\w':-])*)(?=\()`, + ByGroups(Operator, NameFunction), + Mutators(Pop(1), Push(`regex-function`)), + }, + // <var=function> + {`(&)?(\w[\w':-]*)(>)`, ByGroups(Operator, NameFunction, Punctuation), Pop(1)}, + // <var= + Default(Pop(1), Push(`regex-property`)), + }, + "regex-property": { + {`(?<!(?<!\\)\\)>`, Punctuation, Pop(1)}, + Include("regex-class-builtin"), + Include("variable"), + Include(`regex-starting-operators`), Include("colon-pair-attribute"), {`(?<!(?<!\\)\\)\[`, Punctuation, Push("regex-character-class")}, {`\+|\-`, Operator, nil}, - {`@[\w'-:]+`, NameVariable, nil}, - {`(?<=<)[|!?.]`, Operator, nil}, + {`@[\w':-]+`, NameVariable, nil}, {`.+?`, StringRegex, nil}, }, + `regex-starting-operators`: { + {`(?<=<)[|!?.]+`, Operator, nil}, + }, "regex-escape-class": { {`(?i)\\n|\\t|\\h|\\v|\\s|\\d|\\w`, StringEscape, nil}, }, + `regex-character-escape`: { + {`(?<!(?<!\\)\\)(\\)(.)`, ByGroups(StringEscape, StringRegex), nil}, + }, "regex-character-class": { {`(?<!(?<!\\)\\)\]`, Punctuation, Pop(1)}, Include("regex-escape-class"), Include("escape-c-name"), Include("escape-hexadecimal"), + Include(`regex-character-escape`), Include("number"), {`\.\.`, Operator, nil}, {`.+?`, StringRegex, nil}, @@ -923,10 +1029,10 @@ func rakuRules() Rules { `keyword`: Keyword, `opening_delimiters`: Punctuation, `delimiter`: nil, - `value`: UsingSelf("pod-begin"), + `value`: UsingSelf("pod-declaration"), `closing_delimiters`: Punctuation, }), - bracketsFinder(rakuPodDeclaration), + findBrackets(rakuPodDeclaration), }, Include("pod-blocks"), }, @@ -950,7 +1056,7 @@ func rakuRules() Rules { `value`: UsingSelf("pod-begin"), `closing_delimiters`: Keyword, }), - bracketsFinder(rakuPod), + findBrackets(rakuPod), }, // =for ... { @@ -986,13 +1092,13 @@ func rakuRules() Rules { { `(?<=^ *)(?<ws> *)(?<keyword>=head\d+)(?<ws2> *)(?<config>#?)`, ByGroups(Comment, Keyword, GenericHeading, Keyword), - Push("pod-single-heading"), + Push("pod-heading"), }, // =item ... { `(?<=^ *)(?<ws> *)(?<keyword>=(?:item\d*|comment|data|[A-Z]+))(?<ws2> *)(?<config>#?)`, ByGroups(Comment, Keyword, StringDoc, Keyword), - Push("pod-single"), + Push("pod-paragraph"), }, { `(?<=^ *)(?<ws> *)(?<keyword>=finish)(?<config>[^\n]*)`, @@ -1003,7 +1109,7 @@ func rakuRules() Rules { { `(?<=^ *)(?<ws> *)(?<name>=\w[\w'-]*)(?<ws2> *)(?<config>#?)`, ByGroups(Comment, Name, StringDoc, Keyword), - Push("pod-single"), + Push("pod-paragraph"), }, // = podconfig { @@ -1018,8 +1124,12 @@ func rakuRules() Rules { Include("pre-pod-formatter"), {`.+?`, StringDoc, nil}, }, + "pod-declaration": { + Include("pre-pod-formatter"), + {`.+?`, StringDoc, nil}, + }, "pod-paragraph": { - {`\n\s*?\n`, StringDoc, Pop(1)}, + {`\n *\n|\n(?=^ *=)`, StringDoc, Pop(1)}, Include("pre-pod-formatter"), {`.+?`, StringDoc, nil}, }, @@ -1028,8 +1138,8 @@ func rakuRules() Rules { Include("pre-pod-formatter"), {`.+?`, StringDoc, nil}, }, - "pod-single-heading": { - {`\n`, GenericHeading, Pop(1)}, + "pod-heading": { + {`\n *\n|\n(?=^ *=)`, GenericHeading, Pop(1)}, Include("pre-pod-formatter"), {`.+?`, GenericHeading, nil}, }, @@ -1043,25 +1153,21 @@ func rakuRules() Rules { { `(?<keyword>[CBIUDTKRPAELZVMSXN])(?<opening_delimiters><+|«)`, ByGroups(Keyword, Punctuation), - Mutators( - bracketsFinder(rakuPodFormatter), - Push("pod-formatter"), MutatorFunc(podFormatter), - ), + findBrackets(rakuPodFormatter), }, }, "pod-formatter": { - // Placeholder rule, will be replaced by podFormatter. DO NOT REMOVE! + // Placeholder rule, will be replaced by mutators. DO NOT REMOVE! {`>`, Punctuation, Pop(1)}, Include("pre-pod-formatter"), - // Placeholder rule, will be replaced by podFormatter. DO NOT REMOVE! + // Placeholder rule, will be replaced by mutators. DO NOT REMOVE! {`.+?`, StringOther, nil}, }, "variable": { {variablePattern, NameVariable, Push("name-adverb")}, {globalVariablePattern, NameVariableGlobal, Push("name-adverb")}, - {`[$@](?:<.*?>)+`, NameVariable, nil}, - {`\$/`, NameVariable, nil}, - {`\$!`, NameVariable, nil}, + {`[$@]<[^>]+>`, NameVariable, nil}, + {`\$[/!¢]`, NameVariable, nil}, {`[$@%]`, NameVariable, nil}, }, "single-quote": { @@ -1069,6 +1175,7 @@ func rakuRules() Rules { }, "single-quote-inner": { {`(?<!(?<!(?<!\\)\\)\\)'`, Punctuation, Pop(1)}, + Include("escape-single-quote"), Include("escape-qq"), {`(?:\\\\|\\[^\\]|[^'\\])+?`, StringSingle, nil}, }, @@ -1077,11 +1184,11 @@ func rakuRules() Rules { Include("qq"), }, "<<": { - {`>>(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%][\w':-]+|\s+\[))`, Punctuation, Pop(1)}, + {`>>(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)}, Include("ww"), }, "«": { - {`»(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%][\w':-]+|\s+\[))`, Punctuation, Pop(1)}, + {`»(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)}, Include("ww"), }, "ww": { @@ -1090,39 +1197,39 @@ func rakuRules() Rules { }, "qq": { Include("qq-variable"), - // Function with adverb - { - `\w[\w:'-]+(?=:['\w-]+` + - colonPairOpeningBrackets + `.+?` + colonPairClosingBrackets + `\()`, - NameFunction, - Push("qq-function", "name-adverb"), - }, - // Function without adverb - {`\w[\w:'-]+(?=\((?!"))`, NameFunction, Push("qq-function")}, Include("closure"), + Include(`escape-char`), Include("escape-hexadecimal"), Include("escape-c-name"), Include("escape-qq"), {`.+?`, StringDouble, nil}, }, - "qq-function": { - {`(\([^"]*?\))`, UsingSelf("root"), nil}, - Default(Pop(1)), - }, "qq-variable": { { - `(?<!(?<!\\)\\)(?:` + variablePattern + `|` + globalVariablePattern + `)`, + `(?<!(?<!\\)\\)(?:` + variablePattern + `|` + globalVariablePattern + `)` + colonPairLookahead + `)`, NameVariable, Push("qq-variable-extras", "name-adverb"), }, }, "qq-variable-extras": { - {`(?:\[.*?\]|\{.*?\}|<<.*?>>|<.*?>|«.*?»)+`, UsingSelf("root"), nil}, // Method { - `(\.)([^(\s]+)(\([^"]*?\))`, - ByGroups(Operator, NameFunction, UsingSelf("root")), - nil, + `(?<operator>\.)(?<method_name>` + namePattern + `)` + colonPairLookahead + `\()`, + ByGroupNames(map[string]Emitter{ + `operator`: Operator, + `method_name`: NameFunction, + }), + Push(`name-adverb`), + }, + // Function/Signature + { + `\(`, Punctuation, replaceRule( + ruleReplacingConfig{ + delimiter: []rune(`)`), + tokenType: Punctuation, + stateName: `root`, + pushState: true, + }), }, Default(Pop(1)), }, @@ -1141,23 +1248,45 @@ func rakuRules() Rules { {`.+?`, String, nil}, }, "closure": { - {`(?<!(?<!\\)\\)\{.+?\}`, UsingSelf("root"), nil}, + {`(?<!(?<!\\)\\){`, Punctuation, replaceRule( + ruleReplacingConfig{ + delimiter: []rune(`}`), + tokenType: Punctuation, + stateName: `root`, + pushState: true, + }), + }, }, "token": { // Token signature - {`(\()(.+?)(\))`, ByGroups(Punctuation, UsingSelf("root"), Punctuation), nil}, - {`\{`, Punctuation, Mutators(Pop(1), bracketsFinder(rakuRegexInsideToken))}, - {`.+?`, Text, nil}, + {`\(`, Punctuation, replaceRule( + ruleReplacingConfig{ + delimiter: []rune(`)`), + tokenType: Punctuation, + stateName: `root`, + pushState: true, + }), + }, + {`{`, Punctuation, replaceRule( + ruleReplacingConfig{ + delimiter: []rune(`}`), + tokenType: Punctuation, + stateName: `regex`, + popState: true, + pushState: true, + }), + }, + {`\s*`, Text, nil}, + Default(Pop(1)), }, } } -// Joins keys and values of rune map +// Joins keys of rune map func joinRuneMap(m map[rune]rune) string { - runes := make([]rune, 0, len(m)*2) - for k, v := range m { + runes := make([]rune, 0, len(m)) + for k := range m { runes = append(runes, k) - runes = append(runes, v) } return string(runes) @@ -1165,11 +1294,24 @@ func joinRuneMap(m map[rune]rune) string { // Finds the index of substring in the string starting at position n func indexAt(str []rune, substr []rune, pos int) int { - text := string(str[pos:]) + strFromPos := str[pos:] + text := string(strFromPos) idx := strings.Index(text, string(substr)) if idx > -1 { idx = utf8.RuneCountInString(text[:idx]) + + // Search again if the substr is escaped with backslash + if (idx > 1 && strFromPos[idx-1] == '\\' && strFromPos[idx-2] != '\\') || + (idx == 1 && strFromPos[idx-1] == '\\') { + idx = indexAt(str[pos:], substr, idx+1) + + idx = utf8.RuneCountInString(text[:idx]) + + if idx < 0 { + return idx + } + } idx += pos } @@ -1186,107 +1328,190 @@ func contains(s []string, e string) bool { return false } -type RakuFormatterRules struct { - pop, formatter *CompiledRule +type rulePosition int + +const ( + topRule rulePosition = 0 + bottomRule = -1 +) + +type ruleMakingConfig struct { + delimiter []rune + pattern string + tokenType Emitter + mutator Mutator + numberOfDelimiterChars int } -// Pop from the pod_formatter_stack and reformat the pod code -func podFormatterPopper(state *LexerState) error { - stack, ok := state.Get("pod_formatter_stack").([]RakuFormatterRules) +type ruleReplacingConfig struct { + delimiter []rune + pattern string + tokenType Emitter + numberOfDelimiterChars int + mutator Mutator + appendMutator Mutator + rulePosition rulePosition + stateName string + pop bool + popState bool + pushState bool +} - if ok && len(stack) > 0 { - // Pop from stack - stack = stack[:len(stack)-1] - state.Set("pod_formatter_stack", stack) - // Call podFormatter to use the last formatter rules - err := podFormatter(state) - if err != nil { - panic(err) +// Pops rule from state-stack and replaces the rule with the previous rule +func popRule(rule ruleReplacingConfig) MutatorFunc { + return func(state *LexerState) error { + stackName := genStackName(rule.stateName, rule.rulePosition) + + stack, ok := state.Get(stackName).([]ruleReplacingConfig) + + if ok && len(stack) > 0 { + // Pop from stack + stack = stack[:len(stack)-1] + lastRule := stack[len(stack)-1] + lastRule.pushState = false + lastRule.popState = false + lastRule.pop = true + state.Set(stackName, stack) + + // Call replaceRule to use the last rule + err := replaceRule(lastRule)(state) + if err != nil { + panic(err) + } } - } - return nil + return nil + } } -// Use the rules from pod_formatter_stack to format the pod code -func podFormatter(state *LexerState) error { - stack, ok := state.Get("pod_formatter_stack").([]RakuFormatterRules) - if ok && len(stack) > 0 { - rules := stack[len(stack)-1] - state.Rules["pod-formatter"][0] = rules.pop - state.Rules["pod-formatter"][len(state.Rules["pod-formatter"])-1] = rules.formatter - } +// Replaces a state's rule based on the rule config and position +func replaceRule(rule ruleReplacingConfig) MutatorFunc { + return func(state *LexerState) error { + stateName := rule.stateName + stackName := genStackName(rule.stateName, rule.rulePosition) - return nil -} + stack, ok := state.Get(stackName).([]ruleReplacingConfig) + if !ok { + stack = []ruleReplacingConfig{} + } + + // If state-stack is empty fill it with the placeholder rule + if len(stack) == 0 { + stack = []ruleReplacingConfig{ + { + // Placeholder, will be overwritten by mutators, DO NOT REMOVE! + pattern: `\A\z`, + tokenType: nil, + mutator: nil, + stateName: stateName, + rulePosition: rule.rulePosition, + }, + } + state.Set(stackName, stack) + } -type RulePosition int + var mutator Mutator + mutators := []Mutator{} + + switch { + case rule.rulePosition == topRule && rule.mutator == nil: + // Default mutator for top rule + mutators = []Mutator{Pop(1), popRule(rule)} + case rule.rulePosition == topRule && rule.mutator != nil: + // Default mutator for top rule, when rule.mutator is set + mutators = []Mutator{rule.mutator, popRule(rule)} + case rule.mutator != nil: + mutators = []Mutator{rule.mutator} + } -const ( - topRule RulePosition = iota + 1000 - bottomRule -) + if rule.appendMutator != nil { + mutators = append(mutators, rule.appendMutator) + } -type RuleMakingConfig struct { - delimiter []rune - pattern string - tokenType TokenType - mutator Mutator - rulePosition RulePosition - state *LexerState - stateName string - pushToStack bool - numberOfDelimiterChars int + if len(mutators) > 0 { + mutator = Mutators(mutators...) + } else { + mutator = nil + } + + ruleConfig := ruleMakingConfig{ + pattern: rule.pattern, + delimiter: rule.delimiter, + numberOfDelimiterChars: rule.numberOfDelimiterChars, + tokenType: rule.tokenType, + mutator: mutator, + } + + cRule := makeRule(ruleConfig) + + switch rule.rulePosition { + case topRule: + state.Rules[stateName][0] = cRule + case bottomRule: + state.Rules[stateName][len(state.Rules[stateName])-1] = cRule + } + + // Pop state name from stack if asked. State should be popped first before Pushing + if rule.popState { + err := Pop(1)(state) + if err != nil { + panic(err) + } + } + + // Push state name to stack if asked + if rule.pushState { + err := Push(stateName)(state) + if err != nil { + panic(err) + } + } + + if !rule.pop { + state.Set(stackName, append(stack, rule)) + } + + return nil + } } -// Makes compiled rules and returns them, If rule position is given, rules are added to the state -// If pushToStack is true, state name will be added to the state stack -func makeRuleAndPushMaybe(config RuleMakingConfig) *CompiledRule { +// Generates rule replacing stack using state name and rule position +func genStackName(stateName string, rulePosition rulePosition) (stackName string) { + switch rulePosition { + case topRule: + stackName = stateName + `-top-stack` + case bottomRule: + stackName = stateName + `-bottom-stack` + } + return +} + +// Makes a compiled rule and returns it +func makeRule(config ruleMakingConfig) *CompiledRule { var rePattern string + if len(config.delimiter) > 0 { - delimiter := strings.Repeat(string(config.delimiter), config.numberOfDelimiterChars) - rePattern = regexp2.Escape(delimiter) + delimiter := string(config.delimiter) + + if config.numberOfDelimiterChars > 1 { + delimiter = strings.Repeat(delimiter, config.numberOfDelimiterChars) + } + + rePattern = `(?<!(?<!\\)\\)` + regexp2.Escape(delimiter) } else { rePattern = config.pattern } + regex := regexp2.MustCompile(rePattern, regexp2.None) cRule := &CompiledRule{ Rule: Rule{rePattern, config.tokenType, config.mutator}, Regexp: regex, } - state := config.state - stateName := config.stateName - switch config.rulePosition { - case topRule: - state.Rules[stateName] = - append([]*CompiledRule{cRule}, state.Rules[stateName][1:]...) - case bottomRule: - state.Rules[stateName] = - append(state.Rules[stateName][:len(state.Rules[stateName])-1], cRule) - } - - // Push state name to stack if asked - if config.pushToStack { - state.Stack = append(state.Stack, config.stateName) - } return cRule } -// Used when the regex knows its own delimiter and uses `UsingSelf("regex")`, -// it only puts a placeholder rule at the top of "regex" state -func makeRegexPoppingRule(state *LexerState) error { - makeRuleAndPushMaybe(RuleMakingConfig{ - pattern: `^$`, - rulePosition: topRule, - state: state, - stateName: "regex", - }) - - return nil -} - // Emitter for colon pairs, changes token state based on key and brackets func colonPair(tokenClass TokenType) Emitter { return EmitterFunc(func(groups []string, state *LexerState) Iterator { diff --git a/vendor/github.com/alecthomas/chroma/lexers/r/rust.go b/vendor/github.com/alecthomas/chroma/lexers/r/rust.go index 25d42e594a..5399c9d7b2 100644 --- a/vendor/github.com/alecthomas/chroma/lexers/r/rust.go +++ b/vendor/github.com/alecthomas/chroma/lexers/r/rust.go @@ -9,9 +9,9 @@ import ( var Rust = internal.Register(MustNewLazyLexer( &Config{ Name: "Rust", - Aliases: []string{"rust"}, + Aliases: []string{"rust", "rs"}, Filenames: []string{"*.rs", "*.rs.in"}, - MimeTypes: []string{"text/rust"}, + MimeTypes: []string{"text/rust", "text/x-rust"}, EnsureNL: true, }, rustRules, @@ -35,20 +35,22 @@ func rustRules() Rules { {`r#*"(?:\\.|[^\\;])*"#*`, LiteralString, nil}, {`"(?:\\.|[^\\"])*"`, LiteralString, nil}, {`\$([a-zA-Z_]\w*|\(,?|\),?|,?)`, CommentPreproc, nil}, - {Words(``, `\b`, `as`, `async`, `await`, `const`, `crate`, `else`, `extern`, `for`, `if`, `impl`, `in`, `loop`, `match`, `move`, `mut`, `pub`, `ref`, `return`, `static`, `super`, `trait`, `unsafe`, `use`, `where`, `while`), Keyword, nil}, - {Words(``, `\b`, `abstract`, `become`, `box`, `do`, `final`, `macro`, `override`, `priv`, `try`, `typeof`, `unsized`, `virtual`, `yield`), KeywordReserved, nil}, + {Words(``, `\b`, `as`, `async`, `await`, `box`, `const`, `crate`, `dyn`, `else`, `extern`, `for`, `if`, `impl`, `in`, `loop`, `match`, `move`, `mut`, `pub`, `ref`, `return`, `static`, `super`, `trait`, `unsafe`, `use`, `where`, `while`), Keyword, nil}, + {Words(``, `\b`, `abstract`, `become`, `do`, `final`, `macro`, `override`, `priv`, `typeof`, `try`, `unsized`, `virtual`, `yield`), KeywordReserved, nil}, {`(true|false)\b`, KeywordConstant, nil}, + {`self\b`, NameBuiltinPseudo, nil}, {`mod\b`, Keyword, Push("modname")}, {`let\b`, KeywordDeclaration, nil}, {`fn\b`, Keyword, Push("funcname")}, {`(struct|enum|type|union)\b`, Keyword, Push("typename")}, {`(default)(\s+)(type|fn)\b`, ByGroups(Keyword, Text, Keyword), nil}, - {Words(``, `\b`, `u8`, `u16`, `u32`, `u64`, `u128`, `i8`, `i16`, `i32`, `i64`, `i128`, `usize`, `isize`, `f32`, `f64`, `str`, `bool`), KeywordType, nil}, - {`self\b`, NameBuiltinPseudo, nil}, - {Words(``, `\b`, `Copy`, `Send`, `Sized`, `Sync`, `Drop`, `Fn`, `FnMut`, `FnOnce`, `Box`, `ToOwned`, `Clone`, `PartialEq`, `PartialOrd`, `Eq`, `Ord`, `AsRef`, `AsMut`, `Into`, `From`, `Default`, `Iterator`, `Extend`, `IntoIterator`, `DoubleEndedIterator`, `ExactSizeIterator`, `Option`, `Some`, `None`, `Result`, `Ok`, `Err`, `SliceConcatExt`, `String`, `ToString`, `Vec`), NameBuiltin, nil}, + {Words(``, `\b`, `u8`, `u16`, `u32`, `u64`, `u128`, `i8`, `i16`, `i32`, `i64`, `i128`, `usize`, `isize`, `f32`, `f64`, `char`, `str`, `bool`), KeywordType, nil}, + {`[sS]elf\b`, NameBuiltinPseudo, nil}, + {Words(``, `\b`, `Copy`, `Send`, `Sized`, `Sync`, `Unpin`, `Drop`, `Fn`, `FnMut`, `FnOnce`, `drop`, `Box`, `ToOwned`, `Clone`, `PartialEq`, `PartialOrd`, `Eq`, `Ord`, `AsRef`, `AsMut`, `Into`, `From`, `Default`, `Iterator`, `Extend`, `IntoIterator`, `DoubleEndedIterator`, `ExactSizeIterator`, `Option`, `Some`, `None`, `Result`, `Ok`, `Err`, `String`, `ToString`, `Vec`), NameBuiltin, nil}, + {Words(``, `!`, `asm`, `assert`, `assert_eq`, `assert_ne`, `cfg`, `column`, `compile_error`, `concat`, `concat_idents`, `dbg`, `debug_assert`, `debug_assert_eq`, `debug_assert_ne`, `env`, `eprint`, `eprintln`, `file`, `format`, `format_args`, `format_args_nl`, `global_asm`, `include`, `include_bytes`, `include_str`, `is_aarch64_feature_detected`, `is_arm_feature_detected`, `is_mips64_feature_detected`, `is_mips_feature_detected`, `is_powerpc64_feature_detected`, `is_powerpc_feature_detected`, `is_x86_feature_detected`, `line`, `llvm_asm`, `log_syntax`, `macro_rules`, `matches`, `module_path`, `option_env`, `panic`, `print`, `println`, `stringify`, `thread_local`, `todo`, `trace_macros`, `unimplemented`, `unreachable`, `vec`, `write`, `writeln`), NameFunctionMagic, nil}, {`::\b`, Text, nil}, {`(?::|->)`, Text, Push("typename")}, - {`(break|continue)(\s*)(\'[A-Za-z_]\w*)?`, ByGroups(Keyword, TextWhitespace, NameLabel), nil}, + {`(break|continue)(\b\s*)(\'[A-Za-z_]\w*)?`, ByGroups(Keyword, TextWhitespace, NameLabel), nil}, {`'(\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0|\\u\{[0-9a-fA-F]{1,6}\}|.)'`, LiteralStringChar, nil}, {`b'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\0|\\u\{[0-9a-fA-F]{1,6}\}|.)'`, LiteralStringChar, nil}, {`0b[01_]+`, LiteralNumberBin, Push("number_lit")}, @@ -57,15 +59,15 @@ func rustRules() Rules { {`[0-9][0-9_]*(\.[0-9_]+[eE][+\-]?[0-9_]+|\.[0-9_]*(?!\.)|[eE][+\-]?[0-9_]+)`, LiteralNumberFloat, Push("number_lit")}, {`[0-9][0-9_]*`, LiteralNumberInteger, Push("number_lit")}, {`b"`, LiteralString, Push("bytestring")}, - {`b?r(#*)".*?"\1`, LiteralString, nil}, - {`'static`, NameBuiltin, nil}, - {`'[a-zA-Z_]\w*`, NameAttribute, nil}, + {`(?s)b?r(#*)".*?"\1`, LiteralString, nil}, + {`'`, Operator, Push("lifetime")}, + {`\.\.=?`, Operator, nil}, {`[{}()\[\],.;]`, Punctuation, nil}, {`[+\-*/%&|<>^!~@=:?]`, Operator, nil}, {`(r#)?[a-zA-Z_]\w*`, Name, nil}, + {`r#[a-zA-Z_]\w*`, Name, nil}, {`#!?\[`, CommentPreproc, Push("attribute[")}, - {`([A-Za-z_]\w*)(!)(\s*)([A-Za-z_]\w*)?(\s*)(\{)`, ByGroups(CommentPreproc, Punctuation, TextWhitespace, Name, TextWhitespace, Punctuation), Push("macro{")}, - {`([A-Za-z_]\w*)(!)(\s*)([A-Za-z_]\w*)?(\()`, ByGroups(CommentPreproc, Punctuation, TextWhitespace, Name, Punctuation), Push("macro(")}, + {`#`, Text, nil}, }, "comment": { {`[^*/]+`, CommentMultiline, nil}, @@ -92,11 +94,17 @@ func rustRules() Rules { "typename": { {`\s+`, Text, nil}, {`&`, KeywordPseudo, nil}, - {Words(``, `\b`, `Copy`, `Send`, `Sized`, `Sync`, `Drop`, `Fn`, `FnMut`, `FnOnce`, `Box`, `ToOwned`, `Clone`, `PartialEq`, `PartialOrd`, `Eq`, `Ord`, `AsRef`, `AsMut`, `Into`, `From`, `Default`, `Iterator`, `Extend`, `IntoIterator`, `DoubleEndedIterator`, `ExactSizeIterator`, `Option`, `Some`, `None`, `Result`, `Ok`, `Err`, `SliceConcatExt`, `String`, `ToString`, `Vec`), NameBuiltin, nil}, - {Words(``, `\b`, `u8`, `u16`, `u32`, `u64`, `i8`, `i16`, `i32`, `i64`, `usize`, `isize`, `f32`, `f64`, `str`, `bool`), KeywordType, nil}, + {`'`, Operator, Push("lifetime")}, + {Words(``, `\b`, `Copy`, `Send`, `Sized`, `Sync`, `Unpin`, `Drop`, `Fn`, `FnMut`, `FnOnce`, `drop`, `Box`, `ToOwned`, `Clone`, `PartialEq`, `PartialOrd`, `Eq`, `Ord`, `AsRef`, `AsMut`, `Into`, `From`, `Default`, `Iterator`, `Extend`, `IntoIterator`, `DoubleEndedIterator`, `ExactSizeIterator`, `Option`, `Some`, `None`, `Result`, `Ok`, `Err`, `String`, `ToString`, `Vec`), NameBuiltin, nil}, + {Words(``, `\b`, `u8`, `u16`, `u32`, `u64`, `u128`, `i8`, `i16`, `i32`, `i64`, `i128`, `usize`, `isize`, `f32`, `f64`, `char`, `str`, `bool`), KeywordType, nil}, {`[a-zA-Z_]\w*`, NameClass, Pop(1)}, Default(Pop(1)), }, + "lifetime": { + {`(static|_)`, NameBuiltin, nil}, + {`[a-zA-Z_]+\w*`, NameAttribute, nil}, + Default(Pop(1)), + }, "number_lit": { {`[ui](8|16|32|64|size)`, Keyword, Pop(1)}, {`f(32|64)`, Keyword, Pop(1)}, @@ -112,28 +120,14 @@ func rustRules() Rules { {`\\x[89a-fA-F][0-9a-fA-F]`, LiteralStringEscape, nil}, Include("string"), }, - "macro{": { - {`\{`, Operator, Push()}, - {`\}`, Operator, Pop(1)}, - }, - "macro(": { - {`\(`, Operator, Push()}, - {`\)`, Operator, Pop(1)}, - }, "attribute_common": { {`"`, LiteralString, Push("string")}, {`\[`, CommentPreproc, Push("attribute[")}, - {`\(`, CommentPreproc, Push("attribute(")}, }, "attribute[": { Include("attribute_common"), - {`\];?`, CommentPreproc, Pop(1)}, - {`[^"\]]+`, CommentPreproc, nil}, - }, - "attribute(": { - Include("attribute_common"), - {`\);?`, CommentPreproc, Pop(1)}, - {`[^")]+`, CommentPreproc, nil}, + {`\]`, CommentPreproc, Pop(1)}, + {`[^"\]\[]+`, CommentPreproc, nil}, }, } } |