make-folder-txt 1.4.4 → 2.0.1
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 +77 -1
- package/bin/make-folder-txt.js +302 -32
- package/completion/install-powershell-completion.ps1 +75 -0
- package/completion/make-folder-txt-completion.bash +41 -0
- package/completion/make-folder-txt-completion.ps1 +67 -0
- package/completion/make-folder-txt-completion.zsh +26 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
Perfect for sharing your codebase with **AI tools**, **teammates**, or **code reviewers** — without zipping files or giving repo access.
|
|
13
13
|
|
|
14
|
-
[Installation](#-installation) · [Usage](#-usage) · [Help](#-get-help) · [Output Format](#-output-format) · [What Gets Skipped](#-what-gets-skipped) · [Contributing](#-contributing)
|
|
14
|
+
[Installation](#-installation) · [Usage](#-usage) · [Help](#-get-help) · [Copy to Clipboard](#-copy-to-clipboard) · [Force Include Everything](#-force-include-everything) · [Shell Autocompletion](#-shell-autocompletion) · [Output Format](#-output-format) · [What Gets Skipped](#-what-gets-skipped) · [Contributing](#-contributing)
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -23,6 +23,9 @@ Ever needed to share your entire project with ChatGPT, Claude, or a teammate —
|
|
|
23
23
|
|
|
24
24
|
- ✅ Run it from any project directory — no arguments needed
|
|
25
25
|
- ✅ Built-in help system with `--help` flag
|
|
26
|
+
- ✅ **Built-in shell autocompletion** (installs automatically)
|
|
27
|
+
- ✅ Copy to clipboard with `--copy` flag
|
|
28
|
+
- ✅ Force include everything with `--force` flag
|
|
26
29
|
- ✅ Generates a clean folder tree + every file's content
|
|
27
30
|
- ✅ `.txtignore` support (works like `.gitignore`)
|
|
28
31
|
- ✅ Automatically skips `node_modules`, binaries, and junk files
|
|
@@ -61,13 +64,84 @@ make-folder-txt --version # Show version info
|
|
|
61
64
|
make-folder-txt -v # Short version of version
|
|
62
65
|
```
|
|
63
66
|
|
|
67
|
+
### 📋 Copy to Clipboard
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
make-folder-txt --copy # Generate output and copy to clipboard
|
|
71
|
+
make-folder-txt --copy --ignore-folder node_modules # Copy filtered output
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The `--copy` flag automatically copies the generated output to your system clipboard, making it easy to paste directly into AI tools, emails, or documents. Works on Windows, macOS, and Linux (requires `xclip` or `xsel` on Linux).
|
|
75
|
+
|
|
76
|
+
### 🔥 Force Include Everything
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
make-folder-txt --force # Include everything (overrides all ignore patterns)
|
|
80
|
+
make-folder-txt --force --copy # Include everything and copy to clipboard
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The `--force` flag overrides all ignore patterns and includes:
|
|
84
|
+
- `node_modules` and other ignored folders
|
|
85
|
+
- Binary files (images, executables, etc.)
|
|
86
|
+
- Large files (no 500 KB limit)
|
|
87
|
+
- Files in `.txtignore`
|
|
88
|
+
- System files and other normally skipped content
|
|
89
|
+
|
|
90
|
+
Use this when you need a complete, unfiltered dump of your entire project.
|
|
91
|
+
|
|
92
|
+
### ⚡ Shell Autocompletion (Built-in)
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
make-folder-txt # Autocompletion installs automatically on first run
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**🎉 No installation required!** The tool automatically installs shell autocompletion the first time you run it.
|
|
99
|
+
|
|
100
|
+
**What gets installed automatically:**
|
|
101
|
+
- **Flag completion**: `make-folder-txt --<TAB>` shows all available flags
|
|
102
|
+
- **Folder completion**: `make-folder-txt --ignore-folder <TAB>` shows folders
|
|
103
|
+
- **File completion**: `make-folder-txt --ignore-file <TAB>` shows files
|
|
104
|
+
|
|
105
|
+
**Supported Shells:**
|
|
106
|
+
- **Bash** - Linux/macOS/Windows (WSL)
|
|
107
|
+
- **Zsh** - macOS/Linux
|
|
108
|
+
- **PowerShell** - Windows (7+)
|
|
109
|
+
|
|
110
|
+
**Example usage:**
|
|
111
|
+
```bash
|
|
112
|
+
$ make-folder-txt --ignore-folder b<TAB>
|
|
113
|
+
# → completes to "bin/" if bin folder exists
|
|
114
|
+
|
|
115
|
+
$ make-folder-txt --ignore-file p<TAB>
|
|
116
|
+
# → completes to "package.json" if package.json exists
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Manual Installation (if needed):**
|
|
120
|
+
```bash
|
|
121
|
+
make-folder-txt --install-completion # Force reinstall completion
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**PowerShell Manual Setup:**
|
|
125
|
+
```powershell
|
|
126
|
+
# If auto-installation doesn't work, load manually:
|
|
127
|
+
. .\completion\make-folder-txt-completion.ps1
|
|
128
|
+
|
|
129
|
+
# Or add to your PowerShell profile for persistence:
|
|
130
|
+
notepad $PROFILE
|
|
131
|
+
# Add: . "C:\path\to\make-folder-txt\completion\make-folder-txt-completion.ps1"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The completion works out of the box - just run the tool once and restart your terminal!
|
|
135
|
+
|
|
64
136
|
Ignore specific folders/files by name:
|
|
65
137
|
|
|
66
138
|
```bash
|
|
67
139
|
make-folder-txt --ignore-folder examples extensions docs
|
|
140
|
+
make-folder-txt -ifo examples extensions docs # shorthand
|
|
68
141
|
make-folder-txt --ignore-folder examples extensions "docs and explaination"
|
|
69
142
|
make-folder-txt --ignore-folder examples extensions docs --ignore-file LICENSE
|
|
70
143
|
make-folder-txt --ignore-file .env .env.local secrets.txt
|
|
144
|
+
make-folder-txt -ifi .env .env.local secrets.txt # shorthand
|
|
71
145
|
```
|
|
72
146
|
|
|
73
147
|
Use a `.txtignore` file (works like `.gitignore`):
|
|
@@ -93,7 +167,9 @@ Include only specific folders/files by name (everything else is ignored):
|
|
|
93
167
|
|
|
94
168
|
```bash
|
|
95
169
|
make-folder-txt --only-folder src docs
|
|
170
|
+
make-folder-txt -ofo src docs # shorthand
|
|
96
171
|
make-folder-txt --only-file package.json README.md
|
|
172
|
+
make-folder-txt -ofi package.json README.md # shorthand
|
|
97
173
|
make-folder-txt --only-folder src --only-file package.json
|
|
98
174
|
```
|
|
99
175
|
|
package/bin/make-folder-txt.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { version } = require("../package.json");
|
|
6
|
+
const { execSync } = require("child_process");
|
|
6
7
|
|
|
7
8
|
// ── config ────────────────────────────────────────────────────────────────────
|
|
8
9
|
const IGNORE_DIRS = new Set(["node_modules", ".git", ".next", "dist", "build", ".cache"]);
|
|
@@ -37,6 +38,34 @@ function readTxtIgnore(rootDir) {
|
|
|
37
38
|
return ignorePatterns;
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
function copyToClipboard(text) {
|
|
42
|
+
try {
|
|
43
|
+
if (process.platform === 'win32') {
|
|
44
|
+
// Windows
|
|
45
|
+
execSync(`echo ${JSON.stringify(text).replace(/"/g, '""')} | clip`, { stdio: 'ignore' });
|
|
46
|
+
} else if (process.platform === 'darwin') {
|
|
47
|
+
// macOS
|
|
48
|
+
execSync(`echo ${JSON.stringify(text)} | pbcopy`, { stdio: 'ignore' });
|
|
49
|
+
} else {
|
|
50
|
+
// Linux (requires xclip or xsel)
|
|
51
|
+
try {
|
|
52
|
+
execSync(`echo ${JSON.stringify(text)} | xclip -selection clipboard`, { stdio: 'ignore' });
|
|
53
|
+
} catch {
|
|
54
|
+
try {
|
|
55
|
+
execSync(`echo ${JSON.stringify(text)} | xsel --clipboard --input`, { stdio: 'ignore' });
|
|
56
|
+
} catch {
|
|
57
|
+
console.warn('⚠️ Could not copy to clipboard. Install xclip or xsel on Linux.');
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.warn('⚠️ Could not copy to clipboard:', err.message);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
40
69
|
function collectFiles(
|
|
41
70
|
dir,
|
|
42
71
|
rootDir,
|
|
@@ -54,6 +83,7 @@ function collectFiles(
|
|
|
54
83
|
hasOnlyFilters = false,
|
|
55
84
|
rootName = "",
|
|
56
85
|
txtIgnore = new Set(),
|
|
86
|
+
force = false,
|
|
57
87
|
} = options;
|
|
58
88
|
|
|
59
89
|
let entries;
|
|
@@ -74,7 +104,7 @@ function collectFiles(
|
|
|
74
104
|
const childIndent = indent + (isLast ? " " : "│ ");
|
|
75
105
|
|
|
76
106
|
if (entry.isDirectory()) {
|
|
77
|
-
if (ignoreDirs.has(entry.name)) {
|
|
107
|
+
if (!force && ignoreDirs.has(entry.name)) {
|
|
78
108
|
if (!hasOnlyFilters) {
|
|
79
109
|
lines.push(`${indent}${connector}${entry.name}/ [skipped]`);
|
|
80
110
|
}
|
|
@@ -84,8 +114,8 @@ function collectFiles(
|
|
|
84
114
|
// Get relative path for .txtignore pattern matching
|
|
85
115
|
const relPathForIgnore = path.relative(rootDir, path.join(dir, entry.name)).split(path.sep).join("/");
|
|
86
116
|
|
|
87
|
-
// Check against .txtignore patterns (both dirname and relative path)
|
|
88
|
-
if (txtIgnore.has(entry.name) || txtIgnore.has(`${entry.name}/`) || txtIgnore.has(relPathForIgnore) || txtIgnore.has(`${relPathForIgnore}/`) || txtIgnore.has(`/${relPathForIgnore}/`)) {
|
|
117
|
+
// Check against .txtignore patterns (both dirname and relative path) unless force is enabled
|
|
118
|
+
if (!force && (txtIgnore.has(entry.name) || txtIgnore.has(`${entry.name}/`) || txtIgnore.has(relPathForIgnore) || txtIgnore.has(`${relPathForIgnore}/`) || txtIgnore.has(`/${relPathForIgnore}/`))) {
|
|
89
119
|
if (!hasOnlyFilters) {
|
|
90
120
|
lines.push(`${indent}${connector}${entry.name}/ [skipped]`);
|
|
91
121
|
}
|
|
@@ -111,6 +141,7 @@ function collectFiles(
|
|
|
111
141
|
hasOnlyFilters,
|
|
112
142
|
rootName,
|
|
113
143
|
txtIgnore,
|
|
144
|
+
force,
|
|
114
145
|
},
|
|
115
146
|
);
|
|
116
147
|
|
|
@@ -123,18 +154,18 @@ function collectFiles(
|
|
|
123
154
|
filePaths.push(...child.filePaths);
|
|
124
155
|
}
|
|
125
156
|
} else {
|
|
126
|
-
if (ignoreFiles.has(entry.name)) return;
|
|
157
|
+
if (!force && ignoreFiles.has(entry.name)) return;
|
|
127
158
|
|
|
128
159
|
// Get relative path for .txtignore pattern matching
|
|
129
160
|
const relPathForIgnore = path.relative(rootDir, path.join(dir, entry.name)).split(path.sep).join("/");
|
|
130
161
|
|
|
131
|
-
// Check against .txtignore patterns (both filename and relative path)
|
|
132
|
-
if (txtIgnore.has(entry.name) || txtIgnore.has(relPathForIgnore) || txtIgnore.has(`/${relPathForIgnore}`)) {
|
|
162
|
+
// Check against .txtignore patterns (both filename and relative path) unless force is enabled
|
|
163
|
+
if (!force && (txtIgnore.has(entry.name) || txtIgnore.has(relPathForIgnore) || txtIgnore.has(`/${relPathForIgnore}`))) {
|
|
133
164
|
return;
|
|
134
165
|
}
|
|
135
166
|
|
|
136
|
-
// Ignore .txt files that match the folder name (e.g., foldername.txt)
|
|
137
|
-
if (entry.name.endsWith('.txt') && entry.name === `${rootName}.txt`) return;
|
|
167
|
+
// Ignore .txt files that match the folder name (e.g., foldername.txt) unless force is enabled
|
|
168
|
+
if (!force && entry.name.endsWith('.txt') && entry.name === `${rootName}.txt`) return;
|
|
138
169
|
|
|
139
170
|
const shouldIncludeFile = !hasOnlyFilters || inSelectedFolder || onlyFiles.has(entry.name);
|
|
140
171
|
if (!shouldIncludeFile) return;
|
|
@@ -148,12 +179,12 @@ function collectFiles(
|
|
|
148
179
|
return { lines, filePaths, hasIncluded: filePaths.length > 0 || lines.length > 0 };
|
|
149
180
|
}
|
|
150
181
|
|
|
151
|
-
function readContent(absPath) {
|
|
182
|
+
function readContent(absPath, force = false) {
|
|
152
183
|
const ext = path.extname(absPath).toLowerCase();
|
|
153
|
-
if (BINARY_EXTS.has(ext)) return "[binary / skipped]";
|
|
184
|
+
if (!force && BINARY_EXTS.has(ext)) return "[binary / skipped]";
|
|
154
185
|
try {
|
|
155
186
|
const stat = fs.statSync(absPath);
|
|
156
|
-
if (stat.size > 500 * 1024) {
|
|
187
|
+
if (!force && stat.size > 500 * 1024) {
|
|
157
188
|
return `[file too large: ${(stat.size / 1024).toFixed(1)} KB – skipped]`;
|
|
158
189
|
}
|
|
159
190
|
return fs.readFileSync(absPath, "utf8");
|
|
@@ -166,6 +197,205 @@ function readContent(absPath) {
|
|
|
166
197
|
|
|
167
198
|
const args = process.argv.slice(2);
|
|
168
199
|
|
|
200
|
+
// Check if completion is already installed, install if not
|
|
201
|
+
function checkAndInstallCompletion() {
|
|
202
|
+
const { execSync } = require('child_process');
|
|
203
|
+
const path = require('path');
|
|
204
|
+
const os = require('os');
|
|
205
|
+
const fs = require('fs');
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const homeDir = os.homedir();
|
|
209
|
+
const shell = process.env.SHELL || '';
|
|
210
|
+
const platform = process.platform;
|
|
211
|
+
let completionInstalled = false;
|
|
212
|
+
|
|
213
|
+
if (platform === 'win32') {
|
|
214
|
+
// Check PowerShell completion - try multiple profile locations
|
|
215
|
+
const profilePaths = [
|
|
216
|
+
path.join(homeDir, 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1'),
|
|
217
|
+
path.join(homeDir, 'Documents', 'PowerShell', 'Microsoft.PowerShell_profile.ps1'),
|
|
218
|
+
path.join(homeDir, '.config', 'powershell', 'Microsoft.PowerShell_profile.ps1')
|
|
219
|
+
];
|
|
220
|
+
|
|
221
|
+
for (const profilePath of profilePaths) {
|
|
222
|
+
if (fs.existsSync(profilePath)) {
|
|
223
|
+
const profileContent = fs.readFileSync(profilePath, 'utf8');
|
|
224
|
+
if (profileContent.includes('make-folder-txt-completion')) {
|
|
225
|
+
completionInstalled = true;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
} else if (shell.includes('zsh')) {
|
|
231
|
+
// Check zsh completion
|
|
232
|
+
const zshrc = path.join(homeDir, '.zshrc');
|
|
233
|
+
if (fs.existsSync(zshrc)) {
|
|
234
|
+
const zshrcContent = fs.readFileSync(zshrc, 'utf8');
|
|
235
|
+
if (zshrcContent.includes('make-folder-txt')) {
|
|
236
|
+
completionInstalled = true;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
} else {
|
|
240
|
+
// Check bash completion
|
|
241
|
+
const bashrc = path.join(homeDir, '.bashrc');
|
|
242
|
+
if (fs.existsSync(bashrc)) {
|
|
243
|
+
const bashrcContent = fs.readFileSync(bashrc, 'utf8');
|
|
244
|
+
if (bashrcContent.includes('make-folder-txt-completion')) {
|
|
245
|
+
completionInstalled = true;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// If completion is not installed, install it automatically
|
|
251
|
+
if (!completionInstalled) {
|
|
252
|
+
console.log('🔧 Installing shell autocompletion for make-folder-txt...');
|
|
253
|
+
|
|
254
|
+
if (platform === 'win32') {
|
|
255
|
+
// Windows PowerShell
|
|
256
|
+
try {
|
|
257
|
+
execSync('powershell -Command "Get-Host"', { stdio: 'ignore' });
|
|
258
|
+
const installScript = path.join(__dirname, '..', 'completion', 'install-powershell-completion.ps1');
|
|
259
|
+
execSync(`powershell -ExecutionPolicy Bypass -File "${installScript}"`, { stdio: 'ignore' });
|
|
260
|
+
console.log('✅ PowerShell completion installed!');
|
|
261
|
+
} catch (err) {
|
|
262
|
+
// Silent fail for PowerShell
|
|
263
|
+
}
|
|
264
|
+
} else if (shell.includes('zsh')) {
|
|
265
|
+
// zsh
|
|
266
|
+
try {
|
|
267
|
+
const zshrc = path.join(homeDir, '.zshrc');
|
|
268
|
+
const completionDir = path.join(homeDir, '.zsh', 'completions');
|
|
269
|
+
execSync(`mkdir -p "${completionDir}"`, { stdio: 'ignore' });
|
|
270
|
+
const completionPath = path.join(__dirname, '..', 'completion', 'make-folder-txt-completion.zsh');
|
|
271
|
+
execSync(`cp "${completionPath}" "${completionDir}/_make-folder-txt"`, { stdio: 'ignore' });
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
const zshrcContent = fs.readFileSync(zshrc, 'utf8');
|
|
275
|
+
if (!zshrcContent.includes('fpath+=~/.zsh/completions')) {
|
|
276
|
+
fs.appendFileSync(zshrc, '\n# make-folder-txt completion\nfpath+=~/.zsh/completions\nautoload -U compinit && compinit\n');
|
|
277
|
+
}
|
|
278
|
+
} catch (e) {
|
|
279
|
+
fs.writeFileSync(zshrc, '# make-folder-txt completion\nfpath+=~/.zsh/completions\nautoload -U compinit && compinit\n');
|
|
280
|
+
}
|
|
281
|
+
console.log('✅ Zsh completion installed!');
|
|
282
|
+
} catch (err) {
|
|
283
|
+
// Silent fail for zsh
|
|
284
|
+
}
|
|
285
|
+
} else {
|
|
286
|
+
// bash
|
|
287
|
+
try {
|
|
288
|
+
const bashrc = path.join(homeDir, '.bashrc');
|
|
289
|
+
const completionPath = path.join(__dirname, '..', 'completion', 'make-folder-txt-completion.bash');
|
|
290
|
+
try {
|
|
291
|
+
const bashrcContent = fs.readFileSync(bashrc, 'utf8');
|
|
292
|
+
if (!bashrcContent.includes('make-folder-txt-completion.bash')) {
|
|
293
|
+
fs.appendFileSync(bashrc, `\n# make-folder-txt completion\nsource "${completionPath}"\n`);
|
|
294
|
+
}
|
|
295
|
+
} catch (e) {
|
|
296
|
+
fs.writeFileSync(bashrc, `# make-folder-txt completion\nsource "${completionPath}"\n`);
|
|
297
|
+
}
|
|
298
|
+
console.log('✅ Bash completion installed!');
|
|
299
|
+
} catch (err) {
|
|
300
|
+
// Silent fail for bash
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
console.log('💡 Restart your terminal to enable autocompletion');
|
|
305
|
+
console.log('');
|
|
306
|
+
}
|
|
307
|
+
} catch (err) {
|
|
308
|
+
// Silent fail - don't interrupt the main functionality
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Run completion check on first run (but not for help/version commands)
|
|
313
|
+
if (!args.includes("--help") && !args.includes("-h") &&
|
|
314
|
+
!args.includes("--version") && !args.includes("-v") &&
|
|
315
|
+
!args.includes("--install-completion")) {
|
|
316
|
+
checkAndInstallCompletion();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (args.includes("--install-completion")) {
|
|
320
|
+
const { execSync } = require('child_process');
|
|
321
|
+
const path = require('path');
|
|
322
|
+
const os = require('os');
|
|
323
|
+
|
|
324
|
+
try {
|
|
325
|
+
const homeDir = os.homedir();
|
|
326
|
+
const shell = process.env.SHELL || '';
|
|
327
|
+
const platform = process.platform;
|
|
328
|
+
|
|
329
|
+
if (platform === 'win32') {
|
|
330
|
+
// Windows - Check if PowerShell is available
|
|
331
|
+
try {
|
|
332
|
+
execSync('powershell -Command "Get-Host"', { stdio: 'ignore' });
|
|
333
|
+
|
|
334
|
+
// Install PowerShell completion
|
|
335
|
+
const completionScript = path.join(__dirname, '..', 'completion', 'make-folder-txt-completion.ps1');
|
|
336
|
+
const installScript = path.join(__dirname, '..', 'completion', 'install-powershell-completion.ps1');
|
|
337
|
+
|
|
338
|
+
// Run the PowerShell installation script
|
|
339
|
+
execSync(`powershell -ExecutionPolicy Bypass -File "${installScript}"`, { stdio: 'inherit' });
|
|
340
|
+
|
|
341
|
+
} catch (err) {
|
|
342
|
+
console.error('❌ Failed to install PowerShell completion:', err.message);
|
|
343
|
+
process.exit(1);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
} else if (shell.includes('zsh')) {
|
|
347
|
+
// Install for zsh
|
|
348
|
+
const zshrc = path.join(homeDir, '.zshrc');
|
|
349
|
+
const completionDir = path.join(homeDir, '.zsh', 'completions');
|
|
350
|
+
|
|
351
|
+
// Create completions directory if it doesn't exist
|
|
352
|
+
try {
|
|
353
|
+
execSync(`mkdir -p "${completionDir}"`, { stdio: 'ignore' });
|
|
354
|
+
} catch (e) {}
|
|
355
|
+
|
|
356
|
+
// Copy completion file
|
|
357
|
+
const completionPath = path.join(__dirname, '..', 'completion', 'make-folder-txt-completion.zsh');
|
|
358
|
+
execSync(`cp "${completionPath}" "${completionDir}/_make-folder-txt"`, { stdio: 'ignore' });
|
|
359
|
+
|
|
360
|
+
// Add to .zshrc if not already there
|
|
361
|
+
try {
|
|
362
|
+
const zshrcContent = fs.readFileSync(zshrc, 'utf8');
|
|
363
|
+
if (!zshrcContent.includes('fpath+=~/.zsh/completions')) {
|
|
364
|
+
fs.appendFileSync(zshrc, '\n# make-folder-txt completion\nfpath+=~/.zsh/completions\nautoload -U compinit && compinit\n');
|
|
365
|
+
}
|
|
366
|
+
} catch (e) {
|
|
367
|
+
// .zshrc doesn't exist, create it
|
|
368
|
+
fs.writeFileSync(zshrc, '# make-folder-txt completion\nfpath+=~/.zsh/completions\nautoload -U compinit && compinit\n');
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
console.log('✅ Zsh completion installed! Restart your terminal or run: source ~/.zshrc');
|
|
372
|
+
|
|
373
|
+
} else {
|
|
374
|
+
// Install for bash
|
|
375
|
+
const bashrc = path.join(homeDir, '.bashrc');
|
|
376
|
+
const completionPath = path.join(__dirname, '..', 'completion', 'make-folder-txt-completion.bash');
|
|
377
|
+
|
|
378
|
+
// Add to .bashrc if not already there
|
|
379
|
+
try {
|
|
380
|
+
const bashrcContent = fs.readFileSync(bashrc, 'utf8');
|
|
381
|
+
if (!bashrcContent.includes('make-folder-txt-completion.bash')) {
|
|
382
|
+
fs.appendFileSync(bashrc, `\n# make-folder-txt completion\nsource "${completionPath}"\n`);
|
|
383
|
+
}
|
|
384
|
+
} catch (e) {
|
|
385
|
+
// .bashrc doesn't exist, create it
|
|
386
|
+
fs.writeFileSync(bashrc, `# make-folder-txt completion\nsource "${completionPath}"\n`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
console.log('✅ Bash completion installed! Restart your terminal or run: source ~/.bashrc');
|
|
390
|
+
}
|
|
391
|
+
} catch (err) {
|
|
392
|
+
console.error('❌ Failed to install completion:', err.message);
|
|
393
|
+
process.exit(1);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
process.exit(0);
|
|
397
|
+
}
|
|
398
|
+
|
|
169
399
|
if (args.includes("-v") || args.includes("--version")) {
|
|
170
400
|
console.log(`v${version}`);
|
|
171
401
|
console.log("Built by Muhammad Saad Amin");
|
|
@@ -181,19 +411,29 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
181
411
|
make-folder-txt [options]
|
|
182
412
|
|
|
183
413
|
\x1b[33mOPTIONS\x1b[0m
|
|
184
|
-
--ignore-folder <names...> Ignore specific folders by name
|
|
185
|
-
--ignore-file <names...> Ignore specific files by name
|
|
186
|
-
--only-folder <names...> Include only specific folders
|
|
187
|
-
--only-file <names...> Include only specific files
|
|
188
|
-
--
|
|
189
|
-
--
|
|
414
|
+
--ignore-folder, -ifo <names...> Ignore specific folders by name
|
|
415
|
+
--ignore-file, -ifi <names...> Ignore specific files by name
|
|
416
|
+
--only-folder, -ofo <names...> Include only specific folders
|
|
417
|
+
--only-file, -ofi <names...> Include only specific files
|
|
418
|
+
--copy Copy output to clipboard
|
|
419
|
+
--force Include everything (overrides all ignore patterns)
|
|
420
|
+
--install-completion Install shell autocompletion (bash/zsh/PowerShell) - usually automatic
|
|
421
|
+
--help, -h Show this help message
|
|
422
|
+
--version, -v Show version information
|
|
190
423
|
|
|
191
424
|
\x1b[33mEXAMPLES\x1b[0m
|
|
192
425
|
make-folder-txt
|
|
426
|
+
make-folder-txt --copy
|
|
427
|
+
make-folder-txt --force
|
|
428
|
+
make-folder-txt --install-completion
|
|
193
429
|
make-folder-txt --ignore-folder node_modules dist
|
|
430
|
+
make-folder-txt -ifo node_modules dist
|
|
194
431
|
make-folder-txt --ignore-file .env .env.local
|
|
432
|
+
make-folder-txt -ifi .env .env.local
|
|
195
433
|
make-folder-txt --only-folder src docs
|
|
434
|
+
make-folder-txt -ofo src docs
|
|
196
435
|
make-folder-txt --only-file package.json README.md
|
|
436
|
+
make-folder-txt -ofi package.json README.md
|
|
197
437
|
|
|
198
438
|
\x1b[33m.TXTIGNORE FILE\x1b[0m
|
|
199
439
|
Create a .txtignore file in your project root to specify files/folders to ignore.
|
|
@@ -214,11 +454,23 @@ const ignoreFiles = new Set(IGNORE_FILES);
|
|
|
214
454
|
const onlyFolders = new Set();
|
|
215
455
|
const onlyFiles = new Set();
|
|
216
456
|
let outputArg = null;
|
|
457
|
+
let copyToClipboardFlag = false;
|
|
458
|
+
let forceFlag = false;
|
|
217
459
|
|
|
218
460
|
for (let i = 0; i < args.length; i += 1) {
|
|
219
461
|
const arg = args[i];
|
|
220
462
|
|
|
221
|
-
if (arg === "--
|
|
463
|
+
if (arg === "--copy") {
|
|
464
|
+
copyToClipboardFlag = true;
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (arg === "--force") {
|
|
469
|
+
forceFlag = true;
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (arg === "--ignore-folder" || arg === "-ifo") {
|
|
222
474
|
let consumed = 0;
|
|
223
475
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
224
476
|
ignoreDirs.add(args[i + 1]);
|
|
@@ -232,8 +484,10 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
232
484
|
continue;
|
|
233
485
|
}
|
|
234
486
|
|
|
235
|
-
if (arg.startsWith("--ignore-folder=")) {
|
|
236
|
-
const value = arg.
|
|
487
|
+
if (arg.startsWith("--ignore-folder=") || arg.startsWith("-ifo=")) {
|
|
488
|
+
const value = arg.startsWith("--ignore-folder=")
|
|
489
|
+
? arg.slice("--ignore-folder=".length)
|
|
490
|
+
: arg.slice("-ifo=".length);
|
|
237
491
|
if (!value) {
|
|
238
492
|
console.error("Error: --ignore-folder requires a folder name.");
|
|
239
493
|
process.exit(1);
|
|
@@ -242,7 +496,7 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
242
496
|
continue;
|
|
243
497
|
}
|
|
244
498
|
|
|
245
|
-
if (arg === "--ignore-file") {
|
|
499
|
+
if (arg === "--ignore-file" || arg === "-ifi") {
|
|
246
500
|
let consumed = 0;
|
|
247
501
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
248
502
|
ignoreFiles.add(args[i + 1]);
|
|
@@ -256,8 +510,10 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
256
510
|
continue;
|
|
257
511
|
}
|
|
258
512
|
|
|
259
|
-
if (arg.startsWith("--ignore-file=")) {
|
|
260
|
-
const value = arg.
|
|
513
|
+
if (arg.startsWith("--ignore-file=") || arg.startsWith("-ifi=")) {
|
|
514
|
+
const value = arg.startsWith("--ignore-file=")
|
|
515
|
+
? arg.slice("--ignore-file=".length)
|
|
516
|
+
: arg.slice("-ifi=".length);
|
|
261
517
|
if (!value) {
|
|
262
518
|
console.error("Error: --ignore-file requires a file name.");
|
|
263
519
|
process.exit(1);
|
|
@@ -266,7 +522,7 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
266
522
|
continue;
|
|
267
523
|
}
|
|
268
524
|
|
|
269
|
-
if (arg === "--only-folder") {
|
|
525
|
+
if (arg === "--only-folder" || arg === "-ofo") {
|
|
270
526
|
let consumed = 0;
|
|
271
527
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
272
528
|
onlyFolders.add(args[i + 1]);
|
|
@@ -280,8 +536,10 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
280
536
|
continue;
|
|
281
537
|
}
|
|
282
538
|
|
|
283
|
-
if (arg.startsWith("--only-folder=")) {
|
|
284
|
-
const value = arg.
|
|
539
|
+
if (arg.startsWith("--only-folder=") || arg.startsWith("-ofo=")) {
|
|
540
|
+
const value = arg.startsWith("--only-folder=")
|
|
541
|
+
? arg.slice("--only-folder=".length)
|
|
542
|
+
: arg.slice("-ofo=".length);
|
|
285
543
|
if (!value) {
|
|
286
544
|
console.error("Error: --only-folder requires a folder name.");
|
|
287
545
|
process.exit(1);
|
|
@@ -290,7 +548,7 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
290
548
|
continue;
|
|
291
549
|
}
|
|
292
550
|
|
|
293
|
-
if (arg === "--only-file") {
|
|
551
|
+
if (arg === "--only-file" || arg === "-ofi") {
|
|
294
552
|
let consumed = 0;
|
|
295
553
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
296
554
|
onlyFiles.add(args[i + 1]);
|
|
@@ -304,8 +562,10 @@ for (let i = 0; i < args.length; i += 1) {
|
|
|
304
562
|
continue;
|
|
305
563
|
}
|
|
306
564
|
|
|
307
|
-
if (arg.startsWith("--only-file=")) {
|
|
308
|
-
const value = arg.
|
|
565
|
+
if (arg.startsWith("--only-file=") || arg.startsWith("-ofi=")) {
|
|
566
|
+
const value = arg.startsWith("--only-file=")
|
|
567
|
+
? arg.slice("--only-file=".length)
|
|
568
|
+
: arg.slice("-ofi=".length);
|
|
309
569
|
if (!value) {
|
|
310
570
|
console.error("Error: --only-file requires a file name.");
|
|
311
571
|
process.exit(1);
|
|
@@ -348,7 +608,7 @@ const { lines: treeLines, filePaths } = collectFiles(
|
|
|
348
608
|
ignoreFiles,
|
|
349
609
|
onlyFolders,
|
|
350
610
|
onlyFiles,
|
|
351
|
-
{ hasOnlyFilters, rootName, txtIgnore },
|
|
611
|
+
{ hasOnlyFilters, rootName, txtIgnore, force: forceFlag },
|
|
352
612
|
);
|
|
353
613
|
|
|
354
614
|
// ── build output ──────────────────────────────────────────────────────────────
|
|
@@ -380,7 +640,7 @@ filePaths.forEach(({ abs, rel }) => {
|
|
|
380
640
|
out.push(subDivider);
|
|
381
641
|
out.push(`FILE: ${rel}`);
|
|
382
642
|
out.push(subDivider);
|
|
383
|
-
out.push(readContent(abs));
|
|
643
|
+
out.push(readContent(abs, forceFlag));
|
|
384
644
|
});
|
|
385
645
|
|
|
386
646
|
out.push("");
|
|
@@ -394,4 +654,14 @@ const sizeKB = (fs.statSync(outputFile).size / 1024).toFixed(1);
|
|
|
394
654
|
console.log(`✅ Done!`);
|
|
395
655
|
console.log(`📄 Output : ${outputFile}`);
|
|
396
656
|
console.log(`📊 Size : ${sizeKB} KB`);
|
|
397
|
-
console.log(`🗂️ Files : ${filePaths.length}
|
|
657
|
+
console.log(`🗂️ Files : ${filePaths.length}`);
|
|
658
|
+
|
|
659
|
+
if (copyToClipboardFlag) {
|
|
660
|
+
const content = fs.readFileSync(outputFile, 'utf8');
|
|
661
|
+
const success = copyToClipboard(content);
|
|
662
|
+
if (success) {
|
|
663
|
+
console.log(`📋 Copied to clipboard!`);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
console.log('');
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# PowerShell completion installation script for make-folder-txt
|
|
2
|
+
|
|
3
|
+
function Install-MakeFolderTxtCompletion {
|
|
4
|
+
param(
|
|
5
|
+
[switch]$Force,
|
|
6
|
+
[switch]$CurrentUser
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
$ErrorActionPreference = 'Stop'
|
|
10
|
+
|
|
11
|
+
# Determine PowerShell profile path
|
|
12
|
+
if ($CurrentUser) {
|
|
13
|
+
$profilePath = $PROFILE.CurrentUserCurrentHost
|
|
14
|
+
} else {
|
|
15
|
+
$profilePath = $PROFILE.AllUsersCurrentHost
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# Create profile directory if it doesn't exist
|
|
19
|
+
$profileDir = Split-Path $profilePath -Parent
|
|
20
|
+
if (-not (Test-Path $profileDir)) {
|
|
21
|
+
try {
|
|
22
|
+
New-Item -ItemType Directory -Path $profileDir -Force | Out-Null
|
|
23
|
+
Write-Host "Created profile directory: $profileDir" -ForegroundColor Green
|
|
24
|
+
} catch {
|
|
25
|
+
Write-Error "Failed to create profile directory: $profileDir"
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# Get the completion script content
|
|
31
|
+
$completionScriptPath = Join-Path $PSScriptRoot 'make-folder-txt-completion.ps1'
|
|
32
|
+
if (-not (Test-Path $completionScriptPath)) {
|
|
33
|
+
Write-Error "Completion script not found: $completionScriptPath"
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
$completionContent = Get-Content $completionScriptPath -Raw
|
|
38
|
+
|
|
39
|
+
# Check if completion is already installed
|
|
40
|
+
if (Test-Path $profilePath) {
|
|
41
|
+
$profileContent = Get-Content $profilePath -Raw
|
|
42
|
+
if ($profileContent -match 'make-folder-txt.*completion') {
|
|
43
|
+
if (-not $Force) {
|
|
44
|
+
Write-Host "make-folder-txt completion is already installed in $profilePath" -ForegroundColor Yellow
|
|
45
|
+
Write-Host "Use -Force to reinstall" -ForegroundColor Yellow
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
Write-Host "Removing existing completion..." -ForegroundColor Yellow
|
|
49
|
+
# Remove existing completion
|
|
50
|
+
$profileContent = $profileContent -replace '(?s)# make-folder-txt completion.*?Register-ArgumentComplester.*?Export-ModuleMember.*?\n', ''
|
|
51
|
+
Set-Content $profilePath $profileContent -Force
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Add completion to profile
|
|
56
|
+
$completionBlock = @"
|
|
57
|
+
|
|
58
|
+
# make-folder-txt completion
|
|
59
|
+
$completionContent
|
|
60
|
+
"@
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
Add-Content $profilePath $completionBlock -Force
|
|
64
|
+
Write-Host "✅ PowerShell completion installed successfully!" -ForegroundColor Green
|
|
65
|
+
Write-Host "Added to: $profilePath" -ForegroundColor Cyan
|
|
66
|
+
Write-Host "Restart PowerShell or run: . `$profile" -ForegroundColor Cyan
|
|
67
|
+
} catch {
|
|
68
|
+
Write-Error "Failed to install completion: $_"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Auto-install if script is run directly
|
|
73
|
+
if ($MyInvocation.InvocationName -eq $MyInvocation.MyCommand.Name) {
|
|
74
|
+
Install-MakeFolderTxtCompletion -CurrentUser
|
|
75
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# make-folder-txt bash completion
|
|
3
|
+
|
|
4
|
+
_make_folder_txt_completion() {
|
|
5
|
+
local cur prev opts
|
|
6
|
+
COMPREPLY=()
|
|
7
|
+
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
8
|
+
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
9
|
+
|
|
10
|
+
opts="--ignore-folder -ifo --ignore-file -ifi --only-folder -ofo --only-file -ofi --copy --force --help --version -h -v"
|
|
11
|
+
|
|
12
|
+
case "${prev}" in
|
|
13
|
+
--ignore-folder|-ifo)
|
|
14
|
+
# Complete with folder names in current directory
|
|
15
|
+
local folders=$(ls -d */ 2>/dev/null | sed 's|/||g')
|
|
16
|
+
COMPREPLY=( $(compgen -W "${folders}" -- ${cur}) )
|
|
17
|
+
return 0
|
|
18
|
+
;;
|
|
19
|
+
--ignore-file|-ifi|--only-file|-ofi)
|
|
20
|
+
# Complete with file names in current directory
|
|
21
|
+
local files=$(ls -p 2>/dev/null | grep -v /)
|
|
22
|
+
COMPREPLY=( $(compgen -W "${files}" -- ${cur}) )
|
|
23
|
+
return 0
|
|
24
|
+
;;
|
|
25
|
+
--only-folder|-ofo)
|
|
26
|
+
# Complete with folder names in current directory
|
|
27
|
+
local folders=$(ls -d */ 2>/dev/null | sed 's|/||g')
|
|
28
|
+
COMPREPLY=( $(compgen -W "${folders}" -- ${cur}) )
|
|
29
|
+
return 0
|
|
30
|
+
;;
|
|
31
|
+
*)
|
|
32
|
+
;;
|
|
33
|
+
esac
|
|
34
|
+
|
|
35
|
+
if [[ ${cur} == -* ]]; then
|
|
36
|
+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
|
37
|
+
return 0
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
complete -F _make_folder_txt_completion make-folder-txt
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# make-folder-txt PowerShell completion script
|
|
2
|
+
|
|
3
|
+
Register-ArgumentCompleter -Native -CommandName 'make-folder-txt' -ScriptBlock {
|
|
4
|
+
param($commandName, $wordToComplete, $commandAst, $fakeBoundParameters)
|
|
5
|
+
|
|
6
|
+
# Get the current argument being completed
|
|
7
|
+
$currentArgument = $wordToComplete
|
|
8
|
+
|
|
9
|
+
# Define available options
|
|
10
|
+
$options = @(
|
|
11
|
+
'--ignore-folder', '-ifo',
|
|
12
|
+
'--ignore-file', '-ifi',
|
|
13
|
+
'--only-folder', '-ofo',
|
|
14
|
+
'--only-file', '-ofi',
|
|
15
|
+
'--copy',
|
|
16
|
+
'--force',
|
|
17
|
+
'--install-completion',
|
|
18
|
+
'--help', '-h',
|
|
19
|
+
'--version', '-v'
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Get the previous parameter to determine context
|
|
23
|
+
$previousParameter = if ($commandAst.CommandElements.Count -gt 1) {
|
|
24
|
+
$commandAst.CommandElements[-2].Extent.Text
|
|
25
|
+
} else {
|
|
26
|
+
''
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
switch ($previousParameter) {
|
|
30
|
+
{ $_ -in '--ignore-folder', '-ifo', '--only-folder', '-ofo' } {
|
|
31
|
+
# Complete with folder names
|
|
32
|
+
try {
|
|
33
|
+
$folders = Get-ChildItem -Directory -Name | Where-Object { $_ -like "*$currentArgument*" }
|
|
34
|
+
return $folders | ForEach-Object {
|
|
35
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', "Folder: $_")
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
return @()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
{ $_ -in '--ignore-file', '-ifi', '--only-file', '-ofi' } {
|
|
42
|
+
# Complete with file names
|
|
43
|
+
try {
|
|
44
|
+
$files = Get-ChildItem -File -Name | Where-Object { $_ -like "*$currentArgument*" }
|
|
45
|
+
return $files | ForEach-Object {
|
|
46
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', "File: $_")
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
return @()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
default {
|
|
53
|
+
# Complete with options
|
|
54
|
+
if ($currentArgument -like '-*') {
|
|
55
|
+
$matchingOptions = $options | Where-Object { $_ -like "*$currentArgument*" }
|
|
56
|
+
return $matchingOptions | ForEach-Object {
|
|
57
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', "Option: $_")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return @()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Export the completion function
|
|
67
|
+
Export-ModuleMember -Function *
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#compdef make-folder-txt
|
|
2
|
+
# make-folder-txt zsh completion
|
|
3
|
+
|
|
4
|
+
_make_folder_txt() {
|
|
5
|
+
local -a arguments
|
|
6
|
+
arguments=(
|
|
7
|
+
'--ignore-folder[Ignore specific folders by name]:folder:_directories'
|
|
8
|
+
'-ifo[Ignore specific folders by name]:folder:_directories'
|
|
9
|
+
'--ignore-file[Ignore specific files by name]:file:_files'
|
|
10
|
+
'-ifi[Ignore specific files by name]:file:_files'
|
|
11
|
+
'--only-folder[Include only specific folders]:folder:_directories'
|
|
12
|
+
'-ofo[Include only specific folders]:folder:_directories'
|
|
13
|
+
'--only-file[Include only specific files]:file:_files'
|
|
14
|
+
'-ofi[Include only specific files]:file:_files'
|
|
15
|
+
'--copy[Copy output to clipboard]'
|
|
16
|
+
'--force[Include everything (overrides all ignore patterns)]'
|
|
17
|
+
'--help[Show help message]'
|
|
18
|
+
'--version[Show version information]'
|
|
19
|
+
'-h[Show help message]'
|
|
20
|
+
'-v[Show version information]'
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
_arguments -s -S $arguments && return 0
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
_make_folder_txt "$@"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "make-folder-txt",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Generate a single .txt file containing the full folder structure and file contents of any project, ignoring node_modules and other junk.",
|
|
5
5
|
"main": "bin/make-folder-txt.js",
|
|
6
6
|
"bin": {
|