From 5eb75363bdeda709d1d5b94cc29f2810eaa1fa71 Mon Sep 17 00:00:00 2001 From: Simon Cambier Date: Fri, 6 May 2022 21:04:56 +0200 Subject: [PATCH] #41 - Settings page --- src/main.ts | 19 ++------- src/search.ts | 28 ++++++++----- src/settings.ts | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 src/settings.ts diff --git a/src/main.ts b/src/main.ts index 65b63b0..19b2860 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { Notice, Plugin, TFile } from 'obsidian' +import { Plugin, TFile } from 'obsidian' import { addToIndex, initGlobalSearchIndex, @@ -6,10 +6,12 @@ import { removeFromIndexByPath, } from './search' import { OmnisearchInFileModal, OmnisearchVaultModal } from './modals' +import { loadSettings, SettingsTab } from './settings' export default class OmnisearchPlugin extends Plugin { async onload(): Promise { - warningOldVersion() + await loadSettings(this) + this.addSettingTab(new SettingsTab(this)) // Commands to display Omnisearch modals this.addCommand({ @@ -59,16 +61,3 @@ export default class OmnisearchPlugin extends Plugin { }) } } - -function warningOldVersion(): void { - const plugins = ((app as any).plugins?.plugins ?? {}) as Record - if (plugins['scambier.omnisearch']) { - new Notice( - `OMNISEARCH -It looks like you have 2 versions of Omnisearch installed. -Please uninstall the old one (up to 0.2.5) and keep the new one (1.0.0+) -(Click to dismiss)`, - 0, - ) - } -} diff --git a/src/search.ts b/src/search.ts index e5d9941..f0f7993 100644 --- a/src/search.ts +++ b/src/search.ts @@ -14,6 +14,7 @@ import { wait, } from './utils' import type { Query } from './query' +import { settings } from './settings' let minisearchInstance: MiniSearch let indexedNotes: Record = {} @@ -57,7 +58,7 @@ export async function initGlobalSearchIndex(): Promise { if (file) await addToIndex(file) } - if (files.length > 0) { + if (files.length > 0 && settings.showIndexingNotices) { new Notice( `Omnisearch - Indexed ${files.length} notes in ${ new Date().getTime() - start @@ -82,19 +83,24 @@ async function search(query: Query): Promise { fuzzy: term => (term.length > 4 ? 0.2 : false), combineWith: 'AND', boost: { - basename: 2, - headings1: 1.5, - headings2: 1.3, - headings3: 1.1, + basename: settings.weightBasename, + headings1: settings.weightH1, + headings2: settings.weightH2, + headings3: settings.weightH3, }, }) - // Half the score for files that are in Obsidian's excluded list - results.forEach(result => { - if (app.metadataCache.isUserIgnored && app.metadataCache.isUserIgnored(result.id)) { - result.score /= 3 // TODO: make this value configurable or toggleable? - } - }) + // Downrank files that are in Obsidian's excluded list + if (settings.respectExcluded) { + results.forEach(result => { + if ( + app.metadataCache.isUserIgnored && + app.metadataCache.isUserIgnored(result.id) + ) { + result.score /= 3 // TODO: make this value configurable or toggleable? + } + }) + } // If the search query contains quotes, filter out results that don't have the exact match const exactTerms = query.getExactTerms() diff --git a/src/settings.ts b/src/settings.ts new file mode 100644 index 0000000..65d8101 --- /dev/null +++ b/src/settings.ts @@ -0,0 +1,104 @@ +import { Plugin, PluginSettingTab, Setting, SliderComponent } from 'obsidian' +import type OmnisearchPlugin from './main' + +interface WeightingSettings { + weightBasename: number + weightH1: number + weightH2: number + weightH3: number +} + +export interface OmnisearchSettings extends WeightingSettings { + showIndexingNotices: boolean + respectExcluded: boolean +} + +export class SettingsTab extends PluginSettingTab { + plugin: OmnisearchPlugin + + constructor(plugin: OmnisearchPlugin) { + super(app, plugin) + this.plugin = plugin + } + + display(): void { + const { containerEl } = this + containerEl.empty() + + // Title + const title = document.createElement('h2') + title.textContent = 'Omnisearch settings' + containerEl.appendChild(title) + + // Show notices + new Setting(containerEl) + .setName('Show indexing notices') + .setDesc('Show a notice when indexing is done, usually at startup.') + .addToggle(toggle => + toggle.setValue(settings.showIndexingNotices).onChange(async v => { + settings.showIndexingNotices = v + await saveSettings(this.plugin) + }), + ) + + // Respect excluded files + new Setting(containerEl) + .setName('Respect Obsidian\'s "Excluded Files"') + .setDesc( + 'Files that are in Obsidian\'s "Options > Files & Links > Excluded Files" list will be downranked in results.', + ) + .addToggle(toggle => + toggle.setValue(settings.respectExcluded).onChange(async v => { + settings.respectExcluded = v + await saveSettings(this.plugin) + }), + ) + + new Setting(containerEl).setName('Results weighting').setHeading() + + new Setting(containerEl) + .setName(`File name (default: ${DEFAULT_SETTINGS.weightBasename})`) + .addSlider(cb => this.weightSlider(cb, 'weightBasename')) + + new Setting(containerEl) + .setName(`Headings level 1 (default: ${DEFAULT_SETTINGS.weightH1})`) + .addSlider(cb => this.weightSlider(cb, 'weightH1')) + + new Setting(containerEl) + .setName(`Headings level 2 (default: ${DEFAULT_SETTINGS.weightH2})`) + .addSlider(cb => this.weightSlider(cb, 'weightH2')) + + new Setting(containerEl) + .setName(`Headings level 3 (default: ${DEFAULT_SETTINGS.weightH3})`) + .addSlider(cb => this.weightSlider(cb, 'weightH3')) + } + + weightSlider(cb: SliderComponent, key: keyof WeightingSettings): void { + cb.setLimits(1, 3, 0.1) + cb.setValue(settings[key]) + cb.setDynamicTooltip() + cb.onChange(v => { + settings[key] = v + saveSettings(this.plugin) + }) + } +} + +export const DEFAULT_SETTINGS: OmnisearchSettings = { + showIndexingNotices: true, + respectExcluded: true, + weightBasename: 2, + weightH1: 1.5, + weightH2: 1.3, + weightH3: 1.1, +} as const + +export let settings: OmnisearchSettings = Object.assign({}, DEFAULT_SETTINGS) + +export async function loadSettings(plugin: Plugin): Promise { + settings = Object.assign({}, DEFAULT_SETTINGS, await plugin.loadData()) +} + +export async function saveSettings(plugin: Plugin): Promise { + await plugin.saveData(settings) +}