Massive refactoring to get rid of the deprecated global app instance
This commit is contained in:
@@ -4,7 +4,6 @@ import {
|
|||||||
getTextExtractor,
|
getTextExtractor,
|
||||||
type IndexedDocument,
|
type IndexedDocument,
|
||||||
} from './globals'
|
} from './globals'
|
||||||
import { database } from './database'
|
|
||||||
import {
|
import {
|
||||||
extractHeadingsFromCache,
|
extractHeadingsFromCache,
|
||||||
getAliasesFromMetadata,
|
getAliasesFromMetadata,
|
||||||
@@ -24,10 +23,9 @@ import {
|
|||||||
import type { CanvasData } from 'obsidian/canvas'
|
import type { CanvasData } from 'obsidian/canvas'
|
||||||
import type { AsPlainObject } from 'minisearch'
|
import type { AsPlainObject } from 'minisearch'
|
||||||
import type MiniSearch from 'minisearch'
|
import type MiniSearch from 'minisearch'
|
||||||
import { settings } from './settings'
|
|
||||||
import { getObsidianApp } from './stores/obsidian-app'
|
import { getObsidianApp } from './stores/obsidian-app'
|
||||||
|
import { OmnisearchCache } from './database'
|
||||||
const app = getObsidianApp()
|
import { getSettings } from './settings'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is responsible for extracting the text from a file and
|
* This function is responsible for extracting the text from a file and
|
||||||
@@ -37,6 +35,8 @@ const app = getObsidianApp()
|
|||||||
async function getAndMapIndexedDocument(
|
async function getAndMapIndexedDocument(
|
||||||
path: string
|
path: string
|
||||||
): Promise<IndexedDocument> {
|
): Promise<IndexedDocument> {
|
||||||
|
const app = getObsidianApp()
|
||||||
|
const settings = getSettings()
|
||||||
const file = app.vault.getAbstractFileByPath(path)
|
const file = app.vault.getAbstractFileByPath(path)
|
||||||
if (!file) throw new Error(`Invalid file path: "${path}"`)
|
if (!file) throw new Error(`Invalid file path: "${path}"`)
|
||||||
if (!(file instanceof TFile)) throw new Error(`Not a TFile: "${path}"`)
|
if (!(file instanceof TFile)) throw new Error(`Not a TFile: "${path}"`)
|
||||||
@@ -224,6 +224,7 @@ class CacheManager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.nextQueryIsEmpty = false
|
this.nextQueryIsEmpty = false
|
||||||
|
const database = OmnisearchCache.getInstance()
|
||||||
let history = await database.searchHistory.toArray()
|
let history = await database.searchHistory.toArray()
|
||||||
history = history.filter(s => s.query !== query).reverse()
|
history = history.filter(s => s.query !== query).reverse()
|
||||||
history.unshift({ query })
|
history.unshift({ query })
|
||||||
@@ -236,7 +237,7 @@ class CacheManager {
|
|||||||
* @returns The search history, in reverse chronological order
|
* @returns The search history, in reverse chronological order
|
||||||
*/
|
*/
|
||||||
public async getSearchHistory(): Promise<ReadonlyArray<string>> {
|
public async getSearchHistory(): Promise<ReadonlyArray<string>> {
|
||||||
const data = (await database.searchHistory.toArray())
|
const data = (await OmnisearchCache.getInstance().searchHistory.toArray())
|
||||||
.reverse()
|
.reverse()
|
||||||
.map(o => o.query)
|
.map(o => o.query)
|
||||||
if (this.nextQueryIsEmpty) {
|
if (this.nextQueryIsEmpty) {
|
||||||
@@ -267,7 +268,9 @@ class CacheManager {
|
|||||||
data: AsPlainObject
|
data: AsPlainObject
|
||||||
} | null> {
|
} | null> {
|
||||||
try {
|
try {
|
||||||
const cachedIndex = (await database.minisearch.toArray())[0]
|
const cachedIndex = (
|
||||||
|
await OmnisearchCache.getInstance().minisearch.toArray()
|
||||||
|
)[0]
|
||||||
return cachedIndex
|
return cachedIndex
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
new Notice(
|
new Notice(
|
||||||
@@ -284,6 +287,7 @@ class CacheManager {
|
|||||||
indexed: Map<string, number>
|
indexed: Map<string, number>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const paths = Array.from(indexed).map(([k, v]) => ({ path: k, mtime: v }))
|
const paths = Array.from(indexed).map(([k, v]) => ({ path: k, mtime: v }))
|
||||||
|
const database = OmnisearchCache.getInstance()
|
||||||
await database.minisearch.clear()
|
await database.minisearch.clear()
|
||||||
await database.minisearch.add({
|
await database.minisearch.add({
|
||||||
date: new Date().toISOString(),
|
date: new Date().toISOString(),
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
import ResultItemInFile from './ResultItemInFile.svelte'
|
import ResultItemInFile from './ResultItemInFile.svelte'
|
||||||
import { Query } from 'src/search/query'
|
import { Query } from 'src/search/query'
|
||||||
import { openNote } from 'src/tools/notes'
|
import { openNote } from 'src/tools/notes'
|
||||||
import { searchEngine } from 'src/search/omnisearch'
|
|
||||||
import { stringsToRegex } from 'src/tools/text-processing'
|
import { stringsToRegex } from 'src/tools/text-processing'
|
||||||
|
import { Omnisearch } from 'src/search/omnisearch'
|
||||||
|
|
||||||
export let modal: OmnisearchInFileModal
|
export let modal: OmnisearchInFileModal
|
||||||
export let parent: OmnisearchVaultModal | null = null
|
export let parent: OmnisearchVaultModal | null = null
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
query = new Query(searchQuery)
|
query = new Query(searchQuery)
|
||||||
note =
|
note =
|
||||||
(
|
(
|
||||||
await searchEngine.getSuggestions(query, {
|
await Omnisearch.getInstance().getSuggestions(query, {
|
||||||
singleFilePath,
|
singleFilePath,
|
||||||
})
|
})
|
||||||
)[0] ?? null
|
)[0] ?? null
|
||||||
|
|||||||
@@ -24,12 +24,12 @@
|
|||||||
} from 'src/components/modals'
|
} from 'src/components/modals'
|
||||||
import ResultItemVault from './ResultItemVault.svelte'
|
import ResultItemVault from './ResultItemVault.svelte'
|
||||||
import { Query } from 'src/search/query'
|
import { Query } from 'src/search/query'
|
||||||
import { settings } from '../settings'
|
|
||||||
import * as NotesIndex from '../notes-index'
|
import * as NotesIndex from '../notes-index'
|
||||||
import { cacheManager } from '../cache-manager'
|
import { cacheManager } from '../cache-manager'
|
||||||
import { searchEngine } from 'src/search/omnisearch'
|
|
||||||
import { cancelable, CancelablePromise } from 'cancelable-promise'
|
import { cancelable, CancelablePromise } from 'cancelable-promise'
|
||||||
import { debounce } from 'lodash-es'
|
import { debounce } from 'lodash-es'
|
||||||
|
import { Omnisearch } from 'src/search/omnisearch'
|
||||||
|
import { getSettings } from 'src/settings'
|
||||||
|
|
||||||
export let modal: OmnisearchVaultModal
|
export let modal: OmnisearchVaultModal
|
||||||
export let previousQuery: string | undefined
|
export let previousQuery: string | undefined
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
$: selectedNote = resultNotes[selectedIndex]
|
$: selectedNote = resultNotes[selectedIndex]
|
||||||
$: searchQuery = searchQuery ?? previousQuery
|
$: searchQuery = searchQuery ?? previousQuery
|
||||||
$: if (settings.openInNewPane) {
|
$: if (getSettings().openInNewPane) {
|
||||||
openInNewPaneKey = '↵'
|
openInNewPaneKey = '↵'
|
||||||
openInCurrentPaneKey = getCtrlKeyLabel() + ' ↵'
|
openInCurrentPaneKey = getCtrlKeyLabel() + ' ↵'
|
||||||
createInNewPaneKey = 'shift ↵'
|
createInNewPaneKey = 'shift ↵'
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
query = new Query(searchQuery)
|
query = new Query(searchQuery)
|
||||||
cancelableQuery = cancelable(
|
cancelableQuery = cancelable(
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
resolve(searchEngine.getSuggestions(query))
|
resolve(Omnisearch.getInstance().getSuggestions(query))
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
resultNotes = await cancelableQuery
|
resultNotes = await cancelableQuery
|
||||||
@@ -299,7 +299,7 @@
|
|||||||
on:input="{e => (searchQuery = e.detail)}"
|
on:input="{e => (searchQuery = e.detail)}"
|
||||||
placeholder="Omnisearch - Vault">
|
placeholder="Omnisearch - Vault">
|
||||||
<div class="omnisearch-input-container__buttons">
|
<div class="omnisearch-input-container__buttons">
|
||||||
{#if settings.showCreateButton}
|
{#if getSettings().showCreateButton}
|
||||||
<button on:click="{onClickCreateNote}">Create note</button>
|
<button on:click="{onClickCreateNote}">Create note</button>
|
||||||
{/if}
|
{/if}
|
||||||
{#if Platform.isMobile}
|
{#if Platform.isMobile}
|
||||||
@@ -329,7 +329,7 @@
|
|||||||
<div style="text-align: center;">
|
<div style="text-align: center;">
|
||||||
{#if !resultNotes.length && searchQuery && !searching}
|
{#if !resultNotes.length && searchQuery && !searching}
|
||||||
We found 0 result for your search here.
|
We found 0 result for your search here.
|
||||||
{#if settings.simpleSearch && searchQuery
|
{#if getSettings().simpleSearch && searchQuery
|
||||||
.split(SPACE_OR_PUNCTUATION)
|
.split(SPACE_OR_PUNCTUATION)
|
||||||
.some(w => w.length < 3)}
|
.some(w => w.length < 3)}
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import type { Modifier } from 'obsidian'
|
|||||||
import ModalVault from './ModalVault.svelte'
|
import ModalVault from './ModalVault.svelte'
|
||||||
import ModalInFile from './ModalInFile.svelte'
|
import ModalInFile from './ModalInFile.svelte'
|
||||||
import { Action, eventBus, EventNames, isInputComposition } from '../globals'
|
import { Action, eventBus, EventNames, isInputComposition } from '../globals'
|
||||||
import { settings } from '../settings'
|
|
||||||
import { cacheManager } from 'src/cache-manager'
|
import { cacheManager } from 'src/cache-manager'
|
||||||
|
import { getSettings } from 'src/settings'
|
||||||
|
|
||||||
abstract class OmnisearchModal extends Modal {
|
abstract class OmnisearchModal extends Modal {
|
||||||
protected constructor(app: App) {
|
protected constructor(app: App) {
|
||||||
super(app)
|
super(app)
|
||||||
|
const settings = getSettings()
|
||||||
|
|
||||||
// Remove all the default modal's children
|
// Remove all the default modal's children
|
||||||
// so that we can more easily customize it
|
// so that we can more easily customize it
|
||||||
@@ -165,7 +166,9 @@ export class OmnisearchVaultModal extends OmnisearchModal {
|
|||||||
|
|
||||||
cacheManager.getSearchHistory().then(history => {
|
cacheManager.getSearchHistory().then(history => {
|
||||||
// Previously searched query (if enabled in settings)
|
// Previously searched query (if enabled in settings)
|
||||||
const previous = settings.showPreviousQueryResults ? history[0] : null
|
const previous = getSettings().showPreviousQueryResults
|
||||||
|
? history[0]
|
||||||
|
: null
|
||||||
|
|
||||||
// Instantiate and display the Svelte component
|
// Instantiate and display the Svelte component
|
||||||
const cmp = new ModalVault({
|
const cmp = new ModalVault({
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import { getObsidianApp } from './stores/obsidian-app'
|
|||||||
|
|
||||||
export class OmnisearchCache extends Dexie {
|
export class OmnisearchCache extends Dexie {
|
||||||
public static readonly dbVersion = 8
|
public static readonly dbVersion = 8
|
||||||
public static readonly dbName = 'omnisearch/cache/' + getObsidianApp().appId
|
public static getDbName() {
|
||||||
|
return 'omnisearch/cache/' + getObsidianApp().appId
|
||||||
|
}
|
||||||
|
|
||||||
private static instance: OmnisearchCache
|
private static instance: OmnisearchCache
|
||||||
|
|
||||||
@@ -21,7 +23,7 @@ export class OmnisearchCache extends Dexie {
|
|||||||
>
|
>
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
super(OmnisearchCache.dbName)
|
super(OmnisearchCache.getDbName())
|
||||||
// Database structure
|
// Database structure
|
||||||
this.version(OmnisearchCache.dbVersion).stores({
|
this.version(OmnisearchCache.dbVersion).stores({
|
||||||
searchHistory: '++id',
|
searchHistory: '++id',
|
||||||
@@ -37,7 +39,7 @@ export class OmnisearchCache extends Dexie {
|
|||||||
public static async clearOldDatabases(): Promise<void> {
|
public static async clearOldDatabases(): Promise<void> {
|
||||||
const toDelete = (await indexedDB.databases()).filter(
|
const toDelete = (await indexedDB.databases()).filter(
|
||||||
db =>
|
db =>
|
||||||
db.name === OmnisearchCache.dbName &&
|
db.name === OmnisearchCache.getDbName() &&
|
||||||
// version multiplied by 10 https://github.com/dexie/Dexie.js/issues/59
|
// version multiplied by 10 https://github.com/dexie/Dexie.js/issues/59
|
||||||
db.version !== OmnisearchCache.dbVersion * 10
|
db.version !== OmnisearchCache.dbVersion * 10
|
||||||
)
|
)
|
||||||
@@ -63,5 +65,3 @@ export class OmnisearchCache extends Dexie {
|
|||||||
await this.minisearch.clear()
|
await this.minisearch.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const database = OmnisearchCache.getInstance()
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { EventBus } from './tools/event-bus'
|
import { EventBus } from './tools/event-bus'
|
||||||
import { writable } from 'svelte/store'
|
import { writable } from 'svelte/store'
|
||||||
import { settings } from './settings'
|
|
||||||
import type { TFile } from 'obsidian'
|
import type { TFile } from 'obsidian'
|
||||||
import { Platform } from 'obsidian'
|
|
||||||
import { getObsidianApp } from './stores/obsidian-app'
|
import { getObsidianApp } from './stores/obsidian-app'
|
||||||
|
|
||||||
export const regexLineSplit = /\r?\n|\r|((\.|\?|!)( |\r?\n|\r))/g
|
export const regexLineSplit = /\r?\n|\r|((\.|\?|!)( |\r?\n|\r))/g
|
||||||
@@ -14,9 +12,6 @@ export const regexExtensions = /(?:^|\s)\.(\w+)/g
|
|||||||
export const excerptBefore = 100
|
export const excerptBefore = 100
|
||||||
export const excerptAfter = 300
|
export const excerptAfter = 300
|
||||||
|
|
||||||
export const highlightClass = `suggestion-highlight omnisearch-highlight ${
|
|
||||||
settings.highlight ? 'omnisearch-default-highlight' : ''
|
|
||||||
}`
|
|
||||||
export const K_DISABLE_OMNISEARCH = 'omnisearch-disabled'
|
export const K_DISABLE_OMNISEARCH = 'omnisearch-disabled'
|
||||||
|
|
||||||
export const eventBus = new EventBus()
|
export const eventBus = new EventBus()
|
||||||
@@ -118,10 +113,6 @@ export function getTextExtractor(): TextExtractorApi | undefined {
|
|||||||
return (getObsidianApp() as any).plugins?.plugins?.['text-extractor']?.api
|
return (getObsidianApp() as any).plugins?.plugins?.['text-extractor']?.api
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isCacheEnabled(): boolean {
|
|
||||||
return !Platform.isIosApp && settings.useCache
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SEPARATORS =
|
export const SEPARATORS =
|
||||||
/[|\t\n\r\^"= -#%-*,.`\/<>:;?@[-\]_{}\u00A0\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u1680\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2000-\u200A\u2010-\u2029\u202F-\u2043\u2045-\u2051\u2053-\u205F\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u3000-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/
|
/[|\t\n\r\^"= -#%-*,.`\/<>:;?@[-\]_{}\u00A0\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u1680\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2000-\u200A\u2010-\u2029\u202F-\u2043\u2045-\u2051\u2053-\u205F\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u3000-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/
|
||||||
.toString()
|
.toString()
|
||||||
|
|||||||
23
src/main.ts
23
src/main.ts
@@ -4,27 +4,22 @@ import {
|
|||||||
OmnisearchVaultModal,
|
OmnisearchVaultModal,
|
||||||
} from './components/modals'
|
} from './components/modals'
|
||||||
import {
|
import {
|
||||||
|
getSettings,
|
||||||
|
isCacheEnabled,
|
||||||
isPluginDisabled,
|
isPluginDisabled,
|
||||||
loadSettings,
|
loadSettings,
|
||||||
saveSettings,
|
saveSettings,
|
||||||
settings,
|
|
||||||
SettingsTab,
|
SettingsTab,
|
||||||
showExcerpt,
|
showExcerpt,
|
||||||
} from './settings'
|
} from './settings'
|
||||||
import {
|
import { eventBus, EventNames, indexingStep, IndexingStepType } from './globals'
|
||||||
eventBus,
|
|
||||||
EventNames,
|
|
||||||
indexingStep,
|
|
||||||
IndexingStepType,
|
|
||||||
isCacheEnabled,
|
|
||||||
} from './globals'
|
|
||||||
import api, { notifyOnIndexed } from './tools/api'
|
import api, { notifyOnIndexed } from './tools/api'
|
||||||
import { isFileIndexable, logDebug } from './tools/utils'
|
import { isFileIndexable, logDebug } from './tools/utils'
|
||||||
import { OmnisearchCache, database } from './database'
|
import { OmnisearchCache } from './database'
|
||||||
import * as NotesIndex from './notes-index'
|
import * as NotesIndex from './notes-index'
|
||||||
import { searchEngine } from './search/omnisearch'
|
|
||||||
import { cacheManager } from './cache-manager'
|
import { cacheManager } from './cache-manager'
|
||||||
import { setObsidianApp } from './stores/obsidian-app'
|
import { setObsidianApp } from './stores/obsidian-app'
|
||||||
|
import { Omnisearch } from './search/omnisearch'
|
||||||
|
|
||||||
export default class OmnisearchPlugin extends Plugin {
|
export default class OmnisearchPlugin extends Plugin {
|
||||||
// FIXME: fix the type
|
// FIXME: fix the type
|
||||||
@@ -56,6 +51,7 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
|
|
||||||
registerAPI(this)
|
registerAPI(this)
|
||||||
|
|
||||||
|
const settings = getSettings()
|
||||||
if (settings.ribbonIcon) {
|
if (settings.ribbonIcon) {
|
||||||
this.addRibbonButton()
|
this.addRibbonButton()
|
||||||
}
|
}
|
||||||
@@ -85,6 +81,8 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const searchEngine = Omnisearch.getInstance()
|
||||||
|
|
||||||
this.app.workspace.onLayoutReady(async () => {
|
this.app.workspace.onLayoutReady(async () => {
|
||||||
// Listeners to keep the search index up-to-date
|
// Listeners to keep the search index up-to-date
|
||||||
this.registerEvent(
|
this.registerEvent(
|
||||||
@@ -134,6 +132,7 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async executeFirstLaunchTasks(): Promise<void> {
|
async executeFirstLaunchTasks(): Promise<void> {
|
||||||
|
const settings = getSettings()
|
||||||
const code = '1.21.0'
|
const code = '1.21.0'
|
||||||
// if (settings.welcomeMessage !== code && getTextExtractor()) {
|
// if (settings.welcomeMessage !== code && getTextExtractor()) {
|
||||||
// const welcome = new DocumentFragment()
|
// const welcome = new DocumentFragment()
|
||||||
@@ -152,7 +151,7 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
|
|
||||||
// Clear cache when disabling Omnisearch
|
// Clear cache when disabling Omnisearch
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
await database.clearCache()
|
await OmnisearchCache.getInstance().clearCache()
|
||||||
}
|
}
|
||||||
this.apiHttpServer.close()
|
this.apiHttpServer.close()
|
||||||
}
|
}
|
||||||
@@ -180,6 +179,7 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
// Map documents in the background
|
// Map documents in the background
|
||||||
// Promise.all(files.map(f => cacheManager.addToLiveCache(f.path)))
|
// Promise.all(files.map(f => cacheManager.addToLiveCache(f.path)))
|
||||||
|
|
||||||
|
const searchEngine = Omnisearch.getInstance()
|
||||||
if (isCacheEnabled()) {
|
if (isCacheEnabled()) {
|
||||||
console.time('Omnisearch - Loading index from cache')
|
console.time('Omnisearch - Loading index from cache')
|
||||||
indexingStep.set(IndexingStepType.LoadingCache)
|
indexingStep.set(IndexingStepType.LoadingCache)
|
||||||
@@ -221,6 +221,7 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
|
|
||||||
if ((diff.toRemove.length || diff.toAdd.length) && isCacheEnabled()) {
|
if ((diff.toRemove.length || diff.toAdd.length) && isCacheEnabled()) {
|
||||||
indexingStep.set(IndexingStepType.WritingCache)
|
indexingStep.set(IndexingStepType.WritingCache)
|
||||||
|
const settings = getSettings()
|
||||||
|
|
||||||
// Disable settings.useCache while writing the cache, in case it freezes
|
// Disable settings.useCache while writing the cache, in case it freezes
|
||||||
settings.useCache = false
|
settings.useCache = false
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { TAbstractFile } from 'obsidian'
|
import type { TAbstractFile } from 'obsidian'
|
||||||
import { searchEngine } from './search/omnisearch'
|
import { Omnisearch } from './search/omnisearch'
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Index a non-existing note.
|
// * Index a non-existing note.
|
||||||
@@ -42,6 +42,7 @@ export function markNoteForReindex(note: TAbstractFile): void {
|
|||||||
export async function refreshIndex(): Promise<void> {
|
export async function refreshIndex(): Promise<void> {
|
||||||
const paths = [...notesToReindex].map(n => n.path)
|
const paths = [...notesToReindex].map(n => n.path)
|
||||||
if (paths.length) {
|
if (paths.length) {
|
||||||
|
const searchEngine = Omnisearch.getInstance()
|
||||||
searchEngine.removeFromPaths(paths)
|
searchEngine.removeFromPaths(paths)
|
||||||
await searchEngine.addFromPaths(paths)
|
await searchEngine.addFromPaths(paths)
|
||||||
notesToReindex.clear()
|
notesToReindex.clear()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import MiniSearch, { type Options, type SearchResult } from 'minisearch'
|
import MiniSearch, { type Options, type SearchResult } from 'minisearch'
|
||||||
import type { DocumentRef, IndexedDocument, ResultNote } from '../globals'
|
import type { DocumentRef, IndexedDocument, ResultNote } from '../globals'
|
||||||
|
|
||||||
import { settings } from '../settings'
|
|
||||||
import { chunkArray, logDebug, removeDiacritics } from '../tools/utils'
|
import { chunkArray, logDebug, removeDiacritics } from '../tools/utils'
|
||||||
import { Notice } from 'obsidian'
|
import { Notice } from 'obsidian'
|
||||||
import type { Query } from './query'
|
import type { Query } from './query'
|
||||||
@@ -10,10 +9,21 @@ import { sortBy } from 'lodash-es'
|
|||||||
import { getMatches, stringsToRegex } from 'src/tools/text-processing'
|
import { getMatches, stringsToRegex } from 'src/tools/text-processing'
|
||||||
import { tokenizeForIndexing, tokenizeForSearch } from './tokenizer'
|
import { tokenizeForIndexing, tokenizeForSearch } from './tokenizer'
|
||||||
import { getObsidianApp } from '../stores/obsidian-app'
|
import { getObsidianApp } from '../stores/obsidian-app'
|
||||||
|
import { getSettings } from 'src/settings'
|
||||||
|
|
||||||
export class Omnisearch {
|
export class Omnisearch {
|
||||||
|
|
||||||
|
private static instance: Omnisearch
|
||||||
|
|
||||||
app = getObsidianApp()
|
app = getObsidianApp()
|
||||||
|
settings = getSettings()
|
||||||
|
|
||||||
|
public static getInstance(): Omnisearch {
|
||||||
|
if (!Omnisearch.instance) {
|
||||||
|
Omnisearch.instance = new Omnisearch();
|
||||||
|
}
|
||||||
|
return Omnisearch.instance;
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly options: Options<IndexedDocument> = {
|
public static readonly options: Options<IndexedDocument> = {
|
||||||
tokenize: tokenizeForIndexing,
|
tokenize: tokenizeForIndexing,
|
||||||
@@ -27,7 +37,7 @@ export class Omnisearch {
|
|||||||
return (doc as any)[fieldName]
|
return (doc as any)[fieldName]
|
||||||
},
|
},
|
||||||
processTerm: (term: string) =>
|
processTerm: (term: string) =>
|
||||||
(settings.ignoreDiacritics ? removeDiacritics(term) : term).toLowerCase(),
|
(getSettings().ignoreDiacritics ? removeDiacritics(term) : term).toLowerCase(),
|
||||||
idField: 'path',
|
idField: 'path',
|
||||||
fields: [
|
fields: [
|
||||||
'basename',
|
'basename',
|
||||||
@@ -55,7 +65,7 @@ export class Omnisearch {
|
|||||||
// private previousResults: SearchResult[] = []
|
// private previousResults: SearchResult[] = []
|
||||||
// private previousQuery: Query | null = null
|
// private previousQuery: Query | null = null
|
||||||
|
|
||||||
constructor() {
|
private constructor() {
|
||||||
this.minisearch = new MiniSearch(Omnisearch.options)
|
this.minisearch = new MiniSearch(Omnisearch.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +174,7 @@ export class Omnisearch {
|
|||||||
logDebug('Starting search for', query)
|
logDebug('Starting search for', query)
|
||||||
|
|
||||||
let fuzziness: number
|
let fuzziness: number
|
||||||
switch (settings.fuzziness) {
|
switch (this.settings.fuzziness) {
|
||||||
case '0':
|
case '0':
|
||||||
fuzziness = 0
|
fuzziness = 0
|
||||||
break
|
break
|
||||||
@@ -186,14 +196,14 @@ export class Omnisearch {
|
|||||||
fuzzy: term =>
|
fuzzy: term =>
|
||||||
term.length <= 3 ? 0 : term.length <= 5 ? fuzziness / 2 : fuzziness,
|
term.length <= 3 ? 0 : term.length <= 5 ? fuzziness / 2 : fuzziness,
|
||||||
boost: {
|
boost: {
|
||||||
basename: settings.weightBasename,
|
basename: this.settings.weightBasename,
|
||||||
directory: settings.weightDirectory,
|
directory: this.settings.weightDirectory,
|
||||||
aliases: settings.weightBasename,
|
aliases: this.settings.weightBasename,
|
||||||
headings1: settings.weightH1,
|
headings1: this.settings.weightH1,
|
||||||
headings2: settings.weightH2,
|
headings2: this.settings.weightH2,
|
||||||
headings3: settings.weightH3,
|
headings3: this.settings.weightH3,
|
||||||
tags: settings.weightUnmarkedTags,
|
tags: this.settings.weightUnmarkedTags,
|
||||||
unmarkedTags: settings.weightUnmarkedTags,
|
unmarkedTags: this.settings.weightUnmarkedTags,
|
||||||
},
|
},
|
||||||
// The query is already tokenized, don't tokenize again
|
// The query is already tokenized, don't tokenize again
|
||||||
tokenize: text => [text],
|
tokenize: text => [text],
|
||||||
@@ -239,11 +249,11 @@ export class Omnisearch {
|
|||||||
|
|
||||||
logDebug(
|
logDebug(
|
||||||
'searching with downranked folders',
|
'searching with downranked folders',
|
||||||
settings.downrankedFoldersFilters
|
this.settings.downrankedFoldersFilters
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hide or downrank files that are in Obsidian's excluded list
|
// Hide or downrank files that are in Obsidian's excluded list
|
||||||
if (settings.hideExcluded) {
|
if (this.settings.hideExcluded) {
|
||||||
// Filter the files out
|
// Filter the files out
|
||||||
results = results.filter(
|
results = results.filter(
|
||||||
result =>
|
result =>
|
||||||
@@ -269,10 +279,10 @@ export class Omnisearch {
|
|||||||
|
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
const path = result.id
|
const path = result.id
|
||||||
if (settings.downrankedFoldersFilters.length > 0) {
|
if (this.settings.downrankedFoldersFilters.length > 0) {
|
||||||
// downrank files that are in folders listed in the downrankedFoldersFilters
|
// downrank files that are in folders listed in the downrankedFoldersFilters
|
||||||
let downrankingFolder = false
|
let downrankingFolder = false
|
||||||
settings.downrankedFoldersFilters.forEach(filter => {
|
this.settings.downrankedFoldersFilters.forEach(filter => {
|
||||||
if (path.startsWith(filter)) {
|
if (path.startsWith(filter)) {
|
||||||
// we don't want the filter to match the folder sources, e.g.
|
// we don't want the filter to match the folder sources, e.g.
|
||||||
// it needs to match a whole folder name
|
// it needs to match a whole folder name
|
||||||
@@ -289,7 +299,7 @@ export class Omnisearch {
|
|||||||
const pathPartsLength = pathParts.length
|
const pathPartsLength = pathParts.length
|
||||||
for (let i = 0; i < pathPartsLength; i++) {
|
for (let i = 0; i < pathPartsLength; i++) {
|
||||||
const pathPart = pathParts[i]
|
const pathPart = pathParts[i]
|
||||||
if (settings.downrankedFoldersFilters.includes(pathPart)) {
|
if (this.settings.downrankedFoldersFilters.includes(pathPart)) {
|
||||||
result.score /= 10
|
result.score /= 10
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -299,7 +309,7 @@ export class Omnisearch {
|
|||||||
// Boost custom properties
|
// Boost custom properties
|
||||||
const metadata = this.app.metadataCache.getCache(path)
|
const metadata = this.app.metadataCache.getCache(path)
|
||||||
if (metadata) {
|
if (metadata) {
|
||||||
for (const { name, weight } of settings.weightCustomProperties) {
|
for (const { name, weight } of this.settings.weightCustomProperties) {
|
||||||
const values = metadata?.frontmatter?.[name]
|
const values = metadata?.frontmatter?.[name]
|
||||||
if (values && result.terms.some(t => values.includes(t))) {
|
if (values && result.terms.some(t => values.includes(t))) {
|
||||||
logDebug(`Boosting field "${name}" x${weight} for ${path}`)
|
logDebug(`Boosting field "${name}" x${weight} for ${path}`)
|
||||||
@@ -379,7 +389,7 @@ export class Omnisearch {
|
|||||||
): Promise<ResultNote[]> {
|
): Promise<ResultNote[]> {
|
||||||
// Get the raw results
|
// Get the raw results
|
||||||
let results: SearchResult[]
|
let results: SearchResult[]
|
||||||
if (settings.simpleSearch) {
|
if (this.settings.simpleSearch) {
|
||||||
results = await this.search(query, {
|
results = await this.search(query, {
|
||||||
prefixLength: 3,
|
prefixLength: 3,
|
||||||
singleFilePath: options?.singleFilePath,
|
singleFilePath: options?.singleFilePath,
|
||||||
@@ -450,4 +460,3 @@ export class Omnisearch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const searchEngine = new Omnisearch()
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { settings } from '../settings'
|
import { getSettings } from 'src/settings'
|
||||||
import { removeDiacritics } from '../tools/utils'
|
import { removeDiacritics } from '../tools/utils'
|
||||||
import { parse } from 'search-query-parser'
|
import { parse } from 'search-query-parser'
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ export class Query {
|
|||||||
#inQuotes: string[]
|
#inQuotes: string[]
|
||||||
|
|
||||||
constructor(text = '') {
|
constructor(text = '') {
|
||||||
if (settings.ignoreDiacritics) {
|
if (getSettings().ignoreDiacritics) {
|
||||||
text = removeDiacritics(text)
|
text = removeDiacritics(text)
|
||||||
}
|
}
|
||||||
const parsed = parse(text.toLowerCase(), {
|
const parsed = parse(text.toLowerCase(), {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
chsRegex,
|
chsRegex,
|
||||||
getChsSegmenter,
|
getChsSegmenter,
|
||||||
} from 'src/globals'
|
} from 'src/globals'
|
||||||
import { settings } from 'src/settings'
|
import { getSettings } from 'src/settings'
|
||||||
import { logDebug, splitCamelCase, splitHyphens } from 'src/tools/utils'
|
import { logDebug, splitCamelCase, splitHyphens } from 'src/tools/utils'
|
||||||
const markdownLinkExtractor = require('markdown-link-extractor')
|
const markdownLinkExtractor = require('markdown-link-extractor')
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ function tokenizeChsWord(tokens: string[]): string[] {
|
|||||||
export function tokenizeForIndexing(text: string): string[] {
|
export function tokenizeForIndexing(text: string): string[] {
|
||||||
const words = tokenizeWords(text)
|
const words = tokenizeWords(text)
|
||||||
let urls: string[] = []
|
let urls: string[] = []
|
||||||
if (settings.tokenizeUrls) {
|
if (getSettings().tokenizeUrls) {
|
||||||
try {
|
try {
|
||||||
urls = markdownLinkExtractor(text)
|
urls = markdownLinkExtractor(text)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -8,14 +8,10 @@ import {
|
|||||||
SliderComponent,
|
SliderComponent,
|
||||||
} from 'obsidian'
|
} from 'obsidian'
|
||||||
import { writable } from 'svelte/store'
|
import { writable } from 'svelte/store'
|
||||||
import { database } from './database'
|
import { K_DISABLE_OMNISEARCH, getTextExtractor } from './globals'
|
||||||
import {
|
|
||||||
K_DISABLE_OMNISEARCH,
|
|
||||||
getTextExtractor,
|
|
||||||
isCacheEnabled,
|
|
||||||
} from './globals'
|
|
||||||
import type OmnisearchPlugin from './main'
|
import type OmnisearchPlugin from './main'
|
||||||
import { getObsidianApp } from './stores/obsidian-app'
|
import { getObsidianApp } from './stores/obsidian-app'
|
||||||
|
import { OmnisearchCache } from './database'
|
||||||
|
|
||||||
interface WeightingSettings {
|
interface WeightingSettings {
|
||||||
weightBasename: number
|
weightBasename: number
|
||||||
@@ -95,6 +91,7 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
|
|
||||||
display(): void {
|
display(): void {
|
||||||
const { containerEl } = this
|
const { containerEl } = this
|
||||||
|
const database = OmnisearchCache.getInstance()
|
||||||
containerEl.empty()
|
containerEl.empty()
|
||||||
|
|
||||||
if (this.app.loadLocalStorage(K_DISABLE_OMNISEARCH) == '1') {
|
if (this.app.loadLocalStorage(K_DISABLE_OMNISEARCH) == '1') {
|
||||||
@@ -479,38 +476,37 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(
|
.setName(
|
||||||
`File name & declared aliases (default: ${DEFAULT_SETTINGS.weightBasename})`
|
`File name & declared aliases (default: ${getDefaultSettings().weightBasename})`
|
||||||
)
|
)
|
||||||
.addSlider(cb => this.weightSlider(cb, 'weightBasename'))
|
.addSlider(cb => this.weightSlider(cb, 'weightBasename'))
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(`File directory (default: ${DEFAULT_SETTINGS.weightDirectory})`)
|
.setName(`File directory (default: ${getDefaultSettings().weightDirectory})`)
|
||||||
.addSlider(cb => this.weightSlider(cb, 'weightDirectory'))
|
.addSlider(cb => this.weightSlider(cb, 'weightDirectory'))
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(`Headings level 1 (default: ${DEFAULT_SETTINGS.weightH1})`)
|
.setName(`Headings level 1 (default: ${getDefaultSettings().weightH1})`)
|
||||||
.addSlider(cb => this.weightSlider(cb, 'weightH1'))
|
.addSlider(cb => this.weightSlider(cb, 'weightH1'))
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(`Headings level 2 (default: ${DEFAULT_SETTINGS.weightH2})`)
|
.setName(`Headings level 2 (default: ${getDefaultSettings().weightH2})`)
|
||||||
.addSlider(cb => this.weightSlider(cb, 'weightH2'))
|
.addSlider(cb => this.weightSlider(cb, 'weightH2'))
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(`Headings level 3 (default: ${DEFAULT_SETTINGS.weightH3})`)
|
.setName(`Headings level 3 (default: ${getDefaultSettings().weightH3})`)
|
||||||
.addSlider(cb => this.weightSlider(cb, 'weightH3'))
|
.addSlider(cb => this.weightSlider(cb, 'weightH3'))
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(
|
.setName(`Tags (default: ${getDefaultSettings().weightUnmarkedTags})`)
|
||||||
`Tags (default: ${DEFAULT_SETTINGS.weightUnmarkedTags})`
|
|
||||||
)
|
|
||||||
.addSlider(cb => this.weightSlider(cb, 'weightUnmarkedTags'))
|
.addSlider(cb => this.weightSlider(cb, 'weightUnmarkedTags'))
|
||||||
|
|
||||||
//#region Specific tags
|
//#region Specific tags
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName('Header properties fields')
|
.setName('Header properties fields')
|
||||||
.setDesc('You can set custom weights for values of header properties (e.g. "keywords").')
|
.setDesc(
|
||||||
|
'You can set custom weights for values of header properties (e.g. "keywords").'
|
||||||
|
)
|
||||||
|
|
||||||
for (let i = 0; i < settings.weightCustomProperties.length; i++) {
|
for (let i = 0; i < settings.weightCustomProperties.length; i++) {
|
||||||
const item = settings.weightCustomProperties[i]
|
const item = settings.weightCustomProperties[i]
|
||||||
@@ -547,8 +543,7 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a new custom tag
|
// Add a new custom tag
|
||||||
new Setting(containerEl)
|
new Setting(containerEl).addButton(btn => {
|
||||||
.addButton(btn => {
|
|
||||||
btn.setButtonText('Add a new property')
|
btn.setButtonText('Add a new property')
|
||||||
btn.onClick(cb => {
|
btn.onClick(cb => {
|
||||||
settings.weightCustomProperties.push({ name: '', weight: 1 })
|
settings.weightCustomProperties.push({ name: '', weight: 1 })
|
||||||
@@ -712,9 +707,9 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = getObsidianApp()
|
function getDefaultSettings(): OmnisearchSettings {
|
||||||
|
const app = getObsidianApp()
|
||||||
export const DEFAULT_SETTINGS: OmnisearchSettings = {
|
return {
|
||||||
useCache: true,
|
useCache: true,
|
||||||
hideExcluded: false,
|
hideExcluded: false,
|
||||||
downrankedFoldersFilters: [] as string[],
|
downrankedFoldersFilters: [] as string[],
|
||||||
@@ -752,12 +747,20 @@ export const DEFAULT_SETTINGS: OmnisearchSettings = {
|
|||||||
|
|
||||||
welcomeMessage: '',
|
welcomeMessage: '',
|
||||||
verboseLogging: false,
|
verboseLogging: false,
|
||||||
} as const
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export let settings = Object.assign({}, DEFAULT_SETTINGS) as OmnisearchSettings
|
let settings: OmnisearchSettings
|
||||||
|
|
||||||
|
export function getSettings(): OmnisearchSettings {
|
||||||
|
if (!settings) {
|
||||||
|
settings = Object.assign({}, getDefaultSettings()) as OmnisearchSettings
|
||||||
|
}
|
||||||
|
return settings
|
||||||
|
}
|
||||||
|
|
||||||
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 = Object.assign({}, getDefaultSettings(), await plugin.loadData())
|
||||||
showExcerpt.set(settings.showExcerpt)
|
showExcerpt.set(settings.showExcerpt)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,13 +769,17 @@ export async function saveSettings(plugin: Plugin): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isPluginDisabled(): boolean {
|
export function isPluginDisabled(): boolean {
|
||||||
return app.loadLocalStorage(K_DISABLE_OMNISEARCH) === '1'
|
return getObsidianApp().loadLocalStorage(K_DISABLE_OMNISEARCH) === '1'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canIndexUnsupportedFiles(): boolean {
|
export function canIndexUnsupportedFiles(): boolean {
|
||||||
return (
|
return (
|
||||||
settings.unsupportedFilesIndexing === 'yes' ||
|
settings.unsupportedFilesIndexing === 'yes' ||
|
||||||
(settings.unsupportedFilesIndexing === 'default' &&
|
(settings.unsupportedFilesIndexing === 'default' &&
|
||||||
!!app.vault.getConfig('showUnsupportedFiles'))
|
!!getObsidianApp().vault.getConfig('showUnsupportedFiles'))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isCacheEnabled(): boolean {
|
||||||
|
return !Platform.isIosApp && settings.useCache
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ export function setObsidianApp(app: App) {
|
|||||||
*/
|
*/
|
||||||
export function getObsidianApp() {
|
export function getObsidianApp() {
|
||||||
if (!obsidianApp) {
|
if (!obsidianApp) {
|
||||||
// throw new Error('Obsidian app not set')
|
throw new Error('Obsidian app not set')
|
||||||
// console.trace('Obsidian app not set')
|
|
||||||
return app // FIXME: please.
|
|
||||||
}
|
}
|
||||||
return obsidianApp as App
|
return obsidianApp as App
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import * as http from 'http'
|
|||||||
import * as url from 'url'
|
import * as url from 'url'
|
||||||
import api from './api'
|
import api from './api'
|
||||||
import { Notice } from 'obsidian'
|
import { Notice } from 'obsidian'
|
||||||
import { settings } from 'src/settings'
|
import { getSettings } from 'src/settings'
|
||||||
|
|
||||||
export function getServer() {
|
export function getServer() {
|
||||||
const server = http.createServer(async function (req, res) {
|
const server = http.createServer(async function (req, res) {
|
||||||
@@ -47,7 +47,7 @@ export function getServer() {
|
|||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
console.log(`Omnisearch - Started HTTP server on port ${port}`)
|
console.log(`Omnisearch - Started HTTP server on port ${port}`)
|
||||||
if (settings.httpApiNotice) {
|
if (getSettings().httpApiNotice) {
|
||||||
new Notice(`Omnisearch - Started HTTP server on port ${port}`)
|
new Notice(`Omnisearch - Started HTTP server on port ${port}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,6 +62,7 @@ export function getServer() {
|
|||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
server.close()
|
server.close()
|
||||||
|
const settings = getSettings()
|
||||||
console.log(`Omnisearch - Terminated HTTP server`)
|
console.log(`Omnisearch - Terminated HTTP server`)
|
||||||
if (settings.httpApiEnabled && settings.httpApiNotice) {
|
if (settings.httpApiEnabled && settings.httpApiNotice) {
|
||||||
new Notice(`Omnisearch - Terminated HTTP server`)
|
new Notice(`Omnisearch - Terminated HTTP server`)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { ResultNote } from '../globals'
|
import type { ResultNote } from '../globals'
|
||||||
import { Query } from '../search/query'
|
import { Query } from '../search/query'
|
||||||
import { searchEngine } from '../search/omnisearch'
|
|
||||||
import { makeExcerpt } from './text-processing'
|
import { makeExcerpt } from './text-processing'
|
||||||
import { refreshIndex } from '../notes-index'
|
import { refreshIndex } from '../notes-index'
|
||||||
import { getObsidianApp } from '../stores/obsidian-app'
|
import { getObsidianApp } from '../stores/obsidian-app'
|
||||||
|
import { Omnisearch } from 'src/search/omnisearch'
|
||||||
|
|
||||||
type ResultNoteApi = {
|
type ResultNoteApi = {
|
||||||
score: number
|
score: number
|
||||||
@@ -20,7 +20,6 @@ export type SearchMatchApi = {
|
|||||||
offset: number
|
offset: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = getObsidianApp()
|
|
||||||
|
|
||||||
let notified = false
|
let notified = false
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ function mapResults(results: ResultNote[]): ResultNoteApi[] {
|
|||||||
|
|
||||||
const res: ResultNoteApi = {
|
const res: ResultNoteApi = {
|
||||||
score,
|
score,
|
||||||
vault: app.vault.getName(),
|
vault: getObsidianApp().vault.getName(),
|
||||||
path,
|
path,
|
||||||
basename,
|
basename,
|
||||||
foundWords,
|
foundWords,
|
||||||
@@ -56,7 +55,7 @@ function mapResults(results: ResultNote[]): ResultNoteApi[] {
|
|||||||
|
|
||||||
async function search(q: string): Promise<ResultNoteApi[]> {
|
async function search(q: string): Promise<ResultNoteApi[]> {
|
||||||
const query = new Query(q)
|
const query = new Query(q)
|
||||||
const raw = await searchEngine.getSuggestions(query)
|
const raw = await Omnisearch.getInstance().getSuggestions(query)
|
||||||
return mapResults(raw)
|
return mapResults(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import { type CachedMetadata, MarkdownView, TFile } from 'obsidian'
|
|||||||
import type { ResultNote } from '../globals'
|
import type { ResultNote } from '../globals'
|
||||||
import { getObsidianApp } from '../stores/obsidian-app'
|
import { getObsidianApp } from '../stores/obsidian-app'
|
||||||
|
|
||||||
const app = getObsidianApp()
|
|
||||||
|
|
||||||
export async function openNote(
|
export async function openNote(
|
||||||
item: ResultNote,
|
item: ResultNote,
|
||||||
offset = 0,
|
offset = 0,
|
||||||
@@ -12,6 +10,7 @@ export async function openNote(
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Check if the note is already open,
|
// Check if the note is already open,
|
||||||
// to avoid opening it twice if the first one is pinned
|
// to avoid opening it twice if the first one is pinned
|
||||||
|
const app = getObsidianApp()
|
||||||
let alreadyOpenAndPinned = false
|
let alreadyOpenAndPinned = false
|
||||||
app.workspace.iterateAllLeaves(leaf => {
|
app.workspace.iterateAllLeaves(leaf => {
|
||||||
if (leaf.view instanceof MarkdownView) {
|
if (leaf.view instanceof MarkdownView) {
|
||||||
@@ -48,6 +47,7 @@ export async function openNote(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createNote(name: string, newLeaf = false): Promise<void> {
|
export async function createNote(name: string, newLeaf = false): Promise<void> {
|
||||||
|
const app = getObsidianApp()
|
||||||
try {
|
try {
|
||||||
let pathPrefix: string
|
let pathPrefix: string
|
||||||
switch (app.vault.getConfig('newFileLocation')) {
|
switch (app.vault.getConfig('newFileLocation')) {
|
||||||
@@ -83,7 +83,7 @@ export function getNonExistingNotes(
|
|||||||
return (metadata.links ?? [])
|
return (metadata.links ?? [])
|
||||||
.map(l => {
|
.map(l => {
|
||||||
const path = removeAnchors(l.link)
|
const path = removeAnchors(l.link)
|
||||||
return app.metadataCache.getFirstLinkpathDest(path, file.path)
|
return getObsidianApp().metadataCache.getFirstLinkpathDest(path, file.path)
|
||||||
? ''
|
? ''
|
||||||
: l.link
|
: l.link
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
highlightClass,
|
|
||||||
type SearchMatch,
|
type SearchMatch,
|
||||||
regexLineSplit,
|
regexLineSplit,
|
||||||
regexYaml,
|
regexYaml,
|
||||||
@@ -7,11 +6,11 @@ import {
|
|||||||
excerptAfter,
|
excerptAfter,
|
||||||
excerptBefore,
|
excerptBefore,
|
||||||
} from 'src/globals'
|
} from 'src/globals'
|
||||||
import { settings } from 'src/settings'
|
|
||||||
import { removeDiacritics, warnDebug } from './utils'
|
import { removeDiacritics, warnDebug } from './utils'
|
||||||
import type { Query } from 'src/search/query'
|
import type { Query } from 'src/search/query'
|
||||||
import { Notice } from 'obsidian'
|
import { Notice } from 'obsidian'
|
||||||
import { escapeRegExp } from 'lodash-es'
|
import { escapeRegExp } from 'lodash-es'
|
||||||
|
import { getSettings } from 'src/settings'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the matches in the text with a <span> element and a highlight class
|
* Wraps the matches in the text with a <span> element and a highlight class
|
||||||
@@ -20,6 +19,10 @@ import { escapeRegExp } from 'lodash-es'
|
|||||||
* @returns The html string with the matches highlighted
|
* @returns The html string with the matches highlighted
|
||||||
*/
|
*/
|
||||||
export function highlightText(text: string, matches: SearchMatch[]): string {
|
export function highlightText(text: string, matches: SearchMatch[]): string {
|
||||||
|
const highlightClass = `suggestion-highlight omnisearch-highlight ${
|
||||||
|
getSettings().highlight ? 'omnisearch-default-highlight' : ''
|
||||||
|
}`
|
||||||
|
|
||||||
if (!matches.length) {
|
if (!matches.length) {
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
@@ -125,7 +128,7 @@ export function getMatches(
|
|||||||
): SearchMatch[] {
|
): SearchMatch[] {
|
||||||
const originalText = text
|
const originalText = text
|
||||||
// text = text.toLowerCase().replace(new RegExp(SEPARATORS, 'gu'), ' ')
|
// text = text.toLowerCase().replace(new RegExp(SEPARATORS, 'gu'), ' ')
|
||||||
if (settings.ignoreDiacritics) {
|
if (getSettings().ignoreDiacritics) {
|
||||||
text = removeDiacritics(text)
|
text = removeDiacritics(text)
|
||||||
}
|
}
|
||||||
const startTime = new Date().getTime()
|
const startTime = new Date().getTime()
|
||||||
@@ -165,6 +168,7 @@ export function getMatches(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function makeExcerpt(content: string, offset: number): string {
|
export function makeExcerpt(content: string, offset: number): string {
|
||||||
|
const settings = getSettings()
|
||||||
try {
|
try {
|
||||||
const pos = offset ?? -1
|
const pos = offset ?? -1
|
||||||
const from = Math.max(0, pos - excerptBefore)
|
const from = Math.max(0, pos - excerptBefore)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
Platform,
|
Platform,
|
||||||
} from 'obsidian'
|
} from 'obsidian'
|
||||||
import { getTextExtractor, isSearchMatch, type SearchMatch } from '../globals'
|
import { getTextExtractor, isSearchMatch, type SearchMatch } from '../globals'
|
||||||
import { canIndexUnsupportedFiles, settings } from '../settings'
|
import { canIndexUnsupportedFiles, getSettings } from '../settings'
|
||||||
import { type BinaryLike, createHash } from 'crypto'
|
import { type BinaryLike, createHash } from 'crypto'
|
||||||
import { md5 } from 'pure-md5'
|
import { md5 } from 'pure-md5'
|
||||||
|
|
||||||
@@ -136,6 +136,7 @@ export function getCtrlKeyLabel(): 'ctrl' | '⌘' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isContentIndexable(path: string): boolean {
|
export function isContentIndexable(path: string): boolean {
|
||||||
|
const settings = getSettings()
|
||||||
const hasTextExtractor = !!getTextExtractor()
|
const hasTextExtractor = !!getTextExtractor()
|
||||||
const canIndexPDF = hasTextExtractor && settings.PDFIndexing
|
const canIndexPDF = hasTextExtractor && settings.PDFIndexing
|
||||||
const canIndexImages = hasTextExtractor && settings.imagesIndexing
|
const canIndexImages = hasTextExtractor && settings.imagesIndexing
|
||||||
@@ -176,7 +177,7 @@ export function isFileOffice(path: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isFilePlaintext(path: string): boolean {
|
export function isFilePlaintext(path: string): boolean {
|
||||||
return [...settings.indexedFileTypes, 'md'].some(t => path.endsWith(`.${t}`))
|
return [...getSettings().indexedFileTypes, 'md'].some(t => path.endsWith(`.${t}`))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isFileCanvas(path: string): boolean {
|
export function isFileCanvas(path: string): boolean {
|
||||||
@@ -251,7 +252,7 @@ export function warnDebug(...args: any[]): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function printDebug(fn: (...args: any[]) => any, ...args: any[]): void {
|
function printDebug(fn: (...args: any[]) => any, ...args: any[]): void {
|
||||||
if (settings.verboseLogging) {
|
if (getSettings().verboseLogging) {
|
||||||
const t = new Date()
|
const t = new Date()
|
||||||
const ts = `${t.getMinutes()}:${t.getSeconds()}:${t.getMilliseconds()}`
|
const ts = `${t.getMinutes()}:${t.getSeconds()}:${t.getMilliseconds()}`
|
||||||
fn(...['Omnisearch -', ts + ' -', ...args])
|
fn(...['Omnisearch -', ts + ' -', ...args])
|
||||||
|
|||||||
Reference in New Issue
Block a user