Compare commits

...

20 commits

Author SHA1 Message Date
Quorafind
16fcf917a6 chore: update for version.json 2026-03-23 16:39:37 +08:00
Quorafind
fd4bf87a1f chore: update version spec 2026-03-19 09:39:16 +08:00
Quorafind
1e1ee35f9d chore: bump version to 4.3.0 2026-03-18 16:48:35 +08:00
Quorafind
e3201d9ed6 feat(cmdk): add content search and preview scroll-to-position
Add Phase 3 progressive content search to CMDK modal using
prepareSimpleSearch API for substring matching (CJK-friendly).
Uses adaptive yielding (5ms threshold) and offset-based line
computation to avoid costly line splitting.

Also fix preview scroll: pass full result to showPreview so
heading and content results navigate to correct position via
setViewState + setEphemeralState.
2026-03-18 16:47:57 +08:00
Quorafind
8cb09f6345 chore: bump version to 4.2.0 2026-03-17 14:55:15 +08:00
Quorafind
e1b2a6e2db chore: bump version to 4.2.0 2026-03-17 14:55:15 +08:00
Quorafind
3896bcfc34 feat: add CMDK quick search modal with progressive rendering
- Double-tap configurable modifier key (default: Shift) to invoke
  a SuggestModal-based quick search with real-time file preview
- Progressive heading search via chooser.addSuggestion() and batched
  setTimeout, using metadataCache for zero I/O
- File navigation via setViewState with heading subpath support
- Settings tab for trigger key selection and double-tap interval
- Fix inputEl timing race with retry logic and optional chaining
- Fix extra view creation when defaultViewType is window
- Add auto-preview on ArrowUp/ArrowDown in FloatSearchModal
2026-03-17 14:55:15 +08:00
Boninall
8953f2175d
Merge pull request #71 from Quorafind/feat/4-1-0
feat: support pass view state
2025-02-27 16:27:36 +08:00
quorafind
c3d9e96b19 chore: bump version 2025-02-27 16:25:45 +08:00
quorafind
e56db18fae feat: support pass view state 2025-02-27 16:24:55 +08:00
Boninall
aa638ee588
Merge pull request #70 from Quorafind/feat/4-1-0
Feat/4 1 0
2025-02-27 16:06:09 +08:00
quorafind
4bb81fa23e chore: bump version 2025-02-27 16:05:26 +08:00
quorafind
81fb30c532 feat: support features like update window cleartimeout 2025-02-27 16:04:11 +08:00
quorafind
9875f56314 feat: support all kinds of search operator 2025-02-27 16:03:04 +08:00
quorafind
ab7c600b3c fix: should not trigger by float search itself twice 2025-02-27 15:25:39 +08:00
quorafind
9b7a38f0f2 fix: load window incorrectly 2025-02-27 15:12:41 +08:00
quorafind
97ff7789b7 chore: bump version 2024-10-31 16:19:18 +08:00
quorafind
5832628666 feat: support open search view directly 2024-10-31 16:17:09 +08:00
quorafind
f44be02007 chore: update readme 2024-05-11 22:38:49 +08:00
quorafind
912d213100 chore: update readme 2024-05-11 22:37:16 +08:00
8 changed files with 3070 additions and 1368 deletions

View file

