refactor: moved suggester to own file, cleanup

This commit is contained in:
Daniel Bauer
2024-12-10 17:19:15 +01:00
parent 58f85df5cb
commit 61b881b08e
2 changed files with 89 additions and 114 deletions

80
src/DataviewSuggester.ts Normal file
View File

@@ -0,0 +1,80 @@
import { App, Editor, Plugin, EditorPosition, EditorSuggest, EditorSuggestContext, EditorSuggestTriggerInfo, TFile } from 'obsidian';
export class DataviewSuggester extends EditorSuggest<String> {
app: App
constructor(plugin: Plugin) {
super(plugin.app)
}
onTrigger(
cursor: EditorPosition,
editor: Editor,
file: TFile,
): EditorSuggestTriggerInfo | null {
const line = editor.getLine(cursor.line);
const regex = /\((.*?)\)/g // todo min characters for match? -> research on best practices
let match
while((match = regex.exec(line)) !== null) {
// check if cursor is positioned inside the match
const cursorInMatch = cursor.ch > match.index && cursor.ch <= match.index + match[1].length + 1
if (cursorInMatch) {
return {
start: { line: cursor.line, ch: match.index+1 },
end: { line: cursor.line, ch: match.index + match[1].length+1 },
query: match[1],
};
}
}
return null;
}
getSuggestions(context: EditorSuggestContext): string[] | Promise<string[]> {
const suggestions: string[] = []
// TODO use official dv api?
// @ts-ignore
for (const page of this.app.plugins.plugins.dataview.index.pages) {
const fields = page[1].fields
for (let [key, val] of fields) {
let arrayVal
if (!Array.isArray(val)) {
arrayVal = [val]
} else {
arrayVal = val
}
for (const value of arrayVal) {
// TODO whitespace in match
// Fuzzy matching?
const suggestion = key + ":: " + value
if (suggestion.includes(context.query) && !suggestions.includes(suggestion)) {
suggestions.push(key+ ":: " + value)
}
}
}
}
console.log(suggestions)
return suggestions
}
renderSuggestion(value: string, el: HTMLElement): void {
el.setText(value)
}
selectSuggestion(value: string, evt: MouseEvent | KeyboardEvent): void {
console.log("selected", value)
const { editor, start, end } = this.context!;
editor.replaceRange(value, start, end);
const newCursorPos = {
line: end.line + 1,
ch: 0,
};
editor.setCursor(newCursorPos);
}
}

View File

@@ -1,17 +1,16 @@
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, EditorChange, EditorPosition, EditorSuggest, EditorSuggestContext, EditorSuggestTriggerInfo, TFile } from 'obsidian'; import { App, Plugin, PluginSettingTab, Setting } from 'obsidian';
import { DataviewSuggester } from './DataviewSuggester';
// Remember to rename these classes and interfaces! interface DataviewAutocompleteSettings {
// mySetting: string;
interface MyPluginSettings {
mySetting: string;
} }
const DEFAULT_SETTINGS: MyPluginSettings = { const DEFAULT_SETTINGS: DataviewAutocompleteSettings = {
mySetting: 'default' // mySetting: 'default'
} }
export default class MyPlugin extends Plugin { export default class DataviewAutocompletePlugin extends Plugin {
settings: MyPluginSettings; settings: DataviewAutocompleteSettings;
suggester: DataviewSuggester suggester: DataviewSuggester
async onload() { async onload() {
@@ -34,107 +33,3 @@ export default class MyPlugin extends Plugin {
await this.saveData(this.settings); await this.saveData(this.settings);
} }
} }
class SampleSettingTab extends PluginSettingTab {
plugin: MyPlugin;
constructor(app: App, plugin: MyPlugin) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const {containerEl} = this;
containerEl.empty();
new Setting(containerEl)
.setName('Setting #1')
.setDesc('It\'s a secret')
.addText(text => text
.setPlaceholder('Enter your secret')
.setValue(this.plugin.settings.mySetting)
.onChange(async (value) => {
this.plugin.settings.mySetting = value;
await this.plugin.saveSettings();
}));
}
}
class DataviewSuggester extends EditorSuggest<String> {
app: App
constructor(plugin: Plugin) {
super(plugin.app)
}
onTrigger(
cursor: EditorPosition,
editor: Editor,
file: TFile,
): EditorSuggestTriggerInfo | null {
const line = editor.getLine(cursor.line);
const regex = /\((.*?)\)/g // todo min characters for match? -> research on best practices
let match
while((match = regex.exec(line)) !== null) {
// check if cursor is positioned inside the match
const cursorInMatch = cursor.ch > match.index && cursor.ch <= match.index + match[1].length + 1
if (cursorInMatch) {
return {
start: { line: cursor.line, ch: match.index+1 },
end: { line: cursor.line, ch: match.index + match[1].length+1 },
query: match[1],
};
}
}
return null;
}
getSuggestions(context: EditorSuggestContext): string[] | Promise<string[]> {
const suggestions: string[] = []
// TODO use official dv api?
// @ts-ignore
for (const page of this.app.plugins.plugins.dataview.index.pages) {
const fields = page[1].fields
for (let [key, val] of fields) {
let arrayVal
if (!Array.isArray(val)) {
arrayVal = [val]
} else {
arrayVal = val
}
for (const value of arrayVal) {
// TODO whitespace in match
// Fuzzy matching?
const suggestion = key + ":: " + value
if (suggestion.includes(context.query) && !suggestions.includes(suggestion)) {
suggestions.push(key+ ":: " + value)
}
}
}
}
console.log(suggestions)
return suggestions
}
renderSuggestion(value: string, el: HTMLElement): void {
el.setText(value)
}
selectSuggestion(value: string, evt: MouseEvent | KeyboardEvent): void {
console.log("selected", value)
const { editor, start, end } = this.context!;
editor.replaceRange(value, start, end);
const newCursorPos = {
line: end.line + 1,
ch: 0,
};
editor.setCursor(newCursorPos);
}
}