@code-yeongyu/senpi-tui 2026.10.7 → 2026.10.9
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.
|
@@ -69,6 +69,7 @@ export declare class Editor implements Component, Focusable {
|
|
|
69
69
|
private autocompleteList?;
|
|
70
70
|
private autocompleteState;
|
|
71
71
|
private autocompletePrefix;
|
|
72
|
+
private autocompleteListSnapshot?;
|
|
72
73
|
/** The provider items behind `autocompleteList`, which only carries the display fields. */
|
|
73
74
|
private autocompleteItems;
|
|
74
75
|
private autocompleteMaxVisible;
|
|
@@ -358,6 +359,9 @@ export declare class Editor implements Component, Focusable {
|
|
|
358
359
|
private applyAutocompleteSuggestions;
|
|
359
360
|
private cancelAutocompleteRequest;
|
|
360
361
|
private clearAutocompleteUi;
|
|
362
|
+
private isAutocompleteListStale;
|
|
363
|
+
/** Accept on a list that predates the text: re-query for the current token, then accept its best match. */
|
|
364
|
+
private acceptRefreshedAutocomplete;
|
|
361
365
|
private cancelAutocomplete;
|
|
362
366
|
isShowingAutocomplete(): boolean;
|
|
363
367
|
private updateAutocomplete;
|
|
@@ -688,6 +688,10 @@ export class Editor {
|
|
|
688
688
|
return;
|
|
689
689
|
}
|
|
690
690
|
if (kb.matches(data, "tui.input.tab")) {
|
|
691
|
+
if (this.isAutocompleteListStale()) {
|
|
692
|
+
this.acceptRefreshedAutocomplete();
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
691
695
|
const selected = this.autocompleteList.getSelectedItem();
|
|
692
696
|
if (selected && this.autocompleteProvider) {
|
|
693
697
|
const drillsIntoNamespace = this.isSlashNamespaceSelection(selected.value);
|
|
@@ -706,6 +710,10 @@ export class Editor {
|
|
|
706
710
|
return;
|
|
707
711
|
}
|
|
708
712
|
if (kb.matches(data, "tui.select.confirm")) {
|
|
713
|
+
if (!this.autocompletePrefix.startsWith("/") && this.isAutocompleteListStale()) {
|
|
714
|
+
this.acceptRefreshedAutocomplete();
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
709
717
|
const selected = this.autocompleteList.getSelectedItem();
|
|
710
718
|
if (selected && this.autocompleteProvider) {
|
|
711
719
|
const drillsIntoNamespace = this.isSlashNamespaceSelection(selected.value);
|
|
@@ -2191,6 +2199,24 @@ export class Editor {
|
|
|
2191
2199
|
this.tui.requestRender();
|
|
2192
2200
|
return;
|
|
2193
2201
|
}
|
|
2202
|
+
if (options.acceptSelection) {
|
|
2203
|
+
const bestMatchIndex = this.getBestAutocompleteMatchIndex(suggestions.items, suggestions.prefix);
|
|
2204
|
+
const item = suggestions.items[Math.max(bestMatchIndex, 0)];
|
|
2205
|
+
const drillsIntoNamespace = suggestions.prefix.startsWith("/") && isSlashNamespaceItem(item.value);
|
|
2206
|
+
this.pushUndoSnapshot();
|
|
2207
|
+
this.lastAction = null;
|
|
2208
|
+
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, item, suggestions.prefix);
|
|
2209
|
+
this.state.lines = result.lines;
|
|
2210
|
+
this.state.cursorLine = result.cursorLine;
|
|
2211
|
+
this.setCursorCol(result.cursorCol);
|
|
2212
|
+
this.clearAutocompleteUi();
|
|
2213
|
+
if (this.onChange)
|
|
2214
|
+
this.onChange(this.getText());
|
|
2215
|
+
if (drillsIntoNamespace)
|
|
2216
|
+
this.tryTriggerAutocomplete();
|
|
2217
|
+
this.tui.requestRender();
|
|
2218
|
+
return;
|
|
2219
|
+
}
|
|
2194
2220
|
if (options.force && options.explicitTab && suggestions.items.length === 1) {
|
|
2195
2221
|
const item = suggestions.items[0];
|
|
2196
2222
|
this.pushUndoSnapshot();
|
|
@@ -2216,6 +2242,11 @@ export class Editor {
|
|
|
2216
2242
|
}
|
|
2217
2243
|
applyAutocompleteSuggestions(suggestions, state) {
|
|
2218
2244
|
this.autocompletePrefix = suggestions.prefix;
|
|
2245
|
+
this.autocompleteListSnapshot = {
|
|
2246
|
+
text: this.getText(),
|
|
2247
|
+
line: this.state.cursorLine,
|
|
2248
|
+
col: this.state.cursorCol,
|
|
2249
|
+
};
|
|
2219
2250
|
this.autocompleteItems = suggestions.items;
|
|
2220
2251
|
this.autocompleteList = this.createAutocompleteList(suggestions.prefix, suggestions.items);
|
|
2221
2252
|
const bestMatchIndex = this.getBestAutocompleteMatchIndex(suggestions.items, suggestions.prefix);
|
|
@@ -2238,6 +2269,22 @@ export class Editor {
|
|
|
2238
2269
|
this.autocompleteList = undefined;
|
|
2239
2270
|
this.autocompleteItems = [];
|
|
2240
2271
|
this.autocompletePrefix = "";
|
|
2272
|
+
this.autocompleteListSnapshot = undefined;
|
|
2273
|
+
}
|
|
2274
|
+
isAutocompleteListStale() {
|
|
2275
|
+
const snapshot = this.autocompleteListSnapshot;
|
|
2276
|
+
return (snapshot !== undefined &&
|
|
2277
|
+
(snapshot.text !== this.getText() ||
|
|
2278
|
+
snapshot.line !== this.state.cursorLine ||
|
|
2279
|
+
snapshot.col !== this.state.cursorCol));
|
|
2280
|
+
}
|
|
2281
|
+
/** Accept on a list that predates the text: re-query for the current token, then accept its best match. */
|
|
2282
|
+
acceptRefreshedAutocomplete() {
|
|
2283
|
+
this.requestAutocomplete({
|
|
2284
|
+
force: this.autocompleteState === "force",
|
|
2285
|
+
explicitTab: true,
|
|
2286
|
+
acceptSelection: true,
|
|
2287
|
+
});
|
|
2241
2288
|
}
|
|
2242
2289
|
cancelAutocomplete() {
|
|
2243
2290
|
this.cancelAutocompleteRequest();
|
package/package.json
CHANGED