#70 - Added a "toggle context" setting + settings is now a Svelte store

A bit more verbose, but allows for proper reactivity
This commit is contained in:
Simon Cambier
2022-09-10 21:23:12 +02:00
parent c74ed2892c
commit 66e1d2d334
4 changed files with 97 additions and 31 deletions

View File

@@ -11,6 +11,7 @@
import ResultItemVault from './ResultItemVault.svelte' import ResultItemVault from './ResultItemVault.svelte'
import { Query } from 'src/query' import { Query } from 'src/query'
import { saveSearchHistory, searchHistory } from 'src/search-history' import { saveSearchHistory, searchHistory } from 'src/search-history'
import { SearchContextType, settings } from 'src/settings'
export let modal: OmnisearchVaultModal export let modal: OmnisearchVaultModal
let selectedIndex = 0 let selectedIndex = 0
@@ -28,6 +29,7 @@ import { saveSearchHistory, searchHistory } from 'src/search-history'
} }
onMount(async () => { onMount(async () => {
console.log('mount')
await reindexNotes() await reindexNotes()
searchQuery = searchHistory[historySearchIndex] searchQuery = searchHistory[historySearchIndex]
eventBus.enable('vault') eventBus.enable('vault')
@@ -38,8 +40,9 @@ import { saveSearchHistory, searchHistory } from 'src/search-history'
eventBus.on('vault', 'tab', switchToInFileModal) eventBus.on('vault', 'tab', switchToInFileModal)
eventBus.on('vault', 'arrow-up', () => moveIndex(-1)) eventBus.on('vault', 'arrow-up', () => moveIndex(-1))
eventBus.on('vault', 'arrow-down', () => moveIndex(1)) eventBus.on('vault', 'arrow-down', () => moveIndex(1))
eventBus.on('vault', 'prev-search-history', () => prevSearchHistory()) eventBus.on('vault', 'prev-search-history', prevSearchHistory)
eventBus.on('vault', 'next-search-history', () => nextSearchHistory()) eventBus.on('vault', 'next-search-history', nextSearchHistory)
eventBus.on('vault', 'toggle-context', toggleContext)
}) })
onDestroy(() => { onDestroy(() => {
@@ -59,6 +62,16 @@ import { saveSearchHistory, searchHistory } from 'src/search-history'
searchQuery = searchHistory[historySearchIndex] searchQuery = searchHistory[historySearchIndex]
} }
function toggleContext() {
settings.update(s => {
s.showContext =
s.showContext === SearchContextType.None
? SearchContextType.Simple
: SearchContextType.None
return s
})
}
async function updateResults() { async function updateResults() {
query = new Query(searchQuery) query = new Query(searchQuery)
resultNotes = (await getSuggestions(query)).sort( resultNotes = (await getSuggestions(query)).sort(
@@ -212,4 +225,10 @@ import { saveSearchHistory, searchHistory } from 'src/search-history'
<div class="prompt-instruction"> <div class="prompt-instruction">
<span class="prompt-instruction-command">esc</span><span>to close</span> <span class="prompt-instruction-command">esc</span><span>to close</span>
</div> </div>
<br />
<div class="prompt-instruction">
<span class="prompt-instruction-command">ctrl+h</span><span
>to toggle context</span>
</div>
</div> </div>

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { getNoteFromCache } from 'src/notes' import { getNoteFromCache } from 'src/notes'
import { settings } from 'src/settings' import { SearchContextType, settings } from 'src/settings'
import type { ResultNote } from '../globals' import type { ResultNote } from '../globals'
import { getMatches } from '../search' import { getMatches } from '../search'
import { highlighter, makeExcerpt, stringsToRegex } from '../utils' import { highlighter, makeExcerpt, stringsToRegex } from '../utils'
@@ -13,7 +13,7 @@
$: matches = getMatches(note.content, reg) $: matches = getMatches(note.content, reg)
$: cleanedContent = makeExcerpt(note.content, note.matches[0]?.offset ?? -1) $: cleanedContent = makeExcerpt(note.content, note.matches[0]?.offset ?? -1)
$: glyph = getNoteFromCache(note.path)?.doesNotExist $: glyph = getNoteFromCache(note.path)?.doesNotExist
$: title = settings.showShortName ? note.basename : note.path $: title = $settings.showShortName ? note.basename : note.path
</script> </script>
<ResultItemContainer id={note.path} {selected} on:mousemove on:click {glyph}> <ResultItemContainer id={note.path} {selected} on:mousemove on:click {glyph}>
@@ -28,7 +28,10 @@
</span> </span>
{/if} {/if}
</div> </div>
{#if $settings.showContext !== SearchContextType.None}
<div class="omnisearch-result__body"> <div class="omnisearch-result__body">
{@html cleanedContent.replace(reg, highlighter)} {@html cleanedContent.replace(reg, highlighter)}
</div> </div>
{/if}
</ResultItemContainer> </ResultItemContainer>

View File

@@ -3,6 +3,7 @@ import ModalVault from './components/ModalVault.svelte'
import ModalInFile from './components/ModalInFile.svelte' import ModalInFile from './components/ModalInFile.svelte'
import { eventBus, isInputComposition } from './globals' import { eventBus, isInputComposition } from './globals'
import { settings } from './settings' import { settings } from './settings'
import { get } from 'svelte/store'
abstract class OmnisearchModal extends Modal { abstract class OmnisearchModal extends Modal {
constructor(app: App) { constructor(app: App) {
@@ -37,7 +38,7 @@ abstract class OmnisearchModal extends Modal {
] as const) { ] as const) {
for (const modifier of ['Ctrl', 'Meta'] as const) { for (const modifier of ['Ctrl', 'Meta'] as const) {
this.scope.register([modifier], key.k, e => { this.scope.register([modifier], key.k, e => {
if (settings.CtrlJK && this.app.vault.getConfig('vimMode')) { if (get(settings).CtrlJK && this.app.vault.getConfig('vimMode')) {
e.preventDefault() e.preventDefault()
eventBus.emit('arrow-' + key.dir) eventBus.emit('arrow-' + key.dir)
} }
@@ -52,7 +53,7 @@ abstract class OmnisearchModal extends Modal {
] as const) { ] as const) {
for (const modifier of ['Ctrl', 'Meta'] as const) { for (const modifier of ['Ctrl', 'Meta'] as const) {
this.scope.register([modifier], key.k, e => { this.scope.register([modifier], key.k, e => {
if (settings.CtrlNP && this.app.vault.getConfig('vimMode')) { if (get(settings).CtrlNP && this.app.vault.getConfig('vimMode')) {
e.preventDefault() e.preventDefault()
eventBus.emit('arrow-' + key.dir) eventBus.emit('arrow-' + key.dir)
} }
@@ -98,6 +99,12 @@ abstract class OmnisearchModal extends Modal {
e.preventDefault() e.preventDefault()
eventBus.emit('prev-search-history') eventBus.emit('prev-search-history')
}) })
// Context
this.scope.register(['Ctrl'], 'h', e => {
e.preventDefault()
eventBus.emit('toggle-context')
})
} }
} }

View File

@@ -1,6 +1,7 @@
import { Plugin, PluginSettingTab, Setting, SliderComponent } from 'obsidian' import { Plugin, PluginSettingTab, Setting, SliderComponent } from 'obsidian'
import { notesCacheFilePath, searchIndexFilePath } from './globals' import { notesCacheFilePath, searchIndexFilePath } from './globals'
import type OmnisearchPlugin from './main' import type OmnisearchPlugin from './main'
import { get, readable, writable } from 'svelte/store'
interface WeightingSettings { interface WeightingSettings {
weightBasename: number weightBasename: number
@@ -15,11 +16,17 @@ export interface OmnisearchSettings extends WeightingSettings {
showIndexingNotices: boolean showIndexingNotices: boolean
ribbonIcon: boolean ribbonIcon: boolean
showShortName: boolean showShortName: boolean
showContext: SearchContextType
CtrlJK: boolean CtrlJK: boolean
CtrlNP: boolean CtrlNP: boolean
storeIndexInFile: boolean storeIndexInFile: boolean
} }
export enum SearchContextType {
None,
Simple,
}
export class SettingsTab extends PluginSettingTab { export class SettingsTab extends PluginSettingTab {
plugin: OmnisearchPlugin plugin: OmnisearchPlugin
@@ -46,8 +53,11 @@ export class SettingsTab extends PluginSettingTab {
'Files that are in Obsidian\'s "Options > Files & Links > Excluded Files" list will be downranked in results.' 'Files that are in Obsidian\'s "Options > Files & Links > Excluded Files" list will be downranked in results.'
) )
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.respectExcluded).onChange(async v => { toggle.setValue(get(settings).respectExcluded).onChange(async v => {
settings.respectExcluded = v settings.update(s => {
s.respectExcluded = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
}) })
) )
@@ -63,8 +73,11 @@ export class SettingsTab extends PluginSettingTab {
.setName('Ignore diacritics') .setName('Ignore diacritics')
.setDesc(diacriticsDesc) .setDesc(diacriticsDesc)
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.ignoreDiacritics).onChange(async v => { toggle.setValue(get(settings).ignoreDiacritics).onChange(async v => {
settings.ignoreDiacritics = v settings.update(s => {
s.ignoreDiacritics = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
}) })
) )
@@ -82,10 +95,13 @@ export class SettingsTab extends PluginSettingTab {
.setName('EXPERIMENTAL - Store index in file') .setName('EXPERIMENTAL - Store index in file')
.setDesc(serializedIndexDesc) .setDesc(serializedIndexDesc)
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.storeIndexInFile).onChange(async v => { toggle.setValue(get(settings).storeIndexInFile).onChange(async v => {
app.vault.adapter.remove(notesCacheFilePath) app.vault.adapter.remove(notesCacheFilePath)
app.vault.adapter.remove(searchIndexFilePath) app.vault.adapter.remove(searchIndexFilePath)
settings.storeIndexInFile = v settings.update(s => {
s.storeIndexInFile = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
}) })
) )
@@ -103,8 +119,11 @@ export class SettingsTab extends PluginSettingTab {
'Add a button on the sidebar to open the Vault search modal. Needs a restart to remove the button.' 'Add a button on the sidebar to open the Vault search modal. Needs a restart to remove the button.'
) )
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.ribbonIcon).onChange(async v => { toggle.setValue(get(settings).ribbonIcon).onChange(async v => {
settings.ribbonIcon = v settings.update(s => {
s.ribbonIcon = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
if (v) { if (v) {
this.plugin.addRibbonButton() this.plugin.addRibbonButton()
@@ -117,8 +136,11 @@ export class SettingsTab extends PluginSettingTab {
.setName('Show indexing notices') .setName('Show indexing notices')
.setDesc('Show a notice when indexing is done, usually at startup.') .setDesc('Show a notice when indexing is done, usually at startup.')
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.showIndexingNotices).onChange(async v => { toggle.setValue(get(settings).showIndexingNotices).onChange(async v => {
settings.showIndexingNotices = v settings.update(s => {
s.showIndexingNotices = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
}) })
) )
@@ -130,8 +152,11 @@ export class SettingsTab extends PluginSettingTab {
'In the search results, only show the note name, without the full path.' 'In the search results, only show the note name, without the full path.'
) )
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.showShortName).onChange(async v => { toggle.setValue(get(settings).showShortName).onChange(async v => {
settings.showShortName = v settings.update(s => {
s.showShortName = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
}) })
) )
@@ -171,8 +196,11 @@ export class SettingsTab extends PluginSettingTab {
'Use [Ctrl/Cmd]+j/k to navigate up/down in the results, if Vim mode is enabled' 'Use [Ctrl/Cmd]+j/k to navigate up/down in the results, if Vim mode is enabled'
) )
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.CtrlJK).onChange(async v => { toggle.setValue(get(settings).CtrlJK).onChange(async v => {
settings.CtrlJK = v settings.update(s => {
s.CtrlJK = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
}) })
) )
@@ -182,8 +210,11 @@ export class SettingsTab extends PluginSettingTab {
'Use [Ctrl/Cmd]+n/p to navigate up/down in the results, if Vim mode is enabled' 'Use [Ctrl/Cmd]+n/p to navigate up/down in the results, if Vim mode is enabled'
) )
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(settings.CtrlNP).onChange(async v => { toggle.setValue(get(settings).CtrlNP).onChange(async v => {
settings.CtrlNP = v settings.update(s => {
s.CtrlNP = v
return s
})
await saveSettings(this.plugin) await saveSettings(this.plugin)
}) })
) )
@@ -193,10 +224,13 @@ export class SettingsTab extends PluginSettingTab {
weightSlider(cb: SliderComponent, key: keyof WeightingSettings): void { weightSlider(cb: SliderComponent, key: keyof WeightingSettings): void {
cb.setLimits(1, 3, 0.1) cb.setLimits(1, 3, 0.1)
cb.setValue(settings[key]) cb.setValue(get(settings)[key])
cb.setDynamicTooltip() cb.setDynamicTooltip()
cb.onChange(v => { cb.onChange(v => {
settings[key] = v settings.update(s => {
s[key] = v
return s
})
saveSettings(this.plugin) saveSettings(this.plugin)
}) })
} }
@@ -209,6 +243,7 @@ export const DEFAULT_SETTINGS: OmnisearchSettings = {
showIndexingNotices: false, showIndexingNotices: false,
showShortName: false, showShortName: false,
ribbonIcon: true, ribbonIcon: true,
showContext: SearchContextType.Simple,
weightBasename: 2, weightBasename: 2,
weightH1: 1.5, weightH1: 1.5,
@@ -221,12 +256,14 @@ export const DEFAULT_SETTINGS: OmnisearchSettings = {
storeIndexInFile: false, storeIndexInFile: false,
} as const } as const
export let settings: OmnisearchSettings = Object.assign({}, DEFAULT_SETTINGS) export const settings = writable(
Object.assign({}, DEFAULT_SETTINGS) as OmnisearchSettings
)
export async function loadSettings(plugin: Plugin): Promise<void> { export async function loadSettings(plugin: Plugin): Promise<void> {
settings = Object.assign({}, DEFAULT_SETTINGS, await plugin.loadData()) settings.set(Object.assign({}, DEFAULT_SETTINGS, await plugin.loadData()))
} }
export async function saveSettings(plugin: Plugin): Promise<void> { export async function saveSettings(plugin: Plugin): Promise<void> {
await plugin.saveData(settings) await plugin.saveData(get(settings))
} }