From d242dc000d0fccf470f38c542f4330ce7e2537c9 Mon Sep 17 00:00:00 2001 From: sdfsdf Date: Tue, 1 Oct 2024 22:19:35 +0200 Subject: [PATCH] vault backup: 2024-10-01 22:19:35 --- GGDoc/.obsidian/community-plugins.json | 3 +- .../.obsidian/plugins/awesome-image/data.json | 2 +- .../plugins/obsidian-style-settings/data.json | 3 +- .../.obsidian/plugins/settings-search/main.js | 510 ++++++++++++++++++ .../plugins/settings-search/manifest.json | 10 + .../plugins/settings-search/styles.css | 25 + GGDoc/.obsidian/workspace.json | 14 +- GGDoc/Misc/How to Obsidian.md | 2 +- GGDoc/Pasted image 20241001215011.png | Bin 13002 -> 0 bytes 9 files changed, 558 insertions(+), 11 deletions(-) create mode 100644 GGDoc/.obsidian/plugins/settings-search/main.js create mode 100644 GGDoc/.obsidian/plugins/settings-search/manifest.json create mode 100644 GGDoc/.obsidian/plugins/settings-search/styles.css delete mode 100644 GGDoc/Pasted image 20241001215011.png diff --git a/GGDoc/.obsidian/community-plugins.json b/GGDoc/.obsidian/community-plugins.json index e341df4..0db10fc 100644 --- a/GGDoc/.obsidian/community-plugins.json +++ b/GGDoc/.obsidian/community-plugins.json @@ -9,5 +9,6 @@ "dataview", "awesome-image", "automatic-table-of-contents", - "multi-properties" + "multi-properties", + "settings-search" ] \ No newline at end of file diff --git a/GGDoc/.obsidian/plugins/awesome-image/data.json b/GGDoc/.obsidian/plugins/awesome-image/data.json index 6042f78..5d58bf3 100644 --- a/GGDoc/.obsidian/plugins/awesome-image/data.json +++ b/GGDoc/.obsidian/plugins/awesome-image/data.json @@ -22,7 +22,7 @@ "moveTheImageHotkey": "ALT", "switchTheImageHotkey": "NONE", "doubleClickToolbar": "toolbar_full_screen", - "viewTriggerHotkey": "CTRL", + "viewTriggerHotkey": "NONE", "realTimeUpdate": true, "excludedFolders": [ ".git/", diff --git a/GGDoc/.obsidian/plugins/obsidian-style-settings/data.json b/GGDoc/.obsidian/plugins/obsidian-style-settings/data.json index 393fdea..bfe13d7 100644 --- a/GGDoc/.obsidian/plugins/obsidian-style-settings/data.json +++ b/GGDoc/.obsidian/plugins/obsidian-style-settings/data.json @@ -7,5 +7,6 @@ "minimal-style@@h1-color@@dark": "#99D5BC", "modular-css-layout-mc@@callout-min-width": 100, "modular-css-layout-mc@@callout-nowrap-min-width": 100, - "minimal-style@@pdf-dark-opacity": 1 + "minimal-style@@pdf-dark-opacity": 1, + "minimal-style@@zoom-off": true } \ No newline at end of file diff --git a/GGDoc/.obsidian/plugins/settings-search/main.js b/GGDoc/.obsidian/plugins/settings-search/main.js new file mode 100644 index 0000000..bcd6e69 --- /dev/null +++ b/GGDoc/.obsidian/plugins/settings-search/main.js @@ -0,0 +1,510 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +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 __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); +var __export = (target, all) => { + __markAsModule(target); + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __reExport = (target, module2, desc) => { + if (module2 && typeof module2 === "object" || typeof module2 === "function") { + for (let key of __getOwnPropNames(module2)) + if (!__hasOwnProp.call(target, key) && key !== "default") + __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); + } + return target; +}; +var __toModule = (module2) => { + return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); +}; +var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; +}; + +// src/main.ts +__export(exports, { + default: () => SettingsSearch +}); +var import_obsidian = __toModule(require("obsidian")); + +// node_modules/monkey-around/mjs/index.js +function around(obj, factories) { + const removers = Object.keys(factories).map((key) => around1(obj, key, factories[key])); + return removers.length === 1 ? removers[0] : function() { + removers.forEach((r) => r()); + }; +} +function around1(obj, method, createWrapper) { + const original = obj[method], hadOwn = obj.hasOwnProperty(method); + let current = createWrapper(original); + if (original) + Object.setPrototypeOf(current, original); + Object.setPrototypeOf(wrapper, current); + obj[method] = wrapper; + return remove; + function wrapper(...args) { + if (current === original && obj[method] === wrapper) + remove(); + return current.apply(this, args); + } + function remove() { + if (obj[method] === wrapper) { + if (hadOwn) + obj[method] = original; + else + delete obj[method]; + } + if (current === original) + return; + current = original; + Object.setPrototypeOf(wrapper, original || Function); + } +} + +// src/main.ts +var SettingsSearch = class extends import_obsidian.Plugin { + constructor() { + super(...arguments); + __publicField(this, "settingsSearchEl", createDiv("settings-search-container vertical-tab-header-group")); + __publicField(this, "settingsResultsContainerEl", createDiv("settings-search-results-container vertical-tab-content")); + __publicField(this, "settingsNavItemContainer", this.settingsSearchEl.createDiv("vertical-tab-header-group-items").createDiv("vertical-tab-nav-item settings-search-input")); + __publicField(this, "settingsResultsEl"); + __publicField(this, "search"); + __publicField(this, "locale"); + __publicField(this, "resources", []); + __publicField(this, "results", []); + __publicField(this, "loaded", false); + __publicField(this, "tabIndex", 0); + __publicField(this, "pluginTabIndex", 0); + __publicField(this, "seen", []); + __publicField(this, "settingCache", new Map()); + __publicField(this, "searchAppended", false); + __publicField(this, "activeIndex", -1); + __publicField(this, "activeSetting"); + __publicField(this, "scope", new import_obsidian.Scope(this.app.scope)); + __publicField(this, "mobileContainers", []); + } + async onload() { + (window["SettingsSearch"] = { + addResources: this.addResources.bind(this), + removeResources: this.removeResources.bind(this), + removeTabResources: this.removeTabResources.bind(this) + }) && this.register(() => delete window["SettingsSearch"]); + this.app.workspace.onLayoutReady(async () => { + this.settingsResultsContainerEl.createEl("h3", { + text: "Settings Search Results" + }); + this.settingsResultsEl = this.settingsResultsContainerEl.createDiv("settings-search-results"); + this.buildScope(); + this.buildSearch(); + this.buildResources(); + this.buildPluginResources(); + this.patchSettings(); + this.loaded = true; + this.app.workspace.trigger("settings-search-loaded"); + }); + } + buildResources() { + const tab = this.app.setting.settingTabs[this.tabIndex]; + if (tab && tab.id !== void 0 && !this.seen.includes(tab.id)) { + this.getTabResources(tab); + this.tabIndex++; + setTimeout(() => this.buildResources()); + } + } + buildPluginResources() { + const tab = this.app.setting.pluginTabs[this.pluginTabIndex]; + if (tab) { + this.getTabResources(tab); + this.pluginTabIndex++; + setTimeout(() => this.buildPluginResources()); + } + } + get manifests() { + return Object.values(this.app.plugins.manifests); + } + addResourceToCache(resource) { + if (!resource || !resource.text || !resource.name || !resource.tab) { + return new Error("A valid resource must be provided."); + } + let name; + if (resource.external) { + name = createFragment((el) => { + (0, import_obsidian.setIcon)(el.createSpan({ + attr: { + "aria-label": "This setting was added by another plugin." + } + }), "info"); + el.createSpan({ text: resource.text }); + }); + } else { + name = resource.text; + } + const setting = new import_obsidian.Setting(createDiv()).setName(name).setDesc(createFragment((e) => e.createDiv().innerHTML = resource.desc ?? "")); + if (resource.external) { + setting.settingEl.addClass("set-externally"); + } + if (resource.tab == "community-plugins") { + let plugin = this.manifests.find((p) => p.name == resource.text); + if (plugin && this.app.plugins.getPlugin(plugin.id)?._loaded && this.app.setting.pluginTabs.find((t) => t.id == plugin.id)) { + setting.addExtraButton((b) => { + b.setTooltip(`Open ${resource.text} Settings`).onClick(() => { + this.app.setting.openTabById(plugin.id); + }); + }); + } + } + if (resource.tab == "plugins") { + const plugins = Object.values(this.app.internalPlugins.plugins); + const plugin = plugins.find((p) => p._loaded && p.instance.name == resource.text); + if (plugin && this.app.setting.pluginTabs.find((t) => t.id == plugin.instance.id)) { + setting.addExtraButton((b) => { + b.setTooltip(`Open ${resource.text} Settings`).onClick(() => { + this.app.setting.openTabById(plugin.instance.id); + }); + }); + } + } + setting.addExtraButton((b) => { + b.setIcon("forward-arrow").onClick(() => { + this.showResult(resource); + }); + }); + this.settingCache.set(resource, setting); + } + getResourceFromCache(resource) { + if (!this.settingCache.has(resource)) { + this.addResourceToCache(resource); + } + return this.settingCache.get(resource); + } + removeResourcesFromCache(resources) { + for (const resource of resources) { + this.settingCache.delete(resource); + } + } + addResources(...resources) { + for (const resource of resources) { + resource.external = true; + if (this.resources.find((k) => this.equivalent(resource, k))) + continue; + this.resources.push(resource); + this.addResourceToCache(resource); + } + return () => this.removeResources(...resources); + } + equivalent(resource1, resource2) { + return resource1.name == resource2.name && resource1.tab == resource2.tab && resource1.text == resource2.text && resource1.desc == resource2.desc && resource1.external == resource2.external; + } + removeResources(...resources) { + const removing = []; + const keys = [...this.settingCache.keys()]; + for (const resource of resources) { + if (!resource || !resource.text || !resource.name || !resource.tab) { + continue; + } + resource.external = true; + this.resources = this.resources.filter((r) => !this.equivalent(resource, r)); + removing.push(...keys.filter((k) => k == resource || this.equivalent(resource, k))); + } + this.removeResourcesFromCache(removing); + } + removeTabResources(tab) { + const removing = this.resources.filter((t) => t.tab == tab); + this.resources = this.resources.filter((t) => t.tab != tab); + this.removeResourcesFromCache(removing); + } + async getTabResources(tab) { + await tab.display(); + const settings = tab.containerEl.querySelectorAll(".setting-item:not(.setting-item-header)"); + for (const el of Array.from(settings)) { + const text = el.querySelector(".setting-item-name")?.textContent; + if (!text) + continue; + const desc = el.querySelector(".setting-item-description")?.innerHTML ?? ""; + const resource = { + tab: tab.id, + name: tab.name, + text, + desc + }; + this.resources.push(resource); + this.addResourceToCache(resource); + } + if (this.app.setting.activeTab?.id == tab.id) + return; + this.seen.push(tab.id); + tab.containerEl.detach(); + tab.hide(); + } + patchSettings() { + const self = this; + this.register(around(this.app.setting, { + onOpen: function(next) { + return function() { + next.apply(this); + if (!import_obsidian.Platform.isMobile) + self.search.inputEl.focus(); + return next; + }; + } + })); + this.register(around(this.app.setting, { + addSettingTab: function(next) { + return function(tab) { + if (tab && tab.id !== void 0 && !self.seen.includes(tab.id)) { + self.getTabResources(tab); + } + return next.call(this, tab); + }; + } + })); + this.register(around(this.app.setting, { + removeSettingTab: function(next) { + return function(tab) { + if (this.isPluginSettingTab(tab)) { + self.removeTabResources(tab.id); + } + return next.call(this, tab); + }; + } + })); + this.register(around(this.app.setting, { + openTab: function(next) { + return function(tab) { + self.searchAppended = false; + self.app.keymap.popScope(self.scope); + return next.call(this, tab); + }; + }, + openTabById: function(next) { + return function(tab) { + self.searchAppended = false; + self.app.keymap.popScope(self.scope); + return next.call(this, tab); + }; + }, + onClose: function(next) { + return function() { + if (import_obsidian.Platform.isMobile) { + self.detach(); + } + return next.call(this); + }; + } + })); + } + buildSearch() { + const tempSetting = new import_obsidian.Setting(createDiv()).addSearch((s) => { + this.search = s; + }); + this.settingsNavItemContainer.append(tempSetting.controlEl); + tempSetting.settingEl.detach(); + this.search.onChange((v) => { + this.onChange(v); + }); + this.search.setPlaceholder("Search settings..."); + this.app.setting.tabHeadersEl.prepend(this.settingsSearchEl); + } + buildScope() { + this.scope.register(["Ctrl"], "N", () => { + if (this.activeSetting) { + this.activeSetting.settingEl.removeClass("active"); + } + this.activeIndex = ((this.activeIndex + 1) % this.results.length + this.results.length) % this.results.length; + this.centerActiveSetting(); + }); + this.scope.register([], "ArrowDown", () => { + if (this.activeSetting) { + this.activeSetting.settingEl.removeClass("active"); + } + this.activeIndex = ((this.activeIndex + 1) % this.results.length + this.results.length) % this.results.length; + this.centerActiveSetting(); + }); + this.scope.register(["Ctrl"], "P", () => { + if (this.activeSetting) { + this.activeSetting.settingEl.removeClass("active"); + } + this.activeIndex = ((this.activeIndex - 1) % this.results.length + this.results.length) % this.results.length; + this.centerActiveSetting(); + }); + this.scope.register([], "ArrowUp", () => { + if (this.activeSetting) { + this.activeSetting.settingEl.removeClass("active"); + } + this.activeIndex = ((this.activeIndex - 1) % this.results.length + this.results.length) % this.results.length; + this.centerActiveSetting(); + }); + this.scope.register([], "Enter", () => { + if (this.activeSetting) { + this.showResult(this.results[this.activeIndex]); + } + }); + } + centerActiveSetting() { + const result = this.results[this.activeIndex]; + this.activeSetting = this.getResourceFromCache(result); + this.activeSetting.settingEl.addClass("active"); + this.activeSetting.settingEl.scrollIntoView({ + behavior: "auto", + block: "nearest" + }); + } + detachFromMobile() { + if (import_obsidian.Platform.isMobile) { + this.settingsResultsContainerEl.detach(); + for (const header of this.mobileContainers) { + this.app.setting.tabHeadersEl.append(header); + } + this.search.setValue(""); + } + } + detachFromDesktop() { + if (import_obsidian.Platform.isDesktop) { + this.app.setting.openTabById(this.app.setting.lastTabId); + } + } + detach() { + this.detachFromDesktop(); + this.detachFromMobile(); + this.searchAppended = false; + } + onChange(v) { + if (!v) { + this.detach(); + this.app.keymap.popScope(this.scope); + return; + } + if (!this.searchAppended) { + this.activeIndex = -1; + this.app.keymap.popScope(this.scope); + this.app.keymap.pushScope(this.scope); + if (this.activeSetting) { + this.activeSetting.settingEl.removeClass("active"); + this.activeSetting = null; + } + if (!import_obsidian.Platform.isMobile) { + this.app.setting.activeTab.navEl.removeClass("is-active"); + this.app.setting.tabContentContainer.empty(); + this.app.setting.tabContentContainer.append(this.settingsResultsContainerEl); + } else { + const headers = this.app.setting.tabHeadersEl.querySelectorAll(".vertical-tab-header-group:not(.settings-search-container)"); + for (const header of Array.from(headers)) { + this.mobileContainers.push(header); + header.detach(); + } + this.app.setting.tabHeadersEl.append(this.settingsResultsContainerEl); + } + this.searchAppended = true; + } + this.appendResults(this.performFuzzySearch(v)); + } + getMatchText(text, result) { + const matchElements = {}; + return createFragment((content) => { + for (let i = 0; i < text.length; i++) { + let match = result.matches.find((m) => m[0] === i); + if (match) { + const index = result.matches.indexOf(match); + if (!matchElements[index]) { + matchElements[index] = createSpan("suggestion-highlight"); + } + let element = matchElements[index]; + content.appendChild(element); + element.appendText(text.substring(match[0], match[1])); + i += match[1] - match[0] - 1; + continue; + } + content.appendText(text[i]); + } + }); + } + appendResults(results) { + this.settingsResultsEl.empty(); + if (results.length) { + const headers = {}; + for (const resource of results) { + if (!(resource.tab in headers)) { + headers[resource.tab] = this.settingsResultsEl.createDiv(); + new import_obsidian.Setting(headers[resource.tab]).setHeading().setName(resource.name); + } + const setting = this.getResourceFromCache(resource); + headers[resource.tab].append(setting.settingEl); + } + } else { + this.settingsResultsEl.setText("No results found :("); + } + } + showResult(result) { + this.search.setValue(""); + const tab = this.app.setting.settingTabs.find((t) => t.id == result.tab) ?? this.app.setting.pluginTabs.find((t) => t.id == result.tab); + if (!tab) { + new import_obsidian.Notice("There was an issue opening the setting tab."); + return; + } + this.app.setting.openTabById(tab.id); + this.app.keymap.popScope(this.scope); + this.detach(); + try { + const names = tab.containerEl.querySelectorAll(".setting-item-name"); + const el = Array.from(names).find((n) => n.textContent == result.text); + if (!el) + return; + const setting = el.closest(".setting-item"); + if (!setting) + return; + if (tab.id == "obsidian-style-settings") { + let collapsed = setting.closest(".style-settings-container"); + let previous = collapsed?.previousElementSibling; + while (previous != null && previous.hasClass("is-collapsed") && previous.hasClass("style-settings-heading")) { + previous.removeClass("is-collapsed"); + collapsed = collapsed.parentElement?.closest(".style-settings-container"); + previous = collapsed?.previousElementSibling; + } + } + let details = setting.closest("details"); + while (details) { + details.setAttr("open", "open"); + details = details.parentElement?.closest("details"); + } + setting.scrollIntoView(true); + setting.addClass("is-flashing"); + window.setTimeout(() => setting.removeClass("is-flashing"), 3e3); + } catch (e) { + console.error(e); + } + } + performFuzzySearch(input) { + const results = [], hotkeys = []; + for (const resource of this.resources) { + let result = (0, import_obsidian.prepareSimpleSearch)(input)(resource.text) ?? (0, import_obsidian.prepareSimpleSearch)(input)(resource.desc); + if (result) { + if (resource.tab == "hotkeys") { + hotkeys.push(resource); + } else { + results.push(resource); + } + } + } + this.results = [...results, ...hotkeys]; + return this.results; + } + onunload() { + this.settingsSearchEl.detach(); + this.settingsResultsEl.detach(); + this.detach(); + if (this.searchAppended && import_obsidian.Platform.isDesktop) + this.app.setting.openTabById(this.app.setting.lastTabId); + } +}; diff --git a/GGDoc/.obsidian/plugins/settings-search/manifest.json b/GGDoc/.obsidian/plugins/settings-search/manifest.json new file mode 100644 index 0000000..400b89d --- /dev/null +++ b/GGDoc/.obsidian/plugins/settings-search/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "settings-search", + "name": "Settings Search", + "version": "1.3.10", + "minAppVersion": "0.12.17", + "author": "Jeremy Valentine", + "description": "Globally search settings in Obsidian.md", + "authorUrl": "https://github.com/valentine195", + "isDesktopOnly": false +} diff --git a/GGDoc/.obsidian/plugins/settings-search/styles.css b/GGDoc/.obsidian/plugins/settings-search/styles.css new file mode 100644 index 0000000..ba64aed --- /dev/null +++ b/GGDoc/.obsidian/plugins/settings-search/styles.css @@ -0,0 +1,25 @@ +/* src/assets/main.css */ +.settings-search-container.vertical-tab-header-group { + padding-bottom: 0; +} +.settings-search-input { + padding-left: 6px; +} +.vertical-tab-nav-item.settings-search-input { + background-color: inherit !important; +} +.settings-search-input .setting-item-control { + display: block; +} +.settings-search-input .search-input-container { + margin: 0; +} +.settings-search-results .setting-item.active { + background-color: var(--background-secondary); +} +.settings-search-results .set-externally .setting-item-name { + display: flex; + gap: 0.5rem; +} + +/* src/styles.css */ diff --git a/GGDoc/.obsidian/workspace.json b/GGDoc/.obsidian/workspace.json index c436e7f..d61a61c 100644 --- a/GGDoc/.obsidian/workspace.json +++ b/GGDoc/.obsidian/workspace.json @@ -14,8 +14,8 @@ "type": "markdown", "state": { "file": "Misc/How to Obsidian.md", - "mode": "preview", - "source": true + "mode": "source", + "source": false } } } @@ -48,7 +48,7 @@ "state": { "type": "search", "state": { - "query": "tag:#test", + "query": "ebbb1dda8bfee815342b9f51b1cc6de5e0e8113be18679e7930bb2f039ba6573", "matchingCase": false, "explainSearch": false, "collapseAll": false, @@ -163,14 +163,15 @@ }, "active": "21a3cd5caa3c9d8f", "lastOpenFiles": [ + "Misc/Untitled.canvas", + "Misc/How to Obsidian.md", + "Misc/Tags.md", + "Pasted image 20241001215011.png", "Misc/Storage/Attachments/e/b/b", "Misc/Storage/Attachments/e/b", "Misc/Storage/Attachments/e", "Misc/Storage/Attachments/e/b/b/ebbb1dda8bfee815342b9f51b1cc6de5e0e8113be18679e7930bb2f039ba6573.png", - "Misc/Tags.md", "10 Design/Hypothèses/Flow de la sauvegarde - mort.md", - "Misc/How to Obsidian.md", - "Pasted image 20241001215011.png", "Misc/Storage/Attachments/1/b/c", "Misc/Storage/Attachments/1/b", "Misc/Storage/Attachments/1", @@ -190,7 +191,6 @@ "Misc/Plugins.md", "Misc/Storage/Attachments/8/2/8", "Misc/Storage/Attachments/8/2", - "Misc/Storage/Attachments/8", "Misc/Storage/Attachments/8/2/8/828b38e1763369b52b2efba15d4668326e86f70408af7ebaf2d99b9f1210a5ed.png", "Misc/Storage/Attachments/9/4/e/94ebc76d29274d246b1bd9bcb4b1714cc49112ad86de394b437f3e65d4b38ec5.png", "Welcome.md" diff --git a/GGDoc/Misc/How to Obsidian.md b/GGDoc/Misc/How to Obsidian.md index 10ee0e4..2570a74 100644 --- a/GGDoc/Misc/How to Obsidian.md +++ b/GGDoc/Misc/How to Obsidian.md @@ -45,7 +45,7 @@ Customize minimal theme css. Features includes : - Colorful headers ## Multi Properties -![[ebbb1dda8bfee815342b9f51b1cc6de5e0e8113be18679e7930bb2f039ba6573.png]] + Bulk edit tags for multiple files ## Style Settings diff --git a/GGDoc/Pasted image 20241001215011.png b/GGDoc/Pasted image 20241001215011.png deleted file mode 100644 index e352d5b34d68b5fe6a09641b10dec53c16c2eeb6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13002 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 bsTn%d`)}|Qp8`KMq0qf-gm?|Nd+>h%_G4C}