@@ -29,3 +29,22 @@
|
|||||||
|
|
||||||
.omnisearch-highlight {
|
.omnisearch-highlight {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.omnisearch-input-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.omnisearch-input-field {
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.omnisearch-input__context {
|
||||||
|
position: absolute;
|
||||||
|
right: 1em;
|
||||||
|
top: calc(50% - 0.75em);
|
||||||
|
color: var(--text-faint);
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import { createEventDispatcher, onMount, tick } from 'svelte'
|
import { createEventDispatcher, onMount, tick } from 'svelte'
|
||||||
|
|
||||||
export let value = ''
|
export let value = ''
|
||||||
|
export let label = ''
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let elInput: HTMLInputElement
|
let elInput: HTMLInputElement
|
||||||
@@ -22,13 +23,22 @@
|
|||||||
}, 100)
|
}, 100)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<input
|
<div class="omnisearch-input-container">
|
||||||
|
<div class="omnisearch-input-field">
|
||||||
|
<input
|
||||||
bind:value
|
bind:value
|
||||||
bind:this={elInput}
|
bind:this="{elInput}"
|
||||||
on:input={debouncedOnInput}
|
on:input="{debouncedOnInput}"
|
||||||
on:compositionstart={_ => toggleInputComposition(true)}
|
on:compositionstart="{_ => toggleInputComposition(true)}"
|
||||||
on:compositionend={_ => toggleInputComposition(false)}
|
on:compositionend="{_ => toggleInputComposition(false)}"
|
||||||
type="text"
|
type="text"
|
||||||
class="prompt-input"
|
class="prompt-input"
|
||||||
placeholder="Type to search through your notes"
|
placeholder="Type to search through your notes"
|
||||||
spellcheck="false" />
|
spellcheck="false" />
|
||||||
|
|
||||||
|
<span class="omnisearch-input__context">
|
||||||
|
{label}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -140,11 +140,12 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="modal-title">Omnisearch - File</div>
|
<InputSearch
|
||||||
<div class="modal-content">
|
value={searchQuery}
|
||||||
<InputSearch value={searchQuery} on:input={e => (searchQuery = e.detail)} />
|
on:input={e => (searchQuery = e.detail)}
|
||||||
|
label="Omnisearch - File" />
|
||||||
|
|
||||||
<ModalContainer>
|
<ModalContainer>
|
||||||
{#if groupedOffsets.length && note}
|
{#if groupedOffsets.length && note}
|
||||||
{#each groupedOffsets as offset, i}
|
{#each groupedOffsets as offset, i}
|
||||||
<ResultItemInFile
|
<ResultItemInFile
|
||||||
@@ -160,8 +161,7 @@
|
|||||||
We found 0 result for your search here.
|
We found 0 result for your search here.
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</ModalContainer>
|
</ModalContainer>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="prompt-instructions">
|
<div class="prompt-instructions">
|
||||||
<div class="prompt-instruction">
|
<div class="prompt-instruction">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
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 { settings } from 'src/settings'
|
import { settings } from '../settings'
|
||||||
|
|
||||||
export let modal: OmnisearchVaultModal
|
export let modal: OmnisearchVaultModal
|
||||||
let selectedIndex = 0
|
let selectedIndex = 0
|
||||||
@@ -53,6 +53,7 @@
|
|||||||
}
|
}
|
||||||
searchQuery = searchHistory[historySearchIndex]
|
searchQuery = searchHistory[historySearchIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextSearchHistory() {
|
function nextSearchHistory() {
|
||||||
if (--historySearchIndex < 0) {
|
if (--historySearchIndex < 0) {
|
||||||
historySearchIndex = searchHistory.length ? searchHistory.length - 1 : 0
|
historySearchIndex = searchHistory.length ? searchHistory.length - 1 : 0
|
||||||
@@ -66,7 +67,7 @@
|
|||||||
(a, b) => b.score - a.score
|
(a, b) => b.score - a.score
|
||||||
)
|
)
|
||||||
selectedIndex = 0
|
selectedIndex = 0
|
||||||
scrollIntoView()
|
await scrollIntoView()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onClick(evt?: MouseEvent | KeyboardEvent) {
|
function onClick(evt?: MouseEvent | KeyboardEvent) {
|
||||||
@@ -167,23 +168,29 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="modal-title">Omnisearch - Vault</div>
|
<InputSearch
|
||||||
<div class="modal-content">
|
value="{searchQuery}"
|
||||||
<InputSearch value={searchQuery} on:input={e => (searchQuery = e.detail)} />
|
on:input="{e => (searchQuery = e.detail)}"
|
||||||
|
label="Omnisearch - Vault">
|
||||||
|
{#if $settings.showCreateButton}
|
||||||
|
<button on:click="{createNoteAndCloseModal}">Create note</button>
|
||||||
|
{/if}
|
||||||
|
</InputSearch>
|
||||||
|
|
||||||
<ModalContainer>
|
<ModalContainer>
|
||||||
{#each resultNotes as result, i}
|
{#each resultNotes as result, i}
|
||||||
<ResultItemVault
|
<ResultItemVault
|
||||||
selected={i === selectedIndex}
|
selected="{i === selectedIndex}"
|
||||||
note={result}
|
note="{result}"
|
||||||
on:mousemove={e => (selectedIndex = i)}
|
on:mousemove="{_ => (selectedIndex = i)}"
|
||||||
on:click={onClick} />
|
on:click="{onClick}" />
|
||||||
{/each}
|
{/each}
|
||||||
{#if !resultNotes.length && searchQuery}
|
{#if !resultNotes.length && searchQuery}
|
||||||
<center> We found 0 result for your search here. </center>
|
<div style="text-align: center;">
|
||||||
|
We found 0 result for your search here.
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</ModalContainer>
|
</ModalContainer>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="prompt-instructions">
|
<div class="prompt-instructions">
|
||||||
<div class="prompt-instruction">
|
<div class="prompt-instruction">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { App, Modal, TFile, Platform } from 'obsidian'
|
import { App, Modal, TFile } from 'obsidian'
|
||||||
import ModalVault from './components/ModalVault.svelte'
|
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'
|
||||||
@@ -6,14 +6,14 @@ import { settings } from './settings'
|
|||||||
import { get } from 'svelte/store'
|
import { get } from 'svelte/store'
|
||||||
|
|
||||||
abstract class OmnisearchModal extends Modal {
|
abstract class OmnisearchModal extends Modal {
|
||||||
constructor(app: App) {
|
protected constructor(app: App) {
|
||||||
super(app)
|
super(app)
|
||||||
|
|
||||||
// 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
|
||||||
const closeEl = this.containerEl.find('.modal-close-button')
|
// const closeEl = this.containerEl.find('.modal-close-button')
|
||||||
this.modalEl.replaceChildren()
|
this.modalEl.replaceChildren()
|
||||||
this.modalEl.append(closeEl)
|
// this.modalEl.append(closeEl)
|
||||||
this.modalEl.addClass('omnisearch-modal', 'prompt')
|
this.modalEl.addClass('omnisearch-modal', 'prompt')
|
||||||
// this.modalEl.removeClass('modal')
|
// this.modalEl.removeClass('modal')
|
||||||
this.modalEl.tabIndex = -1
|
this.modalEl.tabIndex = -1
|
||||||
|
|||||||
@@ -1,7 +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'
|
import { get, writable } from 'svelte/store'
|
||||||
|
|
||||||
interface WeightingSettings {
|
interface WeightingSettings {
|
||||||
weightBasename: number
|
weightBasename: number
|
||||||
@@ -17,6 +17,7 @@ export interface OmnisearchSettings extends WeightingSettings {
|
|||||||
ribbonIcon: boolean
|
ribbonIcon: boolean
|
||||||
showShortName: boolean
|
showShortName: boolean
|
||||||
showContext: boolean
|
showContext: boolean
|
||||||
|
showCreateButton: boolean
|
||||||
CtrlJK: boolean
|
CtrlJK: boolean
|
||||||
CtrlNP: boolean
|
CtrlNP: boolean
|
||||||
storeIndexInFile: boolean
|
storeIndexInFile: boolean
|
||||||
@@ -61,8 +62,7 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
const diacriticsDesc = new DocumentFragment()
|
const diacriticsDesc = new DocumentFragment()
|
||||||
diacriticsDesc.createSpan({}, span => {
|
diacriticsDesc.createSpan({}, span => {
|
||||||
span.innerHTML = `Normalize diacritics in search terms. Words like "brûlée" or "žluťoučký" will be indexed as "brulee" and "zlutoucky".<br/>
|
span.innerHTML = `Normalize diacritics in search terms. Words like "brûlée" or "žluťoučký" will be indexed as "brulee" and "zlutoucky".<br/>
|
||||||
<strong>Needs a restart to fully take effect.</strong>
|
<strong>Needs a restart to fully take effect.</strong>`
|
||||||
`
|
|
||||||
})
|
})
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName('Ignore diacritics')
|
.setName('Ignore diacritics')
|
||||||
@@ -77,6 +77,7 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Store index
|
||||||
const serializedIndexDesc = new DocumentFragment()
|
const serializedIndexDesc = new DocumentFragment()
|
||||||
serializedIndexDesc.createSpan({}, span => {
|
serializedIndexDesc.createSpan({}, span => {
|
||||||
span.innerHTML = `The search index is stored on disk, instead of being rebuilt at every startup.
|
span.innerHTML = `The search index is stored on disk, instead of being rebuilt at every startup.
|
||||||
@@ -91,8 +92,8 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
.setDesc(serializedIndexDesc)
|
.setDesc(serializedIndexDesc)
|
||||||
.addToggle(toggle =>
|
.addToggle(toggle =>
|
||||||
toggle.setValue(get(settings).storeIndexInFile).onChange(async v => {
|
toggle.setValue(get(settings).storeIndexInFile).onChange(async v => {
|
||||||
app.vault.adapter.remove(notesCacheFilePath)
|
await app.vault.adapter.remove(notesCacheFilePath)
|
||||||
app.vault.adapter.remove(searchIndexFilePath)
|
await app.vault.adapter.remove(searchIndexFilePath)
|
||||||
settings.update(s => {
|
settings.update(s => {
|
||||||
s.storeIndexInFile = v
|
s.storeIndexInFile = v
|
||||||
return s
|
return s
|
||||||
@@ -145,10 +146,29 @@ export class SettingsTab extends PluginSettingTab {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Show "Create note" button
|
||||||
|
const createBtnDesc = new DocumentFragment()
|
||||||
|
createBtnDesc.createSpan({}, span => {
|
||||||
|
span.innerHTML = `Shows a button next to the search input, to create a note.
|
||||||
|
Acts the same as the <code>shift ↵</code> shortcut, can be useful for mobile device users.`
|
||||||
|
})
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName('Show "Create note" button')
|
||||||
|
.setDesc(createBtnDesc)
|
||||||
|
.addToggle(toggle =>
|
||||||
|
toggle.setValue(get(settings).showCreateButton).onChange(async v => {
|
||||||
|
settings.update(s => {
|
||||||
|
s.showCreateButton = v
|
||||||
|
return s
|
||||||
|
})
|
||||||
|
await saveSettings(this.plugin)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
// Show notices
|
// Show notices
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName('Show indexing notices')
|
.setName('Show indexing notices')
|
||||||
.setDesc('Show a notice when indexing is done, usually at startup.')
|
.setDesc('Shows a notice when indexing is done, usually at startup.')
|
||||||
.addToggle(toggle =>
|
.addToggle(toggle =>
|
||||||
toggle.setValue(get(settings).showIndexingNotices).onChange(async v => {
|
toggle.setValue(get(settings).showIndexingNotices).onChange(async v => {
|
||||||
settings.update(s => {
|
settings.update(s => {
|
||||||
@@ -258,6 +278,7 @@ export const DEFAULT_SETTINGS: OmnisearchSettings = {
|
|||||||
showShortName: false,
|
showShortName: false,
|
||||||
ribbonIcon: true,
|
ribbonIcon: true,
|
||||||
showContext: true,
|
showContext: true,
|
||||||
|
showCreateButton: false,
|
||||||
|
|
||||||
weightBasename: 2,
|
weightBasename: 2,
|
||||||
weightH1: 1.5,
|
weightH1: 1.5,
|
||||||
|
|||||||
Reference in New Issue
Block a user