@firstpick/pi-extension-bang-command-autocomplete 0.1.3 → 0.1.5
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/README.md +13 -2
- package/index.ts +33 -18
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Autocomplete for `!<command>` in Pi.
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
Built-in suggestions for common shell commands appear as soon as you type `!`.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
Learned full command lines and commands from the current session surface next to each other while you refine a bang.
|
|
12
|
+
|
|
5
13
|
## What it does
|
|
6
14
|
|
|
7
15
|
- Suggests command names while typing `!<command>`.
|
|
8
|
-
- Uses a built-in common-command index out of the box.
|
|
16
|
+
- Uses a built-in common-command index out of the box (with platform-aware defaults).
|
|
9
17
|
- Learns commands you run via `!`/`!!` and persists them across Pi sessions.
|
|
10
18
|
- Learns full bang command lines (e.g. `!git add .`) and suggests them directly.
|
|
11
19
|
- Learns flags used with those commands (e.g. `!rg -n`) and suggests them when you type `!<command> ` or `!<command> -...`.
|
|
@@ -22,7 +30,10 @@ pi install npm:@firstpick/pi-extension-bang-command-autocomplete
|
|
|
22
30
|
## Configuration
|
|
23
31
|
|
|
24
32
|
- `PI_BANG_AUTOCOMPLETE_INCLUDE_HISTORY`
|
|
25
|
-
- `1|true|yes|on`: include commands from
|
|
33
|
+
- `1|true|yes|on`: include commands from shell history.
|
|
34
|
+
- Bash: `~/.bash_history`
|
|
35
|
+
- Zsh: `~/.zsh_history`
|
|
36
|
+
- Fish: `$XDG_DATA_HOME/fish/fish_history` (fallback: `~/.local/share/fish/fish_history`)
|
|
26
37
|
- unset/other: use built-in command list only (default).
|
|
27
38
|
- `PI_BANG_AUTOCOMPLETE_RUNTIME_STORE_PATH`
|
|
28
39
|
- optional absolute/relative file path for persisted learned commands.
|
package/index.ts
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import type { ExtensionAPI } from "@
|
|
4
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { envFlag, getAgentDir } from "@firstpick/pi-utils";
|
|
5
6
|
|
|
6
7
|
type CommandSource = "common" | "history" | "runtime";
|
|
7
8
|
|
|
8
9
|
const DEFAULT_RUNTIME_STORE_PATH = path.join(
|
|
9
|
-
|
|
10
|
-
".pi",
|
|
11
|
-
"agent",
|
|
10
|
+
getAgentDir(),
|
|
12
11
|
"state",
|
|
13
12
|
"bang-command-autocomplete-runtime.json",
|
|
14
13
|
);
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
const raw = process.env[name]?.trim().toLowerCase();
|
|
18
|
-
if (!raw) return fallback;
|
|
19
|
-
return raw === "1" || raw === "true" || raw === "yes" || raw === "on";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const COMMON_COMMANDS = [
|
|
15
|
+
const COMMON_COMMANDS_BASE = [
|
|
23
16
|
"ls",
|
|
24
17
|
"la",
|
|
25
18
|
"ll",
|
|
@@ -51,10 +44,6 @@ const COMMON_COMMANDS = [
|
|
|
51
44
|
"just",
|
|
52
45
|
"docker",
|
|
53
46
|
"docker-compose",
|
|
54
|
-
"systemctl",
|
|
55
|
-
"journalctl",
|
|
56
|
-
"pacman",
|
|
57
|
-
"yay",
|
|
58
47
|
"curl",
|
|
59
48
|
"wget",
|
|
60
49
|
"ssh",
|
|
@@ -65,6 +54,17 @@ const COMMON_COMMANDS = [
|
|
|
65
54
|
"btop",
|
|
66
55
|
] as const;
|
|
67
56
|
|
|
57
|
+
const COMMON_COMMANDS_UNIX = ["systemctl", "journalctl"] as const;
|
|
58
|
+
const COMMON_COMMANDS_LINUX = ["pacman", "yay"] as const;
|
|
59
|
+
|
|
60
|
+
function getCommonCommands(): string[] {
|
|
61
|
+
const platform = os.platform();
|
|
62
|
+
const commands = [...COMMON_COMMANDS_BASE];
|
|
63
|
+
if (platform !== "win32") commands.push(...COMMON_COMMANDS_UNIX);
|
|
64
|
+
if (platform === "linux") commands.push(...COMMON_COMMANDS_LINUX);
|
|
65
|
+
return commands;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
68
|
function parseCommandLine(commandLine: string): { executable?: string; flags: string[] } {
|
|
69
69
|
const trimmed = commandLine.trim();
|
|
70
70
|
if (!trimmed || trimmed.startsWith("#")) return { flags: [] };
|
|
@@ -95,7 +95,8 @@ function extractExecutable(commandLine: string): string | undefined {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
function readFishHistoryExecutables(): string[] {
|
|
98
|
-
const
|
|
98
|
+
const fishDataHome = process.env.XDG_DATA_HOME?.trim() || path.join(os.homedir(), ".local", "share");
|
|
99
|
+
const historyPath = path.join(fishDataHome, "fish", "fish_history");
|
|
99
100
|
if (!fs.existsSync(historyPath)) return [];
|
|
100
101
|
|
|
101
102
|
const content = fs.readFileSync(historyPath, "utf8");
|
|
@@ -124,6 +125,20 @@ function readBashHistoryExecutables(): string[] {
|
|
|
124
125
|
.filter((v): v is string => Boolean(v));
|
|
125
126
|
}
|
|
126
127
|
|
|
128
|
+
function readZshHistoryExecutables(): string[] {
|
|
129
|
+
const historyPath = path.join(os.homedir(), ".zsh_history");
|
|
130
|
+
if (!fs.existsSync(historyPath)) return [];
|
|
131
|
+
|
|
132
|
+
const content = fs.readFileSync(historyPath, "utf8");
|
|
133
|
+
return content
|
|
134
|
+
.split(/\r?\n/)
|
|
135
|
+
.map((line) => {
|
|
136
|
+
const cleaned = line.includes(";") ? line.slice(line.indexOf(";") + 1) : line;
|
|
137
|
+
return extractExecutable(cleaned);
|
|
138
|
+
})
|
|
139
|
+
.filter((v): v is string => Boolean(v));
|
|
140
|
+
}
|
|
141
|
+
|
|
127
142
|
function getRuntimeStorePath(): string {
|
|
128
143
|
const configured = process.env.PI_BANG_AUTOCOMPLETE_RUNTIME_STORE_PATH?.trim();
|
|
129
144
|
return configured ? path.resolve(configured) : DEFAULT_RUNTIME_STORE_PATH;
|
|
@@ -218,12 +233,12 @@ function writeRuntimeData(storePath: string, data: RuntimeStoreData): void {
|
|
|
218
233
|
function buildCommandIndex(includeHistory: boolean): Array<{ command: string; source: CommandSource }> {
|
|
219
234
|
const merged = new Map<string, CommandSource>();
|
|
220
235
|
|
|
221
|
-
for (const command of
|
|
236
|
+
for (const command of getCommonCommands()) {
|
|
222
237
|
merged.set(command, "common");
|
|
223
238
|
}
|
|
224
239
|
|
|
225
240
|
if (includeHistory) {
|
|
226
|
-
const historyExecutables = [...readFishHistoryExecutables(), ...readBashHistoryExecutables()];
|
|
241
|
+
const historyExecutables = [...readFishHistoryExecutables(), ...readBashHistoryExecutables(), ...readZshHistoryExecutables()];
|
|
227
242
|
for (let i = historyExecutables.length - 1; i >= 0; i--) {
|
|
228
243
|
const command = historyExecutables[i];
|
|
229
244
|
if (!command) continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firstpick/pi-extension-bang-command-autocomplete",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Autocomplete for !<command> in Pi, with optional shell-history indexing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -15,11 +15,14 @@
|
|
|
15
15
|
]
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"@
|
|
18
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
21
|
"index.ts",
|
|
22
22
|
"README.md",
|
|
23
23
|
"LICENSE"
|
|
24
|
-
]
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@firstpick/pi-utils": "^0.1.0"
|
|
27
|
+
}
|
|
25
28
|
}
|