@fresh-editor/fresh-editor 0.1.83 → 0.1.87

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.
@@ -37,6 +37,318 @@ type TextPropertyEntry = {
37
37
  */
38
38
  properties?: Record<string, unknown>;
39
39
  };
40
+ type TsCompositeLayoutConfig = {
41
+ /**
42
+ * Layout type: "side-by-side", "stacked", or "unified"
43
+ */
44
+ type: string;
45
+ /**
46
+ * Width ratios for side-by-side (e.g., [0.5, 0.5])
47
+ */
48
+ ratios: Array<number> | null;
49
+ /**
50
+ * Show separator between panes
51
+ */
52
+ showSeparator: boolean;
53
+ /**
54
+ * Spacing for stacked layout
55
+ */
56
+ spacing: number | null;
57
+ };
58
+ type TsCompositeSourceConfig = {
59
+ /**
60
+ * Buffer ID of the source buffer (required)
61
+ */
62
+ bufferId: number;
63
+ /**
64
+ * Label for this pane (e.g., "OLD", "NEW")
65
+ */
66
+ label: string;
67
+ /**
68
+ * Whether this pane is editable
69
+ */
70
+ editable: boolean;
71
+ /**
72
+ * Style configuration
73
+ */
74
+ style: TsCompositePaneStyle | null;
75
+ };
76
+ type TsCompositePaneStyle = {
77
+ /**
78
+ * Background color for added lines (RGB)
79
+ * Using [u8; 3] instead of (u8, u8, u8) for better rquickjs_serde compatibility
80
+ */
81
+ addBg: [number, number, number] | null;
82
+ /**
83
+ * Background color for removed lines (RGB)
84
+ */
85
+ removeBg: [number, number, number] | null;
86
+ /**
87
+ * Background color for modified lines (RGB)
88
+ */
89
+ modifyBg: [number, number, number] | null;
90
+ /**
91
+ * Gutter style: "line-numbers", "diff-markers", "both", or "none"
92
+ */
93
+ gutterStyle: string | null;
94
+ };
95
+ type TsCompositeHunk = {
96
+ /**
97
+ * Starting line in old buffer (0-indexed)
98
+ */
99
+ oldStart: number;
100
+ /**
101
+ * Number of lines in old buffer
102
+ */
103
+ oldCount: number;
104
+ /**
105
+ * Starting line in new buffer (0-indexed)
106
+ */
107
+ newStart: number;
108
+ /**
109
+ * Number of lines in new buffer
110
+ */
111
+ newCount: number;
112
+ };
113
+ type TsCreateCompositeBufferOptions = {
114
+ /**
115
+ * Buffer name (displayed in tabs/title)
116
+ */
117
+ name: string;
118
+ /**
119
+ * Mode for keybindings
120
+ */
121
+ mode: string;
122
+ /**
123
+ * Layout configuration
124
+ */
125
+ layout: TsCompositeLayoutConfig;
126
+ /**
127
+ * Source pane configurations
128
+ */
129
+ sources: Array<TsCompositeSourceConfig>;
130
+ /**
131
+ * Diff hunks for alignment (optional)
132
+ */
133
+ hunks: Array<TsCompositeHunk> | null;
134
+ };
135
+ type ViewportInfo = {
136
+ /**
137
+ * Byte position of the first visible line
138
+ */
139
+ topByte: number;
140
+ /**
141
+ * Left column offset (horizontal scroll)
142
+ */
143
+ leftColumn: number;
144
+ /**
145
+ * Viewport width
146
+ */
147
+ width: number;
148
+ /**
149
+ * Viewport height
150
+ */
151
+ height: number;
152
+ };
153
+ type LayoutHints = {
154
+ /**
155
+ * Optional compose width for centering/wrapping
156
+ */
157
+ composeWidth: number | null;
158
+ /**
159
+ * Optional column guides for aligned tables
160
+ */
161
+ columnGuides: Array<number> | null;
162
+ };
163
+ type ViewTokenWire = {
164
+ /**
165
+ * Source byte offset in the buffer. None for injected content (annotations).
166
+ */
167
+ source_offset: number | null;
168
+ /**
169
+ * The token content
170
+ */
171
+ kind: ViewTokenWireKind;
172
+ /**
173
+ * Optional styling for injected content (only used when source_offset is None)
174
+ */
175
+ style?: ViewTokenStyle;
176
+ };
177
+ type ViewTokenWireKind = {
178
+ "Text": string;
179
+ } | "Newline" | "Space" | "Break" | {
180
+ "BinaryByte": number;
181
+ };
182
+ type ViewTokenStyle = {
183
+ /**
184
+ * Foreground color as RGB tuple
185
+ */
186
+ fg: [number, number, number] | null;
187
+ /**
188
+ * Background color as RGB tuple
189
+ */
190
+ bg: [number, number, number] | null;
191
+ /**
192
+ * Whether to render in bold
193
+ */
194
+ bold: boolean;
195
+ /**
196
+ * Whether to render in italic
197
+ */
198
+ italic: boolean;
199
+ };
200
+ type PromptSuggestion = {
201
+ /**
202
+ * The text to display
203
+ */
204
+ text: string;
205
+ /**
206
+ * Optional description
207
+ */
208
+ description?: string;
209
+ /**
210
+ * The value to use when selected (defaults to text if None)
211
+ */
212
+ value?: string;
213
+ /**
214
+ * Whether this suggestion is disabled (greyed out, defaults to false)
215
+ */
216
+ disabled?: boolean;
217
+ /**
218
+ * Optional keyboard shortcut
219
+ */
220
+ keybinding?: string;
221
+ };
222
+ type DirEntry = {
223
+ /**
224
+ * File/directory name
225
+ */
226
+ name: string;
227
+ /**
228
+ * True if this is a file
229
+ */
230
+ is_file: boolean;
231
+ /**
232
+ * True if this is a directory
233
+ */
234
+ is_dir: boolean;
235
+ };
236
+ type BufferInfo = {
237
+ /**
238
+ * Buffer ID
239
+ */
240
+ id: number;
241
+ /**
242
+ * File path (if any)
243
+ */
244
+ path: string;
245
+ /**
246
+ * Whether the buffer has been modified
247
+ */
248
+ modified: boolean;
249
+ /**
250
+ * Length of buffer in bytes
251
+ */
252
+ length: number;
253
+ };
254
+ type JsDiagnostic = {
255
+ /**
256
+ * Document URI
257
+ */
258
+ uri: string;
259
+ /**
260
+ * Diagnostic message
261
+ */
262
+ message: string;
263
+ /**
264
+ * Severity: 1=Error, 2=Warning, 3=Info, 4=Hint, null=unknown
265
+ */
266
+ severity: number | null;
267
+ /**
268
+ * Range in the document
269
+ */
270
+ range: JsRange;
271
+ /**
272
+ * Source of the diagnostic (e.g., "typescript", "eslint")
273
+ */
274
+ source?: string;
275
+ };
276
+ type JsRange = {
277
+ /**
278
+ * Start position
279
+ */
280
+ start: JsPosition;
281
+ /**
282
+ * End position
283
+ */
284
+ end: JsPosition;
285
+ };
286
+ type JsPosition = {
287
+ /**
288
+ * Zero-indexed line number
289
+ */
290
+ line: number;
291
+ /**
292
+ * Zero-indexed character offset
293
+ */
294
+ character: number;
295
+ };
296
+ type ActionSpec = {
297
+ /**
298
+ * Action name (e.g., "move_word_right", "delete_line")
299
+ */
300
+ action: string;
301
+ /**
302
+ * Number of times to repeat the action (default 1)
303
+ */
304
+ count: number;
305
+ };
306
+ type TsActionPopupAction = {
307
+ /**
308
+ * Unique action identifier (returned in ActionPopupResult)
309
+ */
310
+ id: string;
311
+ /**
312
+ * Display text for the button (can include command hints)
313
+ */
314
+ label: string;
315
+ };
316
+ type ActionPopupOptions = {
317
+ /**
318
+ * Unique identifier for the popup (used in ActionPopupResult)
319
+ */
320
+ id: string;
321
+ /**
322
+ * Title text for the popup
323
+ */
324
+ title: string;
325
+ /**
326
+ * Body message (supports basic formatting)
327
+ */
328
+ message: string;
329
+ /**
330
+ * Action buttons to display
331
+ */
332
+ actions: Array<TsActionPopupAction>;
333
+ };
334
+ type FileExplorerDecoration = {
335
+ /**
336
+ * File path to decorate
337
+ */
338
+ path: string;
339
+ /**
340
+ * Symbol to display (e.g., "●", "M", "A")
341
+ */
342
+ symbol: string;
343
+ /**
344
+ * Color as RGB array (rquickjs_serde requires array, not tuple)
345
+ */
346
+ color: [number, number, number];
347
+ /**
348
+ * Priority for display when multiple decorations exist (higher wins)
349
+ */
350
+ priority: number;
351
+ };
40
352
  type BackgroundProcessResult = {
41
353
  /**
42
354
  * Unique process ID for later reference
@@ -53,6 +365,46 @@ type BufferSavedDiff = {
53
365
  byte_ranges: Array<[number, number]>;
54
366
  line_ranges: Array<[number, number]> | null;
55
367
  };
368
+ type TsCompositeHunk = {
369
+ /**
370
+ * Starting line in old buffer (0-indexed)
371
+ */
372
+ oldStart: number;
373
+ /**
374
+ * Number of lines in old buffer
375
+ */
376
+ oldCount: number;
377
+ /**
378
+ * Starting line in new buffer (0-indexed)
379
+ */
380
+ newStart: number;
381
+ /**
382
+ * Number of lines in new buffer
383
+ */
384
+ newCount: number;
385
+ };
386
+ type TsCreateCompositeBufferOptions = {
387
+ /**
388
+ * Buffer name (displayed in tabs/title)
389
+ */
390
+ name: string;
391
+ /**
392
+ * Mode for keybindings
393
+ */
394
+ mode: string;
395
+ /**
396
+ * Layout configuration
397
+ */
398
+ layout: TsCompositeLayoutConfig;
399
+ /**
400
+ * Source pane configurations
401
+ */
402
+ sources: Array<TsCompositeSourceConfig>;
403
+ /**
404
+ * Diff hunks for alignment (optional)
405
+ */
406
+ hunks: Array<TsCompositeHunk> | null;
407
+ };
56
408
  type CreateVirtualBufferInExistingSplitOptions = {
57
409
  /**
58
410
  * Buffer name (displayed in tabs/title)
@@ -185,6 +537,28 @@ type SpawnResult = {
185
537
  */
186
538
  exit_code: number;
187
539
  };
