Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import * as dotenv from 'dotenv';

const DEFAULT_SETTINGS: Partial<AiTaggerSettings> = {
model: 'gpt-4o-mini',
lowerCaseMode: false
lowerCaseMode: false,
insertionPoint: 'Frontmatter'
}

export default class AiTagger extends Plugin {
Expand Down Expand Up @@ -71,7 +72,37 @@ export default class AiTagger extends Plugin {
}
}

async tagText(currentFile: TFile, text: string) {
private insertTagsIntoFrontmatter(file: TFile, generatedTags: string[]) {
this.app.fileManager.processFrontMatter(file, frontmatter => {
if (!frontmatter["tags"]) {
frontmatter["tags"] = generatedTags;
} else {
frontmatter["tags"].push(...generatedTags);
}
});
}

private formatTagsForBody(tags: string[]): string {
const formatted = tags
.map(t => t?.toString?.() ?? '')
.map(t => t.trim())
.filter(t => t.length > 0)
.map(t => t.startsWith('#') ? t : `#${t}`);
return formatted.join(' ');
}

private insertTagsAtCursor(file: TFile, tags: string[], editor?: Editor): boolean {
if (!editor) {
return false;
}

const insertion = this.formatTagsForBody(tags);
const cursor = editor.getCursor();
editor.replaceRange(insertion, cursor);
return true;
}

async tagText(currentFile: TFile, text: string, editor?: Editor) {
// notify user that we are generating tags
new Notice("Generating tags...");
console.info("Generating tags...");
Expand Down Expand Up @@ -101,14 +132,18 @@ export default class AiTagger extends Plugin {
generatedTags = convertTagsToLowerCase(generatedTags);
}

// update frontmatter with generated tags
this.app.fileManager.processFrontMatter(currentFile, frontmatter => {
if (!frontmatter["tags"]) {
frontmatter["tags"] = generatedTags;
} else {
frontmatter["tags"].push(...generatedTags)
// Insert tags based on user preference
if (this.settings.insertionPoint === 'Cursor') {
const inserted = this.insertTagsAtCursor(currentFile, generatedTags, editor);
if (!inserted) {
// Fallback to frontmatter when no editor is available
this.insertTagsIntoFrontmatter(currentFile, generatedTags);
new Notice('No active editor found. Inserted tags into frontmatter instead.');
}
});
} else {
// Default/frontmatter insertion
this.insertTagsIntoFrontmatter(currentFile, generatedTags);
}
} catch (error) {
console.error('Error in tagText():', error);
new Notice(error.message);
Expand Down Expand Up @@ -154,7 +189,7 @@ export default class AiTagger extends Plugin {
if (markdownView !== null && currentFile !== null) {
// get current document as a string
let fileContents: string = markdownView.editor.getValue();
this.tagText(currentFile, fileContents);
this.tagText(currentFile, fileContents, markdownView.editor);
} else {
const message = "Open and select a document to use the AI Tagger"
new Notice(message);
Expand Down Expand Up @@ -182,9 +217,9 @@ export default class AiTagger extends Plugin {
if (selection === "") {
// if selection is empty, use the entire document
let fileContents: string = editor.getValue();
this.tagText(currentFile, fileContents);
this.tagText(currentFile, fileContents, editor);
} else {
this.tagText(currentFile, selection);
this.tagText(currentFile, selection, editor);
}
}
} catch (error) {
Expand Down
16 changes: 16 additions & 0 deletions src/settings-tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,21 @@ export class AiTaggerSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}),
);

// Insertion Point dropdown
new Setting(containerElement)
.setName('Insertion Point')
.setDesc('Choose where to insert tags: "Cursor" inserts at the cursor\'s current position; "Frontmatter" inserts into the note\'s frontmatter.')
.addDropdown(dropDown => {
dropDown.addOptions({
Frontmatter: 'Frontmatter',
Cursor: 'Cursor',
});
dropDown.setValue(this.plugin.settings.insertionPoint ?? 'Frontmatter');
dropDown.onChange(async (value) => {
this.plugin.settings.insertionPoint = value as 'Frontmatter' | 'Cursor';
await this.plugin.saveSettings();
});
});
}
}
1 change: 1 addition & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ export interface AiTaggerSettings {
useCustomBaseUrl: boolean;
customBaseUrl: string;
lowerCaseMode: boolean;
insertionPoint?: 'Frontmatter' | 'Cursor';
[key: `${string}ApiKey`]: string;
}