Massive refactor to get rid of the global app.
This commit is contained in:
@@ -2,10 +2,11 @@
|
||||
import { debounce } from 'obsidian'
|
||||
import { toggleInputComposition } from 'src/globals'
|
||||
import { createEventDispatcher, tick } from 'svelte'
|
||||
import { cacheManager } from '../cache-manager'
|
||||
import type OmnisearchPlugin from '../main'
|
||||
|
||||
export let initialValue = ''
|
||||
export let placeholder = ''
|
||||
export let plugin: OmnisearchPlugin
|
||||
let initialSet = false
|
||||
let value = ''
|
||||
let elInput: HTMLInputElement
|
||||
@@ -39,7 +40,7 @@
|
||||
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('')
|
||||
plugin.cacheManager.addToSearchHistory('')
|
||||
dispatch('input', value)
|
||||
}, 300)
|
||||
</script>
|
||||
@@ -50,13 +51,13 @@
|
||||
bind:this="{elInput}"
|
||||
bind:value="{value}"
|
||||
class="prompt-input"
|
||||
use:selectInput
|
||||
on:compositionend="{_ => toggleInputComposition(false)}"
|
||||
on:compositionstart="{_ => toggleInputComposition(true)}"
|
||||
on:input="{debouncedOnInput}"
|
||||
placeholder="{placeholder}"
|
||||
spellcheck="false"
|
||||
type="text" />
|
||||
type="text"
|
||||
use:selectInput />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
} from 'src/globals'
|
||||
import { getCtrlKeyLabel, loopIndex } from 'src/tools/utils'
|
||||
import { onDestroy, onMount, tick } from 'svelte'
|
||||
import { MarkdownView, App, Platform } from 'obsidian'
|
||||
import { MarkdownView, Platform } from 'obsidian'
|
||||
import ModalContainer from './ModalContainer.svelte'
|
||||
import {
|
||||
OmnisearchInFileModal,
|
||||
@@ -18,14 +18,13 @@
|
||||
import ResultItemInFile from './ResultItemInFile.svelte'
|
||||
import { Query } from 'src/search/query'
|
||||
import { openNote } from 'src/tools/notes'
|
||||
import { stringsToRegex } from 'src/tools/text-processing'
|
||||
import { Omnisearch } from 'src/search/omnisearch'
|
||||
import type OmnisearchPlugin from '../main'
|
||||
|
||||
export let plugin: OmnisearchPlugin
|
||||
export let modal: OmnisearchInFileModal
|
||||
export let parent: OmnisearchVaultModal | null = null
|
||||
export let singleFilePath = ''
|
||||
export let previousQuery: string | undefined
|
||||
export let app: App
|
||||
|
||||
let searchQuery: string
|
||||
let groupedOffsets: number[] = []
|
||||
@@ -51,10 +50,12 @@
|
||||
|
||||
$: (async () => {
|
||||
if (searchQuery) {
|
||||
query = new Query(searchQuery)
|
||||
query = new Query(searchQuery, {
|
||||
ignoreDiacritics: plugin.settings.ignoreDiacritics,
|
||||
})
|
||||
note =
|
||||
(
|
||||
await Omnisearch.getInstance().getSuggestions(query, {
|
||||
await plugin.omnisearch.getSuggestions(query, {
|
||||
singleFilePath,
|
||||
})
|
||||
)[0] ?? null
|
||||
@@ -131,12 +132,12 @@
|
||||
if (parent) parent.close()
|
||||
|
||||
// Open (or switch focus to) the note
|
||||
const reg = stringsToRegex(note.foundWords)
|
||||
const reg = plugin.textProcessor.stringsToRegex(note.foundWords)
|
||||
reg.exec(note.content)
|
||||
await openNote(note, reg.lastIndex, newTab)
|
||||
await openNote(plugin.app, note, reg.lastIndex, newTab)
|
||||
|
||||
// Move cursor to the match
|
||||
const view = app.workspace.getActiveViewOfType(MarkdownView)
|
||||
const view = plugin.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!view) {
|
||||
// Not an editable document, so no cursor to place
|
||||
return
|
||||
@@ -155,12 +156,13 @@
|
||||
}
|
||||
|
||||
function switchToVaultModal(): void {
|
||||
new OmnisearchVaultModal(app, searchQuery ?? previousQuery).open()
|
||||
new OmnisearchVaultModal(plugin, searchQuery ?? previousQuery).open()
|
||||
modal.close()
|
||||
}
|
||||
</script>
|
||||
|
||||
<InputSearch
|
||||
plugin="{plugin}"
|
||||
on:input="{e => (searchQuery = e.detail)}"
|
||||
placeholder="Omnisearch - File"
|
||||
initialValue="{previousQuery}">
|
||||
@@ -175,6 +177,7 @@
|
||||
{#if groupedOffsets.length && note}
|
||||
{#each groupedOffsets as offset, i}
|
||||
<ResultItemInFile
|
||||
{plugin}
|
||||
offset="{offset}"
|
||||
note="{note}"
|
||||
index="{i}"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { App, MarkdownView, Notice, Platform, TFile } from 'obsidian'
|
||||
import { MarkdownView, Notice, Platform, TFile } from 'obsidian'
|
||||
import { onDestroy, onMount, tick } from 'svelte'
|
||||
import InputSearch from './InputSearch.svelte'
|
||||
import ModalContainer from './ModalContainer.svelte'
|
||||
@@ -24,16 +24,13 @@
|
||||
} from 'src/components/modals'
|
||||
import ResultItemVault from './ResultItemVault.svelte'
|
||||
import { Query } from 'src/search/query'
|
||||
import * as NotesIndex from '../notes-index'
|
||||
import { cacheManager } from '../cache-manager'
|
||||
import { cancelable, CancelablePromise } from 'cancelable-promise'
|
||||
import { debounce } from 'lodash-es'
|
||||
import { Omnisearch } from 'src/search/omnisearch'
|
||||
import { getSettings } from 'src/settings'
|
||||
import type OmnisearchPlugin from '../main'
|
||||
|
||||
export let modal: OmnisearchVaultModal
|
||||
export let previousQuery: string | undefined
|
||||
export let app: App
|
||||
export let plugin: OmnisearchPlugin
|
||||
|
||||
let selectedIndex = 0
|
||||
let historySearchIndex = 0
|
||||
@@ -51,7 +48,7 @@
|
||||
|
||||
$: selectedNote = resultNotes[selectedIndex]
|
||||
$: searchQuery = searchQuery ?? previousQuery
|
||||
$: if (getSettings().openInNewPane) {
|
||||
$: if (plugin.settings.openInNewPane) {
|
||||
openInNewPaneKey = '↵'
|
||||
openInCurrentPaneKey = getCtrlKeyLabel() + ' ↵'
|
||||
createInNewPaneKey = 'shift ↵'
|
||||
@@ -103,7 +100,7 @@
|
||||
eventBus.on('vault', Action.PrevSearchHistory, prevSearchHistory)
|
||||
eventBus.on('vault', Action.NextSearchHistory, nextSearchHistory)
|
||||
eventBus.on('vault', Action.OpenInNewLeaf, openNoteInNewLeaf)
|
||||
await NotesIndex.refreshIndex()
|
||||
await plugin.notesIndexer.refreshIndex()
|
||||
await updateResultsDebounced()
|
||||
})
|
||||
|
||||
@@ -113,7 +110,9 @@
|
||||
|
||||
async function prevSearchHistory() {
|
||||
// Filter out the empty string, if it's there
|
||||
const history = (await cacheManager.getSearchHistory()).filter(s => s)
|
||||
const history = (await plugin.cacheManager.getSearchHistory()).filter(
|
||||
s => s
|
||||
)
|
||||
if (++historySearchIndex >= history.length) {
|
||||
historySearchIndex = 0
|
||||
}
|
||||
@@ -122,7 +121,9 @@
|
||||
}
|
||||
|
||||
async function nextSearchHistory() {
|
||||
const history = (await cacheManager.getSearchHistory()).filter(s => s)
|
||||
const history = (await plugin.cacheManager.getSearchHistory()).filter(
|
||||
s => s
|
||||
)
|
||||
if (--historySearchIndex < 0) {
|
||||
historySearchIndex = history.length ? history.length - 1 : 0
|
||||
}
|
||||
@@ -138,10 +139,12 @@
|
||||
cancelableQuery.cancel()
|
||||
cancelableQuery = null
|
||||
}
|
||||
query = new Query(searchQuery)
|
||||
query = new Query(searchQuery, {
|
||||
ignoreDiacritics: plugin.settings.ignoreDiacritics,
|
||||
})
|
||||
cancelableQuery = cancelable(
|
||||
new Promise(resolve => {
|
||||
resolve(Omnisearch.getInstance().getSuggestions(query))
|
||||
resolve(plugin.omnisearch.getSuggestions(query))
|
||||
})
|
||||
)
|
||||
resultNotes = await cancelableQuery
|
||||
@@ -188,7 +191,7 @@
|
||||
|
||||
function saveCurrentQuery() {
|
||||
if (searchQuery) {
|
||||
cacheManager.addToSearchHistory(searchQuery)
|
||||
plugin.cacheManager.addToSearchHistory(searchQuery)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +202,7 @@
|
||||
) {
|
||||
saveCurrentQuery()
|
||||
const offset = note.matches?.[0]?.offset ?? 0
|
||||
openNote(note, offset, newPane, newLeaf)
|
||||
openNote(plugin.app, note, offset, newPane, newLeaf)
|
||||
}
|
||||
|
||||
async function onClickCreateNote(_e: MouseEvent) {
|
||||
@@ -211,7 +214,7 @@
|
||||
}): Promise<void> {
|
||||
if (searchQuery) {
|
||||
try {
|
||||
await createNote(searchQuery, opt?.newLeaf)
|
||||
await createNote(plugin.app, searchQuery, opt?.newLeaf)
|
||||
} catch (e) {
|
||||
new Notice((e as Error).message)
|
||||
return
|
||||
@@ -222,11 +225,11 @@
|
||||
|
||||
function insertLink(): void {
|
||||
if (!selectedNote) return
|
||||
const file = app.vault
|
||||
const file = plugin.app.vault
|
||||
.getMarkdownFiles()
|
||||
.find(f => f.path === selectedNote.path)
|
||||
const active = app.workspace.getActiveFile()
|
||||
const view = app.workspace.getActiveViewOfType(MarkdownView)
|
||||
const active = plugin.app.workspace.getActiveFile()
|
||||
const view = plugin.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (!view?.editor) {
|
||||
new Notice('Omnisearch - Error - No active editor', 3000)
|
||||
return
|
||||
@@ -235,7 +238,7 @@
|
||||
// Generate link
|
||||
let link: string
|
||||
if (file && active) {
|
||||
link = app.fileManager.generateMarkdownLink(file, active.path)
|
||||
link = plugin.app.fileManager.generateMarkdownLink(file, active.path)
|
||||
} else {
|
||||
link = `[[${selectedNote.basename}.${getExtension(selectedNote.path)}]]`
|
||||
}
|
||||
@@ -249,7 +252,7 @@
|
||||
modal.close()
|
||||
}
|
||||
|
||||
function switchToInFileModal(): void {
|
||||
function switchToInFileModal(): void {
|
||||
// Do nothing if the selectedNote is a PDF,
|
||||
// or if there is 0 match (e.g indexing in progress)
|
||||
if (
|
||||
@@ -264,15 +267,15 @@
|
||||
|
||||
if (selectedNote) {
|
||||
// Open in-file modal for selected search result
|
||||
const file = app.vault.getAbstractFileByPath(selectedNote.path)
|
||||
const file = plugin.app.vault.getAbstractFileByPath(selectedNote.path)
|
||||
if (file && file instanceof TFile) {
|
||||
new OmnisearchInFileModal(app, file, searchQuery).open()
|
||||
new OmnisearchInFileModal(plugin, file, searchQuery).open()
|
||||
}
|
||||
} else {
|
||||
// Open in-file modal for active file
|
||||
const view = app.workspace.getActiveViewOfType(MarkdownView)
|
||||
const view = plugin.app.workspace.getActiveViewOfType(MarkdownView)
|
||||
if (view?.file) {
|
||||
new OmnisearchInFileModal(app, view.file, searchQuery).open()
|
||||
new OmnisearchInFileModal(plugin, view.file, searchQuery).open()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,11 +298,12 @@
|
||||
|
||||
<InputSearch
|
||||
bind:this="{refInput}"
|
||||
plugin="{plugin}"
|
||||
initialValue="{searchQuery}"
|
||||
on:input="{e => (searchQuery = e.detail)}"
|
||||
placeholder="Omnisearch - Vault">
|
||||
<div class="omnisearch-input-container__buttons">
|
||||
{#if getSettings().showCreateButton}
|
||||
{#if plugin.settings.showCreateButton}
|
||||
<button on:click="{onClickCreateNote}">Create note</button>
|
||||
{/if}
|
||||
{#if Platform.isMobile}
|
||||
@@ -317,7 +321,7 @@
|
||||
<ModalContainer>
|
||||
{#each resultNotes as result, i}
|
||||
<ResultItemVault
|
||||
app="{app}"
|
||||
{plugin}
|
||||
selected="{i === selectedIndex}"
|
||||
note="{result}"
|
||||
on:mousemove="{_ => (selectedIndex = i)}"
|
||||
@@ -329,7 +333,7 @@
|
||||
<div style="text-align: center;">
|
||||
{#if !resultNotes.length && searchQuery && !searching}
|
||||
We found 0 result for your search here.
|
||||
{#if getSettings().simpleSearch && searchQuery
|
||||
{#if plugin.settings.simpleSearch && searchQuery
|
||||
.split(SPACE_OR_PUNCTUATION)
|
||||
.some(w => w.length < 3)}
|
||||
<br />
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { makeExcerpt, highlightText } from 'src/tools/text-processing'
|
||||
import type { ResultNote } from '../globals'
|
||||
import ResultItemContainer from './ResultItemContainer.svelte'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import type OmnisearchPlugin from '../main'
|
||||
|
||||
export let plugin: OmnisearchPlugin
|
||||
export let offset: number
|
||||
export let note: ResultNote
|
||||
export let index = 0
|
||||
export let selected = false
|
||||
|
||||
$: cleanedContent = makeExcerpt(note?.content ?? '', offset)
|
||||
$: cleanedContent = plugin.textProcessor.makeExcerpt(note?.content ?? '', offset)
|
||||
</script>
|
||||
|
||||
<ResultItemContainer
|
||||
id="{index.toString()}"
|
||||
selected="{selected}"
|
||||
on:mousemove
|
||||
on:auxclick
|
||||
on:click
|
||||
on:auxclick>
|
||||
on:mousemove
|
||||
selected="{selected}">
|
||||
<div class="omnisearch-result__body">
|
||||
{@html highlightText(cleanedContent, note.matches)}
|
||||
{@html plugin.textProcessor.highlightText(cleanedContent, note.matches)}
|
||||
</div>
|
||||
</ResultItemContainer>
|
||||
|
||||
@@ -9,18 +9,12 @@
|
||||
pathWithoutFilename,
|
||||
} from '../tools/utils'
|
||||
import ResultItemContainer from './ResultItemContainer.svelte'
|
||||
import { TFile, setIcon, App } from 'obsidian'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import {
|
||||
stringsToRegex,
|
||||
getMatches,
|
||||
makeExcerpt,
|
||||
highlightText,
|
||||
} from 'src/tools/text-processing'
|
||||
import { TFile, setIcon } from 'obsidian'
|
||||
import type OmnisearchPlugin from '../main'
|
||||
|
||||
export let selected = false
|
||||
export let note: ResultNote
|
||||
export let app: App
|
||||
export let plugin: OmnisearchPlugin
|
||||
|
||||
let imagePath: string | null = null
|
||||
let title = ''
|
||||
@@ -31,16 +25,15 @@
|
||||
$: {
|
||||
imagePath = null
|
||||
if (isFileImage(note.path)) {
|
||||
const file = app.vault.getAbstractFileByPath(note.path)
|
||||
const file = plugin.app.vault.getAbstractFileByPath(note.path)
|
||||
if (file instanceof TFile) {
|
||||
imagePath = app.vault.getResourcePath(file)
|
||||
imagePath = plugin.app.vault.getResourcePath(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
$: reg = stringsToRegex(note.foundWords)
|
||||
$: matchesTitle = getMatches(title, reg)
|
||||
$: matchesNotePath = getMatches(notePath, reg)
|
||||
$: cleanedContent = makeExcerpt(note.content, note.matches[0]?.offset ?? -1)
|
||||
$: matchesTitle = plugin.textProcessor.getMatches(title, note.foundWords)
|
||||
$: matchesNotePath = plugin.textProcessor.getMatches(notePath, note.foundWords)
|
||||
$: cleanedContent = plugin.textProcessor.makeExcerpt(note.content, note.matches[0]?.offset ?? -1)
|
||||
$: glyph = false //cacheManager.getLiveDocument(note.path)?.doesNotExist
|
||||
$: {
|
||||
title = note.basename
|
||||
@@ -63,15 +56,15 @@
|
||||
<ResultItemContainer
|
||||
glyph="{glyph}"
|
||||
id="{note.path}"
|
||||
on:click
|
||||
on:auxclick
|
||||
on:click
|
||||
on:mousemove
|
||||
selected="{selected}">
|
||||
<div>
|
||||
<div class="omnisearch-result__title-container">
|
||||
<span class="omnisearch-result__title">
|
||||
<span bind:this="{elFilePathIcon}"></span>
|
||||
<span>{@html highlightText(title, matchesTitle)}</span>
|
||||
<span>{@html plugin.textProcessor.highlightText(title, matchesTitle)}</span>
|
||||
<span class="omnisearch-result__extension">
|
||||
.{getExtension(note.path)}
|
||||
</span>
|
||||
@@ -91,14 +84,14 @@
|
||||
{#if notePath}
|
||||
<div class="omnisearch-result__folder-path">
|
||||
<span bind:this="{elFolderPathIcon}"></span>
|
||||
<span>{@html highlightText(notePath, matchesNotePath)}</span>
|
||||
<span>{@html plugin.textProcessor.highlightText(notePath, matchesNotePath)}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div style="display: flex; flex-direction: row;">
|
||||
{#if $showExcerpt}
|
||||
<div class="omnisearch-result__body">
|
||||
{@html highlightText(cleanedContent, note.matches)}
|
||||
{@html plugin.textProcessor.highlightText(cleanedContent, note.matches)}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { App, MarkdownView, Modal, TFile } from 'obsidian'
|
||||
import { MarkdownView, Modal, TFile } from 'obsidian'
|
||||
import type { Modifier } from 'obsidian'
|
||||
import ModalVault from './ModalVault.svelte'
|
||||
import ModalInFile from './ModalInFile.svelte'
|
||||
import { Action, eventBus, EventNames, isInputComposition } from '../globals'
|
||||
import { cacheManager } from 'src/cache-manager'
|
||||
import { getSettings } from 'src/settings'
|
||||
import type OmnisearchPlugin from 'src/main'
|
||||
|
||||
abstract class OmnisearchModal extends Modal {
|
||||
protected constructor(app: App) {
|
||||
super(app)
|
||||
const settings = getSettings()
|
||||
protected constructor(plugin: OmnisearchPlugin) {
|
||||
super(plugin.app)
|
||||
const settings = plugin.settings
|
||||
|
||||
// Remove all the default modal's children
|
||||
// so that we can more easily customize it
|
||||
@@ -153,20 +152,20 @@ abstract class OmnisearchModal extends Modal {
|
||||
export class OmnisearchVaultModal extends OmnisearchModal {
|
||||
/**
|
||||
* Instanciate the Omnisearch vault modal
|
||||
* @param app
|
||||
* @param plugin
|
||||
* @param query The query to pre-fill the search field with
|
||||
*/
|
||||
constructor(app: App, query?: string) {
|
||||
super(app)
|
||||
constructor(plugin: OmnisearchPlugin, query?: string) {
|
||||
super(plugin)
|
||||
|
||||
// Selected text in the editor
|
||||
const selectedText = app.workspace
|
||||
const selectedText = plugin.app.workspace
|
||||
.getActiveViewOfType(MarkdownView)
|
||||
?.editor.getSelection()
|
||||
|
||||
cacheManager.getSearchHistory().then(history => {
|
||||
plugin.cacheManager.getSearchHistory().then(history => {
|
||||
// Previously searched query (if enabled in settings)
|
||||
const previous = getSettings().showPreviousQueryResults
|
||||
const previous = plugin.settings.showPreviousQueryResults
|
||||
? history[0]
|
||||
: null
|
||||
|
||||
@@ -174,7 +173,7 @@ export class OmnisearchVaultModal extends OmnisearchModal {
|
||||
const cmp = new ModalVault({
|
||||
target: this.modalEl,
|
||||
props: {
|
||||
app,
|
||||
plugin,
|
||||
modal: this,
|
||||
previousQuery: query || selectedText || previous || '',
|
||||
},
|
||||
@@ -190,17 +189,17 @@ export class OmnisearchVaultModal extends OmnisearchModal {
|
||||
|
||||
export class OmnisearchInFileModal extends OmnisearchModal {
|
||||
constructor(
|
||||
app: App,
|
||||
plugin: OmnisearchPlugin,
|
||||
file: TFile,
|
||||
searchQuery: string = '',
|
||||
parent?: OmnisearchModal
|
||||
) {
|
||||
super(app)
|
||||
super(plugin)
|
||||
|
||||
const cmp = new ModalInFile({
|
||||
target: this.modalEl,
|
||||
props: {
|
||||
app,
|
||||
plugin,
|
||||
modal: this,
|
||||
singleFilePath: file.path,
|
||||
parent: parent,
|
||||
|
||||
Reference in New Issue
Block a user