diff --git a/src/cache-manager.ts b/src/cache-manager.ts index 96a629e..e817645 100644 --- a/src/cache-manager.ts +++ b/src/cache-manager.ts @@ -1,9 +1,39 @@ import type { TFile } from 'obsidian' import type { IndexedDocument } from './globals' +import { database } from './database' class CacheManager { private documentsCache: Map = new Map() - private writeInterval = 10_000 // In milliseconds + /** + * Show an empty input field next time the user opens Omnisearch modal + */ + private nextQueryIsEmpty = true + + public async addToSearchHistory(query: string): Promise { + if (!query) { + this.nextQueryIsEmpty = true + return + } + this.nextQueryIsEmpty = false + let history = await database.searchHistory.toArray() + history = history.filter(s => s.query !== query).reverse() + history.unshift({ query }) + history = history.slice(0, 10) + await database.searchHistory.clear() + await database.searchHistory.bulkAdd(history) + } + + public async getSearchHistory(): Promise> { + const data = (await database.searchHistory.toArray()) + .reverse() + .map(o => o.query) + console.log(this.nextQueryIsEmpty) + if (this.nextQueryIsEmpty) { + data.unshift('') + } + console.log(data) + return data + } public async updateDocument(path: string, note: IndexedDocument) { this.documentsCache.set(path, note) diff --git a/src/components/InputSearch.svelte b/src/components/InputSearch.svelte index f015d53..9cabb6c 100644 --- a/src/components/InputSearch.svelte +++ b/src/components/InputSearch.svelte @@ -2,6 +2,7 @@ import { debounce } from 'obsidian' import { toggleInputComposition } from 'src/globals' import { createEventDispatcher, tick } from 'svelte' + import { cacheManager } from "../cache-manager" export let initialValue = '' export let placeholder = '' @@ -24,22 +25,25 @@ } const debouncedOnInput = debounce(() => { + // If typing a query and not executing it, + // the next time we open the modal, the search field will be empty + cacheManager.addToSearchHistory('') dispatch('input', value) - }, 250) + }, 200)
+ spellcheck="false" + type="text"/>
diff --git a/src/components/ModalInFile.svelte b/src/components/ModalInFile.svelte index 93d3d59..148d875 100644 --- a/src/components/ModalInFile.svelte +++ b/src/components/ModalInFile.svelte @@ -1,4 +1,4 @@ - @@ -19,7 +19,6 @@ import ResultItemInFile from './ResultItemInFile.svelte' import { Query } from 'src/search/query' import { openNote } from 'src/tools/notes' - import { saveSearchHistory } from '../search/search-history' export let modal: OmnisearchInFileModal export let parent: OmnisearchVaultModal | null = null @@ -50,11 +49,11 @@ $: (async () => { if (searchQuery) { query = new Query(searchQuery) - note = (await Search.getSuggestions(query, { singleFilePath }))[0] ?? null + note = (await Search.getSuggestions(query, {singleFilePath}))[0] ?? null lastSearch = searchQuery } selectedIndex = 0 - scrollIntoView() + await scrollIntoView() })() $: { @@ -105,14 +104,13 @@ async function scrollIntoView(): Promise { await tick() const elem = document.querySelector(`[data-result-id="${selectedIndex}"]`) - elem?.scrollIntoView({ behavior: 'auto', block: 'nearest' }) + elem?.scrollIntoView({behavior: 'auto', block: 'nearest'}) } async function openSelection( evt?: MouseEvent | KeyboardEvent ): Promise { if (note) { - await saveSearchHistory() modal.close() if (parent) parent.close() @@ -132,8 +130,8 @@ pos.ch = 0 view.editor.setCursor(pos) view.editor.scrollIntoView({ - from: { line: pos.line - 10, ch: 0 }, - to: { line: pos.line + 10, ch: 0 }, + from: {line: pos.line - 10, ch: 0}, + to: {line: pos.line + 10, ch: 0}, }) } } @@ -145,9 +143,9 @@ + placeholder="Omnisearch - File" + value="{searchQuery}"/> {#if groupedOffsets.length && note} @@ -158,7 +156,7 @@ index="{i}" selected="{i === selectedIndex}" on:mousemove="{_e => (selectedIndex = i)}" - on:click="{openSelection}" /> + on:click="{openSelection}"/> {/each} {:else}
diff --git a/src/components/ModalVault.svelte b/src/components/ModalVault.svelte index e3267fd..67e4043 100644 --- a/src/components/ModalVault.svelte +++ b/src/components/ModalVault.svelte @@ -1,6 +1,6 @@ @@ -197,7 +199,7 @@ selected="{i === selectedIndex}" note="{result}" on:mousemove="{_ => (selectedIndex = i)}" - on:click="{onClick}" /> + on:click="{onClick}"/> {/each} {#if !resultNotes.length && searchQuery}
@@ -222,7 +224,7 @@ to switch to In-File Search
-
+
{getCtrlKeyLabel()} ↵ @@ -237,7 +239,7 @@ to create in a new pane
-
+
alt ↵ diff --git a/src/database.ts b/src/database.ts index 5565aac..38d3098 100644 --- a/src/database.ts +++ b/src/database.ts @@ -6,18 +6,13 @@ class OmnisearchCache extends Dexie { { path: string; hash: string; size: number; text: string }, string > - documents!: Dexie.Table< - { document: IndexedDocument; path: string; mtime: number }, - string - > - minisearch!: Dexie.Table + searchHistory!: Dexie.Table<{ id?: number; query: string }, number> constructor() { super(app.appId + '_omnisearch') - this.version(2).stores({ + this.version(3).stores({ pdf: 'path, hash, size, text', - documents: 'path, mtime, document', - minisearch: 'data', + searchHistory: '++id, query', }) } } diff --git a/src/file-loader.ts b/src/file-loader.ts index 667f997..7be6289 100644 --- a/src/file-loader.ts +++ b/src/file-loader.ts @@ -39,7 +39,7 @@ export async function getPDFFiles(): Promise { input.push( NotesIndex.processQueue(async () => { const doc = await fileToIndexedDocument(file) - cacheManager.updateDocument(file.path, doc) + await cacheManager.updateDocument(file.path, doc) data.push(doc) }) ) diff --git a/src/globals.ts b/src/globals.ts index 48e01b3..f77e44a 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -12,8 +12,6 @@ export const highlightClass = 'suggestion-highlight omnisearch-highlight' export const eventBus = new EventBus() -export const historyFilePath = `${app.vault.configDir}/plugins/omnisearch/historyCache.json` - export const EventNames = { ToggleExcerpts: 'toggle-excerpts', } as const diff --git a/src/main.ts b/src/main.ts index 2108b2c..7cb7b9d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,7 +8,6 @@ import { loadSettings, settings, SettingsTab, showExcerpt } from './settings' import { eventBus, EventNames } from './globals' import { registerAPI } from '@vanakat/plugin-api' import api from './tools/api' -import { loadSearchHistory } from './search/search-history' import { isFilePlaintext } from './tools/utils' import * as NotesIndex from './notes-index' import * as FileLoader from './file-loader' @@ -17,7 +16,6 @@ export default class OmnisearchPlugin extends Plugin { async onload(): Promise { await cleanOldCacheFiles() await loadSettings(this) - await loadSearchHistory() // Initialize minisearch await Search.initSearchEngine() @@ -125,6 +123,7 @@ async function cleanOldCacheFiles() { `${app.vault.configDir}/plugins/omnisearch/notesCache.json`, `${app.vault.configDir}/plugins/omnisearch/notesCache.data`, `${app.vault.configDir}/plugins/omnisearch/searchIndex.data`, + `${app.vault.configDir}/plugins/omnisearch/historyCache.json`, `${app.vault.configDir}/plugins/omnisearch/pdfCache.data`, ] for (const item of toDelete) { diff --git a/src/search/search-history.ts b/src/search/search-history.ts deleted file mode 100644 index 6c3b2d1..0000000 --- a/src/search/search-history.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { historyFilePath } from '../globals' - -export let searchHistory: string[] = [] - -export async function loadSearchHistory(): Promise { - if (await app.vault.adapter.exists(historyFilePath)) { - try { - searchHistory = JSON.parse(await app.vault.adapter.read(historyFilePath)) - // Keep the last 100 searches - searchHistory = searchHistory.slice(0, 100) - } catch (e) { - console.trace('Could not load search history from the file') - console.error(e) - searchHistory = [] - } - } else { - searchHistory = [] - } -} - -export async function saveSearchHistory(): Promise { - await app.vault.adapter.write(historyFilePath, JSON.stringify(searchHistory)) -}