Compare commits

...

22 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
Quorafind
460fe4edd0 chore: bump version 2024-04-09 15:45:17 +08:00
Quorafind
8c2817eb22 chore: bump version 2024-04-09 15:42:28 +08:00
8 changed files with 3073 additions and 1370 deletions

View file

@ -1,15 +1,10 @@
{
"id": "float-search",
"name": "Floating Search",
"version": "3.5.0",
"minAppVersion": "0.15.0",
"version": "4.3.0",
"minAppVersion": "1.2.0",
"description": "You can use search view in modal/leaf/popout window now.",
"author": "Boninall",
"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
}

View file

@ -1,6 +1,6 @@
{
"name": "float-search",
"version": "3.5.0",
"version": "4.3.0",
"description": "You can use search view in modal/leaf/popout window now.",
"main": "main.js",
"scripts": {
@ -17,7 +17,7 @@
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.14.47",
"obsidian": "latest",
"obsidian": "^1.12.3",
"tslib": "2.4.0",
"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] => {
// 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 (!initiatingEl) initiatingEl = parent?.containerEl;
@ -72,7 +72,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
detaching = 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;
@ -86,16 +86,16 @@ export class EmbeddedView extends nosuper(HoverPopover) {
document: Document = this.targetEl?.ownerDocument ?? window.activeDocument ?? window.document;
id = genId(8);
bounce?: NodeJS.Timeout;
bounce?: number;
boundOnZoomOut: () => void;
originalPath: string; // these are kept to avoid adopting targets w/a different link
originalLinkText: string;
static activePopover?: EmbeddedView;
static activeWindows() {
static activeWindows(plugin: FloatSearchPlugin) {
const windows: Window[] = [window];
const {floatingSplit} = app.workspace;
const {floatingSplit} = plugin.app.workspace;
if (floatingSplit) {
for (const split of floatingSplit.children) {
if (split.win) windows.push(split.win);
@ -104,16 +104,16 @@ export class EmbeddedView extends nosuper(HoverPopover) {
return windows;
}
static containerForDocument(doc: Document) {
if (doc !== document && app.workspace.floatingSplit)
for (const container of app.workspace.floatingSplit.children) {
static containerForDocument(doc: Document, plugin: FloatSearchPlugin) {
if (doc !== document && plugin.app.workspace.floatingSplit)
for (const container of plugin.app.workspace.floatingSplit.children) {
if (container.doc === doc) return container;
}
return app.workspace.rootSplit;
return plugin.app.workspace.rootSplit;
}
static activePopovers() {
return this.activeWindows().flatMap(this.popoversForWindow);
static activePopovers(plugin: FloatSearchPlugin) {
return this.activeWindows(plugin).flatMap(this.popoversForWindow);
}
static popoversForWindow(win?: Window) {
@ -128,8 +128,8 @@ export class EmbeddedView extends nosuper(HoverPopover) {
return el ? popovers.get(el) : undefined;
}
static iteratePopoverLeaves(ws: Workspace, cb: (leaf: WorkspaceLeaf) => boolean | void) {
for (const popover of this.activePopovers()) {
static iteratePopoverLeaves(ws: Workspace, cb: (leaf: WorkspaceLeaf) => boolean | void, plugin: FloatSearchPlugin) {
for (const popover of this.activePopovers(plugin)) {
if (popover.rootSplit && ws.iterateLeaves(cb, popover.rootSplit)) return true;
}
return false;
@ -221,7 +221,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
if (this.shouldShow()) {
if (this.state === PopoverState.Hiding) {
this.state = PopoverState.Shown;
clearTimeout(this.timer);
window.clearTimeout(this.timer);
}
} else {
if (this.state === PopoverState.Showing) {
@ -252,7 +252,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
attachLeaf(): WorkspaceLeaf {
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);
const leaf = this.plugin.app.workspace.createLeafInParent(this.rootSplit, 0);
@ -264,7 +264,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
onload(): void {
super.onload();
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
// @ts-ignore
this.rootSplit.children.forEach((item: any, index: any) => {
@ -326,7 +326,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
}
shouldShowChild(): boolean {
return EmbeddedView.activePopovers().some(popover => {
return EmbeddedView.activePopovers(this.plugin).some(popover => {
if (popover !== this && popover.targetEl && this.hoverEl.contains(popover.targetEl)) {
return popover.shouldShow();
}
@ -355,7 +355,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
this.targetEl.appendChild(this.hoverEl);
this.onShow();
app.workspace.onLayoutChange();
this.plugin.app.workspace.onLayoutChange();
// initializingHoverPopovers.remove(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
// it doesn't bring us back up after we close
if (this.timer) {
clearTimeout(this.timer);
window.clearTimeout(this.timer);
this.timer = 0;
}
@ -465,7 +465,7 @@ export class EmbeddedView extends nosuper(HoverPopover) {
eState = Object.assign(this.buildEphemeralState(file, link), eState);
const parentMode = this.getDefaultMode();
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();
// console.log(leaf);
if (leafViewType === "image") {

View file

@ -1,290 +1,326 @@
import "obsidian";
import {
EditorPosition,
EphemeralState,
Loc,
MarkdownPreviewRenderer, MarkdownSubView,
Plugin,
PluginManifest,
SuggestModal,
TFile, TFolder,
View, WorkspaceItem,
WorkspaceLeaf
EditorPosition,
EphemeralState,
Loc,
MarkdownPreviewRenderer,
MarkdownSubView,
Plugin,
PluginManifest,
SuggestModal,
TFile,
TFolder,
View,
WorkspaceItem,
WorkspaceLeaf,
} from "obsidian";
import { EmbeddedViewParent } from "../leafView";
interface InternalPlugins {
switcher: QuickSwitcherPlugin;
"page-preview": InternalPlugin;
graph: GraphPlugin;
switcher: QuickSwitcherPlugin;
"page-preview": InternalPlugin;
graph: GraphPlugin;
}
interface OpenViewState {
eState?: EphemeralState;
state?: { mode: string };
active?: boolean;
eState?: Record<string, unknown>;
state?: { mode: string };
active?: boolean;
}
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 {
disable(): void;
disable(): void;
enable(): void;
enable(): void;
enabled: boolean;
_loaded: boolean;
instance: { name: string; id: string };
enabled: boolean;
_loaded: boolean;
instance: { name: string; id: string };
}
interface GraphPlugin extends InternalPlugin {
views: { localgraph: (leaf: WorkspaceLeaf) => GraphView };
views: { localgraph: (leaf: WorkspaceLeaf) => GraphView };
}
interface GraphView extends View {
engine: typeof Object;
renderer: { worker: { terminate(): void } };
engine: typeof Object;
renderer: { worker: { terminate(): void } };
}
interface QuickSwitcherPlugin extends InternalPlugin {
instance: {
name: string;
id: string;
QuickSwitcherModal: typeof QuickSwitcherModal;
};
instance: {
name: string;
id: string;
QuickSwitcherModal: typeof QuickSwitcherModal;
};
}
declare global {
const i18next: {
t(id: string): string;
};
const i18next: {
t(id: string): string;
};
interface Window {
activeWindow: Window;
activeDocument: Document;
}
interface Window {
activeWindow: Window;
activeDocument: Document;
}
}
declare module "obsidian" {
interface App {
commands: {
listCommands(): Command[];
findCommand(id: string): Command;
removeCommand(id: string): void;
executeCommandById(id: string): void;
commands: Record<string, Command>;
};
internalPlugins: {
plugins: InternalPlugins;
getPluginById<T extends keyof InternalPlugins>(id: T): InternalPlugins[T];
};
plugins: {
manifests: Record<string, PluginManifest>;
plugins: Record<string, Plugin> & {
["recent-files-obsidian"]: Plugin & {
shouldAddFile(file: TFile): boolean;
};
};
getPlugin(id: string): Plugin;
getPlugin(id: "calendar"): CalendarPlugin;
};
dom: { appContainerEl: HTMLElement };
viewRegistry: ViewRegistry;
interface App {
commands: {
listCommands(): Command[];
findCommand(id: string): Command;
removeCommand(id: string): void;
executeCommandById(id: string): void;
commands: Record<string, Command>;
};
internalPlugins: {
plugins: InternalPlugins;
getPluginById<T extends keyof InternalPlugins>(
id: T
): InternalPlugins[T];
};
plugins: {
manifests: Record<string, PluginManifest>;
plugins: Record<string, Plugin> & {
["recent-files-obsidian"]: Plugin & {
shouldAddFile(file: TFile): boolean;
};
};
getPlugin(id: string): Plugin;
getPlugin(id: "calendar"): CalendarPlugin;
};
dom: { appContainerEl: HTMLElement };
viewRegistry: ViewRegistry;
openWithDefaultApp(path: string): void;
}
openWithDefaultApp(path: string): void;
interface ViewRegistry {
typeByExtension: Record<string, string>; // file extensions to view types
viewByType: Record<string, (leaf: WorkspaceLeaf) => View>; // file extensions to view types
}
dragManager: any;
}
interface CalendarPlugin {
view: View;
}
interface ViewRegistry {
typeByExtension: Record<string, string>; // file extensions to view types
viewByType: Record<string, (leaf: WorkspaceLeaf) => View>; // file extensions to view types
}
interface WorkspaceParent {
insertChild(index: number, child: WorkspaceItem, resize?: boolean): void;
interface CalendarPlugin {
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;
children: any;
}
removeChild(leaf: WorkspaceLeaf, resize?: boolean): void;
interface MarkdownEditView {
editorEl: HTMLElement;
}
containerEl: HTMLElement;
children: any;
parent: any;
}
class MarkdownPreviewRendererStatic extends MarkdownPreviewRenderer {
static registerDomEvents(el: HTMLElement, handlerInstance: unknown, cb: (el: HTMLElement) => unknown): void;
}
interface MarkdownEditView {
editorEl: HTMLElement;
}
interface WorkspaceLeaf {
openLinkText(linkText: string, path: string, state?: unknown): Promise<void>;
class MarkdownPreviewRendererStatic extends MarkdownPreviewRenderer {
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;
working: boolean;
parentSplit: WorkspaceParent;
activeTime: number;
}
updateHeader(): void;
interface Workspace {
recordHistory(leaf: WorkspaceLeaf, pushHistory: boolean): void;
containerEl: HTMLDivElement;
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): {
target: WorkspaceItem;
sidedock: boolean;
};
iterateLeaves(
item: WorkspaceItem | WorkspaceItem[],
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.
activeLeafEvents(): void;
onDragLeaf(event: MouseEvent, leaf: WorkspaceLeaf): 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 {
getClickableTokenAt(pos: EditorPosition): {
text: string;
type: string;
start: EditorPosition;
end: EditorPosition;
};
}
pushUndoHistory(leaf: WorkspaceLeaf, id: string, e: any): void;
}
interface WorkspaceItem {
side?: "left" | "right";
}
interface Editor {
getClickableTokenAt(pos: EditorPosition): {
text: string;
type: string;
start: EditorPosition;
end: EditorPosition;
};
}
interface View {
iconEl: HTMLElement;
file: TFile;
interface WorkspaceItem {
side?: "left" | "right";
}
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;
contentEl: HTMLElement;
}
getMode(): string;
interface SearchView extends View {
onKeyArrowRightInFocus(e: KeyboardEvent): void;
headerEl: HTMLElement;
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;
searchComponent: SearchComponent;
headerDom: any;
}
onKeyShowMoreAfter(e: KeyboardEvent): void;
interface EmptyView extends View {
actionListEl: HTMLElement;
emptyTitleEl: HTMLElement;
}
dom: any;
searchComponent: SearchComponent;
headerDom: any;
}
interface FileManager {
createNewMarkdownFile(folder: TFolder, fileName: string): Promise<TFile>;
}
interface EmptyView extends View {
actionListEl: HTMLElement;
emptyTitleEl: HTMLElement;
}
enum PopoverState {
Showing,
Shown,
Hiding,
Hidden,
}
interface FileManager {
createNewMarkdownFile(
folder: TFolder,
fileName: string
): Promise<TFile>;
}
interface Menu {
items: MenuItem[];
dom: HTMLElement;
hideCallback: () => unknown;
}
enum PopoverState {
Showing,
Shown,
Hiding,
Hidden,
}
interface MenuItem {
iconEl: HTMLElement;
dom: HTMLElement;
}
interface Menu {
items: MenuItem[];
dom: HTMLElement;
hideCallback: () => unknown;
}
interface EphemeralState {
focus?: boolean;
subpath?: string;
line?: number;
startLoc?: Loc;
endLoc?: Loc;
scroll?: number;
}
interface MenuItem {
iconEl: HTMLElement;
dom: HTMLElement;
}
interface HoverParent {
type?: string;
}
interface EphemeralState {
focus?: boolean;
subpath?: string;
line?: number;
startLoc?: Loc;
endLoc?: Loc;
scroll?: number;
}
interface WorkspaceContainer {
type: "window" | "split" | "tab";
}
interface HoverParent {
type?: string;
}
interface HoverPopover {
parent: EmbeddedViewParent | null;
targetEl: HTMLElement;
hoverEl: HTMLElement;
interface WorkspaceContainer {
type: "window" | "split" | "tab";
}
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;
waitTime: number;
shouldShowSelf(): boolean;
shouldShow(): boolean;
timer: number;
waitTime: number;
transition(): void;
}
shouldShow(): boolean;
interface MousePos {
x: number;
y: number;
}
transition(): void;
}
interface Plugin {
registerGlobalCommand(command: Command): void;
}
interface MousePos {
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 {
width: 700px;
padding-bottom: 0;
transition: width 0.15s ease;
}
.float-search-modal.float-search-width {
width: 1200px;
}
.float-search-modal-search-ctn, .float-search-modal-file-ctn {
.float-search-modal-search-ctn,
.float-search-modal-file-ctn {
height: 100%;
width: 100%;
}
@ -63,7 +65,6 @@ If your plugin does not need CSS, delete this file.
z-index: 30;
}
.float-search-modal-instructions {
border-top: 1px solid var(--background-secondary);
user-select: none;
@ -82,7 +83,8 @@ If your plugin does not need CSS, delete this file.
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);
}
@ -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 {
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

@ -28,5 +28,11 @@
"3.4.8": "0.15.0",
"3.4.9": "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",
"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"
}