import { MarkdownView, ObsidianProtocolData, Plugin } from "obsidian"; import DatePickerModal from "./modals/date-picker"; import NLDParser, { NLDResult } from "./parser"; import { NLDSettingsTab, NLDSettings, DEFAULT_SETTINGS } from "./settings"; import DateSuggest from "./suggest/date-suggest"; import { getParseCommand, getCurrentDateCommand, getCurrentTimeCommand, getNowCommand, } from "./commands"; import { getFormattedDate, getOrCreateDailyNote, parseTruthy } from "./utils"; export default class NaturalLanguageDates extends Plugin { private parser: NLDParser; public settings: NLDSettings; async onload(): Promise<void> { console.log("Loading natural language date parser plugin"); await this.loadSettings(); this.addCommand({ id: "nlp-dates", name: "Parse natural language date", callback: () => getParseCommand(this, "replace"), hotkeys: [], }); this.addCommand({ id: "nlp-dates-link", name: "Parse natural language date (as link)", callback: () => getParseCommand(this, "link"), hotkeys: [], }); this.addCommand({ id: "nlp-date-clean", name: "Parse natural language date (as plain text)", callback: () => getParseCommand(this, "clean"), hotkeys: [], }); this.addCommand({ id: "nlp-parse-time", name: "Parse natural language time", callback: () => getParseCommand(this, "time"), hotkeys: [], }); this.addCommand({ id: "nlp-now", name: "Insert the current date and time", callback: () => getNowCommand(this), hotkeys: [], }); this.addCommand({ id: "nlp-today", name: "Insert the current date", callback: () => getCurrentDateCommand(this), hotkeys: [], }); this.addCommand({ id: "nlp-time", name: "Insert the current time", callback: () => getCurrentTimeCommand(this), hotkeys: [], }); this.addCommand({ id: "nlp-picker", name: "Date picker", checkCallback: (checking: boolean) => { if (checking) { return !!this.app.workspace.getActiveViewOfType(MarkdownView); } new DatePickerModal(this.app, this).open(); }, hotkeys: [], }); this.addSettingTab(new NLDSettingsTab(this.app, this)); this.registerObsidianProtocolHandler("nldates", this.actionHandler.bind(this)); this.registerEditorSuggest(new DateSuggest(this.app, this)); this.app.workspace.onLayoutReady(() => { // initialize the parser when layout is ready so that the correct locale is used this.parser = new NLDParser(); }); } onunload(): void { console.log("Unloading natural language date parser plugin"); } async loadSettings(): Promise<void> { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings(): Promise<void> { await this.saveData(this.settings); } /* @param dateString: A string that contains a date in natural language, e.g. today, tomorrow, next week @param format: A string that contains the formatting string for a Moment @returns NLDResult: An object containing the date, a cloned Moment and the formatted string. */ parse(dateString: string, format: string): NLDResult { const date = this.parser.getParsedDate(dateString, this.settings.weekStart); const formattedString = getFormattedDate(date, format); if (formattedString === "Invalid date") { console.debug("Input date " + dateString + " can't be parsed by nldates"); } return { formattedString, date, moment: window.moment(date), }; } /* @param dateString: A string that contains a date in natural language, e.g. today, tomorrow, next week @returns NLDResult: An object containing the date, a cloned Moment and the formatted string. */ parseDate(dateString: string): NLDResult { return this.parse(dateString, this.settings.format); } parseTime(dateString: string): NLDResult { return this.parse(dateString, this.settings.timeFormat); } async actionHandler(params: ObsidianProtocolData): Promise<void> { const { workspace } = this.app; const date = this.parseDate(params.day); const newPane = parseTruthy(params.newPane || "yes"); if (date.moment.isValid()) { const dailyNote = await getOrCreateDailyNote(date.moment); let leaf = workspace.activeLeaf; if (newPane) { leaf = workspace.splitActiveLeaf(); } await leaf.openFile(dailyNote); workspace.setActiveLeaf(leaf); } } }