Improve completion in REPL (#343)
* Improve completion in REPL - refine `get_context_object` to avoid throwing errors (eg: q.<TAB>) - do not call `eval` in `get_context_object` to avoid throwing errors and reduce bloat caused by variable closures. - support completion of directives
This commit is contained in:
parent
02c06d0036
commit
fd99929f5d
2 changed files with 11605 additions and 11475 deletions
23017
gen/repl.c
23017
gen/repl.c
File diff suppressed because it is too large
Load diff
63
repl.js
63
repl.js
|
@ -551,51 +551,60 @@ import * as os from "os";
|
|||
cursor_pos = 0;
|
||||
}
|
||||
|
||||
function get_context_word(line, pos) {
|
||||
var s = "";
|
||||
while (pos > 0 && is_word(line[pos - 1])) {
|
||||
function get_context_word(line, end) {
|
||||
var pos = end;
|
||||
while (pos > 0 && is_word(line[pos - 1]))
|
||||
pos--;
|
||||
s = line[pos] + s;
|
||||
}
|
||||
return s;
|
||||
return line.slice(pos, end);
|
||||
}
|
||||
function get_context_object(line, pos) {
|
||||
var obj, base, c;
|
||||
if (pos <= 0 || " ~!%^&*(-+={[|:;,<>?/".indexOf(line[pos - 1]) >= 0)
|
||||
if (pos <= 0)
|
||||
return g;
|
||||
if (pos >= 2 && line[pos - 1] === ".") {
|
||||
var c = line[pos - 1];
|
||||
if (pos === 1 && c === '\\')
|
||||
return directives;
|
||||
if ("'\"`@#)]}\\".indexOf(c) >= 0)
|
||||
return void 0;
|
||||
if (pos >= 2 && c === ".") {
|
||||
pos--;
|
||||
obj = {};
|
||||
switch (c = line[pos - 1]) {
|
||||
case '\'':
|
||||
case '\"':
|
||||
case '`':
|
||||
return "a";
|
||||
case ']':
|
||||
return [];
|
||||
case '}':
|
||||
return {};
|
||||
return []; // incorrect for a[b].<TAB>
|
||||
case '/':
|
||||
return / /;
|
||||
default:
|
||||
if (is_word(c)) {
|
||||
base = get_context_word(line, pos);
|
||||
if (["true", "false", "null", "this"].includes(base) || !isNaN(+base))
|
||||
return eval(base);
|
||||
// Check if `base` is a set of regexp flags
|
||||
if (pos - base.length >= 3 && line[pos - base.length - 1] === '/')
|
||||
return new RegExp('', base);
|
||||
obj = get_context_object(line, pos - base.length);
|
||||
var base = get_context_word(line, pos);
|
||||
var base_pos = pos - base.length;
|
||||
if (base === 'true' || base === 'false')
|
||||
return true;
|
||||
if (base === 'null')
|
||||
return null;
|
||||
if (base === 'this')
|
||||
return g;
|
||||
if (!isNaN(+base)) // number literal, incorrect for 1.<TAB>
|
||||
return 0;
|
||||
var obj = get_context_object(line, base_pos);
|
||||
if (obj === null || obj === void 0)
|
||||
return obj;
|
||||
if (obj === g && obj[base] === void 0)
|
||||
return eval(base);
|
||||
else
|
||||
if (typeof obj[base] !== 'undefined')
|
||||
return obj[base];
|
||||
// Check if `base` is a set of regexp flags
|
||||
// TODO(chqrlie): this is incorrect for a/i<TAB>...
|
||||
// Should use colorizer to determine the token type
|
||||
if (base_pos >= 3 && line[base_pos - 1] === '/' && base.match(/^[dgimsuvy]+$/))
|
||||
return RegExp();
|
||||
// base is a local identifier, complete as generic object
|
||||
}
|
||||
return {};
|
||||
break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
return void 0;
|
||||
return g;
|
||||
}
|
||||
|
||||
function get_completions(line, pos) {
|
||||
|
@ -1044,6 +1053,10 @@ import * as os from "os";
|
|||
"\\q exit\n");
|
||||
}
|
||||
|
||||
var directives = Object.setPrototypeOf({
|
||||
h: "h", help: "help", load: "load", x: "x", d: "d", t: "t",
|
||||
clear: "clear", q: "q" }, null);
|
||||
|
||||
function eval_and_print(expr) {
|
||||
var result;
|
||||
|
||||
|
|
Loading…
Reference in a new issue