-
Notifications
You must be signed in to change notification settings - Fork 6
/
code-pane.mjs
115 lines (103 loc) · 3.6 KB
/
code-pane.mjs
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
import fetch from "node-fetch";
import {
printAt,
renderText
} from "./term-utils.mjs";
import { ScrollableTextPane } from "./scrollable-text-pane.mjs";
import StyledString from "styled_string";
import { inspect } from "util";
export function CodePane(db, box) {
const self = {
unsetStep,
updateStep,
updateDisplay,
get textPane() { return textPane },
showCurrentLine() { scrollCodeIfNeeded() },
getLineNoForY
};
const log = db.log;
const textPane = ScrollableTextPane(db, box);
const cache = db.cache;
let codeLines = [];
let codeFileId = null;
function unsetStep() {
const codeFile = getCodeFile();
if (codeFile) {
textPane.updateLine(db.snapshot.line_no - 1,
" " + codeLines[db.snapshot.line_no - 1]);
}
}
function updateStep() {
const codeFile = getCodeFile();
if (codeFile) {
//log.write(`snapshot: ${JSON.stringify(db.snapshot)}\n`);
const arrow = "→";
const displayLine = (arrow + codeLines[db.snapshot.line_no - 1])
.padEnd(textPane.longestLineLength, " ");
//log.write(`displayLine: ${displayLine}\n`);
textPane.updateLine(db.snapshot.line_no - 1,
StyledString(displayLine, {
background: "white",
foreground: "black"
}));
} else {
const funCall = cache.getFunCall(db.snapshot.fun_call_id);
const fun = cache.getFun(funCall.fun_id);
codeLines = [`${fun.name}() line ${db.snapshot.line_no}. No source code available :(`];
textPane.updateAllLines(codeLines);
}
}
function scrollCodeIfNeeded() {
const line = db.snapshot.line_no;
let offset = textPane.scrollTopOffset;
if (line > (offset + box.height - 1)) {
offset = Math.min(
codeLines.length - box.height,
line - Math.floor(box.height / 2)
);
}
if (line < (offset + 1)) {
offset = Math.max(0, line - Math.floor(box.height / 2));
}
textPane.scrollTopTo(offset);
}
function getFunCall() {
return cache.getFunCall(db.snapshot.fun_call_id);
}
function getCodeFile() {
const funCall = getFunCall();
const fun = cache.getFun(funCall.fun_id);
if (fun.code_file_id) {
const codeFile = cache.getCodeFile(fun.code_file_id);
return codeFile;
}
return null;
}
function updateCodeDisplay() {
const funCall = getFunCall();
if (funCall.code_file_id !== codeFileId) {
const codeFile = getCodeFile();
if (codeFile) {
codeLines = codeFile.source.split("\n");
// convert tabs to 4 spaces...
codeLines = codeLines.map((line) => line.replace(/\t/g, ' '));
codeFileId = codeFile.id;
} else {
const funCall = getFunCall();
const fun = cache.getFun(funCall.fun_id);
codeLines = [`${fun.name}() line ${db.snapshot.line_no}. No source code available :(`];
codeFileId = null;
}
textPane.updateAllLines(codeLines.map((line) => " " + line));
}
}
function getLineNoForY(y) {
return y + textPane.scrollTopOffset;
}
function updateDisplay() {
updateCodeDisplay();
scrollCodeIfNeeded();
updateStep();
}
return self;
}