diff --git a/src/DataviewSuggester.ts b/src/DataviewSuggester.ts index 6ea6eeb..1c3662a 100644 --- a/src/DataviewSuggester.ts +++ b/src/DataviewSuggester.ts @@ -1,7 +1,6 @@ import { App, Editor, - Plugin, EditorPosition, EditorSuggest, EditorSuggestContext, @@ -11,8 +10,11 @@ import { import { getTriggerText } from "./trigger"; import uFuzzy from "@leeoniya/ufuzzy"; import { getAPI, DataviewApi } from "obsidian-dataview"; +import DataviewAutocompletePlugin from "./main"; export class DataviewSuggester extends EditorSuggest { + plugin: DataviewAutocompletePlugin; + maxSuggestions: number; searcher: uFuzzy; @@ -22,12 +24,13 @@ export class DataviewSuggester extends EditorSuggest { suggestionsRefCount: { [key: string]: number } = {}; // maps suggestions to number of files including them constructor( - plugin: Plugin, + plugin: DataviewAutocompletePlugin, maxSuggestions: number = 10, singleErrorMode: boolean = false, allowExtraChars: boolean = false, ) { super(plugin.app); + this.plugin = plugin; this.maxSuggestions = maxSuggestions; this.searcher = new uFuzzy({ intraMode: singleErrorMode ? 1 : 0, @@ -50,15 +53,26 @@ export class DataviewSuggester extends EditorSuggest { } getSuggestions(context: EditorSuggestContext): string[] | Promise { - let idxs = this.searcher.filter(this.suggestionsList, context.query); + // TODO: add filter at index-time? + let filtered = this.suggestionsList; + for (const filterPattern of this.plugin.settings.ignoredFields) { + const regex = new RegExp(`^(${filterPattern})::.*`); + const ignoredSuggestions = filtered.filter((suggestion) => regex.test(suggestion)); + // minimatch.match(filtered, filterPattern + ":: *", { partial: true }) + for (const ignoredSuggestion of ignoredSuggestions) { + filtered = filtered.slice(filtered.indexOf(ignoredSuggestion) + 1); + } + } + + const idxs = this.searcher.filter(filtered, context.query); if (idxs != null && idxs.length > 0) { - let info = this.searcher.info(idxs, this.suggestionsList, context.query); - let order = this.searcher.sort(info, this.suggestionsList, context.query); + let info = this.searcher.info(idxs, filtered, context.query); + let order = this.searcher.sort(info, filtered, context.query); // return top N suggestions with marks return order .slice(0, this.maxSuggestions) - .map((idx) => [idx, this.suggestionsList[info.idx[idx]]]) + .map((idx) => [idx, filtered[info.idx[idx]]]) .map((suggestion: [number, string]) => uFuzzy.highlight(suggestion[1], info.ranges[suggestion[0]])); } return []; diff --git a/src/SettingsTab.ts b/src/SettingsTab.ts new file mode 100644 index 0000000..4440ea6 --- /dev/null +++ b/src/SettingsTab.ts @@ -0,0 +1,39 @@ +import { App, PluginSettingTab, Setting } from "obsidian"; +import DataviewAutocompletePlugin from "./main"; + +export class SettingsTab extends PluginSettingTab { + plugin: DataviewAutocompletePlugin; + + constructor(app: App, plugin: DataviewAutocompletePlugin) { + super(app, plugin); + this.plugin = plugin; + } + + display(): void { + let { containerEl } = this; + containerEl.empty(); + + const excludeDesc = document.createDocumentFragment(); + const link = document.createElement("a"); + link.href = "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions"; + link.text = "Regex patterns"; + excludeDesc.append(link); + excludeDesc.append(" to exclude field names from suggestions. One pattern per line."); + new Setting(containerEl) + .setName("Exclude fields") + .setDesc(excludeDesc) + .addTextArea((textArea) => { + textArea.inputEl.setAttribute("rows", "5"); + textArea + .setPlaceholder("created.*\nmodified.*\ndate") + .setValue(this.plugin.settings.ignoredFields.join("\n")) + .onChange(async (value) => { + this.plugin.settings.ignoredFields = value + .split("\n") + .map((val) => val.trim()) + .filter((val) => val.length > 0); + await this.plugin.saveSettings(); + }); + }); + } +} diff --git a/src/main.ts b/src/main.ts index 1c11ad1..8a541c3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,13 +1,14 @@ import { App, Plugin, PluginSettingTab, Setting, TFile } from "obsidian"; import { DataviewSuggester } from "./DataviewSuggester"; import { getAPI } from "obsidian-dataview"; +import { SettingsTab } from "./SettingsTab"; interface DataviewAutocompleteSettings { ignoredFields: string[]; } const DEFAULT_SETTINGS: DataviewAutocompleteSettings = { - ignoredFields: [], + ignoredFields: ["created.*", "modified.*", "date"], }; export default class DataviewAutocompletePlugin extends Plugin { @@ -16,6 +17,7 @@ export default class DataviewAutocompletePlugin extends Plugin { async onload() { await this.loadSettings(); + this.addSettingTab(new SettingsTab(this.app, this)); this.registerEvent( // @ts-ignore