From 3589818a1c687a9c355e6a80eb5307a4a053d9fa Mon Sep 17 00:00:00 2001
From: Philipp Stracker
Date: Wed, 25 Feb 2026 21:59:24 +0100
Subject: [PATCH] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20Commit=20deployable=20p?=
=?UTF-8?q?lugin?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
dist/main.js | 2 +-
dist/manifest.json | 4 ++--
dist/styles.css | 20 ++++++++++++++++++++
3 files changed, 23 insertions(+), 3 deletions(-)
create mode 100644 dist/styles.css
diff --git a/dist/main.js b/dist/main.js
index 72ec6f8..ab27a88 100644
--- a/dist/main.js
+++ b/dist/main.js
@@ -3,4 +3,4 @@ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
-var S=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var C=(r,s)=>{for(var t in s)S(r,t,{get:s[t],enumerable:!0})},I=(r,s,t,e)=>{if(s&&typeof s=="object"||typeof s=="function")for(let i of F(s))!b.call(r,i)&&i!==t&&S(r,i,{get:()=>s[i],enumerable:!(e=w(s,i))||e.enumerable});return r};var A=r=>I(S({},"__esModule",{value:!0}),r);var N={};C(N,{default:()=>M});module.exports=A(N);var L=require("obsidian");var h={mentionTypes:[],matchStart:!0,maxMatchLength:15,stopCharacters:"?!\"'`:;/#+*=&%$\xA7<>"},k="@#+!$%^&*~=-:;><|",T=k.split("");var x=require("obsidian");function u(r,s){if(!r.endsWith(".md"))return null;for(let t=0;t{if(t instanceof x.TFile&&t.extension==="md"){let e=u(t.path,this.settings);e&&this.addFileToMap(e)}}),this.fileMaps}getFileMaps(){return this.fileMaps}updateIndex(s,t){let e=!1,i=u(s,this.settings);if(i&&(this.addFileToMap(i),e=!0),t){let n=u(t,this.settings);n&&(this.removeFileFromMap(n),e=!0)}return e}addFileToMap(s){let t=s.sign;if(!t)return;let e=s.name.toLowerCase();this.fileMaps[t]=this.fileMaps[t]||{},this.fileMaps[t][e]=s}removeFileFromMap(s){let t=s.sign;if(!t||!this.fileMaps[t])return;let e=s.name.toLowerCase();delete this.fileMaps[t][e]}};var c=class{constructor(s,t){this.settings=t,this.fileIndexer=new d(s,t)}initialize(){return this.fileIndexer.initialize()}getFileMaps(){return this.fileIndexer.getFileMaps()}handleFileEvent(s,t){return this.fileIndexer.updateIndex(s.path,t)}getUsedSigns(){return this.settings.mentionTypes.map(s=>s.sign).filter(Boolean)}updateSettings(s){this.settings=s,this.initialize()}};var E=require("obsidian");var m=class extends E.EditorSuggest{constructor(t,e,i){super(t);this.currSign="";this.settings=e,this.mentionManager=i,this.fileMaps=i.getFileMaps()}setSuggestionsMap(t){this.fileMaps=t}onTrigger(t,e,i){let n=e.getLine(t.line).substring(0,t.ch);if(!n)return null;let{signIndex:o,sign:g}=this.findMostRecentSign(n);if(o<0)return null;this.currSign=g;let a=n.substring(o+1);return this.shouldShowSuggestions(a,o,n)?{start:{line:t.line,ch:o},end:{line:t.line,ch:t.ch},query:a}:null}findMostRecentSign(t){let e=this.mentionManager.getUsedSigns(),i=-1,n="";for(let o of e){let g=t.lastIndexOf(o);g!==-1&&g>i&&(i=g,n=o)}return{signIndex:i,sign:n}}shouldShowSuggestions(t,e,i){var g,a;if(!t||t.includes("]]"))return!1;let n=(g=this.settings.maxMatchLength)!=null?g:h.maxMatchLength;if(n&&t.length>n)return!1;let o=(a=this.settings.stopCharacters)!=null?a:h.stopCharacters;if(o){for(let l of o)if(t.includes(l))return!1}return e===0||i[e-1]===" "}getSuggestions(t){let e=[],i=this.fileMaps[this.currSign]||{},n=t.query.toLowerCase();return e=this.getMatchingSuggestions(i,n,t),e.push(this.createNewItemSuggestion(t)),e}getMatchingSuggestions(t,e,i){let n=[];for(let o in t)o&&this.isMatch(o,e)&&n.push({suggestionType:"set",displayText:t[o].name.trim(),linkName:t[o].name,context:i});return n}isMatch(t,e){return this.settings.matchStart?t.startsWith(e):t.includes(e)}createNewItemSuggestion(t){return{suggestionType:"create",displayText:t.query,linkName:t.query,context:t}}renderSuggestion(t,e){if(t.suggestionType==="create"){let i=v(this.settings.mentionTypes,this.currSign),n=(i==null?void 0:i.label)||"Item";e.setText(`Create ${n}: ${t.displayText}`)}else e.setText(t.displayText)}selectSuggestion(t,e){let i=y(this.currSign,t.linkName);t.context.editor.replaceRange(i,t.context.start,t.context.end)}};var p=require("obsidian");var f=class extends p.PluginSettingTab{constructor(t,e){super(t,e);this.plugin=e}display(){let{containerEl:t}=this,e=this.plugin.settings.mentionTypes.map(i=>i.sign).filter(i=>i!==void 0);t.empty(),new p.Setting(t).setName("Mention Things").setHeading(),this.renderMentionTypesSection(t,e),this.renderGeneralSettings(t)}renderMentionTypesSection(t,e){this.plugin.settings.mentionTypes.forEach((i,n)=>{this.renderMentionTypeRow(t,i,n,e)}),new p.Setting(t).addButton(i=>{i.setButtonText("New type").setCta().onClick(async()=>{this.plugin.settings.mentionTypes.push({}),await this.plugin.saveSettings(),this.display()})})}renderMentionTypeRow(t,e,i,n){let o=new p.Setting(t),g=this.getAvailableSigns(n,e==null?void 0:e.sign);o.addDropdown(a=>a.addOptions(g).setValue((e==null?void 0:e.sign)||"").onChange(async l=>{this.plugin.settings.mentionTypes[i].sign=l,await this.plugin.saveSettings(),this.display()})),o.addText(a=>a.setPlaceholder('Type label, for example "Person"').setValue((e==null?void 0:e.label)||"").onChange(async l=>{this.plugin.settings.mentionTypes[i].label=l,await this.plugin.saveSettings()}).inputEl.addClass("type_label")),o.addExtraButton(a=>a.setIcon("cross").setTooltip("Delete").onClick(async()=>{this.plugin.settings.mentionTypes.splice(i,1),await this.plugin.saveSettings(),this.display()})),o.infoEl.remove()}renderGeneralSettings(t){new p.Setting(t).setName("General settings").setHeading(),new p.Setting(t).setName("Match from start").setDesc("Whether to suggest only items that start with the search term. When disabled, any part of the name can match the search term").addToggle(e=>{var i;return e.setValue((i=this.plugin.settings.matchStart)!=null?i:!1).onChange(async n=>{this.plugin.settings.matchStart=n,await this.plugin.saveSettings()})}),new p.Setting(t).setName("Max match length").setDesc("Maximum number of characters to match (3-50)").addSlider(e=>{var i;e.setLimits(3,50,1).setValue((i=this.plugin.settings.maxMatchLength)!=null?i:15).setDynamicTooltip().onChange(async n=>{this.plugin.settings.maxMatchLength=n,await this.plugin.saveSettings()})}),new p.Setting(t).setName("Stop characters").setDesc("Characters that will stop the matching process. Leave empty to disable.").addText(e=>{var i;e.setPlaceholder("?!\"'`:;/#+*=&%$\xA7<>").setValue((i=this.plugin.settings.stopCharacters)!=null?i:"?!\"'`:;/#+*=&%$\xA7<>").onChange(async n=>{let o=[...new Set(n.split(""))].join("");this.plugin.settings.stopCharacters=o,await this.plugin.saveSettings()})})}getAvailableSigns(t,e){let i={};return T.forEach(n=>{(e===n||!t.includes(n))&&(i[n]=`${n}Name`)}),i}};var M=class extends L.Plugin{async onload(){await this.loadSettings(),this.mentionManager=new c(this.app,this.settings),this.suggestionProvider=new m(this.app,this.settings,this.mentionManager),this.registerEditorSuggest(this.suggestionProvider),this.addSettingTab(new f(this.app,this)),this.registerFileEvents(),this.app.workspace.onLayoutReady(()=>{let t=this.mentionManager.initialize();this.suggestionProvider.setSuggestionsMap(t)})}registerFileEvents(){this.registerEvent(this.app.vault.on("delete",async t=>{this.mentionManager.handleFileEvent(t)&&this.refreshSuggestions()})),this.registerEvent(this.app.vault.on("create",async t=>{this.mentionManager.handleFileEvent(t)&&this.refreshSuggestions()})),this.registerEvent(this.app.vault.on("rename",async(t,e)=>{this.mentionManager.handleFileEvent(t,e)&&this.refreshSuggestions()}))}refreshSuggestions(){let t=this.mentionManager.getFileMaps();this.suggestionProvider.setSuggestionsMap(t)}async loadSettings(){this.settings=Object.assign({},h,await this.loadData())}async saveSettings(){await this.saveData(this.settings),this.mentionManager&&(this.mentionManager.updateSettings(this.settings),this.refreshSuggestions())}};
+var T=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var N=(a,i)=>{for(var t in i)T(a,t,{get:i[t],enumerable:!0})},P=(a,i,t,e)=>{if(i&&typeof i=="object"||typeof i=="function")for(let n of C(i))!I.call(a,n)&&n!==t&&T(a,n,{get:()=>i[n],enumerable:!(e=k(i,n))||e.enumerable});return a};var D=a=>P(T({},"__esModule",{value:!0}),a);var G={};N(G,{default:()=>y});module.exports=D(G);var A=require("obsidian");var c={mentionTypes:[],matchStart:!0,maxMatchLength:15,stopCharacters:"?!;:\"'`/#*%<>[]()"},$="@!+$&~-_=,;'{}^\xA7\u2605\u2192\xB6\xB0\u20AC\xA3\xA5\xA2\xB1\xB5\xA9\u2122\xAE\xAB\xBB",v=$.split("");var E=require("obsidian");var x=require("obsidian");function u(a,i){var e,n;if(!a.endsWith(".md"))return null;let t=(n=(e=a.split("/"))==null?void 0:e.pop())==null?void 0:n.replace(/\.[^.]+$/,"");if(!t)return null;for(let s=0;s{if(!(t instanceof E.TFile)||t.extension!=="md")return;let e=u(t.path,this.settings);e&&this.addFileToMap(e)}),this.fileMaps}getFileMaps(){return this.fileMaps}updateIndex(i,t){let e=!1,n=u(i,this.settings);if(n&&(this.addFileToMap(n),e=!0),t){let s=u(t,this.settings);s&&(this.removeFileFromMap(s),e=!0)}return e}addFileToMap(i){let t=i.sign;if(!t)return;let e=i.name.toLowerCase();this.fileMaps[t]=this.fileMaps[t]||{},this.fileMaps[t][e]=i}removeFileFromMap(i){let t=i.sign;if(!t||!this.fileMaps[t])return;let e=i.name.toLowerCase();delete this.fileMaps[t][e]}};var f=class{constructor(i,t){this.settings=t,this.fileIndexer=new m(i,t)}initialize(){return this.fileIndexer.initialize()}getFileMaps(){return this.fileIndexer.getFileMaps()}handleFileEvent(i,t){return this.fileIndexer.updateIndex(i.path,t)}getUsedSigns(){return this.settings.mentionTypes.map(i=>i.sign).filter(Boolean)}updateSettings(i){this.settings=i,this.initialize()}};var F=require("obsidian");var M=class extends F.EditorSuggest{constructor(t,e,n){super(t);this.currSign="";this.prevMention="";this.settings=e,this.mentionManager=n,this.fileMaps=n.getFileMaps()}get currType(){return w(this.settings.mentionTypes,this.currSign)}setSuggestionsMap(t){this.fileMaps=t}onTrigger(t,e,n){let s=e.getLine(t.line).substring(0,t.ch);if(!s)return null;let{signIndex:r,sign:o}=this.findMostRecentSign(s);if(r<0)return null;this.currSign=o;let l=s.substring(r+1);return this.shouldShowSuggestions(l,r,s)?{start:{line:t.line,ch:r},end:{line:t.line,ch:t.ch},query:l}:null}findMostRecentSign(t){let e=this.mentionManager.getUsedSigns(),n=-1,s="";for(let r of e){let o=t.lastIndexOf(r);o!==-1&&o>n&&(n=o,s=r)}return{signIndex:n,sign:s}}shouldShowSuggestions(t,e,n){var o,l;if(!t)return!1;if(this.prevMention){if(t.startsWith(this.prevMention))return!1;this.prevMention=""}if(/\[\[.*]]/.test(t)||/\[.*]\(.*\)/.test(t))return!1;let s=(o=this.settings.maxMatchLength)!=null?o:c.maxMatchLength;if(s&&t.length>s)return!1;let r=(l=this.settings.stopCharacters)!=null?l:c.stopCharacters;if(r){for(let h of r)if(t.includes(h))return!1}return e===0||n[e-1]===" "}getSuggestions(t){let e,n=this.fileMaps[this.currSign]||{},s=t.query.toLowerCase();return e=this.getMatchingSuggestions(n,s,t),e.push(this.createNewItemSuggestion(t)),e}getMatchingSuggestions(t,e,n){let s=[];for(let r in t)r&&this.isMatch(r,e)&&s.push({suggestionType:"set",displayText:t[r].name.trim(),linkName:t[r].name,path:t[r].path,context:n});return s}isMatch(t,e){return this.settings.matchStart?t.startsWith(e):t.includes(e)}createNewItemSuggestion(t){return{suggestionType:"create",displayText:t.query,linkName:t.query,path:"",context:t}}renderSuggestion(t,e){if(t.suggestionType==="create"){let n=this.currType,s=(n==null?void 0:n.label)||"Item";e.setText(`Create ${s}: ${t.displayText}`)}else e.setText(t.displayText)}selectSuggestion(t,e){var o;let n=this.currType;if(!(n!=null&&n.sign))return;let s=t.context;console.log("Insert:",n,t);let r=b(this.app,s.file.path,t.path,n.sign,t.linkName,(o=n.type)!=null?o:"link");this.prevMention=t.linkName,t.context.editor.replaceRange(r,t.context.start,t.context.end)}};var g=require("obsidian");var S=class extends g.PluginSettingTab{constructor(i,t){super(i,t),this.plugin=t}display(){let{containerEl:i}=this,t=this.plugin.settings.mentionTypes.map(e=>e.sign).filter(e=>e!==void 0);i.empty(),new g.Setting(i).setName("Mention Things").setHeading(),this.renderMentionTypesSection(i,t),this.renderGeneralSettings(i)}renderMentionTypesSection(i,t){this.plugin.settings.mentionTypes.forEach((e,n)=>{this.renderMentionTypeRow(i,e,n,t)}),new g.Setting(i).addButton(e=>{e.setButtonText("New type").setCta().onClick(async()=>{this.plugin.settings.mentionTypes.push({}),await this.plugin.saveSettings(),this.display()})})}renderMentionTypeRow(i,t,e,n){let s=new g.Setting(i),r=this.getAvailableSigns(n,t==null?void 0:t.sign),o=this.getAvailableTypes();s.setClass("mention-type-row"),s.addDropdown(p=>p.addOptions(r).setValue((t==null?void 0:t.sign)||"").onChange(async d=>{this.plugin.settings.mentionTypes[e].sign=d,await this.plugin.saveSettings(),this.display()})),s.addText(p=>p.setPlaceholder('Type label, for example "Person"').setValue((t==null?void 0:t.label)||"").onChange(async d=>{this.plugin.settings.mentionTypes[e].label=d,await this.plugin.saveSettings(),l()}).inputEl.addClass("type-label")),s.addDropdown(p=>p.addOptions(o).setValue((t==null?void 0:t.type)||"link").onChange(async d=>{this.plugin.settings.mentionTypes[e].type=d,await this.plugin.saveSettings(),this.display()}));let l=()=>{let p=t.label||"Name";h.classList.add("type-preview"),h.innerText=L(this.app,t.type,t.sign,p)},h=s.controlEl.createSpan();s.controlEl.append(h),l(),s.addExtraButton(p=>p.setIcon("cross").setTooltip("Delete").onClick(async()=>{this.plugin.settings.mentionTypes.splice(e,1),await this.plugin.saveSettings(),this.display()})),s.infoEl.remove()}renderGeneralSettings(i){new g.Setting(i).setName("General settings").setHeading(),new g.Setting(i).setName("Match from start").setDesc("Whether to suggest only items that start with the search term. When disabled, any part of the name can match the search term").addToggle(t=>{var e;return t.setValue((e=this.plugin.settings.matchStart)!=null?e:!1).onChange(async n=>{this.plugin.settings.matchStart=n,await this.plugin.saveSettings()})}),new g.Setting(i).setName("Max match length").setDesc("Maximum number of characters to match (3-50)").addSlider(t=>{var e;t.setLimits(3,50,1).setValue((e=this.plugin.settings.maxMatchLength)!=null?e:15).setDynamicTooltip().onChange(async n=>{this.plugin.settings.maxMatchLength=n,await this.plugin.saveSettings()})}),new g.Setting(i).setName("Stop characters").setDesc("Characters that will stop the matching process. Leave empty to disable.").addText(t=>{var e;t.setPlaceholder("?!\"'`:;/#+*=&%$\xA7<>").setValue((e=this.plugin.settings.stopCharacters)!=null?e:"?!\"'`:;/#+*=&%$\xA7<>").onChange(async n=>{this.plugin.settings.stopCharacters=[...new Set(n.split(""))].join(""),await this.plugin.saveSettings()})})}getAvailableSigns(i,t){let e={};return v.forEach(n=>{(t===n||!i.includes(n))&&(e[n]=`${n}Name`)}),e}getAvailableTypes(){let i={};return i.text="As Text",i.link="As Link",i}};var y=class extends A.Plugin{async onload(){await this.loadSettings(),this.mentionManager=new f(this.app,this.settings),this.suggestionProvider=new M(this.app,this.settings,this.mentionManager),this.registerEditorSuggest(this.suggestionProvider),this.addSettingTab(new S(this.app,this)),this.registerFileEvents(),this.app.workspace.onLayoutReady(()=>{let i=this.mentionManager.initialize();this.suggestionProvider.setSuggestionsMap(i)})}registerFileEvents(){this.registerEvent(this.app.vault.on("delete",async i=>{this.mentionManager.handleFileEvent(i)&&this.refreshSuggestions()})),this.registerEvent(this.app.vault.on("create",async i=>{this.mentionManager.handleFileEvent(i)&&this.refreshSuggestions()})),this.registerEvent(this.app.vault.on("rename",async(i,t)=>{this.mentionManager.handleFileEvent(i,t)&&this.refreshSuggestions()}))}refreshSuggestions(){let i=this.mentionManager.getFileMaps();this.suggestionProvider.setSuggestionsMap(i)}async loadSettings(){this.settings=Object.assign({},c,await this.loadData())}async saveSettings(){await this.saveData(this.settings),this.mentionManager&&(this.mentionManager.updateSettings(this.settings),this.refreshSuggestions())}};
diff --git a/dist/manifest.json b/dist/manifest.json
index d0c4fe8..b70cbb0 100644
--- a/dist/manifest.json
+++ b/dist/manifest.json
@@ -1,10 +1,10 @@
{
"id": "mention-things",
"name": "Mention Things",
- "version": "1.0.2",
+ "version": "1.1.0",
"minAppVersion": "0.15.0",
"description": "Define a list of prefixes to trigger an autocomplete suggestion to insert a link.",
"author": "Philipp Stracker",
"authorUrl": "https://philippstracker.com",
"isDesktopOnly": false
-}
+}
\ No newline at end of file
diff --git a/dist/styles.css b/dist/styles.css
new file mode 100644
index 0000000..d548335
--- /dev/null
+++ b/dist/styles.css
@@ -0,0 +1,20 @@
+.mention-type-row {
+ --preview-width: 20ch;
+
+ .type-label {
+ flex: 1 1 auto;
+ }
+
+ .type-preview {
+ display: inline-block;
+ min-width: var(--preview-width);
+ max-width: var(--preview-width);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ text-align: left;
+ font-size: 12px;
+ opacity: 0.7;
+ }
+}