mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
127 lines
3.6 KiB
TypeScript
127 lines
3.6 KiB
TypeScript
import {
|
|
Editor,
|
|
EditorPosition,
|
|
EditorSuggest,
|
|
EditorSuggestContext,
|
|
EditorSuggestTriggerInfo,
|
|
TFile,
|
|
} from "obsidian";
|
|
import { FRONTMATTER_KEYS_INFO } from "../Dialogs/SuggesterInfo";
|
|
import {
|
|
EXCALIDRAW_AUTOMATE_INFO,
|
|
EXCALIDRAW_SCRIPTENGINE_INFO,
|
|
} from "../Dialogs/SuggesterInfo";
|
|
import type ExcalidrawPlugin from "../../core/main";
|
|
|
|
/**
|
|
* The field suggester recommends document properties in source mode, ea and utils function and attribute names.
|
|
*/
|
|
export class FieldSuggester extends EditorSuggest<string> {
|
|
plugin: ExcalidrawPlugin;
|
|
suggestType: "ea" | "excalidraw" | "utils";
|
|
latestTriggerInfo: EditorSuggestTriggerInfo;
|
|
|
|
constructor(plugin: ExcalidrawPlugin) {
|
|
super(plugin.app);
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
onTrigger(
|
|
cursor: EditorPosition,
|
|
editor: Editor,
|
|
_: TFile,
|
|
): EditorSuggestTriggerInfo | null {
|
|
if (this.plugin.settings.fieldSuggester) {
|
|
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
|
|
const match =
|
|
sub.match(/^excalidraw-(.*)$/)?.[1] ??
|
|
sub.match(/(^ea|\Wea)\.([\w\.]*)$/)?.[2] ??
|
|
sub.match(/(^utils|\Wutils)\.([\w\.]*)$/)?.[2];
|
|
if (match !== undefined) {
|
|
this.suggestType = sub.match(/^excalidraw-(.*)$/)
|
|
? "excalidraw"
|
|
: sub.match(/(^ea|\Wea)\.([\w\.]*)$/)
|
|
? "ea"
|
|
: "utils";
|
|
this.latestTriggerInfo = {
|
|
end: cursor,
|
|
start: {
|
|
ch: cursor.ch - match.length,
|
|
line: cursor.line,
|
|
},
|
|
query: match,
|
|
};
|
|
return this.latestTriggerInfo;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getSuggestions = (context: EditorSuggestContext) => {
|
|
const query = context.query.toLowerCase();
|
|
const keys =
|
|
this.suggestType === "ea"
|
|
? EXCALIDRAW_AUTOMATE_INFO
|
|
: this.suggestType === "utils"
|
|
? EXCALIDRAW_SCRIPTENGINE_INFO
|
|
: FRONTMATTER_KEYS_INFO;
|
|
return keys
|
|
.map((sug) => sug.field)
|
|
.filter((sug) => sug.toLowerCase().includes(query));
|
|
};
|
|
|
|
renderSuggestion(suggestion: string, el: HTMLElement): void {
|
|
const text = suggestion.replace(
|
|
this.suggestType === "ea"
|
|
? "ea."
|
|
: this.suggestType === "utils"
|
|
? "utils."
|
|
: "excalidraw-",
|
|
"",
|
|
);
|
|
const keys =
|
|
this.suggestType === "ea"
|
|
? EXCALIDRAW_AUTOMATE_INFO
|
|
: this.suggestType === "utils"
|
|
? EXCALIDRAW_SCRIPTENGINE_INFO
|
|
: FRONTMATTER_KEYS_INFO;
|
|
const value = keys.find((f) => f.field === suggestion);
|
|
el.createEl("b", { text });
|
|
el.createEl("br");
|
|
if (value.code) {
|
|
el.createEl("code", { text: value.code });
|
|
}
|
|
if (value.desc) {
|
|
el.createDiv("div", (el) => (el.innerHTML = value.desc));
|
|
}
|
|
}
|
|
|
|
selectSuggestion(suggestion: string): void {
|
|
const { context } = this;
|
|
if (context) {
|
|
const keys =
|
|
this.suggestType === "ea"
|
|
? EXCALIDRAW_AUTOMATE_INFO
|
|
: this.suggestType === "utils"
|
|
? EXCALIDRAW_SCRIPTENGINE_INFO
|
|
: FRONTMATTER_KEYS_INFO;
|
|
const replacement = `${suggestion}${
|
|
keys.find((f) => f.field === suggestion)?.after
|
|
}`;
|
|
context.editor.replaceRange(
|
|
replacement,
|
|
this.latestTriggerInfo.start,
|
|
this.latestTriggerInfo.end,
|
|
);
|
|
if (this.latestTriggerInfo.start.ch === this.latestTriggerInfo.end.ch) {
|
|
// Dirty hack to prevent the cursor being at the
|
|
// beginning of the word after completion,
|
|
// Not sure what's the cause of this bug.
|
|
const cursor_pos = this.latestTriggerInfo.end;
|
|
cursor_pos.ch += replacement.length;
|
|
context.editor.setCursor(cursor_pos);
|
|
}
|
|
}
|
|
}
|
|
}
|