8 Commits
0.8.0 ... 0.8.3

Author SHA1 Message Date
Daniel Bauer
d85c07126f bump version 2024-12-18 11:07:11 +01:00
Daniel Bauer
020054857b feat: remove lookbehinds, make compatible with iOS 2024-12-18 11:07:06 +01:00
Daniel Bauer
f58f736df4 feat: replace innerHTML call with createEL (obsidian plugin guidelines) 2024-12-18 10:34:00 +01:00
Daniel Bauer
1644899116 bump version 2024-12-17 19:46:30 +01:00
Daniel Bauer
1debbb51f2 remove unused styles.css 2024-12-17 19:46:30 +01:00
Daniel Bauer
dd86b55bed chore: remove debug statements 2024-12-17 19:43:32 +01:00
Daniel Bauer
8240045641 fix: index not building on plugin enabling 2024-12-17 19:36:20 +01:00
Daniel Bauer
2dae1175f8 fix: indexing not working if there are non-markdown files 2024-12-17 18:47:41 +01:00
8 changed files with 60 additions and 57 deletions

View File

@@ -1,7 +1,7 @@
{ {
"id": "dataview-autocompletion", "id": "dataview-autocompletion",
"name": "Dataview Autocompletion", "name": "Dataview Autocompletion",
"version": "0.8.0", "version": "0.8.3",
"minAppVersion": "0.15.0", "minAppVersion": "0.15.0",
"description": "Adds autocompletion to Dataview metadata fields", "description": "Adds autocompletion to Dataview metadata fields",
"author": "Daniel Bauer", "author": "Daniel Bauer",

View File

@@ -1,6 +1,6 @@
{ {
"name": "obsidian-dataview-autocompletion", "name": "obsidian-dataview-autocompletion",
"version": "0.8", "version": "0.8.3",
"description": "This is a plugin for Obsidian that provides autocompletion for Dataview metadata fields", "description": "This is a plugin for Obsidian that provides autocompletion for Dataview metadata fields",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
@@ -8,6 +8,7 @@
"build": "npx rollup --config rollup.config.js --environment BUILD:production", "build": "npx rollup --config rollup.config.js --environment BUILD:production",
"check-format": "npx prettier --check src", "check-format": "npx prettier --check src",
"test": "npx jest", "test": "npx jest",
"bdd": "npx jest -i --watch --no-cache",
"version": "node ersion-bump.mjs && git add manifest.json versions.json" "version": "node ersion-bump.mjs && git add manifest.json versions.json"
}, },
"keywords": [ "keywords": [

View File

@@ -68,9 +68,19 @@ export class DataviewSuggester extends EditorSuggest<String> {
} }
renderSuggestion(value: string, el: HTMLElement): void { renderSuggestion(value: string, el: HTMLElement): void {
// replace marks with bold // Split the value into parts based on the <mark> tags and their content
const formattedHtml = value.replace(/<mark>(.*?)<\/mark>/g, '<span style="font-weight: bold;">$1</span>'); const parts = value.split(/(<mark>.*?<\/mark>)/g);
el.innerHTML = formattedHtml;
// We cannot use inner HTML; Create a span for each part
parts.forEach((part) => {
if (part.startsWith("<mark>") && part.endsWith("</mark>")) {
const text = part.slice(6, -7); // Remove <mark> and </mark>
el.createEl("span", { text, cls: "suggestion-highlight" });
} else {
// For normal text, create a text node or <span>
el.createEl("span", { text: part });
}
});
} }
selectSuggestion(value: string, evt: MouseEvent | KeyboardEvent): void { selectSuggestion(value: string, evt: MouseEvent | KeyboardEvent): void {
@@ -159,6 +169,8 @@ export class DataviewSuggester extends EditorSuggest<String> {
} }
const page = dataviewApi.page(file.path); const page = dataviewApi.page(file.path);
if (page === undefined) continue; // not a markdown file
const fields = Object.keys(page) const fields = Object.keys(page)
.filter((k) => k !== "file") .filter((k) => k !== "file")
.map((k) => [k, page[k]]); .map((k) => [k, page[k]]);
@@ -218,6 +230,8 @@ export class DataviewSuggester extends EditorSuggest<String> {
const updateCompositeValues = []; const updateCompositeValues = [];
const page = getAPI(this.app).page(file.path); const page = getAPI(this.app).page(file.path);
if (page === undefined) return; // not a markdown file
const fields = Object.keys(page) const fields = Object.keys(page)
.filter((k) => k !== "file") .filter((k) => k !== "file")
.map((k) => [k, page[k]]); .map((k) => [k, page[k]]);
@@ -297,13 +311,12 @@ export class DataviewSuggester extends EditorSuggest<String> {
for (const value of this.suggestionsRefs.get(file.path)!) { for (const value of this.suggestionsRefs.get(file.path)!) {
this.suggestionsRefCount.set(value, this.suggestionsRefCount.get(value)! - 1); this.suggestionsRefCount.set(value, this.suggestionsRefCount.get(value)! - 1);
if (this.suggestionsRefCount.get(value) === 0) { if (this.suggestionsRefCount.get(value) === 0) {
console.debug("deleting value from suggestion index", value);
this.suggestionsList.splice(this.suggestionsList.indexOf(value), 1); this.suggestionsList.splice(this.suggestionsList.indexOf(value), 1);
} }
} }
this.suggestionsRefs.delete(file.path); this.suggestionsRefs.delete(file.path);
} else { } else {
console.warn("Unknown update type:", type, file, oldPath); console.debug("Unknown update type:", type, file, oldPath);
} }
} }
} }

