@mojir/lits 2.1.27 → 2.1.29

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.
package/dist/cli/cli.js CHANGED
@@ -92,7 +92,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
92
92
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
93
93
  };
94
94
 
95
- var version = "2.1.27";
95
+ var version = "2.1.29";
96
96
 
97
97
  function getCodeMarker(sourceCodeInfo) {
98
98
  if (!sourceCodeInfo.position || !sourceCodeInfo.code)
@@ -13318,7 +13318,7 @@ var tokenizeDocString = function (input, position) {
13318
13318
  nextThreeChars = input.slice(position + length, position + length + 3);
13319
13319
  }
13320
13320
  if (!char) {
13321
- throw new LitsError("Unclosed doc string at position ".concat(position, "."), undefined);
13321
+ return [length, ['Error', value, undefined, "Unclosed doc string at position ".concat(position)]];
13322
13322
  }
13323
13323
  value += '"""'; // closing quote
13324
13324
  return [length + 3, ['DocString', value]];
@@ -13345,7 +13345,7 @@ var tokenizeString = function (input, position) {
13345
13345
  char = input[position + length];
13346
13346
  }
13347
13347
  if (!char) {
13348
- throw new LitsError("Unclosed string at position ".concat(position, "."), undefined);
13348
+ return [length, ['Error', value, undefined, "Unclosed string at position ".concat(position)]];
13349
13349
  }
13350
13350
  value += '"'; // closing quote
13351
13351
  return [length + 1, ['String', value]];
@@ -13356,16 +13356,20 @@ var tokenizeRegexpShorthand = function (input, position) {
13356
13356
  var _a = __read(tokenizeString(input, position + 1), 2), stringLength = _a[0], token = _a[1];
13357
13357
  if (!token)
13358
13358
  return NO_MATCH;
13359
+ if (token[0] === 'Error') {
13360
+ var errorToken = ['Error', "#".concat(token[1]), undefined, "Unclosed regexp at position ".concat(position)];
13361
+ return [stringLength + 1, errorToken];
13362
+ }
13359
13363
  position += stringLength + 1;
13360
13364
  var length = stringLength + 1;
13361
13365
  var options = '';
13362
13366
  while (input[position] === 'g' || input[position] === 'i') {
13363
- if (options.includes(input[position])) {
13364
- throw new LitsError("Duplicated regexp option \"".concat(input[position], "\" at position ").concat(position, "."), undefined);
13365
- }
13366
13367
  options += input[position];
13367
13368
  length += 1;
13368
13369
  position += 1;
13370
+ if (options.includes(input[position])) {
13371
+ return [length, ['Error', "#".concat(token[1]).concat(options), undefined, "Duplicated regexp option \"".concat(input[position], "\"")]];
13372
+ }
13369
13373
  }
13370
13374
  return [length, ['RegexpShorthand', "#".concat(token[1]).concat(options)]];
13371
13375
  };
@@ -13409,7 +13413,7 @@ var tokenizeNumber = function (input, position) {
13409
13413
  if (i === start) {
13410
13414
  return NO_MATCH;
13411
13415
  }
13412
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13416
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13413
13417
  }
13414
13418
  }
13415
13419
  else if (char === '.') {
@@ -13417,7 +13421,7 @@ var tokenizeNumber = function (input, position) {
13417
13421
  return NO_MATCH;
13418
13422
  }
13419
13423
  if (hasDecimalPoint || hasExponent) {
13420
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13424
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13421
13425
  }
13422
13426
  hasDecimalPoint = true;
13423
13427
  }
@@ -13426,10 +13430,10 @@ var tokenizeNumber = function (input, position) {
13426
13430
  return NO_MATCH;
13427
13431
  }
13428
13432
  if (hasExponent) {
13429
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13433
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13430
13434
  }
13431
13435
  if (input[i - 1] === '.' || input[i - 1] === '+' || input[i - 1] === '-') {
13432
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13436
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13433
13437
  }
