diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json index f6b29c1df..94e7f5db6 100755 --- a/.obsidian/community-plugins.json +++ b/.obsidian/community-plugins.json @@ -10,5 +10,6 @@ "obsidian-style-settings", "obsidian-tasks-plugin", "templater-obsidian", - "obsidian-zotero-desktop-connector" + "obsidian-zotero-desktop-connector", + "spacekeys" ] \ No newline at end of file diff --git a/.obsidian/hotkeys.json b/.obsidian/hotkeys.json index 90cbff79d..bf364fbe9 100755 --- a/.obsidian/hotkeys.json +++ b/.obsidian/hotkeys.json @@ -87,6 +87,13 @@ { "modifiers": [], "key": "F4" + }, + { + "modifiers": [ + "Mod", + "Shift" + ], + "key": "H" } ], "highlightr-plugin:Cyan": [ @@ -276,5 +283,29 @@ "key": "K" } ], - "editor:delete-paragraph": [] + "editor:delete-paragraph": [], + "workspace:goto-tab-1": [], + "workspace:goto-tab-2": [], + "workspace:goto-tab-3": [], + "workspace:goto-tab-4": [], + "workspace:goto-tab-5": [], + "workspace:goto-tab-6": [], + "workspace:goto-tab-7": [], + "workspace:goto-tab-8": [], + "editor:insert-mathblock": [ + { + "modifiers": [ + "Mod" + ], + "key": "M" + } + ], + "editor:insert-table": [ + { + "modifiers": [ + "Mod" + ], + "key": "T" + } + ] } \ No newline at end of file diff --git a/.obsidian/plugins/spacekeys/main.js b/.obsidian/plugins/spacekeys/main.js new file mode 100644 index 000000000..213231da5 --- /dev/null +++ b/.obsidian/plugins/spacekeys/main.js @@ -0,0 +1,221 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +var M=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var ae=(i,s)=>{for(var e in s)M(i,e,{get:s[e],enumerable:!0})},re=(i,s,e,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let n of ne(s))!oe.call(i,n)&&n!==e&&M(i,n,{get:()=>s[n],enumerable:!(t=ie(s,n))||t.enumerable});return i};var le=i=>re(M({},"__esModule",{value:!0}),i);var we={};ae(we,{default:()=>F});module.exports=le(we);var r=require("obsidian");var _=/^(.|[a-z]+|f[1-9]|f1[0-2])$/i,H={" ":"SPC",enter:"ENT",tab:"TAB",backspace:"BSP",arrowup:"Up",arrowdown:"Down",arrowleft:"Left",arrowright:"Right"},ce={" ":"SPC",enter:"\u21B5",tab:"TAB",backspace:"\u232B",arrowup:"\u2191",arrowdown:"\u2193",arrowleft:"\u2190",arrowright:"\u2192"};function w(i){return i.length==1&&i!=" "}var u=class{constructor(s,e={}){var t,n,o,a;this.key=s,this.ctrl=(t=e.ctrl)!=null?t:!1,this.shift=(n=e.shift)!=null?n:!1,this.alt=(o=e.alt)!=null?o:!1,this.meta=(a=e.meta)!=null?a:!1}static fromEvent(s){let e=s.key;e.length>1&&(e=e.toLowerCase());let t={ctrl:s.ctrlKey,shift:s.shiftKey,alt:s.altKey,meta:s.metaKey},n=new u(e,t);return w(e)&&(n.shift=!1),n}static compare(s,e){if(s.key!=e.key){let t=w(s.key),n=w(e.key);return!t&&n?-1:t&&!n?1:s.key.localeCompare(e.key)}return!s.ctrl&&e.ctrl?-1:s.ctrl&&!e.ctrl?1:!s.shift&&e.shift?-1:s.shift&&!e.shift?1:!s.alt&&e.alt?-1:s.alt&&!e.alt?1:!s.meta&&e.meta?-1:s.meta&&!e.meta?1:0}equals(s){return this.key==s.key&&this.ctrl==s.ctrl&&this.shift==s.shift&&this.alt==s.alt&&this.meta==s.meta}basicRepr(){let s="";return this.ctrl&&(s+="C"),this.shift&&!w(this.key)&&(s+="S"),this.alt&&(s+="A"),this.meta&&(s+="M"),s&&(s+="-"),this.key in H?s+=H[this.key]:this.key.length>1?s+=this.key.toUpperCase():s+=this.key,s}fancyRepr(){var e;let s="";return this.ctrl&&(s+="^"),this.shift&&!w(this.key)&&(s+="\u21E7"),this.alt&&(s+="\u2387"),this.meta&&(s+="\u229E"),s+=(e=ce[this.key])!=null?e:this.key,s}},p=class{constructor(s,e=null){this.command_id=s;this.description=e}},d=class{constructor(s=null){this.description=s,this.children=[]}isEmpty(){return this.children.length==0}setChild(s,e){for(let t=0;tthis.resolve(!0));let o=(f=t.yesCls)!=null?f:"mod-cta";o&&this.yesBtn.addClass(o),this.noBtn=n.createEl("button",{text:(k=t.noText)!=null?k:"Cancel"}),this.noBtn.addEventListener("click",se=>this.resolve(!1));let a=(G=t.noCls)!=null?G:"mod-cancel";a&&this.noBtn.addClass(a)}open(){super.open(),(this.default?this.yesBtn:this.noBtn).focus()}resolve(e){this.callback&&!this.invoked&&(this.invoked=!0,this.callback(e)),this.close()}};function q(i,s){let{modalEl:e}=i,t=createEl("div",{cls:"spacekeys-modal-title"});return e.insertBefore(t,e.firstChild),s&&(t.textContent=s),t}var W=require("obsidian");var D=class extends Error{};function C(i,s){if(!i)throw new D(s)}var h=class extends Error{constructor(e,{details:t,context:n}={}){super(e);this.details=t!=null?t:null,this.context=n!=null?n:null}};function I(i,s="(internal error)"){return i instanceof h?i.message:s}function V(i){return typeof i=="object"&&!Array.isArray(i)&&i!==null}function B(i,s){let e={};for(let t in s){let n=s[t];if(t in i){let o=i[t];V(n)&&V(o)?e[t]=B(o,n):e[t]=o}else e[t]=n}return e}function U(i,s=/\s+/){if(s instanceof RegExp){let e=s.exec(i);return e?[i.substring(0,e.index),i.substring(e.index+e[0].length)]:[i,null]}else{let e=i.indexOf(s);return e<0?[i,null]:[i.substring(0,e),i.substring(e+s.length)]}}var z=`This is a sample keymap file for the [Spacekeys](http://github.com/jlumpe/obsidian-spacekeys) Obsidian plugin. The keymap itself is defined in a YAML code block below, it is wrapped in a Markdown file to allow editing within Obsidian. To use this file, enter its path in the Spacekeys plugin settings. + +You can use the "Spacekeys: Find command ID" command to search for command IDs (either by assigning it a hotkey or invoking it through the command palette). See the plugin's description for more detailed instructions. + + +`;function O(i){return typeof i=="object"&&!Array.isArray(i)&&i!==null}var g=class extends Error{constructor(e,t=null,n){super(e);this.path=t;this.data=n}};function y(i,s,e,t){throw new g(i,t?s.concat(t):s,e)}var me={space:" ",spc:" ",up:"arrowup",down:"arrowdown",left:"arrowleft",right:"arrowright"};function ue(i){var o;let s={success:!1,error:"Invalid key code: "+JSON.stringify(i)};if(!i)return s;if(i=="-")return{success:!0,key:new u("-")};let e={},t,n=i.indexOf("-");if(n>=0){let a=i.substring(0,n);if(t=i.substring(n+1).toLowerCase(),!t||!a)return s;for(let l=0;l1&&(t=t.toLowerCase()),t=(o=me[t])!=null?o:t,_.test(t)?(w(t)&&(e.shift=!1),{success:!0,key:new u(t,e)}):s}var he={" ":"spc",arrowup:"up",arrowdown:"down",arrowleft:"left",arrowright:"right"};function $(i){var t;let s=(t=he[i.key])!=null?t:i.key,e="";return i.ctrl&&(e+="c"),i.shift&&(e+="s"),i.alt&&(e+="a"),i.meta&&(e+="m"),e?e+"-"+s:s}function ge(i,s){if(!O(i))throw new g("Root element not an object",[],i);if(!("items"in i))throw new g('Expected "items" property',[],i);let e=J(i,[],s);return C(e instanceof d),e}function J(i,s,e){let t;if(typeof i=="string"){let[n,o]=U(i.trim()," ");t=new p(n,o==null?void 0:o.trim())}else if(O(i))"items"in i?("command"in i&&y('Object has both "items" and "command" properties',s,i),t=fe(i,s,e)):"command"in i?(typeof i.command!="string"&&y("Expected string",s,i.command,["command"]),t=new p(i.command)):y('Object must have either "items" or "command" property',s,i),"description"in i&&(typeof i.description!="string"&&i.description!==null&&y("Expected string or null",s,i.description,["description"]),t.description=i.description);else throw y("Expected string or object",s,i);if(t instanceof p&&!t.command_id)throw y("Command ID cannot be empty",s,t.command_id,["command"]);return t}function fe(i,s,e){let t;!O(i.items)&&i.items!==null&&y("Expected group.items to be an object",s,i.item,["items"]),i.clear!==void 0&&typeof i.clear!="boolean"&&y("Expected group.clear to be a bool",s,i.clear,["clear"]),e&&i.clear!==!0?t=e.copy():t=new d;for(let n in i.items){let o=i.items[n],a=ue(n);a.success||y(a.error,s,i.items,["items"]);let l=a.key;if(o===null){t.removeChild(l);continue}let c=t.getChild(l),f=c instanceof d?c:void 0,k=J(o,s.concat(["items",n]),f);t.setChild(l,k)}return t}function E(i,s){let e;try{e=(0,W.parseYaml)(i)}catch(t){throw new g(String(t))}return ge(e,s)}function X(i,s){let e=ye(i);if(!e)throw new g("No code block found");return E(e,s)}function ye(i){let s=i.matchAll(/^```.*$/mg),e=null;for(let t of s)if(C(t.index),e===null)e=t.index+t[0].length;else return i.substring(e,t.index);return null}function T(i,s){return s&&s!="auto"?s:/\.ya?ml$/.test(i)?"yaml":/\.md$/.test(i)?"markdown":null}function Q(i){let s=z;return s+="```yaml\n",s+=i,s+="\n```\n",s}function Z(i){return i.map(s=>s.basicRepr()).join(" ")}var Y={delay:500,execDelay:100,showInvalid:!0,backspaceReverts:!0,backspaceCloses:!0,trimDescriptions:!0,dimBackground:!0},S=class extends m.Modal{constructor(e,t,n){super(e);this.timeoutHandle=null;this.commands=t,this.settings=Object.assign({},Y,n),this.containerEl.addClass("spacekeys-modal-container"),this.modalEl.addClass("spacekeys-modal"),this.modalEl.empty(),this.suggestionsEl=this.modalEl.createEl("div",{cls:"spacekeys-suggestions"}),this.statusEl=this.modalEl.createEl("div",{cls:"spacekeys-modal-status"}),this.isOpen=!1,this.setCollapsed(!0),this.dimBackground=this.settings.dimBackground,this.keySequence=[],this.scope.register(null,null,this.handleKey.bind(this))}onOpen(){super.onOpen(),this.isOpen=!0,this.settings.delay<=0?this.setCollapsed(!1):this.setExpandTimer(),this.update()}onClose(){super.onClose(),this.isOpen=!1,this.clearExpandTimer(),this.setCollapsed(!0)}setExpandTimer(){this.clearExpandTimer(),this.isOpen&&this.isCollapsed&&(this.timeoutHandle=window.setTimeout(()=>this.delayedExpand(),this.settings.delay))}clearExpandTimer(){this.timeoutHandle!==null&&window.clearTimeout(this.timeoutHandle),this.timeoutHandle=null}delayedExpand(){this.timeoutHandle=null,this.isOpen&&this.setCollapsed(!1)}setCollapsed(e){e=e&&this.settings.delay>0,this.isCollapsed=e,this.containerEl.toggleClass("spacekeys-modal-collapsed",e)}handleKey(e,t){if(this.settings.delay>0&&this.setExpandTimer(),this.settings.backspaceReverts&&t.key=="Backspace"){this.settings.backspaceCloses&&this.keySequence.length==0?this.close():(this.keySequence.pop(),this.update());return}this.keySequence.push(u.fromEvent(e)),this.update(),e.preventDefault()}update(){let e=this.commands.find(this.keySequence);if(e instanceof p){this.tryExec(e.command_id),this.close();return}let t=this.keySequence.length==0;if(this.statusEl.toggleClass("spacekeys-modal-status-empty",t),this.statusEl.empty(),this.keySequence.length==0?this.statusEl.appendText(""):this.statusEl.appendText(Z(this.keySequence)),this.suggestionsEl.empty(),e===null){this.invalidKeys(),this.close();return}let n=this.getSuggestions(e);for(let o of n){let a=this.suggestionsEl.createEl("div");this.renderSuggestion(o,a)}}getSuggestions(e){let t=[];for(let n of e.children){let o={key:n.key,item:n.item,command:n.item instanceof p?L(this.app,n.item.command_id):null};(this.settings.showInvalid||!(n.item instanceof p&&o.command===null))&&t.push(o)}return t.sort(this.compareSuggestions.bind(this)),t}compareSuggestions(e,t){let n=e.item instanceof d,o=t.item instanceof d;return n&&!o?-1:o&&!n?1:u.compare(e.key,t.key)}renderKey(e,t){let n=e.fancyRepr();t.addClass("spacekeys-suggestion-key"),t.createEl("kbd",{text:n})}renderSuggestion(e,t){t.addClass("spacekeys-suggestion");let n=e.item.description;e.item instanceof p?(t.addClass("spacekeys-command"),e.command?n||(n=this.getCommandDescription(e.command.name)):(t.addClass("spacekeys-invalid"),n!=null||(n=e.item.command_id))):t.addClass("spacekeys-group");let o=t.createEl("div");this.renderKey(e.key,o),t.createEl("div",{cls:"spacekeys-suggestion-label",text:n!=null?n:"?"}),t.setAttr("title",n)}getCommandDescription(e){var t,n;return this.settings.trimDescriptions&&(n=(t=/^.+:\s*(.*)/.exec(e))==null?void 0:t[1])!=null?n:e}tryExec(e){let t=L(this.app,e);t?this.execCommand(t):this.invalidCommand(e)}invalidCommand(e){let t=JSON.stringify(e),n=document.createDocumentFragment();n.appendText("Unknown command: "),n.createEl("code",{text:t}),new m.Notice(n),console.error("Invalid command ID: "+t)}execCommand(e){window.setTimeout(()=>this.app.commands.executeCommand(e),this.settings.execDelay)}invalidKeys(){let e=Z(this.keySequence),t=document.createDocumentFragment();t.appendText("Invalid key sequence: "),t.createEl("code",{text:e}),new m.Notice(t)}},K=class extends m.FuzzySuggestModal{constructor(s){super(s);let e=q(this);e.createEl("strong",{text:"Spacekeys"}),e.appendText(": find command"),this.setInstructions([{command:"\u21B5",purpose:"Copy ID"},{command:"Ctrl + \u21B5",purpose:"Insert ID"}]),this.scope.register(["Ctrl"],"Enter",(t,n)=>{this.chooser.useSelectedItem(t)})}getItems(){return j(this.app)}getItemText(s){return s.name+" "+s.id}onChooseItem(s,e){e.ctrlKey?this.insertCommand(s):this.copyCommand(s)}copyCommand(s){navigator.clipboard.writeText(s.id),new m.Notice("Copied to clipboard: "+s.id)}insertCommand(s){let e=this.app.workspace.getActiveViewOfType(m.MarkdownView);e&&e.editor.replaceSelection(s.id)}},P=class extends m.Modal{constructor(e){super(e);this.keycodes="";this.initContents(),this.scope.register(null,null,this.handleKey.bind(this))}initContents(){this.setTitle("Spacekeys key code finder");let e=` + Enter one or more keypresses to get their key codes. + Press Esc to close the modal and copy the key codes to the clipboard. + `;this.contentEl.createEl("p",{text:e}),this.text=this.contentEl.createEl("input",{type:"text"}),this.text.addClass("spacekeys-key-code-generator"),this.text.readOnly=!0}handleKey(e,t){let n=u.fromEvent(e),o=$(n);this.keycodes&&(this.keycodes+=" "),this.keycodes+=o,this.text.value=this.keycodes,e.preventDefault()}onClose(){super.onClose(),this.keycodes&&(navigator.clipboard.writeText(this.keycodes),new m.Notice("Key code(s) copied to clipboard"))}};var ee=`items: + SPC: command-palette:open + TAB: editor:focus + /: global-search:open + ",": editor:context-menu + "?": switcher:open + P: app:go-back + N: app:go-forward + + w: + description: Workspace + items: + TAB: editor:focus + d: workspace:close + f: file-explorer:open + h: editor:focus-left + l: editor:focus-right + k: editor:focus-top + j: editor:focus-bottom + n: workspace:next-tab + N: workspace:new-tab + o: outline:open + p: workspace:previous-tab + P: workspace:toggle-pin + s: workspace:split-horizontal + S: workspace:toggle-stacked-tabs + t: tag-pane:open + u: workspace:undo-close-pane + v: workspace:split-vertical + L: app:toggle-left-sidebar + r: app:toggle-right-sidebar + R: app:toggle-ribbon + w: workspace:open-in-new-window + W: workspace:move-to-new-window + + x: + description: Close + items: + g: workspace:close-tab-group + G: workspace:close-others-tab-group + t: workspace:close + T: workspace:close-others + w: workspace:close-window + + # workspace:goto-tab-1 + # workspace:goto-tab-2 + # workspace:goto-tab-3 + # workspace:goto-tab-4 + # workspace:goto-tab-5 + # workspace:goto-tab-6 + # workspace:goto-tab-7 + # workspace:goto-tab-8 + # workspace:goto-last-tab + + # workspace:show-trash + + f: + description: File + items: + a: markdown:add-alias + c: workspace:copy-path + C: workspace:copy-url + d: app:delete-file + m: file-explorer:move-file + o: open-with-default-app:open + O: open-with-default-app:show + r: editor:open-search-replace + R: workspace:edit-file-title + s: editor:save-file + t: file-explorer:reveal-active-file + T: tag-pane:open + u: outline:open-for-current + /: editor:open-search + + n: + description: New + items: + c: file-explorer:duplicate-file + n: file-explorer:new-file + N: file-explorer:new-file-in-current-tab + r: file-explorer:new-file-in-new-pane + + + p: + description: Properties + items: + a: markdown:add-metadata-property + e: markdown:edit-metadata-property + c: markdown:clear-metadata-properties + + x: + description: Text + items: + b: editor:toggle-bold + c: editor:toggle-code + C: editor:toggle-comments + d: editor:delete-paragraph + F: editor:clear-formatting + i: editor:toggle-italics + p: editor:insert-codeblock + q: editor:toggle-blockquote + s: editor:toggle-strikethrough + l: editor:toggle-bullet-list + H: editor:toggle-highlight + M: editor:toggle-inline-math + + # editor:set-heading + # editor:set-heading-0 + # editor:set-heading-1 + # editor:set-heading-2 + # editor:set-heading-3 + # editor:set-heading-4 + # editor:set-heading-5 + # editor:set-heading-6 + # editor:rename-heading + + # editor:swap-line-down + # editor:swap-line-up + + # editor:toggle-bullet-list + # editor:toggle-checklist-status + # editor:toggle-numbered-list + # editor:cycle-list-checklist + + i: + description: Insert + items: + a: editor:attach-file + c: editor:insert-codeblock + C: editor:insert-callout + e: editor:insert-embed + l: editor:insert-link + L: editor:insert-wikilink + m: editor:insert-mathblock + r: editor:insert-horizontal-rule + T: editor:insert-tag + + t: + description: Template + items: + t: insert-template + d: insert-current-date + T: insert-current-time + + t: + description: Table + items: + h: editor:table-col-left + l: editor:table-col-right + k: editor:table-row-up + j: editor:table-row-down + c: editor:table-col-after + C: editor:table-col-before + r: editor:table-row-after + R: editor:table-row-before + v: editor:table-row-copy + V: editor:table-col-copy + i: editor:insert-table + + d: + description: Delete + items: + c: editor:table-col-delete + r: editor:table-row-delete + + a: + description: Align + items: + c: editor:table-col-align-center + l: editor:table-col-align-left + r: editor:table-col-align-right + + v: + description: View + items: + p: editor:toggle-source + r: markdown:toggle-preview + s: editor:toggle-spellcheck + T: window:toggle-always-on-top + + # window:reset-zoom + # window:zoom-in + # window:zoom-out + + # "Workspaces" core plugin + l: + description: Layout + items: + l: workspaces:save-and-load + L: workspaces:load + o: workspaces:open-modal + s: workspaces:save + +# editor:toggle-fold-properties +# editor:toggle-fold +# editor:unfold-all +# editor:fold-all +# editor:fold-less +# editor:fold-more + +# editor:follow-link +# editor:open-link-in-new-leaf +# editor:open-link-in-new-split +# editor:open-link-in-new-window + +`;var A={default:ee};var te={keymapFile:{path:null,format:"auto",extend:!1},modal:Y};function R(i){if(!(i in A))return console.error("No builtin keymap named "+i),null;let s=A[i];try{return E(s)}catch(e){console.error("Error parsing default keymap "+i),e instanceof g?console.error(e.message,e.path,e.data):console.error(e)}return null}var F=class extends r.Plugin{async onload(){var e;console.log("Loading Spacekeys"),this.registerCommands(),this.keymap=(e=R("default"))!=null?e:new d,await this.loadSettings(),this.addSettingTab(new N(this.app,this)),this.app.workspace.onLayoutReady(()=>{this.settings.keymapFile.path&&this.loadKeymap(!0).catch(t=>{let n=I(t);console.log(`Spacekeys: failed to load user keymap file ${this.settings.keymapFile.path}: ${n}`)})})}registerCommands(){this.addCommand({id:"leader",name:"Leader",callback:()=>this.activateLeader()}),this.addCommand({id:"load-keymap",name:"Reload keymap",callback:async()=>this.loadKeymap().then(()=>{new r.Notice("Keymap loaded from file")}).catch(e=>{new r.Notice("Failed to load keymap: "+I(e),5e3)})}),this.addCommand({id:"find-command",name:"Find command ID",callback:()=>{new K(this.app).open()}}),this.addCommand({id:"get-keycode",name:"Get key code",callback:()=>{new P(this.app).open()}})}onunload(){}async loadSettings(){let e=await this.loadData();if(e===null){this.settings=te;return}this.settings=B(e,te)}async saveSettings(){this.settings.pluginVersion=this.manifest.version,await this.saveData(this.settings)}activateLeader(){new S(this.app,this.keymap,this.settings.modal).open()}async loadKeymap(e=!1){let t=this.settings.keymapFile.path,n;if(!t){if(e)return!1;throw new h("Keymap file not set in plugin settings")}let o=this.app.vault.getFileByPath(t);if(o===null)throw new h("File not found");let a=T(t,this.settings.keymapFile.format);if(a==null)throw new h("Could not guess format of file from extension");try{n=await this.app.vault.cachedRead(o)}catch(c){throw console.error(c),new h("Unable to read file",{context:c})}let l=this.settings.keymapFile.extend&&R("default")||void 0;try{a==="markdown"?this.keymap=X(n,l):this.keymap=E(n,l)}catch(c){console.error(c);let f=c instanceof g?c.message:null;throw new h("Parse error",{details:f,context:c})}return!0}},N=class extends r.PluginSettingTab{constructor(e,t){super(e,t);this.plugin=t}display(){let{containerEl:e}=this;e.empty(),new r.Setting(e).setName("Spacekeys keymap file").setDesc("YAML or Markdown file defining a custom keymap (see plugin description).").setHeading().addButton(t=>t.setIcon("refresh-cw").setTooltip("(Re)load keymap from file").onClick(n=>this.loadKeymap()).setClass("mod-cta")).addButton(t=>t.setIcon("file-plus-2").setTooltip("Create file with default contents").onClick(n=>this.createFile())).addButton(t=>t.setIcon("pencil").setTooltip("Open file for editing").onClick(n=>this.openFile())).addButton(t=>t.setIcon("external-link").setTooltip("Show file in system explorer").onClick(n=>this.showFile())),new r.Setting(e).setName("Path").setDesc("Path to file within your vault, including extension (.md, .yml).").addText(t=>{var n;return t.setPlaceholder("spacekeys.md").setValue((n=this.plugin.settings.keymapFile.path)!=null?n:"").onChange(async o=>{o=o.trim(),this.plugin.settings.keymapFile.path=o?(0,r.normalizePath)(o):null,await this.plugin.saveSettings()})}),new r.Setting(e).setName("Format").setDesc('Force parsing as specified format, or leave on "Auto" to determine based on file extension.').addDropdown(t=>t.addOptions({auto:"Auto",markdown:"Markdown",yaml:"YAML"}).setValue(this.plugin.settings.keymapFile.format).onChange(async n=>{this.plugin.settings.keymapFile.format=n,await this.plugin.saveSettings()})),new r.Setting(e).setName("Extend default").setDesc("File extends the default keymap instead of defining a new one.").addToggle(t=>t.setValue(this.plugin.settings.keymapFile.extend).onChange(async n=>{this.plugin.settings.keymapFile.extend=n,await this.plugin.saveSettings()})),new r.Setting(e).setHeading().setName("Behavior"),new r.Setting(e).setName("Delay").setDesc("Delay before expanding suggestions modal (milliseconds).").addText(t=>t.setValue(""+this.plugin.settings.modal.delay).onChange(async n=>{let o=parseInt(n);this.plugin.settings.modal.delay=o>0?o:0,await this.plugin.saveSettings()})),new r.Setting(e).setName("Backspace undoes last keypress").setDesc("Pressing backspace while the leader modal is open undoes the last keypress. You can disable this to assign commands to the backspace key.").addToggle(t=>t.setValue(this.plugin.settings.modal.backspaceReverts).onChange(async n=>{this.plugin.settings.modal.backspaceReverts=n,await this.plugin.saveSettings()})),new r.Setting(e).setName("Backspace closes on empty").setDesc("Attempting to undo the last keypress when there is no input closes the leader modal.").addToggle(t=>t.setValue(this.plugin.settings.modal.backspaceCloses).onChange(async n=>{this.plugin.settings.modal.backspaceCloses=n,await this.plugin.saveSettings()})),new r.Setting(e).setHeading().setName("Appearance"),new r.Setting(e).setName("Dim background").setDesc("Dim the rest of the window when displaying key suggestions.").addToggle(t=>t.setValue(this.plugin.settings.modal.dimBackground).onChange(async n=>{this.plugin.settings.modal.dimBackground=n,await this.plugin.saveSettings()})),new r.Setting(e).setName("Shorten command labels").setDesc("Hide the part of the command description before the colon (if any). This is typically redundant. Does not apply to command descriptions set explicitly in the keymap file.").addToggle(t=>t.setValue(this.plugin.settings.modal.trimDescriptions).onChange(async n=>{this.plugin.settings.modal.trimDescriptions=n,await this.plugin.saveSettings()})),new r.Setting(e).setName("Show invalid commands").setDesc("Show key sequences with invalid command IDs. This can help with debugging your key map file.").addToggle(t=>t.setValue(this.plugin.settings.modal.showInvalid).onChange(async n=>{this.plugin.settings.modal.showInvalid=n,await this.plugin.saveSettings()}))}async loadKeymap(){if(!this.plugin.settings.keymapFile.path){let e=R("default");C(e),this.plugin.keymap=e,new r.Notice("Default keymap loaded");return}try{await this.plugin.loadKeymap(),new r.Notice("Keymap reloaded");return}catch(e){if(!(e instanceof h))throw e;this.showLoadErrorModal(e)}}showLoadErrorModal(e){let t=new r.Modal(this.app),n=t.contentEl.createEl("p",{text:e.message});if(t.setTitle("Error loading keymap"),e.context instanceof g){let{path:o}=e.context;n.appendText(": "+e.context.message),o&&(n.appendText(" (at "),o.length>0?(n.createEl("code",{text:o.join(".")}),n.appendText(" in")):n.appendText("root element of"),n.appendText(" YAML content)"))}n.appendText("."),new r.Setting(t.contentEl).addButton(o=>o.setButtonText("OK").setCta().onClick(a=>t.close())),t.open()}async createFile(){let e=this.plugin.settings.keymapFile.path;if(!e)return;let t=T(e,this.plugin.settings.keymapFile.format);if(t==null)throw new h("Could not guess format of file from extension");let n=A.default,o=t==="markdown"?Q(n):n,a=this.app.vault.getFileByPath(e);if(a){let l=new x(this.app,{title:"Keymap file exists",message:`The file "${e}" exists, overwrite?`,yesText:"Overwrite",yesCls:"mod-warning",default:!1});l.callback=async c=>{c&&(await this.app.vault.modify(a,o),v(this.app,a,{newLeaf:"tab"}))},l.open()}else{let l=await this.app.vault.create(e,o);v(this.app,l,{newLeaf:"tab"})}}openFile(){let e=this.plugin.settings.keymapFile.path;if(!e)return;let t=this.app.vault.getAbstractFileByPath(e);if(!(t instanceof r.TFile)){new r.Notice("Not a file: "+e);return}let n=T(e,this.plugin.settings.keymapFile.format);v(this.app,t,{newLeaf:n=="markdown"?"tab":!1})}showFile(){let e=this.plugin.settings.keymapFile.path;e&&this.app.showInFolder(e)}}; + +/* nosourcemap */ \ No newline at end of file diff --git a/.obsidian/plugins/spacekeys/manifest.json b/.obsidian/plugins/spacekeys/manifest.json new file mode 100644 index 000000000..3d85b05ab --- /dev/null +++ b/.obsidian/plugins/spacekeys/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "spacekeys", + "name": "Spacekeys", + "version": "0.3.1", + "minAppVersion": "1.7.0", + "description": "Define hotkeys based on sequences of keypresses.", + "author": "Jared Lumpe", + "authorUrl": "https://github.com/jlumpe", + "isDesktopOnly": true +} diff --git a/.obsidian/plugins/spacekeys/styles.css b/.obsidian/plugins/spacekeys/styles.css new file mode 100644 index 000000000..83c812822 --- /dev/null +++ b/.obsidian/plugins/spacekeys/styles.css @@ -0,0 +1,125 @@ +:root { + --spacekeys-suggestions-column-width: 250px; + --spacekeys-suggestions-max-height: 40%; +} + +.prompt .spacekeys-modal-title { + border-bottom: 1px solid var(--background-secondary); + font-size: var(--font-ui-small); + text-align: center; + padding: var(--size-4-2); +} + +.spacekeys-modal { + position: absolute; + bottom: 0; + width: 100%; + max-width: none; + min-height: 0; + max-height: var(--spacekeys-suggestions-max-height); + /* overflow: hidden; */ + + display: flex; + flex-direction: column; + + padding: var(--size-4-2); + gap: var(--size-4-2); + + border: none; + border-top: var(--modal-border-width) solid var(--modal-border-color); + border-radius: 0; + box-shadow: none; + + .spacekeys-suggestions { + flex: 1 1; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(var(--spacekeys-suggestions-column-width), 1fr)); + gap: var(--size-4-1) var(--size-4-2); + padding: 0; + overflow-y: auto; + + .spacekeys-suggestion { + display: flex; + flex-direction: row; + + /* line-height: var(--line-height-tight); */ + /* height: var(--line-height-tight); */ + + gap: var(--size-4-2); + + &:hover { + background-color: var(--background-modifier-hover); + } + + .spacekeys-suggestion-key { + flex: 0 0; + + kbd { + /* font-size: var(--font-ui-medium); */ + color: var(--text-accent); + } + } + + .spacekeys-suggestion-label { + flex: 1 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + &.spacekeys-group { + .spacekeys-suggestion-label { + color: var(--text-accent); + } + + .spacekeys-suggestion-key kbd { + /* Not very readable? */ + /* color: var(--text-on-accent); */ + /* background: var(--interactive-accent); */ + } + } + + &.spacekeys-command { + &.spacekeys-invalid { + .spacekeys-suggestion-label { + color: var(--text-error); + } + } + } + } + } + + .spacekeys-modal-status { + flex: 0 0; + font-size: var(--font-ui-medium); + font-family: monospace; + white-space: nowrap; + + &.spacekeys-modal-status-empty { + color: var(--text-muted); + } + } +} + +/* Collapsed state (after open, before delay) */ +.spacekeys-modal-container.spacekeys-modal-collapsed { + /* Hide the dimmed background effect */ + .modal-bg { + /* + For some reason, the default modal sets the opacity of the background element via an inline + style. Since that overrides any attempts to set the opacity via CSS, the hacky workaround + is to instead set the background color to transparent. + */ + background: rgba(0, 0, 0, 0); + } + .spacekeys-suggestions { + display: none; + } +} + + +input.spacekeys-key-code-generator { + width: 100%; + font-family: monospace; + font-size: var(--font-ui-large); +}