generated from obsidianmd/obsidian-sample-plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.ts
111 lines (87 loc) · 3.83 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// https://marcus.se.net/obsidian-plugin-docs/reference/typescript
import { Notice, Plugin, parseFrontMatterAliases, parseYaml, stringifyYaml } from 'obsidian';
import type { Editor, MarkdownView, TFile } from 'obsidian';
import type { NoteAliasesSettings } from './src/Settings';
import NoteAliasesSettingTab, { DEFAULT_SETTINGS } from './src/Settings';
import { getLinks, log } from './src/util';
import type { Link } from './src/util';
export default class NoteAliases extends Plugin {
public settings: NoteAliasesSettings = DEFAULT_SETTINGS;
private notice: Notice | null = null;
public async loadSettings (): Promise<void> {
this.settings = { ...DEFAULT_SETTINGS, ...(await this.loadData()) as NoteAliasesSettings };
}
public async onload (): Promise<void> {
this.addSettingTab(new NoteAliasesSettingTab(this.app, this));
await this.loadSettings();
this.addCommands();
}
public async saveSettings (): Promise<void> {
await this.saveData(this.settings);
}
private addCommands (): void {
this.addCommand({
id: 'save-alias',
name: 'Save alias of the link under cursor in the target note frontmatter',
editorCheckCallback: (checking: boolean, editor: Editor, view: MarkdownView) => {
const position = editor.getCursor();
const line = editor.getLine(position.line);
const links = getLinks(line);
const link = links.find(
linkItem => linkItem.start <= position.ch && linkItem.end >= position.ch
);
if (!link) return false;
if (checking) return true;
this.saveAlias(view, link).catch(error => { console.error(error); });
return true;
},
});
}
private async getTargetFile (target: string, fromPath: string): Promise<TFile> {
const existFile = this.app.metadataCache.getFirstLinkpathDest(target, fromPath);
if (existFile) return existFile;
const targetPath = `${this.app.fileManager.getNewFileParent(fromPath).path}/${target}.md`;
const targetFile = await this.app.vault.create(targetPath, '');
return targetFile;
}
private async processFrontMatter (
file: TFile, fn: (frontmatter: object) => void
): Promise<void> {
if (typeof this.app.fileManager.processFrontMatter === 'function') {
await this.app.fileManager.processFrontMatter(file, fn);
return;
}
const frontMatterRe = /^---+\n(?<frontmatter>(?:.|\n)*)---+$/um;
const contentBefore = await this.app.vault.read(file);
const frontmatterStr = frontMatterRe.exec(contentBefore)?.[1];
const frontmatter = (frontmatterStr ? parseYaml(frontmatterStr) : {}) as object;
fn(frontmatter);
const processedFrontMatter = `---\n${stringifyYaml(frontmatter)}---`;
const contentAfter = frontmatterStr ?
contentBefore.replace(frontMatterRe, processedFrontMatter) :
`${processedFrontMatter}\n${contentBefore}`;
await this.app.vault.modify(file, contentAfter);
}
private async saveAlias (view: MarkdownView, link: Link): Promise<void> {
const { alias } = link;
if (!alias) return;
const fromPath = view.file.path;
const targetFile = await this.getTargetFile(link.target, fromPath);
log('saveAlias', { link, sourceFile: fromPath, targetFile });
if (targetFile.extension !== 'md') return;
await this.processFrontMatter(targetFile, (metadata: { aliases?: unknown }) => {
const aliases = parseFrontMatterAliases(metadata) ?? [];
const exists = aliases.some(item => item === alias);
if (exists) {
this.notify(`save-alias: "${alias}" already in aliases list of "${targetFile.basename}"`);
return;
}
metadata.aliases = [...aliases, alias];
this.notify(`save-alias: "${alias}" saved in "${targetFile.basename}"`);
});
}
private notify (message: string): void {
this.notice?.hide();
this.notice = new Notice(message);
}
}