@vemjs/renderer-vecto 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/CommandBar.d.ts.map +1 -1
- package/dist/CommandBar.js +6 -1
- package/dist/CommandBar.js.map +1 -1
- package/dist/VemEditorEntity.d.ts.map +1 -1
- package/dist/VemEditorEntity.js +216 -37
- package/dist/VemEditorEntity.js.map +1 -1
- package/dist/WorkspaceExplorer.d.ts +6 -1
- package/dist/WorkspaceExplorer.d.ts.map +1 -1
- package/dist/WorkspaceExplorer.js +98 -8
- package/dist/WorkspaceExplorer.js.map +1 -1
- package/package.json +1 -1
- package/src/CommandBar.ts +8 -1
- package/src/VemEditorEntity.ts +266 -38
- package/src/WorkspaceExplorer.ts +111 -8
|
@@ -45,6 +45,22 @@ export class WorkspaceExplorer extends UIComponent {
|
|
|
45
45
|
onDidOpenDirectory(cb) {
|
|
46
46
|
this.openDirectoryCallbacks.push(cb);
|
|
47
47
|
}
|
|
48
|
+
flattenFiles(nodes) {
|
|
49
|
+
const list = [];
|
|
50
|
+
const recurse = (nodeList, prefix) => {
|
|
51
|
+
for (const node of nodeList) {
|
|
52
|
+
const path = prefix ? `${prefix}/${node.label}` : node.label;
|
|
53
|
+
if (node.children && node.children.length > 0) {
|
|
54
|
+
recurse(node.children, path);
|
|
55
|
+
}
|
|
56
|
+
else if (!node.children || node.children.length === 0) {
|
|
57
|
+
list.push(path);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
recurse(nodes, '');
|
|
62
|
+
return list;
|
|
63
|
+
}
|
|
48
64
|
async handleOpenFolder() {
|
|
49
65
|
if (typeof window === 'undefined' || !window.showDirectoryPicker) {
|
|
50
66
|
console.warn('File System Access API is not supported in this environment.');
|
|
@@ -53,6 +69,12 @@ export class WorkspaceExplorer extends UIComponent {
|
|
|
53
69
|
try {
|
|
54
70
|
const rootHandle = await window.showDirectoryPicker();
|
|
55
71
|
const nodes = await this.fsHandler.readDirectory(rootHandle);
|
|
72
|
+
// Cache all file paths for search plugins (like Telescope)
|
|
73
|
+
const fileList = this.flattenFiles(nodes);
|
|
74
|
+
const activeState = this.getActiveEditorState();
|
|
75
|
+
if (activeState) {
|
|
76
|
+
activeState.projectFiles = fileList;
|
|
77
|
+
}
|
|
56
78
|
this.treeView = new TreeView({
|
|
57
79
|
nodes,
|
|
58
80
|
width: this.leftPanel.width,
|
|
@@ -85,8 +107,58 @@ export class WorkspaceExplorer extends UIComponent {
|
|
|
85
107
|
console.error('Error selecting directory:', err);
|
|
86
108
|
}
|
|
87
109
|
}
|
|
110
|
+
getActiveEditorState() {
|
|
111
|
+
return this.workspace.getActiveLayout()?.getActiveState() || null;
|
|
112
|
+
}
|
|
113
|
+
lastSidebarPosition = 'left';
|
|
114
|
+
lastSidebarWidth = 240;
|
|
115
|
+
syncLayout(activeState) {
|
|
116
|
+
const layout = activeState.layoutConfig;
|
|
117
|
+
this.remove(this.panelGroup);
|
|
118
|
+
this.panelGroup = new PanelGroup({
|
|
119
|
+
direction: 'horizontal',
|
|
120
|
+
width: this.width,
|
|
121
|
+
height: this.height,
|
|
122
|
+
});
|
|
123
|
+
this.leftPanel = new Panel({
|
|
124
|
+
minSize: 150,
|
|
125
|
+
defaultSize: layout.sidebarWidth / Math.max(1, this.width),
|
|
126
|
+
});
|
|
127
|
+
this.rightPanel = new Panel({ minSize: 300 });
|
|
128
|
+
if (layout.sidebarPosition === 'left') {
|
|
129
|
+
this.leftPanel.add(this.openBtn);
|
|
130
|
+
if (this.treeView)
|
|
131
|
+
this.leftPanel.add(this.treeView);
|
|
132
|
+
this.rightPanel.add(this.workspace);
|
|
133
|
+
this.panelGroup.addPanel(this.leftPanel);
|
|
134
|
+
this.panelGroup.addPanel(this.rightPanel);
|
|
135
|
+
}
|
|
136
|
+
else if (layout.sidebarPosition === 'right') {
|
|
137
|
+
this.leftPanel.add(this.openBtn);
|
|
138
|
+
if (this.treeView)
|
|
139
|
+
this.leftPanel.add(this.treeView);
|
|
140
|
+
this.rightPanel.add(this.workspace);
|
|
141
|
+
this.panelGroup.addPanel(this.rightPanel);
|
|
142
|
+
this.panelGroup.addPanel(this.leftPanel);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
this.rightPanel.add(this.workspace);
|
|
146
|
+
this.panelGroup.addPanel(this.rightPanel);
|
|
147
|
+
}
|
|
148
|
+
this.add(this.panelGroup);
|
|
149
|
+
}
|
|
88
150
|
update(dt, time) {
|
|
89
151
|
super.update(dt, time);
|
|
152
|
+
const activeState = this.getActiveEditorState();
|
|
153
|
+
if (activeState) {
|
|
154
|
+
const layout = activeState.layoutConfig;
|
|
155
|
+
if (layout.sidebarPosition !== this.lastSidebarPosition ||
|
|
156
|
+
layout.sidebarWidth !== this.lastSidebarWidth) {
|
|
157
|
+
this.lastSidebarPosition = layout.sidebarPosition;
|
|
158
|
+
this.lastSidebarWidth = layout.sidebarWidth;
|
|
159
|
+
this.syncLayout(activeState);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
90
162
|
if (this.panelGroup.width !== this.width || this.panelGroup.height !== this.height) {
|
|
91
163
|
this.panelGroup.width = this.width;
|
|
92
164
|
this.panelGroup.height = this.height;
|
|
@@ -102,14 +174,32 @@ export class WorkspaceExplorer extends UIComponent {
|
|
|
102
174
|
this.workspace.height = this.rightPanel.height;
|
|
103
175
|
}
|
|
104
176
|
}
|
|
105
|
-
render(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
177
|
+
render(r) {
|
|
178
|
+
const activeState = this.getActiveEditorState();
|
|
179
|
+
if (!activeState)
|
|
180
|
+
return;
|
|
181
|
+
const theme = activeState.theme;
|
|
182
|
+
const layout = activeState.layoutConfig;
|
|
183
|
+
// Apply button styling
|
|
184
|
+
this.openBtn.bg = theme.statusBarBg;
|
|
185
|
+
this.openBtn.hoverBg = theme.statusBarBg;
|
|
186
|
+
this.openBtn.color = theme.fg;
|
|
187
|
+
if (this.treeView) {
|
|
188
|
+
/* eslint-disable-next-line no-underscore-dangle */
|
|
189
|
+
this.treeView._color = theme.fg;
|
|
190
|
+
/* eslint-disable-next-line no-underscore-dangle */
|
|
191
|
+
this.treeView._selColor = theme.accent + '33';
|
|
192
|
+
}
|
|
193
|
+
if (layout.sidebarPosition !== 'hidden') {
|
|
194
|
+
const startX = layout.sidebarPosition === 'left' ? 0 : this.width - this.leftPanel.width;
|
|
195
|
+
r.beginPath();
|
|
196
|
+
r.moveTo(startX, 0);
|
|
197
|
+
r.lineTo(startX + this.leftPanel.width, 0);
|
|
198
|
+
r.lineTo(startX + this.leftPanel.width, this.height);
|
|
199
|
+
r.lineTo(startX, this.height);
|
|
200
|
+
r.closePath();
|
|
201
|
+
r.fill(theme.sidebarBg);
|
|
202
|
+
}
|
|
113
203
|
}
|
|
114
204
|
}
|
|
115
205
|
//# sourceMappingURL=WorkspaceExplorer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceExplorer.js","sourceRoot":"","sources":["../src/WorkspaceExplorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,OAAO,iBAAkB,SAAQ,WAAW;IACxC,UAAU,CAAa;IACvB,SAAS,CAAQ;IACjB,UAAU,CAAQ;IAClB,SAAS,CAAe;IACxB,QAAQ,GAAoB,IAAI,CAAC;IACjC,OAAO,CAAS;IAChB,SAAS,CAAoB;IAC7B,sBAAsB,GAGC,EAAE,CAAC;IAElC,YAAY,KAAa,EAAE,MAAc,EAAE,WAAoB;QAC7D,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,iBAAiB,EAAE,CAAC;QAEzC,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC;YAC/B,SAAS,EAAE,YAAY;YACvB,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,GAAG,IAAI,KAAK,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,GAAG,IAAI,KAAK,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAE9C,IAAI,CAAC,SAAS,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAEpE,IAAI,CAAC,OAAO,GAAG,IAAI,MAAM,CAAC,aAAa,EAAE;YACvC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE;YACtC,EAAE,EAAE,SAAS,EAAE,YAAY;YAC3B,OAAO,EAAE,SAAS;YAClB,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEpC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAEM,YAAY;QACjB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEM,kBAAkB,CACvB,EAAwE;QAExE,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAE,MAAc,CAAC,mBAAmB,EAAE,CAAC;YAC1E,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;YAC7E,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAO,MAAc,CAAC,mBAAmB,EAAE,CAAC;YAC/D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YAE7D,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC;gBAC3B,KAAK;gBACL,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,EAAE;gBACxB,IAAI,EAAE,gBAAgB;gBACtB,KAAK,EAAE,SAAS;gBAChB,aAAa,EAAE,yBAAyB;gBACxC,UAAU,EAAE,2BAA2B;gBACvC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;oBACvB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACzD,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;wBAC1D,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBACjC,CAAC;gBACH,CAAC;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAElC,qCAAqC;YACrC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC7C,IAAI,CAAC;oBACH,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC5B,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,CAAC,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,EAAU,EAAE,IAAY;QACpC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAEvB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YACnF,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACnC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACvC,CAAC;QAED,IACE,IAAI,CAAC,QAAQ;YACb,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,EACtF,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACrC,CAAC;QAED,IACE,IAAI,CAAC,SAAS,CAAC,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK;YAC9C,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,UAAU,CAAC,MAAM,EAChD,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAC7C,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QACjD,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"WorkspaceExplorer.js","sourceRoot":"","sources":["../src/WorkspaceExplorer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/CommandBar.ts
CHANGED
|
@@ -58,12 +58,19 @@ export class CommandBar extends UIComponent {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
public render(r: IRenderer): void {
|
|
61
|
+
const theme = this.editorState.theme;
|
|
62
|
+
|
|
63
|
+
// Sync theme colors dynamically
|
|
64
|
+
this.prefixText.color = theme.accent;
|
|
65
|
+
this.input.color = theme.statusBarFg;
|
|
66
|
+
this.input.bg = theme.statusBarBg;
|
|
67
|
+
|
|
61
68
|
r.beginPath();
|
|
62
69
|
r.moveTo(0, 0);
|
|
63
70
|
r.lineTo(this.width, 0);
|
|
64
71
|
r.lineTo(this.width, this.height);
|
|
65
72
|
r.lineTo(0, this.height);
|
|
66
73
|
r.closePath();
|
|
67
|
-
r.fill(
|
|
74
|
+
r.fill(theme.statusBarBg);
|
|
68
75
|
}
|
|
69
76
|
}
|
package/src/VemEditorEntity.ts
CHANGED
|
@@ -57,28 +57,46 @@ export class VemEditorEntity extends UIComponent {
|
|
|
57
57
|
const buffer = this.editorState.getBuffer();
|
|
58
58
|
const cursor = this.editorState.getCursor();
|
|
59
59
|
const lineCount = buffer.getLineCount();
|
|
60
|
+
const theme = this.editorState.theme;
|
|
61
|
+
const layout = this.editorState.layoutConfig;
|
|
60
62
|
|
|
61
63
|
// 1. Calculate gutter width dynamically
|
|
62
64
|
const maxLineDigits = Math.max(2, lineCount.toString().length);
|
|
63
65
|
const gutterWidth = maxLineDigits * this.charWidth + 15;
|
|
64
66
|
|
|
65
|
-
// 2.
|
|
67
|
+
// 2. Sync theme colors
|
|
68
|
+
this.gutterText.color = theme.gutterFg;
|
|
69
|
+
this.bodyText.color = theme.fg;
|
|
70
|
+
|
|
71
|
+
// 3. Set line numbers text
|
|
66
72
|
const lineNums: string[] = [];
|
|
67
73
|
for (let i = 1; i <= lineCount; i++) {
|
|
68
74
|
lineNums.push(i.toString().padStart(maxLineDigits, ' '));
|
|
69
75
|
}
|
|
70
76
|
this.gutterText.setText(lineNums.join('\n'));
|
|
71
|
-
this.gutterText.setPosition(5, 5);
|
|
72
77
|
|
|
73
|
-
//
|
|
74
|
-
const spans =
|
|
78
|
+
// 4. Set editor body text
|
|
79
|
+
const spans: any[] = [];
|
|
80
|
+
const lines = buffer.getLines();
|
|
81
|
+
lines.forEach((line, idx) => {
|
|
75
82
|
const suffix = idx === lineCount - 1 ? '' : '\n';
|
|
76
|
-
|
|
83
|
+
const highlight = (this.editorState as any).highlightLine;
|
|
84
|
+
if (highlight) {
|
|
85
|
+
const lineSpans = highlight(line, idx);
|
|
86
|
+
if (lineSpans.length > 0) {
|
|
87
|
+
const lastSpan = { ...lineSpans[lineSpans.length - 1] };
|
|
88
|
+
lastSpan.text += suffix;
|
|
89
|
+
spans.push(...lineSpans.slice(0, -1), lastSpan);
|
|
90
|
+
} else {
|
|
91
|
+
spans.push({ text: suffix });
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
spans.push({ text: line + suffix });
|
|
95
|
+
}
|
|
77
96
|
});
|
|
78
97
|
this.bodyText.setSpans(spans);
|
|
79
|
-
this.bodyText.setPosition(gutterWidth + 5, 5);
|
|
80
98
|
|
|
81
|
-
//
|
|
99
|
+
// 5. Handle viewport scrolling to keep cursor visible
|
|
82
100
|
const visibleLines = Math.floor((this.height - 35) / this.lineHeight); // reserve 35px for status bar
|
|
83
101
|
if (cursor.line >= this.scrollY + visibleLines) {
|
|
84
102
|
this.scrollY = cursor.line - visibleLines + 1;
|
|
@@ -86,13 +104,9 @@ export class VemEditorEntity extends UIComponent {
|
|
|
86
104
|
this.scrollY = cursor.line;
|
|
87
105
|
}
|
|
88
106
|
|
|
89
|
-
//
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
this.bodyText.setPosition(gutterWidth + 5, 5 + scrollOffsetY);
|
|
93
|
-
|
|
94
|
-
// 5. Handle CommandBar visibility
|
|
95
|
-
if (this.editorState.getMode() === 'COMMAND') {
|
|
107
|
+
// 6. Position and layout based on statusBarPosition
|
|
108
|
+
const hasCommandBar = this.editorState.getMode() === 'COMMAND';
|
|
109
|
+
if (hasCommandBar) {
|
|
96
110
|
if (!this.children.includes(this.commandBar)) {
|
|
97
111
|
this.add(this.commandBar);
|
|
98
112
|
}
|
|
@@ -102,6 +116,17 @@ export class VemEditorEntity extends UIComponent {
|
|
|
102
116
|
this.remove(this.commandBar);
|
|
103
117
|
}
|
|
104
118
|
}
|
|
119
|
+
|
|
120
|
+
const scrollOffsetY = -this.scrollY * this.lineHeight;
|
|
121
|
+
if (layout.statusBarPosition === 'top') {
|
|
122
|
+
this.commandBar.setPosition(0, 0);
|
|
123
|
+
this.gutterText.setPosition(5, 5 + scrollOffsetY + 30);
|
|
124
|
+
this.bodyText.setPosition(gutterWidth + 5, 5 + scrollOffsetY + 30);
|
|
125
|
+
} else {
|
|
126
|
+
this.commandBar.setPosition(0, this.height - 30);
|
|
127
|
+
this.gutterText.setPosition(5, 5 + scrollOffsetY);
|
|
128
|
+
this.bodyText.setPosition(gutterWidth + 5, 5 + scrollOffsetY);
|
|
129
|
+
}
|
|
105
130
|
}
|
|
106
131
|
|
|
107
132
|
public setAutocompleteItems(items: { label: string; detail?: string }[]): void {
|
|
@@ -140,6 +165,9 @@ export class VemEditorEntity extends UIComponent {
|
|
|
140
165
|
}
|
|
141
166
|
|
|
142
167
|
public render(r: IRenderer): void {
|
|
168
|
+
const theme = this.editorState.theme;
|
|
169
|
+
const layout = this.editorState.layoutConfig;
|
|
170
|
+
|
|
143
171
|
// 1. Draw editor background
|
|
144
172
|
r.beginPath();
|
|
145
173
|
r.moveTo(0, 0);
|
|
@@ -147,7 +175,7 @@ export class VemEditorEntity extends UIComponent {
|
|
|
147
175
|
r.lineTo(this.width, this.height);
|
|
148
176
|
r.lineTo(0, this.height);
|
|
149
177
|
r.closePath();
|
|
150
|
-
r.fill(
|
|
178
|
+
r.fill(theme.bg);
|
|
151
179
|
|
|
152
180
|
const lineCount = this.editorState.getBuffer().getLineCount();
|
|
153
181
|
const maxLineDigits = Math.max(2, lineCount.toString().length);
|
|
@@ -160,11 +188,28 @@ export class VemEditorEntity extends UIComponent {
|
|
|
160
188
|
r.lineTo(gutterWidth, this.height);
|
|
161
189
|
r.lineTo(0, this.height);
|
|
162
190
|
r.closePath();
|
|
163
|
-
r.fill(
|
|
191
|
+
r.fill(theme.gutterBg);
|
|
192
|
+
|
|
193
|
+
// Apply scrolling transformation (with offset if statusBar is top)
|
|
194
|
+
const contentOffsetY = layout.statusBarPosition === 'top' ? 30 : 0;
|
|
164
195
|
|
|
165
|
-
// Apply scrolling transformation for cursor and selections
|
|
166
196
|
r.save();
|
|
167
|
-
r.translate(0, -this.scrollY * this.lineHeight);
|
|
197
|
+
r.translate(0, -this.scrollY * this.lineHeight + contentOffsetY);
|
|
198
|
+
|
|
199
|
+
// 2.5. Draw Gutter Decorations (Git diff signs)
|
|
200
|
+
const decs = (this.editorState as any).gutterDecorations;
|
|
201
|
+
if (decs && decs.size > 0) {
|
|
202
|
+
for (let l = 0; l < lineCount; l++) {
|
|
203
|
+
const dec = decs.get(l);
|
|
204
|
+
if (dec) {
|
|
205
|
+
const decY = 5 + l * this.lineHeight;
|
|
206
|
+
r.beginPath();
|
|
207
|
+
r.roundRect(1, decY + 2, 3, this.lineHeight - 4, 1.5);
|
|
208
|
+
r.closePath();
|
|
209
|
+
r.fill(dec.color);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
168
213
|
|
|
169
214
|
// 3. Draw Visual Mode selections
|
|
170
215
|
const selection = this.editorState.getVisualSelection();
|
|
@@ -191,7 +236,7 @@ export class VemEditorEntity extends UIComponent {
|
|
|
191
236
|
r.lineTo(x + w, y + h);
|
|
192
237
|
r.lineTo(x, y + h);
|
|
193
238
|
r.closePath();
|
|
194
|
-
r.fill(
|
|
239
|
+
r.fill(theme.accent + '44'); // Theme accent with 25% opacity
|
|
195
240
|
};
|
|
196
241
|
|
|
197
242
|
if (type === 'line') {
|
|
@@ -259,40 +304,102 @@ export class VemEditorEntity extends UIComponent {
|
|
|
259
304
|
r.lineTo(cursorX + 2, cursorY + this.lineHeight);
|
|
260
305
|
r.lineTo(cursorX, cursorY + this.lineHeight);
|
|
261
306
|
r.closePath();
|
|
262
|
-
r.fill(
|
|
307
|
+
r.fill(theme.accent);
|
|
263
308
|
} else {
|
|
264
309
|
r.moveTo(cursorX, cursorY);
|
|
265
310
|
r.lineTo(cursorX + this.charWidth, cursorY);
|
|
266
311
|
r.lineTo(cursorX + this.charWidth, cursorY + this.lineHeight);
|
|
267
312
|
r.lineTo(cursorX, cursorY + this.lineHeight);
|
|
268
313
|
r.closePath();
|
|
269
|
-
r.fill(
|
|
314
|
+
r.fill(theme.accent + '88'); // 50% opacity accent
|
|
270
315
|
}
|
|
271
316
|
|
|
272
317
|
r.restore(); // Restore scroll transform
|
|
273
318
|
|
|
274
|
-
// 5. Draw status bar
|
|
319
|
+
// 5. Draw status bar
|
|
275
320
|
const statusBarHeight = 30;
|
|
276
|
-
const statusY = this.height - statusBarHeight;
|
|
321
|
+
const statusY = layout.statusBarPosition === 'top' ? 0 : this.height - statusBarHeight;
|
|
277
322
|
r.beginPath();
|
|
278
323
|
r.moveTo(0, statusY);
|
|
279
324
|
r.lineTo(this.width, statusY);
|
|
280
|
-
r.lineTo(this.width,
|
|
281
|
-
r.lineTo(0,
|
|
325
|
+
r.lineTo(this.width, statusY + statusBarHeight);
|
|
326
|
+
r.lineTo(0, statusY + statusBarHeight);
|
|
282
327
|
r.closePath();
|
|
283
|
-
r.fill(
|
|
328
|
+
r.fill(theme.statusBarBg);
|
|
329
|
+
|
|
330
|
+
const sl = this.editorState.statuslineLayout;
|
|
331
|
+
if (
|
|
332
|
+
mode !== 'COMMAND' &&
|
|
333
|
+
((sl.left && sl.left.length > 0) || (sl.right && sl.right.length > 0))
|
|
334
|
+
) {
|
|
335
|
+
// Custom statusline layout (lualine-like)
|
|
336
|
+
let startX = 0;
|
|
337
|
+
if (sl.left) {
|
|
338
|
+
for (const segment of sl.left) {
|
|
339
|
+
const textWidth = (r as any).measureText
|
|
340
|
+
? (r as any).measureText(segment.text).width
|
|
341
|
+
: segment.text.length * 8;
|
|
342
|
+
const font = segment.bold ? 'bold 12px monospace' : '12px monospace';
|
|
343
|
+
const color = segment.color || theme.statusBarFg;
|
|
344
|
+
|
|
345
|
+
if (segment.bg) {
|
|
346
|
+
const blockWidth = textWidth + 20;
|
|
347
|
+
r.beginPath();
|
|
348
|
+
r.moveTo(startX, statusY);
|
|
349
|
+
r.lineTo(startX + blockWidth, statusY);
|
|
350
|
+
r.lineTo(startX + blockWidth, statusY + statusBarHeight);
|
|
351
|
+
r.lineTo(startX, statusY + statusBarHeight);
|
|
352
|
+
r.closePath();
|
|
353
|
+
r.fill(segment.bg);
|
|
354
|
+
|
|
355
|
+
r.fillText(segment.text, startX + 10, statusY + 18, font, color);
|
|
356
|
+
startX += blockWidth;
|
|
357
|
+
} else {
|
|
358
|
+
r.fillText(segment.text, startX + 10, statusY + 18, font, color);
|
|
359
|
+
startX += textWidth + 15;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
284
363
|
|
|
285
|
-
|
|
364
|
+
let endX = this.width;
|
|
365
|
+
if (sl.right) {
|
|
366
|
+
for (const segment of sl.right) {
|
|
367
|
+
const textWidth = (r as any).measureText
|
|
368
|
+
? (r as any).measureText(segment.text).width
|
|
369
|
+
: segment.text.length * 8;
|
|
370
|
+
const font = segment.bold ? 'bold 12px monospace' : '12px monospace';
|
|
371
|
+
const color = segment.color || theme.statusBarFg;
|
|
372
|
+
|
|
373
|
+
if (segment.bg) {
|
|
374
|
+
const blockWidth = textWidth + 20;
|
|
375
|
+
endX -= blockWidth;
|
|
376
|
+
r.beginPath();
|
|
377
|
+
r.moveTo(endX, statusY);
|
|
378
|
+
r.lineTo(endX + blockWidth, statusY);
|
|
379
|
+
r.lineTo(endX + blockWidth, statusY + statusBarHeight);
|
|
380
|
+
r.lineTo(endX, statusY + statusBarHeight);
|
|
381
|
+
r.closePath();
|
|
382
|
+
r.fill(segment.bg);
|
|
383
|
+
|
|
384
|
+
r.fillText(segment.text, endX + 10, statusY + 18, font, color);
|
|
385
|
+
} else {
|
|
386
|
+
endX -= textWidth + 15;
|
|
387
|
+
r.fillText(segment.text, endX + 10, statusY + 18, font, color);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
} else if (mode !== 'COMMAND') {
|
|
392
|
+
// Default fallback status bar
|
|
286
393
|
const modeText = `-- ${mode} --`;
|
|
287
394
|
const posText = `${cursor.line + 1}:${cursor.character + 1}`;
|
|
288
395
|
const pendingKeys = this.editorState.getPendingKeys();
|
|
289
396
|
const pendingText = pendingKeys.length > 0 ? pendingKeys.join('') : '';
|
|
290
397
|
|
|
291
|
-
r.fillText(modeText, 10, statusY + 18, 'bold 12px monospace',
|
|
398
|
+
r.fillText(modeText, 10, statusY + 18, 'bold 12px monospace', theme.accent);
|
|
292
399
|
if (pendingText) {
|
|
293
|
-
r.fillText(pendingText, 120, statusY + 18, '12px monospace',
|
|
400
|
+
r.fillText(pendingText, 120, statusY + 18, '12px monospace', theme.statusBarFg);
|
|
294
401
|
}
|
|
295
|
-
r.fillText(posText, this.width - 60, statusY + 18, '12px monospace',
|
|
402
|
+
r.fillText(posText, this.width - 60, statusY + 18, '12px monospace', theme.statusBarFg);
|
|
296
403
|
}
|
|
297
404
|
|
|
298
405
|
// 6. Draw autocomplete popup menu
|
|
@@ -308,23 +415,24 @@ export class VemEditorEntity extends UIComponent {
|
|
|
308
415
|
|
|
309
416
|
// Translate coordinates from buffer space to screen space
|
|
310
417
|
let popupX = cursorX;
|
|
311
|
-
let popupY = cursorY + this.lineHeight - this.scrollY * this.lineHeight;
|
|
418
|
+
let popupY = cursorY + this.lineHeight - this.scrollY * this.lineHeight + contentOffsetY;
|
|
312
419
|
|
|
313
420
|
// Adjust positioning if it overflows screen boundaries
|
|
314
421
|
if (popupX + popupWidth > this.width) {
|
|
315
422
|
popupX = Math.max(gutterWidth + 5, this.width - popupWidth - 5);
|
|
316
423
|
}
|
|
317
|
-
if (popupY + popupHeight > statusY) {
|
|
318
|
-
// Render above the cursor if it would overlay/go past the status bar
|
|
424
|
+
if (layout.statusBarPosition === 'bottom' && popupY + popupHeight > statusY) {
|
|
319
425
|
popupY = cursorY - this.scrollY * this.lineHeight - popupHeight;
|
|
426
|
+
} else if (layout.statusBarPosition === 'top' && popupY < 30) {
|
|
427
|
+
popupY = cursorY + this.lineHeight - this.scrollY * this.lineHeight + 30;
|
|
320
428
|
}
|
|
321
429
|
|
|
322
430
|
// Draw background panel
|
|
323
431
|
r.beginPath();
|
|
324
432
|
r.roundRect(popupX, popupY, popupWidth, popupHeight, 4);
|
|
325
433
|
r.closePath();
|
|
326
|
-
r.fill(
|
|
327
|
-
r.stroke('
|
|
434
|
+
r.fill(theme.statusBarBg);
|
|
435
|
+
r.stroke(theme.accent + '88', 1.2);
|
|
328
436
|
|
|
329
437
|
// Draw menu items
|
|
330
438
|
r.save();
|
|
@@ -342,10 +450,10 @@ export class VemEditorEntity extends UIComponent {
|
|
|
342
450
|
r.lineTo(popupX + popupWidth - 2, itemY + 18);
|
|
343
451
|
r.lineTo(popupX + 2, itemY + 18);
|
|
344
452
|
r.closePath();
|
|
345
|
-
r.fill('
|
|
453
|
+
r.fill(theme.accent + '44');
|
|
346
454
|
}
|
|
347
455
|
|
|
348
|
-
const labelColor = i === this.selectedAutocompleteIndex ?
|
|
456
|
+
const labelColor = i === this.selectedAutocompleteIndex ? theme.accent : theme.fg;
|
|
349
457
|
r.fillText(item.label, popupX + 8, itemY + 13, '12px monospace', labelColor);
|
|
350
458
|
if (item.detail) {
|
|
351
459
|
r.fillText(
|
|
@@ -353,11 +461,131 @@ export class VemEditorEntity extends UIComponent {
|
|
|
353
461
|
popupX + 8 + item.label.length * 7.5,
|
|
354
462
|
itemY + 13,
|
|
355
463
|
'10px monospace',
|
|
356
|
-
|
|
464
|
+
theme.gutterFg,
|
|
357
465
|
);
|
|
358
466
|
}
|
|
359
467
|
}
|
|
360
468
|
r.restore();
|
|
361
469
|
}
|
|
470
|
+
|
|
471
|
+
// 7. Draw centered Floating Popup Picker Modal (Telescope-like)
|
|
472
|
+
const popup = this.editorState.activePopup;
|
|
473
|
+
if (popup) {
|
|
474
|
+
const modalW = Math.min(550, this.width - 40);
|
|
475
|
+
const modalH = Math.min(380, this.height - 80);
|
|
476
|
+
const modalX = (this.width - modalW) / 2;
|
|
477
|
+
const modalY = (this.height - modalH) / 2;
|
|
478
|
+
|
|
479
|
+
// Draw modal backdrop shade
|
|
480
|
+
r.beginPath();
|
|
481
|
+
r.roundRect(0, 0, this.width, this.height, 0);
|
|
482
|
+
r.closePath();
|
|
483
|
+
r.fill('rgba(15, 23, 42, 0.6)'); // Translucent dark overlay
|
|
484
|
+
|
|
485
|
+
// Draw main panel
|
|
486
|
+
r.beginPath();
|
|
487
|
+
r.roundRect(modalX, modalY, modalW, modalH, 6);
|
|
488
|
+
r.closePath();
|
|
489
|
+
r.fill(theme.bg);
|
|
490
|
+
r.stroke(theme.accent, 1.5);
|
|
491
|
+
|
|
492
|
+
// Title
|
|
493
|
+
r.fillText(
|
|
494
|
+
popup.title.toUpperCase(),
|
|
495
|
+
modalX + 15,
|
|
496
|
+
modalY + 28,
|
|
497
|
+
'bold 13px Outfit, monospace',
|
|
498
|
+
theme.accent,
|
|
499
|
+
);
|
|
500
|
+
|
|
501
|
+
// Input Search Bar
|
|
502
|
+
r.beginPath();
|
|
503
|
+
r.roundRect(modalX + 15, modalY + 42, modalW - 30, 28, 4);
|
|
504
|
+
r.closePath();
|
|
505
|
+
r.fill(theme.statusBarBg);
|
|
506
|
+
r.stroke(theme.accent + '44', 1);
|
|
507
|
+
|
|
508
|
+
const queryText = `> ${this.editorState.popupFilterText}`;
|
|
509
|
+
r.fillText(queryText, modalX + 25, modalY + 60, '13px monospace', theme.fg);
|
|
510
|
+
|
|
511
|
+
// Draw flashing block cursor in search bar
|
|
512
|
+
const cursorOffset = (r as any).measureText
|
|
513
|
+
? (r as any).measureText(queryText).width
|
|
514
|
+
: queryText.length * 8;
|
|
515
|
+
r.beginPath();
|
|
516
|
+
r.roundRect(modalX + 25 + cursorOffset + 2, modalY + 48, 8, 15, 0);
|
|
517
|
+
r.closePath();
|
|
518
|
+
r.fill(theme.accent);
|
|
519
|
+
|
|
520
|
+
// Divider line
|
|
521
|
+
r.beginPath();
|
|
522
|
+
r.moveTo(modalX + 15, modalY + 82);
|
|
523
|
+
r.lineTo(modalX + modalW - 15, modalY + 82);
|
|
524
|
+
r.closePath();
|
|
525
|
+
r.stroke(theme.gutterBg, 1.2);
|
|
526
|
+
|
|
527
|
+
// Render filtered list items
|
|
528
|
+
const items = this.editorState.getFilteredPopupItems();
|
|
529
|
+
const listStartY = modalY + 95;
|
|
530
|
+
const itemH = 22;
|
|
531
|
+
const maxVisibleItems = 11;
|
|
532
|
+
const startIndex = Math.max(
|
|
533
|
+
0,
|
|
534
|
+
Math.min(
|
|
535
|
+
this.editorState.activePopupIndex - Math.floor(maxVisibleItems / 2),
|
|
536
|
+
items.length - maxVisibleItems,
|
|
537
|
+
),
|
|
538
|
+
);
|
|
539
|
+
|
|
540
|
+
r.save();
|
|
541
|
+
r.clip(modalX + 15, modalY + 85, modalW - 30, modalH - 100);
|
|
542
|
+
|
|
543
|
+
for (let i = 0; i < Math.min(maxVisibleItems, items.length); i++) {
|
|
544
|
+
const itemIdx = startIndex + i;
|
|
545
|
+
const item = items[itemIdx];
|
|
546
|
+
if (!item) break;
|
|
547
|
+
|
|
548
|
+
const rowY = listStartY + i * itemH;
|
|
549
|
+
|
|
550
|
+
if (itemIdx === this.editorState.activePopupIndex) {
|
|
551
|
+
// Draw active row highlight background
|
|
552
|
+
r.beginPath();
|
|
553
|
+
r.roundRect(modalX + 15, rowY, modalW - 30, itemH, 4);
|
|
554
|
+
r.closePath();
|
|
555
|
+
r.fill(theme.accent + '33');
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const labelColor = itemIdx === this.editorState.activePopupIndex ? theme.accent : theme.fg;
|
|
559
|
+
r.fillText(
|
|
560
|
+
item.label,
|
|
561
|
+
modalX + 25,
|
|
562
|
+
rowY + 15,
|
|
563
|
+
itemIdx === this.editorState.activePopupIndex ? 'bold 12px monospace' : '12px monospace',
|
|
564
|
+
labelColor,
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
if (item.detail) {
|
|
568
|
+
const detailX = modalX + modalW - 35 - item.detail.length * 7.5;
|
|
569
|
+
r.fillText(
|
|
570
|
+
item.detail,
|
|
571
|
+
Math.max(modalX + 250, detailX),
|
|
572
|
+
rowY + 15,
|
|
573
|
+
'10px monospace',
|
|
574
|
+
theme.gutterFg,
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
r.restore();
|
|
579
|
+
|
|
580
|
+
// Draw item counts indicator
|
|
581
|
+
const countText = `${this.editorState.activePopupIndex + 1}/${items.length}`;
|
|
582
|
+
r.fillText(
|
|
583
|
+
countText,
|
|
584
|
+
modalX + modalW - 20 - countText.length * 7.5,
|
|
585
|
+
modalY + 28,
|
|
586
|
+
'11px monospace',
|
|
587
|
+
theme.gutterFg,
|
|
588
|
+
);
|
|
589
|
+
}
|
|
362
590
|
}
|
|
363
591
|
}
|