Skip to content

Commit

Permalink
feat: ✨ Relation Suggestor with custom trigger (#286)
Browse files Browse the repository at this point in the history
  • Loading branch information
SkepticMystic committed Jan 23, 2022
1 parent 7424c8b commit d7ffaf2
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 32 deletions.
97 changes: 82 additions & 15 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9664,6 +9664,7 @@ const DEFAULT_SETTINGS = {
dotsColour: "#000000",
dvWaitTime: 5000,
enableAlphaSort: true,
enableRelationSuggestor: false,
fieldSuggestor: true,
filterImpliedSiblingsOfDifferentTypes: false,
limitWriteBCCheckboxes: [],
Expand All @@ -9688,6 +9689,7 @@ const DEFAULT_SETTINGS = {
showNameOrType: true,
showRelationType: true,
regexNoteField: "",
relSuggestorTrigger: "\\",
rlLeaf: true,
showAllPathsIfNoneToIndexNote: false,
showAllAliases: true,
Expand Down Expand Up @@ -9834,6 +9836,10 @@ function strToRegex(input) {
console.log(e);
return null;
}
}
// Source: https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
}

/**
Expand Down Expand Up @@ -31438,19 +31444,17 @@ class FieldSuggestor extends obsidian.EditorSuggest {
}
onTrigger(cursor, editor, _) {
var _a;
if (this.plugin.settings.fieldSuggestor) {
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
const match = (_a = sub.match(/^BC-(.*)$/)) === null || _a === void 0 ? void 0 : _a[1];
if (match !== undefined) {
return {
end: cursor,
start: {
ch: sub.lastIndexOf(match),
line: cursor.line,
},
query: match,
};
}
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
const match = (_a = sub.match(/^BC-(.*)$/)) === null || _a === void 0 ? void 0 : _a[1];
if (match !== undefined) {
return {
end: cursor,
start: {
ch: sub.lastIndexOf(match),
line: cursor.line,
},
query: match,
};
}
return null;
}
Expand Down Expand Up @@ -33398,6 +33402,49 @@ async function refreshIndex(plugin) {
new obsidian.Notice("Index refreshed");
}

class RelationSuggestor extends obsidian.EditorSuggest {
constructor(plugin) {
super(plugin.app);
this.getSuggestions = (context) => {
const { query } = context;
const { userHiers } = this.plugin.settings;
return getFields(userHiers).filter((sug) => sug.includes(query));
};
this.plugin = plugin;
}
onTrigger(cursor, editor, _) {
var _a;
const trig = this.plugin.settings.relSuggestorTrigger;
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
const regex = new RegExp(`.*?${escapeRegex(trig)}(.*)$`);
const match = (_a = regex.exec(sub)) === null || _a === void 0 ? void 0 : _a[1];
if (match === undefined)
return null;
return {
start: {
ch: sub.lastIndexOf(trig),
line: cursor.line,
},
end: cursor,
query: match,
};
}
renderSuggestion(suggestion, el) {
el.createDiv({
text: suggestion,
cls: "codeblock-suggestion",
});
}
selectSuggestion(suggestion) {
const { context } = this;
if (context) {
const trig = this.plugin.settings.relSuggestorTrigger;
const { start, end, editor } = context;
editor.replaceRange(suggestion + ":", { ch: start.ch + 1 - trig.length, line: start.line }, end);
}
}
}

/* src\Components\KoFi.svelte generated by Svelte v3.35.0 */

function create_fragment$h(ctx) {
Expand Down Expand Up @@ -37488,6 +37535,22 @@ class BCSettingTab extends obsidian.PluginSettingTab {
settings.fieldSuggestor = value;
await plugin.saveSettings();
}));
new obsidian.Setting(alternativeHierarchyDetails)
.setName("Enable Relation Suggestor")
.setDesc(fragWithHTML("Enable an editor suggestor which gets triggered by a custom string to show a list of relations from your hierarchies to insert."))
.addToggle((toggle) => toggle
.setValue(settings.enableRelationSuggestor)
.onChange(async (value) => {
settings.enableRelationSuggestor = value;
await plugin.saveSettings();
}));
new obsidian.Setting(alternativeHierarchyDetails)
.setName("Relation Suggestor Trigger")
.setDesc(fragWithHTML("The string used to trigger the relation suggestor. Default is <code>\\</code>."))
.addText((text) => text.setValue(settings.relSuggestorTrigger).onChange(async (value) => {
settings.relSuggestorTrigger = value;
await plugin.saveSettings();
}));
addTagNoteSettings(plugin, alternativeHierarchyDetails);
addRegexNoteSettings(plugin, alternativeHierarchyDetails);
addNoSystemSettings(plugin, alternativeHierarchyDetails);
Expand Down Expand Up @@ -61784,10 +61847,14 @@ class BCPlugin extends obsidian.Plugin {
console.log("loading breadcrumbs plugin");
const { app } = this;
await this.loadSettings();
const { settings } = this;
this.addSettingTab(new BCSettingTab(app, this));
this.db = new Debugger(this);
this.registerEditorSuggest(new FieldSuggestor(this));
const { settings } = this;
const { fieldSuggestor, enableRelationSuggestor } = settings;
if (fieldSuggestor)
this.registerEditorSuggest(new FieldSuggestor(this));
if (enableRelationSuggestor)
this.registerEditorSuggest(new RelationSuggestor(this));
const { openMatrixOnLoad, openStatsOnLoad, openDuckOnLoad, openDownOnLoad, showBCs, showBCsInEditLPMode, userHiers, } = settings;
this.VIEWS = [
{
Expand Down
25 changes: 12 additions & 13 deletions src/FieldSuggestor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,19 @@ export class FieldSuggestor extends EditorSuggest<string> {
editor: Editor,
_: TFile
): EditorSuggestTriggerInfo | null {
if (this.plugin.settings.fieldSuggestor) {
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
const match = sub.match(/^BC-(.*)$/)?.[1];
if (match !== undefined) {
return {
end: cursor,
start: {
ch: sub.lastIndexOf(match),
line: cursor.line,
},
query: match,
};
}
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
const match = sub.match(/^BC-(.*)$/)?.[1];
if (match !== undefined) {
return {
end: cursor,
start: {
ch: sub.lastIndexOf(match),
line: cursor.line,
},
query: match,
};
}

return null;
}

Expand Down
68 changes: 68 additions & 0 deletions src/RelationSuggestor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
Editor,
EditorPosition,
EditorSuggest,
EditorSuggestContext,
EditorSuggestTriggerInfo,
TFile,
} from "obsidian";
import type BCPlugin from "./main";
import { escapeRegex } from "./Utils/generalUtils";
import { getFields } from "./Utils/HierUtils";

export class RelationSuggestor extends EditorSuggest<string> {
plugin: BCPlugin;

constructor(plugin: BCPlugin) {
super(plugin.app);
this.plugin = plugin;
}

onTrigger(
cursor: EditorPosition,
editor: Editor,
_: TFile
): EditorSuggestTriggerInfo | null {
const trig = this.plugin.settings.relSuggestorTrigger;
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);

const regex = new RegExp(`.*?${escapeRegex(trig)}(.*)$`);
const match = regex.exec(sub)?.[1];

if (match === undefined) return null;
return {
start: {
ch: sub.lastIndexOf(trig),
line: cursor.line,
},
end: cursor,
query: match,
};
}

getSuggestions = (context: EditorSuggestContext) => {
const { query } = context;
const { userHiers } = this.plugin.settings;
return getFields(userHiers).filter((sug) => sug.includes(query));
};

renderSuggestion(suggestion: string, el: HTMLElement): void {
el.createDiv({
text: suggestion,
cls: "codeblock-suggestion",
});
}

selectSuggestion(suggestion: string): void {
const { context } = this;
if (context) {
const trig = this.plugin.settings.relSuggestorTrigger;
const { start, end, editor } = context;
editor.replaceRange(
suggestion + ":",
{ ch: start.ch + 1 - trig.length, line: start.line },
end
);
}
}
}
28 changes: 28 additions & 0 deletions src/Settings/BreadcrumbsSettingTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,34 @@ export class BCSettingTab extends PluginSettingTab {
await plugin.saveSettings();
})
);
new Setting(alternativeHierarchyDetails)
.setName("Enable Relation Suggestor")
.setDesc(
fragWithHTML(
"Enable an editor suggestor which gets triggered by a custom string to show a list of relations from your hierarchies to insert."
)
)
.addToggle((toggle) =>
toggle
.setValue(settings.enableRelationSuggestor)
.onChange(async (value) => {
settings.enableRelationSuggestor = value;
await plugin.saveSettings();
})
);
new Setting(alternativeHierarchyDetails)
.setName("Relation Suggestor Trigger")
.setDesc(
fragWithHTML(
"The string used to trigger the relation suggestor. Default is <code>\\</code>."
)
)
.addText((text) =>
text.setValue(settings.relSuggestorTrigger).onChange(async (value) => {
settings.relSuggestorTrigger = value;
await plugin.saveSettings();
})
);

