@@ -18,6 +18,7 @@ import type { Previewer } from "jsr:@vim-fall/core@^0.3.0/previewer";
1818import type { Theme } from "jsr:@vim-fall/core@^0.3.0/theme" ;
1919
2020import { Scheduler } from "./lib/scheduler.ts" ;
21+ import { debounce } from "./lib/debounce.ts" ;
2122import { Cmdliner } from "./util/cmdliner.ts" ;
2223import { isIncrementalMatcher } from "./util/predicate.ts" ;
2324import { buildMappingHelpPages } from "./util/mapping.ts" ;
@@ -37,6 +38,7 @@ import { HelpComponent } from "./component/help.ts";
3738import { consume , type Event } from "./event.ts" ;
3839
3940const SCHEDULER_INTERVAL = 10 ;
41+ const PREVIEW_DEBOUNCE_DELAY = 150 ;
4042const MATCHER_ICON = "🅼 " ;
4143const SORTER_ICON = "🆂 " ;
4244const RENDERER_ICON = "🆁 " ;
@@ -70,6 +72,7 @@ export type PickerResult<T extends Detail> = {
7072
7173export type PickerOptions = {
7274 schedulerInterval ?: number ;
75+ previewDebounceDelay ?: number ;
7376} ;
7477
7578export type PickerContext < T extends Detail > = {
@@ -89,6 +92,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
8992 static readonly ZINDEX_ALLOCATION = 4 ;
9093 readonly #stack = new AsyncDisposableStack ( ) ;
9194 readonly #schedulerInterval: number ;
95+ readonly #previewDebounceDelay: number ;
9296 readonly #name: string ;
9397 readonly #coordinator: Coordinator ;
9498 readonly #collectProcessor: CollectProcessor < T > ;
@@ -110,6 +114,8 @@ export class Picker<T extends Detail> implements AsyncDisposable {
110114
111115 constructor ( params : PickerParams < T > , options : PickerOptions = { } ) {
112116 this . #schedulerInterval = options . schedulerInterval ?? SCHEDULER_INTERVAL ;
117+ this . #previewDebounceDelay = options . previewDebounceDelay ??
118+ PREVIEW_DEBOUNCE_DELAY ;
113119
114120 const { name, theme, coordinator, zindex = 50 , context } = params ;
115121 this . #name = name ;
@@ -358,6 +364,10 @@ export class Picker<T extends Detail> implements AsyncDisposable {
358364 const reserve = ( callback : ReservedCallback ) => {
359365 reservedCallbacks . push ( callback ) ;
360366 } ;
367+ const reservePreviewDebounced = debounce ( reserve , {
368+ delay : this . #previewDebounceDelay,
369+ signal,
370+ } ) ;
361371 const cmdliner = new Cmdliner ( {
362372 cmdline : this . #inputComponent. cmdline ,
363373 cmdpos : this . #inputComponent. cmdpos ,
@@ -368,7 +378,13 @@ export class Picker<T extends Detail> implements AsyncDisposable {
368378 await cmdliner . check ( denops ) ;
369379
370380 // 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+ ) ;
372388
373389 // Handle reserved callbacks asynchronously
374390 for ( const callback of reservedCallbacks ) {
@@ -469,9 +485,10 @@ export class Picker<T extends Detail> implements AsyncDisposable {
469485 }
470486 }
471487
472- #handleEvent( event : Event , { accept, reserve } : {
488+ #handleEvent( event : Event , { accept, reserve, reservePreviewDebounced } : {
473489 accept : ( name : string ) => Promise < void > ;
474490 reserve : ( callback : ReservedCallback ) => void ;
491+ reservePreviewDebounced : ( callback : ReservedCallback ) => void ;
475492 } ) : void {
476493 switch ( event . type ) {
477494 case "vim-cmdline-changed" :
@@ -617,7 +634,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
617634 }
618635 this . #previewProcessor. previewerIndex = index ;
619636 this . #listComponent. title = this . #getExtensionIndicator( ) ;
620- reserve ( ( denops ) => {
637+ reservePreviewDebounced ( ( denops ) => {
621638 this . #previewProcessor?. start ( denops , {
622639 item : this . #matchProcessor. items [ this . #renderProcessor. cursor ] ,
623640 } ) ;
@@ -628,7 +645,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
628645 if ( ! this . #previewProcessor) break ;
629646 this . #previewProcessor. previewerIndex = event . index ;
630647 this . #listComponent. title = this . #getExtensionIndicator( ) ;
631- reserve ( ( denops ) => {
648+ reservePreviewDebounced ( ( denops ) => {
632649 this . #previewProcessor?. start ( denops , {
633650 item : this . #matchProcessor. items [ this . #renderProcessor. cursor ] ,
634651 } ) ;
@@ -756,7 +773,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
756773 const line = this . #renderProcessor. line ;
757774 this . #listComponent. items = this . #renderProcessor. items ;
758775 this . #listComponent. execute ( `silent! normal! ${ line } G` ) ;
759- reserve ( ( denops ) => {
776+ reservePreviewDebounced ( ( denops ) => {
760777 this . #previewProcessor?. start ( denops , {
761778 item : this . #matchProcessor. items [ this . #renderProcessor. cursor ] ,
762779 } ) ;
0 commit comments