View File

@@ -1,6 +1,6 @@
import { App, Plugin, PluginSettingTab, Setting, TFile } from "obsidian"; import { App, Plugin, PluginSettingTab, Setting, TFile } from "obsidian";
import { DataviewSuggester } from "./DataviewSuggester"; import { DataviewSuggester } from "./DataviewSuggester";
import { getAPI } from "obsidian-dataview"; import { getAPI, isPluginEnabled } from "obsidian-dataview";
import { SettingsTab } from "./SettingsTab"; import { SettingsTab } from "./SettingsTab";
interface DataviewAutocompleteSettings { interface DataviewAutocompleteSettings {
@@ -15,18 +15,19 @@ const DEFAULT_SETTINGS: DataviewAutocompleteSettings = {
export default class DataviewAutocompletePlugin extends Plugin { export default class DataviewAutocompletePlugin extends Plugin {
settings: DataviewAutocompleteSettings; settings: DataviewAutocompleteSettings;
suggester: DataviewSuggester | undefined; suggester: DataviewSuggester;
async onload() { async onload() {
await this.loadSettings(); await this.loadSettings();
this.addSettingTab(new SettingsTab(this.app, this)); this.addSettingTab(new SettingsTab(this.app, this));
this.suggester = new DataviewSuggester(this, 10, true, true);
this.registerEditorSuggest(this.suggester);
this.registerEvent( this.registerEvent(
// @ts-ignore // @ts-ignore
this.app.metadataCache.on("dataview:index-ready", () => { this.app.metadataCache.on("dataview:index-ready", () => {
if (this.suggester !== undefined) { this.suggester.onDataviewIndexReady();
this.suggester.onDataviewIndexReady();
}
}), }),
); );
@@ -35,24 +36,14 @@ export default class DataviewAutocompletePlugin extends Plugin {
// @ts-ignore // @ts-ignore
"dataview:metadata-change", "dataview:metadata-change",
(type: string, file: TFile, oldPath?: string) => { (type: string, file: TFile, oldPath?: string) => {
if (this.suggester !== undefined) { this.suggester.onDataviewMetadataChange(type, file, oldPath);
this.suggester.onDataviewMetadataChange(type, file, oldPath);
}
}, },
), ),
); );
this.app.workspace.onLayoutReady(() => { if (isPluginEnabled(this.app) && getAPI(this.app)?.index.initialized) {
// @ts-ignore this.suggester.onDataviewIndexReady();
if (!Object.keys(this.app.plugins.plugins).includes("dataview")) { }
console.warn("Dataview plugin not installed. Dataview Autocompletion plugin will not work.");
} else {
// register suggester, requires dataview to be loaded first.
console.log("Registering dataview autocompletion suggester");
this.suggester = new DataviewSuggester(this, 10, true, true);
this.registerEditorSuggest(this.suggester);
}
});
} }
onunload() {} onunload() {}

View File

@@ -3,29 +3,28 @@
* and captures the enclosed text * and captures the enclosed text
* If the brackets start a markdown link, they are ignored. * If the brackets start a markdown link, they are ignored.
* Wiki links don't need to be ignored since Obsidian overwrites suggestions for them. * Wiki links don't need to be ignored since Obsidian overwrites suggestions for them.
* We are not allowd to use lookbehinds, because iOS does not support them in older versions.
*/ */
const filledRegex = new RegExp( const filledRegex = new RegExp(
"(" + [
[ // pattern for parantheses
// pattern for parantheses // look for opening parantheses; no closing or opening square bracket before to exlude markdown links, etc.
// pos. lookbehind for opening parantheses; no closing square bracket before to exlude markdown links /(?:^\(|[^\[\]]\()/,
/(?<=^\(|[^\]]\()/, /(.+?)/,
/.+?/, // pos. lookahead for closing paranthesis; not followed by another one for nested ((test))
// pos. lookahead for closing paranthesis; not followed by another one for nested ((test)) /(?=\)$|\)[^\)])/,
/(?=\)$|\)[^\)])/,
/|/, /|/,
// pattern for square brackets // pattern for square brackets
// pos. lookbehind for opening square bracket // look for opening square brackets
/(?<=\[)/, /(?:\[)/,
/.+?/, /(.+?)/,
// pos. lookahead for closing bracket; not followed by another one ([[test]]) or an opening paranthese (markdown link!) // pos. lookahead for closing bracket; not followed by another one ([[test]]) or an opening paranthese (markdown link!)
/(?=\]$|\][^\]\(])/, /(?=\]$|\][^\]\(])/,
] ]
.map((s) => s.source) .map((s) => s.source)
.join("") + .join(""),
")",
"g", "g",
); );
@@ -52,17 +51,19 @@ export function getTriggerText(line: string, cursorPos: number): [string, number
*/ */
function getTriggerTextFromRegex(line: string, cursorPos: number, regex: RegExp): [string, number, number] | null { function getTriggerTextFromRegex(line: string, cursorPos: number, regex: RegExp): [string, number, number] | null {
let matches = Array.from(line.matchAll(regex)); let matches = Array.from(line.matchAll(regex));
console.log(matches);
for (const match of matches) { for (const match of matches) {
if (match.index === undefined) { if (match.index === undefined) {
continue; continue;
} }
const matchStart = match!.index; const matchText = match[1] || match[2];
const matchEnd = matchStart + match[1].length; const matchStart = match!.index + match[0].indexOf(matchText);
const matchEnd = matchStart + matchText.length;
const cursorInMatch = cursorPos >= matchStart && cursorPos <= matchEnd; const cursorInMatch = cursorPos >= matchStart && cursorPos <= matchEnd;
if (cursorInMatch) { if (cursorInMatch) {
return [match[1], matchStart, matchEnd]; return [matchText, matchStart, matchEnd];
} }
} }
return null; return null;

View File

@@ -1,8 +1,3 @@
/* span.suggestion-highlight {
font-weight: bold;
This CSS file will be included with your plugin, and }
available in the app when your plugin is enabled.
If your plugin does not need CSS, delete this file.
*/

View File

@@ -1,5 +1,6 @@
[ [
"sample-plugin", "sample-plugin",
"dataview", "dataview",
"obsidian-dataview-autocompletion" "obsidian-dataview-autocompletion",
"dataview-autocompletion"
] ]

View File

@@ -0,0 +1 @@
{"test": "this is a test file"}