@@ -57,6 +57,7 @@ export type PickerParams<T extends Detail> = {
5757 renderers ?: readonly Renderer < T > [ ] ;
5858 previewers ?: readonly Previewer < T > [ ] ;
5959 zindex ?: number ;
60+ context ?: PickerContext < T > ;
6061} ;
6162
6263export type PickerResult < T extends Detail > = {
@@ -71,6 +72,19 @@ export type PickerOptions = {
7172 schedulerInterval ?: number ;
7273} ;
7374
75+ export type PickerContext < T extends Detail > = {
76+ readonly query : string ;
77+ readonly selection : Set < unknown > ;
78+ readonly collectedItems : readonly IdItem < T > [ ] ;
79+ readonly filteredItems : readonly IdItem < T > [ ] ;
80+ readonly cursor : number ;
81+ readonly offset : number ;
82+ readonly matcherIndex : number ;
83+ readonly sorterIndex : number ;
84+ readonly rendererIndex : number ;
85+ readonly previewerIndex ?: number ;
86+ } ;
87+
7488export class Picker < T extends Detail > implements AsyncDisposable {
7589 static readonly ZINDEX_ALLOCATION = 4 ;
7690 readonly #stack = new AsyncDisposableStack ( ) ;
@@ -92,15 +106,17 @@ export class Picker<T extends Detail> implements AsyncDisposable {
92106 readonly #sorterIcon: string ;
93107 readonly #rendererIcon: string ;
94108 readonly #previewerIcon: string ;
95- #selection: Set < unknown > = new Set ( ) ;
109+ #selection: Set < unknown > ;
96110
97111 constructor ( params : PickerParams < T > , options : PickerOptions = { } ) {
98112 this . #schedulerInterval = options . schedulerInterval ?? SCHEDULER_INTERVAL ;
99- this . #name = params . name ;
100- this . #coordinator = params . coordinator ;
113+
114+ const { name, theme, coordinator, zindex = 50 , context } = params ;
115+ this . #name = name ;
116+ this . #coordinator = coordinator ;
117+ this . #selection = context ?. selection ?? new Set ( ) ;
101118
102119 // Components
103- const { theme, zindex = 50 } = params ;
104120 this . #matcherIcon = theme . matcherIcon ?? MATCHER_ICON ;
105121 this . #sorterIcon = theme . sorterIcon ?? SORTER_ICON ;
106122 this . #rendererIcon = theme . rendererIcon ?? RENDERER_ICON ;
@@ -109,6 +125,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
109125 const style = this . #coordinator. style ( theme ) ;
110126 this . #inputComponent = this . #stack. use (
111127 new InputComponent ( {
128+ cmdline : context ?. query ?? "" ,
112129 spinner : theme . spinner ,
113130 headSymbol : theme . headSymbol ,
114131 failSymbol : theme . failSymbol ,
@@ -141,27 +158,54 @@ export class Picker<T extends Detail> implements AsyncDisposable {
141158
142159 // Processor
143160 this . #collectProcessor = this . #stack. use (
144- new CollectProcessor ( params . source ) ,
161+ new CollectProcessor ( params . source , {
162+ initialItems : context ?. collectedItems ,
163+ } ) ,
145164 ) ;
146165 this . #matchProcessor = this . #stack. use (
147166 new MatchProcessor ( params . matchers , {
167+ initialItems : context ?. filteredItems ,
168+ initialQuery : context ?. query ,
169+ initialIndex : context ?. matcherIndex ,
148170 // Use incremental mode for Curator matcher
149171 incremental : isIncrementalMatcher ( params . matchers [ 0 ] ) ,
150172 } ) ,
151173 ) ;
152174 this . #sortProcessor = this . #stack. use (
153- new SortProcessor ( params . sorters ?? [ ] ) ,
175+ new SortProcessor ( params . sorters ?? [ ] , {
176+ // initialItems: this.#matchProcessor.items,
177+ initialIndex : context ?. sorterIndex ,
178+ } ) ,
154179 ) ;
155180 this . #renderProcessor = this . #stack. use (
156- new RenderProcessor (
157- params . renderers ?? [ ] ,
158- ) ,
181+ new RenderProcessor ( params . renderers ?? [ ] , {
182+ // initialItems: session?.renderedItems,
183+ initialIndex : context ?. rendererIndex ,
184+ initialCursor : context ?. cursor ,
185+ initialOffset : context ?. offset ,
186+ } ) ,
159187 ) ;
160188 this . #previewProcessor = this . #stack. use (
161- new PreviewProcessor ( params . previewers ?? [ ] ) ,
189+ new PreviewProcessor ( params . previewers ?? [ ] , {
190+ initialIndex : context ?. previewerIndex ,
191+ } ) ,
162192 ) ;
163193 }
164194
195+ get context ( ) : PickerContext < T > {
196+ return {
197+ query : this . #inputComponent. cmdline ,
198+ selection : this . #selection,
199+ collectedItems : this . #collectProcessor. items ,
200+ filteredItems : this . #matchProcessor. items ,
201+ cursor : this . #renderProcessor. cursor ,
202+ offset : this . #renderProcessor. offset ,
203+ matcherIndex : this . #matchProcessor. matcherIndex ,
204+ sorterIndex : this . #sortProcessor. sorterIndex ,
205+ rendererIndex : this . #renderProcessor. rendererIndex ,
206+ } ;
207+ }
208+
165209 #getHelpDimension( screen : Size ) : Dimension {
166210 const width = Math . floor ( screen . width * this . #helpWidthRatio) ;
167211 const height = Math . floor ( screen . height * this . #helpHeightRatio) ;
@@ -290,7 +334,7 @@ export class Picker<T extends Detail> implements AsyncDisposable {
290334
291335 async start (
292336 denops : Denops ,
293- { args } : { args : string [ ] } ,
337+ { args } : { args : readonly string [ ] } ,
294338 { signal } : { signal ?: AbortSignal } = { } ,
295339 ) : Promise < PickerResult < T > | undefined > {
296340 await using stack = new AsyncDisposableStack ( ) ;
0 commit comments