1 package f
2
3 import (
4 . "github.com/alecthomas/chroma"
5 "github.com/alecthomas/chroma/lexers/internal"
6 )
7
8
9 var Fish = internal.Register(MustNewLazyLexer(
10 &Config{
11 Name: "Fish",
12 Aliases: []string{"fish", "fishshell"},
13 Filenames: []string{"*.fish", "*.load"},
14 MimeTypes: []string{"application/x-fish"},
15 },
16 fishRules,
17 ))
18
19 func fishRules() Rules {
20 keywords := []string{
21 `begin`, `end`, `if`, `else`, `while`, `break`, `for`, `return`, `function`, `block`,
22 `case`, `continue`, `switch`, `not`, `and`, `or`, `set`, `echo`, `exit`, `pwd`, `true`,
23 `false`, `cd`, `cdh`, `count`, `test`,
24 }
25 keywordsPattern := Words(`\b`, `\b`, keywords...)
26
27 builtins := []string{
28 `alias`, `bg`, `bind`, `breakpoint`, `builtin`, `argparse`, `abbr`, `string`, `command`,
29 `commandline`, `complete`, `contains`, `dirh`, `dirs`, `disown`, `emit`, `eval`, `exec`,
30 `fg`, `fish`, `fish_add_path`, `fish_breakpoint_prompt`, `fish_command_not_found`,
31 `fish_config`, `fish_git_prompt`, `fish_greeting`, `fish_hg_prompt`, `fish_indent`,
32 `fish_is_root_user`, `fish_key_reader`, `fish_mode_prompt`, `fish_opt`, `fish_pager`,
33 `fish_prompt`, `fish_right_prompt`, `fish_status_to_signal`, `fish_svn_prompt`,
34 `fish_title`, `fish_update_completions`, `fish_vcs_prompt`, `fishd`, `funced`,
35 `funcsave`, `functions`, `help`, `history`, `isatty`, `jobs`, `math`, `mimedb`, `nextd`,
36 `open`, `prompt_pwd`, `realpath`, `popd`, `prevd`, `psub`, `pushd`, `random`, `read`,
37 `set_color`, `source`, `status`, `suspend`, `trap`, `type`, `ulimit`, `umask`, `vared`,
38 `fc`, `getopts`, `hash`, `kill`, `printf`, `time`, `wait`,
39 }
40
41 return Rules{
42 "root": {
43 Include("basic"),
44 Include("interp"),
45 Include("data"),
46 },
47 "interp": {
48 {`\$\(\(`, Keyword, Push("math")},
49 {`\(`, Keyword, Push("paren")},
50 {`\$#?(\w+|.)`, NameVariable, nil},
51 },
52 "basic": {
53 {Words(`(?<=(?:^|\A|;|&&|\|\||\||`+keywordsPattern+`)\s*)`, `(?=;?\b)`, keywords...), Keyword, nil},
54 {`(?<=for\s+\S+\s+)in\b`, Keyword, nil},
55 {Words(`\b`, `\s*\b(?!\.)`, builtins...), NameBuiltin, nil},
56 {`#!.*\n`, CommentHashbang, nil},
57 {`#.*\n`, Comment, nil},
58 {`\\[\w\W]`, LiteralStringEscape, nil},
59 {`(\b\w+)(\s*)(=)`, ByGroups(NameVariable, Text, Operator), nil},
60 {`[\[\]()={}]`, Operator, nil},
61 {`(?<=\[[^\]]+)\.\.|-(?=[^\[]+\])`, Operator, nil},
62 {`<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2`, LiteralString, nil},
63 {`(?<=set\s+(?:--?[^\d\W][\w-]*\s+)?)\w+`, NameVariable, nil},
64 {`(?<=for\s+)\w[\w-]*(?=\s+in)`, NameVariable, nil},
65 {`(?<=function\s+)\w(?:[^\n])*?(?= *[-\n])`, NameFunction, nil},
66 {`(?<=(?:^|\b(?:and|or|sudo)\b|;|\|\||&&|\||\(|(?:\b\w+\s*=\S+\s)) *)\w[\w-]*`, NameFunction, nil},
67 },
68 "data": {
69 {`(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\$])*"`, LiteralStringDouble, nil},
70 {`"`, LiteralStringDouble, Push("string")},
71 {`(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'`, LiteralStringSingle, nil},
72 {`(?s)'.*?'`, LiteralStringSingle, nil},
73 {`;`, Punctuation, nil},
74 {`&&|\|\||&|\||\^|<|>`, Operator, nil},
75 {`\s+`, Text, nil},
76 {`\b\d+\b`, LiteralNumber, nil},
77 {`(?<=\s+)--?[^\d][\w-]*`, NameAttribute, nil},
78 {".+?", Text, nil},
79 },
80 "string": {
81 {`"`, LiteralStringDouble, Pop(1)},
82 {`(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+`, LiteralStringDouble, nil},
83 Include("interp"),
84 },
85 "paren": {
86 {`\)`, Keyword, Pop(1)},
87 Include("root"),
88 },
89 "math": {
90 {`\)\)`, Keyword, Pop(1)},
91 {`[-+*/%^|&]|\*\*|\|\|`, Operator, nil},
92 {`\d+#\d+`, LiteralNumber, nil},
93 {`\d+#(?! )`, LiteralNumber, nil},
94 {`\d+`, LiteralNumber, nil},
95 Include("root"),
96 },
97 }
98 }
99
View as plain text