@fresh-editor/fresh-editor 0.1.4
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/.gitignore +2 -0
- package/LICENSE +117 -0
- package/README.md +54 -0
- package/binary-install.js +212 -0
- package/binary.js +126 -0
- package/install.js +4 -0
- package/npm-shrinkwrap.json +900 -0
- package/package.json +100 -0
- package/plugins/README.md +121 -0
- package/plugins/clangd_support.md +20 -0
- package/plugins/clangd_support.ts +323 -0
- package/plugins/color_highlighter.ts +302 -0
- package/plugins/diagnostics_panel.ts +308 -0
- package/plugins/examples/README.md +245 -0
- package/plugins/examples/async_demo.ts +165 -0
- package/plugins/examples/bookmarks.ts +329 -0
- package/plugins/examples/buffer_query_demo.ts +110 -0
- package/plugins/examples/git_grep.ts +262 -0
- package/plugins/examples/hello_world.ts +93 -0
- package/plugins/examples/virtual_buffer_demo.ts +116 -0
- package/plugins/find_references.ts +357 -0
- package/plugins/git_find_file.ts +298 -0
- package/plugins/git_grep.ts +188 -0
- package/plugins/git_log.ts +1283 -0
- package/plugins/lib/fresh.d.ts +849 -0
- package/plugins/lib/index.ts +24 -0
- package/plugins/lib/navigation-controller.ts +214 -0
- package/plugins/lib/panel-manager.ts +218 -0
- package/plugins/lib/types.ts +72 -0
- package/plugins/lib/virtual-buffer-factory.ts +158 -0
- package/plugins/manual_help.ts +243 -0
- package/plugins/markdown_compose.ts +1207 -0
- package/plugins/merge_conflict.ts +1811 -0
- package/plugins/path_complete.ts +163 -0
- package/plugins/search_replace.ts +481 -0
- package/plugins/todo_highlighter.ts +204 -0
- package/plugins/welcome.ts +74 -0
- package/run-fresh.js +4 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/// <reference path="../types/fresh.d.ts" />
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Git Find File Plugin
|
|
5
|
+
*
|
|
6
|
+
* Provides interactive file finding functionality with fuzzy search
|
|
7
|
+
* for git-tracked files. Uses the prompt API for interactive selection.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// State management
|
|
11
|
+
let allFiles: string[] = [];
|
|
12
|
+
let filteredFiles: string[] = [];
|
|
13
|
+
let isLoading = false;
|
|
14
|
+
|
|
15
|
+
// Simple fuzzy filter function
|
|
16
|
+
function fuzzyMatch(str: string, pattern: string): boolean {
|
|
17
|
+
if (pattern === "") {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
str = str.toLowerCase();
|
|
22
|
+
pattern = pattern.toLowerCase();
|
|
23
|
+
|
|
24
|
+
let strIdx = 0;
|
|
25
|
+
let patIdx = 0;
|
|
26
|
+
|
|
27
|
+
while (strIdx < str.length && patIdx < pattern.length) {
|
|
28
|
+
if (str[strIdx] === pattern[patIdx]) {
|
|
29
|
+
patIdx++;
|
|
30
|
+
}
|
|
31
|
+
strIdx++;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return patIdx >= pattern.length;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Score a fuzzy match (higher is better)
|
|
38
|
+
function fuzzyScore(str: string, pattern: string): number {
|
|
39
|
+
if (pattern === "") return 0;
|
|
40
|
+
|
|
41
|
+
str = str.toLowerCase();
|
|
42
|
+
pattern = pattern.toLowerCase();
|
|
43
|
+
|
|
44
|
+
let score = 0;
|
|
45
|
+
let strIdx = 0;
|
|
46
|
+
let patIdx = 0;
|
|
47
|
+
let consecutiveMatches = 0;
|
|
48
|
+
let lastMatchIdx = -1;
|
|
49
|
+
|
|
50
|
+
while (strIdx < str.length && patIdx < pattern.length) {
|
|
51
|
+
if (str[strIdx] === pattern[patIdx]) {
|
|
52
|
+
// Bonus for consecutive matches
|
|
53
|
+
if (lastMatchIdx === strIdx - 1) {
|
|
54
|
+
consecutiveMatches++;
|
|
55
|
+
score += consecutiveMatches * 10;
|
|
56
|
+
} else {
|
|
57
|
+
consecutiveMatches = 1;
|
|
58
|
+
score += 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Bonus for matching at start of path segments
|
|
62
|
+
if (strIdx === 0 || str[strIdx - 1] === "/" || str[strIdx - 1] === "_" || str[strIdx - 1] === "-") {
|
|
63
|
+
score += 15;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Bonus for matching filename (after last /)
|
|
67
|
+
const lastSlash = str.lastIndexOf("/");
|
|
68
|
+
if (strIdx > lastSlash) {
|
|
69
|
+
score += 5;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
lastMatchIdx = strIdx;
|
|
73
|
+
patIdx++;
|
|
74
|
+
}
|
|
75
|
+
strIdx++;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Penalty for longer paths
|
|
79
|
+
score -= str.length * 0.1;
|
|
80
|
+
|
|
81
|
+
return patIdx >= pattern.length ? score : -1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Filter and sort files by query using fuzzy matching
|
|
85
|
+
function filterFiles(files: string[], query: string): string[] {
|
|
86
|
+
if (query === "" || query.trim() === "") {
|
|
87
|
+
// Return first 100 files for empty query
|
|
88
|
+
return files.slice(0, 100);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const scored: Array<{ file: string; score: number }> = [];
|
|
92
|
+
|
|
93
|
+
for (const file of files) {
|
|
94
|
+
const score = fuzzyScore(file, query);
|
|
95
|
+
if (score > 0) {
|
|
96
|
+
scored.push({ file, score });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Stop early if we have enough high-quality matches
|
|
100
|
+
if (scored.length >= 500) {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Sort by score descending
|
|
106
|
+
scored.sort((a, b) => b.score - a.score);
|
|
107
|
+
|
|
108
|
+
// Return top 100 results
|
|
109
|
+
return scored.slice(0, 100).map((s) => s.file);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Load git-tracked files asynchronously
|
|
113
|
+
async function loadGitFiles(): Promise<void> {
|
|
114
|
+
if (isLoading) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
isLoading = true;
|
|
119
|
+
editor.setStatus("Loading git files...");
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const result = await editor.spawnProcess("git", ["ls-files"]);
|
|
123
|
+
|
|
124
|
+
if (result.exit_code === 0) {
|
|
125
|
+
allFiles = result.stdout.split("\n").filter((line) => line.trim() !== "");
|
|
126
|
+
|
|
127
|
+
editor.debug(`Loaded ${allFiles.length} git-tracked files`);
|
|
128
|
+
editor.setStatus(`Git Find File: ${allFiles.length} files indexed`);
|
|
129
|
+
} else {
|
|
130
|
+
editor.debug(`Failed to load git files: ${result.stderr}`);
|
|
131
|
+
editor.setStatus(`Error loading git files: ${result.stderr}`);
|
|
132
|
+
allFiles = [];
|
|
133
|
+
}
|
|
134
|
+
} catch (e) {
|
|
135
|
+
editor.debug(`Exception loading git files: ${e}`);
|
|
136
|
+
editor.setStatus("Failed to load git files");
|
|
137
|
+
allFiles = [];
|
|
138
|
+
} finally {
|
|
139
|
+
isLoading = false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Convert filtered files to prompt suggestions
|
|
144
|
+
function filesToSuggestions(files: string[]): PromptSuggestion[] {
|
|
145
|
+
return files.map((file) => {
|
|
146
|
+
return {
|
|
147
|
+
text: file,
|
|
148
|
+
description: undefined,
|
|
149
|
+
value: file,
|
|
150
|
+
disabled: false,
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Global function to start file finder
|
|
156
|
+
globalThis.start_git_find_file = async function (): Promise<void> {
|
|
157
|
+
// Load files if not already loaded
|
|
158
|
+
if (allFiles.length === 0 && !isLoading) {
|
|
159
|
+
await loadGitFiles();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (allFiles.length === 0) {
|
|
163
|
+
editor.setStatus("No git-tracked files found");
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Clear previous results
|
|
168
|
+
filteredFiles = [];
|
|
169
|
+
|
|
170
|
+
// Start the prompt
|
|
171
|
+
editor.startPrompt("Find file: ", "git-find-file");
|
|
172
|
+
|
|
173
|
+
// Show initial suggestions (first 100 files)
|
|
174
|
+
const initial = filterFiles(allFiles, "");
|
|
175
|
+
filteredFiles = initial;
|
|
176
|
+
editor.setPromptSuggestions(filesToSuggestions(initial));
|
|
177
|
+
editor.setStatus(`${allFiles.length} files available - type to filter`);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// React to prompt input changes
|
|
181
|
+
globalThis.onGitFindFilePromptChanged = function (args: { prompt_type: string; input: string }): boolean {
|
|
182
|
+
if (args.prompt_type !== "git-find-file") {
|
|
183
|
+
return true; // Not our prompt
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const query = args.input;
|
|
187
|
+
|
|
188
|
+
// Filter files based on query
|
|
189
|
+
const matches = filterFiles(allFiles, query);
|
|
190
|
+
filteredFiles = matches;
|
|
191
|
+
|
|
192
|
+
// Update suggestions
|
|
193
|
+
editor.setPromptSuggestions(filesToSuggestions(matches));
|
|
194
|
+
|
|
195
|
+
// Update status
|
|
196
|
+
if (matches.length > 0) {
|
|
197
|
+
if (query.trim() === "") {
|
|
198
|
+
editor.setStatus(`Showing first ${matches.length} of ${allFiles.length} files`);
|
|
199
|
+
} else {
|
|
200
|
+
editor.setStatus(`Found ${matches.length} files matching "${query}"`);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
editor.setStatus(`No files matching "${query}"`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return true;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Handle prompt confirmation (user pressed Enter)
|
|
210
|
+
globalThis.onGitFindFilePromptConfirmed = function (args: {
|
|
211
|
+
prompt_type: string;
|
|
212
|
+
selected_index: number | null;
|
|
213
|
+
input: string;
|
|
214
|
+
}): boolean {
|
|
215
|
+
if (args.prompt_type !== "git-find-file") {
|
|
216
|
+
return true; // Not our prompt
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
editor.debug(`git-find-file confirmed: selected_index=${args.selected_index}, input=${args.input}`);
|
|
220
|
+
|
|
221
|
+
// Check if user selected a suggestion
|
|
222
|
+
if (args.selected_index !== null && filteredFiles[args.selected_index]) {
|
|
223
|
+
const selectedFile = filteredFiles[args.selected_index];
|
|
224
|
+
|
|
225
|
+
editor.debug(`Opening file: ${selectedFile}`);
|
|
226
|
+
|
|
227
|
+
// Open the file at line 1
|
|
228
|
+
editor.openFile(selectedFile, 1, 1);
|
|
229
|
+
editor.setStatus(`Opened ${selectedFile}`);
|
|
230
|
+
} else if (args.input.trim() !== "") {
|
|
231
|
+
// Try to open input directly if it's a valid file path
|
|
232
|
+
const inputFile = args.input.trim();
|
|
233
|
+
|
|
234
|
+
// Check if the exact input matches any file
|
|
235
|
+
if (allFiles.includes(inputFile)) {
|
|
236
|
+
editor.openFile(inputFile, 1, 1);
|
|
237
|
+
editor.setStatus(`Opened ${inputFile}`);
|
|
238
|
+
} else {
|
|
239
|
+
editor.setStatus(`File not found: ${inputFile}`);
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
editor.setStatus("No file selected");
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return true;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// Handle prompt cancellation (user pressed Escape)
|
|
249
|
+
globalThis.onGitFindFilePromptCancelled = function (args: { prompt_type: string }): boolean {
|
|
250
|
+
if (args.prompt_type !== "git-find-file") {
|
|
251
|
+
return true; // Not our prompt
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Clear results
|
|
255
|
+
filteredFiles = [];
|
|
256
|
+
editor.setStatus("File finder cancelled");
|
|
257
|
+
|
|
258
|
+
return true;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// Register event handlers
|
|
262
|
+
editor.on("prompt_changed", "onGitFindFilePromptChanged");
|
|
263
|
+
editor.on("prompt_confirmed", "onGitFindFilePromptConfirmed");
|
|
264
|
+
editor.on("prompt_cancelled", "onGitFindFilePromptCancelled");
|
|
265
|
+
|
|
266
|
+
// Reload git files command
|
|
267
|
+
globalThis.git_reload_files = async function (): Promise<void> {
|
|
268
|
+
allFiles = [];
|
|
269
|
+
await loadGitFiles();
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Show file count command
|
|
273
|
+
globalThis.git_file_count = function (): void {
|
|
274
|
+
if (allFiles.length === 0) {
|
|
275
|
+
editor.setStatus("No git files loaded. Use 'Git Find File: Reload' to index files.");
|
|
276
|
+
} else {
|
|
277
|
+
editor.setStatus(`${allFiles.length} git-tracked files indexed`);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// Register commands
|
|
282
|
+
editor.registerCommand("Git Find File", "Find and open a git-tracked file", "start_git_find_file", "normal");
|
|
283
|
+
|
|
284
|
+
editor.registerCommand(
|
|
285
|
+
"Git Find File: Reload",
|
|
286
|
+
"Reload the git file index",
|
|
287
|
+
"git_reload_files",
|
|
288
|
+
"normal"
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
editor.registerCommand("Git Find File: Count", "Show number of indexed git files", "git_file_count", "normal");
|
|
292
|
+
|
|
293
|
+
// Note: We don't load git files on plugin init because spawning processes requires async context
|
|
294
|
+
// Files will be loaded lazily on first use
|
|
295
|
+
|
|
296
|
+
editor.debug("Git Find File plugin loaded successfully (TypeScript)");
|
|
297
|
+
editor.debug("Usage: Call start_git_find_file() or use command palette 'Git Find File'");
|
|
298
|
+
editor.setStatus("Git Find File plugin ready");
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/// <reference path="../types/fresh.d.ts" />
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Git Grep Plugin
|
|
5
|
+
*
|
|
6
|
+
* Provides interactive git grep functionality with live search results.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
interface GrepMatch {
|
|
10
|
+
file: string;
|
|
11
|
+
line: number;
|
|
12
|
+
column: number;
|
|
13
|
+
content: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// State management
|
|
17
|
+
let gitGrepResults: GrepMatch[] = [];
|
|
18
|
+
|
|
19
|
+
// Parse git grep output line
|
|
20
|
+
// Format: file:line:column:content
|
|
21
|
+
function parseGitGrepLine(line: string): GrepMatch | null {
|
|
22
|
+
const match = line.match(/^([^:]+):(\d+):(\d+):(.*)$/);
|
|
23
|
+
if (match) {
|
|
24
|
+
return {
|
|
25
|
+
file: match[1],
|
|
26
|
+
line: parseInt(match[2], 10),
|
|
27
|
+
column: parseInt(match[3], 10),
|
|
28
|
+
content: match[4].trimStart(),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Parse git grep output into suggestions
|
|
35
|
+
function parseGitGrepOutput(stdout: string): {
|
|
36
|
+
results: GrepMatch[];
|
|
37
|
+
suggestions: PromptSuggestion[];
|
|
38
|
+
} {
|
|
39
|
+
const results: GrepMatch[] = [];
|
|
40
|
+
const suggestions: PromptSuggestion[] = [];
|
|
41
|
+
|
|
42
|
+
for (const line of stdout.split("\n")) {
|
|
43
|
+
if (!line.trim()) continue;
|
|
44
|
+
const match = parseGitGrepLine(line);
|
|
45
|
+
if (match) {
|
|
46
|
+
results.push(match);
|
|
47
|
+
suggestions.push({
|
|
48
|
+
text: `${match.file}:${match.line}:${match.column}`,
|
|
49
|
+
description: match.content,
|
|
50
|
+
value: `${match.file}:${match.line}:${match.column}`,
|
|
51
|
+
disabled: false,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Limit to 100 results for performance
|
|
55
|
+
if (results.length >= 100) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { results, suggestions };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Global function to start git grep
|
|
65
|
+
globalThis.start_git_grep = function(): void {
|
|
66
|
+
// Clear previous results
|
|
67
|
+
gitGrepResults = [];
|
|
68
|
+
|
|
69
|
+
// Start the prompt
|
|
70
|
+
editor.startPrompt("Git grep: ", "git-grep");
|
|
71
|
+
editor.setStatus("Type to search...");
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// React to prompt input changes
|
|
75
|
+
globalThis.onGitGrepPromptChanged = function(args: {
|
|
76
|
+
prompt_type: string;
|
|
77
|
+
input: string;
|
|
78
|
+
}): boolean {
|
|
79
|
+
if (args.prompt_type !== "git-grep") {
|
|
80
|
+
return true; // Not our prompt
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const query = args.input;
|
|
84
|
+
|
|
85
|
+
// Don't search for empty queries
|
|
86
|
+
if (!query || query.trim() === "") {
|
|
87
|
+
editor.setPromptSuggestions([]);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Spawn git grep asynchronously
|
|
92
|
+
editor.spawnProcess("git", ["grep", "-n", "--column", "-I", "--", query])
|
|
93
|
+
.then((result) => {
|
|
94
|
+
if (result.exit_code === 0) {
|
|
95
|
+
// Parse results and update suggestions
|
|
96
|
+
const { results, suggestions } = parseGitGrepOutput(result.stdout);
|
|
97
|
+
gitGrepResults = results;
|
|
98
|
+
|
|
99
|
+
// Update prompt with suggestions
|
|
100
|
+
editor.setPromptSuggestions(suggestions);
|
|
101
|
+
|
|
102
|
+
// Update status
|
|
103
|
+
if (results.length > 0) {
|
|
104
|
+
editor.setStatus(`Found ${results.length} matches`);
|
|
105
|
+
} else {
|
|
106
|
+
editor.setStatus("No matches found");
|
|
107
|
+
}
|
|
108
|
+
} else if (result.exit_code === 1) {
|
|
109
|
+
// No matches found (git grep returns 1)
|
|
110
|
+
gitGrepResults = [];
|
|
111
|
+
editor.setPromptSuggestions([]);
|
|
112
|
+
editor.setStatus("No matches found");
|
|
113
|
+
} else {
|
|
114
|
+
// Error occurred
|
|
115
|
+
editor.setStatus(`Git grep error: ${result.stderr}`);
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
.catch((e) => {
|
|
119
|
+
editor.setStatus(`Git grep error: ${e}`);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return true;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Handle prompt confirmation (user pressed Enter)
|
|
126
|
+
globalThis.onGitGrepPromptConfirmed = function(args: {
|
|
127
|
+
prompt_type: string;
|
|
128
|
+
selected_index: number | null;
|
|
129
|
+
input: string;
|
|
130
|
+
}): boolean {
|
|
131
|
+
if (args.prompt_type !== "git-grep") {
|
|
132
|
+
return true; // Not our prompt
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
editor.debug(
|
|
136
|
+
`prompt-confirmed: selected_index=${args.selected_index}, num_results=${gitGrepResults.length}`
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Check if user selected a suggestion
|
|
140
|
+
if (args.selected_index !== null && gitGrepResults[args.selected_index]) {
|
|
141
|
+
const selected = gitGrepResults[args.selected_index];
|
|
142
|
+
|
|
143
|
+
editor.debug(`Opening file: ${selected.file}:${selected.line}:${selected.column}`);
|
|
144
|
+
|
|
145
|
+
// Open the file at the specific location
|
|
146
|
+
editor.openFile(selected.file, selected.line, selected.column);
|
|
147
|
+
editor.setStatus(`Opened ${selected.file}:${selected.line}:${selected.column}`);
|
|
148
|
+
} else {
|
|
149
|
+
// No selection
|
|
150
|
+
editor.debug("No file selected - selected_index is null or out of bounds");
|
|
151
|
+
editor.setStatus("No file selected");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return true;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Handle prompt cancellation (user pressed Escape)
|
|
158
|
+
globalThis.onGitGrepPromptCancelled = function(args: {
|
|
159
|
+
prompt_type: string;
|
|
160
|
+
}): boolean {
|
|
161
|
+
if (args.prompt_type !== "git-grep") {
|
|
162
|
+
return true; // Not our prompt
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Clear results
|
|
166
|
+
gitGrepResults = [];
|
|
167
|
+
editor.setStatus("Git grep cancelled");
|
|
168
|
+
|
|
169
|
+
return true;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// Register event handlers
|
|
173
|
+
editor.on("prompt_changed", "onGitGrepPromptChanged");
|
|
174
|
+
editor.on("prompt_confirmed", "onGitGrepPromptConfirmed");
|
|
175
|
+
editor.on("prompt_cancelled", "onGitGrepPromptCancelled");
|
|
176
|
+
|
|
177
|
+
// Register command
|
|
178
|
+
editor.registerCommand(
|
|
179
|
+
"Git Grep",
|
|
180
|
+
"Search for text in git-tracked files",
|
|
181
|
+
"start_git_grep",
|
|
182
|
+
"normal"
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// Log that plugin loaded successfully
|
|
186
|
+
editor.debug("Git Grep plugin loaded successfully (TypeScript)");
|
|
187
|
+
editor.debug("Usage: Call start_git_grep() or use command palette 'Git Grep'");
|
|
188
|
+
editor.setStatus("Git Grep plugin ready");
|