Skip to content

Commit 8fac6b8

Browse files
Autocomplete path and support absolute and home directory paths
NOTE: These have been slopped out by clankers. Use caution.
1 parent e6f9570 commit 8fac6b8

1 file changed

Lines changed: 62 additions & 3 deletions

File tree

pi/save-last-extension.ts

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,61 @@
11
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2-
import { writeFile } from "node:fs/promises";
3-
import { join } from "node:path";
2+
import type { AutocompleteItem } from "@mariozechner/pi-tui";
3+
import { writeFile, readdir, stat } from "node:fs/promises";
4+
import { join, isAbsolute, dirname, basename } from "node:path";
5+
import { homedir } from "node:os";
46

57
export default function (pi: ExtensionAPI) {
8+
const getFileCompletions = async (prefix: string): Promise<AutocompleteItem[] | null> => {
9+
try {
10+
// Resolve the directory and file prefix
11+
let dir = "";
12+
let filePrefix = prefix;
13+
14+
if (prefix.includes("/")) {
15+
dir = dirname(prefix);
16+
filePrefix = basename(prefix);
17+
} else if (prefix.startsWith("~")) {
18+
const home = homedir();
19+
const rest = prefix.slice(1);
20+
if (rest.includes("/")) {
21+
dir = join(home, dirname(rest));
22+
filePrefix = basename(rest);
23+
} else {
24+
dir = home;
25+
filePrefix = rest;
26+
}
27+
} else {
28+
dir = ".";
29+
}
30+
31+
// Read directory contents
32+
const entries = await readdir(dir, { withFileTypes: true });
33+
const completions: AutocompleteItem[] = [];
34+
35+
for (const entry of entries) {
36+
if (entry.name.startsWith(filePrefix)) {
37+
const fullPath = join(dir, entry.name);
38+
let displayPath = fullPath;
39+
if (prefix.startsWith("~")) {
40+
displayPath = "~" + fullPath.slice(homedir().length);
41+
}
42+
43+
completions.push({
44+
value: displayPath + (entry.isDirectory() ? "/" : ""),
45+
label: entry.name + (entry.isDirectory() ? "/" : ""),
46+
});
47+
}
48+
}
49+
50+
return completions.length > 0 ? completions : null;
51+
} catch {
52+
return null;
53+
}
54+
};
55+
656
pi.registerCommand("save-last", {
757
description: "Export the most recent AI response to a txt file",
58+
getArgumentCompletions: (prefix: string) => getFileCompletions(prefix),
859
handler: async (args, ctx) => {
960
ctx.ui.notify(`Export started`, "success");
1061
const entries = ctx.sessionManager.getBranch();
@@ -30,7 +81,15 @@ export default function (pi: ExtensionAPI) {
3081

3182
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
3283
const filename = args.trim() || `ai-response-${timestamp}.txt`;
33-
const filepath = join(ctx.cwd, filename);
84+
85+
let filepath: string;
86+
if (isAbsolute(filename)) {
87+
filepath = filename;
88+
} else if (filename.startsWith("~")) {
89+
filepath = join(homedir(), filename.slice(1));
90+
} else {
91+
filepath = join(ctx.cwd, filename);
92+
}
3493

3594
await writeFile(filepath, lastAssistantText, "utf8");
3695
ctx.ui.notify(`Exported to ${filename}`, "success");

0 commit comments

Comments
 (0)