TypeScript: step 4
[jackhill/mal.git] / ts / node_readline.ts
1 import * as path from "path";
2 import * as ffi from "ffi";
3 import * as fs from "fs";
4
5 // IMPORTANT: choose one
6 const RL_LIB = "libreadline"; // NOTE: libreadline is GPL
7 //var RL_LIB = "libedit";
8
9 const HISTORY_FILE = path.join(process.env.HOME, ".mal-history");
10
11 const rllib = ffi.Library(RL_LIB, {
12 "readline": ["string", ["string"]],
13 "add_history": ["int", ["string"]],
14 });
15
16 let rlHistoryLoaded = false;
17
18 export function readline(prompt?: string): string | null {
19 prompt = prompt || "user> ";
20
21 if (!rlHistoryLoaded) {
22 rlHistoryLoaded = true;
23 let lines: string[] = [];
24 if (fs.existsSync(HISTORY_FILE)) {
25 lines = fs.readFileSync(HISTORY_FILE).toString().split("\n");
26 }
27 // Max of 2000 lines
28 lines = lines.slice(Math.max(lines.length - 2000, 0));
29 for (let i = 0; i < lines.length; i++) {
30 if (lines[i]) { rllib.add_history(lines[i]); }
31 }
32 }
33
34 const line = rllib.readline(prompt);
35 if (line) {
36 rllib.add_history(line);
37 try {
38 fs.appendFileSync(HISTORY_FILE, line + "\n");
39 } catch (exc) {
40 // ignored
41 }
42 }
43
44 return line;
45 };