From 53f1d5e58a9ada19a5bfd6771a1f9b63b0e3b405 Mon Sep 17 00:00:00 2001 From: Shougo Matsushita Date: Tue, 20 Jun 2023 13:57:19 +0900 Subject: [PATCH] Change filters type --- denops/ddu/ddu.ts | 144 ++++++++++++++++++++++++++++---------------- denops/ddu/types.ts | 12 +++- doc/ddu.txt | 38 +++++++++--- 3 files changed, 130 insertions(+), 64 deletions(-) diff --git a/denops/ddu/ddu.ts b/denops/ddu/ddu.ts index 391b7f0..f71cf09 100644 --- a/denops/ddu/ddu.ts +++ b/denops/ddu/ddu.ts @@ -44,6 +44,7 @@ import { SourceOptions, TreePath, UiOptions, + UserFilter, UserOptions, UserSource, } from "./types.ts"; @@ -320,19 +321,19 @@ export class Ddu { } const [sourceOptions, sourceParams] = sourceArgs( + source, this.options, userSource, - source, ); // Call "onRefreshItems" hooks const filters = sourceOptions.matchers.concat( sourceOptions.sorters, ).concat(sourceOptions.converters); - for (const filterName of filters) { + for (const userFilter of filters) { const [filter, filterOptions, filterParams] = await this.getFilter( denops, - filterName, + userFilter, ); if (!filter || !filter.onRefreshItems) { continue; @@ -499,9 +500,9 @@ export class Ddu { return; } const [sourceOptions, _] = sourceArgs( + source, this.options, userSource, - source, ); sources.push({ name: userSource.name, @@ -665,9 +666,9 @@ export class Ddu { continue; } const [sourceOptions, sourceParams] = sourceArgs( + source, this.options, userSource, - source, ); // The source may not have "onEvent" @@ -818,11 +819,11 @@ export class Ddu { return null; } - const [kindOptions, _1] = kindArgs(this.options, kind); + const [kindOptions, _1] = kindArgs(kind, this.options); const [sourceOptions, _2] = sourceArgs( + source, this.options, this.options.sources[indexes.length > 0 ? indexes[0] : 0], - source, ); return { @@ -869,12 +870,12 @@ export class Ddu { indexes.length > 0 ? indexes[0] : 0 ]; const [sourceOptions, sourceParams] = sourceArgs( + source, this.options, userSource, - source, ); - const [kindOptions, kindParams] = kindArgs(this.options, kind); + const [kindOptions, kindParams] = kindArgs(kind, this.options); // Get default action in the first if (actionName === "default") { @@ -895,8 +896,8 @@ export class Ddu { // NOTE: "actionName" may be overwritten by aliases const [actionOptions, actionParams] = actionArgs( - this.options, actionName, + this.options, userActionParams, ); @@ -1077,9 +1078,9 @@ export class Ddu { const index = parent.__sourceIndex; const source = this.loader.getSource(parent.__sourceName); const [sourceOptions, sourceParams] = sourceArgs( + source, this.options, this.options.sources[index], - source, ); this.setExpanded(convertTreePath(parent.treePath)); @@ -1243,9 +1244,9 @@ export class Ddu { const index = item.__sourceIndex; const source = this.loader.getSource(item.__sourceName); const [sourceOptions, _] = sourceArgs( + source, this.options, this.options.sources[index], - source, ); if (!item.treePath) { @@ -1369,9 +1370,9 @@ export class Ddu { getSourceArgs() { return this.options.sources.map((userSource) => sourceArgs( + this.loader.getSource(userSource.name), this.options, userSource, - this.loader.getSource(userSource.name), ) ); } @@ -1388,9 +1389,9 @@ export class Ddu { const source = this.loader.getSource(userSource.name); const [sourceOptions, sourceParams] = sourceArgs( + source, this.options, userSource, - source, ); if (!source || !source.checkUpdated) { @@ -1476,9 +1477,9 @@ export class Ddu { } const [sourceOptions, sourceParams] = sourceArgs( + source, this.options, userSource, - source, ); return [source, sourceOptions, sourceParams]; @@ -1486,7 +1487,7 @@ export class Ddu { async getFilter( denops: Denops, - name: string, + userFilter: UserFilter, ): Promise< [ BaseFilter | undefined, @@ -1494,15 +1495,22 @@ export class Ddu { BaseFilterParams, ] > { - if (!this.loader.getFilter(name)) { - await this.autoload(denops, "filter", name); + // Convert type + if (typeof userFilter === "string") { + userFilter = { + name: userFilter, + }; + } + + if (!this.loader.getFilter(userFilter.name)) { + await this.autoload(denops, "filter", userFilter.name); } - const filter = this.loader.getFilter(name); + const filter = this.loader.getFilter(userFilter.name); if (!filter) { await denops.call( "ddu#util#print_error", - `Not found filter: ${name}`, + `Not found filter: ${userFilter.name}`, ); return [ undefined, @@ -1511,7 +1519,11 @@ export class Ddu { ]; } - const [filterOptions, filterParams] = filterArgs(this.options, filter); + const [filterOptions, filterParams] = filterArgs( + filter, + this.options, + userFilter, + ); await checkFilterOnInit(filter, denops, filterOptions, filterParams); return [filter, filterOptions, filterParams]; @@ -1566,7 +1578,7 @@ export class Ddu { ]; } - const [columnOptions, columnParams] = columnArgs(this.options, column); + const [columnOptions, columnParams] = columnArgs(column, this.options); await checkColumnOnInit(column, denops, columnOptions, columnParams); return [column, columnOptions, columnParams]; @@ -1580,9 +1592,9 @@ export class Ddu { ): Promise<[boolean, number, DduItem[]]> { const source = this.loader.getSource(userSource.name); const [sourceOptions, _] = sourceArgs( + source, this.options, userSource, - source, ); const state = this.gatherStates[index]; @@ -1623,14 +1635,14 @@ export class Ddu { private async callFilters( denops: Denops, sourceOptions: SourceOptions, - filters: string[], + filters: UserFilter[], input: string, items: DduItem[], ) { - for (const filterName of filters) { + for (const userFilter of filters) { const [filter, filterOptions, filterParams] = await this.getFilter( denops, - filterName, + userFilter, ); if (!filter) { continue; @@ -1775,9 +1787,9 @@ function sourceArgs< Params extends BaseSourceParams, UserData extends unknown, >( + source: BaseSource | null, options: DduOptions, userSource: UserSource | null, - source: BaseSource | null, ): [SourceOptions, BaseSourceParams] { const o = foldMerge( mergeSourceOptions, @@ -1788,42 +1800,60 @@ function sourceArgs< userSource?.options, ], ); - const p = foldMerge(mergeSourceParams, defaultDummy, [ - source?.params(), - options.sourceParams["_"], - source ? options.sourceParams[source.name] : {}, - userSource?.params, - ]); + const p = foldMerge( + mergeSourceParams, + defaultDummy, + [ + source?.params(), + options.sourceParams["_"], + source ? options.sourceParams[source.name] : {}, + userSource?.params, + ], + ); return [o, p]; } function filterArgs< Params extends BaseFilterParams, >( - options: DduOptions, filter: BaseFilter, + options: DduOptions, + userFilter: UserFilter, ): [FilterOptions, BaseFilterParams] { + // Convert type + if (typeof userFilter === "string") { + userFilter = { + name: userFilter, + }; + } + const o = foldMerge( mergeFilterOptions, defaultFilterOptions, [ options.filterOptions["_"], options.filterOptions[filter.name], + userFilter?.options, + ], + ); + const p = foldMerge( + mergeFilterParams, + defaultDummy, + [ + filter?.params(), + options.filterParams["_"], + options.filterParams[filter.name], + userFilter?.params, ], ); - const p = foldMerge(mergeFilterParams, defaultDummy, [ - filter?.params(), - options.filterParams["_"], - options.filterParams[filter.name], - ]); return [o, p]; } function kindArgs< Params extends BaseKindParams, >( - options: DduOptions, kind: BaseKind, + options: DduOptions, ): [KindOptions, BaseKindParams] { const o = foldMerge( mergeKindOptions, @@ -1833,19 +1863,23 @@ function kindArgs< options.kindOptions[kind.name], ], ); - const p = foldMerge(mergeKindParams, defaultDummy, [ - kind?.params(), - options.kindParams["_"], - options.kindParams[kind.name], - ]); + const p = foldMerge( + mergeKindParams, + defaultDummy, + [ + kind?.params(), + options.kindParams["_"], + options.kindParams[kind.name], + ], + ); return [o, p]; } function columnArgs< Params extends BaseColumnParams, >( - options: DduOptions, column: BaseColumn, + options: DduOptions, ): [ColumnOptions, BaseColumnParams] { const o = foldMerge( mergeColumnOptions, @@ -1855,17 +1889,21 @@ function columnArgs< options.columnOptions[column.name], ], ); - const p = foldMerge(mergeColumnParams, defaultDummy, [ - column?.params(), - options.columnParams["_"], - options.columnParams[column.name], - ]); + const p = foldMerge( + mergeColumnParams, + defaultDummy, + [ + column?.params(), + options.columnParams["_"], + options.columnParams[column.name], + ], + ); return [o, p]; } function actionArgs( - options: DduOptions, actionName: string, + options: DduOptions, params: BaseActionParams, ): [ActionOptions, BaseActionParams] { const o = foldMerge( @@ -2104,7 +2142,7 @@ Deno.test("sourceArgs", () => { } const source = new S(); source.name = "strength"; - const [o, p] = sourceArgs(userOptions, null, source); + const [o, p] = sourceArgs(source, userOptions, null); assertEquals(o, { ...defaultSourceOptions(), matcherKey: "bar", diff --git a/denops/ddu/types.ts b/denops/ddu/types.ts index 397bbc5..a921a70 100644 --- a/denops/ddu/types.ts +++ b/denops/ddu/types.ts @@ -53,6 +53,12 @@ export type UserSource = { params?: BaseSourceParams; }; +export type UserFilter = string | { + name: string; + options?: FilterOptions; + params?: BaseFilterParams; +}; + export type SourceInfo = { name: string; index: number; @@ -108,14 +114,14 @@ export type SourceOptions = { ) => Promise) >; columns: string[]; - converters: string[]; + converters: UserFilter[]; defaultAction: string; ignoreCase: boolean; matcherKey: string; - matchers: string[]; + matchers: UserFilter[]; maxItems: number; path: TreePath; - sorters: string[]; + sorters: UserFilter[]; volatile: boolean; }; diff --git a/doc/ddu.txt b/doc/ddu.txt index b1f4474..0ac9573 100644 --- a/doc/ddu.txt +++ b/doc/ddu.txt @@ -630,9 +630,16 @@ columns (string[]) Default: [] *ddu-source-option-converters* -converters (string[]) - It is a list of registered filter names to change items - attributes. +converters (string[] | dictionary[]) + It is a list of registered filter names or elements which are + formatted as: +> + #{ + name: {filter-name}, + options: {filter-options}, + params: {filter-params}, + } +< Please see |ddu-filters|. Items will be processed in the order you specify here. @@ -658,9 +665,16 @@ matcherKey (string) Default: "word" *ddu-source-option-matchers* -matchers (string[]) - It is a list of registered filter names to filter items - by user input. +matchers (string[] | dictionary[]) + It is a list of registered filter names or elements which are + formatted as: +> + #{ + name: {filter-name}, + options: {filter-options}, + params: {filter-params}, + } +< Please see |ddu-filters|. Items will be processed in the order you specify here. @@ -679,8 +693,16 @@ path (string | string[]) NOTE: It must be full path. *ddu-source-option-sorters* -sorters (string[]) - It is a list of registered filter names to sort items. +sorters (string[] | dictionary[]) + It is a list of registered filter names or elements which are + formatted as: +> + #{ + name: {filter-name}, + options: {filter-options}, + params: {filter-params}, + } +< Please see |ddu-filters|. Items will be processed in the order you specify here.