-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: subdir issue with file suggestion component
chore: reorg code a bit more. more to come yet. chore: update project metadata
- Loading branch information
1 parent
9a2396a
commit 7ad1e0e
Showing
22 changed files
with
495 additions
and
104,283 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"$schema": "https://biomejs.dev/schemas/1.7.1/schema.json", | ||
"organizeImports": { | ||
"enabled": true | ||
}, | ||
"linter": { | ||
"enabled": true, | ||
"rules": { | ||
"recommended": true | ||
} | ||
}, | ||
"files": { | ||
"ignore": [ "node_modules/**/*", "src/**/*.test.ts", "src/**/*.svelte" ] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { AbstractInputSuggest, TFolder, type App, type TAbstractFile } from "obsidian"; | ||
import { damerauLevenshtein } from "../../lib/damerau-levenshtein"; | ||
|
||
/** | ||
* Provides suggestions for file and folder paths. | ||
*/ | ||
export class FileInputSuggest extends AbstractInputSuggest<TAbstractFile> { | ||
app: App; | ||
inputEl: HTMLDivElement | HTMLInputElement; | ||
// biome-ignore lint/suspicious/noExplicitAny: obsidian demands it | ||
callback: (value: TAbstractFile, evt: MouseEvent | KeyboardEvent) => any = () => { }; | ||
filter: "file" | "folder" | "both" = "both"; | ||
|
||
/** | ||
* Creates a new instance of the FileInputSuggest class. | ||
* @param app - The application instance. Required to list files/folders in the Vault. | ||
* @param textInputEl - An input or editable div. | ||
*/ | ||
constructor(app: App, textInputEl: HTMLDivElement | HTMLInputElement) { | ||
super(app, textInputEl); | ||
this.inputEl = textInputEl; | ||
this.app = app; | ||
} | ||
|
||
/** | ||
* Calculates the similarity score between a query and a path. | ||
* The score is based on the Damerau-Levenshtein distance between the query and path, | ||
* with a multiplier that favors partial substring matches and prefix matches. | ||
* | ||
* @param query - The query string. | ||
* @param path - The path string. | ||
* @returns The similarity score between the query and path. | ||
*/ | ||
static similarityScore(query: string, path: string): number { | ||
// augment the edit distance with a multiplier which favours partial substring matches | ||
const q = query.toLowerCase(); | ||
const p = path.toLowerCase(); | ||
|
||
return damerauLevenshtein(q, p) * (p.includes(q) ? 0.2 : 1) * (p.startsWith(q) ? 0.1 : 1); | ||
}; | ||
|
||
/** | ||
* Recurses through the entire directory tree to get the complete list of folders. | ||
* @param folder - The folder to start the recursion from. If not provided, the root folder of the app's vault is used. | ||
* @returns A flat array of folder objects. | ||
*/ | ||
getFolders(folder?: TFolder): TFolder[] { | ||
const f = (folder || this.app.vault.getRoot()); | ||
const filteredChildren = f.children | ||
.filter((val): val is TFolder => val instanceof TFolder); | ||
const childFolders = filteredChildren | ||
.map((folder) => this.getFolders(folder)); | ||
const flatChildFolders = childFolders.flat(); | ||
return [f, ...flatChildFolders]; | ||
} | ||
|
||
/** | ||
* Retrieves the suggestions for the given query. | ||
* @param query - The query string. | ||
* @returns An array of file or folder objects which match the query. | ||
*/ | ||
protected getSuggestions(query: string): TAbstractFile[] { | ||
const files = [ | ||
...this.filter !== "file" ? this.getFolders() : [], | ||
...this.filter !== "folder" ? this.app.vault.getFiles() : [] | ||
]; | ||
files.sort((a, b) => FileInputSuggest.similarityScore(query, a.name) - FileInputSuggest.similarityScore(query, b.name)); | ||
return files; | ||
} | ||
|
||
/** | ||
* Adds the suggestion for the given file to the popover. | ||
* @param file - The file or folder to render. | ||
* @param el - The HTML element to render the suggestion in. | ||
*/ | ||
renderSuggestion(file: TAbstractFile, el: HTMLElement) { | ||
el.appendText(file.path); | ||
} | ||
|
||
/** | ||
* Fired when the user selects a given suggestion and performs the necessary actions. | ||
* @param file - The file or folder that was selected. | ||
* @param evt - The event that triggered the selection. | ||
*/ | ||
async selectSuggestion(file: TAbstractFile, evt: MouseEvent | KeyboardEvent) { | ||
super.setValue(file.path); | ||
this.callback(file, evt); | ||
this.close(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { TextComponent, type App, type TAbstractFile } from "obsidian"; | ||
import { FileInputSuggest } from "./file-input-suggest"; | ||
|
||
/** | ||
* Represents a component for file suggestions. | ||
* @class | ||
*/ | ||
export class FileSuggestionComponent extends TextComponent { | ||
fileInputSuggest: FileInputSuggest; | ||
|
||
/** | ||
* Creates an <input> which will offer a popover list of suggested files and/or folders. | ||
* @constructor | ||
* @param {HTMLElement} containerEl - The container element to append the FileSuggester to. | ||
* @param {App} app - The App instance. Required to list files/folders in the Vault. | ||
*/ | ||
constructor(containerEl: HTMLElement, app: App) { | ||
super(containerEl); | ||
containerEl.appendChild(this.inputEl); | ||
this.fileInputSuggest = new FileInputSuggest(app, this.inputEl); | ||
} | ||
|
||
/** | ||
* Sets the callback function to be executed when a file is selected. | ||
* | ||
* @param cb - The callback function to be executed. It takes two parameters: the selected file and the event that triggered the selection. | ||
* @returns The current instance of the `FileSuggester` class. | ||
*/ | ||
// biome-ignore lint/suspicious/noExplicitAny: obsidian demands it | ||
onSelect(cb: (value: TAbstractFile, evt: MouseEvent | KeyboardEvent) => any): this { | ||
this.fileInputSuggest.onSelect(cb); | ||
this.fileInputSuggest.callback = cb; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the component up to suggest files, folders, or both. | ||
* | ||
* @param filter - The filter to apply. Can be "file", "folder", or "both". Defaults to "both". | ||
* @returns The current instance of the file suggester. | ||
*/ | ||
addFilter(filter: "file" | "folder" | "both" = "both"): this { | ||
this.fileInputSuggest.filter = filter; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the limit for the number of files and/or folders suggested. | ||
* | ||
* @param limit - The maximum number of files and/or folders to suggest. Defaults to 100. | ||
* @returns The current instance of the `FileSuggester` class. | ||
*/ | ||
addLimit(limit = 100): this { | ||
this.fileInputSuggest.limit = limit; | ||
return this; | ||
} | ||
} | ||
|
6 changes: 2 additions & 4 deletions
6
src/components/NotePropSettings.svelte → ...mponents/frontmatter-prop-settings.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.