540
+ type PromptSuggestion = {
541
+ /**
542
+ * The text to display
543
+ */
544
+ text: string;
545
+ /**
546
+ * Optional description
547
+ */
548
+ description?: string;
549
+ /**
550
+ * The value to use when selected (defaults to text if None)
551
+ */
552
+ value?: string;
553
+ /**
554
+ * Whether this suggestion is disabled (greyed out, defaults to false)
555
+ */
556
+ disabled?: boolean;
557
+ /**
558
+ * Optional keyboard shortcut
559
+ */
560
+ keybinding?: string;
561
+ };
188
562
  type TextPropertiesAtCursor = Array<Record<string, unknown>>;
189
563
  type TsHighlightSpan = {
190
564
  start: number;
@@ -193,6 +567,16 @@ type TsHighlightSpan = {
193
567
  bold: boolean;
194
568
  italic: boolean;
195
569
  };
570
+ type VirtualBufferResult = {
571
+ /**
572
+ * The created buffer ID
573
+ */
574
+ bufferId: number;
575
+ /**
576
+ * The split ID (if created in a new split)
577
+ */
578
+ splitId: number | null;
579
+ };
196
580
  /**
197
581
  * Main editor API interface
198
582
  */
@@ -208,7 +592,7 @@ interface EditorAPI {
208
592
  /**
209
593
  * List all open buffers - returns array of BufferInfo objects
210
594
  */
211
- listBuffers(): unknown;
595
+ listBuffers(): BufferInfo[];
212
596
  debug(msg: string): void;
213
597
  info(msg: string): void;
214
598
  warn(msg: string): void;
@@ -217,7 +601,7 @@ interface EditorAPI {
217
601
  copyToClipboard(text: string): void;
218
602
  setClipboard(text: string): void;
219
603
  /**
220
- * Register a command - reads plugin name from __currentPluginName__ global
604
+ * Register a command - reads plugin name from __pluginName__ global
221
605
  * context is optional - can be omitted, null, undefined, or a string
222
606
  */
223
607
  registerCommand(name: string, description: string, handlerName: string, context?: unknown): boolean;
@@ -234,7 +618,7 @@ interface EditorAPI {
234
618
  */
235
619
  executeAction(actionName: string): boolean;
236
620
  /**
237
- * Translate a string - reads plugin name from __currentPluginName__ global
621
+ * Translate a string - reads plugin name from __pluginName__ global
238
622
  * Args is optional - can be omitted, undefined, null, or an object
239
623
  */
240
624
  t(key: string, ...args: unknown[]): string;
@@ -255,9 +639,14 @@ interface EditorAPI {
255
639
  */
256
640
  isBufferModified(bufferId: number): boolean;
257
641
  /**
642
+ * Save a buffer to a specific file path
643
+ * Used by :w filename to save unnamed buffers or save-as
644
+ */
645
+ saveBufferToPath(bufferId: number, path: string): boolean;
646
+ /**
258
647
  * Get buffer info by ID
259
648
  */
260
- getBufferInfo(bufferId: number): unknown;
649
+ getBufferInfo(bufferId: number): BufferInfo | null;
261
650
  /**
262
651
  * Get primary cursor info for active buffer
263
652
  */
@@ -273,12 +662,17 @@ interface EditorAPI {
273
662
  /**
274
663
  * Get viewport info for active buffer
275
664
  */
276
- getViewport(): unknown;
665
+ getViewport(): ViewportInfo | null;
277
666
  /**
278
667
  * Get the line number (0-indexed) of the primary cursor
279
668
  */
280
669
  getCursorLine(): number;
281
670
  /**
671
+ * Get the byte offset of the start of a line (0-indexed line number)
672
+ * Returns null if the line number is out of range
673
+ */
674
+ getLineStartPosition(line: number): Promise<number | null>;
675
+ /**
282
676
  * Find buffer by file path, returns buffer ID or 0 if not found
283
677
  */
284
678
  findBufferByPath(path: string): number;
@@ -332,6 +726,7 @@ interface EditorAPI {
332
726
  getCwd(): string;
333
727
  /**
334
728
  * Join path components (variadic - accepts multiple string arguments)
729
+ * Always uses forward slashes for cross-platform consistency (like Node.js path.posix.join)
335
730
  */
336
731
  pathJoin(...parts: string[]): string;
337
732
  /**
@@ -365,7 +760,7 @@ interface EditorAPI {
365
760
  /**
366
761
  * Read directory contents (returns array of {name, is_file, is_dir})
367
762
  */
368
- readDir(path: string): unknown;
763
+ readDir(path: string): DirEntry[];
369
764
  /**
370
765
  * Get current config as JS object
371
766
  */
@@ -409,7 +804,7 @@ interface EditorAPI {
409
804
  /**
410
805
  * Check if a background process is still running
411
806
  */
412
- isProcessRunning(processId: number): boolean;
807
+ isProcessRunning(ProcessId: number): boolean;
413
808
  /**
414
809
  * Kill a process by ID (alias for killBackgroundProcess)
415
810
  */
@@ -420,12 +815,17 @@ interface EditorAPI {
420
815
  pluginTranslate(pluginName: string, key: string, args?: Record<string, unknown>): string;
421
816
  /**
422
817
  * Create a composite buffer (async)
818
+ *
819
+ * Uses typed CreateCompositeBufferOptions - serde validates field names at runtime
820
+ * via `deny_unknown_fields` attribute
423
821
  */
424
- createCompositeBuffer(opts: Record<string, unknown>): Promise<number>;
822
+ createCompositeBuffer(opts: CreateCompositeBufferOptions): Promise<number>;
425
823
  /**
426
824
  * Update alignment hunks for a composite buffer
825
+ *
826
+ * Uses typed Vec<CompositeHunk> - serde validates field names at runtime
427
827
  */
428
- updateCompositeAlignment(bufferId: number, hunks: Record<string, unknown>[]): boolean;
828
+ updateCompositeAlignment(bufferId: number, hunks: CompositeHunk[]): boolean;
429
829
  /**
430
830
  * Close a composite buffer
431
831
  */
@@ -456,6 +856,9 @@ interface EditorAPI {
456
856
  removeOverlay(bufferId: number, handle: string): boolean;
457
857
  /**
458
858
  * Submit a view transform for a buffer/split
859
+ *
860
+ * Note: tokens should be ViewTokenWire[], layoutHints should be LayoutHints
861
+ * These use manual parsing due to complex enum handling
459
862
  */
460
863
  submitViewTransform(bufferId: number, splitId: number | null, start: number, end: number, tokens: Record<string, unknown>[], LayoutHints?: Record<string, unknown>): boolean;
461
864
  /**
@@ -464,8 +867,10 @@ interface EditorAPI {
464
867
  clearViewTransform(bufferId: number, splitId: number | null): boolean;
465
868
  /**
466
869
  * Set file explorer decorations for a namespace
870
+ *
871
+ * Uses typed Vec<FileExplorerDecoration> - serde validates field names at runtime
467
872
  */
468
- setFileExplorerDecorations(namespace: string, decorations: Record<string, unknown>[]): boolean;
873
+ setFileExplorerDecorations(namespace: string, decorations: FileExplorerDecoration[]): boolean;
469
874
  /**
470
875
  * Clear file explorer decorations for a namespace
471
876
  */
@@ -495,6 +900,11 @@ interface EditorAPI {
495
900
  */
496
901
  addVirtualLine(bufferId: number, position: number, text: string, fgR: number, fgG: number, fgB: number, bgR: number, bgG: number, bgB: number, above: boolean, namespace: string, priority: number): boolean;
497
902
  /**
903
+ * Show a prompt and wait for user input (async)
904
+ * Returns the user input or null if cancelled
905
+ */
906
+ prompt(label: string, initialValue: string): Promise<string | null>;
907
+ /**
498
908
  * Start an interactive prompt
499
909
  */
500
910
  startPrompt(label: string, promptType: string): boolean;
@@ -503,9 +913,11 @@ interface EditorAPI {
503
913
  */
504
914
  startPromptWithInitial(label: string, promptType: string, initialValue: string): boolean;
505
915
  /**
506
- * Set suggestions for the current prompt (takes array of suggestion objects)
916
+ * Set suggestions for the current prompt
917
+ *
918
+ * Uses typed Vec<Suggestion> - serde validates field names at runtime
507
919
  */
508
- setPromptSuggestions(suggestionsArr: Record<string, unknown>[]): boolean;
920
+ setPromptSuggestions(suggestions: Suggestion[]): boolean;
509
921
  /**
510
922
  * Define a buffer mode (takes bindings as array of [key, command] pairs)
511
923
  */
@@ -572,12 +984,16 @@ interface EditorAPI {
572
984
  removeScrollSyncGroup(groupId: number): boolean;
573
985
  /**
574
986
  * Execute multiple actions in sequence
987
+ *
988
+ * Takes typed ActionSpec array - serde validates field names at runtime
575
989
  */
576
- executeActions(actions: Record<string, unknown>[]): boolean;
990
+ executeActions(actions: ActionSpec[]): boolean;
577
991
  /**
578
992
  * Show an action popup
993
+ *
994
+ * Takes a typed ActionPopupOptions struct - serde validates field names at runtime
579
995
  */
580
- showActionPopup(opts: Record<string, unknown>): boolean;
996
+ showActionPopup(opts: ActionPopupOptions): boolean;
581
997
  /**
582
998
  * Disable LSP for a specific language
583
999
  */
@@ -585,25 +1001,27 @@ interface EditorAPI {
585
1001
  /**
586
1002
  * Get all diagnostics from LSP
587
1003
  */
588
- getAllDiagnostics(): unknown;
1004
+ getAllDiagnostics(): JsDiagnostic[];
589
1005
  /**
590
1006
  * Get registered event handlers for an event
591
1007
  */
592
1008
  getHandlers(eventName: string): string[];
593
1009
  /**
594
- * Create a virtual buffer in current split (async, returns buffer ID)
1010
+ * Create a virtual buffer in current split (async, returns buffer and split IDs)
595
1011
  */
596
- createVirtualBuffer(opts: CreateVirtualBufferOptions): Promise<number>;
1012
+ createVirtualBuffer(opts: CreateVirtualBufferOptions): Promise<VirtualBufferResult>;
597
1013
  /**
598
- * Create a virtual buffer in a new split (async, returns request_id)
1014
+ * Create a virtual buffer in a new split (async, returns buffer and split IDs)
599
1015
  */
600
- createVirtualBufferInSplit(opts: CreateVirtualBufferInSplitOptions): Promise<number>;
1016
+ createVirtualBufferInSplit(opts: CreateVirtualBufferInSplitOptions): Promise<VirtualBufferResult>;
601
1017
  /**
602
- * Create a virtual buffer in an existing split (async, returns request_id)
1018
+ * Create a virtual buffer in an existing split (async, returns buffer and split IDs)
603
1019
  */
604
- createVirtualBufferInExistingSplit(opts: CreateVirtualBufferInExistingSplitOptions): Promise<number>;
1020
+ createVirtualBufferInExistingSplit(opts: CreateVirtualBufferInExistingSplitOptions): Promise<VirtualBufferResult>;
605
1021
  /**
606
1022
  * Set virtual buffer content (takes array of entry objects)
1023
+ *
1024
+ * Note: entries should be TextPropertyEntry[] - uses manual parsing for HashMap support
607
1025
  */
608
1026
  setVirtualBufferContent(bufferId: number, entriesArr: Record<string, unknown>[]): boolean;
609
1027
  /**
@@ -110,20 +110,20 @@ export class PanelManager {
110
110
  const result = await this.editor.createVirtualBufferInSplit({
111
111
  name: this.panelName,
112
112
  mode: this.modeName,
113
- read_only: true,
113
+ readOnly: true,
114
114
  entries,
115
115
  ratio,
116
- panel_id: this.panelName,
117
- show_line_numbers: showLineNumbers,
118
- editing_disabled: editingDisabled,
116
+ panelId: this.panelName,
117
+ showLineNumbers: showLineNumbers,
118
+ editingDisabled: editingDisabled,
119
119
  });
120
120
 
121
121
  // Track state
122
- this.state.bufferId = result.buffer_id;
123
- this.state.splitId = result.split_id ?? this.editor.getActiveSplitId();
122
+ this.state.bufferId = result.bufferId;
123
+ this.state.splitId = result.splitId ?? this.editor.getActiveSplitId();
124
124
  this.state.isOpen = true;
125
125
 
126
- return result.buffer_id;
126
+ return result.bufferId;
127
127
  }
128
128
 
129
129
  /**
@@ -41,14 +41,14 @@ interface EditorApi {
41
41
  createVirtualBufferInSplit(options: {
42
42
  name: string;
43
43
  mode: string;
44
- read_only: boolean;
44
+ readOnly: boolean;
45
45
  entries: TextPropertyEntry[];
46
46
  ratio: number;
47
47
  direction: string;
48
- panel_id: string;
49
- show_line_numbers: boolean;
50
- editing_disabled: boolean;
51
- }): Promise<{ buffer_id: number; split_id?: number }>;
48
+ panelId: string;
49
+ showLineNumbers: boolean;
50
+ editingDisabled: boolean;
51
+ }): Promise<{ bufferId: number; splitId?: number }>;
52
52
  setVirtualBufferContent(bufferId: number, entries: TextPropertyEntry[]): void;
53
53
  closeBuffer(bufferId: number): void;
54
54
  closeSplit(splitId: number): void;
@@ -137,17 +137,17 @@ export class SearchPreview {
137
137
  const result = await this.editor.createVirtualBufferInSplit({
138
138
  name: "*Preview*",
139
139
  mode: this.modeName,
140
- read_only: true,
140
+ readOnly: true,
141
141
  entries,
142
142
  ratio: 0.5,
143
143
  direction: "vertical",
144
- panel_id: this.panelId,
145
- show_line_numbers: false,
146
- editing_disabled: true,
144
+ panelId: this.panelId,
145
+ showLineNumbers: false,
146
+ editingDisabled: true,
147
147
  });
148
148
 
149
- this.bufferId = result.buffer_id;
150
- this.splitId = result.split_id ?? null;
149
+ this.bufferId = result.bufferId;
150
+ this.splitId = result.splitId ?? null;
151
151
 
152
152
  // Return focus to original split so prompt stays active
153
153
  if (this.originalSplitId !== null) {
@@ -196,7 +196,7 @@ export class SearchPreview {
196
196
  * - Tracks search version to discard stale results
197
197
  */
198
198
  export class DebouncedSearch {
199
- private currentSearch: ProcessHandle | null = null;
199
+ private currentSearch: ProcessHandle<SpawnResult> | null = null;
200
200
  private pendingKill: Promise<boolean> | null = null;
201
201
  private searchVersion = 0;
202
202
  private lastQuery = "";
@@ -216,7 +216,7 @@ export class DebouncedSearch {
216
216
  */
217
217
  async search(
218
218
  query: string,
219
- executor: () => ProcessHandle,
219
+ executor: () => ProcessHandle<SpawnResult>,
220
220
  onResults: (result: SpawnResult) => void
221
221
  ): Promise<void> {
222
222
  const thisVersion = ++this.searchVersion;