#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:
@@ -10,7 +10,8 @@
|
|||||||
import { OmnisearchInFileModal, type OmnisearchVaultModal } from 'src/modals'
|
import { OmnisearchInFileModal, type OmnisearchVaultModal } from 'src/modals'
|
||||||
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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user