diff --git a/src/floatSearchIndex.ts b/src/floatSearchIndex.ts index 7e189f4..5f4bcb2 100644 --- a/src/floatSearchIndex.ts +++ b/src/floatSearchIndex.ts @@ -1,889 +1,889 @@ import { - addIcon, - App, - Editor, ExtraButtonComponent, - Menu, MenuItem, - Modal, OpenViewState, PaneType, - Plugin, SearchView, setIcon, - TAbstractFile, - TFile, - Workspace, - WorkspaceContainer, WorkspaceItem, - WorkspaceLeaf + addIcon, + App, + Editor, ExtraButtonComponent, + Menu, MenuItem, + Modal, OpenViewState, PaneType, + Plugin, SearchView, setIcon, + TAbstractFile, + TFile, + Workspace, + WorkspaceContainer, WorkspaceItem, + WorkspaceLeaf } from 'obsidian'; import { EmbeddedView, isEmebeddedLeaf, spawnLeafView } from "./leafView"; import { around } from "monkey-around"; type sortOrder = - "alphabetical" - | "alphabeticalReverse" - | "byModifiedTime" - | "byModifiedTimeReverse" - | "byCreatedTime" - | "byCreatedTimeReverse"; + "alphabetical" + | "alphabeticalReverse" + | "byModifiedTime" + | "byModifiedTimeReverse" + | "byCreatedTime" + | "byCreatedTimeReverse"; type searchType = "modal" | "sidebar" | PaneType; interface viewType { - type: searchType; - icon: string; + type: searchType; + icon: string; } interface searchState { - collapseAll?: boolean; - explainSearch?: boolean; - extraContext?: boolean; - matchingCase?: boolean; - query: string; - sortOrder?: sortOrder; - current?: boolean; + collapseAll?: boolean; + explainSearch?: boolean; + extraContext?: boolean; + matchingCase?: boolean; + query: string; + sortOrder?: sortOrder; + current?: boolean; } interface FloatSearchSettings { - searchViewState: searchState; + searchViewState: searchState; } const DEFAULT_SETTINGS: FloatSearchSettings = { - searchViewState: { - collapseAll: false, - explainSearch: false, - extraContext: false, - matchingCase: false, - query: "", - sortOrder: "alphabetical", - } + searchViewState: { + collapseAll: false, + explainSearch: false, + extraContext: false, + matchingCase: false, + query: "", + sortOrder: "alphabetical", + } } const allViews: viewType[] = [{ - type: "modal", - icon: "square-equal" + type: "modal", + icon: "square-equal" }, { - type: "sidebar", - icon: "panel-left-inactive" + type: "sidebar", + icon: "panel-left-inactive" }, { - type: "split", - icon: "split-square-horizontal" + type: "split", + icon: "split-square-horizontal" }, { - type: "tab", - icon: "panel-top" + type: "tab", + icon: "panel-top" }, { - type: "window", - icon: "app-window" + type: "window", + icon: "app-window" }]; const initSearchViewWithLeaf = async (app: App, type: PaneType | 'sidebar', state?: searchState) => { - const leaf = type === 'sidebar' ? app.workspace.getLeftLeaf(false) : app.workspace.getLeaf(type); - leaf.setPinned(type !== 'sidebar'); - await leaf.setViewState({ - type: "search", - active: true, - state: state - }); - setTimeout(() => { - const inputEl = leaf.containerEl.getElementsByTagName("input")[0]; - inputEl.focus(); - }, 0); + const leaf = type === 'sidebar' ? app.workspace.getLeftLeaf(false) : app.workspace.getLeaf(type); + leaf.setPinned(type !== 'sidebar'); + await leaf.setViewState({ + type: "search", + active: true, + state: state + }); + setTimeout(() => { + const inputEl = leaf.containerEl.getElementsByTagName("input")[0]; + inputEl.focus(); + }, 0); } export default class FloatSearchPlugin extends Plugin { - settings: FloatSearchSettings; - private state: any; - private modal: FloatSearchModal; + settings: FloatSearchSettings; + private state: any; + private modal: FloatSearchModal; - private applyStateDebounceTimer = 0; - private applySettingsDebounceTimer = 0; + private applyStateDebounceTimer = 0; + private applySettingsDebounceTimer = 0; - public applySettingsUpdate() { - clearTimeout(this.applySettingsDebounceTimer); - this.applySettingsDebounceTimer = window.setTimeout(async () => { - await this.saveSettings(); - }, 1000); - } + public applySettingsUpdate() { + clearTimeout(this.applySettingsDebounceTimer); + this.applySettingsDebounceTimer = window.setTimeout(async () => { + await this.saveSettings(); + }, 1000); + } - private applyStateUpdate() { - this.applyStateDebounceTimer = window.setTimeout(() => { - clearTimeout(this.applyStateDebounceTimer); - this.state = { - ...this.state, - query: "", - }; - }, 30000); - } + private applyStateUpdate() { + this.applyStateDebounceTimer = window.setTimeout(() => { + clearTimeout(this.applyStateDebounceTimer); + this.state = { + ...this.state, + query: "", + }; + }, 30000); + } - async onload() { - await this.loadSettings(); - this.initState(); - this.registerIcons(); + async onload() { + await this.loadSettings(); + this.initState(); + this.registerIcons(); - this.patchWorkspace(); - this.patchWorkspaceLeaf(); - this.patchSearchView(); + this.patchWorkspace(); + this.patchWorkspaceLeaf(); + this.patchSearchView(); - this.registerObsidianURIHandler(); - this.registerObsidianCommands(); - this.registerEditorMenuHandler(); - this.registerContextMenuHandler(); + this.registerObsidianURIHandler(); + this.registerObsidianCommands(); + this.registerEditorMenuHandler(); + this.registerContextMenuHandler(); - this.addRibbonIcon('search', 'Search Obsidian In Modal', () => this.initModal(this.state, true, true)); - } + this.addRibbonIcon('search', 'Search Obsidian In Modal', () => this.initModal(this.state, true, true)); + } - onunload() { - this.state = undefined; - this.modal?.close(); - } + onunload() { + this.state = undefined; + this.modal?.close(); + } - registerIcons() { - addIcon('panel-left-inactive', ``) - addIcon('app-window', ``); - addIcon('panel-top', ``); - addIcon('square-equal', ``); - } + registerIcons() { + addIcon('panel-left-inactive', ``) + addIcon('app-window', ``); + addIcon('panel-top', ``); + addIcon('square-equal', ``); + } - initState() { - this.state = this.settings.searchViewState as searchState; - } + initState() { + this.state = this.settings.searchViewState as searchState; + } - initModal(state: searchState, stateSave: boolean = false, clearQuery: boolean = false) { - this.modal = new FloatSearchModal((state) => { - this.state = state; - if (stateSave) this.applyStateUpdate(); - this.settings.searchViewState = state as searchState; - this.applySettingsUpdate(); - }, this, {...state, query: clearQuery ? "" : state.query}); - this.modal.open(); - } + initModal(state: searchState, stateSave: boolean = false, clearQuery: boolean = false) { + this.modal = new FloatSearchModal((state) => { + this.state = state; + if (stateSave) this.applyStateUpdate(); + this.settings.searchViewState = state as searchState; + this.applySettingsUpdate(); + }, this, {...state, query: clearQuery ? "" : state.query}); + this.modal.open(); + } - patchWorkspace() { - let layoutChanging = false; - const uninstaller = around(Workspace.prototype, { - getLeaf: (next) => - function (...args) { - const activeLeaf = this.activeLeaf; - if (activeLeaf && !activeLeaf.pinned) { - const fsCtnEl = (activeLeaf.parent?.containerEl as HTMLElement).parentElement; - if (fsCtnEl?.hasClass("fs-content")) { - if (activeLeaf.view.getViewType() === "markdown") { - return activeLeaf; - } - const newLeaf = app.workspace.getUnpinnedLeaf(); - if (newLeaf) { - this.setActiveLeaf(newLeaf); - } - } - return next.call(this); - } - return next.call(this, ...args); - }, - changeLayout(old) { - return async function (workspace: unknown) { - layoutChanging = true; - try { - // Don't consider hover popovers part of the workspace while it's changing - await old.call(this, workspace); - } finally { - layoutChanging = false; - } - }; - }, - iterateLeaves(old) { - type leafIterator = (item: WorkspaceLeaf) => boolean | void; - return function (arg1, arg2) { - // Fast exit if desired leaf found - if (old.call(this, arg1, arg2)) return true; + patchWorkspace() { + let layoutChanging = false; + const uninstaller = around(Workspace.prototype, { + getLeaf: (next) => + function (...args) { + const activeLeaf = this.activeLeaf; + if (activeLeaf) { + const fsCtnEl = (activeLeaf.parent?.containerEl as HTMLElement).parentElement; + if (fsCtnEl?.hasClass("fs-content")) { + if (activeLeaf.view.getViewType() === "markdown") { + return activeLeaf; + } + const newLeaf = app.workspace.getUnpinnedLeaf(); + if (newLeaf) { + this.setActiveLeaf(newLeaf); + } + } + return next.call(this); + } + return next.call(this, ...args); + }, + changeLayout(old) { + return async function (workspace: unknown) { + layoutChanging = true; + try { + // Don't consider hover popovers part of the workspace while it's changing + await old.call(this, workspace); + } finally { + layoutChanging = false; + } + }; + }, + iterateLeaves(old) { + type leafIterator = (item: WorkspaceLeaf) => boolean | void; + return function (arg1, arg2) { + // Fast exit if desired leaf found + if (old.call(this, arg1, arg2)) return true; - // Handle old/new API parameter swap - const cb: leafIterator = (typeof arg1 === "function" ? arg1 : arg2) as leafIterator; - const parent: WorkspaceItem = (typeof arg1 === "function" ? arg2 : arg1) as WorkspaceItem; + // Handle old/new API parameter swap + const cb: leafIterator = (typeof arg1 === "function" ? arg1 : arg2) as leafIterator; + const parent: WorkspaceItem = (typeof arg1 === "function" ? arg2 : arg1) as WorkspaceItem; - if (!parent) return false; // <- during app startup, rootSplit can be null - if (layoutChanging) return false; // Don't let HEs close during workspace change + if (!parent) return false; // <- during app startup, rootSplit can be null + if (layoutChanging) return false; // Don't let HEs close during workspace change - // 0.14.x doesn't have WorkspaceContainer; this can just be an instanceof check once 15.x is mandatory: - if (parent === app.workspace.rootSplit || (WorkspaceContainer && parent instanceof WorkspaceContainer)) { - for (const popover of EmbeddedView.popoversForWindow((parent as WorkspaceContainer).win)) { - // Use old API here for compat w/0.14.x - if (old.call(this, cb, popover.rootSplit)) return true; - } - } - return false; - }; - }, - onDragLeaf(old) { - return function (event: MouseEvent, leaf: WorkspaceLeaf) { - return old.call(this, event, leaf); - }; - }, - pushUndoHistory(old: any) { - return function (leaf: WorkspaceLeaf, id: string, ...args: any[]) { - const viewState = leaf.getViewState(); - if (viewState.type === "search") { - return; - } - return old.call(this, leaf, id, ...args); - }; - } - }); - this.register(uninstaller); - } + // 0.14.x doesn't have WorkspaceContainer; this can just be an instanceof check once 15.x is mandatory: + if (parent === app.workspace.rootSplit || (WorkspaceContainer && parent instanceof WorkspaceContainer)) { + for (const popover of EmbeddedView.popoversForWindow((parent as WorkspaceContainer).win)) { + // Use old API here for compat w/0.14.x + if (old.call(this, cb, popover.rootSplit)) return true; + } + } + return false; + }; + }, + onDragLeaf(old) { + return function (event: MouseEvent, leaf: WorkspaceLeaf) { + return old.call(this, event, leaf); + }; + }, + pushUndoHistory(old: any) { + return function (leaf: WorkspaceLeaf, id: string, ...args: any[]) { + const viewState = leaf.getViewState(); + if (viewState.type === "search") { + return; + } + return old.call(this, leaf, id, ...args); + }; + } + }); + this.register(uninstaller); + } - // Used for patch workspaceleaf pinned behaviors - patchWorkspaceLeaf() { - this.register( - around(WorkspaceLeaf.prototype, { - getRoot(old) { - return function () { - const top = old.call(this); - return top?.getRoot === this.getRoot ? top : top?.getRoot(); - }; - }, - setPinned(old) { - return function (pinned: boolean) { - old.call(this, pinned); - if (isEmebeddedLeaf(this) && !pinned) this.setPinned(true); - } - }, - openFile(old) { - return function (file: TFile, openState?: OpenViewState) { - if (isEmebeddedLeaf(this)) { - setTimeout( - around(Workspace.prototype, { - recordMostRecentOpenedFile(old) { - return function (_file: TFile) { - // Don't update the quick switcher's recent list - if (_file !== file) { - return old.call(this, _file); - } - }; - }, - }), - 1, - ); - const recentFiles = this.app.plugins.plugins["recent-files-obsidian"]; - if (recentFiles) { - setTimeout( - around(recentFiles, { - shouldAddFile(old) { - return function (_file: TFile) { - // Don't update the Recent Files plugin - return _file !== file && old.call(this, _file); - }; - }, - }), - 1, - ); - } + // Used for patch workspaceleaf pinned behaviors + patchWorkspaceLeaf() { + this.register( + around(WorkspaceLeaf.prototype, { + getRoot(old) { + return function () { + const top = old.call(this); + return top?.getRoot === this.getRoot ? top : top?.getRoot(); + }; + }, + setPinned(old) { + return function (pinned: boolean) { + old.call(this, pinned); + if (isEmebeddedLeaf(this) && !pinned) this.setPinned(true); + } + }, + openFile(old) { + return function (file: TFile, openState?: OpenViewState) { + if (isEmebeddedLeaf(this)) { + setTimeout( + around(Workspace.prototype, { + recordMostRecentOpenedFile(old) { + return function (_file: TFile) { + // Don't update the quick switcher's recent list + if (_file !== file) { + return old.call(this, _file); + } + }; + }, + }), + 1, + ); + const recentFiles = this.app.plugins.plugins["recent-files-obsidian"]; + if (recentFiles) { + setTimeout( + around(recentFiles, { + shouldAddFile(old) { + return function (_file: TFile) { + // Don't update the Recent Files plugin + return _file !== file && old.call(this, _file); + }; + }, + }), + 1, + ); + } - } + } - const view = old.call(this, file, openState); - setTimeout(() => { - const fsCtnEl = (this.parent.containerEl as HTMLElement).parentElement; - if (!(fsCtnEl?.classList.contains("fs-content"))) return; - if (file.extension != "canvas") return; + const view = old.call(this, file, openState); + setTimeout(() => { + const fsCtnEl = (this.parent.containerEl as HTMLElement).parentElement; + if (!(fsCtnEl?.classList.contains("fs-content"))) return; + if (file.extension != "canvas") return; - const canvas = this.view.canvas; - setTimeout(() => { - if (canvas && openState?.eState?.match) { - let node = canvas.data.nodes?.find((e: any) => e.text === openState.eState.match.content); - node = canvas.nodes.get(node.id); + const canvas = this.view.canvas; + setTimeout(() => { + if (canvas && openState?.eState?.match) { + let node = canvas.data.nodes?.find((e: any) => e.text === openState.eState.match.content); + node = canvas.nodes.get(node.id); - canvas.selectOnly(node); - canvas.zoomToSelection(); - } - }, 20); - }, 1); + canvas.selectOnly(node); + canvas.zoomToSelection(); + } + }, 20); + }, 1); - return view; - } - }, - }), - ); - } + return view; + } + }, + }), + ); + } - patchSearchView() { - const updateCurrentState = (state: searchState) => { - this.state = state; - this.settings.searchViewState = state as searchState; - this.applySettingsUpdate(); - } + patchSearchView() { + const updateCurrentState = (state: searchState) => { + this.state = state; + this.settings.searchViewState = state as searchState; + this.applySettingsUpdate(); + } - const checkCurrentViewType = (leaf: WorkspaceLeaf) => { - const isModal = document.querySelector('.float-search-modal') !== null; - const currentLeafRoot = leaf.getRoot(); - if (currentLeafRoot?.side && (currentLeafRoot?.side === "left" || currentLeafRoot?.side === 'right')) return "sidebar"; - if (leaf.getContainer()?.type === "window") return "window"; - return isModal ? "modal" : "split"; - } + const checkCurrentViewType = (leaf: WorkspaceLeaf) => { + const isModal = document.querySelector('.float-search-modal') !== null; + const currentLeafRoot = leaf.getRoot(); + if (currentLeafRoot?.side && (currentLeafRoot?.side === "left" || currentLeafRoot?.side === 'right')) return "sidebar"; + if (leaf.getContainer()?.type === "window") return "window"; + return isModal ? "modal" : "split"; + } - const initViewMenu = (menu: Menu, current: searchType, originLeaf?: WorkspaceLeaf) => { - menu.dom.toggleClass("float-search-view-menu", true); - let availableViews = allViews.filter((view) => { - if (current === "split") { - return view.type !== "tab"; - } else { - return view.type !== current; - } - }); - for (const view of availableViews) { - menu.addItem((item: MenuItem) => { - item.setTitle(`${view.type} view`).setIcon(`${view.icon}`).onClick(async () => { - if (view.type === "modal") { - originLeaf?.detach(); - setTimeout(() => { - this.initModal(this.state, true, false); - }, 10); - } else if (view.type === "sidebar") { - await initSearchViewWithLeaf(this.app, view.type, this.state); - } else { - if (current === "window") { - originLeaf?.detach(); - setTimeout(async () => { - await initSearchViewWithLeaf(this.app, <"tab" | "split">view.type, this.state); - }, 10); - } else { - await initSearchViewWithLeaf(this.app, view.type, this.state); - } + const initViewMenu = (menu: Menu, current: searchType, originLeaf?: WorkspaceLeaf) => { + menu.dom.toggleClass("float-search-view-menu", true); + let availableViews = allViews.filter((view) => { + if (current === "split") { + return view.type !== "tab"; + } else { + return view.type !== current; + } + }); + for (const view of availableViews) { + menu.addItem((item: MenuItem) => { + item.setTitle(`${view.type} view`).setIcon(`${view.icon}`).onClick(async () => { + if (view.type === "modal") { + originLeaf?.detach(); + setTimeout(() => { + this.initModal(this.state, true, false); + }, 10); + } else if (view.type === "sidebar") { + await initSearchViewWithLeaf(this.app, view.type, this.state); + } else { + if (current === "window") { + originLeaf?.detach(); + setTimeout(async () => { + await initSearchViewWithLeaf(this.app, <"tab" | "split">view.type, this.state); + }, 10); + } else { + await initSearchViewWithLeaf(this.app, view.type, this.state); + } - } - if (current === "modal") { - this.modal.close(); - } else { - originLeaf?.detach(); - } - }); - }); - } - return menu; - } + } + if (current === "modal") { + this.modal.close(); + } else { + originLeaf?.detach(); + } + }); + }); + } + return menu; + } - const patchSearch = () => { - const searchView = this.app.workspace.getLeavesOfType("search")[0]?.view as any; + const patchSearch = () => { + const searchView = this.app.workspace.getLeavesOfType("search")[0]?.view as any; - if (!searchView) return false; + if (!searchView) return false; - const searchViewConstructor = searchView.constructor; + const searchViewConstructor = searchView.constructor; - this.register( - around(searchViewConstructor.prototype, { - onOpen(old) { - return function () { - old.call(this); - const viewSwitchEl = createDiv({cls: "float-search-view-switch"}); - const targetEl = this.filterSectionToggleEl; - const viewSwitchButton = new ExtraButtonComponent(viewSwitchEl); - viewSwitchButton.setIcon('layout-template').setTooltip("Switch to File View"); - viewSwitchButton.onClick(() => { - const currentType = checkCurrentViewType(this.leaf); - const layoutMenu = initViewMenu(new Menu(), currentType, this.leaf); - const viewSwitchButtonPos = viewSwitchEl.getBoundingClientRect(); - layoutMenu.showAtPosition({x: viewSwitchButtonPos.x, y: viewSwitchButtonPos.y + 30}); - }); - targetEl.parentElement.insertBefore(viewSwitchEl, targetEl); - } - }, - startSearch(old) { - return function () { - old.call(this); - const viewState = this.getState(); - updateCurrentState({ - ...viewState, - query: this.searchComponent.getValue(), - }); - } - } - }) - ); - searchView.leaf?.rebuildView(); - console.log("Metadata-Style: all property view get patched"); - return true; - }; - this.app.workspace.onLayoutReady(() => { - if (!patchSearch()) { - const evt = this.app.workspace.on("layout-change", () => { - patchSearch() && this.app.workspace.offref(evt); - }); - this.registerEvent(evt); - } - }); - } + this.register( + around(searchViewConstructor.prototype, { + onOpen(old) { + return function () { + old.call(this); + const viewSwitchEl = createDiv({cls: "float-search-view-switch"}); + const targetEl = this.filterSectionToggleEl; + const viewSwitchButton = new ExtraButtonComponent(viewSwitchEl); + viewSwitchButton.setIcon('layout-template').setTooltip("Switch to File View"); + viewSwitchButton.onClick(() => { + const currentType = checkCurrentViewType(this.leaf); + const layoutMenu = initViewMenu(new Menu(), currentType, this.leaf); + const viewSwitchButtonPos = viewSwitchEl.getBoundingClientRect(); + layoutMenu.showAtPosition({x: viewSwitchButtonPos.x, y: viewSwitchButtonPos.y + 30}); + }); + targetEl.parentElement.insertBefore(viewSwitchEl, targetEl); + } + }, + startSearch(old) { + return function () { + old.call(this); + const viewState = this.getState(); + updateCurrentState({ + ...viewState, + query: this.searchComponent.getValue(), + }); + } + } + }) + ); + searchView.leaf?.rebuildView(); + console.log("Metadata-Style: all property view get patched"); + return true; + }; + this.app.workspace.onLayoutReady(() => { + if (!patchSearch()) { + const evt = this.app.workspace.on("layout-change", () => { + patchSearch() && this.app.workspace.offref(evt); + }); + this.registerEvent(evt); + } + }); + } - registerObsidianURIHandler() { - this.registerObsidianProtocolHandler("fs", (path) => this.initModal({ - ...this.state, - query: path.query, - current: false - }, true, true)); - } + registerObsidianURIHandler() { + this.registerObsidianProtocolHandler("fs", (path) => this.initModal({ + ...this.state, + query: path.query, + current: false + }, true, true)); + } - private createCommand(options: { - id: string; - name: string; - queryBuilder: (file: any) => string; - }): void { - this.addCommand({ - id: options.id, - name: options.name, - checkCallback: (checking: boolean) => { - const activeLeaf = this.app.workspace.activeLeaf; - if (!activeLeaf) return; + private createCommand(options: { + id: string; + name: string; + queryBuilder: (file: any) => string; + }): void { + this.addCommand({ + id: options.id, + name: options.name, + checkCallback: (checking: boolean) => { + const activeLeaf = this.app.workspace.activeLeaf; + if (!activeLeaf) return; - const viewType = activeLeaf.view.getViewType(); - if (viewType === "markdown" || viewType === "canvas") { - if (!checking) { - const currentFile = activeLeaf.view.file; - const query = options.queryBuilder(currentFile); - this.initModal({...this.state, query, current: true}, true, false); - } - return true; - } - } - }); - } + const viewType = activeLeaf.view.getViewType(); + if (viewType === "markdown" || viewType === "canvas") { + if (!checking) { + const currentFile = activeLeaf.view.file; + const query = options.queryBuilder(currentFile); + this.initModal({...this.state, query, current: true}, true, false); + } + return true; + } + } + }); + } - registerObsidianCommands() { - this.addCommand({ - id: 'search-obsidian-globally', - name: 'Search Obsidian Globally', - callback: () => this.initModal({...this.state, query: "", current: false}, false, true) - }); + registerObsidianCommands() { + this.addCommand({ + id: 'search-obsidian-globally', + name: 'Search Obsidian Globally', + callback: () => this.initModal({...this.state, query: "", current: false}, false, true) + }); - this.addCommand({ - id: 'search-obsidian-globally-state', - name: 'Search Obsidian Globally (With Last State)', - callback: () => this.initModal({...this.state, query: "", current: false}, true, false) - }); + this.addCommand({ + id: 'search-obsidian-globally-state', + name: 'Search Obsidian Globally (With Last State)', + callback: () => this.initModal({...this.state, query: "", current: false}, true, false) + }); - this.createCommand({ - id: 'search-in-backlink', - name: 'Search In Backlink Of Current File', - queryBuilder: (file) => { - return " /\\[\\[" + (file.extension === "canvas" ? file.name : file.basename) + "(\\|[^\\]]*)?\\]\\]/"; - } - }); + this.createCommand({ + id: 'search-in-backlink', + name: 'Search In Backlink Of Current File', + queryBuilder: (file) => { + return " /\\[\\[" + (file.extension === "canvas" ? file.name : file.basename) + "(\\|[^\\]]*)?\\]\\]/"; + } + }); - this.createCommand({ - id: 'search-in-current-file', - name: 'Search In Current File', - queryBuilder: (file) => { - return " path:" + `"${file.path}"`; - } - }); + this.createCommand({ + id: 'search-in-current-file', + name: 'Search In Current File', + queryBuilder: (file) => { + return " path:" + `"${file.path}"`; + } + }); - for (const type of ['split', 'tab', 'window'] as PaneType[]) { - this.addCommand({ - id: `open-search-view-${type}`, - name: `Open Search View (${type})`, - callback: async () => initSearchViewWithLeaf(this.app, type) - }); - } - } + for (const type of ['split', 'tab', 'window'] as PaneType[]) { + this.addCommand({ + id: `open-search-view-${type}`, + name: `Open Search View (${type})`, + callback: async () => initSearchViewWithLeaf(this.app, type) + }); + } + } - registerEditorMenuHandler() { - this.registerEvent( - this.app.workspace.on('editor-menu', (menu: Menu, editor: Editor) => { - if (!editor) { - return; - } - if (editor.getSelection().length === 0) { - return; - } - const selection = editor.getSelection().trim(); - let searchWord = selection; + registerEditorMenuHandler() { + this.registerEvent( + this.app.workspace.on('editor-menu', (menu: Menu, editor: Editor) => { + if (!editor) { + return; + } + if (editor.getSelection().length === 0) { + return; + } + const selection = editor.getSelection().trim(); + let searchWord = selection; - if (selection.length > 8) { - searchWord = selection.substring(0, 3) + "..." + selection.substring(selection.length - 3, selection.length); - } else { - searchWord = selection; - } + if (selection.length > 8) { + searchWord = selection.substring(0, 3) + "..." + selection.substring(selection.length - 3, selection.length); + } else { + searchWord = selection; + } - menu.addItem((item) => { - // Add sub menu - item.setTitle('Search "' + searchWord + '"' + " in Float Search").setIcon("search") - .onClick(() => this.initModal({...this.state, query: selection, current: false}, true, false)) - }) - })) - } + menu.addItem((item) => { + // Add sub menu + item.setTitle('Search "' + searchWord + '"' + " in Float Search").setIcon("search") + .onClick(() => this.initModal({...this.state, query: selection, current: false}, true, false)) + }) + })) + } - registerContextMenuHandler() { - this.registerEvent( - this.app.workspace.on("file-menu", (menu: Menu, file: TAbstractFile, source: string, leaf?: WorkspaceLeaf) => { - const popover = leaf ? EmbeddedView.forLeaf(leaf) : undefined; - if (file instanceof TFile && !popover && !leaf) { - menu.addItem(item => { - item - .setIcon("popup-open") - .setTitle("Open in Float Preview") - .onClick(async () => { - if (this.modal) { - await this.modal.initFileView(file, undefined); + registerContextMenuHandler() { + this.registerEvent( + this.app.workspace.on("file-menu", (menu: Menu, file: TAbstractFile, source: string, leaf?: WorkspaceLeaf) => { + const popover = leaf ? EmbeddedView.forLeaf(leaf) : undefined; + if (file instanceof TFile && !popover && !leaf) { + menu.addItem(item => { + item + .setIcon("popup-open") + .setTitle("Open in Float Preview") + .onClick(async () => { + if (this.modal) { + await this.modal.initFileView(file, undefined); - return; - } + return; + } - this.initModal({...this.state, current: false}, true, true); - setTimeout(async () => { - await this.modal.initFileView(file, undefined); - }, 20); - }) - .setSection?.("open"); - }); - } - }), - ); - } + this.initModal({...this.state, current: false}, true, true); + setTimeout(async () => { + await this.modal.initFileView(file, undefined); + }, 20); + }) + .setSection?.("open"); + }); + } + }), + ); + } - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + } - async saveSettings() { - await this.saveData(this.settings); - } + async saveSettings() { + await this.saveData(this.settings); + } } class FloatSearchModal extends Modal { - private readonly plugin: FloatSearchPlugin; - private searchEmbeddedView: EmbeddedView; - private fileEmbeddedView: EmbeddedView; + private readonly plugin: FloatSearchPlugin; + private searchEmbeddedView: EmbeddedView; + private fileEmbeddedView: EmbeddedView; - searchLeaf: WorkspaceLeaf; - fileLeaf: WorkspaceLeaf | undefined; + searchLeaf: WorkspaceLeaf; + fileLeaf: WorkspaceLeaf | undefined; - private cb: (state: any) => void; - private state: any; + private cb: (state: any) => void; + private state: any; - private fileState: any; + private fileState: any; - private searchCtnEl: HTMLElement; - private instructionsEl: HTMLElement; - private fileEl: HTMLElement; - private viewType: string; + private searchCtnEl: HTMLElement; + private instructionsEl: HTMLElement; + private fileEl: HTMLElement; + private viewType: string; - constructor(cb: (state: any) => void, plugin: FloatSearchPlugin, state: any, viewType: string = "search") { - super(plugin.app); - this.plugin = plugin; - this.cb = cb; - this.state = state; - this.viewType = viewType; - } + constructor(cb: (state: any) => void, plugin: FloatSearchPlugin, state: any, viewType: string = "search") { + super(plugin.app); + this.plugin = plugin; + this.cb = cb; + this.state = state; + this.viewType = viewType; + } - async onOpen() { - const {contentEl, containerEl, modalEl} = this; + async onOpen() { + const {contentEl, containerEl, modalEl} = this; - this.searchCtnEl = contentEl.createDiv({cls: "float-search-modal-search-ctn"}); - this.instructionsEl = modalEl.createDiv({cls: "float-search-modal-instructions"}); + this.searchCtnEl = contentEl.createDiv({cls: "float-search-modal-search-ctn"}); + this.instructionsEl = modalEl.createDiv({cls: "float-search-modal-instructions"}); - this.initInstructions(this.instructionsEl); - this.initCss(contentEl, modalEl, containerEl); - await this.initSearchView(this.searchCtnEl); - this.initInput(); - this.initContent(); - } + this.initInstructions(this.instructionsEl); + this.initCss(contentEl, modalEl, containerEl); + await this.initSearchView(this.searchCtnEl); + this.initInput(); + this.initContent(); + } - onClose() { - const {contentEl} = this; + onClose() { + const {contentEl} = this; - this.cb(this.searchLeaf.view.getState()); + this.cb(this.searchLeaf.view.getState()); - this.searchLeaf.detach(); - this.fileLeaf?.detach(); - this.searchEmbeddedView.unload(); - this.fileEmbeddedView?.unload(); - contentEl.empty(); - } + this.searchLeaf.detach(); + this.fileLeaf?.detach(); + this.searchEmbeddedView.unload(); + this.fileEmbeddedView?.unload(); + contentEl.empty(); + } - initInstructions(instructionsEl: HTMLElement) { - const navigateInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-navigate"}); - const collapseInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-collapse"}); - const enterInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-enter"}); - const altEnterInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-alt-enter"}); + initInstructions(instructionsEl: HTMLElement) { + const navigateInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-navigate"}); + const collapseInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-collapse"}); + const enterInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-enter"}); + const altEnterInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-alt-enter"}); - const tabInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-tab"}); - const switchInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-switch"}); + const tabInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-tab"}); + const switchInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-switch"}); - const navigateIconEl = navigateInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); - const navigateTextEl = navigateInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); - navigateIconEl.setText("↑↓"); - navigateTextEl.setText("Navigate"); + const navigateIconEl = navigateInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); + const navigateTextEl = navigateInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); + navigateIconEl.setText("↑↓"); + navigateTextEl.setText("Navigate"); - const collapseIconEl = collapseInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); - const collapseTextEl = collapseInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); - collapseIconEl.setText("Shift+↑↓"); - collapseTextEl.setText("Collapse/Expand"); + const collapseIconEl = collapseInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); + const collapseTextEl = collapseInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); + collapseIconEl.setText("Shift+↑↓"); + collapseTextEl.setText("Collapse/Expand"); - const enterIconEl = enterInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); - const enterTextEl = enterInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); - enterIconEl.setText("↵"); - enterTextEl.setText("Open in background"); + const enterIconEl = enterInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); + const enterTextEl = enterInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); + enterIconEl.setText("↵"); + enterTextEl.setText("Open in background"); - const altEnterIconEl = altEnterInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); - const altEnterTextEl = altEnterInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); - altEnterIconEl.setText("Alt+↵"); - altEnterTextEl.setText("Open File and Close"); + const altEnterIconEl = altEnterInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); + const altEnterTextEl = altEnterInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); + altEnterIconEl.setText("Alt+↵"); + altEnterTextEl.setText("Open File and Close"); - const tabIconEl = tabInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); - const tabTextEl = tabInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); - tabIconEl.setText("Tab/Shift+Tab"); - tabTextEl.setText("Preview/Close Preview"); + const tabIconEl = tabInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); + const tabTextEl = tabInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); + tabIconEl.setText("Tab/Shift+Tab"); + tabTextEl.setText("Preview/Close Preview"); - const switchIconEl = switchInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); - const switchTextEl = switchInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); - switchIconEl.setText("Ctrl+G"); - switchTextEl.setText("Switch Between Search and File View"); + const switchIconEl = switchInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); + const switchTextEl = switchInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); + switchIconEl.setText("Ctrl+G"); + switchTextEl.setText("Switch Between Search and File View"); - const clickInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-click"}); - const clickIconEl = clickInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); - const clickTextEl = clickInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); - clickIconEl.setText("Alt+Click"); - clickTextEl.setText("Close Modal While In File View"); - } + const clickInstructionsEl = instructionsEl.createDiv({cls: "float-search-modal-instructions-click"}); + const clickIconEl = clickInstructionsEl.createSpan({cls: "float-search-modal-instructions-key"}); + const clickTextEl = clickInstructionsEl.createSpan({cls: "float-search-modal-instructions-text"}); + clickIconEl.setText("Alt+Click"); + clickTextEl.setText("Close Modal While In File View"); + } - initCss(contentEl: HTMLElement, modalEl: HTMLElement, containerEl: HTMLElement) { - contentEl.classList.add("float-search-modal-content"); - modalEl.classList.add("float-search-modal"); - containerEl.classList.add("float-search-modal-container"); - } + initCss(contentEl: HTMLElement, modalEl: HTMLElement, containerEl: HTMLElement) { + contentEl.classList.add("float-search-modal-content"); + modalEl.classList.add("float-search-modal"); + containerEl.classList.add("float-search-modal-container"); + } - async initSearchView(contentEl: HTMLElement) { - const [createdLeaf, embeddedView] = spawnLeafView(this.plugin, contentEl); - this.searchLeaf = createdLeaf; - this.searchEmbeddedView = embeddedView; + async initSearchView(contentEl: HTMLElement) { + const [createdLeaf, embeddedView] = spawnLeafView(this.plugin, contentEl); + this.searchLeaf = createdLeaf; + this.searchEmbeddedView = embeddedView; - this.searchLeaf.setPinned(true); - await this.searchLeaf.setViewState({ - type: "search", - }); + this.searchLeaf.setPinned(true); + await this.searchLeaf.setViewState({ + type: "search", + }); - setTimeout(async () => { - await this.searchLeaf.view.setState(this.state, true); - this.state?.current ? (this.searchLeaf.view as SearchView).searchComponent.inputEl.setSelectionRange(0, 0) : (this.searchLeaf.view as SearchView).searchComponent.inputEl.setSelectionRange(0, this.state?.query?.length); - }, 0); + setTimeout(async () => { + await this.searchLeaf.view.setState(this.state, true); + this.state?.current ? (this.searchLeaf.view as SearchView).searchComponent.inputEl.setSelectionRange(0, 0) : (this.searchLeaf.view as SearchView).searchComponent.inputEl.setSelectionRange(0, this.state?.query?.length); + }, 0); - return; - } + return; + } - initInput() { - const inputEl = this.contentEl.getElementsByTagName("input")[0]; - inputEl.focus(); - inputEl.onkeydown = (e) => { - const currentView = this.searchLeaf.view as SearchView; - switch (e.key) { - case "ArrowDown": - if (e.shiftKey) { - currentView.onKeyShowMoreAfter(e); - if (currentView.dom.focusedItem) { - if (currentView.dom.focusedItem.collapsible) { - currentView.dom.focusedItem.setCollapse(false); - } - } - break; - } else { - currentView.onKeyArrowDownInFocus(e); - break; - } - case "ArrowUp": - if (e.shiftKey) { - currentView.onKeyShowMoreBefore(e); - if (currentView.dom.focusedItem) { - if (currentView.dom.focusedItem.collapseEl) { - currentView.dom.focusedItem.setCollapse(true); - } - } - break; - } else { - currentView.onKeyArrowUpInFocus(e); - break; - } - case "ArrowLeft": - currentView.onKeyArrowLeftInFocus(e); - break; - case "ArrowRight": - currentView.onKeyArrowRightInFocus(e); - break; - case "Enter": - currentView.onKeyEnterInFocus(e); - if (e.altKey && currentView.dom.focusedItem) { - this.close(); - } - break; - case "Tab": - e.preventDefault(); - if (e.shiftKey) { - if (this.fileLeaf) { - this.fileLeaf?.detach(); - this.fileLeaf = undefined; - this.fileEmbeddedView?.unload(); - this.modalEl.toggleClass("float-search-width", false); - this.fileEl.detach(); + initInput() { + const inputEl = this.contentEl.getElementsByTagName("input")[0]; + inputEl.focus(); + inputEl.onkeydown = (e) => { + const currentView = this.searchLeaf.view as SearchView; + switch (e.key) { + case "ArrowDown": + if (e.shiftKey) { + currentView.onKeyShowMoreAfter(e); + if (currentView.dom.focusedItem) { + if (currentView.dom.focusedItem.collapsible) { + currentView.dom.focusedItem.setCollapse(false); + } + } + break; + } else { + currentView.onKeyArrowDownInFocus(e); + break; + } + case "ArrowUp": + if (e.shiftKey) { + currentView.onKeyShowMoreBefore(e); + if (currentView.dom.focusedItem) { + if (currentView.dom.focusedItem.collapseEl) { + currentView.dom.focusedItem.setCollapse(true); + } + } + break; + } else { + currentView.onKeyArrowUpInFocus(e); + break; + } + case "ArrowLeft": + currentView.onKeyArrowLeftInFocus(e); + break; + case "ArrowRight": + currentView.onKeyArrowRightInFocus(e); + break; + case "Enter": + currentView.onKeyEnterInFocus(e); + if (e.altKey && currentView.dom.focusedItem) { + this.close(); + } + break; + case "Tab": + e.preventDefault(); + if (e.shiftKey) { + if (this.fileLeaf) { + this.fileLeaf?.detach(); + this.fileLeaf = undefined; + this.fileEmbeddedView?.unload(); + this.modalEl.toggleClass("float-search-width", false); + this.fileEl.detach(); - break; - } - } + break; + } + } - if (currentView.dom.focusedItem) { - const item = currentView.dom.focusedItem; - const file = item.parent.file instanceof TFile ? item.parent.file : item.file; + if (currentView.dom.focusedItem) { + const item = currentView.dom.focusedItem; + const file = item.parent.file instanceof TFile ? item.parent.file : item.file; - item.parent.file instanceof TFile ? this.initFileView(file, { - match: { - content: item.content, - matches: item.matches - } - }) : this.initFileView(file, undefined); - } - break; - case "e": - if (e.ctrlKey) { - e.preventDefault(); - if (this.fileLeaf) { - const estate = this.fileLeaf.getViewState(); - estate.state.mode = "preview" === estate.state.mode ? "source" : "preview"; - this.fileLeaf.setViewState(estate, { - focus: !0 - }); - setTimeout(() => { - (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); - }, 0); - } - } - break; - case "g": - if (this.fileLeaf && e.ctrlKey) { - e.preventDefault(); - this.plugin.app.workspace.setActiveLeaf(this.fileLeaf, { - focus: true, - }); - } - break; - case "C": - if (e.ctrlKey && e.shiftKey) { - e.preventDefault(); - const text = currentView.dom.focusedItem.el.innerText; - navigator.clipboard.writeText(text); - } - break; + item.parent.file instanceof TFile ? this.initFileView(file, { + match: { + content: item.content, + matches: item.matches + } + }) : this.initFileView(file, undefined); + } + break; + case "e": + if (e.ctrlKey) { + e.preventDefault(); + if (this.fileLeaf) { + const estate = this.fileLeaf.getViewState(); + estate.state.mode = "preview" === estate.state.mode ? "source" : "preview"; + this.fileLeaf.setViewState(estate, { + focus: !0 + }); + setTimeout(() => { + (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); + }, 0); + } + } + break; + case "g": + if (this.fileLeaf && e.ctrlKey) { + e.preventDefault(); + this.plugin.app.workspace.setActiveLeaf(this.fileLeaf, { + focus: true, + }); + } + break; + case "C": + if (e.ctrlKey && e.shiftKey) { + e.preventDefault(); + const text = currentView.dom.focusedItem.el.innerText; + navigator.clipboard.writeText(text); + } + break; - } - } - } + } + } + } - initContent() { - const {contentEl} = this; - contentEl.onclick = (e) => { - const resultElement = contentEl.getElementsByClassName('search-results-children')[0]; - if (resultElement.children.length < 2) { - return; - } + initContent() { + const {contentEl} = this; + contentEl.onclick = (e) => { + const resultElement = contentEl.getElementsByClassName('search-results-children')[0]; + if (resultElement.children.length < 2) { + return; + } - let targetElement = e.target as HTMLElement | null; + let targetElement = e.target as HTMLElement | null; - if (e.altKey || !this.fileLeaf) { - while (targetElement) { - if (targetElement.classList.contains('tree-item-icon')) { - break; - } - if (targetElement.classList.contains('tree-item')) { - this.close(); - break; - } - targetElement = targetElement.parentElement; - } - return; - } + if (e.altKey || !this.fileLeaf) { + while (targetElement) { + if (targetElement.classList.contains('tree-item-icon')) { + break; + } + if (targetElement.classList.contains('tree-item')) { + this.close(); + break; + } + targetElement = targetElement.parentElement; + } + return; + } - if (this.fileLeaf) { - const currentView = this.searchLeaf.view as SearchView; + if (this.fileLeaf) { + const currentView = this.searchLeaf.view as SearchView; - if ((this.searchCtnEl as Node).contains(targetElement as Node)) { - while (targetElement) { - if (targetElement.classList.contains('tree-item')) { - break; - } - targetElement = targetElement.parentElement; - } - if (!targetElement) return; + if ((this.searchCtnEl as Node).contains(targetElement as Node)) { + while (targetElement) { + if (targetElement.classList.contains('tree-item')) { + break; + } + targetElement = targetElement.parentElement; + } + if (!targetElement) return; - const fileInnerEl = targetElement?.getElementsByClassName("tree-item-inner")[0] as HTMLElement; - const innerText = fileInnerEl.innerText; - const file = this.plugin.app.metadataCache.getFirstLinkpathDest(innerText, ""); + const fileInnerEl = targetElement?.getElementsByClassName("tree-item-inner")[0] as HTMLElement; + const innerText = fileInnerEl.innerText; + const file = this.plugin.app.metadataCache.getFirstLinkpathDest(innerText, ""); - if (file) { - const item = currentView.dom.resultDomLookup.get(file); - currentView.dom.setFocusedItem(item); - this.initFileView(file, undefined); - (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); - } - } + if (file) { + const item = currentView.dom.resultDomLookup.get(file); + currentView.dom.setFocusedItem(item); + this.initFileView(file, undefined); + (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); + } + } - return; - } - } - } + return; + } + } + } - async initFileView(file: TFile, state: any) { - if (this.fileLeaf) { - await this.fileLeaf.openFile(file, { - active: false, - eState: state - }); + async initFileView(file: TFile, state: any) { + if (this.fileLeaf) { + await this.fileLeaf.openFile(file, { + active: false, + eState: state + }); - if (this.fileState?.match?.matches[0] === state?.match?.matches[0] && state && this.fileState) { - setTimeout(() => { - if (this.fileLeaf) { - this.plugin.app.workspace.setActiveLeaf(this.fileLeaf, { - focus: true, - }); - } - }, 0); - } else { - this.fileState = state; - setTimeout(() => { - (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); - }, 0); - } + if (this.fileState?.match?.matches[0] === state?.match?.matches[0] && state && this.fileState) { + setTimeout(() => { + if (this.fileLeaf) { + this.plugin.app.workspace.setActiveLeaf(this.fileLeaf, { + focus: true, + }); + } + }, 0); + } else { + this.fileState = state; + setTimeout(() => { + (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); + }, 0); + } - return; - } + return; + } - const {contentEl} = this; - this.fileEl = contentEl.createDiv({cls: "float-search-modal-file-ctn"}); - this.modalEl.toggleClass("float-search-width", true); - this.fileEl.onkeydown = (e) => { - if (e.ctrlKey && e.key === "g") { - e.preventDefault(); - e.stopPropagation(); + const {contentEl} = this; + this.fileEl = contentEl.createDiv({cls: "float-search-modal-file-ctn"}); + this.modalEl.toggleClass("float-search-width", true); + this.fileEl.onkeydown = (e) => { + if (e.ctrlKey && e.key === "g") { + e.preventDefault(); + e.stopPropagation(); - (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); - } + (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); + } - if (e.key === "Tab" && e.ctrlKey) { - e.preventDefault(); - e.stopPropagation(); + if (e.key === "Tab" && e.ctrlKey) { + e.preventDefault(); + e.stopPropagation(); - (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); - } - } + (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); + } + } - if (!this.fileEl) return; + if (!this.fileEl) return; - const [createdLeaf, embeddedView] = spawnLeafView(this.plugin, this.fileEl); - this.fileLeaf = createdLeaf; - this.fileEmbeddedView = embeddedView; + const [createdLeaf, embeddedView] = spawnLeafView(this.plugin, this.fileEl); + this.fileLeaf = createdLeaf; + this.fileEmbeddedView = embeddedView; - this.fileLeaf.setPinned(true); - await this.fileLeaf.openFile(file, { - active: false, - eState: state - }); - this.fileState = state; + this.fileLeaf.setPinned(true); + await this.fileLeaf.openFile(file, { + active: false, + eState: state + }); + this.fileState = state; - (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); + (this.searchLeaf.view as SearchView).searchComponent.inputEl.focus(); - } + } }