13434
13438
  if (input[i + 1] === '+' || input[i + 1] === '-') {
13435
13439
  i += 1;
@@ -13449,7 +13453,7 @@ var tokenizeNumber = function (input, position) {
13449
13453
  }
13450
13454
  var nextChar = input[i];
13451
13455
  if (nextChar && nextChar !== ':' && !postNumberRegExp.test(nextChar)) {
13452
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13456
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13453
13457
  }
13454
13458
  return [length, ['Number', input.substring(position, i)]];
13455
13459
  };
@@ -13499,7 +13503,7 @@ var tokenizeSymbol = function (input, position) {
13499
13503
  var escaping = false;
13500
13504
  while (char !== '\'' || escaping) {
13501
13505
  if (char === undefined)
13502
- throw new LitsError("Unclosed string at position ".concat(position, "."), undefined);
13506
+ return [length_1, ['Error', value, undefined, "Unclosed quoted symbol at position ".concat(position)]];
13503
13507
  length_1 += 1;
13504
13508
  if (escaping) {
13505
13509
  escaping = false;
@@ -13570,7 +13574,7 @@ var tokenizeMultiLineComment = function (input, position) {
13570
13574
  length_2 += 1;
13571
13575
  }
13572
13576
  if (position + length_2 + 1 >= input.length) {
13573
- throw new LitsError('Comment not closed', undefined);
13577
+ return [length_2, ['Error', value, undefined, "Unclosed multi-line comment at position ".concat(position)]];
13574
13578
  }
13575
13579
  value += '*/';
13576
13580
  length_2 += 2;
@@ -13623,9 +13627,6 @@ function tokenize(input, debug, filePath) {
13623
13627
  ? createSourceCodeInfo(input, position, filePath)
13624
13628
  : undefined;
13625
13629
  var tokenDescriptor = getCurrentToken(input, position);
13626
- if (!tokenDescriptor) {
13627
- throw new LitsError("Unrecognized character '".concat(input[position], "'."), sourceCodeInfo);
13628
- }
13629
13630
  var _a = __read(tokenDescriptor, 2), count = _a[0], token = _a[1];
13630
13631
  position += count;
13631
13632
  if (token) {
@@ -13676,7 +13677,7 @@ function getCurrentToken(input, position) {
13676
13677
  }
13677
13678
  finally { if (e_1) throw e_1.error; }
13678
13679
  }
13679
- return null;
13680
+ return [1, ['Error', input[initialPosition], undefined, 'Unrecognized character']];
13680
13681
  }
13681
13682
 
13682
13683
  function isSymbolToken(token, symbolName) {
@@ -13964,6 +13965,11 @@ var Parser = /** @class */ (function () {
13964
13965
  this.parseState.position += 1;
13965
13966
  };
13966
13967
  Parser.prototype.parse = function () {
13968
+ this.tokenStream.tokens.forEach(function (token) {
13969
+ if (token[0] === 'Error') {
13970
+ throw new LitsError(token[3], token[2]);
13971
+ }
13972
+ });
13967
13973
  var nodes = [];
13968
13974
  while (!this.isAtEnd()) {
13969
13975
  nodes.push(this.parseExpression(0, true));
@@ -15030,20 +15036,14 @@ var AutoCompleter = /** @class */ (function () {
15030
15036
  this.suggestions = [];
15031
15037
  this.suggestionIndex = null;
15032
15038
  var partialProgram = this.originalProgram.slice(0, this.originalPosition);
15033
- var tokenStream = null;
15034
- try {
15035
- tokenStream = lits.tokenize(partialProgram);
15036
- }
15037
- catch (_a) {
15038
- // do nothing
15039
- }
15040
- if (!tokenStream) {
15041
- return;
15042
- }
15039
+ var tokenStream = lits.tokenize(partialProgram);
15043
15040
  var lastToken = tokenStream.tokens.at(-1);
15044
15041
  if (!lastToken) {
15045
15042
  return;
15046
15043
  }
15044
+ if (lastToken[0] === 'Error') {
15045
+ return;
15046
+ }
15047
15047
  this.searchString = lastToken[1];
15048
15048
  this.prefixProgram = this.originalProgram.slice(0, this.originalPosition - this.searchString.length);
15049
15049
  this.suffixProgram = this.originalProgram.slice(this.prefixProgram.length + this.searchString.length);
@@ -15103,27 +15103,47 @@ var AutoCompleter = /** @class */ (function () {
15103
15103
  };
15104
15104
  AutoCompleter.prototype.generateSuggestions = function (params) {
15105
15105
  var _this = this;
15106
+ var blacklist = new Set(['0_def', '0_defn', '0_fn']);
15107
+ var startsWithCaseSensitive = this.generateWithPredicate(params, function (suggestion) {
15108
+ return !blacklist.has(suggestion) && suggestion.startsWith(_this.searchString);
15109
+ });
15110
+ startsWithCaseSensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15111
+ var startsWithCaseInsensitive = this.generateWithPredicate(params, function (suggestion) {
15112
+ return !blacklist.has(suggestion) && suggestion.toLowerCase().startsWith(_this.searchString.toLowerCase());
15113
+ });
15114
+ startsWithCaseInsensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15115
+ var includesCaseSensitive = this.generateWithPredicate(params, function (suggestion) {
15116
+ return !blacklist.has(suggestion) && suggestion.includes(_this.searchString);
15117
+ });
15118
+ includesCaseSensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15119
+ var includesCaseInsensitive = this.generateWithPredicate(params, function (suggestion) {
15120
+ return !blacklist.has(suggestion) && suggestion.includes(_this.searchString.toLowerCase());
15121
+ });
15122
+ includesCaseInsensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15123
+ return __spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(startsWithCaseSensitive), false), __read(startsWithCaseInsensitive), false), __read(includesCaseSensitive), false), __read(includesCaseInsensitive), false);
15124
+ };
15125
+ AutoCompleter.prototype.generateWithPredicate = function (params, shouldInclude) {
15106
15126
  var _a, _b, _c, _d;
15107
15127
  var suggestions = new Set();
15108
- litsCommands.forEach(function (name) {
15109
- if (name.startsWith(_this.searchString)) {
15110
- suggestions.add(name);
15128
+ litsCommands.forEach(function (suggestion) {
15129
+ if (shouldInclude(suggestion)) {
15130
+ suggestions.add(suggestion);
15111
15131
  }
15112
15132
  });
15113
15133
  Object.keys((_a = params.globalContext) !== null && _a !== void 0 ? _a : {})
15114
- .filter(function (name) { return name.startsWith(_this.searchString); })
15115
- .forEach(function (name) { return suggestions.add(name); });
15134
+ .filter(shouldInclude)
15135
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15116
15136
  (_b = params.contexts) === null || _b === void 0 ? void 0 : _b.forEach(function (context) {
15117
15137
  Object.keys(context)
15118
- .filter(function (name) { return name.startsWith(_this.searchString); })
15119
- .forEach(function (name) { return suggestions.add(name); });
15138
+ .filter(shouldInclude)
15139
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15120
15140
  });
15121
15141
  Object.keys((_c = params.jsFunctions) !== null && _c !== void 0 ? _c : {})
15122
- .filter(function (name) { return name.startsWith(_this.searchString); })
15123
- .forEach(function (name) { return suggestions.add(name); });
15142
+ .filter(shouldInclude)
15143
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15124
15144
  Object.keys((_d = params.values) !== null && _d !== void 0 ? _d : {})
15125
- .filter(function (name) { return name.startsWith(_this.searchString); })
15126
- .forEach(function (name) { return suggestions.add(name); });
15145
+ .filter(shouldInclude)
15146
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15127
15147
  return __spreadArray([], __read(suggestions), false).sort(function (a, b) { return a.localeCompare(b); });
15128
15148
  };
15129
15149
  return AutoCompleter;
@@ -20,4 +20,5 @@ export declare class AutoCompleter {
20
20
  getSuggestions(): string[];
21
21
  getSearchString(): string;
22
22
  private generateSuggestions;
23
+ private generateWithPredicate;
23
24
  }
@@ -1,10 +1,11 @@
1
1
  import type { ReservedSymbol } from './reservedNames';
2
2
  import { type SymbolicBinaryOperator, type SymbolicOperator } from './operators';
3
- export declare const tokenTypes: readonly ["LBrace", "LBracket", "RBrace", "RBracket", "LParen", "RParen", "BasePrefixedNumber", "DocString", "MultiLineComment", "Number", "Operator", "RegexpShorthand", "ReservedSymbol", "SingleLineComment", "String", "Symbol", "Whitespace"];
3
+ export declare const tokenTypes: readonly ["LBrace", "LBracket", "RBrace", "RBracket", "LParen", "RParen", "BasePrefixedNumber", "DocString", "Error", "MultiLineComment", "Number", "Operator", "RegexpShorthand", "ReservedSymbol", "SingleLineComment", "String", "Symbol", "Whitespace"];
4
4
  export type TokenType = typeof tokenTypes[number];
5
5
  declare const modifierNames: readonly ["&rest", "&let", "&when", "&while"];
6
6
  export type ModifierName = typeof modifierNames[number];
7
7
  type GenericToken<T extends TokenType, V extends string = string> = [T, V] | [T, V, SourceCodeInfo];
8
+ export type ErrorToken = ['Error', string, SourceCodeInfo | undefined, string];
8
9
  export type LBraceToken = GenericToken<'LBrace', '{'>;
9
10
  export type LBracketToken = GenericToken<'LBracket', '['>;
10
11
  export type LParenToken = GenericToken<'LParen', '('>;
@@ -22,7 +23,7 @@ export type StringToken = GenericToken<'String'>;
22
23
  export type DocStringToken = GenericToken<'DocString'>;
23
24
  export type SymbolToken<T extends string = string> = GenericToken<'Symbol', T>;
24
25
  export type WhitespaceToken = GenericToken<'Whitespace'>;
25
- export type Token = LBraceToken | LBracketToken | LParenToken | RBraceToken | RBracketToken | RParenToken | BasePrefixedNumberToken | DocStringToken | MultiLineCommentToken | NumberToken | OperatorToken | RegexpShorthandToken | ReservedSymbolToken | SingleLineCommentToken | StringToken | SymbolToken | WhitespaceToken;
26
+ export type Token = LBraceToken | LBracketToken | LParenToken | RBraceToken | RBracketToken | RParenToken | BasePrefixedNumberToken | DocStringToken | ErrorToken | MultiLineCommentToken | NumberToken | OperatorToken | RegexpShorthandToken | ReservedSymbolToken | SingleLineCommentToken | StringToken | SymbolToken | WhitespaceToken;
26
27
  export type TokenDescriptor<T extends Token> = [length: number, token?: T];
27
28
  export interface SourceCodeInfo {
28
29
  position: {
@@ -1,5 +1,5 @@
1
- import type { BasePrefixedNumberToken, DocStringToken, LBraceToken, LBracketToken, LParenToken, MultiLineCommentToken, NumberToken, OperatorToken, RBraceToken, RBracketToken, RParenToken, RegexpShorthandToken, ReservedSymbolToken, SingleLineCommentToken, StringToken, SymbolToken, Token, TokenDescriptor, WhitespaceToken } from './token';
2
- export type Tokenizer<T extends Token> = (input: string, position: number) => TokenDescriptor<T>;
1
+ import type { BasePrefixedNumberToken, DocStringToken, ErrorToken, LBraceToken, LBracketToken, LParenToken, MultiLineCommentToken, NumberToken, OperatorToken, RBraceToken, RBracketToken, RParenToken, RegexpShorthandToken, ReservedSymbolToken, SingleLineCommentToken, StringToken, SymbolToken, Token, TokenDescriptor, WhitespaceToken } from './token';
2
+ export type Tokenizer<T extends Token> = (input: string, position: number) => TokenDescriptor<T | ErrorToken>;
3
3
  export declare const NO_MATCH: TokenDescriptor<never>;
4
4
  export declare const tokenizeDocString: Tokenizer<DocStringToken>;
5
5
  export declare const tokenizeWhitespace: Tokenizer<WhitespaceToken>;
package/dist/index.esm.js CHANGED
@@ -13344,7 +13344,7 @@ var tokenizeDocString = function (input, position) {
13344
13344
  nextThreeChars = input.slice(position + length, position + length + 3);
13345
13345
  }
13346
13346
  if (!char) {
13347
- throw new LitsError("Unclosed doc string at position ".concat(position, "."), undefined);
13347
+ return [length, ['Error', value, undefined, "Unclosed doc string at position ".concat(position)]];
13348
13348
  }
13349
13349
  value += '"""'; // closing quote
13350
13350
  return [length + 3, ['DocString', value]];
@@ -13371,7 +13371,7 @@ var tokenizeString = function (input, position) {
13371
13371
  char = input[position + length];
13372
13372
  }
13373
13373
  if (!char) {
13374
- throw new LitsError("Unclosed string at position ".concat(position, "."), undefined);
13374
+ return [length, ['Error', value, undefined, "Unclosed string at position ".concat(position)]];
13375
13375
  }
13376
13376
  value += '"'; // closing quote
13377
13377
  return [length + 1, ['String', value]];
@@ -13382,16 +13382,20 @@ var tokenizeRegexpShorthand = function (input, position) {
13382
13382
  var _a = __read(tokenizeString(input, position + 1), 2), stringLength = _a[0], token = _a[1];
13383
13383
  if (!token)
13384
13384
  return NO_MATCH;
13385
+ if (token[0] === 'Error') {
13386
+ var errorToken = ['Error', "#".concat(token[1]), undefined, "Unclosed regexp at position ".concat(position)];
13387
+ return [stringLength + 1, errorToken];
13388
+ }
13385
13389
  position += stringLength + 1;
13386
13390
  var length = stringLength + 1;
13387
13391
  var options = '';
13388
13392
  while (input[position] === 'g' || input[position] === 'i') {
13389
- if (options.includes(input[position])) {
13390
- throw new LitsError("Duplicated regexp option \"".concat(input[position], "\" at position ").concat(position, "."), undefined);
13391
- }
13392
13393
  options += input[position];
13393
13394
  length += 1;
13394
13395
  position += 1;
13396
+ if (options.includes(input[position])) {
13397
+ return [length, ['Error', "#".concat(token[1]).concat(options), undefined, "Duplicated regexp option \"".concat(input[position], "\"")]];
13398
+ }
13395
13399
  }
13396
13400
  return [length, ['RegexpShorthand', "#".concat(token[1]).concat(options)]];
13397
13401
  };
@@ -13435,7 +13439,7 @@ var tokenizeNumber = function (input, position) {
13435
13439
  if (i === start) {
13436
13440
  return NO_MATCH;
13437
13441
  }
13438
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13442
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13439
13443
  }
13440
13444
  }
13441
13445
  else if (char === '.') {
@@ -13443,7 +13447,7 @@ var tokenizeNumber = function (input, position) {
13443
13447
  return NO_MATCH;
13444
13448
  }
13445
13449
  if (hasDecimalPoint || hasExponent) {
13446
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13450
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13447
13451
  }
13448
13452
  hasDecimalPoint = true;
13449
13453
  }
@@ -13452,10 +13456,10 @@ var tokenizeNumber = function (input, position) {
13452
13456
  return NO_MATCH;
13453
13457
  }
13454
13458
  if (hasExponent) {
13455
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13459
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13456
13460
  }
13457
13461
  if (input[i - 1] === '.' || input[i - 1] === '+' || input[i - 1] === '-') {
13458
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13462
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13459
13463
  }
13460
13464
  if (input[i + 1] === '+' || input[i + 1] === '-') {
13461
13465
  i += 1;
@@ -13475,7 +13479,7 @@ var tokenizeNumber = function (input, position) {
13475
13479
  }
13476
13480
  var nextChar = input[i];
13477
13481
  if (nextChar && nextChar !== ':' && !postNumberRegExp.test(nextChar)) {
13478
- throw new LitsError("Invalid number format at position ".concat(i, "."), undefined);
13482
+ return [i - position + 1, ['Error', input.substring(position, i + 1), undefined, "Invalid number format at position ".concat(i + 1)]];
13479
13483
  }
13480
13484
  return [length, ['Number', input.substring(position, i)]];
13481
13485
  };
@@ -13525,7 +13529,7 @@ var tokenizeSymbol = function (input, position) {
13525
13529
  var escaping = false;
13526
13530
  while (char !== '\'' || escaping) {
13527
13531
  if (char === undefined)
13528
- throw new LitsError("Unclosed string at position ".concat(position, "."), undefined);
13532
+ return [length_1, ['Error', value, undefined, "Unclosed quoted symbol at position ".concat(position)]];
13529
13533
  length_1 += 1;
13530
13534
  if (escaping) {
13531
13535
  escaping = false;
@@ -13596,7 +13600,7 @@ var tokenizeMultiLineComment = function (input, position) {
13596
13600
  length_2 += 1;
13597
13601
  }
13598
13602
  if (position + length_2 + 1 >= input.length) {
13599
- throw new LitsError('Comment not closed', undefined);
13603
+ return [length_2, ['Error', value, undefined, "Unclosed multi-line comment at position ".concat(position)]];
13600
13604
  }
13601
13605
  value += '*/';
13602
13606
  length_2 += 2;
@@ -13649,9 +13653,6 @@ function tokenize(input, debug, filePath) {
13649
13653
  ? createSourceCodeInfo(input, position, filePath)
13650
13654
  : undefined;
13651
13655
  var tokenDescriptor = getCurrentToken(input, position);
13652
- if (!tokenDescriptor) {
13653
- throw new LitsError("Unrecognized character '".concat(input[position], "'."), sourceCodeInfo);
13654
- }
13655
13656
  var _a = __read(tokenDescriptor, 2), count = _a[0], token = _a[1];
13656
13657
  position += count;
13657
13658
  if (token) {
@@ -13702,7 +13703,7 @@ function getCurrentToken(input, position) {
13702
13703
  }
13703
13704
  finally { if (e_1) throw e_1.error; }
13704
13705
  }
13705
- return null;
13706
+ return [1, ['Error', input[initialPosition], undefined, 'Unrecognized character']];
13706
13707
  }
13707
13708
 
13708
13709
  function isSymbolToken(token, symbolName) {
@@ -13990,6 +13991,11 @@ var Parser = /** @class */ (function () {
13990
13991
  this.parseState.position += 1;
13991
13992
  };
13992
13993
  Parser.prototype.parse = function () {
13994
+ this.tokenStream.tokens.forEach(function (token) {
13995
+ if (token[0] === 'Error') {
13996
+ throw new LitsError(token[3], token[2]);
13997
+ }
13998
+ });
13993
13999
  var nodes = [];
13994
14000
  while (!this.isAtEnd()) {
13995
14001
  nodes.push(this.parseExpression(0, true));
@@ -15056,20 +15062,14 @@ var AutoCompleter = /** @class */ (function () {
15056
15062
  this.suggestions = [];
15057
15063
  this.suggestionIndex = null;
15058
15064
  var partialProgram = this.originalProgram.slice(0, this.originalPosition);
15059
- var tokenStream = null;
15060
- try {
15061
- tokenStream = lits.tokenize(partialProgram);
15062
- }
15063
- catch (_a) {
15064
- // do nothing
15065
- }
15066
- if (!tokenStream) {
15067
- return;
15068
- }
15065
+ var tokenStream = lits.tokenize(partialProgram);
15069
15066
  var lastToken = tokenStream.tokens.at(-1);
15070
15067
  if (!lastToken) {
15071
15068
  return;
15072
15069
  }
15070
+ if (lastToken[0] === 'Error') {
15071
+ return;
15072
+ }
15073
15073
  this.searchString = lastToken[1];
15074
15074
  this.prefixProgram = this.originalProgram.slice(0, this.originalPosition - this.searchString.length);
15075
15075
  this.suffixProgram = this.originalProgram.slice(this.prefixProgram.length + this.searchString.length);
@@ -15129,27 +15129,47 @@ var AutoCompleter = /** @class */ (function () {
15129
15129
  };
15130
15130
  AutoCompleter.prototype.generateSuggestions = function (params) {
15131
15131
  var _this = this;
15132
+ var blacklist = new Set(['0_def', '0_defn', '0_fn']);
15133
+ var startsWithCaseSensitive = this.generateWithPredicate(params, function (suggestion) {
15134
+ return !blacklist.has(suggestion) && suggestion.startsWith(_this.searchString);
15135
+ });
15136
+ startsWithCaseSensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15137
+ var startsWithCaseInsensitive = this.generateWithPredicate(params, function (suggestion) {
15138
+ return !blacklist.has(suggestion) && suggestion.toLowerCase().startsWith(_this.searchString.toLowerCase());
15139
+ });
15140
+ startsWithCaseInsensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15141
+ var includesCaseSensitive = this.generateWithPredicate(params, function (suggestion) {
15142
+ return !blacklist.has(suggestion) && suggestion.includes(_this.searchString);
15143
+ });
15144
+ includesCaseSensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15145
+ var includesCaseInsensitive = this.generateWithPredicate(params, function (suggestion) {
15146
+ return !blacklist.has(suggestion) && suggestion.includes(_this.searchString.toLowerCase());
15147
+ });
15148
+ includesCaseInsensitive.forEach(function (suggestion) { return blacklist.add(suggestion); });
15149
+ return __spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(startsWithCaseSensitive), false), __read(startsWithCaseInsensitive), false), __read(includesCaseSensitive), false), __read(includesCaseInsensitive), false);
15150
+ };
15151
+ AutoCompleter.prototype.generateWithPredicate = function (params, shouldInclude) {
15132
15152
  var _a, _b, _c, _d;
15133
15153
  var suggestions = new Set();
15134
- litsCommands.forEach(function (name) {
15135
- if (name.startsWith(_this.searchString)) {
15136
- suggestions.add(name);
15154
+ litsCommands.forEach(function (suggestion) {
15155
+ if (shouldInclude(suggestion)) {
15156
+ suggestions.add(suggestion);
15137
15157
  }
15138
15158
  });
15139
15159
  Object.keys((_a = params.globalContext) !== null && _a !== void 0 ? _a : {})
15140
- .filter(function (name) { return name.startsWith(_this.searchString); })
15141
- .forEach(function (name) { return suggestions.add(name); });
15160
+ .filter(shouldInclude)
15161
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15142
15162
  (_b = params.contexts) === null || _b === void 0 ? void 0 : _b.forEach(function (context) {
15143
15163
  Object.keys(context)
15144
- .filter(function (name) { return name.startsWith(_this.searchString); })
15145
- .forEach(function (name) { return suggestions.add(name); });
15164
+ .filter(shouldInclude)
15165
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15146
15166
  });
15147
15167
  Object.keys((_c = params.jsFunctions) !== null && _c !== void 0 ? _c : {})
15148
- .filter(function (name) { return name.startsWith(_this.searchString); })
15149
- .forEach(function (name) { return suggestions.add(name); });
15168
+ .filter(shouldInclude)
15169
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15150
15170
  Object.keys((_d = params.values) !== null && _d !== void 0 ? _d : {})
15151
- .filter(function (name) { return name.startsWith(_this.searchString); })
15152
- .forEach(function (name) { return suggestions.add(name); });
15171
+ .filter(shouldInclude)
15172
+ .forEach(function (suggestion) { return suggestions.add(suggestion); });
15153
15173
  return __spreadArray([], __read(suggestions), false).sort(function (a, b) { return a.localeCompare(b); });
15154
15174
  };
15155
15175
  return AutoCompleter;