/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // src/main.ts var main_exports = {}; __export(main_exports, { default: () => CoreSearchAssistantPlugin }); module.exports = __toCommonJS(main_exports); // src/Events.ts var import_obsidian = require("obsidian"); var EVENT_SEARCH_RESULT_ITEM_DETECTED = "search-result-item-detected"; var EVENT_SORT_ORDER_CHANGED = "sort-order-changed"; var CoreSearchAssistantEvents = class extends import_obsidian.Events { trigger(name, ...data) { super.trigger(name, ...data); } on(name, callback, ctx) { return super.on(name, callback, ctx); } }; // src/ModeScope.ts var ModeScope = class { constructor() { this._depth = 0; } get inSearchMode() { return this._depth > 0; } get depth() { return this._depth; } push() { this._depth++; } pop() { this._depth--; if (this.depth < 0) { throw "[ERROR in Core Search Assistant] ModeScope.depth < 0"; } } reset() { this._depth = 0; } }; // src/Setting.ts var import_obsidian6 = require("obsidian"); // src/ui/HotkeySetter.ts var import_obsidian5 = require("obsidian"); // node_modules/svelte/src/runtime/internal/utils.js function noop() { } function run(fn) { return fn(); } function blank_object() { return /* @__PURE__ */ Object.create(null); } function run_all(fns) { fns.forEach(run); } function is_function(thing) { return typeof thing === "function"; } function safe_not_equal(a, b) { return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function"; } function is_empty(obj) { return Object.keys(obj).length === 0; } function subscribe(store, ...callbacks) { if (store == null) { for (const callback of callbacks) { callback(void 0); } return noop; } const unsub = store.subscribe(...callbacks); return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; } function component_subscribe(component, store, callback) { component.$$.on_destroy.push(subscribe(store, callback)); } // node_modules/svelte/src/runtime/internal/globals.js var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : ( // @ts-ignore Node typings have this global ); // node_modules/svelte/src/runtime/internal/ResizeObserverSingleton.js var ResizeObserverSingleton = class _ResizeObserverSingleton { /** @param {ResizeObserverOptions} options */ constructor(options) { /** * @private * @readonly * @type {WeakMap} */ __publicField(this, "_listeners", "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0); /** * @private * @type {ResizeObserver} */ __publicField(this, "_observer"); /** @type {ResizeObserverOptions} */ __publicField(this, "options"); this.options = options; } /** * @param {Element} element * @param {import('./private.js').Listener} listener * @returns {() => void} */ observe(element2, listener) { this._listeners.set(element2, listener); this._getObserver().observe(element2, this.options); return () => { this._listeners.delete(element2); this._observer.unobserve(element2); }; } /** * @private */ _getObserver() { return this._observer ?? (this._observer = new ResizeObserver((entries) => { for (const entry of entries) { _ResizeObserverSingleton.entries.set(entry.target, entry); this._listeners.get(entry.target)?.(entry); } })); } }; ResizeObserverSingleton.entries = "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0; // node_modules/svelte/src/runtime/internal/dom.js var is_hydrating = false; function start_hydrating() { is_hydrating = true; } function end_hydrating() { is_hydrating = false; } function append(target, node) { target.appendChild(node); } function append_styles(target, style_sheet_id, styles) { const append_styles_to = get_root_for_style(target); if (!append_styles_to.getElementById(style_sheet_id)) { const style = element("style"); style.id = style_sheet_id; style.textContent = styles; append_stylesheet(append_styles_to, style); } } function get_root_for_style(node) { if (!node) return document; const root = node.getRootNode ? node.getRootNode() : node.ownerDocument; if (root && /** @type {ShadowRoot} */ root.host) { return ( /** @type {ShadowRoot} */ root ); } return node.ownerDocument; } function append_stylesheet(node, style) { append( /** @type {Document} */ node.head || node, style ); return style.sheet; } function insert(target, node, anchor) { target.insertBefore(node, anchor || null); } function detach(node) { if (node.parentNode) { node.parentNode.removeChild(node); } } function destroy_each(iterations, detaching) { for (let i = 0; i < iterations.length; i += 1) { if (iterations[i]) iterations[i].d(detaching); } } function element(name) { return document.createElement(name); } function text(data) { return document.createTextNode(data); } function space() { return text(" "); } function listen(node, event, handler, options) { node.addEventListener(event, handler, options); return () => node.removeEventListener(event, handler, options); } function attr(node, attribute, value) { if (value == null) node.removeAttribute(attribute); else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value); } function children(element2) { return Array.from(element2.childNodes); } function set_data(text2, data) { data = "" + data; if (text2.data === data) return; text2.data = /** @type {string} */ data; } function toggle_class(element2, name, toggle) { element2.classList.toggle(name, !!toggle); } function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) { return new CustomEvent(type, { detail, bubbles, cancelable }); } function get_custom_elements_slots(element2) { const result = {}; element2.childNodes.forEach( /** @param {Element} node */ (node) => { result[node.slot || "default"] = true; } ); return result; } // node_modules/svelte/src/runtime/internal/lifecycle.js var current_component; function set_current_component(component) { current_component = component; } function get_current_component() { if (!current_component) throw new Error("Function called outside component initialization"); return current_component; } function onMount(fn) { get_current_component().$$.on_mount.push(fn); } function onDestroy(fn) { get_current_component().$$.on_destroy.push(fn); } function createEventDispatcher() { const component = get_current_component(); return (type, detail, { cancelable = false } = {}) => { const callbacks = component.$$.callbacks[type]; if (callbacks) { const event = custom_event( /** @type {string} */ type, detail, { cancelable } ); callbacks.slice().forEach((fn) => { fn.call(component, event); }); return !event.defaultPrevented; } return true; }; } // node_modules/svelte/src/runtime/internal/scheduler.js var dirty_components = []; var binding_callbacks = []; var render_callbacks = []; var flush_callbacks = []; var resolved_promise = /* @__PURE__ */ Promise.resolve(); var update_scheduled = false; function schedule_update() { if (!update_scheduled) { update_scheduled = true; resolved_promise.then(flush); } } function add_render_callback(fn) { render_callbacks.push(fn); } var seen_callbacks = /* @__PURE__ */ new Set(); var flushidx = 0; function flush() { if (flushidx !== 0) { return; } const saved_component = current_component; do { try { while (flushidx < dirty_components.length) { const component = dirty_components[flushidx]; flushidx++; set_current_component(component); update(component.$$); } } catch (e) { dirty_components.length = 0; flushidx = 0; throw e; } set_current_component(null); dirty_components.length = 0; flushidx = 0; while (binding_callbacks.length) binding_callbacks.pop()(); for (let i = 0; i < render_callbacks.length; i += 1) { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { seen_callbacks.add(callback); callback(); } } render_callbacks.length = 0; } while (dirty_components.length); while (flush_callbacks.length) { flush_callbacks.pop()(); } update_scheduled = false; seen_callbacks.clear(); set_current_component(saved_component); } function update($$) { if ($$.fragment !== null) { $$.update(); run_all($$.before_update); const dirty = $$.dirty; $$.dirty = [-1]; $$.fragment && $$.fragment.p($$.ctx, dirty); $$.after_update.forEach(add_render_callback); } } function flush_render_callbacks(fns) { const filtered = []; const targets = []; render_callbacks.forEach((c) => fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c)); targets.forEach((c) => c()); render_callbacks = filtered; } // node_modules/svelte/src/runtime/internal/transitions.js var outroing = /* @__PURE__ */ new Set(); var outros; function group_outros() { outros = { r: 0, c: [], p: outros // parent group }; } function check_outros() { if (!outros.r) { run_all(outros.c); } outros = outros.p; } function transition_in(block, local) { if (block && block.i) { outroing.delete(block); block.i(local); } } function transition_out(block, local, detach2, callback) { if (block && block.o) { if (outroing.has(block)) return; outroing.add(block); outros.c.push(() => { outroing.delete(block); if (callback) { if (detach2) block.d(1); callback(); } }); block.o(local); } else if (callback) { callback(); } } // node_modules/svelte/src/runtime/internal/each.js function ensure_array_like(array_like_or_iterator) { return array_like_or_iterator?.length !== void 0 ? array_like_or_iterator : Array.from(array_like_or_iterator); } // node_modules/svelte/src/shared/boolean_attributes.js var _boolean_attributes = ( /** @type {const} */ [ "allowfullscreen", "allowpaymentrequest", "async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "hidden", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected" ] ); var boolean_attributes = /* @__PURE__ */ new Set([..._boolean_attributes]); // node_modules/svelte/src/runtime/internal/Component.js function create_component(block) { block && block.c(); } function mount_component(component, target, anchor) { const { fragment, after_update } = component.$$; fragment && fragment.m(target, anchor); add_render_callback(() => { const new_on_destroy = component.$$.on_mount.map(run).filter(is_function); if (component.$$.on_destroy) { component.$$.on_destroy.push(...new_on_destroy); } else { run_all(new_on_destroy); } component.$$.on_mount = []; }); after_update.forEach(add_render_callback); } function destroy_component(component, detaching) { const $$ = component.$$; if ($$.fragment !== null) { flush_render_callbacks($$.after_update); run_all($$.on_destroy); $$.fragment && $$.fragment.d(detaching); $$.on_destroy = $$.fragment = null; $$.ctx = []; } } function make_dirty(component, i) { if (component.$$.dirty[0] === -1) { dirty_components.push(component); schedule_update(); component.$$.dirty.fill(0); } component.$$.dirty[i / 31 | 0] |= 1 << i % 31; } function init(component, options, instance8, create_fragment8, not_equal, props, append_styles2 = null, dirty = [-1]) { const parent_component = current_component; set_current_component(component); const $$ = component.$$ = { fragment: null, ctx: [], // state props, update: noop, not_equal, bound: blank_object(), // lifecycle on_mount: [], on_destroy: [], on_disconnect: [], before_update: [], after_update: [], context: new Map(options.context || (parent_component ? parent_component.$$.context : [])), // everything else callbacks: blank_object(), dirty, skip_bound: false, root: options.target || parent_component.$$.root }; append_styles2 && append_styles2($$.root); let ready = false; $$.ctx = instance8 ? instance8(component, options.props || {}, (i, ret, ...rest) => { const value = rest.length ? rest[0] : ret; if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value); if (ready) make_dirty(component, i); } return ret; }) : []; $$.update(); ready = true; run_all($$.before_update); $$.fragment = create_fragment8 ? create_fragment8($$.ctx) : false; if (options.target) { if (options.hydrate) { start_hydrating(); const nodes = children(options.target); $$.fragment && $$.fragment.l(nodes); nodes.forEach(detach); } else { $$.fragment && $$.fragment.c(); } if (options.intro) transition_in(component.$$.fragment); mount_component(component, options.target, options.anchor); end_hydrating(); flush(); } set_current_component(parent_component); } var SvelteElement; if (typeof HTMLElement === "function") { SvelteElement = class extends HTMLElement { constructor($$componentCtor, $$slots, use_shadow_dom) { super(); /** The Svelte component constructor */ __publicField(this, "$$ctor"); /** Slots */ __publicField(this, "$$s"); /** The Svelte component instance */ __publicField(this, "$$c"); /** Whether or not the custom element is connected */ __publicField(this, "$$cn", false); /** Component props data */ __publicField(this, "$$d", {}); /** `true` if currently in the process of reflecting component props back to attributes */ __publicField(this, "$$r", false); /** @type {Record} Props definition (name, reflected, type etc) */ __publicField(this, "$$p_d", {}); /** @type {Record} Event listeners */ __publicField(this, "$$l", {}); /** @type {Map} Event listener unsubscribe functions */ __publicField(this, "$$l_u", /* @__PURE__ */ new Map()); this.$$ctor = $$componentCtor; this.$$s = $$slots; if (use_shadow_dom) { this.attachShadow({ mode: "open" }); } } addEventListener(type, listener, options) { this.$$l[type] = this.$$l[type] || []; this.$$l[type].push(listener); if (this.$$c) { const unsub = this.$$c.$on(type, listener); this.$$l_u.set(listener, unsub); } super.addEventListener(type, listener, options); } removeEventListener(type, listener, options) { super.removeEventListener(type, listener, options); if (this.$$c) { const unsub = this.$$l_u.get(listener); if (unsub) { unsub(); this.$$l_u.delete(listener); } } } async connectedCallback() { this.$$cn = true; if (!this.$$c) { let create_slot = function(name) { return () => { let node; const obj = { c: function create() { node = element("slot"); if (name !== "default") { attr(node, "name", name); } }, /** * @param {HTMLElement} target * @param {HTMLElement} [anchor] */ m: function mount(target, anchor) { insert(target, node, anchor); }, d: function destroy(detaching) { if (detaching) { detach(node); } } }; return obj; }; }; await Promise.resolve(); if (!this.$$cn || this.$$c) { return; } const $$slots = {}; const existing_slots = get_custom_elements_slots(this); for (const name of this.$$s) { if (name in existing_slots) { $$slots[name] = [create_slot(name)]; } } for (const attribute of this.attributes) { const name = this.$$g_p(attribute.name); if (!(name in this.$$d)) { this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, "toProp"); } } for (const key in this.$$p_d) { if (!(key in this.$$d) && this[key] !== void 0) { this.$$d[key] = this[key]; delete this[key]; } } this.$$c = new this.$$ctor({ target: this.shadowRoot || this, props: { ...this.$$d, $$slots, $$scope: { ctx: [] } } }); const reflect_attributes = () => { this.$$r = true; for (const key in this.$$p_d) { this.$$d[key] = this.$$c.$$.ctx[this.$$c.$$.props[key]]; if (this.$$p_d[key].reflect) { const attribute_value = get_custom_element_value( key, this.$$d[key], this.$$p_d, "toAttribute" ); if (attribute_value == null) { this.removeAttribute(this.$$p_d[key].attribute || key); } else { this.setAttribute(this.$$p_d[key].attribute || key, attribute_value); } } } this.$$r = false; }; this.$$c.$$.after_update.push(reflect_attributes); reflect_attributes(); for (const type in this.$$l) { for (const listener of this.$$l[type]) { const unsub = this.$$c.$on(type, listener); this.$$l_u.set(listener, unsub); } } this.$$l = {}; } } // We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte // and setting attributes through setAttribute etc, this is helpful attributeChangedCallback(attr2, _oldValue, newValue) { if (this.$$r) return; attr2 = this.$$g_p(attr2); this.$$d[attr2] = get_custom_element_value(attr2, newValue, this.$$p_d, "toProp"); this.$$c?.$set({ [attr2]: this.$$d[attr2] }); } disconnectedCallback() { this.$$cn = false; Promise.resolve().then(() => { if (!this.$$cn && this.$$c) { this.$$c.$destroy(); this.$$c = void 0; } }); } $$g_p(attribute_name) { return Object.keys(this.$$p_d).find( (key) => this.$$p_d[key].attribute === attribute_name || !this.$$p_d[key].attribute && key.toLowerCase() === attribute_name ) || attribute_name; } }; } function get_custom_element_value(prop, value, props_definition, transform) { const type = props_definition[prop]?.type; value = type === "Boolean" && typeof value !== "boolean" ? value != null : value; if (!transform || !props_definition[prop]) { return value; } else if (transform === "toAttribute") { switch (type) { case "Object": case "Array": return value == null ? null : JSON.stringify(value); case "Boolean": return value ? "" : null; case "Number": return value == null ? null : value; default: return value; } } else { switch (type) { case "Object": case "Array": return value && JSON.parse(value); case "Boolean": return value; case "Number": return value != null ? +value : value; default: return value; } } } var SvelteComponent = class { constructor() { /** * ### PRIVATE API * * Do not use, may change at any time * * @type {any} */ __publicField(this, "$$"); /** * ### PRIVATE API * * Do not use, may change at any time * * @type {any} */ __publicField(this, "$$set"); } /** @returns {void} */ $destroy() { destroy_component(this, 1); this.$destroy = noop; } /** * @template {Extract} K * @param {K} type * @param {((e: Events[K]) => void) | null | undefined} callback * @returns {() => void} */ $on(type, callback) { if (!is_function(callback)) { return noop; } const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []); callbacks.push(callback); return () => { const index = callbacks.indexOf(callback); if (index !== -1) callbacks.splice(index, 1); }; } /** * @param {Partial} props * @returns {void} */ $set(props) { if (this.$$set && !is_empty(props)) { this.$$.skip_bound = true; this.$$set(props); this.$$.skip_bound = false; } } }; // node_modules/svelte/src/shared/version.js var PUBLIC_VERSION = "4"; // node_modules/svelte/src/runtime/internal/disclose-version/index.js if (typeof window !== "undefined") (window.__svelte || (window.__svelte = { v: /* @__PURE__ */ new Set() })).v.add(PUBLIC_VERSION); // src/ui/HotKeyEntry.svelte var import_obsidian4 = require("obsidian"); // src/ui/HotkeySetting.svelte var import_obsidian3 = require("obsidian"); // src/utils/Keymap.ts var import_obsidian2 = require("obsidian"); var CODE_KEY_MAP = { Semicolon: ";", Quote: "'", Comma: ",", Period: ".", Slash: "/", BracketLeft: "[", BracketRight: "]", BackSlash: "\\", Backquote: "`", Space: " ", Minus: "-", Equal: "=" }; for (let i = 0; i < 10; i++) { CODE_KEY_MAP[`Digit${i}`] = i.toString(); } for (let i = 65; i < 91; i++) { const char = String.fromCharCode(i); const upChar = char.toUpperCase(); CODE_KEY_MAP[`Key${upChar}`] = char; } function convertCodeToKey(code) { return CODE_KEY_MAP[code] ?? code; } function convertKeyToText(key) { switch (key) { case "ArrowLeft": return "\u2190"; case "ArrowRight": return "\u2192"; case "ArrowUp": return "\u2191"; case "ArrowDown": return "\u2193"; case "Mod": return import_obsidian2.Platform.isMacOS ? "\u2318" : "Ctrl"; case "Ctrl": return import_obsidian2.Platform.isMacOS ? "\u2303" : "Ctrl"; case "Meta": return import_obsidian2.Platform.isMacOS ? "\u2318" : "Win"; case "Alt": return import_obsidian2.Platform.isMacOS ? "\u2325" : "Alt"; case "Shift": return import_obsidian2.Platform.isMacOS ? "\u21E7" : "Shift"; case " ": return "Space"; case "Enter": return "\u21B5"; default: return key.charAt(0).toUpperCase() + key.slice(1); } } function convertHotkeyToText(hotkey) { const parts = []; hotkey.modifiers.forEach((mod) => { parts.push(convertKeyToText(mod)); }); const modifierPart = parts.join(" "); const keyPart = convertKeyToText(hotkey.key); return ` ${modifierPart} ${keyPart} `; } function compileModifiers(modifiers) { return modifiers.map((modifier) => { return "Mod" === modifier ? import_obsidian2.Platform.isMacOS ? "Meta" : "Ctrl" : modifier; }).sort().join(","); } function decompileModifiers(modifiersId) { const modifiers = []; const parts = modifiersId.split(","); parts.forEach((s) => { if (import_obsidian2.Platform.isMacOS && s === "Meta" || !import_obsidian2.Platform.isMacOS && s === "Ctrl") { modifiers.push("Mod"); return; } if (s === "Alt" || s === "Shift" || s === "Meta" || s === "Ctrl") { modifiers.push(s); return; } }); return modifiers; } function getModifiers(evt) { const modifiers = []; evt.ctrlKey && modifiers.push("Ctrl"); evt.metaKey && modifiers.push("Meta"); evt.altKey && modifiers.push("Alt"); evt.shiftKey && modifiers.push("Shift"); return compileModifiers(modifiers); } function getHotkey(evt) { const modifiers = decompileModifiers(getModifiers(evt)); const key = convertCodeToKey(evt.code); return { modifiers, key }; } function contain(hotkeys, hotkey) { const hotkeyId = convertHotkeyToText(hotkey); return hotkeys.some((key) => { return hotkeyId === convertHotkeyToText(key); }); } // src/ui/HotkeySetting.svelte function add_css(target) { append_styles(target, "svelte-2wacg2", ".icon-container.svelte-2wacg2{display:inline-block;cursor:pointer;width:16px;height:16px;border-radius:10px;line-height:16px;text-align:center}.icon-container.svelte-2wacg2:hover{background-color:var(--background-modifier-error);color:var(--text-on-accent)}.setting-hotkey.svelte-2wacg2{font-size:12px;background-color:var(--background-secondary-alt);border-radius:4px;padding:0 10px;min-height:24px;align-self:flex-end;position:relative}"); } function create_fragment(ctx) { let span1; let t0_value = convertHotkeyToText( /*hotkey*/ ctx[0] ) + ""; let t0; let t1; let span0; let mounted; let dispose; return { c() { span1 = element("span"); t0 = text(t0_value); t1 = space(); span0 = element("span"); attr(span0, "class", "icon-container svelte-2wacg2"); attr(span1, "class", "setting-hotkey svelte-2wacg2"); }, m(target, anchor) { insert(target, span1, anchor); append(span1, t0); append(span1, t1); append(span1, span0); ctx[3](span0); if (!mounted) { dispose = listen( span0, "click", /*onIconClicked*/ ctx[2] ); mounted = true; } }, p(ctx2, [dirty]) { if (dirty & /*hotkey*/ 1 && t0_value !== (t0_value = convertHotkeyToText( /*hotkey*/ ctx2[0] ) + "")) set_data(t0, t0_value); }, i: noop, o: noop, d(detaching) { if (detaching) { detach(span1); } ctx[3](null); mounted = false; dispose(); } }; } function instance($$self, $$props, $$invalidate) { let { hotkey } = $$props; let iconContainerEl; const dispatcher = createEventDispatcher(); onMount(() => { if (iconContainerEl instanceof HTMLSpanElement) { (0, import_obsidian3.setIcon)(iconContainerEl, "cross", 8); } }); function onIconClicked() { dispatcher("removed"); } function span0_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { iconContainerEl = $$value; $$invalidate(1, iconContainerEl); }); } $$self.$$set = ($$props2) => { if ("hotkey" in $$props2) $$invalidate(0, hotkey = $$props2.hotkey); }; return [hotkey, iconContainerEl, onIconClicked, span0_binding]; } var HotkeySetting = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance, create_fragment, safe_not_equal, { hotkey: 0 }, add_css); } }; var HotkeySetting_default = HotkeySetting; // src/ui/HotKeyEntry.svelte function add_css2(target) { append_styles(target, "svelte-1my40ui", ".item-container.svelte-1my40ui{display:flex;align-items:center;padding:18px 0 18px 0;border-top:1px solid var(--background-modifier-border)}.info-container.svelte-1my40ui{flex:1 1 auto;flex-grow:1;margin-right:20px}.control-container.svelte-1my40ui{flex:1 1 auto;text-align:right;display:flex;justify-content:flex-end;align-items:center}.hotkeys-container.svelte-1my40ui{display:flex;flex-direction:column;margin-right:6px}.setting-hotkey.svelte-1my40ui{font-size:12px;background-color:var(--interactive-accent);border-radius:4px;padding:0 10px;min-height:24px;align-self:flex-end;position:relative;color:var(--text-on-accent)}.icon-container.svelte-1my40ui{padding:4px 6px;border-radius:4px;color:var(--text-faint);cursor:pointer;height:26px}.icon-container.svelte-1my40ui:hover{background-color:var(--background-secondary-alt);color:var(--text-normal)}.icon-container.svelte-1my40ui .clickable-icon{color:unset;cursor:unset;margin:unset}.icon-container.svelte-1my40ui .setting-editor-extra-setting-button{line-height:0}.icon-container.svelte-1my40ui .clickable-icon svg{position:relative;bottom:2px}"); } function get_each_context(ctx, list, i) { const child_ctx = ctx.slice(); child_ctx[13] = list[i]; return child_ctx; } function create_each_block(ctx) { let hotkeysetting; let current; function removed_handler() { return ( /*removed_handler*/ ctx[8]( /*hotkey*/ ctx[13] ) ); } hotkeysetting = new HotkeySetting_default({ props: { hotkey: ( /*hotkey*/ ctx[13] ) } }); hotkeysetting.$on("removed", removed_handler); return { c() { create_component(hotkeysetting.$$.fragment); }, m(target, anchor) { mount_component(hotkeysetting, target, anchor); current = true; }, p(new_ctx, dirty) { ctx = new_ctx; const hotkeysetting_changes = {}; if (dirty & /*_hotkeys*/ 16) hotkeysetting_changes.hotkey = /*hotkey*/ ctx[13]; hotkeysetting.$set(hotkeysetting_changes); }, i(local) { if (current) return; transition_in(hotkeysetting.$$.fragment, local); current = true; }, o(local) { transition_out(hotkeysetting.$$.fragment, local); current = false; }, d(detaching) { destroy_component(hotkeysetting, detaching); } }; } function create_if_block(ctx) { let div; return { c() { div = element("div"); div.textContent = "Press hotkey..."; attr(div, "class", "setting-hotkey svelte-1my40ui"); }, m(target, anchor) { insert(target, div, anchor); }, d(detaching) { if (detaching) { detach(div); } } }; } function create_fragment2(ctx) { let div3; let div0; let t0; let t1; let div2; let div1; let t2; let t3; let span0; let t4; let span1; let current; let mounted; let dispose; let each_value = ensure_array_like( /*_hotkeys*/ ctx[4] ?? [] ); let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i)); } const out = (i) => transition_out(each_blocks[i], 1, 1, () => { each_blocks[i] = null; }); let if_block = ( /*_listening*/ ctx[3] && create_if_block(ctx) ); return { c() { div3 = element("div"); div0 = element("div"); t0 = text( /*actionName*/ ctx[0] ); t1 = space(); div2 = element("div"); div1 = element("div"); for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } t2 = space(); if (if_block) if_block.c(); t3 = space(); span0 = element("span"); t4 = space(); span1 = element("span"); attr(div0, "class", "info-container svelte-1my40ui"); attr(div1, "class", "hotkeys-container svelte-1my40ui"); attr(span0, "class", "icon-container svelte-1my40ui"); attr(span1, "class", "icon-container svelte-1my40ui"); attr(div2, "class", "control-container svelte-1my40ui"); attr(div3, "class", "item-container svelte-1my40ui"); }, m(target, anchor) { insert(target, div3, anchor); append(div3, div0); append(div0, t0); append(div3, t1); append(div3, div2); append(div2, div1); for (let i = 0; i < each_blocks.length; i += 1) { if (each_blocks[i]) { each_blocks[i].m(div1, null); } } append(div1, t2); if (if_block) if_block.m(div1, null); append(div2, t3); append(div2, span0); ctx[9](span0); append(div2, t4); append(div2, span1); ctx[11](span1); current = true; if (!mounted) { dispose = [ listen( span0, "click", /*click_handler*/ ctx[10] ), listen( span1, "click", /*click_handler_1*/ ctx[12] ) ]; mounted = true; } }, p(ctx2, [dirty]) { if (!current || dirty & /*actionName*/ 1) set_data( t0, /*actionName*/ ctx2[0] ); if (dirty & /*_hotkeys, dispatcher*/ 48) { each_value = ensure_array_like( /*_hotkeys*/ ctx2[4] ?? [] ); let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context(ctx2, each_value, i); if (each_blocks[i]) { each_blocks[i].p(child_ctx, dirty); transition_in(each_blocks[i], 1); } else { each_blocks[i] = create_each_block(child_ctx); each_blocks[i].c(); transition_in(each_blocks[i], 1); each_blocks[i].m(div1, t2); } } group_outros(); for (i = each_value.length; i < each_blocks.length; i += 1) { out(i); } check_outros(); } if ( /*_listening*/ ctx2[3] ) { if (if_block) { } else { if_block = create_if_block(ctx2); if_block.c(); if_block.m(div1, null); } } else if (if_block) { if_block.d(1); if_block = null; } }, i(local) { if (current) return; for (let i = 0; i < each_value.length; i += 1) { transition_in(each_blocks[i]); } current = true; }, o(local) { each_blocks = each_blocks.filter(Boolean); for (let i = 0; i < each_blocks.length; i += 1) { transition_out(each_blocks[i]); } current = false; }, d(detaching) { if (detaching) { detach(div3); } destroy_each(each_blocks, detaching); if (if_block) if_block.d(); ctx[9](null); ctx[11](null); mounted = false; run_all(dispose); } }; } var ICON_SIZE = 22; function instance2($$self, $$props, $$invalidate) { let _hotkeys; let _listening; let { actionName } = $$props; let { hotkeys } = $$props; const listening = false; let restoreButtonEl; let addHotkeyButtonEl; const dispatcher = createEventDispatcher(); onMount(() => { if (restoreButtonEl) { const component = new import_obsidian4.ExtraButtonComponent(restoreButtonEl).setTooltip("Restore default"); (0, import_obsidian4.setIcon)(component.extraSettingsEl, "reset", ICON_SIZE); } if (addHotkeyButtonEl) { const component = new import_obsidian4.ExtraButtonComponent(addHotkeyButtonEl).setTooltip("Customize this action"); (0, import_obsidian4.setIcon)(component.extraSettingsEl, "any-key", ICON_SIZE); } }); const removed_handler = (hotkey) => { dispatcher("removed", { removed: hotkey }); }; function span0_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { restoreButtonEl = $$value; $$invalidate(1, restoreButtonEl); }); } const click_handler = () => { dispatcher("restored"); }; function span1_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { addHotkeyButtonEl = $$value; $$invalidate(2, addHotkeyButtonEl); }); } const click_handler_1 = () => { dispatcher("start-listening-keys"); }; $$self.$$set = ($$props2) => { if ("actionName" in $$props2) $$invalidate(0, actionName = $$props2.actionName); if ("hotkeys" in $$props2) $$invalidate(6, hotkeys = $$props2.hotkeys); }; $$self.$$.update = () => { if ($$self.$$.dirty & /*hotkeys*/ 64) { $: $$invalidate(4, _hotkeys = [...hotkeys ?? []]); } }; $: $$invalidate(3, _listening = listening); return [ actionName, restoreButtonEl, addHotkeyButtonEl, _listening, _hotkeys, dispatcher, hotkeys, listening, removed_handler, span0_binding, click_handler, span1_binding, click_handler_1 ]; } var HotKeyEntry = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance2, create_fragment2, safe_not_equal, { actionName: 0, hotkeys: 6, listening: 7 }, add_css2); } get listening() { return this.$$.ctx[7]; } }; var HotKeyEntry_default = HotKeyEntry; // src/ui/HotkeySetter.ts var HotkeySetter = class { constructor(app2, containerEl, text2, currentHotkeys, defaultHotkeys) { this.shouldReflect = (_) => true; this.onRestored = () => { const { component } = this; if (!component) return; const renewed = [...this.defaultHotkeys]; if (this.shouldReflect(renewed)) { this.currentHotkeys = renewed; component.$set({ hotkeys: renewed }); } }; this.onRemoved = (evt) => { const { component } = this; if (!component) return; if (!(evt instanceof CustomEvent)) return; const removed = evt.detail.removed; const renewed = [...this.currentHotkeys]; renewed.remove(removed); if (this.shouldReflect(renewed)) { this.currentHotkeys = renewed; component.$set({ hotkeys: renewed }); } }; this.onStartListening = () => { const { component } = this; if (!component) return; component.$set({ listening: true }); this.scope = new import_obsidian5.Scope(); this.app.keymap.pushScope(this.scope); this.scope.register(null, null, (evt) => { evt.preventDefault(); if (evt.key === "Escape") { component.$set({ listening: false }); if (this.scope) this.app.keymap.popScope(this.scope); return; } const hotkey = getHotkey(evt); const collision = contain(this.currentHotkeys, hotkey); if (collision) return; const renewed = [...this.currentHotkeys]; renewed.push(hotkey); if (!this.shouldReflect(renewed, hotkey)) return; this.currentHotkeys = renewed; component.$set({ hotkeys: renewed }); component.$set({ listening: false }); if (this.scope) this.app.keymap.popScope(this.scope); }); }; this.app = app2; this.containerEl = containerEl; this.text = text2; this.currentHotkeys = [...currentHotkeys]; this.defaultHotkeys = [...defaultHotkeys]; this.component = this.attachComponent(); } unload() { this.onunload(); } /** * @param cb : should return true if you want to adopt the current change */ onChanged(cb) { this.shouldReflect = cb; return this; } attachComponent() { const component = new HotKeyEntry_default({ target: this.containerEl, props: { actionName: this.text, hotkeys: this.currentHotkeys } }); component.$on("removed", this.onRemoved); component.$on("restored", this.onRestored); component.$on("start-listening-keys", this.onStartListening); return component; } onunload() { this.component?.$destroy(); if (this.scope) { this.app.keymap.popScope(this.scope); } } }; // src/Setting.ts var AVAILABLE_OUTLINE_WIDTHS = [0, 3, 5, 7, 10]; var AUTO_PREVIEW_MODE_IDS = ["none", "singleView", "cardView"]; var autoPreviewModeInfos = { none: "none", singleView: "single view", cardView: "card view" }; var AVAILABLE_CARD_LAYOUT = ["2x2", "2x3", "3x2", "3x3"]; var DEFAULT_SETTINGS = { keepSelectedItemsCentered: false, outlineWidth: 5, autoPreviewMode: "cardView", cardViewLayout: "2x3", splitDirection: "horizontal", autoToggleSidebar: false, renderCardsManually: false, // hideIframe: false, searchModeHotkeys: { selectNext: [ { modifiers: ["Ctrl"], key: "n" }, { modifiers: [], key: "ArrowDown" } ], selectPrevious: [ { modifiers: ["Ctrl"], key: "p" }, { modifiers: [], key: "ArrowUp" } ], previewModal: [{ modifiers: ["Ctrl"], key: " " }], open: [{ modifiers: ["Ctrl"], key: "Enter" }], openInNewPane: [{ modifiers: ["Ctrl", "Shift"], key: "Enter" }], showOptions: [{ modifiers: ["Shift"], key: " " }], nextPage: [{ modifiers: ["Ctrl"], key: "]" }], previousPage: [{ modifiers: ["Ctrl"], key: "[" }], copyLink: [{ modifiers: ["Ctrl"], key: "i" }] }, previewModalHotkeys: { scrollDown: [ { modifiers: ["Ctrl"], key: "n" }, { modifiers: [], key: "ArrowDown" } ], scrollUp: [ { modifiers: ["Ctrl"], key: "p" }, { modifiers: [], key: "ArrowUp" } ], bigScrollDown: [{ modifiers: [], key: " " }], bigScrollUp: [{ modifiers: ["Shift"], key: " " }], open: [{ modifiers: ["Ctrl"], key: "Enter" }], openInNewPage: [{ modifiers: ["Ctrl", "Shift"], key: "Enter" }], closeModal: [{ modifiers: ["Ctrl"], key: " " }], focusNext: [{ modifiers: [], key: "Tab" }], focusPrevious: [{ modifiers: ["Shift"], key: "Tab" }], togglePreviewMode: [{ modifiers: ["Ctrl"], key: "e" }], copyLink: [{ modifiers: ["Ctrl"], key: "i" }] } }; var CoreSearchAssistantSettingTab = class extends import_obsidian6.PluginSettingTab { constructor(app2, plugin2) { super(app2, plugin2); this.plugin = plugin2; this.hotkeySetters = []; } display() { this.hide(); const { containerEl } = this; containerEl.empty(); new import_obsidian6.Setting(containerEl).setName("Keep selected item centered").addToggle((component) => { component.setValue( this.plugin.settings?.keepSelectedItemsCentered ?? DEFAULT_SETTINGS.keepSelectedItemsCentered ).onChange((value) => { if (!this.plugin.settings) { return; } this.plugin.settings.keepSelectedItemsCentered = value; this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Outline width (px)").setDesc("An outline appears when you enter search mode.").addDropdown((component) => { AVAILABLE_OUTLINE_WIDTHS.forEach((width) => { const text2 = width.toString(); component.addOption(text2, text2); }); component.setValue( validOutlineWidth(this.plugin.settings?.outlineWidth).toString() ).onChange((value) => { const width = Number.parseInt(value); if (!this.plugin.settings) { return; } if (!AVAILABLE_OUTLINE_WIDTHS.includes(width)) { return; } this.plugin.settings.outlineWidth = width; this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Auto preview mode").addDropdown((component) => { component.addOptions(autoPreviewModeInfos).setValue(this.plugin.settings?.autoPreviewMode ?? "cardView").onChange((id) => { if (!this.plugin.settings) { return; } if (!AUTO_PREVIEW_MODE_IDS.includes(id)) { return; } this.plugin.settings.autoPreviewMode = id; this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Default layout of card view").addDropdown((component) => { AVAILABLE_CARD_LAYOUT.forEach((layout) => { component.addOption(layout, layout); }); component.setValue( this.plugin.settings?.cardViewLayout ?? DEFAULT_SETTINGS.cardViewLayout ).onChange((value) => { if (!this.plugin.settings) { return; } if (!AVAILABLE_CARD_LAYOUT.includes(value)) { return; } this.plugin.settings.cardViewLayout = value; this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Default split direction").setDesc("This applies when you open a file in a new pane").addDropdown((component) => { if (!this.plugin.settings) { return; } component.addOptions({ horizontal: "horizontal", vertical: "vertical" }).setValue(this.plugin.settings.splitDirection).onChange(async (direction) => { if (!this.plugin.settings) { return; } if (direction === "horizontal" || direction === "vertical") { this.plugin.settings.splitDirection = direction; await this.plugin.saveSettings(); } }); }); new import_obsidian6.Setting(containerEl).setName("Toggle sidebars automatically").setDesc( "Automatically collapse the other sidebar when entering the search mode and the search panel when exiting the search mode" ).addToggle((component) => { if (!this.plugin.settings) { return; } component.setValue(this.plugin.settings.autoToggleSidebar).onChange((value) => { if (!this.plugin.settings) { return; } this.plugin.settings.autoToggleSidebar = value; this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Render cards manually").setDesc("If enabled, you must hit the enter key to render cards.").addToggle((component) => { if (!this.plugin.settings) return; component.setValue(this.plugin.settings.renderCardsManually).onChange((value) => { if (!this.plugin.settings) return; this.plugin.settings.renderCardsManually = value; this.plugin.saveSettings(); }); }); containerEl.createEl("h2", { text: "Hotkeys" }); const { settings } = this.plugin; containerEl.createEl("h3", { text: "Search mode" }); if (!settings) return; SEARCH_MODE_HOTKEY_ACTION_IDS.forEach((actionId) => { const hotkeys = settings.searchModeHotkeys[actionId]; const defaultHotkeys = DEFAULT_SETTINGS.searchModeHotkeys[actionId]; const description = SEARCH_MODE_HOTKEY_ACTION_INFO[actionId]; const hotkeySetter = new HotkeySetter( this.app, containerEl, description, hotkeys, defaultHotkeys ).onChanged((renewed, added) => { if (added) { if (added.modifiers.length === 0) return false; const collision = SEARCH_MODE_HOTKEY_ACTION_IDS.some((actionId2) => { const hotkeys2 = settings.searchModeHotkeys[actionId2]; return contain(hotkeys2, added); }); if (collision) { new import_obsidian6.Notice("Hotkeys are conflicting!"); return false; } } settings.searchModeHotkeys[actionId] = renewed; this.plugin.saveSettings(); return true; }); this.hotkeySetters.push(hotkeySetter); }); containerEl.createEl("h3", { text: "Preview Modal" }); PREVIEW_MODAL_HOTKEY_ACTION_IDS.forEach((actionId) => { const hotkeys = settings.previewModalHotkeys[actionId]; const defaultHotkeys = DEFAULT_SETTINGS.previewModalHotkeys[actionId]; const description = PREVIEW_MODAL_HOTKEY_ACTION_INFO[actionId]; DEFAULT_SETTINGS.previewModalHotkeys[actionId]; const hotkeySetter = new HotkeySetter( this.app, containerEl, description, hotkeys, defaultHotkeys ).onChanged((renewed, added) => { if (added) { const collision = PREVIEW_MODAL_HOTKEY_ACTION_IDS.some((actionId2) => { const hotkeys2 = settings.previewModalHotkeys[actionId2]; return contain(hotkeys2, added); }); if (collision) { new import_obsidian6.Notice("Hotkeys are conflicting!"); return false; } } settings.previewModalHotkeys[actionId] = renewed; this.plugin.saveSettings(); return true; }); this.hotkeySetters.push(hotkeySetter); }); } hide() { super.hide(); this.hotkeySetters.forEach((s) => s.unload()); this.hotkeySetters = []; } }; function validOutlineWidth(width) { if (typeof width !== "number") { return DEFAULT_SETTINGS.outlineWidth; } if (!Number.isInteger(width)) { return DEFAULT_SETTINGS.outlineWidth; } if (!AVAILABLE_OUTLINE_WIDTHS.includes(width)) { return DEFAULT_SETTINGS.outlineWidth; } return width; } function parseCardLayout(layout) { const [row, column] = layout.split("x"); return [Number.parseInt(row ?? "0"), Number.parseInt(column ?? "0")]; } var SEARCH_MODE_HOTKEY_ACTION_IDS = [ "selectNext", "selectPrevious", "previewModal", "open", "openInNewPane", "showOptions", "nextPage", "previousPage", "copyLink" ]; var SEARCH_MODE_HOTKEY_ACTION_INFO = { selectNext: "Select the next item", selectPrevious: "Select the previous item", previewModal: "Preview the selected item", open: "Open the selected item", openInNewPane: "Open the selected item in a new pane", showOptions: "Set search options", nextPage: "Move to the next set of cards", previousPage: "Move to the previous set of cards", copyLink: "Copy wiki link of the selected item" }; var PREVIEW_MODAL_HOTKEY_ACTION_IDS = [ "scrollDown", "scrollUp", "bigScrollDown", "bigScrollUp", "open", "openInNewPage", "closeModal", "focusNext", "focusPrevious", "togglePreviewMode", "copyLink" ]; var PREVIEW_MODAL_HOTKEY_ACTION_INFO = { scrollDown: "Scroll down a bit", scrollUp: "Scroll up a bit", bigScrollDown: "Scroll down a lot", bigScrollUp: "Scroll up a lot", open: "Open the selected item", openInNewPage: "Open the selected item in a new pane", closeModal: "Close the modal", focusNext: "Focus on the next match", focusPrevious: "Focus on the previous match", togglePreviewMode: "Toggle preview mode", copyLink: "Copy wiki link of the selected item" }; // src/components/OptionModal.ts var import_obsidian7 = require("obsidian"); // src/types/Option.ts var searchOptions = { matchingCase: { iconId: "uppercase-lowercase-a", description: "Toggle matching case" }, explainSearch: { iconId: "info", description: "Toggle explanation of search term" }, collapseAll: { iconId: "bullet-list", description: "Toggle collapsing results" }, extraContext: { iconId: "expand-vertically", description: "Toggle showing more context" }, alphabetical: { iconId: "down-arrow-with-tail", description: "Sort by file name (A \u2192 Z)" }, alphabeticalReverse: { iconId: "up-arrow-with-tail", description: "Sort by file name (Z \u2192 A)" }, byModifiedTime: { iconId: "down-arrow-with-tail", description: "Sort by modified time (new \u2192 old)" }, byModifiedTimeReverse: { iconId: "up-arrow-with-tail", description: "Sort by modified time (old \u2192 new)" }, byCreatedTime: { iconId: "down-arrow-with-tail", description: "Sort by created time (new \u2192 old)" }, byCreatedTimeReverse: { iconId: "up-arrow-with-tail", description: "Sort by created time (old \u2192 new)" } }; // src/components/OptionModal.ts var OptionModal = class extends import_obsidian7.Modal { constructor(app2, plugin2, modeScope) { super(app2); this.plugin = plugin2; this.modeScope = modeScope; this.items = [ { id: "matchingCase", key: "a", onChoose: () => { this.plugin.searchInterface?.toggleMatchingCase(); this.plugin.searchInterface?.renewSortOrderInfo(); this.plugin.controller?.reset(); } }, { id: "explainSearch", key: "s", onChoose: () => { this.plugin.searchInterface?.toggleExplainSearch(); } }, { id: "collapseAll", key: "d", onChoose: () => { this.plugin.searchInterface?.toggleCollapseAll(); } }, { id: "extraContext", key: "f", onChoose: () => { this.plugin.searchInterface?.toggleExtraContext(); } }, { id: "alphabetical", key: "g", onChoose: () => { const changed = this.plugin.searchInterface?.setSortOrder("alphabetical"); if (changed) { this.plugin.searchInterface?.renewSortOrderInfo(); this.plugin.controller?.reset(); } } }, { id: "alphabeticalReverse", key: "h", onChoose: () => { const changed = this.plugin.searchInterface?.setSortOrder( "alphabeticalReverse" ); if (changed) { this.plugin.searchInterface?.renewSortOrderInfo(); this.plugin.controller?.reset(); } } }, { id: "byModifiedTime", key: "j", onChoose: () => { const changed = this.plugin.searchInterface?.setSortOrder("byModifiedTime"); if (changed) { this.plugin.searchInterface?.renewSortOrderInfo(); this.plugin.controller?.reset(); } } }, { id: "byModifiedTimeReverse", key: "k", onChoose: () => { const changed = this.plugin.searchInterface?.setSortOrder( "byModifiedTimeReverse" ); if (changed) { this.plugin.searchInterface?.renewSortOrderInfo(); this.plugin.controller?.reset(); } } }, { id: "byCreatedTime", key: "l", onChoose: () => { const changed = this.plugin.searchInterface?.setSortOrder("byCreatedTime"); if (changed) { this.plugin.searchInterface?.renewSortOrderInfo(); this.plugin.controller?.reset(); } } }, { id: "byCreatedTimeReverse", key: ";", onChoose: () => { const changed = this.plugin.searchInterface?.setSortOrder( "byCreatedTimeReverse" ); if (changed) { this.plugin.searchInterface?.renewSortOrderInfo(); this.plugin.controller?.reset(); } } } ]; } onOpen() { this.modeScope.push(); this.items.forEach((item) => { this.scope.register([], item.key, item.onChoose); }); this.renderOptions(); } onClose() { const { containerEl } = this; containerEl.empty(); setTimeout(() => this.modeScope.pop(), 100); } renderOptions() { const { contentEl } = this; contentEl.empty(); this.containerEl.addClass("core-search-assistant_option-modal"); this.items.forEach((item) => { const entryEl = contentEl.createEl("div", { cls: "suggestion-item" }); const iconEl = entryEl.createEl("span", { cls: "suggestion-icon" }); (0, import_obsidian7.setIcon)(iconEl, searchOptions[item.id].iconId); entryEl.createEl("span", { text: searchOptions[item.id].description, cls: "suggestion-content" }); entryEl.createEl("kbd", { text: item.key.toUpperCase(), cls: "suggestion-hotkey" }); }); } }; // src/components/PreviewModal.ts var import_obsidian13 = require("obsidian"); // src/interfaces/ViewGenerator.ts var import_obsidian8 = require("obsidian"); // src/utils/Util.ts async function delay(millisecond) { await new Promise((resolve) => setTimeout(resolve, millisecond)); } function scrollIteration(editor) { const line = lineCount(editor); if (line === void 0) { return void 0; } return Math.max(Math.floor(line / 1e3), 1); } function lineCount(editor) { const line = editor?.cm?.state?.doc?.length; return typeof line === "number" ? line : void 0; } async function retry(cb, interval, trials, check = (got) => got !== void 0) { for (let i = 0; i < trials; i++) { const got = cb(); if (check(got)) { return got; } await delay(interval); } return void 0; } function shallowClone(obj) { return Object.assign({}, obj); } function deepClone(obj) { if (obj === null) return obj; if (typeof obj !== "object") return obj; if (Array.isArray(obj)) { const clone2 = new Array(obj.length); obj.forEach((value, id) => { clone2[id] = deepClone(value); }); return clone2; } const clone = shallowClone(obj); for (const key in clone) { const value = clone[key]; clone[key] = deepClone(value); } return clone; } function deepMerge(a, b) { if (b === void 0) { return deepClone(a); } if (a === void 0) { return deepClone(b); } if (typeof a !== typeof b) { throw new Error(`failed to deepMerge ${a} and ${b}`); } if (typeof b !== "object") return deepClone(b); if (b === null) { return deepClone(a); } if (a === null) { return deepClone(b); } if (Array.isArray(b)) { if (Array.isArray(a)) { return deepClone(b); } throw new Error(`failed to deepMerge ${a} and ${b}`); } if (Array.isArray(a)) { throw new Error(`failed to deepMerge ${a} and ${b}`); } const clone = shallowClone(a); for (const key in a) { clone[key] = deepMerge(a[key], b[key]); } for (const key in b) { clone[key] = deepMerge(a[key], b[key]); } return clone; } // src/interfaces/ViewGenerator.ts var ViewGenerator = class { constructor(app2, containerEl, file) { this.extensions = []; this.app = app2; this.containerEl = containerEl; this.leaf = new import_obsidian8.WorkspaceLeaf(this.app); this.file = file; } async load(mode) { await this.onload(mode); return this; } async unload() { this.onunload(); } async toggleViewMode() { for (const ext of this.extensions) { if (!await ext.isMine(this.leaf)) continue; await ext.toggleViewMode(this.leaf); return; } } async onload(mode) { const fileType = fileTypeMap[this.file.extension]; if (!fileType) return; this.containerEl.appendChild(this.leaf.containerEl); await this.openFile(); for (const ext of this.extensions) { if (!await ext.isMine(this.leaf)) continue; await ext.setViewMode(this.leaf, mode ?? "preview"); return; } } onunload() { this.leaf.detach(); } async openFile() { const { leaf, file } = this; await leaf.openFile(file); } // it should be called once because is is not idempotent // it can be called even when view mode = 'preview' highlightMatches(matches, cls) { const view = this.leaf.view; if (!(view instanceof import_obsidian8.MarkdownView)) { return; } const editor = view.editor; const ranges = []; matches.forEach((match) => { const range = { from: editor.offsetToPos(match[0]), to: editor.offsetToPos(match[1]) }; ranges.push(range); }); editor.addHighlights(ranges, cls); } async scrollIntoView(match, center) { const view = this.leaf.view; if (!(view instanceof import_obsidian8.MarkdownView)) { return; } if (view.getMode() !== "source") { return; } const editor = view.editor; const range = { from: editor.offsetToPos(match[0]), to: editor.offsetToPos(match[1]) }; const iter = scrollIteration(editor); if (iter === void 0) { return; } for (let i = 0; i < iter; i++) { editor.scrollIntoView(range, center); await delay(1); } } async focusOn(match, cls, center) { const view = this.leaf.view; if (!(view instanceof import_obsidian8.MarkdownView)) { return; } if (view.getMode() !== "source") { return; } await this.scrollIntoView(match, center); const { editor } = view; editor.removeHighlights(cls); const range = { from: editor.offsetToPos(match[0]), to: editor.offsetToPos(match[1]) }; editor.addHighlights([range], cls); } registerExtension(ext) { this.extensions.push(ext); return this; } }; var fileTypeMap = { md: "md", png: "image", jpg: "image", jpeg: "image", gif: "image", bmp: "image", svg: "image", webp: "image", mp3: "audio", webm: "audio", wav: "audio", m4a: "audio", ogg: "audio", "3gp": "audio", flac: "audio", mp4: "movie", ogv: "movie", pdf: "pdf" }; // src/interfaces/viewGeneratorExtensions/Excalidraw.ts var import_obsidian9 = require("obsidian"); var excalidrawPluginId = "obsidian-excalidraw-plugin"; var excalidrawViewType = "excalidraw"; var ExcalidrawViewGeneratorExtension = class { constructor(app2) { this.app = app2; const excalidraw = this.app.plugins.plugins[excalidrawPluginId]; if (!isExcalidrawPlugin(excalidraw)) { this.excalidraw = void 0; } else { this.excalidraw = excalidraw; } } isMine(leaf) { return leaf.view.getViewType() === excalidrawViewType; } // https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/109fe05302bde0e8fe4e97c3bad6ca3f51f6b6b1/src/main.ts#L953-L986 async setViewMode(leaf, mode) { const { excalidraw } = this; if (!excalidraw) return; excalidraw.excalidrawFileModes[leaf.id] = "markdown"; await excalidraw.setMarkdownView(leaf); if (!(leaf.view instanceof import_obsidian9.MarkdownView)) return; await leaf.view.setState( { ...leaf.view.getState(), mode }, {} ); leaf.view.editor.blur(); } async toggleViewMode(leaf) { const { excalidraw } = this; if (!excalidraw) return; excalidraw.excalidrawFileModes[leaf.id] = "markdown"; await excalidraw.setMarkdownView(leaf); if (!(leaf.view instanceof import_obsidian9.MarkdownView)) return; const mode = leaf.view.getMode(); await leaf.view.setState( { ...leaf.view.getState(), mode: mode === "preview" ? "source" : "preview" }, {} ); leaf.view.editor.blur(); } }; function isExcalidrawPlugin(plugin2) { if (!(plugin2 instanceof import_obsidian9.Plugin)) return false; const { excalidrawFileModes, setMarkdownView } = plugin2; if (typeof excalidrawFileModes !== "object") return false; if (typeof setMarkdownView !== "function") return false; return true; } // src/interfaces/viewGeneratorExtensions/Kanban.ts var import_obsidian10 = require("obsidian"); var kanbanPluginId = "obsidian-kanban"; var frontMatterKey = "kanban-plugin"; var kanbanViewType = "kanban"; var KanbanViewGeneratorExtension = class { constructor(app2) { this.app = app2; const kanban = this.app.plugins.plugins[kanbanPluginId]; if (IsKanbanPlugin(kanban)) { this.kanban = kanban; } if (kanban === void 0) { this.kanban = void 0; } } isMine(leaf) { const { view } = leaf; if (view.getViewType() === kanbanViewType) return true; if (!(view instanceof import_obsidian10.TextFileView)) return false; const fileCache = this.app.metadataCache.getFileCache(view.file); const fileIsKanban = !!fileCache?.frontmatter && !!fileCache.frontmatter[frontMatterKey]; return fileIsKanban; } // https://github.com/mgmeyers/obsidian-kanban/blob/350fc891a8489f70551d288ae914534424c8c095/src/main.ts#L317-L345 async setViewMode(leaf, mode) { const { kanban } = this; if (!kanban) return; if (mode === "source") { kanban.kanbanFileModes[leaf.id] = "markdown"; await kanban.setMarkdownView(leaf); await leaf.view.setState( { ...leaf.view.getState(), mode: "source" }, {} ); if (leaf.view instanceof import_obsidian10.MarkdownView) { leaf.view.editor.blur(); } } else { kanban.kanbanFileModes[leaf.id] = kanbanViewType; await kanban.setKanbanView(leaf); } } async toggleViewMode(leaf) { const { kanban } = this; if (!kanban) return; const mode = kanban.kanbanFileModes[leaf.id]; await this.setViewMode(leaf, mode === "markdown" ? "preview" : "source"); } }; function IsKanbanPlugin(plugin2) { if (!(plugin2 instanceof import_obsidian10.Plugin)) return false; const { kanbanFileModes, setKanbanView, setMarkdownView } = plugin2; if (typeof kanbanFileModes !== "object") return false; if (typeof setMarkdownView !== "function") return false; if (typeof setKanbanView !== "function") return false; return true; } // src/interfaces/viewGeneratorExtensions/Markdown.ts var import_obsidian11 = require("obsidian"); var MarkdownViewGeneratorExtension = class { isMine(leaf) { return leaf.view instanceof import_obsidian11.MarkdownView; } async setViewMode(leaf, mode) { await leaf.view.setState( { ...leaf.view.getState(), mode }, {} ); } async toggleViewMode(leaf) { if (!(leaf.view instanceof import_obsidian11.MarkdownView)) return; await this.setViewMode( leaf, leaf.view.getMode() === "preview" ? "source" : "preview" ); } }; // src/interfaces/viewGeneratorExtensions/NonMarkdown.ts var import_obsidian12 = require("obsidian"); var NON_MARKDOWN_FILE_TYPES = ["image", "audio", "pdf", "video"]; var NonMarkdownViewGeneratorExtension = class { isMine(leaf) { if (!(leaf.view instanceof import_obsidian12.FileView)) return false; return NON_MARKDOWN_FILE_TYPES.includes( leaf.view.getViewType() ); } setViewMode(_leaf, _mode) { return; } toggleViewMode(_) { return; } }; // node_modules/svelte/src/runtime/store/index.js var subscriber_queue = []; function writable(value, start = noop) { let stop; const subscribers = /* @__PURE__ */ new Set(); function set(new_value) { if (safe_not_equal(value, new_value)) { value = new_value; if (stop) { const run_queue = !subscriber_queue.length; for (const subscriber of subscribers) { subscriber[1](); subscriber_queue.push(subscriber, value); } if (run_queue) { for (let i = 0; i < subscriber_queue.length; i += 2) { subscriber_queue[i][0](subscriber_queue[i + 1]); } subscriber_queue.length = 0; } } } } function update2(fn) { set(fn(value)); } function subscribe2(run2, invalidate = noop) { const subscriber = [run2, invalidate]; subscribers.add(subscriber); if (subscribers.size === 1) { stop = start(set, update2) || noop; } run2(value); return () => { subscribers.delete(subscriber); if (subscribers.size === 0 && stop) { stop(); stop = null; } }; } return { set, update: update2, subscribe: subscribe2 }; } // src/ui/store.ts var app = writable(); var plugin = writable(); // src/ui/PreviewModalContent.svelte function add_css3(target) { append_styles(target, "svelte-6cqu2r", ".core-search-assistant_preview-modal_view-container.svelte-6cqu2r{min-width:700px}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .highlight-search-match{color:var(--highlight-search-match);background-color:var(--highlight-search-match-bg)}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .focus-search-match{background-color:var(--focus-search-match-bg)}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf{contain:initial !important}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .view-content{overflow:unset}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-preview-view{overflow:unset}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf-content{overflow:unset}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf-resize-handle{display:none}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .view-header{display:none}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-preview-view{padding:0}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view{pointer-events:none}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .workspace-leaf-content[data-type='pdf']{height:990px}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view.mod-cm6 .cm-editor{flex:initial;display:initial}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view.mod-cm6{display:initial}.core-search-assistant_preview-modal_view-container.svelte-6cqu2r .markdown-source-view.mod-cm6 .cm-scroller{padding:0}"); } function create_fragment3(ctx) { let div; return { c() { div = element("div"); attr(div, "class", "core-search-assistant_preview-modal_view-container svelte-6cqu2r"); }, m(target, anchor) { insert(target, div, anchor); ctx[5](div); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) { detach(div); } ctx[5](null); } }; } function instance3($$self, $$props, $$invalidate) { let $app; component_subscribe($$self, app, ($$value) => $$invalidate(7, $app = $$value)); let { file } = $$props; let { matches } = $$props; let contentContainerEl; let renderer; onMount(async () => { if (!file) { return; } if (!contentContainerEl) { return; } const fileType = fileTypeMap[file.extension]; if (fileType !== void 0) { contentContainerEl.empty(); renderer = await new ViewGenerator($app, contentContainerEl, file).registerExtension(new ExcalidrawViewGeneratorExtension($app)).registerExtension(new KanbanViewGeneratorExtension($app)).registerExtension(new MarkdownViewGeneratorExtension()).registerExtension(new NonMarkdownViewGeneratorExtension()).load("source"); highlightMatches(); } }); onDestroy(() => { setTimeout(() => renderer?.unload(), 1e3); }); async function toggleViewMode() { await renderer?.toggleViewMode(); } function focusOn(matchId, center) { if (!matches) return; const match = matches[matchId]; if (match === void 0) { return; } renderer?.focusOn(match, "focus-search-match", center); } function highlightMatches() { renderer?.highlightMatches(matches ?? [], "highlight-search-match"); } function div_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { contentContainerEl = $$value; $$invalidate(0, contentContainerEl); }); } $$self.$$set = ($$props2) => { if ("file" in $$props2) $$invalidate(1, file = $$props2.file); if ("matches" in $$props2) $$invalidate(2, matches = $$props2.matches); }; return [contentContainerEl, file, matches, toggleViewMode, focusOn, div_binding]; } var PreviewModalContent = class extends SvelteComponent { constructor(options) { super(); init( this, options, instance3, create_fragment3, safe_not_equal, { file: 1, matches: 2, toggleViewMode: 3, focusOn: 4 }, add_css3 ); } get toggleViewMode() { return this.$$.ctx[3]; } get focusOn() { return this.$$.ctx[4]; } }; var PreviewModalContent_default = PreviewModalContent; // src/utils/Link.ts function generateInternalLinkFrom(app2, file) { const text2 = getDisplayText(app2.metadataCache, file); return app2.fileManager.generateMarkdownLink(file, "", void 0, text2); } function getDisplayText(metadataCache, file) { const cache = metadataCache.getFileCache(file); if (!cache) return void 0; const title = getTitle(cache.frontmatter); if (title !== void 0) { return title; } const h1 = getFirstH1(cache.headings); if (h1 !== void 0) { return h1; } return void 0; } function getTitle(frontmatter) { return frontmatter?.title; } function getFirstH1(headings) { if (!headings) return void 0; for (const heading of headings) { if (heading.level !== 1) continue; return heading.heading; } return void 0; } // src/components/PreviewModal.ts var SCROLL_AMOUNT = 70; var PreviewModal = class extends import_obsidian13.Modal { constructor(app2, plugin2, modeScope, item) { super(app2); this.plugin = plugin2; this.modeScope = modeScope; this.item = item; this.currentFocus = -1; } async onOpen() { await this.renderView(); this.modeScope.push(); const hotkeyMap = this.plugin.settings?.previewModalHotkeys; if (!hotkeyMap) return; hotkeyMap.closeModal.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { this.shouldRestoreSelection = true; this.close(); }); }); hotkeyMap.open.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { this.openAndFocus(this.currentFocus); this.plugin.controller?.exit(); this.shouldRestoreSelection = false; this.close(); }); }); hotkeyMap.openInNewPage.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { this.openAndFocus( this.currentFocus, this.plugin.settings?.splitDirection ); this.plugin.controller?.exit(); this.shouldRestoreSelection = false; this.close(); }); }); hotkeyMap.bigScrollDown.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { this.scroll("down"); }); }); hotkeyMap.bigScrollUp.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { this.scroll("up"); }); }); hotkeyMap.scrollDown.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { this.scroll("down", SCROLL_AMOUNT); }); }); hotkeyMap.scrollUp.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { this.scroll("up", SCROLL_AMOUNT); }); }); hotkeyMap.focusNext.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, (evt) => { evt.preventDefault(); const numMatches = this.countMatches(); if (numMatches === void 0 || numMatches === 0) { return; } this.currentFocus = cyclicId(++this.currentFocus, numMatches); this.previewContent?.focusOn(this.currentFocus, true); }); }); hotkeyMap.focusPrevious.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, (evt) => { evt.preventDefault(); const numMatches = this.countMatches(); if (numMatches === void 0 || numMatches === 0) { return; } this.currentFocus = cyclicId(--this.currentFocus, numMatches); this.previewContent?.focusOn(this.currentFocus, true); }); }); hotkeyMap.togglePreviewMode.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, (evt) => { (async () => { evt.preventDefault(); await this.previewContent?.toggleViewMode(); })(); }); }); hotkeyMap.copyLink.forEach((hotkey) => { this.scope.register(hotkey.modifiers, hotkey.key, () => { const { file } = this.item; const internalLink = generateInternalLinkFrom(this.app, file); navigator.clipboard.writeText(internalLink); new import_obsidian13.Notice("Copy wiki link!"); }); }); } onClose() { this.previewContent?.$destroy(); setTimeout(() => { if (this.modeScope.depth > 1) { this.modeScope.pop(); } }, 100); } async renderView() { const { contentEl } = this; contentEl.empty(); contentEl.hide(); this.previewContent = new PreviewModalContent_default({ target: contentEl, props: { file: this.item.file, matches: this.item.result.content } }); contentEl.show(); } countMatches() { return this.item.result.content?.length; } scroll(direction, px) { const { containerEl, contentEl } = this; const move = (px ?? containerEl.clientHeight / 2) * (direction === "up" ? -1 : 1); contentEl.scrollBy({ top: move, behavior: "smooth" }); } async openAndFocus(matchId, direction) { const { item } = this; const leaf = direction === void 0 ? this.app.workspace.getMostRecentLeaf() : this.app.workspace.splitActiveLeaf(direction); await leaf.openFile(item.file); this.app.workspace.setActiveLeaf(leaf, true, true); const match = item?.result?.content?.[matchId]; if (!match) { return; } const { view } = leaf; if (!(view instanceof import_obsidian13.MarkdownView)) { return; } const editor = view.editor; const range = { from: editor.offsetToPos(match[0]), to: editor.offsetToPos(match[1]) }; editor.addHighlights([range], "obsidian-search-match-highlight"); const iter = scrollIteration(editor); if (iter === void 0) { return; } for (let i = 0; i < iter; i++) { editor.scrollIntoView(range, true); } editor.setCursor(range.from); } }; function cyclicId(id, total) { return (id % total + total) % total; } // src/Controller.ts var obsidian = __toESM(require("obsidian"), 1); var import_obsidian14 = require("obsidian"); // src/ui/CardContainer.svelte function add_css4(target) { append_styles(target, "svelte-1g7kfgn", ".core-search-assistant_card-container.svelte-1g7kfgn.svelte-1g7kfgn{overflow:hidden;display:flex;flex-direction:column;height:100%;position:relative;box-shadow:0 2px 5px rgba(0, 0, 0, 0.2);border-radius:10px;cursor:pointer;background-color:var(--background-primary);box-sizing:content-box}.core-search-assistant_card-container.svelte-1g7kfgn.svelte-1g7kfgn:hover{border:5px solid var(--interactive-accent);margin:-5px}.core-search-assistant_card-container.is-selected.svelte-1g7kfgn.svelte-1g7kfgn{border:5px solid var(--interactive-accent);margin:-5px}.card-container-header.svelte-1g7kfgn.svelte-1g7kfgn{padding:5px 10px;background-color:var(--background-secondary);display:flex;color:var(--text-muted)}.file-name-container.svelte-1g7kfgn.svelte-1g7kfgn{font-size:1rem;line-height:1.2rem;overflow-wrap:break-word;min-width:0;flex:1}.file-name-container.svelte-1g7kfgn span.matched-in-path{color:var(--text-normal);font-weight:bold}.content-container-wrapper.svelte-1g7kfgn.svelte-1g7kfgn{padding:5px;flex:1;height:100%;min-height:0}.content-container.svelte-1g7kfgn.svelte-1g7kfgn{overflow:hidden;height:100%;font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn div.content-not-supported-file-format.svelte-1g7kfgn{font-size:1rem;color:var(--text-muted)}.content-container.svelte-1g7kfgn p{font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn code{font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn div{font-size:0.8rem}.content-container.svelte-1g7kfgn li{font-size:0.8rem;line-height:1.2}.content-container.svelte-1g7kfgn h1{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h2{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h3{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h4{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h5{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn h6{font-size:1rem;line-height:1.2;margin:5px}.content-container.svelte-1g7kfgn a{pointer-events:none}.content-container.svelte-1g7kfgn .workspace-leaf{contain:initial !important;height:100%}.content-container.svelte-1g7kfgn .workspace-leaf-resize-handle{display:none}.content-container.svelte-1g7kfgn .view-header{display:none}.content-container.svelte-1g7kfgn .view-content{flex:1;overflow:hidden}.content-container.svelte-1g7kfgn .markdown-preview-view{padding:0;overflow:hidden}.content-container.svelte-1g7kfgn .modal-content{margin:0}"); } function create_fragment4(ctx) { let div5; let div1; let div0; let t0; let div4; let div3; let div2; let t1_value = `${/*file*/ ctx[1].extension.toUpperCase()} file`; let t1; let div5_data_path_value; let mounted; let dispose; return { c() { div5 = element("div"); div1 = element("div"); div0 = element("div"); t0 = space(); div4 = element("div"); div3 = element("div"); div2 = element("div"); t1 = text(t1_value); attr(div0, "class", "file-name-container svelte-1g7kfgn"); attr(div1, "class", "card-container-header svelte-1g7kfgn"); attr(div2, "class", "content-not-supported-file-format svelte-1g7kfgn"); attr(div3, "class", "content-container svelte-1g7kfgn"); attr(div4, "class", "content-container-wrapper svelte-1g7kfgn"); attr(div5, "class", "core-search-assistant_card-container svelte-1g7kfgn"); attr( div5, "data-id", /*id*/ ctx[0] ); attr(div5, "data-path", div5_data_path_value = /*file*/ ctx[1].path); attr(div5, "role", "button"); toggle_class( div5, "is-selected", /*selected*/ ctx[2] ); }, m(target, anchor) { insert(target, div5, anchor); append(div5, div1); append(div1, div0); ctx[8](div0); append(div5, t0); append(div5, div4); append(div4, div3); append(div3, div2); append(div2, t1); ctx[9](div3); if (!mounted) { dispose = listen( div5, "click", /*onClicked*/ ctx[5] ); mounted = true; } }, p(ctx2, [dirty]) { if (dirty & /*file*/ 2 && t1_value !== (t1_value = `${/*file*/ ctx2[1].extension.toUpperCase()} file`)) set_data(t1, t1_value); if (dirty & /*id*/ 1) { attr( div5, "data-id", /*id*/ ctx2[0] ); } if (dirty & /*file*/ 2 && div5_data_path_value !== (div5_data_path_value = /*file*/ ctx2[1].path)) { attr(div5, "data-path", div5_data_path_value); } if (dirty & /*selected*/ 4) { toggle_class( div5, "is-selected", /*selected*/ ctx2[2] ); } }, i: noop, o: noop, d(detaching) { if (detaching) { detach(div5); } ctx[8](null); ctx[9](null); mounted = false; dispose(); } }; } function renderFileName(fileName, containerEl) { containerEl.appendText(fileName); } function instance4($$self, $$props, $$invalidate) { let $app; component_subscribe($$self, app, ($$value) => $$invalidate(11, $app = $$value)); let { id } = $$props; let { file } = $$props; let { selected } = $$props; let { focusEl } = $$props; let contentContainerEl; let fileNameContainerEl; let renderer; const dispatch = createEventDispatcher(); function path() { return file.path; } onMount(async () => { if (!fileNameContainerEl) { return; } renderFileName(file.name, fileNameContainerEl); if (!contentContainerEl) { return; } const fileType = fileTypeMap[file.extension]; if (fileType !== void 0) { contentContainerEl.empty(); renderer = await new ViewGenerator($app, contentContainerEl, file).registerExtension(new ExcalidrawViewGeneratorExtension($app)).registerExtension(new KanbanViewGeneratorExtension($app)).registerExtension(new MarkdownViewGeneratorExtension()).registerExtension(new NonMarkdownViewGeneratorExtension()).load("preview"); } focusEl?.focus(); }); onDestroy(() => { setTimeout(() => renderer?.unload(), 1e3); }); async function onClicked() { await openFile(); dispatch("click"); } async function openFile() { const leaf = $app.workspace.getMostRecentLeaf(); await leaf.openFile(file); $app.workspace.setActiveLeaf(leaf, true, true); } function div0_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { fileNameContainerEl = $$value; $$invalidate(4, fileNameContainerEl); }); } function div3_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { contentContainerEl = $$value; $$invalidate(3, contentContainerEl); }); } $$self.$$set = ($$props2) => { if ("id" in $$props2) $$invalidate(0, id = $$props2.id); if ("file" in $$props2) $$invalidate(1, file = $$props2.file); if ("selected" in $$props2) $$invalidate(2, selected = $$props2.selected); if ("focusEl" in $$props2) $$invalidate(6, focusEl = $$props2.focusEl); }; return [ id, file, selected, contentContainerEl, fileNameContainerEl, onClicked, focusEl, path, div0_binding, div3_binding ]; } var CardContainer = class extends SvelteComponent { constructor(options) { super(); init( this, options, instance4, create_fragment4, safe_not_equal, { id: 0, file: 1, selected: 2, focusEl: 6, path: 7 }, add_css4 ); } get path() { return this.$$.ctx[7]; } }; var CardContainer_default = CardContainer; // src/ui/CardViewComponent.svelte function add_css5(target) { append_styles(target, "svelte-pwex1j", ".card-view-container.svelte-pwex1j{position:absolute;top:0;left:0;width:100%;height:100%;z-index:var(--layer-modal);padding:20px 30px;display:flex;justify-content:center}.card-view-background.svelte-pwex1j{position:absolute;top:0;left:0;width:100%;height:100%;background-color:var(--background-modifier-cover)}.cards-container.svelte-pwex1j{display:grid;grid-gap:20px;height:100%;width:100%;min-height:0}"); } function create_fragment5(ctx) { let div2; let div0; let t; let div1; let mounted; let dispose; return { c() { div2 = element("div"); div0 = element("div"); t = space(); div1 = element("div"); attr(div0, "class", "card-view-background svelte-pwex1j"); attr(div1, "class", "cards-container svelte-pwex1j"); attr(div2, "class", "card-view-container svelte-pwex1j"); }, m(target, anchor) { insert(target, div2, anchor); append(div2, div0); append(div2, t); append(div2, div1); ctx[10](div1); if (!mounted) { dispose = listen( div0, "click", /*click_handler*/ ctx[9] ); mounted = true; } }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) { detach(div2); } ctx[10](null); mounted = false; dispose(); } }; } function cardsPerPage(layout) { if (!checkLayout(layout)) return 0; return layout[0] * layout[1]; } function setLayout(contentEl, layout) { if (!contentEl) return; if (!checkLayout(layout)) return; contentEl.style.gridTemplateColumns = `repeat(${layout[1]}, minmax(0, 1fr))`; contentEl.style.gridTemplateRows = `repeat(${layout[0]}, 1fr)`; } function checkLayout(layout) { const check = (x) => Number.isInteger(x) && x > 0; return check(layout[0]) && check(layout[1]); } function instance5($$self, $$props, $$invalidate) { let { layout } = $$props; let { focusEl } = $$props; let contentEl; let cards = []; const dispatcher = createEventDispatcher(); function addCard(file) { if (!contentEl) return; if (!focusEl) return; if (cards.length >= cardsPerPage(layout)) return; const card = new CardContainer_default({ target: contentEl, props: { file, id: cards.length, selected: false, focusEl } }); cards.push(card); } function renderPage(files) { files.forEach((file) => { addCard(file); }); } function focusOn(id) { const pos = id % cardsPerPage(layout); [-1, 0, 1].forEach((i) => { const card = cards[pos + i]; if (!card) return; if (i === 0) { card.$set({ selected: true }); } else { card.$set({ selected: false }); } }); } function detachCards() { cards.forEach((card) => { card.$destroy(); }); cards = []; } function checkCardsRenderedCorrectly(files) { if (!checkLayout(layout)) return false; for (let i = 0; i < cardsPerPage(layout); i++) { const file = files[i]; const card = cards[i]; if (file?.path !== card?.path()) { return false; } } return true; } onMount(() => { setLayout(contentEl, layout); }); onDestroy(() => { detachCards(); }); const click_handler = () => { dispatcher("should-destroy"); }; function div1_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { contentEl = $$value; $$invalidate(0, contentEl); }); } $$self.$$set = ($$props2) => { if ("layout" in $$props2) $$invalidate(2, layout = $$props2.layout); if ("focusEl" in $$props2) $$invalidate(3, focusEl = $$props2.focusEl); }; return [ contentEl, dispatcher, layout, focusEl, addCard, renderPage, focusOn, detachCards, checkCardsRenderedCorrectly, click_handler, div1_binding ]; } var CardViewComponent = class extends SvelteComponent { constructor(options) { super(); init( this, options, instance5, create_fragment5, safe_not_equal, { layout: 2, focusEl: 3, addCard: 4, renderPage: 5, focusOn: 6, detachCards: 7, checkCardsRenderedCorrectly: 8 }, add_css5 ); } get addCard() { return this.$$.ctx[4]; } get renderPage() { return this.$$.ctx[5]; } get focusOn() { return this.$$.ctx[6]; } get detachCards() { return this.$$.ctx[7]; } get checkCardsRenderedCorrectly() { return this.$$.ctx[8]; } }; var CardViewComponent_default = CardViewComponent; // src/ui/Outline.svelte function add_css6(target) { append_styles(target, "svelte-f5i2qg", ".outline-container.svelte-f5i2qg{position:absolute;top:0;left:0;width:100%;height:100%;z-index:var(--layer-modal);pointer-events:none}"); } function create_fragment6(ctx) { let div; return { c() { div = element("div"); attr(div, "class", "outline-container svelte-f5i2qg"); }, m(target, anchor) { insert(target, div, anchor); ctx[2](div); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) { detach(div); } ctx[2](null); } }; } var STYLE_VAR_COLOR_SEARCH_MODE_OUTLINE = "--search-mode-outline"; function instance6($$self, $$props, $$invalidate) { let { lineWidth } = $$props; let el; onMount(() => { if (!el) return; $$invalidate(0, el.style.outline = `${lineWidth}px solid var(${STYLE_VAR_COLOR_SEARCH_MODE_OUTLINE})`, el); $$invalidate(0, el.style.outlineOffset = `-${lineWidth}px`, el); }); function div_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { el = $$value; $$invalidate(0, el); }); } $$self.$$set = ($$props2) => { if ("lineWidth" in $$props2) $$invalidate(1, lineWidth = $$props2.lineWidth); }; return [el, lineWidth, div_binding]; } var Outline = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance6, create_fragment6, safe_not_equal, { lineWidth: 1 }, add_css6); } }; var Outline_default = Outline; // src/ui/WorkspacePreview.svelte function add_css7(target) { append_styles(target, "svelte-1fata0e", ".core-search-assistant_workspace-preview_container.svelte-1fata0e{position:absolute;top:0;left:0;width:100%;height:100%;z-index:var(--layer-modal);background-color:var(--background-primary);padding:20px 30px;overflow:auto}.core-search-assistant_workspace-preview_container.svelte-1fata0e .highlight-search-match{color:var(--highlight-search-match);background-color:var(--highlight-search-match-bg)}.core-search-assistant_workspace-preview_container.svelte-1fata0e .focus-search-match{background-color:var(--focus-search-match-bg)}.core-search-assistant_workspace-preview_container.svelte-1fata0e .workspace-leaf{contain:initial !important;height:100%}.core-search-assistant_workspace-preview_container.svelte-1fata0e .workspace-leaf-resize-handle{display:none}.core-search-assistant_workspace-preview_container.svelte-1fata0e .view-header{display:none}.core-search-assistant_workspace-preview_container.svelte-1fata0e .view-content{overflow:hidden}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-preview-view{padding:0}.core-search-assistant_workspace-preview_container.svelte-1fata0e .modal-content{margin:0}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view.mod-cm6 .cm-editor{flex:initial;display:initial}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view.mod-cm6{display:initial}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view{pointer-events:none}.core-search-assistant_workspace-preview_container.svelte-1fata0e .markdown-source-view.mod-cm6 .cm-scroller{padding:0}"); } function create_fragment7(ctx) { let div1; let div0; let t_value = `${/*file*/ ctx[0].extension.toUpperCase()} file`; let t; return { c() { div1 = element("div"); div0 = element("div"); t = text(t_value); attr(div0, "class", "content-not-supported-file-format"); attr(div1, "class", "core-search-assistant_workspace-preview_container svelte-1fata0e"); }, m(target, anchor) { insert(target, div1, anchor); append(div1, div0); append(div0, t); ctx[4](div1); }, p(ctx2, [dirty]) { if (dirty & /*file*/ 1 && t_value !== (t_value = `${/*file*/ ctx2[0].extension.toUpperCase()} file`)) set_data(t, t_value); }, i: noop, o: noop, d(detaching) { if (detaching) { detach(div1); } ctx[4](null); } }; } function instance7($$self, $$props, $$invalidate) { let $app; component_subscribe($$self, app, ($$value) => $$invalidate(6, $app = $$value)); let { file } = $$props; let { matches } = $$props; let { focusEl } = $$props; let containerEl; let renderer; onMount(async () => { if (!containerEl) return; const fileType = fileTypeMap[file.extension]; if (fileType !== void 0) { containerEl.empty(); renderer = await new ViewGenerator($app, containerEl, file).registerExtension(new ExcalidrawViewGeneratorExtension($app)).registerExtension(new KanbanViewGeneratorExtension($app)).registerExtension(new MarkdownViewGeneratorExtension()).registerExtension(new NonMarkdownViewGeneratorExtension()).load("source"); highlightMatches(); } focusEl?.focus(); }); onDestroy(() => { setTimeout(() => renderer?.unload(), 1e3); }); function highlightMatches() { renderer?.highlightMatches(matches ?? [], "highlight-search-match"); } function div1_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { containerEl = $$value; $$invalidate(1, containerEl); }); } $$self.$$set = ($$props2) => { if ("file" in $$props2) $$invalidate(0, file = $$props2.file); if ("matches" in $$props2) $$invalidate(2, matches = $$props2.matches); if ("focusEl" in $$props2) $$invalidate(3, focusEl = $$props2.focusEl); }; return [file, containerEl, matches, focusEl, div1_binding]; } var WorkspacePreview = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance7, create_fragment7, safe_not_equal, { file: 0, matches: 2, focusEl: 3 }, add_css7); } }; var WorkspacePreview_default = WorkspacePreview; // src/Controller.ts var DELAY_TO_RELOAD_IN_MILLISECOND = 1e3; var RETRY_INTERVAL = 1; var RETRY_TRIALS = 1e3; var DELAY_TO_RENDER_CARD_VIEW_ON_ENTRY_IN_MILLISECOND = 100; var Controller = class extends obsidian.Component { constructor(app2, plugin2, events, searchInterface) { super(); this.app = app2; this.plugin = plugin2; this.events = events; this.searchInterface = searchInterface; this.modeScope = new ModeScope(); this.cardViewCheckDebouncer = (0, import_obsidian14.debounce)( this.onCheckCardView, DELAY_TO_RELOAD_IN_MILLISECOND, true ); this.countSearchItemDetected = 0; } onunload() { this.exit(); } onload() { this.saveLayout(); this.setSearchModeTriggers(); } async enter() { if (this.modeScope.inSearchMode) { return; } this.setHotkeys(); this.addChildren(); if (this.plugin.settings?.autoToggleSidebar) { this.collapseOppositeSidedock(); } const shouldDetectSearchItems = this.plugin.settings?.autoPreviewMode === "cardView" && this.plugin.settings.renderCardsManually === false; if (shouldDetectSearchItems) { this.searchInterface.startWatching(this.events); await delay(DELAY_TO_RENDER_CARD_VIEW_ON_ENTRY_IN_MILLISECOND); this.renewCardViewPage(); this.cardViewCheckDebouncer(); } this.modeScope.push(); } reset() { if (!this.modeScope.inSearchMode) { return; } this.forget(); this.unfocus(); this.cardViewComponent?.detachCards(); this.countSearchItemDetected = 0; } exit(reason) { if (!this.modeScope.inSearchMode) { return; } this.reset(); this.detachHotkeys(); this.removeChildren(); if (this.shouldCollapseSidedock(reason)) { this.collapseSidedock(); } if (this.plugin.settings?.autoToggleSidebar) { this.restoreOppositeSidedock(); } this.countSearchItemDetected = 0; this.searchInterface.stopWatching(); this.unfocus(); this.modeScope.reset(); } focus() { if (this.currentFocusId === void 0) { return; } this.searchInterface.focusOn(this.currentFocusId); this.cardViewComponent?.focusOn(this.currentFocusId); } open(direction) { if (this.currentFocusId === void 0) { return; } this.searchInterface.open(this.currentFocusId, direction); } async renewCardViewPage() { if (this.plugin.settings?.autoPreviewMode !== "cardView") return; this.cardViewComponent?.detachCards(); this.cardViewComponent?.renderPage(this.filesToBeRendered()); if (this.currentFocusId !== void 0) { this.cardViewComponent?.focusOn(this.currentFocusId ?? 0); } } filesToBeRendered() { const cardsPerPage2 = this.cardsPerPage(); if (cardsPerPage2 === void 0) { return []; } const pageId = Math.floor((this.currentFocusId ?? 0) / cardsPerPage2); const items = this.plugin.searchInterface?.resultItems; if (!items) return []; return items.slice(pageId * cardsPerPage2).map((item) => item.file); } collapseSidedock() { this.searchInterface.collapseSidedock(); } collapseOppositeSidedock() { const collapsed = this.searchInterface.oppositeSidedock?.collapsed; this.searchInterface.collapseOppositeSidedock(); this._restoreOppositeSidedock = () => { if (collapsed === false) { this.searchInterface.expandOppositeSidedock(); } }; } restoreOppositeSidedock() { const restoreOppositeSidedock = this._restoreOppositeSidedock; if (restoreOppositeSidedock === void 0) { return void 0; } return restoreOppositeSidedock(); } addChildren() { this.removeChildren(); const { settings } = this.plugin; if (settings === void 0) { throw "[ERROR in Core Search Assistant] failed to addChildren: failed to read setting"; } this.outline = new Outline_default({ target: document.body, props: { lineWidth: settings.outlineWidth } }); if (settings.autoPreviewMode === "cardView") { this.renewCardViewComponent(); } } removeChildren() { this.outline?.$destroy(); this.outline = void 0; this.cardViewComponent?.$destroy(); this.cardViewComponent = void 0; this.workspacePreviewComponent?.$destroy(); this.workspacePreviewComponent = void 0; } forget() { this.currentFocusId = void 0; this.countSearchItemDetected = 0; } navigateForward() { let updated = true; const numResults = this.searchInterface.count() ?? 0; if (this.currentFocusId === void 0) { this.currentFocusId = 0; } else { this.currentFocusId++; if (this.currentFocusId >= numResults) { this.currentFocusId = numResults - 1; updated = false; } } if (!updated) return; const { settings } = this.plugin; if (!settings) return; if (settings.autoPreviewMode === "cardView" && this.shouldTransitNextPageInCardView()) { this.renewCardViewPage(); } else if (settings.autoPreviewMode === "singleView") { this.renewWorkspacePreviewComponent(); } this.focus(); } navigateBack() { if (this.currentFocusId === void 0) { return; } let updated = true; this.currentFocusId--; if (this.currentFocusId < 0) { this.currentFocusId = 0; updated = false; } if (!updated) return; const { settings } = this.plugin; if (!settings) return; if (settings.autoPreviewMode === "cardView" && this.shouldTransitPreviousPageInCardView()) { this.renewCardViewPage(); } else if (settings.autoPreviewMode === "singleView") { this.renewWorkspacePreviewComponent(); } this.focus(); } moveToNextPage() { const pageId = this.pageId; if (pageId === void 0) return; const pageCount = this.pageCount; if (pageCount === void 0) return; if (pageId >= pageCount - 1) return; const cardsPerPage2 = this.cardsPerPage(); if (cardsPerPage2 === void 0) return; this.currentFocusId = cardsPerPage2 * (pageId + 1); this.renewCardViewPage(); this.focus(); } moveToPreviousPage() { const pageId = this.pageId; if (pageId === void 0) return; const pageCount = this.pageCount; if (pageCount === void 0) return; if (pageId <= 0) return; const cardsPerPage2 = this.cardsPerPage(); if (cardsPerPage2 === void 0) return; this.currentFocusId = cardsPerPage2 * (pageId - 1); this.renewCardViewPage(); this.focus(); } unfocus() { this.searchInterface.unfocus(); } openPreviewModal() { const { currentFocusId } = this; if (currentFocusId === void 0) { return; } const item = this.searchInterface.getResultItemAt(currentFocusId); if (!item) { return; } new PreviewModal(this.app, this.plugin, this.modeScope, item).open(); } shouldTransitNextPageInCardView() { if (this.currentFocusId === void 0 || this.currentFocusId === 0) { return false; } if (!this.plugin.settings) { return false; } const [row, column] = parseCardLayout(this.plugin.settings.cardViewLayout); const cardsPerPage2 = row * column; return this.currentFocusId % cardsPerPage2 === 0; } shouldTransitPreviousPageInCardView() { if (!this.plugin.settings) { return false; } const [row, column] = parseCardLayout(this.plugin.settings.cardViewLayout); const cardsPerPage2 = row * column; if (this.currentFocusId === void 0) { return false; } return (this.currentFocusId + 1) % cardsPerPage2 === 0; } get pageId() { if (this.currentFocusId === void 0) return void 0; const cardsPerPage2 = this.cardsPerPage(); if (cardsPerPage2 === void 0) return void 0; const pageId = Math.floor(this.currentFocusId / cardsPerPage2); return pageId; } get pageCount() { const numResults = this.plugin.searchInterface?.count(); const cardsPerPage2 = this.cardsPerPage(); if (cardsPerPage2 === void 0) return void 0; const pageCount = Math.ceil((numResults ?? 0) / cardsPerPage2); return pageCount; } cardsPerPage() { if (!this.plugin.settings) { return void 0; } const [row, column] = parseCardLayout(this.plugin.settings.cardViewLayout); return row * column; } /** * check layout change * use for detecting whether layout-change really occurs * @returns callback which returns */ saveLayout() { this.app.workspace.onLayoutReady(async () => { const inputEl = await retry( () => this.searchInterface.searchInputEl, RETRY_INTERVAL, RETRY_TRIALS ); this._layoutChanged = async () => inputEl !== await retry( () => this.searchInterface.searchInputEl, RETRY_INTERVAL, RETRY_TRIALS ); }); } async layoutChanged() { const shouldRenewController = await this._layoutChanged?.(); if (shouldRenewController === void 0) { throw "[ERROR in Core Search Assistant] failed to renewRequired: saveLayout was not called."; } return shouldRenewController; } setSearchModeTriggers() { this.registerEvent( this.events.on( EVENT_SEARCH_RESULT_ITEM_DETECTED, this.onSearchResultItemDetected ) ); this.registerEvent( this.events.on(EVENT_SORT_ORDER_CHANGED, this.onSortOrderChanged) ); this.app.workspace.onLayoutReady(async () => { const appContainerEl = await retry( () => this.app.dom.appContainerEl, RETRY_INTERVAL, RETRY_TRIALS ); if (appContainerEl === void 0) { throw "[ERROR in Core Search Assistant] failed to find the app container element"; } const inputEl = await retry( () => this.plugin.searchInterface?.searchInputEl, RETRY_INTERVAL, RETRY_TRIALS ); if (inputEl === void 0) { throw "[ERROR in Core Search Assistant] failed to find the search input form."; } const matchingCaseButtonEl = await retry( () => this.plugin.searchInterface?.matchingCaseButtonEl, RETRY_INTERVAL, RETRY_TRIALS ); if (matchingCaseButtonEl === void 0) { throw "[ERROR in Core Search Assistant] failed to find the matching case button."; } this.registerDomEvent(appContainerEl, "click", (evt) => { const targetEl = evt.target; if (!(targetEl instanceof HTMLElement)) { return; } if (this.plugin.searchInterface?.searchLeaf?.containerEl.contains( targetEl )) { if (!this.plugin.searchInterface.isBuiltInElementToOpenFile(targetEl)) return; } if (this.plugin.searchInterface?.tabHeaderEl?.contains(targetEl)) { return; } if (this.plugin.searchInterface?.isShowMoreContextButton(targetEl)) { return; } if (this.modeScope.depth === 1) { this.exit({ id: "mouse", event: evt }); } }); this.registerDomEvent(matchingCaseButtonEl, "click", () => { if (this.modeScope.inSearchMode) { this.reset(); } }); this.registerDomEvent(inputEl, "input", () => { if (!this.modeScope.inSearchMode) { this.enter(); } this.reset(); }); this.registerDomEvent(inputEl, "keypress", (evt) => { if (evt.key !== "Enter") { return; } if (!this.modeScope.inSearchMode) { this.enter(); } this.reset(); }); this.registerDomEvent(inputEl, "focus", () => { if (!this.modeScope.inSearchMode) { this.enter(); } }); }); } setHotkeys() { const hotkeyMap = this.plugin.settings?.searchModeHotkeys; if (!hotkeyMap) return; const scope = new obsidian.Scope(); this.app.keymap.pushScope(scope); hotkeyMap.selectNext.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, (evt) => { evt.preventDefault(); this.navigateForward(); }); }); hotkeyMap.selectPrevious.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, (evt) => { evt.preventDefault(); this.navigateBack(); }); }); hotkeyMap.open.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, (evt) => { evt.preventDefault(); this.open(); this.exit(); }); }); hotkeyMap.openInNewPane.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, (evt) => { evt.preventDefault(); this.open(this.plugin.settings?.splitDirection); this.exit(); }); }); hotkeyMap.previewModal.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, () => { if (this.app.vault.config.legacyEditor) { return; } this.openPreviewModal(); }); }); hotkeyMap.showOptions.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, () => { new OptionModal(this.app, this.plugin, this.modeScope).open(); }); }); hotkeyMap.nextPage.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, () => { if (this.plugin.settings?.autoPreviewMode === "cardView") { this.moveToNextPage(); } }); }); hotkeyMap.previousPage.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, () => { if (this.plugin.settings?.autoPreviewMode === "cardView") { this.moveToPreviousPage(); } }); }); hotkeyMap.copyLink.forEach((hotkey) => { scope.register(hotkey.modifiers, hotkey.key, () => { const item = this.searchInterface.getResultItemAt( this.currentFocusId ?? 0 ); if (!item) return; const { file } = item; const internalLink = generateInternalLinkFrom(this.app, file); navigator.clipboard.writeText(internalLink); new import_obsidian14.Notice("Copy wiki link!"); }); }); scope.register([], "Escape", (evt) => { evt.preventDefault(); this.exit(); }); scope.register([], "Enter", (evt) => { setTimeout(this.focusOnInput, 100); const shouldRenderCardsManually = this.plugin.settings?.autoPreviewMode === "cardView" && this.plugin.settings.renderCardsManually; if (shouldRenderCardsManually) { evt.preventDefault(); this.reset(); this.renewCardViewPage(); } }); this._detachHotkeys = () => { this.app.keymap.popScope(scope); }; } detachHotkeys() { const detachHotkeys = this._detachHotkeys; if (detachHotkeys === void 0) { return; } detachHotkeys(); } get onSearchResultItemDetected() { return () => { if (this.plugin.settings?.autoPreviewMode !== "cardView") { return; } if (this.currentFocusId !== void 0) { return; } if (this.countSearchItemDetected === 0) { this.cardViewComponent?.detachCards(); } const item = this.searchInterface.getResultItemAt( this.countSearchItemDetected ); if (!item) return; this.cardViewComponent?.addCard(item.file); this.cardViewCheckDebouncer(); this.countSearchItemDetected++; }; } renewCardViewComponent() { this.cardViewComponent?.$destroy(); const { settings } = this.plugin; if (!settings) return; const focusEl = this.searchInterface.searchInputEl; if (!focusEl) return; const layout = parseCardLayout(settings.cardViewLayout); this.app.workspace.onLayoutReady(() => { const containerEl = this.app.workspace.rootSplit.containerEl; const cardViewComponent = new CardViewComponent_default({ target: containerEl, props: { layout, focusEl } }); this.cardViewComponent = cardViewComponent; }); } renewWorkspacePreviewComponent() { this.workspacePreviewComponent?.$destroy(); if (this.currentFocusId === void 0) return; const focusEl = this.searchInterface.searchInputEl; if (!focusEl) return; const item = this.searchInterface.getResultItemAt(this.currentFocusId); if (!item) return; this.app.workspace.onLayoutReady(() => { const containerEl = this.app.workspace.rootSplit.containerEl; const workspacePreviewComponent = new WorkspacePreview_default({ target: containerEl, props: { file: item.file, matches: item.result.content ?? [], focusEl } }); this.workspacePreviewComponent = workspacePreviewComponent; }); } get focusOnInput() { return async () => { const inputEl = await retry( () => this.plugin.searchInterface?.searchInputEl, RETRY_INTERVAL, RETRY_TRIALS ); if (inputEl === void 0) { throw "[ERROR in Core Search Assistant] failed to find the search input form."; } inputEl.focus(); }; } get onSortOrderChanged() { return () => { this.reset(); if (this.plugin.settings?.autoPreviewMode === "cardView") { this.renewCardViewPage(); } }; } shouldCollapseSidedock(reason) { if (!this.plugin.settings?.autoToggleSidebar) { return false; } if (reason === void 0) { return true; } if (reason.id !== "mouse") { return true; } const targetEl = reason.event.target; if (!(targetEl instanceof HTMLElement)) { return true; } return !this.searchInterface.sideDock?.containerEl.contains(targetEl); } get onCheckCardView() { return () => { const { cardViewComponent } = this; if (!cardViewComponent) return; const ok = cardViewComponent.checkCardsRenderedCorrectly( this.filesToBeRendered() ); if (!ok) { this.reset(); this.renewCardViewPage(); } }; } }; // src/interfaces/SearchComponentInterface.ts var import_obsidian16 = require("obsidian"); // src/types/Guards.ts var import_obsidian15 = require("obsidian"); var SORT_ORDER_IN_SEARCH = [ "alphabeticalReverse", "alphabetical", "byModifiedTime", "byModifiedTimeReverse", "byCreatedTime", "byCreatedTimeReverse" ]; function isSearchView(view) { if (typeof view !== "object") { return false; } if (view === null) { return false; } const { matchingCase, explainSearch, dom, setCollapseAll, setExplainSearch, setExtraContext, setMatchingCase, setSortOrder, searchInfoEl, searchComponent } = view; if (typeof matchingCase !== "boolean") { return false; } if (typeof explainSearch !== "boolean") { return false; } if (!isSearchDom(dom)) { return false; } if (typeof searchComponent !== "object") { return false; } if (typeof searchInfoEl !== "object") { return false; } if (!(searchInfoEl instanceof HTMLDivElement)) { return false; } if (!(setCollapseAll instanceof Function)) { return false; } if (!(setExplainSearch instanceof Function)) { return false; } if (!(setExtraContext instanceof Function)) { return false; } if (!(setMatchingCase instanceof Function)) { return false; } if (!(setSortOrder instanceof Function)) { return false; } return true; } function isSearchDom(obj) { if (typeof obj !== "object") { return false; } if (obj === null) { return false; } const { extraContext, collapseAll, sortOrder, vChildren, childrenEl } = obj; if (typeof extraContext !== "boolean") { return false; } if (typeof collapseAll !== "boolean") { return false; } if (typeof sortOrder !== "string") { return false; } if (!SORT_ORDER_IN_SEARCH.includes(sortOrder)) { return false; } if (!isSearchResultItemGroup(vChildren)) { return false; } if (typeof childrenEl !== "object") { return false; } if (!(childrenEl instanceof HTMLElement)) { return false; } return true; } function isSearchResultItemGroup(obj) { if (typeof obj !== "object" || obj === null) { return false; } const { _children: children2 } = obj; if (typeof children2 !== "object") { return false; } if (!Array.isArray(children2)) { return false; } for (const child of children2) { if (!isSearchResultItem(child)) { return false; } } return true; } function isSearchResultItem(obj) { if (typeof obj !== "object" || obj === null) { return false; } const { file, containerEl } = obj; if (!(file instanceof import_obsidian15.TFile)) { return false; } if (!(containerEl instanceof HTMLElement)) { return false; } return true; } // src/utils/LinkedList.ts var LinkedList = class { constructor(events, eventId) { this.unlinkedPool = /* @__PURE__ */ new Map(); this.events = events; this.eventId = eventId; } // attach nodes recursively structure(cur, pre) { let linked = false; if (pre === void 0) { this.setRoot(cur); linked = true; this.signal(); } else if (this.tail !== void 0 && pre === this.tail.entity) { this.link(cur); linked = true; this.unlinkedPool.delete(cur); this.signal(); } if (linked) { if (!this.unlinkedPool.has(cur)) { return; } const next = this.unlinkedPool.get(cur); if (next === void 0) { return; } this.structure(next, cur); } else { if (pre) { this.unlinkedPool.set(pre, cur); } } } setRoot(entity) { const rootNode = { entity, pre: void 0, next: void 0 }; this.head = rootNode; this.tail = rootNode; } link(cur) { if (!this.tail) { return; } const currentTail = this.tail; currentTail.next = { entity: cur, pre: currentTail, next: void 0 }; this.tail = currentTail.next; } clean() { this.head = void 0; this.tail = void 0; this.unlinkedPool = /* @__PURE__ */ new Map(); } // let outside know a node is attached signal() { this.events.trigger(this.eventId); } }; // src/interfaces/SearchComponentInterface.ts var SearchComponentInterface = class extends import_obsidian16.Component { constructor(app2, plugin2, events) { super(); this.observationConfig = { childList: true }; this.onObservedCallback = async (mutations, _observer) => { for (const mutation of mutations) { if (mutation.addedNodes.length === 0) { continue; } const pre = mutation.previousSibling; if (!(pre instanceof HTMLElement)) { continue; } for (const node of Array.from(mutation.addedNodes)) { if (!(node instanceof HTMLElement)) { continue; } const isSearchResultItem2 = node.tagName === "DIV" && node.hasClass("tree-item") && node.hasClass("search-result"); if (!isSearchResultItem2) { continue; } if (!this.linkedList) { return; } this.linkedList.structure( node, this.isRootSearchResult(pre) ? void 0 : pre ); } } }; this.app = app2; this.plugin = plugin2; this.events = events; this.observer = new MutationObserver( this.onObservedCallback.bind(this) ); } onload() { this.app.workspace.onLayoutReady(() => { this.renewSortOrderInfo(); this.registerDomEvent(document, "click", () => { this.renewSortOrderInfo(this.events); }); }); } onunload() { this.sortOrderContainerEl?.empty(); this.sortOrderContainerEl?.remove(); this.observer.disconnect(); } toggleMatchingCase() { const view = this.searchView; view?.setMatchingCase(!view.matchingCase); } toggleExplainSearch() { const view = this.searchView; view?.setExplainSearch(!view.explainSearch); } toggleCollapseAll() { const view = this.searchView; view?.setCollapseAll(!view.dom.collapseAll); } toggleExtraContext() { const view = this.searchView; view?.setExtraContext(!view.dom.extraContext); } setSortOrder(sortOrder) { const view = this.searchView; const originalOrder = view?.dom.sortOrder; view?.setSortOrder(sortOrder); return sortOrder !== originalOrder; } focusOn(pos) { this.unfocus(); const item = this.getResultItemAt(pos); if (!item) { return; } item.containerEl.addClass( "core-search-assistant_search-result-items-focus" ); item.containerEl.scrollIntoView( this.plugin.settings?.keepSelectedItemsCentered ? { block: "center" } : { block: "nearest" } ); } unfocus() { const items = this.resultItems; items.forEach((item) => { item.containerEl.removeClass( "core-search-assistant_search-result-items-focus" ); }); } async open(pos, direction) { const item = this.getResultItemAt(pos); if (!item) { return; } const { file } = item; const leaf = direction === void 0 ? this.app.workspace.getMostRecentLeaf() : this.app.workspace.splitActiveLeaf(direction); await leaf.openFile(file); this.app.workspace.setActiveLeaf(leaf, true, true); } renewSortOrderInfo(events) { if (!this.sortOrderContainerEl) { this.createSortOrderEls(); } const view = this.searchView; if (!view) { return; } const sortOrder = view.dom.sortOrder; if (!this.sortOrderContentEl) { return; } const originalContent = this.sortOrderContentEl.textContent; this.sortOrderContentEl.textContent = searchOptions[sortOrder].description; if (events !== void 0 && originalContent !== this.sortOrderContentEl.textContent) { events.trigger(EVENT_SORT_ORDER_CHANGED); } } count() { const results = this.searchView?.dom.vChildren._children; if (!results) { return 0; } return results.length; } get resultItems() { return this.searchView?.dom.vChildren._children ?? []; } getResultItemAt(pos) { return this.searchView?.dom.vChildren._children[pos]; } get searchInputEl() { return this.searchView?.searchComponent.inputEl; } startWatching(events) { this.linkedList = new LinkedList( events, EVENT_SEARCH_RESULT_ITEM_DETECTED ); const childrenContainerEl = this.searchView?.dom.childrenEl; if (!(childrenContainerEl instanceof HTMLElement)) { throw "[ERROR in Core Search Assistant] failed to SearchComponentInterface#startWatching: childrenContainerEl is not an instance of HTMLElement"; } this.observer.observe(childrenContainerEl, this.observationConfig); } stopWatching() { this.observer.disconnect(); } collapseOppositeSidedock() { const sideDock = this.oppositeSidedock; if (sideDock === void 0) { throw "[ERROR in Core Search Assistant] failed to collapseOppositeSidedock: failed to fetch the opposite sidedock"; } sideDock.collapse(); } expandOppositeSidedock() { const sideDock = this.oppositeSidedock; if (sideDock === void 0) { throw "[ERROR in Core Search Assistant] failed to expandOppositeSidedock: failed to fetch the opposite sidedock"; } sideDock.expand(); } collapseSidedock() { const sideDock = this.sideDock; if (sideDock === void 0) { throw "[ERROR in Core Search Assistant] failed to collapseSidedock: failed to fetch the sidedock"; } sideDock.collapse(); } get sideDock() { const leaf = this.searchLeaf; if (leaf === void 0) { return void 0; } const parent = leaf.getRoot(); if (parent instanceof import_obsidian16.WorkspaceSidedock) { return parent; } return void 0; } get oppositeSidedock() { const leaf = this.searchLeaf; if (leaf === void 0) { return void 0; } const parent = leaf.getRoot(); if (parent === this.app.workspace.leftSplit) { const opposite = this.app.workspace.rightSplit; return opposite instanceof import_obsidian16.WorkspaceSidedock ? opposite : void 0; } if (parent === this.app.workspace.rightSplit) { const opposite = this.app.workspace.leftSplit; return opposite instanceof import_obsidian16.WorkspaceSidedock ? opposite : void 0; } return void 0; } createSortOrderEls() { this.sortOrderContainerEl = createEl("div", { cls: "search-info-container" }); this.sortOrderContentEl = this.sortOrderContainerEl.createEl("div"); const view = this.searchView; if (!view) { return; } this.sortOrderContainerEl.insertAfter(view.searchInfoEl); } get matchingCaseButtonEl() { return this.searchView?.matchingCaseButtonEl; } get tabHeaderEl() { return this.searchLeaf?.tabHeaderEl; } isBuiltInElementToOpenFile(el) { const isFileNameContainerEl = el.tagName === "DIV" && el.hasClass("tree-item-inner"); const isMatchCountContainerEl = el.tagName === "DIV" && el.hasClass("tree-item-flair-outer"); const isMatchContainerEl = el.tagName === "DIV" && el.hasClass("search-result-file-match"); if (isFileNameContainerEl || isMatchContainerEl || isMatchCountContainerEl) { return true; } const parentEl = el.parentElement; if (parentEl === null) { return false; } return this.isBuiltInElementToOpenFile(parentEl); } isShowMoreContextButton(el) { return el.tagName === "DIV" && el.hasClass("search-result-hover-button"); } // get changeSortOrderButtonEl(): HTMLElement | undefined { // const changeSortOrderButtonEl = // this.searchView?.headerDom.navButtonsEl.querySelector( // 'div.nav-action-button[aria-label="Change sort order"]' // ); // return changeSortOrderButtonEl instanceof HTMLElement // ? changeSortOrderButtonEl // : undefined; // } get searchView() { const leaf = this.searchLeaf; if (!leaf) { return void 0; } const view = leaf.view; return isSearchView(view) ? view : void 0; } get searchLeaf() { return this.app.workspace.getLeavesOfType("search")[0]; } isRootSearchResult(el) { return el.tagName === "DIV" && !el.hasClass("tree-item") && !el.hasClass("search-result"); } // async watchSortOrderChangeByClick() { // const callback = async (evt: Event) => { // this.renewSortOrderInfo(); // if (evt.currentTarget === null) { // return; // } // evt.currentTarget.removeEventListener('click', callback); // }; // await new Promise((resolve) => setTimeout(resolve, 1)); // prevent callback from being called immediately // document.addEventListener('click', callback); // } // getSortOrderSettingButton(): HTMLElement | undefined { // const view = this.getSearchView(); // const buttonsEl = view?.headerDom.navButtonsEl; // if (!buttonsEl) { // return undefined; // } // const sortOrderSettingButtonEl = buttonsEl.querySelector( // 'div.nav-action-button[aria-label="Change sort order"]' // ); // return sortOrderSettingButtonEl // ? (sortOrderSettingButtonEl as HTMLElement) // : undefined; // } }; // src/main.ts var import_obsidian17 = require("obsidian"); var CoreSearchAssistantPlugin = class extends import_obsidian17.Plugin { async onload() { await this.loadSettings(); this.events = new CoreSearchAssistantEvents(); this.searchInterface = this.addChild( new SearchComponentInterface(this.app, this, this.events) ); this.controller = this.addChild( new Controller(this.app, this, this.events, this.searchInterface) ); this.watchLayoutChange(); this.setSvelteStoreValues(); this.addSettingTab(new CoreSearchAssistantSettingTab(this.app, this)); } // override onunload() {} async loadSettings() { this.settings = deepMerge(DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { await this.saveData(this.settings); } renewController() { if (this.controller) { this.removeChild(this.controller); } if (this.events === void 0) { throw "[ERROR in Core Search Interface] failed to renewController: plugin.events = undefined"; } if (this.searchInterface === void 0) { throw "[ERROR in Core Search Interface] failed to renewController: plugin.searchInterface = undefined"; } this.controller = this.addChild( new Controller(this.app, this, this.events, this.searchInterface) ); } watchLayoutChange() { this.app.workspace.onLayoutReady(() => { this.app.workspace.on("layout-change", async () => { if (await this.controller?.layoutChanged()) { this.renewController(); } }); }); } setSvelteStoreValues() { plugin.set(this); app.set(this.app); } }; /* nosourcemap */