1
+ /**
2
+ * @module custom
3
+ *
4
+ * Custom configuration management for vim-fall.
5
+ *
6
+ * This module handles loading, managing, and reloading user customizations
7
+ * for vim-fall. It provides APIs for:
8
+ *
9
+ * - Loading user custom configuration files
10
+ * - Managing global settings (theme, coordinator)
11
+ * - Registering custom pickers
12
+ * - Configuring action pickers
13
+ * - Editing and reloading configurations
14
+ *
15
+ * The custom system allows users to define their own pickers, customize
16
+ * existing ones, and configure the overall appearance and behavior of
17
+ * vim-fall through a TypeScript configuration file.
18
+ */
19
+
1
20
import type { Denops } from "jsr:@denops/std@^7.3.2" ;
2
21
import * as buffer from "jsr:@denops/std@^7.3.2/buffer" ;
3
22
import * as vars from "jsr:@denops/std@^7.3.2/variable" ;
@@ -53,7 +72,22 @@ let actionPickerParams = { ...defaultActionPickerParams };
53
72
const pickerParamsMap = new Map < string , PickerParams > ( ) ;
54
73
55
74
/**
56
- * Edit user custom
75
+ * Opens the user custom configuration file for editing.
76
+ *
77
+ * This function:
78
+ * - Creates the custom file from a template if it doesn't exist
79
+ * - Opens the file in a new buffer
80
+ * - Sets up auto-reload on save
81
+ *
82
+ * @param denops - The Denops instance
83
+ * @param options - Buffer open options (split, vsplit, etc.)
84
+ * @returns A promise that resolves when the file is opened
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * // Open custom file in a vertical split
89
+ * await editUserCustom(denops, { mods: "vertical" });
90
+ * ```
57
91
*/
58
92
export async function editUserCustom (
59
93
denops : Denops ,
@@ -86,7 +120,28 @@ export async function editUserCustom(
86
120
}
87
121
88
122
/**
89
- * Load user custom from the g:fall_config_path.
123
+ * Loads the user custom configuration from the path specified in g:fall_custom_path.
124
+ *
125
+ * This function:
126
+ * - Loads the custom TypeScript module
127
+ * - Executes its main function with the configuration context
128
+ * - Falls back to default configuration on error
129
+ * - Emits User:FallCustomLoaded autocmd on success
130
+ *
131
+ * @param denops - The Denops instance
132
+ * @param options - Loading options
133
+ * @param options.reload - Force reload even if already loaded
134
+ * @param options.verbose - Show loading messages
135
+ * @returns A promise that resolves when loading is complete
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * // Initial load
140
+ * await loadUserCustom(denops);
141
+ *
142
+ * // Force reload with verbose output
143
+ * await loadUserCustom(denops, { reload: true, verbose: true });
144
+ * ```
90
145
*/
91
146
export function loadUserCustom (
92
147
denops : Denops ,
@@ -144,7 +199,26 @@ export function loadUserCustom(
144
199
}
145
200
146
201
/**
147
- * Recache user custom by running `deno cache --reload` command.
202
+ * Recaches the user custom file and its dependencies.
203
+ *
204
+ * This function runs `deno cache --reload` on the custom file to:
205
+ * - Download and update all dependencies
206
+ * - Recompile TypeScript code
207
+ * - Clear the module cache
208
+ *
209
+ * After recaching, Vim must be restarted for changes to take effect.
210
+ *
211
+ * @param denops - The Denops instance
212
+ * @param options - Recache options
213
+ * @param options.verbose - Show cache progress
214
+ * @param options.signal - AbortSignal to cancel the operation
215
+ * @returns A promise that resolves when recaching is complete
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * // Recache with progress output
220
+ * await recacheUserCustom(denops, { verbose: true });
221
+ * ```
148
222
*/
149
223
export async function recacheUserCustom (
150
224
denops : Denops ,
@@ -199,14 +273,32 @@ export async function recacheUserCustom(
199
273
}
200
274
201
275
/**
202
- * Get global custom.
276
+ * Gets the current global settings.
277
+ *
278
+ * @returns The current setting configuration including theme and coordinator
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * const settings = getSetting();
283
+ * console.log("Current theme:", settings.theme);
284
+ * ```
203
285
*/
204
286
export function getSetting ( ) : Readonly < Setting > {
205
287
return setting ;
206
288
}
207
289
208
290
/**
209
- * Get action picker params.
291
+ * Gets the current action picker parameters.
292
+ *
293
+ * Action pickers are used for selecting actions to perform on items.
294
+ *
295
+ * @returns The current action picker configuration
296
+ *
297
+ * @example
298
+ * ```typescript
299
+ * const params = getActionPickerParams();
300
+ * console.log("Action picker matchers:", params.matchers);
301
+ * ```
210
302
*/
211
303
export function getActionPickerParams ( ) : Readonly <
212
304
ActionPickerParams
@@ -215,7 +307,18 @@ export function getActionPickerParams(): Readonly<
215
307
}
216
308
217
309
/**
218
- * Get item picker params.
310
+ * Gets the parameters for a specific picker by name.
311
+ *
312
+ * @param name - The name of the picker
313
+ * @returns The picker parameters if found, undefined otherwise
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * const filePickerParams = getPickerParams("file");
318
+ * if (filePickerParams) {
319
+ * console.log("File picker source:", filePickerParams.source);
320
+ * }
321
+ * ```
219
322
*/
220
323
export function getPickerParams (
221
324
name : string ,
@@ -228,18 +331,42 @@ export function getPickerParams(
228
331
}
229
332
230
333
/**
231
- * List item picker names.
334
+ * Lists all registered picker names.
335
+ *
336
+ * @returns An array of all registered picker names
337
+ *
338
+ * @example
339
+ * ```typescript
340
+ * const pickers = listPickerNames();
341
+ * console.log("Available pickers:", pickers);
342
+ * // Output: ["file", "grep", "buffer", ...]
343
+ * ```
232
344
*/
233
345
export function listPickerNames ( ) : readonly string [ ] {
234
346
return Array . from ( pickerParamsMap . keys ( ) ) ;
235
347
}
236
348
349
+ /**
350
+ * Resets all custom configurations to their defaults.
351
+ * This is called before loading/reloading custom configurations.
352
+ */
237
353
function reset ( ) : void {
238
354
setting = { ...defaultSetting } ;
239
355
actionPickerParams = { ...defaultActionPickerParams } ;
240
356
pickerParamsMap . clear ( ) ;
241
357
}
242
358
359
+ /**
360
+ * Builds the context object passed to custom configuration files.
361
+ *
362
+ * This context provides APIs for:
363
+ * - Refining global settings
364
+ * - Configuring action pickers
365
+ * - Defining new pickers from sources or curators
366
+ *
367
+ * @param denops - The Denops instance
368
+ * @returns The configuration context object
369
+ */
243
370
function buildContext ( denops : Denops ) : {
244
371
denops : Denops ;
245
372
refineSetting : ReturnType < typeof buildRefineSetting > ;
@@ -266,6 +393,13 @@ function buildContext(denops: Denops): {
266
393
} ;
267
394
}
268
395
396
+ /**
397
+ * Gets the URL of the user custom file from g:fall_custom_path.
398
+ *
399
+ * @param denops - The Denops instance
400
+ * @returns The file URL of the custom configuration
401
+ * @throws Error if g:fall_custom_path is not set or invalid
402
+ */
269
403
async function getUserCustomUrl ( denops : Denops ) : Promise < URL > {
270
404
try {
271
405
const path = await vars . g . get ( denops , "fall_custom_path" ) as string ;
@@ -277,6 +411,12 @@ async function getUserCustomUrl(denops: Denops): Promise<URL> {
277
411
}
278
412
}
279
413
414
+ /**
415
+ * Validates a picker name to ensure it's valid and not already used.
416
+ *
417
+ * @param name - The picker name to validate
418
+ * @throws ExpectedError if the name is invalid or already exists
419
+ */
280
420
function validatePickerName ( name : string ) : void {
281
421
if ( pickerParamsMap . has ( name ) ) {
282
422
throw new ExpectedError ( `Picker '${ name } ' is already defined.` ) ;
@@ -286,6 +426,12 @@ function validatePickerName(name: string): void {
286
426
}
287
427
}
288
428
429
+ /**
430
+ * Validates action names to ensure they don't use reserved prefixes.
431
+ *
432
+ * @param actions - The actions object to validate
433
+ * @throws ExpectedError if any action name starts with '@'
434
+ */
289
435
function validateActions ( actions : Record < PropertyKey , unknown > ) : void {
290
436
Object . keys ( actions ) . forEach ( ( name ) => {
291
437
if ( name . startsWith ( "@" ) ) {
0 commit comments