Skip to content

Commit f74bd56

Browse files
committed
feat: support multiple sorters/renderers
1 parent 6d5517b commit f74bd56

File tree

5 files changed

+126
-9
lines changed

5 files changed

+126
-9
lines changed

denops/fall/event.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ export type Event =
2323
| { type: "select-all-items"; method?: SelectMethod }
2424
| { type: "switch-matcher"; amount: number; cycle?: boolean }
2525
| { type: "switch-matcher-at"; index: number | "$" }
26+
| { type: "switch-sorter"; amount: number; cycle?: boolean }
27+
| { type: "switch-sorter-at"; index: number | "$" }
28+
| { type: "switch-renderer"; amount: number; cycle?: boolean }
29+
| { type: "switch-renderer-at"; index: number | "$" }
2630
| { type: "action-invoke"; name: string }
2731
| { type: "list-component-execute"; command: string }
2832
| { type: "preview-component-execute"; command: string }

denops/fall/main/event.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ const isEventComplement = is.UnionOf([
5151
type: is.LiteralOf("switch-matcher-at"),
5252
index: is.UnionOf([is.Number, is.LiteralOf("$")]),
5353
}),
54+
is.ObjectOf({
55+
type: is.LiteralOf("switch-sorter"),
56+
amount: is.Number,
57+
cycle: as.Optional(is.Boolean),
58+
}),
59+
is.ObjectOf({
60+
type: is.LiteralOf("switch-sorter-at"),
61+
index: is.UnionOf([is.Number, is.LiteralOf("$")]),
62+
}),
63+
is.ObjectOf({
64+
type: is.LiteralOf("switch-renderer"),
65+
amount: is.Number,
66+
cycle: as.Optional(is.Boolean),
67+
}),
68+
is.ObjectOf({
69+
type: is.LiteralOf("switch-renderer-at"),
70+
index: is.UnionOf([is.Number, is.LiteralOf("$")]),
71+
}),
5472
// Action
5573
is.ObjectOf({
5674
type: is.LiteralOf("action-invoke"),

denops/fall/picker.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,9 @@ export class Picker<T extends Detail> implements AsyncDisposable {
104104
new MatchProcessor(params.matchers),
105105
);
106106
this.#visualizeProcessor = this.#stack.use(
107-
// TODO: Support multiple sorters/renderers
108107
new VisualizeProcessor(
109-
params.sorters?.at(0),
110-
params.renderers?.at(0),
108+
params.sorters ?? [],
109+
params.renderers ?? [],
111110
),
112111
);
113112
this.#previewProcessor = this.#stack.use(
@@ -385,6 +384,48 @@ export class Picker<T extends Detail> implements AsyncDisposable {
385384
restart: true,
386385
});
387386
break;
387+
case "switch-sorter": {
388+
let index = this.#visualizeProcessor.sorterIndex + event.amount;
389+
if (event.cycle) {
390+
if (index < 0) {
391+
index = this.#visualizeProcessor.sorterCount - 1;
392+
} else if (index >= this.#visualizeProcessor.sorterCount) {
393+
index = 0;
394+
}
395+
}
396+
this.#visualizeProcessor.sorterIndex = index;
397+
this.#visualizeProcessor.start(denops, {
398+
items: this.#matchProcessor.items,
399+
});
400+
break;
401+
}
402+
case "switch-sorter-at":
403+
this.#visualizeProcessor.sorterIndex = event.index;
404+
this.#visualizeProcessor.start(denops, {
405+
items: this.#matchProcessor.items,
406+
});
407+
break;
408+
case "switch-renderer": {
409+
let index = this.#visualizeProcessor.rendererIndex + event.amount;
410+
if (event.cycle) {
411+
if (index < 0) {
412+
index = this.#visualizeProcessor.rendererCount - 1;
413+
} else if (index >= this.#visualizeProcessor.rendererCount) {
414+
index = 0;
415+
}
416+
}
417+
this.#visualizeProcessor.rendererIndex = index;
418+
this.#visualizeProcessor.start(denops, {
419+
items: this.#matchProcessor.items,
420+
});
421+
break;
422+
}
423+
case "switch-renderer-at":
424+
this.#visualizeProcessor.rendererIndex = event.index;
425+
this.#visualizeProcessor.start(denops, {
426+
items: this.#matchProcessor.items,
427+
});
428+
break;
388429
case "action-invoke":
389430
accept(event.name);
390431
break;

denops/fall/processor/visualize.ts

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export type VisualizeProcessorOptions = {
1919
};
2020