addTagNoteSettings(plugin, alternativeHierarchyDetails);
addRegexNoteSettings(plugin, alternativeHierarchyDetails);
Expand Down
7 changes: 5 additions & 2 deletions src/Utils/generalUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { App } from "obsidian";
import { isInVault } from "obsidian-community-lib";
import { dropHeaderOrAlias, regNFlags, splitLinksRegex } from "../constants";
import type { BCSettings } from "../interfaces";

Expand Down Expand Up @@ -176,3 +174,8 @@ export function strToRegex(input: string) {
return null;
}
}

// Source: https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
export function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
}
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ export const DEFAULT_SETTINGS: BCSettings = {
dotsColour: "#000000",
dvWaitTime: 5000,
enableAlphaSort: true,
enableRelationSuggestor: false,
fieldSuggestor: true,
filterImpliedSiblingsOfDifferentTypes: false,
limitWriteBCCheckboxes: [],
Expand All @@ -278,6 +279,7 @@ export const DEFAULT_SETTINGS: BCSettings = {
showNameOrType: true,
showRelationType: true,
regexNoteField: "",
relSuggestorTrigger: "\\",
rlLeaf: true,
showAllPathsIfNoneToIndexNote: false,
showAllAliases: true,
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface BCSettings {
downViewWrap: boolean;
dotsColour: string;
enableAlphaSort: boolean;
enableRelationSuggestor: boolean;
fieldSuggestor: boolean;
filterImpliedSiblingsOfDifferentTypes: boolean;
gridDots: boolean;
Expand Down Expand Up @@ -76,6 +77,7 @@ export interface BCSettings {
showWriteAllBCsCmd: boolean;
sortByNameShowAlias: boolean;
regexNoteField: string;
relSuggestorTrigger: string;
rlLeaf: boolean;
showBCs: boolean;
showBCsInEditLPMode: boolean;
Expand Down
10 changes: 8 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import { FieldSuggestor } from "./FieldSuggestor";
import type { BCSettings, Directions, MyView, ViewInfo } from "./interfaces";
import { buildClosedG, buildMainG, refreshIndex } from "./refreshIndex";
import { RelationSuggestor } from "./RelationSuggestor";
import { BCSettingTab } from "./Settings/BreadcrumbsSettingTab";
import { getFields } from "./Utils/HierUtils";
import { waitForCache } from "./Utils/ObsidianUtils";
Expand Down Expand Up @@ -73,11 +74,16 @@ export default class BCPlugin extends Plugin {
const { app } = this;

await this.loadSettings();
const { settings } = this;
this.addSettingTab(new BCSettingTab(app, this));

this.db = new Debugger(this);
this.registerEditorSuggest(new FieldSuggestor(this));

const { settings } = this;
const { fieldSuggestor, enableRelationSuggestor } = settings;

if (fieldSuggestor) this.registerEditorSuggest(new FieldSuggestor(this));
if (enableRelationSuggestor)
this.registerEditorSuggest(new RelationSuggestor(this));

const {
openMatrixOnLoad,
Expand Down

0 comments on commit d7ffaf2

Please sign in to comment.