Open in a new tab
This commit is contained in:
@@ -42,5 +42,6 @@ module.exports = {
|
|||||||
asyncArrow: 'always',
|
asyncArrow: 'always',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
'no-new': ['off'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.osresult__name {
|
.osresult__name {
|
||||||
padding-left: 1em;
|
padding-right: .5em;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
color: var(--text-normal);
|
||||||
/* color: var(--text-muted);
|
/* color: var(--text-muted);
|
||||||
text-decoration: underline; */
|
text-decoration: underline; */
|
||||||
}
|
}
|
||||||
|
|||||||
90
src/main.ts
90
src/main.ts
@@ -1,8 +1,8 @@
|
|||||||
import { Plugin, SuggestModal } from 'obsidian'
|
import { Notice, Plugin, SuggestModal } from 'obsidian'
|
||||||
import MiniSearch from 'minisearch'
|
import MiniSearch from 'minisearch'
|
||||||
import removeMarkdown from 'remove-markdown'
|
import removeMarkdown from 'remove-markdown'
|
||||||
|
|
||||||
type Note = {
|
type OmniNote = {
|
||||||
path: string
|
path: string
|
||||||
name: string
|
name: string
|
||||||
title: string
|
title: string
|
||||||
@@ -11,13 +11,14 @@ type Note = {
|
|||||||
|
|
||||||
const regexWikilink = /\[\[(?<name>.+?)(\|(?<alias>.+?))?\]\]/g
|
const regexWikilink = /\[\[(?<name>.+?)(\|(?<alias>.+?))?\]\]/g
|
||||||
const regexEmbed = /!\[\[.+?\]\]/g
|
const regexEmbed = /!\[\[.+?\]\]/g
|
||||||
|
const regexYaml = /^---\s*\n(.*?)\n?^---\s?/ms
|
||||||
|
|
||||||
export default class OmnisearchPlugin extends Plugin {
|
export default class OmnisearchPlugin extends Plugin {
|
||||||
minisearch: MiniSearch<Note>
|
minisearch: MiniSearch<OmniNote>
|
||||||
lastSearch?: string
|
lastSearch?: string
|
||||||
|
|
||||||
async instantiateMinisearch(): Promise<void> {
|
async instantiateMinisearch(): Promise<void> {
|
||||||
this.minisearch = new MiniSearch<Note>({
|
this.minisearch = new MiniSearch<OmniNote>({
|
||||||
idField: 'path',
|
idField: 'path',
|
||||||
fields: ['body', 'title', 'name'],
|
fields: ['body', 'title', 'name'],
|
||||||
storeFields: ['body', 'title', 'name'],
|
storeFields: ['body', 'title', 'name'],
|
||||||
@@ -42,7 +43,14 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
|
|
||||||
async onload(): Promise<void> {
|
async onload(): Promise<void> {
|
||||||
this.app.workspace.onLayoutReady(async () => {
|
this.app.workspace.onLayoutReady(async () => {
|
||||||
|
const start = new Date()
|
||||||
await this.instantiateMinisearch()
|
await this.instantiateMinisearch()
|
||||||
|
new Notice(
|
||||||
|
`Omnisearch - files indexed in ${
|
||||||
|
new Date().getTime() - start.getTime()
|
||||||
|
} ms`,
|
||||||
|
3000,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
@@ -56,8 +64,10 @@ export default class OmnisearchPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OmnisearchModal extends SuggestModal<Note> {
|
class OmnisearchModal extends SuggestModal<OmniNote> {
|
||||||
plugin: OmnisearchPlugin
|
private plugin: OmnisearchPlugin
|
||||||
|
private selectedNoteId?: string
|
||||||
|
private mutationObserver?: MutationObserver
|
||||||
|
|
||||||
constructor(plugin: OmnisearchPlugin) {
|
constructor(plugin: OmnisearchPlugin) {
|
||||||
super(plugin.app)
|
super(plugin.app)
|
||||||
@@ -74,8 +84,46 @@ class OmnisearchModal extends SuggestModal<Note> {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onKeydown(ev: KeyboardEvent): void {
|
||||||
|
const noteId = this.selectedNoteId
|
||||||
|
if (ev.key !== 'Enter' || !noteId) return
|
||||||
|
|
||||||
|
if (ev.ctrlKey) {
|
||||||
|
// Open in a new pane
|
||||||
|
this.app.workspace.openLinkText(noteId, '', true)
|
||||||
|
}
|
||||||
|
else if (ev.shiftKey) {
|
||||||
|
// Create a note
|
||||||
|
}
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observes the modal element to keep track of which search result is currently selected
|
||||||
|
* @param modalEl
|
||||||
|
*/
|
||||||
|
setupObserver(modalEl: HTMLElement): void {
|
||||||
|
this.mutationObserver = new MutationObserver(events => {
|
||||||
|
const record = events.find(event =>
|
||||||
|
(event.target as HTMLDivElement).classList.contains('is-selected'),
|
||||||
|
)
|
||||||
|
const id = (record?.target as HTMLElement).getAttribute('data-note-id')
|
||||||
|
if (id) {
|
||||||
|
this.selectedNoteId = id
|
||||||
|
console.log('saved note ' + id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.mutationObserver.observe(modalEl, {
|
||||||
|
attributes: true,
|
||||||
|
subtree: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onOpen(): void {
|
onOpen(): void {
|
||||||
this.inputEl.focus()
|
this.inputEl.focus()
|
||||||
|
this.setupObserver(this.modalEl)
|
||||||
|
|
||||||
|
// Reload last search, if any
|
||||||
if (this.plugin.lastSearch) {
|
if (this.plugin.lastSearch) {
|
||||||
const event = new Event('input', {
|
const event = new Event('input', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
@@ -85,9 +133,15 @@ class OmnisearchModal extends SuggestModal<Note> {
|
|||||||
this.inputEl.dispatchEvent(event)
|
this.inputEl.dispatchEvent(event)
|
||||||
this.inputEl.select()
|
this.inputEl.select()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.inputEl.onkeydown = this.onKeydown.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
getSuggestions(query: string): Note[] {
|
onClose(): void {
|
||||||
|
this.mutationObserver.disconnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
getSuggestions(query: string): OmniNote[] {
|
||||||
console.log('query: ' + query)
|
console.log('query: ' + query)
|
||||||
this.plugin.lastSearch = query
|
this.plugin.lastSearch = query
|
||||||
|
|
||||||
@@ -138,23 +192,28 @@ class OmnisearchModal extends SuggestModal<Note> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSuggestion(value: Note, el: HTMLElement): void {
|
renderSuggestion(value: OmniNote, el: HTMLElement): void {
|
||||||
|
el.setAttribute('data-note-id', value.path)
|
||||||
// title
|
// title
|
||||||
const title = el.createEl('div', { cls: 'osresult__title' })
|
const title = el.createEl('div', { cls: 'osresult__title' })
|
||||||
title.innerHTML = value.title
|
title.innerHTML = value.title
|
||||||
|
|
||||||
// filename
|
// filename
|
||||||
const name = el.createEl('span', { cls: 'osresult__name' })
|
const name = document.createElement('span')
|
||||||
|
name.className = 'osresult__name'
|
||||||
name.innerHTML = value.name
|
name.innerHTML = value.name
|
||||||
title.appendChild(name)
|
|
||||||
|
|
||||||
// body
|
// body
|
||||||
const body = el.createEl('div', { cls: 'osresult__body' })
|
const body = document.createElement('span')
|
||||||
body.innerHTML = value.body
|
body.innerHTML = value.body
|
||||||
|
|
||||||
|
// body container
|
||||||
|
const bodyContainer = el.createEl('div', { cls: 'osresult__body' })
|
||||||
|
bodyContainer.appendChild(name)
|
||||||
|
bodyContainer.appendChild(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
onChooseSuggestion(item: Note, evt: MouseEvent | KeyboardEvent): void {
|
onChooseSuggestion(item: OmniNote): void {
|
||||||
// this.app.workspace
|
|
||||||
this.app.workspace.openLinkText(item.path, '')
|
this.app.workspace.openLinkText(item.path, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,7 +248,7 @@ function removeFirstLine(text: string): string {
|
|||||||
// https://stackoverflow.com/questions/2528076/delete-a-line-of-text-in-javascript
|
// https://stackoverflow.com/questions/2528076/delete-a-line-of-text-in-javascript
|
||||||
const lines = splitLines(text.trim())
|
const lines = splitLines(text.trim())
|
||||||
lines.splice(0, 1)
|
lines.splice(0, 1)
|
||||||
return lines.join('\n')
|
return lines.join('.')
|
||||||
}
|
}
|
||||||
|
|
||||||
function splitLines(text: string): string[] {
|
function splitLines(text: string): string[] {
|
||||||
@@ -198,6 +257,5 @@ function splitLines(text: string): string[] {
|
|||||||
|
|
||||||
function removeFrontMatter(text: string): string {
|
function removeFrontMatter(text: string): string {
|
||||||
// Regex to recognize YAML Front Matter (at beginning of file, 3 hyphens, than any charecter, including newlines, then 3 hyphens).
|
// Regex to recognize YAML Front Matter (at beginning of file, 3 hyphens, than any charecter, including newlines, then 3 hyphens).
|
||||||
const YAMLFrontMatter = /^---\s*\n(.*?)\n?^---\s?/ms
|
return text.replace(regexYaml, '')
|
||||||
return text.replace(YAMLFrontMatter, '')
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user