2121
export class VisualizeProcessor<T extends Detail> {
22-
#sorter?: Sorter<T>;
23-
#renderer?: Renderer<T>;
22+
#sorters: Sorter<T>[];
23+
#renderers: Renderer<T>[];
2424
#height: number;
2525
#scrollOffset: number;
2626
#controller: AbortController = new AbortController();
@@ -30,18 +30,62 @@ export class VisualizeProcessor<T extends Detail> {
3030
#itemCount: number = 0;
3131
#cursor: number = 0;
3232
#offset: number = 0;
33+
#sorterIndex: number = 0;
34+
#rendererIndex: number = 0;
3335

3436
constructor(
35-
sorter: Sorter<T> | undefined,
36-
renderer: Renderer<T> | undefined,
37+
sorters: Sorter<T>[],
38+
renderers: Renderer<T>[],
3739
options: VisualizeProcessorOptions = {},
3840
) {
39-
this.#sorter = sorter;
40-
this.#renderer = renderer;
41+
this.#sorters = sorters;
42+
this.#renderers = renderers;
4143
this.#height = options.height ?? HEIGHT;
4244
this.#scrollOffset = options.scrollOffset ?? SCROLL_OFFSET;
4345
}
4446

47+
get #sorter(): Sorter<T> | undefined {
48+
return this.#sorters.at(this.#sorterIndex);
49+
}
50+
51+
get #renderer(): Renderer<T> | undefined {
52+
return this.#renderers.at(this.#rendererIndex);
53+
}
54+
55+
get sorterCount(): number {
56+
return this.#sorters.length;
57+
}
58+
59+
get rendererCount(): number {
60+
return this.#renderers.length;
61+
}
62+
63+
get sorterIndex(): number {
64+
return this.#sorterIndex;
65+
}
66+
67+
set sorterIndex(index: number | "$") {
68+
if (index === "$" || index >= this.sorterCount) {
69+
index = this.sorterCount - 1;
70+
} else if (index < 0) {
71+
index = 0;
72+
}
73+
this.#sorterIndex = index;
74+
}
75+
76+
get rendererIndex(): number {
77+
return this.#rendererIndex;
78+
}
79+
80+
set rendererIndex(index: number | "$") {
81+
if (index === "$" || index >= this.rendererCount) {
82+
index = this.rendererCount - 1;
83+
} else if (index < 0) {
84+
index = 0;
85+
}
86+
this.#rendererIndex = index;
87+
}
88+
4589
get items() {
4690
return this.#items;
4791
}

plugin/fall/mapping.vim

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ cnoremap <silent> <Plug>(fall-switch-matcher-first) <Cmd>call fall#internal#disp
2424
cnoremap <silent> <Plug>(fall-switch-matcher-last) <Cmd>call fall#internal#dispatch(#{type: 'switch-matcher-at', index: '$'})<CR>
2525
cnoremap <silent> <Plug>(fall-switch-matcher-prev) <Cmd>call fall#internal#dispatch(#{type: 'switch-matcher', amount: -1, cycle: v:true})<CR>
2626
cnoremap <silent> <Plug>(fall-switch-matcher-next) <Cmd>call fall#internal#dispatch(#{type: 'switch-matcher', amount: 1, cycle: v:true})<CR>
27+
cnoremap <silent> <Plug>(fall-switch-sorter-first) <Cmd>call fall#internal#dispatch(#{type: 'switch-sorter-at', index: 0})<CR>
28+
cnoremap <silent> <Plug>(fall-switch-sorter-last) <Cmd>call fall#internal#dispatch(#{type: 'switch-sorter-at', index: '$'})<CR>
29+
cnoremap <silent> <Plug>(fall-switch-sorter-prev) <Cmd>call fall#internal#dispatch(#{type: 'switch-sorter', amount: -1, cycle: v:true})<CR>
30+
cnoremap <silent> <Plug>(fall-switch-sorter-next) <Cmd>call fall#internal#dispatch(#{type: 'switch-sorter', amount: 1, cycle: v:true})<CR>
31+
cnoremap <silent> <Plug>(fall-switch-renderer-first) <Cmd>call fall#internal#dispatch(#{type: 'switch-renderer-at', index: 0})<CR>
32+
cnoremap <silent> <Plug>(fall-switch-renderer-last) <Cmd>call fall#internal#dispatch(#{type: 'switch-renderer-at', index: '$'})<CR>
33+
cnoremap <silent> <Plug>(fall-switch-renderer-prev) <Cmd>call fall#internal#dispatch(#{type: 'switch-renderer', amount: -1, cycle: v:true})<CR>
34+
cnoremap <silent> <Plug>(fall-switch-renderer-next) <Cmd>call fall#internal#dispatch(#{type: 'switch-renderer', amount: 1, cycle: v:true})<CR>
2735
2836
" Preview
2937
cnoremap <silent> <Plug>(fall-preview-first) <Cmd>call fall#internal#dispatch(#{type: 'preview-component-execute', command: 'silent! normal! gg'})<CR>
@@ -72,6 +80,8 @@ if !get(g:, 'fall_disable_default_mapping')
7280
cnoremap <nowait> <Tab> <Plug>(fall-action-select)
7381
" Switch
7482
cnoremap <nowait> <F2> <Plug>(fall-switch-matcher-next)
83+
cnoremap <nowait> <F3> <Plug>(fall-switch-sorter-next)
84+
cnoremap <nowait> <F4> <Plug>(fall-switch-renderer-next)
7585
endfunction
7686

7787
augroup fall_mapping_plugin

0 commit comments

Comments
 (0)