|
6 | 6 | [(integer) (float)] @number |
7 | 7 |
|
8 | 8 | [ |
| 9 | + "not" |
| 10 | + "!" |
| 11 | + "and" |
| 12 | + "or" |
9 | 13 | "&&" |
10 | 14 | "||" |
11 | 15 | "|" |
12 | 16 | "&" |
13 | | - ".." |
14 | 17 | (direction) |
15 | 18 | (stream_redirect) |
16 | 19 | ] @operator |
|
25 | 28 | name: (word) @punctuation.bracket (#match? @punctuation.bracket "^\\[$") |
26 | 29 | argument: (word) @operator (#match? @operator "^(!?=|-[a-zA-Z]+)$")) |
27 | 30 |
|
28 | | -(variable_expansion) @constant |
| 31 | +[(variable_expansion) (list_element_access)] @constant |
29 | 32 |
|
30 | | -[ |
31 | | - "[" |
32 | | - "]" |
33 | | - "{" |
34 | | - "}" |
35 | | - "(" |
36 | | - ")" |
37 | | -] @punctuation.bracket |
| 33 | +(command_substitution ["$" "(" ")"]) @punctuation.bracket |
| 34 | + |
| 35 | +; Brace expansion and globbing. |
| 36 | +; Note: (glob) matches "*" but not "?". It's in the grammar and we can't |
| 37 | +; query it differently. |
| 38 | +["{" "}" "," (home_dir_expansion) (glob)] @operator |
38 | 39 |
|
39 | | -"," @punctuation.delimiter |
| 40 | +; Conditionals |
| 41 | +(if_statement ["if" "end"] @keyword) |
| 42 | +(switch_statement ["switch" "end"] @keyword) |
| 43 | +(case_clause ["case"] @keyword) |
| 44 | +(else_clause ["else"] @keyword) |
| 45 | +(else_if_clause ["else" "if"] @keyword) |
40 | 46 |
|
41 | | -(function_definition name: [(word) (concatenation)] @function) |
42 | | -(command name: (word) @function) |
| 47 | +; Loops/Blocks |
| 48 | +(while_statement ["while" "end"] @keyword) |
| 49 | +(for_statement ["for" "end"] @keyword) |
| 50 | +(begin_statement ["begin" "end"] @keyword) |
43 | 51 |
|
| 52 | +; Functions |
| 53 | +(function_definition ["function" "end"] @keyword) |
| 54 | + |
| 55 | +; Keywords |
44 | 56 | [ |
45 | | - "switch" |
46 | | - "case" |
47 | 57 | "in" |
48 | | - "begin" |
49 | | - "function" |
50 | | - "if" |
51 | | - "else" |
52 | | - "end" |
53 | | - "while" |
54 | | - "for" |
55 | | - "not" |
56 | | - "!" |
57 | | - "and" |
58 | | - "or" |
| 58 | + ";" |
59 | 59 | "return" |
60 | 60 | (break) |
61 | 61 | (continue) |
62 | 62 | ] @keyword |
| 63 | + |
| 64 | +; Treat "&" as a background operator only if it's preceded by a command. |
| 65 | +; Note that an expression like `echo _&_` contains a background operator |
| 66 | +; prior to fish 3.5 and that's how it's handled here. |
| 67 | +((command) "&" @keyword) |
| 68 | + |
| 69 | + |
| 70 | +;; Work around two issues in the compiled grammar. |
| 71 | + |
| 72 | +; (1) |
| 73 | +; Issue: the leading file descriptor in a redirection is missing. |
| 74 | +; Expample: redirect stderr with 2> and the "2" won't get matched. |
| 75 | +; Workaround: within a command, locate the last integer node preceding the |
| 76 | +; redirect and mark that as @operator. |
| 77 | +(command |
| 78 | + name: (concatenation _+ (integer) @operator .) |
| 79 | + redirect: _) |
| 80 | + |
| 81 | +; (2) |
| 82 | +; Issue: commands are not split into the fields (name) (arguments) (comment). |
| 83 | +; |
| 84 | +; The whole expression is wrapped in the field (name) which in turn consists |
| 85 | +; either of one (word) or a (concatenation). |
| 86 | +; |
| 87 | +; The grammar doesn't mark trailing comments and we have to look for "#" and |
| 88 | +; assign all following nodes ourselves. Parentheses within trailing commands |
| 89 | +; are problematic as they start a command substitution and can't be matched |
| 90 | +; by the wildcard node. Sigh. |
| 91 | +; |
| 92 | +; Workaround: use four rules to do the splitting: |
| 93 | +; 1. capture commands with no arguments (word) |
| 94 | +; 2. capture commands with arguments (concatenation) |
| 95 | +; 3. capture command options (arguments starting with "-") |
| 96 | +; 4. capture trailing comments (can't catch everything) |
| 97 | + |
| 98 | +(command name: [ |
| 99 | + ((word) @function) |
| 100 | + (concatenation . (word) @function) |
| 101 | + (concatenation (word) @constant (#match? @constant "^-")) |
| 102 | + (concatenation ("#" @comment _* @comment)) |
| 103 | +]) |
| 104 | + |
| 105 | +(function_definition name: [ |
| 106 | + ((word) @function) |
| 107 | + (concatenation . (word) @function) |
| 108 | + (concatenation (word) @constant (#match? @constant "^-")) |
| 109 | + (concatenation ("#" @comment _* @comment)) |
| 110 | +]) |
| 111 | + |
| 112 | + |
| 113 | +;; Error |
| 114 | +(ERROR) @hint |
0 commit comments