@lvce-editor/shared-process 0.4.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/config/builtinCommands.json +15 -2
  2. package/config/defaultKeyBindings.json +33 -0
  3. package/config/defaultSettings.json +7 -3
  4. package/extensions/builtin.language-basics-docker/extension.json +1 -1
  5. package/extensions/builtin.language-basics-docker/src/tokenizeDockerfile.js +29 -11
  6. package/extensions/builtin.language-basics-editorconfig/src/tokenizeEditorConfig.js +62 -11
  7. package/extensions/builtin.language-basics-gitattributes/src/tokenizeGitAttributes.js +32 -5
  8. package/extensions/builtin.language-basics-html/src/tokenizeHtml.js +7 -2
  9. package/extensions/builtin.language-basics-javascript/extension.json +1 -1
  10. package/extensions/builtin.language-basics-javascript/src/tokenizeJavaScript.js +11 -7
  11. package/extensions/builtin.language-basics-json/extension.json +3 -2
  12. package/extensions/builtin.language-basics-json/src/tokenizeJson.js +11 -24
  13. package/extensions/builtin.language-basics-nvmrc/README.md +14 -0
  14. package/extensions/builtin.language-basics-nvmrc/extension.json +12 -0
  15. package/extensions/builtin.language-basics-nvmrc/src/tokenizeNvmrc.js +30 -0
  16. package/extensions/builtin.language-basics-plaintext/src/tokenizePlaintext.js +4 -7
  17. package/extensions/builtin.language-basics-rust/README.md +14 -0
  18. package/extensions/builtin.language-basics-rust/extension.json +12 -0
  19. package/extensions/builtin.language-basics-rust/src/tokenizeRust.js +158 -0
  20. package/extensions/builtin.language-basics-shellscript/src/tokenizeShellScript.js +37 -7
  21. package/extensions/builtin.language-basics-toml/extension.json +1 -1
  22. package/extensions/builtin.language-basics-toml/src/tokenizeToml.js +93 -8
  23. package/extensions/builtin.language-basics-yaml/src/tokenizeYaml.js +138 -10
  24. package/extensions/builtin.vscode-icons/icon-theme.json +14 -0
  25. package/extensions/builtin.vscode-icons/icons/file_type_master-co.svg +1 -0
  26. package/extensions/builtin.vscode-icons/icons/file_type_wgsl.svg +86 -0
  27. package/package.json +8 -7
  28. package/src/parts/Cli/Cli.js +24 -0
  29. package/src/parts/CliInstall/CliInstall.js +10 -0
  30. package/src/parts/CliLink/CliLink.js +6 -0
  31. package/src/parts/CliList/CliList.js +15 -0
  32. package/src/parts/Download/Download.js +5 -13
  33. package/src/parts/DownloadAndExtract/DownloadAndExtract.js +14 -0
  34. package/src/parts/Error/FileSystemError.js +10 -0
  35. package/src/parts/ExtensionInstall/ExtensionInstall.ipc.js +6 -0
  36. package/src/parts/ExtensionInstall/ExtensionInstall.js +25 -0
  37. package/src/parts/ExtensionInstallFromGitHub/ExtensionInstallFromGitHub.js +34 -0
  38. package/src/parts/ExtensionInstallFromUrl/ExtensionInstallFromUrl.js +32 -0
  39. package/src/parts/ExtensionInstallParseInput/ExtensionInstallParseInput.js +84 -0
  40. package/src/parts/ExtensionLink/ExtensionLink.js +32 -0
  41. package/src/parts/ExtensionList/ExtensionList.js +66 -0
  42. package/src/parts/ExtensionManagement/ExtensionManagement.js +4 -3
  43. package/src/parts/ExtensionUninstall/ExtensionUninstall.js +0 -0
  44. package/src/parts/Extract/Extract.js +34 -0
  45. package/src/parts/FileSystem/FileSystem.js +21 -2
  46. package/src/parts/FileSystemErrorCodes/FileSystemErrorCodes.js +4 -0
  47. package/src/parts/Path/Path.js +4 -0
  48. package/src/parts/Preferences/Preferences.js +17 -1
  49. package/src/parts/SymLink/SymLink.js +15 -0
  50. package/src/parts/TmpFile/TmpFile.js +15 -0
  51. package/src/sharedProcessMain.js +16 -5
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "builtin.language-basics-rust",
3
+ "name": "Language Basics Rust",
4
+ "description": "Provides syntax highlighting and bracket matching in Rust files.",
5
+ "languages": [
6
+ {
7
+ "id": "rust",
8
+ "extensions": [".rs"],
9
+ "tokenize": "src/tokenizeRust.js"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,158 @@
1
+ /**
2
+ * @enum number
3
+ */
4
+ export const State = {
5
+ TopLevelContent: 1,
6
+ InsideString: 2,
7
+ InsideLineComment: 3,
8
+ }
9
+
10
+ export const StateMap = {
11
+ [State.TopLevelContent]: 'TopLevelContent',
12
+ }
13
+
14
+ /**
15
+ * @enum number
16
+ */
17
+ export const TokenType = {
18
+ None: 1,
19
+ Whitespace: 2,
20
+ PunctuationString: 3,
21
+ String: 4,
22
+ Keyword: 5,
23
+ Numeric: 6,
24
+ Punctuation: 7,
25
+ VariableName: 8,
26
+ Comment: 885,
27
+ Text: 9,
28
+ LanguageConstant: 10,
29
+ }
30
+
31
+ export const TokenMap = {
32
+ [TokenType.None]: 'None',
33
+ [TokenType.Whitespace]: 'Whitespace',
34
+ [TokenType.PunctuationString]: 'PunctuationString',
35
+ [TokenType.String]: 'String',
36
+ [TokenType.Keyword]: 'Keyword',
37
+ [TokenType.Numeric]: 'Numeric',
38
+ [TokenType.Punctuation]: 'Punctuation',
39
+ [TokenType.VariableName]: 'VariableName',
40
+ [TokenType.Comment]: 'Comment',
41
+ [TokenType.Text]: 'Text',
42
+
43
+ [TokenType.LanguageConstant]: 'LanguageConstant',
44
+ }
45
+
46
+ const RE_LINE_COMMENT_START = /^\/\//
47
+ const RE_SELECTOR = /^[\.a-zA-Z\d\-\:>]+/
48
+ const RE_WHITESPACE = /^ +/
49
+ const RE_CURLY_OPEN = /^\{/
50
+ const RE_CURLY_CLOSE = /^\}/
51
+ const RE_PROPERTY_NAME = /^[a-zA-Z\-]+\b/
52
+ const RE_COLON = /^:/
53
+ const RE_PROPERTY_VALUE = /^[^;\}]+/
54
+ const RE_SEMICOLON = /^;/
55
+ const RE_COMMA = /^,/
56
+ const RE_ANYTHING = /^.*/s
57
+ const RE_ANYTHING_UNTIL_CLOSE_BRACE = /^[^\}]+/
58
+ const RE_QUOTE_DOUBLE = /^"/
59
+ const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
60
+ const RE_KEYWORD =
61
+ /^(?:as|break|const|continue|crate|else|enum|extern|false|fn|for|if|impl|in|let|loop|match|mod|move|mut|pub|ref|return|self|static|struct|super|trait|true|type|unsafe|where|while)\b/
62
+
63
+ const RE_VARIABLE_NAME = /^[a-zA-Z\_]+/
64
+ const RE_PUNCTUATION = /^[:,;\{\}\[\]\.=\(\)<>]/
65
+ const RE_NUMERIC = /^\d+/
66
+
67
+ export const initialLineState = {
68
+ state: State.TopLevelContent,
69
+ tokens: [],
70
+ }
71
+
72
+ export const hasArrayReturn = true
73
+
74
+ /**
75
+ * @param {string} line
76
+ * @param {any} lineState
77
+ */
78
+ export const tokenizeLine = (line, lineState) => {
79
+ let next = null
80
+ let index = 0
81
+ let tokens = []
82
+ let token = TokenType.None
83
+ let state = lineState.state
84
+ while (index < line.length) {
85
+ const part = line.slice(index)
86
+ switch (state) {
87
+ case State.TopLevelContent:
88
+ if ((next = part.match(RE_WHITESPACE))) {
89
+ token = TokenType.Whitespace
90
+ state = State.TopLevelContent
91
+ } else if ((next = part.match(RE_KEYWORD))) {
92
+ switch (next[0]) {
93
+ case 'true':
94
+ case 'false':
95
+ token = TokenType.LanguageConstant
96
+ break
97
+ default:
98
+ token = TokenType.Keyword
99
+ break
100
+ }
101
+ state = State.TopLevelContent
102
+ } else if ((next = part.match(RE_PUNCTUATION))) {
103
+ token = TokenType.Punctuation
104
+ state = State.TopLevelContent
105
+ } else if ((next = part.match(RE_VARIABLE_NAME))) {
106
+ token = TokenType.VariableName
107
+ state = State.TopLevelContent
108
+ } else if ((next = part.match(RE_NUMERIC))) {
109
+ token = TokenType.Numeric
110
+ state = State.TopLevelContent
111
+ } else if ((next = part.match(RE_QUOTE_DOUBLE))) {
112
+ token = TokenType.PunctuationString
113
+ state = State.InsideString
114
+ } else if ((next = part.match(RE_LINE_COMMENT_START))) {
115
+ token = TokenType.Comment
116
+ state = State.InsideLineComment
117
+ } else if ((next = part.match(RE_ANYTHING))) {
118
+ token = TokenType.Text
119
+ state = State.TopLevelContent
120
+ } else {
121
+ part //?
122
+ throw new Error('no')
123
+ }
124
+ break
125
+ case State.InsideString:
126
+ if ((next = part.match(RE_QUOTE_DOUBLE))) {
127
+ token = TokenType.PunctuationString
128
+ state = State.TopLevelContent
129
+ } else if ((next = part.match(RE_STRING_DOUBLE_QUOTE_CONTENT))) {
130
+ token = TokenType.String
131
+ state = State.InsideString
132
+ } else {
133
+ throw new Error('no')
134
+ }
135
+ break
136
+ case State.InsideLineComment:
137
+ if ((next = part.match(RE_ANYTHING))) {
138
+ token = TokenType.Comment
139
+ state = State.TopLevelContent
140
+ } else {
141
+ throw new Error('no')
142
+ }
143
+ break
144
+ default:
145
+ throw new Error('no')
146
+ }
147
+ const tokenLength = next[0].length
148
+ index += tokenLength
149
+ tokens.push(token, tokenLength)
150
+ }
151
+ if (state === State.InsideLineComment) {
152
+ state = State.TopLevelContent
153
+ }
154
+ return {
155
+ state,
156
+ tokens,
157
+ }
158
+ }
@@ -4,6 +4,7 @@
4
4
  export const State = {
5
5
  TopLevelContent: 1,
6
6
  InsideString: 2,
7
+ InsideLineComment: 3,
7
8
  }
