-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
122 lines (100 loc) · 3.09 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const repl = require("repl");
const util = require("util");
const path = require("path");
const package = require("./package.json");
const readlineVim = require("readline-vim");
const dayjs = require("dayjs");
require("@colors/colors");
require("./fp.js");
class Item {
/**
* @param {string} icon
* @param {keyof import("@colors/colors").Color} color
*/
constructor(icon, color) {
this.icon = icon;
this.color = color;
}
/** @returns {typeof this.icon} */
get coloredIcon() {
return this.icon[this.color];
}
}
/** @constant */
const items = {
js: new Item("", "yellow"),
prompt: {
insert: new Item(">=>", "green"),
normal: new Item("<=<", "cyan"),
},
error: new Item("", "red"),
output: new Item("->", "blue"),
node: new Item("", "green"),
welcomeBar: {
leftCorner: new Item("", "green"),
rightCorner: new Item("", "green"),
},
};
const logEmptyLine = () => console.log("");
const logWelcome = () => {
const {
welcomeBar: { leftCorner, rightCorner },
} = items;
const nodeVersion = process.version;
const content = ` ${items.node.icon} ${nodeVersion} `.brightWhite.bgGreen;
const bar = leftCorner.coloredIcon + content + rightCorner.coloredIcon;
console.log(`${bar} ${package.version}`);
};
logEmptyLine();
logWelcome();
/**
* @param {keyof typeof items["prompt"]} mode
* @returns {string}
*/
const getPrompt = (mode) => {
const { js, prompt } = items;
const promptMode = prompt[mode];
return `${js.coloredIcon} ${promptMode.coloredIcon} `;
};
const prompt = getPrompt("insert");
const writeOutput = (output) => {
const inspectedOutput = util.inspect(output, { colors: true, depth: 20 });
return `${items.output.coloredIcon} ${inspectedOutput}\n`;
};
const writeError = (output) => `${items.error.coloredIcon} ${output.toString().red}\n\n`;
const isOutputError = (output) => {
if (!output?.toString || typeof output !== "object") return false;
return new RegExp(/\w*Error:?/).test(output.toString());
};
const writer = (output) => (isOutputError(output) ? writeError(output) : writeOutput(output));
const replServer = repl.start({
prompt,
useColors: true,
replMode: repl.REPL_MODE_STRICT,
writer,
});
replServer.setupHistory(path.resolve(__dirname, "./history.txt"), (error) => {
if (error) throw error;
});
replServer.context.dayjs = dayjs;
const vim = readlineVim(replServer);
vim.events.on("normal", () => {
replServer.setPrompt(getPrompt("normal"));
});
vim.events.on("insert", () => {
replServer.setPrompt(getPrompt("insert"));
});
// FIXME: make normal mode when pressing "shift-space"
// vim.map.insert("meta-space", "esc");
// vim.map.insert("shift-space", "esc");
// vim.map.insert("space", "esc");
vim.map.insert("ctrl-space", "esc");
vim.map.insert("ctrl-c", "esc");
// console.log(vim.map);
/* process.stdin.on("keypress", (ch, key) => {
console.log('got "keypress"', ch, key);
// if (!key || !key.ctrl || key.name !== 'c') return;
// process.stdin.pause();
}); */
// TODO: https://stackoverflow.com/questions/62323316/how-to-modify-cursor-line-in-node-js-readline
// make syntax highlighting