Improve REPL directive support (#348)
* Improve REPL directive support - use . on column 0 as directive prefix - use `directives` object properties for genericity - accept non ambiguous directive abbreviations - reject invalid directive with extra characters - simplify `handle_directive` and `handle_cmd` - document ".help" instead of "\h" - document ".load"
This commit is contained in:
parent
d308a13579
commit
f62b90daa2
2 changed files with 7081 additions and 7062 deletions
14011
gen/repl.c
14011
gen/repl.c
File diff suppressed because it is too large
Load diff
132
repl.js
132
repl.js
|
@ -217,7 +217,7 @@ import * as os from "os";
|
||||||
var style = style_names[i = j];
|
var style = style_names[i = j];
|
||||||
while (++j < str.length && style_names[j] == style)
|
while (++j < str.length && style_names[j] == style)
|
||||||
continue;
|
continue;
|
||||||
std.puts(colors[styles[style] || 'default']);
|
std.puts(colors[styles[style] || 'none']);
|
||||||
std.puts(str.substring(i, j));
|
std.puts(str.substring(i, j));
|
||||||
std.puts(colors['none']);
|
std.puts(colors['none']);
|
||||||
}
|
}
|
||||||
|
@ -561,11 +561,11 @@ import * as os from "os";
|
||||||
if (pos <= 0)
|
if (pos <= 0)
|
||||||
return g;
|
return g;
|
||||||
var c = line[pos - 1];
|
var c = line[pos - 1];
|
||||||
if (pos === 1 && c === '\\')
|
if (pos === 1 && (c === '\\' || c === '.'))
|
||||||
return directives;
|
return directives;
|
||||||
if ("'\"`@#)]}\\".indexOf(c) >= 0)
|
if ("'\"`@#)]}\\".indexOf(c) >= 0)
|
||||||
return void 0;
|
return void 0;
|
||||||
if (pos >= 2 && c === ".") {
|
if (c === ".") {
|
||||||
pos--;
|
pos--;
|
||||||
switch (c = line[pos - 1]) {
|
switch (c = line[pos - 1]) {
|
||||||
case '\'':
|
case '\'':
|
||||||
|
@ -1002,60 +1002,73 @@ import * as os from "os";
|
||||||
}
|
}
|
||||||
print_rec(a);
|
print_rec(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
function extract_directive(a) {
|
|
||||||
var pos;
|
|
||||||
if (a[0] !== '\\')
|
|
||||||
return "";
|
|
||||||
for (pos = 1; pos < a.length; pos++) {
|
|
||||||
if (!is_alpha(a[pos]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return a.substring(1, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return true if the string after cmd can be evaluted as JS */
|
/* return true if the string was a directive */
|
||||||
function handle_directive(cmd, expr) {
|
function handle_directive(a) {
|
||||||
if (cmd === "h" || cmd === "?" || cmd == "help") {
|
var pos;
|
||||||
|
if (a === "?") {
|
||||||
help();
|
help();
|
||||||
} else if (cmd === "load") {
|
return true;
|
||||||
var filename = expr.substring(cmd.length + 1).trim();
|
}
|
||||||
if (filename.lastIndexOf(".") <= filename.lastIndexOf("/"))
|
if (a[0] !== '\\' && a[0] !== '.')
|
||||||
filename += ".js";
|
|
||||||
std.loadScript(filename);
|
|
||||||
return false;
|
return false;
|
||||||
} else if (cmd === "x") {
|
var pos = 1;
|
||||||
hex_mode = true;
|
while (pos < a.length && a[pos] !== ' ') {
|
||||||
} else if (cmd === "d") {
|
pos++;
|
||||||
hex_mode = false;
|
}
|
||||||
} else if (cmd === "t") {
|
var cmd = a.substring(1, pos);
|
||||||
show_time = !show_time;
|
var partial = 0;
|
||||||
} else if (cmd === "clear") {
|
var fun;
|
||||||
std.puts("\x1b[H\x1b[J");
|
for (var p in directives) {
|
||||||
} else if (cmd === "q") {
|
if (p.startsWith(cmd)) {
|
||||||
std.exit(0);
|
fun = directives[p];
|
||||||
|
partial++;
|
||||||
|
if (p === cmd) {
|
||||||
|
partial = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fun && partial < 2) {
|
||||||
|
fun(a.substring(pos).trim());
|
||||||
} else {
|
} else {
|
||||||
std.puts("Unknown directive: " + cmd + "\n");
|
std.puts(`Unknown directive: ${cmd}\n`);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function help() {
|
function help() {
|
||||||
function sel(n) {
|
var sel = (n) => n ? "*": " ";
|
||||||
return n ? "*": " ";
|
std.puts(".help print this help\n" +
|
||||||
}
|
".x " + sel(hex_mode) + "hexadecimal number display\n" +
|
||||||
std.puts("\\h this help\n" +
|
".dec " + sel(!hex_mode) + "decimal number display\n" +
|
||||||
"\\x " + sel(hex_mode) + "hexadecimal number display\n" +
|
".time " + sel(show_time) + "toggle timing display\n" +
|
||||||
"\\d " + sel(!hex_mode) + "decimal number display\n" +
|
".color " + sel(show_colors) + "toggle colored output\n" +
|
||||||
"\\t " + sel(show_time) + "toggle timing display\n" +
|
".clear clear the terminal\n" +
|
||||||
"\\clear clear the terminal\n" +
|
".load load source code from a file\n" +
|
||||||
"\\q exit\n");
|
".quit exit\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function load(s) {
|
||||||
|
if (s.lastIndexOf(".") <= s.lastIndexOf("/"))
|
||||||
|
s += ".js";
|
||||||
|
std.loadScript(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_bool(s, def) {
|
||||||
|
return s ? "1 true yes Yes".includes(s) : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
var directives = Object.setPrototypeOf({
|
var directives = Object.setPrototypeOf({
|
||||||
h: "h", help: "help", load: "load", x: "x", d: "d", t: "t",
|
"help": help,
|
||||||
clear: "clear", q: "q" }, null);
|
"load": load,
|
||||||
|
"x": (s) => { hex_mode = to_bool(s, true); },
|
||||||
|
"dec": (s) => { hex_mode = !to_bool(s, true); },
|
||||||
|
"time": (s) => { show_time = to_bool(s, !show_time); },
|
||||||
|
"color": (s) => { show_colors = to_bool(s, !show_colors); },
|
||||||
|
"clear": () => { std.puts("\x1b[H\x1b[J") },
|
||||||
|
"quit": () => { std.exit(0); },
|
||||||
|
}, null);
|
||||||
|
|
||||||
function eval_and_print(expr) {
|
function eval_and_print(expr) {
|
||||||
var result;
|
var result;
|
||||||
|
@ -1089,7 +1102,7 @@ import * as os from "os";
|
||||||
}
|
}
|
||||||
|
|
||||||
function cmd_start() {
|
function cmd_start() {
|
||||||
std.puts('QuickJS-ng - Type "\\h" for help\n');
|
std.puts('QuickJS-ng - Type ".help" for help\n');
|
||||||
cmd_readline_start();
|
cmd_readline_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,28 +1116,15 @@ import * as os from "os";
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_cmd(expr) {
|
function handle_cmd(expr) {
|
||||||
var colorstate, cmd;
|
if (!expr)
|
||||||
|
|
||||||
if (expr === null) {
|
|
||||||
expr = "";
|
|
||||||
return;
|
return;
|
||||||
}
|
if (mexpr) {
|
||||||
if (expr === "?") {
|
|
||||||
help();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cmd = extract_directive(expr);
|
|
||||||
if (cmd.length > 0) {
|
|
||||||
if (!handle_directive(cmd, expr))
|
|
||||||
return;
|
|
||||||
expr = expr.substring(cmd.length + 1);
|
|
||||||
}
|
|
||||||
if (expr === "")
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mexpr)
|
|
||||||
expr = mexpr + '\n' + expr;
|
expr = mexpr + '\n' + expr;
|
||||||
colorstate = colorize_js(expr);
|
} else {
|
||||||
|
if (handle_directive(expr))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var colorstate = colorize_js(expr);
|
||||||
pstate = colorstate[0];
|
pstate = colorstate[0];
|
||||||
level = colorstate[1];
|
level = colorstate[1];
|
||||||
if (pstate) {
|
if (pstate) {
|
||||||
|
|
Loading…
Reference in a new issue