8
9
 
9
10
  export const StateMap = {
@@ -22,6 +23,8 @@ export const TokenType = {
22
23
  Numeric: 6,
23
24
  Punctuation: 7,
24
25
  VariableName: 8,
26
+ Comment: 885,
27
+ Text: 9,
25
28
  }
26
29
 
27
30
  export const TokenMap = {
@@ -33,8 +36,11 @@ export const TokenMap = {
33
36
  [TokenType.Numeric]: 'Numeric',
34
37
  [TokenType.Punctuation]: 'Punctuation',
35
38
  [TokenType.VariableName]: 'VariableName',
39
+ [TokenType.Comment]: 'Comment',
40
+ [TokenType.Text]: 'Text',
36
41
  }
37
42
 
43
+ const RE_LINE_COMMENT_START = /^#/
38
44
  const RE_SELECTOR = /^[\.a-zA-Z\d\-\:>]+/
39
45
  const RE_WHITESPACE = /^ +/
40
46
  const RE_CURLY_OPEN = /^\{/
@@ -44,14 +50,14 @@ const RE_COLON = /^:/
44
50
  const RE_PROPERTY_VALUE = /^[^;\}]+/
45
51
  const RE_SEMICOLON = /^;/
46
52
  const RE_COMMA = /^,/
47
- const RE_ANYTHING = /^.*/
53
+ const RE_ANYTHING = /^.*/s
48
54
  const RE_ANYTHING_UNTIL_CLOSE_BRACE = /^[^\}]+/
49
55
  const RE_QUOTE_DOUBLE = /^"/
50
56
  const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
51
57
  const RE_KEYWORD =
52
58
  /^(?:alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|times|trap|true|type|ulimit|umask|unalias|unset|wait)\b/
53
59
 
54
- const RE_VARIABLE_NAME = /^[a-zA-Z]+/
60
+ const RE_VARIABLE_NAME = /^[a-zA-Z\_]+/
55
61
  const RE_PUNCTUATION = /^[:,;\{\}\[\]\.=\(\)<>]/
56
62
  const RE_NUMERIC = /^\d+/
57
63
 
@@ -60,12 +66,21 @@ export const initialLineState = {
60
66
  tokens: [],
61
67
  }
62
68
 
69
+ /**
70
+ *
71
+ * @param {any} lineStateA
72
+ * @param {any} lineStateB
73
+ * @returns
74
+ */
63
75
  export const isEqualLineState = (lineStateA, lineStateB) => {
64
76
  return lineStateA.state === lineStateB.state
65
77
  }
66
78
 
79
+ export const hasArrayReturn = true
80
+
67
81
  /**
68
82
  * @param {string} line
83
+ * @param {any} lineState
69
84
  */
70
85
  export const tokenizeLine = (line, lineState) => {
71
86
  let next = null
@@ -95,6 +110,12 @@ export const tokenizeLine = (line, lineState) => {
95
110
  } else if ((next = part.match(RE_QUOTE_DOUBLE))) {
96
111
  token = TokenType.PunctuationString
97
112
  state = State.InsideString
113
+ } else if ((next = part.match(RE_LINE_COMMENT_START))) {
114
+ token = TokenType.Comment
115
+ state = State.InsideLineComment
116
+ } else if ((next = part.match(RE_ANYTHING))) {
117
+ token = TokenType.Text
118
+ state = State.TopLevelContent
98
119
  } else {
99
120
  part //?
100
121
  throw new Error('no')
@@ -111,14 +132,23 @@ export const tokenizeLine = (line, lineState) => {
111
132
  throw new Error('no')
112
133
  }
113
134
  break
135
+ case State.InsideLineComment:
136
+ if ((next = part.match(RE_ANYTHING))) {
137
+ token = TokenType.Comment
138
+ state = State.TopLevelContent
139
+ } else {
140
+ throw new Error('no')
141
+ }
142
+ break
114
143
  default:
115
144
  throw new Error('no')
116
145
  }
117
- index += next[0].length
118
- tokens.push({
119
- type: token,
120
- length: next[0].length,
121
- })
146
+ const tokenLength = next[0].length
147
+ index += tokenLength
148
+ tokens.push(token, tokenLength)
149
+ }
150
+ if (state === State.InsideLineComment) {
151
+ state = State.TopLevelContent
122
152
  }
123
153
  return {
124
154
  state,
@@ -11,7 +11,7 @@
11
11
  ".tml",
12
12
  ".replit"
13
13
  ],
14
- "filenames": [
14
+ "fileNames": [
15
15
  "Cargo.lock",
16
16
  "Gopkg.lock"
17
17
  ],
@@ -4,6 +4,9 @@
4
4
  export const State = {
5
5
  TopLevelContent: 1,
6
6
  InsideLineComment: 2,
7
+ AfterPropertyName: 3,
8
+ AfterPropertyNameAfterEqualSign: 4,
9
+ InsideString: 5,
7
10
  }
8
11
 
9
12
  export const StateMap = {
@@ -17,12 +20,19 @@ export const StateMap = {
17
20
  export const TokenType = {
18
21
  CssSelector: 1,
19
22
  Whitespace: 2,
23
+ PunctuationString: 3,
24
+ String: 4,
20
25
  None: 57,
21
26
  Unknown: 881,
22
27
  NewLine: 884,
23
28
  Comment: 885,
24
29
  Query: 886,
25
30
  Text: 887,
31
+ Numeric: 15,
32
+ PropertyName: 12,
33
+ PropertyValueString: 14,
34
+ Punctuation: 13,
35
+ LanguageConstant: 11,
26
36
  }
27
37
 
28
38
  export const TokenMap = {
@@ -34,19 +44,29 @@ export const TokenMap = {
34
44
  [TokenType.Comment]: 'Comment',
35
45
  [TokenType.Query]: 'Query',
36
46
  [TokenType.Text]: 'Text',
47
+ [TokenType.PropertyName]: 'JsonPropertyName',
48
+ [TokenType.LanguageConstant]: 'LanguageConstant',
49
+ [TokenType.Punctuation]: 'Punctuation',
50
+ [TokenType.PropertyValueString]: 'PropertyValueString',
51
+ [TokenType.Numeric]: 'Numeric',
52
+ [TokenType.PunctuationString]: 'PunctuationString',
53
+ [TokenType.String]: 'String',
37
54
  }
38
55
 
39
56
  const RE_LINE_COMMENT_START = /^#/
40
57
  const RE_WHITESPACE = /^ +/
41
58
  const RE_CURLY_OPEN = /^\{/
42
59
  const RE_CURLY_CLOSE = /^\}/
43
- const RE_PROPERTY_NAME = /^[a-zA-Z\-]+\b/
60
+ const RE_PROPERTY_NAME = /^[a-zA-Z\-\_\d]+\b(?=\s*=)/
44
61
  const RE_COLON = /^:/
45
62
  const RE_PROPERTY_VALUE = /^[^;\}]+/
46
63
  const RE_SEMICOLON = /^;/
47
64
  const RE_COMMA = /^,/
48
65
  const RE_ANYTHING = /^.*/
49
- const RE_NUMERIC = /^(([0-9]+\.?[0-9]*)|(\.[0-9]+))/
66
+ const RE_NUMERIC_INTEGER = /^((?:[\+\-]?(0|([1-9](([0-9]|_[0-9])+)?))))/
67
+ const RE_NUMERIC_FLOAT = /^([\+\-]?(0|([1-9](([0-9]|_[0-9])+)?))(?:(?:\.(0|([1-9](([0-9]|_[0-9])+)?)))?[eE][\+\-]?[1-9]_?[0-9]*|(?:\.[0-9_]*)))/
68
+ const RE_NAN = /^(?:[\+\-]?nan)/
69
+ const RE_INF = /^(?:[\+\-]?inf)/
50
70
  const RE_ANYTHING_UNTIL_CLOSE_BRACE = /^[^\}]+/
51
71
  const RE_BLOCK_COMMENT_START = /^\/\*/
52
72
  const RE_BLOCK_COMMENT_END = /^\*\//
@@ -62,6 +82,11 @@ const RE_STAR = /^\*/
62
82
  const RE_QUERY_NAME = /^[a-z\-]+/
63
83
  const RE_QUERY_CONTENT = /^[^\)]+/
64
84
  const RE_COMBINATOR = /^[\+\>\~]/
85
+ const RE_LANGUAGE_CONSTANT = /^(?:true|false)\b/
86
+ const RE_EQUAL_SIGN = /^=/
87
+ const RE_LOCAL_TIME = /\d{2}:\d{2}:\d{2}(?:\.\d+)?/
88
+ const RE_QUOTE_DOUBLE = /^"/
89
+ const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
65
90
 
66
91
  export const initialLineState = {
67
92
  state: State.TopLevelContent,
@@ -69,6 +94,8 @@ export const initialLineState = {
69
94
  stack: [],
70
95
  }
71
96
 
97
+ export const hasArrayReturn = true
98
+
72
99
  /**
73
100
  * @param {string} line
74
101
  * @param {any} lineState
@@ -83,7 +110,10 @@ export const tokenizeLine = (line, lineState) => {
83
110
  const part = line.slice(index)
84
111
  switch (state) {
85
112
  case State.TopLevelContent:
86
- if ((next = part.match(RE_LINE_COMMENT_START))) {
113
+ if ((next = part.match(RE_PROPERTY_NAME))) {
114
+ token = TokenType.PropertyName
115
+ state = State.AfterPropertyName
116
+ } else if ((next = part.match(RE_LINE_COMMENT_START))) {
87
117
  token = TokenType.Comment
88
118
  state = State.InsideLineComment
89
119
  } else if ((next = part.match(RE_WHITESPACE))) {
@@ -105,15 +135,70 @@ export const tokenizeLine = (line, lineState) => {
105
135
  throw new Error('no')
106
136
  }
107
137
  break
138
+ case State.AfterPropertyName:
139
+ if ((next = part.match(RE_EQUAL_SIGN))) {
140
+ token = TokenType.Punctuation
141
+ state = State.AfterPropertyNameAfterEqualSign
142
+ } else if ((next = part.match(RE_WHITESPACE))) {
143
+ token = TokenType.Whitespace
144
+ state = State.AfterPropertyName
145
+ } else {
146
+ throw new Error('no')
147
+ }
148
+ break
149
+ case State.AfterPropertyNameAfterEqualSign:
150
+ if ((next = part.match(RE_WHITESPACE))) {
151
+ token = TokenType.Whitespace
152
+ state = State.AfterPropertyNameAfterEqualSign
153
+ } else if ((next = part.match(RE_LANGUAGE_CONSTANT))) {
154
+ token = TokenType.LanguageConstant
155
+ state = State.TopLevelContent
156
+ } else if ((next = part.match(RE_LOCAL_TIME))) {
157
+ token = TokenType.Numeric
158
+ state = State.TopLevelContent
159
+ } else if ((next = part.match(RE_NUMERIC_INTEGER))) {
160
+ token = TokenType.Numeric
161
+ state = State.TopLevelContent
162
+ } else if ((next = part.match(RE_NUMERIC_FLOAT))) {
163
+ token = TokenType.Numeric
164
+ state = State.TopLevelContent
165
+ } else if ((next = part.match(RE_LINE_COMMENT_START))) {
166
+ token = TokenType.Comment
167
+ state = State.InsideLineComment
168
+ } else if ((next = part.match(RE_NAN))) {
169
+ token = TokenType.Numeric
170
+ state = State.TopLevelContent
171
+ } else if ((next = part.match(RE_INF))) {
172
+ token = TokenType.Numeric
173
+ state = State.TopLevelContent
174
+ } else if ((next = part.match(RE_QUOTE_DOUBLE))) {
175
+ token = TokenType.Punctuation
176
+ state = State.InsideString
177
+ } else if ((next = part.match(RE_ANYTHING))) {
178
+ token = TokenType.PropertyValueString
179
+ state = State.TopLevelContent
180
+ } else {
181
+ throw new Error('no')
182
+ }
183
+ break
184
+ case State.InsideString:
185
+ if ((next = part.match(RE_QUOTE_DOUBLE))) {
186
+ token = TokenType.PunctuationString
187
+ state = State.TopLevelContent
188
+ } else if ((next = part.match(RE_STRING_DOUBLE_QUOTE_CONTENT))) {
189
+ token = TokenType.String
190
+ state = State.InsideString
191
+ } else {
192
+ throw new Error('no')
193
+ }
194
+ break
108
195
  default:
109
196
  console.log({ state, line })
110
197
  throw new Error('no')
111
198
  }
112
- index += next[0].length
113
- tokens.push({
114
- type: token,
115
- length: next[0].length,
116
- })
199
+ const tokenLength = next[0].length
200
+ index += tokenLength
201
+ tokens.push(token, tokenLength)
117
202
  }
118
203
  return {
119
204
  state,
@@ -7,6 +7,11 @@ export const State = {
7
7
  AfterPropertyName: 3,
8
8
  AfterPropertyNameAfterColon: 4,
9
9
  AfterDash: 5,
10
+ AfterPropertyNameAfterColonAfterNewLine: 6,
11
+ AfterPipe: 7,
12
+ InsideMultiLineString: 8,
13
+ InsideMultiLineStringAfterWhitespace: 9,
14
+ AfterPropertyValue: 10,
10
15
  }
11
16
 
12
17
  export const StateMap = {
@@ -31,6 +36,7 @@ export const TokenType = {
31
36
  Text: 887,
32
37
  Unknown: 881,
33
38
  Whitespace: 2,
39
+ String: 188,
34
40
  }
35
41
 
36
42
  export const TokenMap = {
@@ -47,18 +53,20 @@ export const TokenMap = {
47
53
  [TokenType.Whitespace]: 'Whitespace',
48
54
  [TokenType.Punctuation]: 'Punctuation',
49
55
  [TokenType.PropertyValueString]: 'String',
56
+ [TokenType.String]: 'String',
50
57
  }
51
58
 
52
59
  const RE_LINE_COMMENT_START = /^#/
53
60
  const RE_WHITESPACE = /^ +/
54
61
  const RE_CURLY_OPEN = /^\{/
55
62
  const RE_CURLY_CLOSE = /^\}/
56
- const RE_PROPERTY_NAME = /^[a-zA-Z\-\_\d\s]+\b(?=\s*:)/
57
- const RE_PROPERTY_VALUE = /^[^;\}]+/
63
+ const RE_PROPERTY_NAME = /^[a-zA-Z\-\_\d\s]+\b(?=\s*:(\s+|$))/
64
+ const RE_PROPERTY_VALUE_1 = /^.+(?=\s+#)/s
58
65
  const RE_SEMICOLON = /^;/
59
66
  const RE_COMMA = /^,/
60
67
  const RE_ANYTHING = /^.*/
61
- const RE_NUMERIC = /^(([0-9]+\.?[0-9]*)|(\.[0-9]+))/
68
+ const RE_ANYTHING_BUT_COMMENT = /^[^#]+/
69
+ const RE_NUMERIC = /^(([0-9]+\.?[0-9]*)|(\.[0-9]+))(?=\s|$)/
62
70
  const RE_ANYTHING_UNTIL_CLOSE_BRACE = /^[^\}]+/
63
71
  const RE_BLOCK_COMMENT_START = /^\/\*/
64
72
  const RE_BLOCK_COMMENT_END = /^\*\//
@@ -74,18 +82,35 @@ const RE_STAR = /^\*/
74
82
  const RE_QUERY_NAME = /^[a-z\-]+/
75
83
  const RE_QUERY_CONTENT = /^[^\)]+/
76
84
  const RE_COMBINATOR = /^[\+\>\~]/
77
- const RE_LANGUAGE_CONSTANT = /^(?:true|false)/
85
+ const RE_LANGUAGE_CONSTANT = /^(?:true|false|null)(?!#)/
78
86
  const RE_COLON = /^:/
79
87
  const RE_DASH = /^\-/
88
+ const RE_WORDS = /^[\w\s]*\w/
89
+ const RE_MULTI_LINE_STRING_START = /^(?:\||>\-|>)/
90
+ const RE_KEY_PRE = /^\s*(\-\s*)?/
80
91
 
81
92
  export const initialLineState = {
82
93
  state: State.TopLevelContent,
83
94
  tokens: [],
84
- stack: [],
95
+ indent: '',
96
+ keyOffset: 0,
85
97
  }
86
98
 
87
99
  export const hasArrayReturn = true
88
100
 
101
+ /**
102
+ *
103
+ * @param {string} line
104
+ * @returns {number}
105
+ */
106
+ const getKeyOffset = (line) => {
107
+ const whiteSpaceMatch = line.match(RE_KEY_PRE)
108
+ if (whiteSpaceMatch) {
109
+ return whiteSpaceMatch[0].length
110
+ }
111
+ return 0
112
+ }
113
+
89
114
  /**
90
115
  * @param {string} line
91
116
  * @param {any} lineState
@@ -96,6 +121,7 @@ export const tokenizeLine = (line, lineState) => {
96
121
  let tokens = []
97
122
  let token = TokenType.None
98
123
  let state = lineState.state
124
+ let keyOffset = lineState.keyOffset
99
125
  while (index < line.length) {
100
126
  const part = line.slice(index)
101
127
  switch (state) {
@@ -118,6 +144,9 @@ export const tokenizeLine = (line, lineState) => {
118
144
  } else if ((next = part.match(RE_NUMERIC))) {
119
145
  token = TokenType.Numeric
120
146
  state = State.TopLevelContent
147
+ } else if ((next = part.match(RE_WORDS))) {
148
+ token = TokenType.Text
149
+ state = State.TopLevelContent
121
150
  } else if ((next = part.match(RE_ANYTHING))) {
122
151
  token = TokenType.Text
123
152
  state = State.TopLevelContent
@@ -155,6 +184,15 @@ export const tokenizeLine = (line, lineState) => {
155
184
  } else if ((next = part.match(RE_NUMERIC))) {
156
185
  token = TokenType.Numeric
157
186
  state = State.TopLevelContent
187
+ } else if ((next = part.match(RE_LINE_COMMENT_START))) {
188
+ token = TokenType.Comment
189
+ state = State.InsideLineComment
190
+ } else if ((next = part.match(RE_MULTI_LINE_STRING_START))) {
191
+ token = TokenType.Punctuation
192
+ state = State.AfterPipe
193
+ } else if ((next = part.match(RE_PROPERTY_VALUE_1))) {
194
+ token = TokenType.PropertyValueString
195
+ state = State.AfterPropertyValue
158
196
  } else if ((next = part.match(RE_ANYTHING))) {
159
197
  token = TokenType.PropertyValueString
160
198
  state = State.TopLevelContent
@@ -162,6 +200,26 @@ export const tokenizeLine = (line, lineState) => {
162
200
  throw new Error('no')
163
201
  }
164
202
  break
203
+ case State.AfterPropertyValue:
204
+ if ((next = part.match(RE_WHITESPACE))) {
205
+ token = TokenType.Whitespace
206
+ state = State.AfterPropertyValue
207
+ } else if ((next = part.match(RE_LINE_COMMENT_START))) {
208
+ token = TokenType.Comment
209
+ state = State.InsideLineComment
210
+ } else {
211
+ part
212
+ throw new Error('no')
213
+ }
214
+ break
215
+ case State.AfterPipe:
216
+ if ((next = part.match(RE_WHITESPACE))) {
217
+ token = TokenType.Whitespace
218
+ state = State.AfterPipe
219
+ } else {
220
+ throw new Error('no')
221
+ }
222
+ break
165
223
  case State.AfterDash:
166
224
  if ((next = part.match(RE_WHITESPACE))) {
167
225
  token = TokenType.Whitespace
@@ -175,6 +233,9 @@ export const tokenizeLine = (line, lineState) => {
175
233
  } else if ((next = part.match(RE_NUMERIC))) {
176
234
  token = TokenType.Numeric
177
235
  state = State.TopLevelContent
236
+ } else if ((next = part.match(RE_MULTI_LINE_STRING_START))) {
237
+ token = TokenType.Punctuation
238
+ state = State.AfterPipe
178
239
  } else if ((next = part.match(RE_ANYTHING))) {
179
240
  token = TokenType.PropertyValueString
180
241
  state = State.TopLevelContent
@@ -182,19 +243,86 @@ export const tokenizeLine = (line, lineState) => {
182
243
  throw new Error('no')
183
244
  }
184
245
  break
246
+ case State.AfterPropertyNameAfterColonAfterNewLine:
247
+ if ((next = part.match(RE_WHITESPACE))) {
248
+ token = TokenType.Whitespace
249
+ state = State.AfterPropertyNameAfterColonAfterNewLine
250
+ } else if ((next = part.match(RE_DASH))) {
251
+ token = TokenType.Punctuation
252
+ state = State.AfterDash
253
+ } else if ((next = part.match(RE_PROPERTY_NAME))) {
254
+ token = TokenType.PropertyName
255
+ state = State.AfterPropertyName
256
+ } else if ((next = part.match(RE_NUMERIC))) {
257
+ token = TokenType.Numeric
258
+ state = State.TopLevelContent
259
+ } else if ((next = part.match(RE_LANGUAGE_CONSTANT))) {
260
+ token = TokenType.LanguageConstant
261
+ state = State.TopLevelContent
262
+ } else if ((next = part.match(RE_WORDS))) {
263
+ token = TokenType.PropertyValueString
264
+ state = State.TopLevelContent
265
+ } else if ((next = part.match(RE_LINE_COMMENT_START))) {
266
+ token = TokenType.Comment
267
+ state = State.InsideLineComment
268
+ } else {
269
+ part
270
+ throw new Error('no')
271
+ }
272
+ break
273
+ case State.InsideMultiLineString:
274
+ if ((next = part.match(RE_WHITESPACE))) {
275
+ token = TokenType.Whitespace
276
+ if (next[0].length > keyOffset) {
277
+ state = State.InsideMultiLineStringAfterWhitespace
278
+ } else {
279
+ state = State.TopLevelContent
280
+ }
281
+ } else if ((next = part.match(RE_PROPERTY_NAME))) {
282
+ token = TokenType.PropertyName
283
+ state = State.AfterPropertyName
284
+ } else if ((next = part.match(RE_DASH))) {
285
+ token = TokenType.Punctuation
286
+ state = State.AfterDash
287
+ } else if ((next = part.match(RE_ANYTHING))) {
288
+ token = TokenType.Text
289
+ state = State.TopLevelContent
290
+ } else {
291
+ throw new Error('no')
292
+ }
293
+ break
294
+ case State.InsideMultiLineStringAfterWhitespace:
295
+ if ((next = part.match(RE_ANYTHING))) {
296
+ token = TokenType.String
297
+ state = State.InsideMultiLineString
298
+ } else {
299
+ throw new Error('no')
300
+ }
301
+ break
185
302
  default:
186
303
  console.log({ state, line })
187
304
  throw new Error('no')
188
305
  }
189
- const length = next[0].length
190
- index += length
191
- tokens.push(token, length)
306
+ const tokenLength = next[0].length
307
+ index += tokenLength
308
+ tokens.push(token, tokenLength)
192
309
  }
193
- if (state === State.AfterPropertyNameAfterColon) {
194
- state = State.TopLevelContent
310
+ switch (state) {
311
+ case State.AfterPropertyNameAfterColon:
312
+ state = State.AfterPropertyNameAfterColonAfterNewLine
313
+ break
314
+ case State.AfterPipe:
315
+ keyOffset = getKeyOffset(line)
316
+ keyOffset
317
+ line
318
+ state = State.InsideMultiLineString
319
+ break
320
+ default:
321
+ break
195
322
  }
196
323
  return {
197
324
  state,
198
325
  tokens,
326
+ keyOffset,
199
327
  }
200
328
  }