Skip to content

Commit 85adf2f

Browse files
committed
update
1 parent 3372f79 commit 85adf2f

File tree

2 files changed

+121
-8
lines changed

2 files changed

+121
-8
lines changed

bin/handlers/pnpm-handler.ts

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ import {
1616
packageJsonScriptCompletion,
1717
packageJsonDependencyCompletion,
1818
} from '../completions/completion-producers.js';
19+
import {
20+
getDirectoriesInCwd,
21+
getCommonWorkspaceDirs,
22+
directoryExists,
23+
getDirectoriesMatching,
24+
} from '../utils/filesystem-utils.js';
1925
import {
2026
stripAnsiEscapes,
2127
measureIndent,
@@ -29,69 +35,124 @@ import {
2935
// regex to detect options section in help text
3036
const OPTIONS_SECTION_RE = /^\s*Options:/i;
3137

38+
function getPnpmStorePaths(): string[] {
39+
const paths = ['~/.pnpm-store'];
40+
41+
if (directoryExists('.pnpm-store')) {
42+
paths.push('./.pnpm-store');
43+
}
44+
45+
return paths;
46+
}
47+
3248
// completion handlers for pnpm options that take values
3349
const pnpmOptionHandlers = {
3450
dir: function (complete: (value: string, description: string) => void) {
3551
complete('./', 'Current directory');
3652
complete('../', 'Parent directory');
37-
complete('./packages', 'Packages directory');
53+
54+
const dirs = getDirectoriesInCwd();
55+
for (const dir of dirs) {
56+
if (dir !== './') {
57+
complete(dir, `Directory: ${dir.slice(2)}`);
58+
}
59+
}
3860
},
61+
3962
loglevel: function (complete: (value: string, description: string) => void) {
4063
complete('debug', 'Debug level');
4164
complete('info', 'Info level');
4265
complete('warn', 'Warning level');
4366
complete('error', 'Error level');
4467
complete('silent', 'Silent level');
4568
},
69+
4670
reporter: function (complete: (value: string, description: string) => void) {
4771
complete('default', 'Default reporter');
4872
complete('silent', 'Silent reporter');
4973
complete('append-only', 'Append-only reporter');
5074
complete('ndjson', 'NDJSON reporter');
5175
},
76+
5277
filter: function (complete: (value: string, description: string) => void) {
53-
complete('./packages/*', 'All packages in packages directory');
54-
complete('./apps/*', 'All apps in apps directory');
55-
complete('@scope/*', 'All packages in scope');
5678
complete('.', 'Current working directory');
79+
complete('...', 'Include dependents');
80+
81+
const workspaceDirs = getCommonWorkspaceDirs();
82+
for (const dir of workspaceDirs) {
83+
complete(`${dir}/*`, `All packages in ${dir.slice(2)}`);
84+
}
85+
86+
complete('@*/*', 'All scoped packages');
87+
complete('@types/*', 'All type packages');
5788
},
89+
5890
'modules-dir': function (
5991
complete: (value: string, description: string) => void
6092
) {
6193
complete('node_modules', 'Default modules directory');
62-
complete('./modules', 'Custom modules directory');
94+
95+
const moduleRelatedDirs = getDirectoriesMatching('module').concat(
96+
getDirectoriesMatching('lib')
97+
);
98+
for (const dir of moduleRelatedDirs) {
99+
complete(dir.slice(2), `Existing directory: ${dir.slice(2)}`);
100+
}
63101
},
102+
64103
'store-dir': function (
65104
complete: (value: string, description: string) => void
66105
) {
67-
complete('~/.pnpm-store', 'Default pnpm store');
68-
complete('./store', 'Local store directory');
106+
const storePaths = getPnpmStorePaths();
107+
for (const path of storePaths) {
108+
complete(
109+
path,
110+
path.startsWith('~') ? 'Default pnpm store' : 'Local store directory'
111+
);
112+
}
69113
},
114+
70115
'lockfile-dir': function (
71116
complete: (value: string, description: string) => void
72117
) {
73118
complete('./', 'Current directory');
74119
complete('../', 'Parent directory');
120+
const dirs = getDirectoriesInCwd();
121+
for (const dir of dirs.slice(0, 5)) {
122+
if (dir !== './') {
123+
complete(dir, `Directory: ${dir.slice(2)}`);
124+
}
125+
}
75126
},
127+
76128
'virtual-store-dir': function (
77129
complete: (value: string, description: string) => void
78130
) {
79131
complete('node_modules/.pnpm', 'Default virtual store');
80-
complete('./.pnpm', 'Custom virtual store');
132+
complete('.pnpm', 'Custom virtual store');
133+
134+
if (directoryExists('.pnpm')) {
135+
complete('./.pnpm', 'Existing .pnpm directory');
136+
}
81137
},
138+
82139
'hoist-pattern': function (
83140
complete: (value: string, description: string) => void
84141
) {
85142
complete('*', 'Hoist everything (default)');
86143
complete('@types/*', 'Hoist only type packages');
87144
complete('eslint*', 'Hoist ESLint packages');
145+
complete('*babel*', 'Hoist Babel packages');
146+
complete('*webpack*', 'Hoist Webpack packages');
88147
},
148+
89149
'public-hoist-pattern': function (
90150
complete: (value: string, description: string) => void
91151
) {
92152
complete('*eslint*', 'Hoist ESLint packages to root');
93153
complete('*prettier*', 'Hoist Prettier packages to root');
94154
complete('@types/*', 'Hoist type packages to root');
155+
complete('*babel*', 'Hoist Babel packages to root');
95156
},
96157
};
97158

bin/utils/filesystem-utils.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { readdirSync, statSync } from 'node:fs';
2+
3+
export function getDirectoriesInCwd(): string[] {
4+
try {
5+
return readdirSync('.')
6+
.filter((item) => {
7+
try {
8+
return statSync(item).isDirectory();
9+
} catch {
10+
return false;
11+
}
12+
})
13+
.map((dir) => `./${dir}`)
14+
.slice(0, 10);
15+
} catch {
16+
return ['./'];
17+
}
18+
}
19+
20+
export function getCommonWorkspaceDirs(): string[] {
21+
const common = ['packages', 'apps', 'libs', 'modules', 'components'];
22+
const existing = [];
23+
24+
for (const dir of common) {
25+
try {
26+
if (statSync(dir).isDirectory()) {
27+
existing.push(`./${dir}`);
28+
}
29+
} catch {}
30+
}
31+
32+
return existing;
33+
}
34+
35+
export function directoryExists(path: string): boolean {
36+
try {
37+
return statSync(path).isDirectory();
38+
} catch {
39+
return false;
40+
}
41+
}
42+
43+
// Get directories that match a pattern (e.g., containing 'lib' or 'module')
44+
export function getDirectoriesMatching(pattern: string): string[] {
45+
try {
46+
return getDirectoriesInCwd().filter((dir) =>
47+
dir.toLowerCase().includes(pattern.toLowerCase())
48+
);
49+
} catch {
50+
return [];
51+
}
52+
}

0 commit comments

Comments
 (0)