diff --git a/src/CmpModalVault.svelte b/src/CmpModalVault.svelte
index 1cb0d37..8301392 100644
--- a/src/CmpModalVault.svelte
+++ b/src/CmpModalVault.svelte
@@ -7,7 +7,7 @@ import { TFile } from "obsidian"
import { onMount, tick } from "svelte"
import CmpInput from "./CmpInput.svelte"
import CmpResultNote from "./CmpResultNote.svelte"
-import type { ResultNote } from "./globals"
+import { eventBus, type ResultNote } from "./globals"
import { ModalInFile, type ModalVault } from "./modal"
import { createNote, openNote } from "./notes"
import { getSuggestions } from "./search"
@@ -30,6 +30,12 @@ $: {
onMount(() => {
searchQuery = lastSearch
+ eventBus.on("vault", "enter", onInputEnter)
+ eventBus.on("vault", "shift-enter", onInputShiftEnter)
+ eventBus.on("vault", "ctrl-enter", onInputCtrlEnter)
+ eventBus.on("vault", "alt-enter", onInputAltEnter)
+ eventBus.on("vault", "arrow-up", () => moveIndex(-1))
+ eventBus.on("vault", "arrow-down", () => moveIndex(1))
})
function onClick() {
@@ -84,16 +90,7 @@ function scrollIntoView(): void {
Omnisearch - Vault
-
(searchQuery = e.detail)}
- on:enter={onInputEnter}
- on:shift-enter={onInputShiftEnter}
- on:ctrl-enter={onInputCtrlEnter}
- on:alt-enter={onInputAltEnter}
- on:arrow-up={() => moveIndex(-1)}
- on:arrow-down={() => moveIndex(1)}
-/>
+ (searchQuery = e.detail)} />
diff --git a/src/event-bus.ts b/src/event-bus.ts
new file mode 100644
index 0000000..577bea5
--- /dev/null
+++ b/src/event-bus.ts
@@ -0,0 +1,36 @@
+export type EventBusCallback = (...args: any[]) => any
+
+export class EventBus {
+ private handlers: Map
= new Map()
+ private disabled: string[] = []
+
+ public on(ctx: string, event: string, callback: EventBusCallback): void {
+ if (ctx.includes('@') || event.includes('@')) {
+ throw new Error('Invalid ctx/event name - Cannot contain @')
+ }
+ this.handlers.set(`${ctx}@${event}`, callback)
+ }
+
+ public off(ctx: string, event: string): void {
+ this.handlers.delete(`${ctx}@${event}`)
+ }
+
+ public disable(ctx: string): void {
+ this.enable(ctx)
+ this.disabled.push(ctx)
+ }
+
+ public enable(ctx: string): void {
+ this.disabled = this.disabled.filter(v => v !== ctx)
+ }
+
+ public emit(event: string, ...args: any[]): void {
+ for (const [key, handler] of this.handlers.entries()) {
+ const ctx = key.split('@')[0]
+ if (this.disabled.includes(ctx)) continue
+ if (key.endsWith(`@${event}`)) {
+ handler(...args)
+ }
+ }
+ }
+}
diff --git a/src/globals.ts b/src/globals.ts
index b7aa738..f3067da 100644
--- a/src/globals.ts
+++ b/src/globals.ts
@@ -1,3 +1,5 @@
+import { EventBus } from './event-bus'
+
// Matches a wikiling that begins a string
export const regexWikilink = /^!?\[\[(?.+?)(\|(?.+?))?\]\]/
export const regexLineSplit = /\r?\n|\r|((\.|\?|!)( |\r?\n|\r))/g
@@ -8,6 +10,10 @@ export const excerptAfter = 180
export const highlightClass = 'suggestion-highlight omnisearch-highlight'
+export const eventBus = new EventBus()
+
+// export const eventBus = new EventBus()
+
export type SearchNote = {
path: string
basename: string
diff --git a/src/modal.ts b/src/modal.ts
index b8d4fd9..e48344f 100644
--- a/src/modal.ts
+++ b/src/modal.ts
@@ -1,6 +1,7 @@
import { App, Modal, TFile } from 'obsidian'
import CmpModalVault from './CmpModalVault.svelte'
import CmpModalInFile from './CmpModalInFile.svelte'
+import { eventBus } from './globals'
abstract class ModalOmnisearch extends Modal {
constructor(app: App) {
@@ -12,13 +13,45 @@ abstract class ModalOmnisearch extends Modal {
this.modalEl.replaceChildren()
this.modalEl.append(closeEl)
this.modalEl.addClass('omnisearch-modal', 'prompt')
+
+ this.modalEl.tabIndex = -1
+ this.modalEl.onkeydown = ev => {
+ switch (ev.key) {
+ case 'ArrowDown':
+ ev.preventDefault()
+ eventBus.emit('arrow-down')
+ break
+ case 'ArrowUp':
+ ev.preventDefault()
+ eventBus.emit('arrow-up')
+ break
+ case 'Enter':
+ ev.preventDefault()
+ if (ev.ctrlKey || ev.metaKey) {
+ // Open in a new pane
+ eventBus.emit('ctrl-enter')
+ }
+ else if (ev.shiftKey) {
+ // Create a new note
+ eventBus.emit('shift-enter')
+ }
+ else if (ev.altKey) {
+ // Expand in-note results
+ eventBus.emit('alt-enter')
+ }
+ else {
+ // Open in current pane
+ eventBus.emit('enter')
+ }
+ break
+ }
+ }
}
}
export class ModalVault extends ModalOmnisearch {
constructor(app: App) {
super(app)
-
new CmpModalVault({
target: this.modalEl,
props: {
diff --git a/src/search.ts b/src/search.ts
index 40547df..94cb4de 100644
--- a/src/search.ts
+++ b/src/search.ts
@@ -6,7 +6,6 @@ import {
type ResultNote,
type SearchMatch,
} from './globals'
-import { get } from 'svelte/store'
import { extractHeadingsFromCache, stringsToRegex, wait } from './utils'
let minisearchInstance: MiniSearch
diff --git a/src/stores.ts b/src/stores.ts
deleted file mode 100644
index 55b9209..0000000
--- a/src/stores.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import { writable } from 'svelte/store'
-import type OmnisearchPlugin from './main'
diff --git a/src/utils.ts b/src/utils.ts
index 73e9dcb..f152f9a 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -32,7 +32,7 @@ export function removeFrontMatter(text: string): string {
}
export function wait(ms: number): Promise {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
diff --git a/tsconfig.json b/tsconfig.json
index 6a98984..b092fc0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -6,7 +6,7 @@
"node"
],
"strict": true,
- "noUncheckedIndexedAccess": true,
+ "noUncheckedIndexedAccess": false,
"baseUrl": ".",
"module": "ESNext",
"target": "ES6",