230 lines
5.1 KiB
TypeScript
230 lines
5.1 KiB
TypeScript
import {
|
|
App,
|
|
Plugin,
|
|
PluginSettingTab,
|
|
Setting,
|
|
Vault,
|
|
Notice,
|
|
} from "obsidian";
|
|
import { format } from "./format.js";
|
|
|
|
interface ScrapsPluginSettings {
|
|
scrapsRootDir: string;
|
|
scrapsPathFormat: string;
|
|
scrapsFileName: string;
|
|
}
|
|
|
|
const DEFAULT_SETTINGS: ScrapsPluginSettings = {
|
|
scrapsRootDir: "_Scraps",
|
|
scrapsPathFormat: "{time YYYY} Week {time WW MMM}",
|
|
scrapsFileName: "{time DDDD} {A} {N}",
|
|
};
|
|
|
|
async function mkdirp(vault: Vault, folderPath: string): Promise<void> {
|
|
const pathParts = folderPath.split("/");
|
|
|
|
// Start building the path incrementally
|
|
let currentPath = "";
|
|
|
|
for (const part of pathParts) {
|
|
currentPath = currentPath ? `${currentPath}/${part}` : part;
|
|
|
|
try {
|
|
// Check if folder exists
|
|
if (!vault.getAbstractFileByPath(currentPath)) {
|
|
// Create the folder if it doesn't exist
|
|
await vault.createFolder(currentPath);
|
|
}
|
|
} catch (error) {
|
|
console.error(`Error creating folder ${currentPath}:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
export default class ScrapsPlugin extends Plugin {
|
|
settings: ScrapsPluginSettings;
|
|
|
|
async ensureScrapDir(): Promise<string> {
|
|
const pathname = `${this.getScrapDir()}`;
|
|
|
|
await mkdirp(this.app.vault, pathname);
|
|
|
|
return pathname;
|
|
}
|
|
|
|
getScrapDir(): string {
|
|
return `${this.settings.scrapsRootDir}/${format(
|
|
this.settings.scrapsPathFormat
|
|
)}`;
|
|
}
|
|
|
|
getScrapFileName(): string {
|
|
return format(this.settings.scrapsFileName, { ext: "md" });
|
|
}
|
|
|
|
getScrapFilePath(): string {
|
|
return `${this.getScrapDir()}/${this.getScrapFileName()}`;
|
|
}
|
|
|
|
async createScrap() {
|
|
await this.ensureScrapDir();
|
|
const newScrap = await this.app.vault.create(
|
|
this.getScrapFilePath(),
|
|
""
|
|
);
|
|
|
|
await this.app.workspace.getLeaf(false).openFile(newScrap);
|
|
}
|
|
|
|
async convertToScrap() {
|
|
const currentFile = this.app.workspace.getActiveFile();
|
|
|
|
if (currentFile === null) {
|
|
new Notice("No file is currently open");
|
|
return;
|
|
}
|
|
|
|
await this.ensureScrapDir();
|
|
|
|
await this.app.fileManager.renameFile(
|
|
currentFile,
|
|
this.getScrapFilePath()
|
|
);
|
|
}
|
|
|
|
async onload() {
|
|
await this.loadSettings();
|
|
this.addSettingTab(new ScrapsSettingTab(this.app, this));
|
|
|
|
this.addCommand({
|
|
id: "scraps-new",
|
|
name: "Scraps: Create new Scrap",
|
|
icon: "badge-plus",
|
|
callback: async () => {
|
|
this.createScrap();
|
|
},
|
|
});
|
|
|
|
this.addRibbonIcon("badge-plus", "Create new Scrap", async () => {
|
|
this.createScrap();
|
|
});
|
|
|
|
this.addCommand({
|
|
id: "scraps-convert",
|
|
name: "Scraps: Convert current file to Scrap",
|
|
icon: "file-plus",
|
|
editorCallback: async () => this.convertToScrap(),
|
|
});
|
|
|
|
this.addRibbonIcon("file-plus", "Convert file to Scrap", async () => {
|
|
this.convertToScrap();
|
|
});
|
|
|
|
this.addCommand({
|
|
id: "scraps-copy",
|
|
name: "Scraps: Copy current file to Scraps",
|
|
icon: "copy-plus",
|
|
editorCallback: async () => {
|
|
const currentFile = this.app.workspace.getActiveFile();
|
|
|
|
if (currentFile === null) {
|
|
new Notice("No file is currently open");
|
|
return;
|
|
}
|
|
|
|
await this.ensureScrapDir();
|
|
|
|
const newScrap = await this.app.vault.copy(
|
|
currentFile,
|
|
this.getScrapFilePath()
|
|
);
|
|
|
|
await this.app.workspace.getLeaf(false).openFile(newScrap);
|
|
},
|
|
});
|
|
}
|
|
|
|
onunload() {}
|
|
|
|
async loadSettings() {
|
|
this.settings = Object.assign(
|
|
{},
|
|
DEFAULT_SETTINGS,
|
|
await this.loadData()
|
|
);
|
|
}
|
|
|
|
async saveSettings() {
|
|
await this.saveData(this.settings);
|
|
}
|
|
}
|
|
|
|
class ScrapsSettingTab extends PluginSettingTab {
|
|
plugin: ScrapsPlugin;
|
|
|
|
constructor(app: App, plugin: ScrapsPlugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
display(): void {
|
|
const { containerEl } = this;
|
|
|
|
containerEl.empty();
|
|
|
|
new Setting(containerEl)
|
|
.setName("Scraps Root Directory")
|
|
.setDesc("The directory where all your scraps will be stored")
|
|
.addText((text) =>
|
|
text
|
|
.setPlaceholder("Enter directory")
|
|
.setValue(this.plugin.settings.scrapsRootDir)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.scrapsRootDir = value;
|
|
await this.plugin.saveSettings();
|
|
})
|
|
);
|
|
|
|
const pathFormatSetting = new Setting(containerEl)
|
|
.setName("Scraps Path Format")
|
|
.setDesc(
|
|
`Preview: ${format(this.plugin.settings.scrapsPathFormat)}`
|
|
)
|
|
.addText((text) =>
|
|
text
|
|
.setPlaceholder("Enter format")
|
|
.setValue(this.plugin.settings.scrapsPathFormat)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.scrapsPathFormat = value;
|
|
pathFormatSetting.setDesc(`Preview: ${format(value)}`);
|
|
await this.plugin.saveSettings();
|
|
})
|
|
);
|
|
|
|
const fileFormatSetting = new Setting(containerEl)
|
|
.setName("Scraps File Name Format")
|
|
.setDesc(
|
|
`Preview: ${format(this.plugin.settings.scrapsFileName, {
|
|
ext: "md",
|
|
})}`
|
|
)
|
|
.addText((text) =>
|
|
text
|
|
.setPlaceholder("Enter format")
|
|
.setValue(this.plugin.settings.scrapsFileName)
|
|
.onChange(async (value) => {
|
|
this.plugin.settings.scrapsFileName = value;
|
|
fileFormatSetting.setDesc(
|
|
`Preview: ${format(value, { ext: "md" })}`
|
|
);
|
|
await this.plugin.saveSettings();
|
|
})
|
|
);
|
|
|
|
new Setting(containerEl)
|
|
.setName("Formatting Help")
|
|
.setDesc("Tokens: {time <moment format>}, {A}, {N}, {MW}");
|
|
}
|
|
}
|