@narumitw/pi-statusline 0.38.0 → 0.39.0
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 +5 -5
- package/src/commands.ts +27 -77
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@narumitw/pi-statusline",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"description": "Pi extension that replaces the footer with an information-rich statusline.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"typecheck": "tsc --noEmit"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@biomejs/biome": "2.5.
|
|
32
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
33
|
-
"@earendil-works/pi-tui": "0.
|
|
34
|
-
"@types/node": "26.1.
|
|
31
|
+
"@biomejs/biome": "2.5.6",
|
|
32
|
+
"@earendil-works/pi-coding-agent": "0.83.0",
|
|
33
|
+
"@earendil-works/pi-tui": "0.83.0",
|
|
34
|
+
"@types/node": "26.1.2",
|
|
35
35
|
"typescript": "7.0.2"
|
|
36
36
|
},
|
|
37
37
|
"repository": {
|
package/src/commands.ts
CHANGED
|
@@ -125,8 +125,8 @@ async function showMainMenu(ctx: ExtensionCommandContext, options: StatuslineCom
|
|
|
125
125
|
signal: fallbackController.signal,
|
|
126
126
|
isCurrent: () => !fallbackController.signal.aborted,
|
|
127
127
|
};
|
|
128
|
-
type Screen = "main" | "advanced";
|
|
129
|
-
type Action = "appearance" | "
|
|
128
|
+
type Screen = "main" | "advanced" | "information";
|
|
129
|
+
type Action = "appearance" | "setInformation" | "layout" | "edit" | "status" | "help" | "back";
|
|
130
130
|
const menu = defineMenu<undefined, Screen, Action, ExtensionCommandContext>({
|
|
131
131
|
start: "main",
|
|
132
132
|
screens: {
|
|
@@ -144,7 +144,7 @@ async function showMainMenu(ctx: ExtensionCommandContext, options: StatuslineCom
|
|
|
144
144
|
{
|
|
145
145
|
id: "information",
|
|
146
146
|
label: `Information (${inferInformationProfile(config.segments)})`,
|
|
147
|
-
|
|
147
|
+
to: "information",
|
|
148
148
|
},
|
|
149
149
|
{ id: "advanced", label: "Advanced", to: "advanced" },
|
|
150
150
|
{ id: "status", label: "Status", action: "status" },
|
|
@@ -153,6 +153,24 @@ async function showMainMenu(ctx: ExtensionCommandContext, options: StatuslineCom
|
|
|
153
153
|
hint: "close",
|
|
154
154
|
};
|
|
155
155
|
},
|
|
156
|
+
information: () => {
|
|
157
|
+
const current = inferInformationProfile(options.getLoaded().config.segments);
|
|
158
|
+
return {
|
|
159
|
+
kind: "choice",
|
|
160
|
+
title: "Information level",
|
|
161
|
+
lines: [`Current profile: ${current}`],
|
|
162
|
+
items: INFORMATION_PROFILE_NAMES.map((profile) => ({
|
|
163
|
+
id: profile,
|
|
164
|
+
label: `${profile[0]?.toUpperCase() ?? ""}${profile.slice(1)}`,
|
|
165
|
+
description: `${INFORMATION_PROFILES[profile].length} segments`,
|
|
166
|
+
details: [`Segments: ${INFORMATION_PROFILES[profile].join(" · ")}`],
|
|
167
|
+
})),
|
|
168
|
+
action: "setInformation",
|
|
169
|
+
currentItemId: current,
|
|
170
|
+
initialItemId: current === "custom" ? "balanced" : current,
|
|
171
|
+
hint: "close",
|
|
172
|
+
};
|
|
173
|
+
},
|
|
156
174
|
advanced: () => {
|
|
157
175
|
const config = options.getLoaded().config;
|
|
158
176
|
const visibleSegmentCount = config.segments.filter(
|
|
@@ -179,8 +197,10 @@ async function showMainMenu(ctx: ExtensionCommandContext, options: StatuslineCom
|
|
|
179
197
|
await choosePalettePreset(ctx, options);
|
|
180
198
|
return { kind: "close" };
|
|
181
199
|
},
|
|
182
|
-
|
|
183
|
-
|
|
200
|
+
setInformation: async ({ itemId }) => {
|
|
201
|
+
const profile = INFORMATION_PROFILE_NAMES.find((candidate) => candidate === itemId);
|
|
202
|
+
if (!profile) return { kind: "rejected" };
|
|
203
|
+
applyInformationProfile(ctx, options, profile);
|
|
184
204
|
return { kind: "close" };
|
|
185
205
|
},
|
|
186
206
|
layout: async () => {
|
|
@@ -317,19 +337,12 @@ async function showPalettePresetPicker(
|
|
|
317
337
|
return result ?? undefined;
|
|
318
338
|
}
|
|
319
339
|
|
|
320
|
-
|
|
340
|
+
function applyInformationProfile(
|
|
321
341
|
ctx: ExtensionCommandContext,
|
|
322
342
|
options: StatuslineCommandOptions,
|
|
343
|
+
selection: InformationProfileName,
|
|
323
344
|
) {
|
|
324
|
-
if (ctx.mode !== "tui") {
|
|
325
|
-
if (ctx.hasUI) ctx.ui.notify(`Edit segments manually: ${options.settingsPath}`, "info");
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
345
|
const current = options.getLoaded();
|
|
329
|
-
const currentProfile = inferInformationProfile(current.config.segments);
|
|
330
|
-
const selection = await showInformationProfilePicker(ctx, currentProfile);
|
|
331
|
-
if (selection === undefined) return;
|
|
332
|
-
|
|
333
346
|
try {
|
|
334
347
|
const change = informationProfileDocument(current, selection);
|
|
335
348
|
const loaded = applySegmentsDocumentChange(change, ctx, options);
|
|
@@ -342,69 +355,6 @@ async function chooseInformationProfile(
|
|
|
342
355
|
}
|
|
343
356
|
}
|
|
344
357
|
|
|
345
|
-
async function showInformationProfilePicker(
|
|
346
|
-
ctx: ExtensionCommandContext,
|
|
347
|
-
current: ReturnType<typeof inferInformationProfile>,
|
|
348
|
-
): Promise<InformationProfileName | undefined> {
|
|
349
|
-
const items: SelectItem[] = INFORMATION_PROFILE_NAMES.map((profile) => ({
|
|
350
|
-
value: profile,
|
|
351
|
-
label: `${profile[0]?.toUpperCase() ?? ""}${profile.slice(1)}`,
|
|
352
|
-
description: `${INFORMATION_PROFILES[profile].length} segments${profile === current ? " • current" : ""}`,
|
|
353
|
-
}));
|
|
354
|
-
const initialProfile = current === "custom" ? "balanced" : current;
|
|
355
|
-
const selectedIndex = INFORMATION_PROFILE_NAMES.indexOf(initialProfile);
|
|
356
|
-
const result = await ctx.ui.custom<InformationProfileName | null>(
|
|
357
|
-
(tui, theme, _keybindings, done) => {
|
|
358
|
-
const container = new Container();
|
|
359
|
-
container.addChild(new DynamicBorder((text: string) => theme.fg("accent", text)));
|
|
360
|
-
const title = new Text("", 1, 0);
|
|
361
|
-
container.addChild(title);
|
|
362
|
-
const list = new SelectList(items, items.length, {
|
|
363
|
-
selectedPrefix: (text) => theme.fg("accent", text),
|
|
364
|
-
selectedText: (text) => theme.fg("accent", text),
|
|
365
|
-
description: (text) => theme.fg("muted", text),
|
|
366
|
-
scrollInfo: (text) => theme.fg("dim", text),
|
|
367
|
-
noMatch: (text) => theme.fg("warning", text),
|
|
368
|
-
});
|
|
369
|
-
list.setSelectedIndex(selectedIndex);
|
|
370
|
-
let selectedProfile = initialProfile;
|
|
371
|
-
const details = new Text("", 1, 0);
|
|
372
|
-
const hint = new Text("", 1, 0);
|
|
373
|
-
const updateThemedText = () => {
|
|
374
|
-
title.setText(theme.fg("accent", theme.bold(`Information level (current: ${current})`)));
|
|
375
|
-
details.setText(
|
|
376
|
-
theme.fg("muted", `Segments: ${INFORMATION_PROFILES[selectedProfile].join(" · ")}`),
|
|
377
|
-
);
|
|
378
|
-
hint.setText(theme.fg("dim", "↑↓ preview contents • enter apply • esc cancel"));
|
|
379
|
-
};
|
|
380
|
-
list.onSelectionChange = (item) => {
|
|
381
|
-
selectedProfile = item.value as InformationProfileName;
|
|
382
|
-
updateThemedText();
|
|
383
|
-
};
|
|
384
|
-
list.onSelect = (item) => done(item.value as InformationProfileName);
|
|
385
|
-
list.onCancel = () => done(null);
|
|
386
|
-
container.addChild(list);
|
|
387
|
-
container.addChild(details);
|
|
388
|
-
container.addChild(hint);
|
|
389
|
-
container.addChild(new DynamicBorder((text: string) => theme.fg("accent", text)));
|
|
390
|
-
updateThemedText();
|
|
391
|
-
|
|
392
|
-
return {
|
|
393
|
-
render: (width: number) => container.render(width),
|
|
394
|
-
invalidate() {
|
|
395
|
-
container.invalidate();
|
|
396
|
-
updateThemedText();
|
|
397
|
-
},
|
|
398
|
-
handleInput(data: string) {
|
|
399
|
-
list.handleInput(data);
|
|
400
|
-
tui.requestRender();
|
|
401
|
-
},
|
|
402
|
-
};
|
|
403
|
-
},
|
|
404
|
-
);
|
|
405
|
-
return result ?? undefined;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
358
|
async function chooseSegments(ctx: ExtensionCommandContext, options: StatuslineCommandOptions) {
|
|
409
359
|
if (ctx.mode !== "tui") {
|
|
410
360
|
if (ctx.hasUI) ctx.ui.notify(`Edit segments manually: ${options.settingsPath}`, "info");
|