@d3ara1n/pi-command-palette 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/package.json +2 -1
- package/src/index.ts +67 -2
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -17,6 +17,9 @@ import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
|
|
17
17
|
import {
|
|
18
18
|
Container,
|
|
19
19
|
type SelectItem,
|
|
20
|
+
fuzzyFilter,
|
|
21
|
+
Key,
|
|
22
|
+
matchesKey,
|
|
20
23
|
SelectList,
|
|
21
24
|
Text,
|
|
22
25
|
} from "@earendil-works/pi-tui";
|
|
@@ -188,9 +191,25 @@ async function showModelSelector(pi: ExtensionAPI, ctx: ExtensionContext): Promi
|
|
|
188
191
|
selectList.onSelect = (item) => done(item.value);
|
|
189
192
|
selectList.onCancel = () => done(null);
|
|
190
193
|
|
|
194
|
+
// Type-to-filter state
|
|
195
|
+
let query = "";
|
|
196
|
+
const queryText = new Text(theme.fg("accent", "> "), 1, 0);
|
|
197
|
+
|
|
198
|
+
function applyQuery() {
|
|
199
|
+
const filtered = query
|
|
200
|
+
? fuzzyFilter(items, query, (item: SelectItem) => `${item.label} ${item.description ?? ""}`)
|
|
201
|
+
: items;
|
|
202
|
+
(selectList as any).filteredItems = filtered;
|
|
203
|
+
selectList.setSelectedIndex(0);
|
|
204
|
+
queryText.setText(theme.fg("accent", `> ${query}▎`));
|
|
205
|
+
container.invalidate();
|
|
206
|
+
tui.requestRender();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
container.addChild(queryText);
|
|
191
210
|
container.addChild(selectList);
|
|
192
211
|
container.addChild(
|
|
193
|
-
new Text(theme.fg("dim", "↑↓ navigate • enter select • esc cancel"), 1, 0),
|
|
212
|
+
new Text(theme.fg("dim", "type to filter • ↑↓ navigate • enter select • esc cancel"), 1, 0),
|
|
194
213
|
);
|
|
195
214
|
container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
|
|
196
215
|
|
|
@@ -202,6 +221,21 @@ async function showModelSelector(pi: ExtensionAPI, ctx: ExtensionContext): Promi
|
|
|
202
221
|
container.invalidate();
|
|
203
222
|
},
|
|
204
223
|
handleInput(data: string) {
|
|
224
|
+
// Backspace → trim query
|
|
225
|
+
if (matchesKey(data, Key.backspace)) {
|
|
226
|
+
if (query.length > 0) {
|
|
227
|
+
query = query.slice(0, -1);
|
|
228
|
+
applyQuery();
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
// Printable character → append to query
|
|
233
|
+
if (data.length === 1 && data.charCodeAt(0) >= 32) {
|
|
234
|
+
query += data;
|
|
235
|
+
applyQuery();
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// Navigation / confirm / cancel → pass to SelectList
|
|
205
239
|
selectList.handleInput(data);
|
|
206
240
|
tui.requestRender();
|
|
207
241
|
},
|
|
@@ -225,7 +259,7 @@ async function showModelSelector(pi: ExtensionAPI, ctx: ExtensionContext): Promi
|
|
|
225
259
|
// ── Command palette overlay ────────────────────────────────────────
|
|
226
260
|
|
|
227
261
|
async function showCommandPalette(pi: ExtensionAPI, ctx: ExtensionContext): Promise<void> {
|
|
228
|
-
if (ctx.
|
|
262
|
+
if (!ctx.hasUI) return;
|
|
229
263
|
|
|
230
264
|
const paletteItems = buildPaletteItems(pi, ctx);
|
|
231
265
|
const selectItems: SelectItem[] = paletteItems.map((item) => ({
|
|
@@ -256,6 +290,22 @@ async function showCommandPalette(pi: ExtensionAPI, ctx: ExtensionContext): Prom
|
|
|
256
290
|
};
|
|
257
291
|
selectList.onCancel = () => done(null);
|
|
258
292
|
|
|
293
|
+
// Type-to-filter state
|
|
294
|
+
let query = "";
|
|
295
|
+
const queryText = new Text(theme.fg("accent", "> "), 1, 0);
|
|
296
|
+
|
|
297
|
+
function applyQuery() {
|
|
298
|
+
const filtered = query
|
|
299
|
+
? fuzzyFilter(selectItems, query, (item: SelectItem) => `${item.label} ${item.description ?? ""}`)
|
|
300
|
+
: selectItems;
|
|
301
|
+
(selectList as any).filteredItems = filtered;
|
|
302
|
+
selectList.setSelectedIndex(0);
|
|
303
|
+
queryText.setText(theme.fg("accent", `> ${query}▎`));
|
|
304
|
+
container.invalidate();
|
|
305
|
+
tui.requestRender();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
container.addChild(queryText);
|
|
259
309
|
container.addChild(selectList);
|
|
260
310
|
container.addChild(
|
|
261
311
|
new Text(theme.fg("dim", "type to filter • ↑↓ navigate • enter select • esc cancel"), 1, 0),
|
|
@@ -270,6 +320,21 @@ async function showCommandPalette(pi: ExtensionAPI, ctx: ExtensionContext): Prom
|
|
|
270
320
|
container.invalidate();
|
|
271
321
|
},
|
|
272
322
|
handleInput(data: string) {
|
|
323
|
+
// Backspace → trim query
|
|
324
|
+
if (matchesKey(data, Key.backspace)) {
|
|
325
|
+
if (query.length > 0) {
|
|
326
|
+
query = query.slice(0, -1);
|
|
327
|
+
applyQuery();
|
|
328
|
+
}
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
// Printable character → append to query
|
|
332
|
+
if (data.length === 1 && data.charCodeAt(0) >= 32) {
|
|
333
|
+
query += data;
|
|
334
|
+
applyQuery();
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
// Navigation / confirm / cancel → pass to SelectList
|
|
273
338
|
selectList.handleInput(data);
|
|
274
339
|
tui.requestRender();
|
|
275
340
|
},
|