@ -1,15 +1,10 @@
{ {
"id": "float-search", "id": "float-search",
"name": "Floating Search", "name": "Floating Search",
"version": "3.5.1", "version": "4.3.0",
"minAppVersion": "0.15.0", "minAppVersion": "1.2.0",
"description": "You can use search view in modal/leaf/popout window now.", "description": "You can use search view in modal/leaf/popout window now.",
"author": "Boninall", "author": "Boninall",
"authorUrl": "https://github.com/Quorafind", "authorUrl": "https://github.com/Quorafind",
"fundingUrl": {
"Buy Me a Coffee": "https://www.buymeacoffee.com/boninall",
"爱发电": "https://afdian.net/a/boninall",
"支付宝": "https://cdn.jsdelivr.net/gh/Quorafind/.github@main/IMAGE/%E6%94%AF%E4%BB%98%E5%AE%9D%E4%BB%98%E6%AC%BE%E7%A0%81.jpg"
},
"isDesktopOnly": false "isDesktopOnly": false
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "float-search", "name": "float-search",
"version": "3.5.1", "version": "4.3.0",
"description": "You can use search view in modal/leaf/popout window now.", "description": "You can use search view in modal/leaf/popout window now.",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
@ -17,7 +17,7 @@
"@typescript-eslint/parser": "5.29.0", "@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0", "builtin-modules": "3.3.0",
"esbuild": "0.14.47", "esbuild": "0.14.47",
"obsidian": "latest", "obsidian": "^1.12.3",
"tslib": "2.4.0", "tslib": "2.4.0",
"typescript": "4.7.4" "typescript": "4.7.4"
}, },

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -53,7 +53,7 @@ function nosuper<T>(base: new (...args: unknown[]) => T): new () => T {
export const spawnLeafView = (plugin: FloatSearchPlugin, initiatingEl?: HTMLElement, leaf?: WorkspaceLeaf, onShowCallback?: () => unknown): [WorkspaceLeaf, EmbeddedView] => { export const spawnLeafView = (plugin: FloatSearchPlugin, initiatingEl?: HTMLElement, leaf?: WorkspaceLeaf, onShowCallback?: () => unknown): [WorkspaceLeaf, EmbeddedView] => {
// When Obsidian doesn't set any leaf active, use leaf instead. // When Obsidian doesn't set any leaf active, use leaf instead.
let parent = app.workspace.activeLeaf as unknown as EmbeddedViewParent; let parent = plugin.app.workspace.activeLeaf as unknown as EmbeddedViewParent;
if (!parent) parent = leaf as unknown as EmbeddedViewParent; if (!parent) parent = leaf as unknown as EmbeddedViewParent;
if (!initiatingEl) initiatingEl = parent?.containerEl; if (!initiatingEl) initiatingEl = parent?.containerEl;
@ -72,7 +72,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
detaching = false; detaching = false;
opening = false; opening = false;
rootSplit: WorkspaceSplit = new (WorkspaceSplit as ConstructableWorkspaceSplit)(window.app.workspace, "vertical"); rootSplit: WorkspaceSplit = new (WorkspaceSplit as ConstructableWorkspaceSplit)(this.plugin.app.workspace, "vertical");
isPinned = true; isPinned = true;
@ -86,16 +86,16 @@ export class EmbeddedView extends nosuper(HoverPopover) {
document: Document = this.targetEl?.ownerDocument ?? window.activeDocument ?? window.document; document: Document = this.targetEl?.ownerDocument ?? window.activeDocument ?? window.document;
id = genId(8); id = genId(8);
bounce?: NodeJS.Timeout; bounce?: number;
boundOnZoomOut: () => void; boundOnZoomOut: () => void;
originalPath: string; // these are kept to avoid adopting targets w/a different link originalPath: string; // these are kept to avoid adopting targets w/a different link
originalLinkText: string; originalLinkText: string;
static activePopover?: EmbeddedView; static activePopover?: EmbeddedView;
static activeWindows() { static activeWindows(plugin: FloatSearchPlugin) {
const windows: Window[] = [window]; const windows: Window[] = [window];
const {floatingSplit} = app.workspace; const {floatingSplit} = plugin.app.workspace;
if (floatingSplit) { if (floatingSplit) {
for (const split of floatingSplit.children) { for (const split of floatingSplit.children) {
if (split.win) windows.push(split.win); if (split.win) windows.push(split.win);
@ -104,16 +104,16 @@ export class EmbeddedView extends nosuper(HoverPopover) {
return windows; return windows;
} }
static containerForDocument(doc: Document) { static containerForDocument(doc: Document, plugin: FloatSearchPlugin) {
if (doc !== document && app.workspace.floatingSplit) if (doc !== document && plugin.app.workspace.floatingSplit)
for (const container of app.workspace.floatingSplit.children) { for (const container of plugin.app.workspace.floatingSplit.children) {
if (container.doc === doc) return container; if (container.doc === doc) return container;
} }
return app.workspace.rootSplit; return plugin.app.workspace.rootSplit;
} }
static activePopovers() { static activePopovers(plugin: FloatSearchPlugin) {
return this.activeWindows().flatMap(this.popoversForWindow); return this.activeWindows(plugin).flatMap(this.popoversForWindow);
} }
static popoversForWindow(win?: Window) { static popoversForWindow(win?: Window) {
@ -128,8 +128,8 @@ export class EmbeddedView extends nosuper(HoverPopover) {
return el ? popovers.get(el) : undefined; return el ? popovers.get(el) : undefined;
} }
static iteratePopoverLeaves(ws: Workspace, cb: (leaf: WorkspaceLeaf) => boolean | void) { static iteratePopoverLeaves(ws: Workspace, cb: (leaf: WorkspaceLeaf) => boolean | void, plugin: FloatSearchPlugin) {
for (const popover of this.activePopovers()) { for (const popover of this.activePopovers(plugin)) {
if (popover.rootSplit && ws.iterateLeaves(cb, popover.rootSplit)) return true; if (popover.rootSplit && ws.iterateLeaves(cb, popover.rootSplit)) return true;
} }
return false; return false;
@ -221,7 +221,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
if (this.shouldShow()) { if (this.shouldShow()) {
if (this.state === PopoverState.Hiding) { if (this.state === PopoverState.Hiding) {
this.state = PopoverState.Shown; this.state = PopoverState.Shown;
clearTimeout(this.timer); window.clearTimeout(this.timer);
} }
} else { } else {
if (this.state === PopoverState.Showing) { if (this.state === PopoverState.Showing) {
@ -252,7 +252,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
attachLeaf(): WorkspaceLeaf { attachLeaf(): WorkspaceLeaf {
this.rootSplit.getRoot = () => this.plugin.app.workspace[this.document === document ? "rootSplit" : "floatingSplit"]!; this.rootSplit.getRoot = () => this.plugin.app.workspace[this.document === document ? "rootSplit" : "floatingSplit"]!;
this.rootSplit.getContainer = () => EmbeddedView.containerForDocument(this.document); this.rootSplit.getContainer = () => EmbeddedView.containerForDocument(this.document, this.plugin);
this.titleEl.insertAdjacentElement("afterend", this.rootSplit.containerEl); this.titleEl.insertAdjacentElement("afterend", this.rootSplit.containerEl);
const leaf = this.plugin.app.workspace.createLeafInParent(this.rootSplit, 0); const leaf = this.plugin.app.workspace.createLeafInParent(this.rootSplit, 0);
@ -264,7 +264,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
onload(): void { onload(): void {
super.onload(); super.onload();
this.registerEvent(this.plugin.app.workspace.on("layout-change", this.updateLeaves, this)); this.registerEvent(this.plugin.app.workspace.on("layout-change", this.updateLeaves, this));
this.registerEvent(app.workspace.on("layout-change", () => { this.registerEvent(this.plugin.app.workspace.on("layout-change", () => {
// Ensure that top-level items in a popover are not tabbed // Ensure that top-level items in a popover are not tabbed
// @ts-ignore // @ts-ignore
this.rootSplit.children.forEach((item: any, index: any) => { this.rootSplit.children.forEach((item: any, index: any) => {
@ -326,7 +326,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
} }
shouldShowChild(): boolean { shouldShowChild(): boolean {
return EmbeddedView.activePopovers().some(popover => { return EmbeddedView.activePopovers(this.plugin).some(popover => {
if (popover !== this && popover.targetEl && this.hoverEl.contains(popover.targetEl)) { if (popover !== this && popover.targetEl && this.hoverEl.contains(popover.targetEl)) {
return popover.shouldShow(); return popover.shouldShow();
} }
@ -355,7 +355,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
this.targetEl.appendChild(this.hoverEl); this.targetEl.appendChild(this.hoverEl);
this.onShow(); this.onShow();
app.workspace.onLayoutChange(); this.plugin.app.workspace.onLayoutChange();
// initializingHoverPopovers.remove(this); // initializingHoverPopovers.remove(this);
// activeHoverPopovers.push(this); // activeHoverPopovers.push(this);
@ -391,7 +391,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
// A timer might be pending to call show() for the first time, make sure // A timer might be pending to call show() for the first time, make sure
// it doesn't bring us back up after we close // it doesn't bring us back up after we close
if (this.timer) { if (this.timer) {
clearTimeout(this.timer); window.clearTimeout(this.timer);
this.timer = 0; this.timer = 0;
} }
@ -465,7 +465,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
eState = Object.assign(this.buildEphemeralState(file, link), eState); eState = Object.assign(this.buildEphemeralState(file, link), eState);
const parentMode = this.getDefaultMode(); const parentMode = this.getDefaultMode();
const state = this.buildState(parentMode, eState); const state = this.buildState(parentMode, eState);
const leaf = await this.openFile(file, state, createInLeaf); const leaf = await this.openFile(file, state as OpenViewState, createInLeaf);
const leafViewType = leaf?.view?.getViewType(); const leafViewType = leaf?.view?.getViewType();
// console.log(leaf); // console.log(leaf);
if (leafViewType === "image") { if (leafViewType === "image") {

View file

@ -1,290 +1,326 @@
import "obsidian"; import "obsidian";
import { import {
EditorPosition, EditorPosition,
EphemeralState, EphemeralState,
Loc, Loc,
MarkdownPreviewRenderer, MarkdownSubView, MarkdownPreviewRenderer,
Plugin, MarkdownSubView,
PluginManifest, Plugin,
SuggestModal, PluginManifest,
TFile, TFolder, SuggestModal,
View, WorkspaceItem, TFile,
WorkspaceLeaf TFolder,
View,
WorkspaceItem,
WorkspaceLeaf,
} from "obsidian"; } from "obsidian";
import { EmbeddedViewParent } from "../leafView"; import { EmbeddedViewParent } from "../leafView";
interface InternalPlugins { interface InternalPlugins {
switcher: QuickSwitcherPlugin; switcher: QuickSwitcherPlugin;
"page-preview": InternalPlugin; "page-preview": InternalPlugin;
graph: GraphPlugin; graph: GraphPlugin;
} }
interface OpenViewState { interface OpenViewState {
eState?: EphemeralState; eState?: Record<string, unknown>;
state?: { mode: string }; state?: { mode: string };
active?: boolean; active?: boolean;
} }
declare class QuickSwitcherModal extends SuggestModal<TFile> { declare class QuickSwitcherModal extends SuggestModal<TFile> {
getSuggestions(query: string): TFile[] | Promise<TFile[]>; getSuggestions(query: string): TFile[] | Promise<TFile[]>;
renderSuggestion(value: TFile, el: HTMLElement): unknown; renderSuggestion(value: TFile, el: HTMLElement): unknown;
onChooseSuggestion(item: TFile, evt: MouseEvent | KeyboardEvent): unknown; onChooseSuggestion(item: TFile, evt: MouseEvent | KeyboardEvent): unknown;
} }
interface InternalPlugin { interface InternalPlugin {
disable(): void; disable(): void;
enable(): void; enable(): void;
enabled: boolean; enabled: boolean;
_loaded: boolean; _loaded: boolean;
instance: { name: string; id: string }; instance: { name: string; id: string };
} }
interface GraphPlugin extends InternalPlugin { interface GraphPlugin extends InternalPlugin {
views: { localgraph: (leaf: WorkspaceLeaf) => GraphView }; views: { localgraph: (leaf: WorkspaceLeaf) => GraphView };
} }
interface GraphView extends View { interface GraphView extends View {
engine: typeof Object; engine: typeof Object;
renderer: { worker: { terminate(): void } }; renderer: { worker: { terminate(): void } };
} }
interface QuickSwitcherPlugin extends InternalPlugin { interface QuickSwitcherPlugin extends InternalPlugin {
instance: { instance: {
name: string; name: string;
id: string; id: string;
QuickSwitcherModal: typeof QuickSwitcherModal; QuickSwitcherModal: typeof QuickSwitcherModal;
}; };
} }
declare global { declare global {
const i18next: { const i18next: {
t(id: string): string; t(id: string): string;
}; };
interface Window { interface Window {
activeWindow: Window; activeWindow: Window;
activeDocument: Document; activeDocument: Document;
} }
} }
declare module "obsidian" { declare module "obsidian" {
interface App { interface App {
commands: { commands: {
listCommands(): Command[]; listCommands(): Command[];
findCommand(id: string): Command; findCommand(id: string): Command;
removeCommand(id: string): void; removeCommand(id: string): void;
executeCommandById(id: string): void; executeCommandById(id: string): void;
commands: Record<string, Command>; commands: Record<string, Command>;
}; };
internalPlugins: { internalPlugins: {
plugins: InternalPlugins; plugins: InternalPlugins;
getPluginById<T extends keyof InternalPlugins>(id: T): InternalPlugins[T]; getPluginById<T extends keyof InternalPlugins>(
}; id: T
plugins: { ): InternalPlugins[T];
manifests: Record<string, PluginManifest>; };
plugins: Record<string, Plugin> & { plugins: {
["recent-files-obsidian"]: Plugin & { manifests: Record<string, PluginManifest>;
shouldAddFile(file: TFile): boolean; plugins: Record<string, Plugin> & {
}; ["recent-files-obsidian"]: Plugin & {
}; shouldAddFile(file: TFile): boolean;
getPlugin(id: string): Plugin; };
getPlugin(id: "calendar"): CalendarPlugin; };
}; getPlugin(id: string): Plugin;
dom: { appContainerEl: HTMLElement }; getPlugin(id: "calendar"): CalendarPlugin;
viewRegistry: ViewRegistry; };
dom: { appContainerEl: HTMLElement };
viewRegistry: ViewRegistry;
openWithDefaultApp(path: string): void; openWithDefaultApp(path: string): void;
}
interface ViewRegistry { dragManager: any;
typeByExtension: Record<string, string>; // file extensions to view types }
viewByType: Record<string, (leaf: WorkspaceLeaf) => View>; // file extensions to view types
}
interface CalendarPlugin { interface ViewRegistry {
view: View; typeByExtension: Record<string, string>; // file extensions to view types
} viewByType: Record<string, (leaf: WorkspaceLeaf) => View>; // file extensions to view types
}
interface WorkspaceParent { interface CalendarPlugin {
insertChild(index: number, child: WorkspaceItem, resize?: boolean): void; view: View;
}
replaceChild(index: number, child: WorkspaceItem, resize?: boolean): void; interface WorkspaceParent {
insertChild(
index: number,
child: WorkspaceItem,
resize?: boolean
): void;
removeChild(leaf: WorkspaceLeaf, resize?: boolean): void; replaceChild(
index: number,
child: WorkspaceItem,
resize?: boolean
): void;
containerEl: HTMLElement; removeChild(leaf: WorkspaceLeaf, resize?: boolean): void;
children: any;
}
interface MarkdownEditView { containerEl: HTMLElement;
editorEl: HTMLElement; children: any;
} parent: any;
}
class MarkdownPreviewRendererStatic extends MarkdownPreviewRenderer { interface MarkdownEditView {
static registerDomEvents(el: HTMLElement, handlerInstance: unknown, cb: (el: HTMLElement) => unknown): void; editorEl: HTMLElement;
} }
interface WorkspaceLeaf { class MarkdownPreviewRendererStatic extends MarkdownPreviewRenderer {
openLinkText(linkText: string, path: string, state?: unknown): Promise<void>; static registerDomEvents(
el: HTMLElement,
handlerInstance: unknown,
cb: (el: HTMLElement) => unknown
): void;
}
updateHeader(): void; interface WorkspaceLeaf {
openLinkText(
linkText: string,
path: string,
state?: unknown
): Promise<void>;
containerEl: HTMLDivElement; updateHeader(): void;
working: boolean;
parentSplit: WorkspaceParent;
activeTime: number;
}
interface Workspace { containerEl: HTMLDivElement;
recordHistory(leaf: WorkspaceLeaf, pushHistory: boolean): void; working: boolean;
parentSplit: WorkspaceParent;
activeTime: number;
}
iterateLeaves(callback: (item: WorkspaceLeaf) => boolean | void, item: WorkspaceItem | WorkspaceItem[]): boolean; interface Workspace {
recordHistory(leaf: WorkspaceLeaf, pushHistory: boolean): void;
iterateLeaves(item: WorkspaceItem | WorkspaceItem[], callback: (item: WorkspaceLeaf) => boolean | void): boolean; iterateLeaves(
callback: (item: WorkspaceLeaf) => boolean | void,
item: WorkspaceItem | WorkspaceItem[]
): boolean;
getDropLocation(event: MouseEvent): { iterateLeaves(
target: WorkspaceItem; item: WorkspaceItem | WorkspaceItem[],
sidedock: boolean; callback: (item: WorkspaceLeaf) => boolean | void
}; ): boolean;
recursiveGetTarget(event: MouseEvent, parent: WorkspaceParent): WorkspaceItem; getDropLocation(event: MouseEvent): {
target: WorkspaceItem;
sidedock: boolean;
};
recordMostRecentOpenedFile(file: TFile): void; recursiveGetTarget(
event: MouseEvent,
parent: WorkspaceParent
): WorkspaceItem;
onDragLeaf(event: MouseEvent, leaf: WorkspaceLeaf): void; recordMostRecentOpenedFile(file: TFile): void;
onLayoutChange(): void; // tell Obsidian leaves have been added/removed/etc. onDragLeaf(event: MouseEvent, leaf: WorkspaceLeaf): void;
activeLeafEvents(): void;
floatingSplit: any; onLayoutChange(): void; // tell Obsidian leaves have been added/removed/etc.
activeLeafEvents(): void;
pushUndoHistory(leaf: WorkspaceLeaf, id: string, e: any): void; floatingSplit: any;
}
interface Editor { pushUndoHistory(leaf: WorkspaceLeaf, id: string, e: any): void;
getClickableTokenAt(pos: EditorPosition): { }
text: string;
type: string;
start: EditorPosition;
end: EditorPosition;
};
}
interface WorkspaceItem { interface Editor {
side?: "left" | "right"; getClickableTokenAt(pos: EditorPosition): {
} text: string;
type: string;
start: EditorPosition;
end: EditorPosition;
};
}
interface View { interface WorkspaceItem {
iconEl: HTMLElement; side?: "left" | "right";
file: TFile; }
setMode(mode: MarkdownSubView): Promise<void>; interface View {
iconEl: HTMLElement;
file: TFile;
followLinkUnderCursor(newLeaf: boolean): void; setMode(mode: MarkdownSubView): Promise<void>;
modes: Record<string, MarkdownSubView>; followLinkUnderCursor(newLeaf: boolean): void;
getMode(): string; modes: Record<string, MarkdownSubView>;
headerEl: HTMLElement; getMode(): string;
contentEl: HTMLElement;
}
interface SearchView extends View { headerEl: HTMLElement;
onKeyArrowRightInFocus(e: KeyboardEvent): void; contentEl: HTMLElement;
}
onKeyArrowLeftInFocus(e: KeyboardEvent): void; interface SearchView extends View {
onKeyArrowRightInFocus(e: KeyboardEvent): void;
onKeyArrowUpInFocus(e: KeyboardEvent): void; onKeyArrowLeftInFocus(e: KeyboardEvent): void;
onKeyArrowDownInFocus(e: KeyboardEvent): void; onKeyArrowUpInFocus(e: KeyboardEvent): void;
onKeyEnterInFocus(e: KeyboardEvent): void; onKeyArrowDownInFocus(e: KeyboardEvent): void;
onKeyShowMoreBefore(e: KeyboardEvent): void; onKeyEnterInFocus(e: KeyboardEvent): void;
onKeyShowMoreAfter(e: KeyboardEvent): void; onKeyShowMoreBefore(e: KeyboardEvent): void;
dom: any; onKeyShowMoreAfter(e: KeyboardEvent): void;
searchComponent: SearchComponent;
headerDom: any;
}
interface EmptyView extends View { dom: any;
actionListEl: HTMLElement; searchComponent: SearchComponent;
emptyTitleEl: HTMLElement; headerDom: any;
} }
interface FileManager { interface EmptyView extends View {
createNewMarkdownFile(folder: TFolder, fileName: string): Promise<TFile>; actionListEl: HTMLElement;
} emptyTitleEl: HTMLElement;
}
enum PopoverState { interface FileManager {
Showing, createNewMarkdownFile(
Shown, folder: TFolder,
Hiding, fileName: string
Hidden, ): Promise<TFile>;
} }
interface Menu { enum PopoverState {
items: MenuItem[]; Showing,
dom: HTMLElement; Shown,
hideCallback: () => unknown; Hiding,
} Hidden,
}
interface MenuItem { interface Menu {
iconEl: HTMLElement; items: MenuItem[];
dom: HTMLElement; dom: HTMLElement;
} hideCallback: () => unknown;
}
interface EphemeralState { interface MenuItem {
focus?: boolean; iconEl: HTMLElement;
subpath?: string; dom: HTMLElement;
line?: number; }
startLoc?: Loc;
endLoc?: Loc;
scroll?: number;
}
interface HoverParent { interface EphemeralState {
type?: string; focus?: boolean;
} subpath?: string;
line?: number;
startLoc?: Loc;
endLoc?: Loc;
scroll?: number;
}
interface WorkspaceContainer { interface HoverParent {
type: "window" | "split" | "tab"; type?: string;
} }
interface HoverPopover { interface WorkspaceContainer {
parent: EmbeddedViewParent | null; type: "window" | "split" | "tab";
targetEl: HTMLElement; }
hoverEl: HTMLElement;
position(pos?: MousePos): void; interface HoverPopover {
parent: EmbeddedViewParent | null;
targetEl: HTMLElement;
hoverEl: HTMLElement;
hide(): void; position(pos?: MousePos): void;
show(): void; hide(): void;
shouldShowSelf(): boolean; show(): void;
timer: number; shouldShowSelf(): boolean;
waitTime: number;
shouldShow(): boolean; timer: number;
waitTime: number;
transition(): void; shouldShow(): boolean;
}
interface MousePos { transition(): void;
x: number; }
y: number;
}
interface Plugin { interface MousePos {
registerGlobalCommand(command: Command): void; x: number;
} y: number;
}
interface Plugin {
registerGlobalCommand(command: Command): void;
}
} }

View file

@ -9,13 +9,15 @@ If your plugin does not need CSS, delete this file.
.float-search-modal { .float-search-modal {
width: 700px; width: 700px;
padding-bottom: 0; padding-bottom: 0;
transition: width 0.15s ease;
} }
.float-search-modal.float-search-width { .float-search-modal.float-search-width {
width: 1200px; width: 1200px;
} }
.float-search-modal-search-ctn, .float-search-modal-file-ctn { .float-search-modal-search-ctn,
.float-search-modal-file-ctn {
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
@ -63,7 +65,6 @@ If your plugin does not need CSS, delete this file.
z-index: 30; z-index: 30;
} }
.float-search-modal-instructions { .float-search-modal-instructions {
border-top: 1px solid var(--background-secondary); border-top: 1px solid var(--background-secondary);
user-select: none; user-select: none;
@ -82,7 +83,8 @@ If your plugin does not need CSS, delete this file.
margin-right: var(--size-2-2); margin-right: var(--size-2-2);
} }
.float-search-modal-content:has(.float-search-modal-file-ctn) .float-search-modal-search-ctn { .float-search-modal-content:has(.float-search-modal-file-ctn)
.float-search-modal-search-ctn {
border-right: 1px solid var(--background-secondary); border-right: 1px solid var(--background-secondary);
} }
@ -142,3 +144,88 @@ body:not(.show-file-path) .search-result-file-title .search-result-file-path {
.show-file-path .search-result-file-title .search-result-file-path:hover { .show-file-path .search-result-file-title .search-result-file-path:hover {
background-color: var(--background-secondary); background-color: var(--background-secondary);
} }
.fs-leaf-view .workspace-split {
background-color: var(--background-primary);
}
/* ── CMDK Modal ── */
.prompt.float-search-cmdk {
width: 700px;
max-width: 90vw;
transition: width 0.15s ease;
}
.prompt.float-search-cmdk.float-search-cmdk-expanded {
width: 1100px;
}
.float-search-cmdk-body {
display: flex;
flex-direction: row;
height: 50vh;
max-height: 600px;
overflow: hidden;
}
.float-search-cmdk-body .prompt-results {
max-height: none;
height: 100%;
overflow-y: auto;
flex: 1 1 auto;
}
.float-search-cmdk-expanded .float-search-cmdk-body .prompt-results {
flex: 0 0 40%;
border-right: 1px solid var(--background-modifier-border);
}
.float-search-cmdk-preview {
flex: 1;
overflow: hidden;
height: 100%;
}
.float-search-cmdk-preview .view-header {
display: none;
}
.float-search-cmdk-preview .view-content {
height: 100%;
}
.float-search-cmdk-preview .fs-block {
height: 100% !important;
}
.float-search-cmdk-preview .fs-content {
height: 100%;
}
.float-search-cmdk-preview .fs-content .workspace-split.mod-vertical {
height: 100%;
}
.float-search-cmdk-preview .workspace-leaf-resize-handle {
display: none;
}
.modal-container.float-search-cmdk-container.mod-dim {
z-index: 30;
}
/* ── Quick Create item ── */
.float-search-cmdk-create-item {
border-top: 1px solid var(--background-modifier-border);
}
.float-search-cmdk-create-item .suggestion-title {
color: var(--text-accent);
font-weight: var(--font-semibold);
}
.float-search-cmdk-create-item .suggestion-flair {
display: flex;
align-items: center;
color: var(--text-accent);
}

View file

@ -29,5 +29,10 @@
"3.4.9": "0.15.0", "3.4.9": "0.15.0",
"3.4.10": "0.15.0", "3.4.10": "0.15.0",
"3.5.0": "0.15.0", "3.5.0": "0.15.0",
"3.5.1": "0.15.0" "3.5.1": "0.15.0",
"4.0.0": "0.15.0",
"4.1.0": "0.15.0",
"4.1.1": "0.15.0",
"4.2.0": "1.2.0",
"4.3.0": "1.2.0"
} }