@@ -18,6 +18,7 @@ import type { Previewer } from "jsr:@vim-fall/core@^0.3.0/previewer";
18
18
import type { Theme } from "jsr:@vim-fall/core@^0.3.0/theme" ;
19
19
20
20
import { Scheduler } from "./lib/scheduler.ts" ;
21
+ import { debounce } from "./lib/debounce.ts" ;
21
22
import { Cmdliner } from "./util/cmdliner.ts" ;
22
23
import { isIncrementalMatcher } from "./util/predicate.ts" ;
23
24
import { buildMappingHelpPages } from "./util/mapping.ts" ;
@@ -37,6 +38,7 @@ import { HelpComponent } from "./component/help.ts";
37
38
import { consume , type Event } from "./event.ts" ;
38
39
39
40
const SCHEDULER_INTERVAL = 10 ;
41
+ const PREVIEW_DEBOUNCE_DELAY = 150 ;
40
42
const MATCHER_ICON = "🅼 " ;
41
43
const SORTER_ICON = "🆂 " ;
42
44
const RENDERER_ICON = "🆁 " ;
@@ -70,6 +72,7 @@ export type PickerResult<T extends Detail> = {
70
72
71
73
export type PickerOptions = {
72
74
schedulerInterval ?: number ;
75
+ previewDebounceDelay ?: number ;
73
76
} ;
74
77
75
78
export type PickerContext < T extends Detail > = {
@@ -89,6 +92,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
89
92
static readonly ZINDEX_ALLOCATION = 4 ;
90
93
readonly #stack = new AsyncDisposableStack ( ) ;
91
94
readonly #schedulerInterval: number ;
95
+ readonly #previewDebounceDelay: number ;
92
96
readonly #name: string ;
93
97
readonly #coordinator: Coordinator ;
94
98
readonly #collectProcessor: CollectProcessor < T > ;
@@ -110,6 +114,8 @@ export class Picker<T extends Detail> implements AsyncDisposable {
110
114
111
115
constructor ( params : PickerParams < T > , options : PickerOptions = { } ) {
112
116
this . #schedulerInterval = options . schedulerInterval ?? SCHEDULER_INTERVAL ;
117
+ this . #previewDebounceDelay = options . previewDebounceDelay ??
118
+ PREVIEW_DEBOUNCE_DELAY ;
113
119
114
120
const { name, theme, coordinator, zindex = 50 , context } = params ;
115
121
this . #name = name ;
@@ -358,6 +364,10 @@ export class Picker<T extends Detail> implements AsyncDisposable {
358
364
const reserve = ( callback : ReservedCallback ) => {
359
365
reservedCallbacks . push ( callback ) ;
360
366
} ;
367
+ const reservePreviewDebounced = debounce ( reserve , {
368
+ delay : this . #previewDebounceDelay,
369
+ signal,
370
+ } ) ;
361
371
const cmdliner = new Cmdliner ( {
362
372
cmdline : this . #inputComponent. cmdline ,
363
373
cmdpos : this . #inputComponent. cmdpos ,
@@ -368,7 +378,13 @@ export class Picker<T extends Detail> implements AsyncDisposable {
368
378
await cmdliner . check ( denops ) ;
369
379
370
380
// Handle events synchronously
371
- consume ( ( event ) => this . #handleEvent( event , { accept, reserve } ) ) ;
381
+ consume ( ( event ) =>
382
+ this . #handleEvent( event , {
383
+ accept,
384
+ reserve,
385
+ reservePreviewDebounced,
386
+ } )
387
+ ) ;
372
388
373
389
// Handle reserved callbacks asynchronously
374
390
for ( const callback of reservedCallbacks ) {
@@ -469,9 +485,10 @@ export class Picker<T extends Detail> implements AsyncDisposable {
469
485
}
470
486
}
471
487
472
- #handleEvent( event : Event , { accept, reserve } : {
488
+ #handleEvent( event : Event , { accept, reserve, reservePreviewDebounced } : {
473
489
accept : ( name : string ) => Promise < void > ;
474
490
reserve : ( callback : ReservedCallback ) => void ;
491
+ reservePreviewDebounced : ( callback : ReservedCallback ) => void ;
475
492
} ) : void {
476
493
switch ( event . type ) {
477
494
case "vim-cmdline-changed" :
@@ -617,7 +634,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
617
634
}
618
635
this . #previewProcessor. previewerIndex = index ;
619
636
this . #listComponent. title = this . #getExtensionIndicator( ) ;
620
- reserve ( ( denops ) => {
637
+ reservePreviewDebounced ( ( denops ) => {
621
638
this . #previewProcessor?. start ( denops , {
622
639
item : this . #matchProcessor. items [ this . #renderProcessor. cursor ] ,
623
640
} ) ;
@@ -628,7 +645,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
628
645
if ( ! this . #previewProcessor) break ;
629
646
this . #previewProcessor. previewerIndex = event . index ;
630
647
this . #listComponent. title = this . #getExtensionIndicator( ) ;
631
- reserve ( ( denops ) => {
648
+ reservePreviewDebounced ( ( denops ) => {
632
649
this . #previewProcessor?. start ( denops , {
633
650
item : this . #matchProcessor. items [ this . #renderProcessor. cursor ] ,
634
651
} ) ;
@@ -756,7 +773,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
756
773
const line = this . #renderProcessor. line ;
757
774
this . #listComponent. items = this . #renderProcessor. items ;
758
775
this . #listComponent. execute ( `silent! normal! ${ line } G` ) ;
759
- reserve ( ( denops ) => {
776
+ reservePreviewDebounced ( ( denops ) => {
760
777
this . #previewProcessor?. start ( denops , {
761
778
item : this . #matchProcessor. items [ this . #renderProcessor. cursor ] ,
762
779
} ) ;
0 commit comments