diff --git a/docs/assets/tempalte-settings.png b/docs/assets/tempalte-settings.png deleted file mode 100644 index 36e9e6e..0000000 Binary files a/docs/assets/tempalte-settings.png and /dev/null differ diff --git a/docs/assets/template-settings.png b/docs/assets/template-settings.png new file mode 100644 index 0000000..bb90307 Binary files /dev/null and b/docs/assets/template-settings.png differ diff --git a/docs/assets/templater-setting.png b/docs/assets/templater-setting.png new file mode 100644 index 0000000..a92d37f Binary files /dev/null and b/docs/assets/templater-setting.png differ diff --git a/docs/changelog.md b/docs/changelog.md index e98c85e..dcb5bb8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,8 +1,13 @@ # Changelog +## [2.3.3](https://github.com/StrangeGirlMurph/obsidian-wikipedia-search/releases/tag/2.3.3) (02.12.2023) +- Adds the template file option. +- Adds the `Override files` setting +- Fixes some bugs. + ## [2.3.2](https://github.com/StrangeGirlMurph/obsidian-wikipedia-search/releases/tag/2.3.2) (27.11.2023) -- Adds the `Create article note` command -- Adds the `Open created article notes` setting +- Adds the `Create article note` command. +- Adds the `Open created article notes` setting. ## [2.3.1](https://github.com/StrangeGirlMurph/obsidian-wikipedia-search/releases/tag/2.3.1) (18.11.2023) - Introduces the new documentation and links it from the settings page. diff --git a/docs/help.md b/docs/help.md new file mode 100644 index 0000000..8653eca --- /dev/null +++ b/docs/help.md @@ -0,0 +1 @@ +If you tried finding an answer to your question in this documentation but still need help with something feel free to ask the community and me for help in the [Q&A in the GitHub Discussions Tab](https://github.com/StrangeGirlMurph/obsidian-wikipedia-search/discussions/categories/q-a). \ No newline at end of file diff --git a/docs/settings.md b/docs/settings.md index 85d697c..0aaea41 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -28,30 +28,30 @@ The default vault folder where articles notes should be created. This only gets Default: `/` (the root folder) ## Template settings -Each user has a list of templates for the inserts that this plugin creates when linking articles. "Linking" in this context might be a bit misdirecting though given the fact that this plugin can do more than just link the article with a url. The templates can be separated into one default template and multiple additional templates. Templates can be deleted with the `-` button at the end. The default template can't be deleted. +Each user has a list of templates for the inserts that this plugin creates when [linking articles](commands.md#link-article) or [creating article notes](commands.md#create-article-note). The templates can be separated into one default template and multiple additional templates. Templates can be deleted with the `-` button at the end. The default template can't be deleted. You can create new templates with the `+` button at the bottom right. The settings for a template can be separated into the following three parts: -*Note: You can only have up to 20 templates. It's a limitation that isn't really justified. I just thought adding this would be a good idea for your own good. If you need more than 20 leave a message.* - ??? info "Screenshot" - ![template settings screenshot](assets/tempalte-settings.png) + ![template settings screenshot](assets/template-settings.png) ### Template name -The first field of each template sets the name of the template.The name of the default template can't be changed (that's why that field is disabled) while the additional templates can have any name. +The first field of each template sets the name of the template. The name of the default template can't be changed (that's why that field is disabled) while the additional templates can have any name. Default: `Additional Template` ### Creates note & Custom note path -The middle part of a templates settings is all about note creation. It consist of a toggle and a text field that appears when the toggle in the "on" state. The toggle controls whether or not the template should create a new note with the articles title as its name, paste the insert in there and link the newly created note instead of directly pasting the insert into the current note. This allows for creating notes for wikipedia articles. We call templates that create new notes "note templates" and templates that doesn't "inline templates". +The middle part of a templates settings is all about note creation. It consist of a toggle and a text field that appears when the "creates a note" toggle is in the "on" state. The toggle controls whether or not the template should create a new note with the articles title as its name, paste the insert in there and link the newly created note instead of directly pasting the insert into the current note. This allows for creating notes for wikipedia articles. We call templates that create new notes "note templates" and templates that doesn't "inline templates". By default all the notes will be created at the [default note path](#default-note-path). The appearing text field lets you customize the location for any given template. Leave it empty to use the default note path. -Default: `false` for the toggle (inline) and `‎` (empty) for the custom note path +Default: `false` as in "inline" for the toggle and `‎` (empty) for the custom note path ### Template string -The last and most important part of any template is its template string. You can edit it over the big text field at the end. The template string is the blueprint for the insert. It can be any kind of string containing line breaks. The plugin recognizes the following character sequences and replaces all occurrences with the following: +The last and most important part of any template is its template string. The template string is the blueprint for the insert. This last section consists of a toggle and an input field which is either a big text or a file search field. The toggle sets whether or not the template string is declared directly in the settings tab in the big text field or separately in a file which the file search field references instead. Template files are only supported for note templates. That's why the toggle disappears and the input automatically switches to the text field once you switch to an inline template. + +The template string can be any kind of string containing line breaks and whatever you can think of. The plugin recognizes the following character sequences and replaces all occurrences with the corresponding data: - `{title}` The articles title or current selection (based on [this setting](#use-article-title-instead-of-selection)). - `{description}` The articles description if available. If not all occurrences will be removed with a notice. @@ -63,6 +63,12 @@ The last and most important part of any template is its template string. You can Default: `[{title}]({url})` for inline templates and `{thumbnail}\n[{title}]({url}): {intro}` for note templates +??? tip + + You can also use [Templater](https://github.com/SilentVoid13/Templater) Syntax in the template string of note templates to make the article notes even better! Just [install](obsidian://show-plugin?id=templater) and enable the Templater Plugin and enable its "Trigger Templater on new file creation" setting: + + ![Templater Setting](assets/templater-setting.png) + ## Workflow optimization settings ??? info "Screenshot" @@ -118,4 +124,9 @@ Default: `false` ### Open created article notes Whether or not to open the newly created article notes directly after creating them. Follows the [article tab placement setting](#article-tab-placement). +Default: `false` + +### Override files +Whether or not to override existing files when creating article notes. + Default: `false` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 3a9f499..f737865 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -65,6 +65,7 @@ nav: - "installation.md" - "settings.md" - "commands.md" + - "help.md" - "roadmap.md" - "changelog.md" - "support.md" diff --git a/src/commands/createArticleNotes.ts b/src/commands/createArticleNotes.ts index f34adcf..40a71a5 100644 --- a/src/commands/createArticleNotes.ts +++ b/src/commands/createArticleNotes.ts @@ -1,4 +1,4 @@ -import { App, TFile } from "obsidian"; +import { App, Notice, TFile } from "obsidian"; import { Template, WikipediaSearchSettings } from "../settings"; import { Article } from "src/utils/searchModal"; import { SearchModal } from "src/utils/searchModal"; @@ -10,7 +10,7 @@ export class CreateArticleNoteModal extends SearchModal { async onChooseSuggestion(article: Article) { const templates = this.settings.templates.filter((template) => template.createNote); if (templates.length > 1) { - new CreateArticleNoteTemplateModal(this.app, this.settings, this.editor!, article).open(); + new CreateArticleNoteTemplateModal(this.app, this.settings, this.editor!, article, true).open(); } else { createArticleNote(this.app, this.settings, article, templates[0]); } @@ -18,19 +18,6 @@ export class CreateArticleNoteModal extends SearchModal { } class CreateArticleNoteTemplateModal extends TemplateModal { - renderSuggestion(template: Template, el: HTMLElement) { - el.createEl("div", { text: `${template.name}` }); - el.createEl("small", { - text: template.templateString.replaceAll("\n", "\\n"), - }); - } - - async getSuggestions(query: string): Promise { - return this.settings.templates - .filter((template) => template.createNote) - .filter((template) => template.name.toLowerCase().includes(query.toLowerCase())); - } - async onChooseSuggestion(template: Template) { createArticleNote(this.app, this.settings, this.article, template); } @@ -42,12 +29,22 @@ async function createArticleNote( article: Article, template: Template ) { - const insert = await generateInsert(settings, article, template.templateString, ""); + let templateString = template.templateString; + if (template.useTemplateFile) { + const templateFile = app.vault.getAbstractFileByPath(template.templateFilePath); + if (!templateFile || !(templateFile instanceof TFile)) { + new Notice(`Aborting! Template file '${template.templateFilePath}' not found!`); + return; + } + templateString = await app.vault.read(templateFile); + } + const insert = await generateInsert(settings, article, templateString, ""); const path = await createNoteInFolder( app, article.title, insert, - template.customPath || settings.defaultNotePath + template.customPath || settings.defaultNotePath, + settings.overrideFiles ); if (!path) return; if (settings.openCreatedNotes) { diff --git a/src/commands/linkArticles.ts b/src/commands/linkArticles.ts index eeae854..a5cd89a 100644 --- a/src/commands/linkArticles.ts +++ b/src/commands/linkArticles.ts @@ -17,19 +17,6 @@ export class LinkArticleModal extends SearchModal { } class LinkArticleTemplateModal extends TemplateModal { - renderSuggestion(template: Template, el: HTMLElement) { - el.createEl("div", { text: `${template.name} ${template.createNote ? "(note)" : "(inplace)"}` }); - el.createEl("small", { - text: template.templateString.replaceAll("\n", "\\n"), - }); - } - - async getSuggestions(query: string): Promise { - return this.settings.templates.filter((template) => - template.name.toLowerCase().includes(query.toLowerCase()) - ); - } - async onChooseSuggestion(template: Template) { insertLink(app, this.editor, this.settings, this.article, template); } @@ -49,7 +36,8 @@ async function insertLink( app, article.title, insert, - template.customPath === "" ? settings.defaultNotePath : template.customPath + template.customPath === "" ? settings.defaultNotePath : template.customPath, + settings.overrideFiles ); if (path == null) return; diff --git a/src/main.ts b/src/main.ts index 44a364b..d69255c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -37,7 +37,7 @@ export default class WikipediaSearchPlugin extends Plugin { name: "Create Article Note", callback: () => { if (this.settings.templates.filter((template) => template.createNote).length === 0) { - new Notice("You have to create a note template first! (see the docs)"); + new Notice("To use this command you have to create a note template first!"); return; } new CreateArticleNoteModal(this.app, this.settings).open(); diff --git a/src/settings.ts b/src/settings.ts index f18e5d5..8366e0d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,13 +1,16 @@ -import { App, Modal, Notice, PluginSettingTab, SearchComponent, Setting } from "obsidian"; +import { App, Notice, PluginSettingTab, SearchComponent, Setting } from "obsidian"; import { languages } from "./utils/languages"; import WikipediaSearchPlugin from "./main"; import { FolderSuggest } from "./utils/suggesters/folderSuggest"; +import { FileSuggest } from "./utils/suggesters/fileSuggest"; export interface Template { name: string; templateString: string; createNote: boolean; - customPath: string; // use the default if empty + customPath: string; // use the default if empty string + useTemplateFile: boolean; + templateFilePath: string; } const DEFAULT_TEMPLATE_STRING_INLINE = "[{title}]({url})"; @@ -18,6 +21,8 @@ export const DEFAULT_TEMPLATE: Template = { templateString: DEFAULT_TEMPLATE_STRING_INLINE, createNote: false, customPath: "", + useTemplateFile: false, + templateFilePath: "", }; export interface WikipediaSearchSettings { @@ -33,6 +38,7 @@ export interface WikipediaSearchSettings { openArticleInFullscreen: boolean; openArticlesInBrowser: boolean; openCreatedNotes: boolean; + overrideFiles: boolean; showedSurfingMessage: boolean; } @@ -49,6 +55,7 @@ export const DEFAULT_SETTINGS: WikipediaSearchSettings = { openArticleInFullscreen: false, openArticlesInBrowser: false, openCreatedNotes: false, + overrideFiles: false, showedSurfingMessage: false, }; @@ -62,24 +69,6 @@ export class WikipediaSearchSettingTab extends PluginSettingTab { this.settings = plugin.settings; } - addNotePathSearch(item: Template, setting: Setting): Setting { - if (!item.createNote) return setting; - - setting.addSearch((search: SearchComponent) => { - new FolderSuggest(app, search.inputEl); - search - .setPlaceholder("custom note path") - .setValue(item.customPath) - .onChange(async (newFolder: string) => { - item.customPath = newFolder; - await this.plugin.saveSettings(); - }); - }); - - setting.controlEl.children[2].setAttr("style", "flex-grow:1;width:170px;"); - return setting; - } - display(): void { const { containerEl } = this; @@ -116,7 +105,7 @@ export class WikipediaSearchSettingTab extends PluginSettingTab { .setDesc("Maximum number of search results to show. (Between 1 and 500)") .addText((text) => text - .setPlaceholder("Limit") + .setPlaceholder("limit") .setValue(this.settings.searchLimit ? this.settings.searchLimit.toString() : "") .onChange(async (value) => { const parsed = parseInt(value); @@ -131,7 +120,7 @@ export class WikipediaSearchSettingTab extends PluginSettingTab { .setDesc("The width of the thumbnails in pixels. (Leave empty to use the original size.)") .addText((text) => text - .setPlaceholder("Width") + .setPlaceholder("width") .setValue(this.settings.thumbnailWidth ? this.settings.thumbnailWidth.toString() : "") .onChange(async (value) => { const parsed = parseInt(value); @@ -160,120 +149,12 @@ export class WikipediaSearchSettingTab extends PluginSettingTab { }); }); - new Setting(containerEl) - .setName("Template guide") - .setDesc("Get an explanation on how to configure templates.") - .addButton((button) => - button.setButtonText("Guide").onClick(async () => { - const modal = new Modal(app); - modal.titleEl.setText("Template guide"); - modal.contentEl.innerHTML = - "1. Start by giving your template a name in the text field at the left.

2. Next you can use the toggle to make the template create a new note with it's content being the inserted template when linking an article instead of inserting directly in the current file.

3. If that toggle is on, a search field appears which allows you to set a custom path for the new note. You can leave it empty if that template should just use the default note path.

4. Lastly you can set the actual template for the insert. All occurrences of '{title}', '{url}', '{language}', '{languageCode}', '{description}', '{intro}' and '{thumbnail}' will be replaced with the articles title (or the selection), url, language, language code, description (if available), intro (the articles first section) and thumbnail embed (if available) respectively.

Note: You can't rename nor delete the default template."; - modal.open(); - }) - ); - - new Setting(containerEl).setName("Templates").setHeading(); - - for (const [i, template] of this.settings.templates.entries()) { - const isDefaultTemplate = i == 0; - - let setting = new Setting(containerEl); - setting.settingEl.removeChild(setting.infoEl); - setting.controlEl.style.flexWrap = "wrap"; - setting.controlEl.style.justifyContent = "center"; + const templateSettings = new DocumentFragment(); + templateSettings.createEl("span").innerHTML = + "Templates (Guide)"; + new Setting(containerEl).setName(templateSettings).setHeading(); - setting.addText((text) => { - if (isDefaultTemplate) text.setDisabled(true); - return text - .setValue(isDefaultTemplate ? "Default Tempalte" : template.name) - .setPlaceholder("Name") - .onChange(async (value) => { - template.name = value; - await this.plugin.saveSettings(); - }); - }); - setting.controlEl.children[0].setAttr("style", "width: 160px;"); - - setting.addToggle((toggle) => - toggle - .setTooltip("creates note") - .setValue(template.createNote) - .onChange(async (value) => { - template.createNote = value; - if ( - template.createNote && - (template.templateString == DEFAULT_TEMPLATE_STRING_INLINE || template.templateString === "") - ) { - template.templateString = DEFAULT_TEMPLATE_STRING_NOTE; - } else if ( - !template.createNote && - (template.templateString == DEFAULT_TEMPLATE_STRING_NOTE || template.templateString === "") - ) { - template.templateString = DEFAULT_TEMPLATE_STRING_INLINE; - } - await this.plugin.saveSettings(); - this.display(); - }) - ); - - setting = this.addNotePathSearch(template, setting); - - setting.addTextArea((text) => { - text.inputEl.setAttr( - "style", - "white-space:pre;overflow-wrap:normal;overflow:hidden;resize:none;flex-grow:1;" - ); - text.inputEl.setAttr("rows", "2"); - - return text - .setPlaceholder("Template") - .setValue(template.templateString) - .onChange(async (value) => { - template.templateString = value; - await this.plugin.saveSettings(); - }); - }); - - setting.addExtraButton((button) => { - if (isDefaultTemplate) button.setDisabled(true); - button.extraSettingsEl.style.height = "min-content"; - return button - .setTooltip("delete template") - .setIcon("minus") - .onClick(async () => { - this.settings.templates.splice(i, 1); - await this.plugin.saveSettings(); - this.display(); - }); - }); - - const div = setting.controlEl.createDiv(); - div.setAttr("style", "display:flex;flex-grow:1;gap:var(--size-4-2);align-items:center;"); - - div.appendChild(setting.controlEl.children[setting.controlEl.children.length - 3]); - div.appendChild(setting.controlEl.children[setting.controlEl.children.length - 2]); - } - - new Setting(containerEl).addExtraButton((button) => - button - .setTooltip("create new template") - .setIcon("plus") - .onClick(async () => { - if (this.settings.templates.length == 21) - return new Notice( - "Easy buddy... I need to stop you right there. You can only have up to 20 templates. It's for your own good! (I think) If you really need more come and talk to me on GitHub. If you convince me I'll let you have more.", - 15000 - ); - - this.settings.templates.push({ - ...DEFAULT_TEMPLATE, - name: `Additional Template`, - }); - await this.plugin.saveSettings(); - this.display(); - }) - ); + this.addTemplateSettings(containerEl); new Setting(containerEl).setName("Workflow optimizations").setHeading(); @@ -355,10 +236,175 @@ export class WikipediaSearchSettingTab extends PluginSettingTab { }) ); + new Setting(containerEl) + .setName("Override files") + .setDesc("Whether or not to override existing files when creating article notes.") + .addToggle((toggle) => + toggle.setValue(this.settings.overrideFiles).onChange(async (value) => { + this.settings.overrideFiles = value; + await this.plugin.saveSettings(); + }) + ); + new Setting(containerEl).setName("Feedback, bug reports and feature requests 🌿").setHeading(); const appendix = `

If you have any kind of feedback, please let me know! No matter how small! I also obsess a lot about small details. I want to make this plugin as useful as possible for everyone. I love to hear about your ideas for new features, all the bugs you found and everything that annoys you. Don't be shy! Just create an issue on GitHub and I'll get back to you ASAP. ~ Murphy :)

PS: Wikipedia also has a dark mode for everyone with an account.

`; const div = containerEl.createEl("div"); div.innerHTML = appendix; } + + addTemplateSettings(containerEl: HTMLElement) { + for (const [i, template] of this.settings.templates.entries()) { + const isDefaultTemplate = i == 0; + + let setting = new Setting(containerEl); + setting.settingEl.removeChild(setting.infoEl); + setting.controlEl.style.flexWrap = "wrap"; + setting.controlEl.style.justifyContent = "center"; + + setting.addText((text) => { + if (isDefaultTemplate) text.setDisabled(true); + return text + .setValue(isDefaultTemplate ? "Default Template" : template.name) + .setPlaceholder("Name") + .onChange(async (value) => { + template.name = value; + await this.plugin.saveSettings(); + }); + }); + setting.controlEl.children[setting.controlEl.children.length - 1].setAttr("style", "width: 140px;"); + + setting.addToggle((toggle) => + toggle + .setTooltip("creates a note") + .setValue(template.createNote) + .onChange(async (value) => { + template.createNote = value; + if ( + template.createNote && + (template.templateString == DEFAULT_TEMPLATE_STRING_INLINE || template.templateString === "") + ) { + template.templateString = DEFAULT_TEMPLATE_STRING_NOTE; + } else if ( + !template.createNote && + (template.templateString == DEFAULT_TEMPLATE_STRING_NOTE || template.templateString === "") + ) { + template.templateString = DEFAULT_TEMPLATE_STRING_INLINE; + } + await this.plugin.saveSettings(); + this.display(); + }) + ); + + const firstGroup = setting.controlEl.createDiv(); + firstGroup.setAttr("style", "display:flex;gap:var(--size-4-2);align-items:center;"); + firstGroup.appendChild(setting.controlEl.children[0]); + firstGroup.appendChild(setting.controlEl.children[0]); + + if (template.createNote) { + setting.addSearch((search: SearchComponent) => { + new FolderSuggest(app, search.inputEl); + search + .setPlaceholder("custom note path") + .setValue(template.customPath) + .onChange(async (newFolder: string) => { + template.customPath = newFolder; + await this.plugin.saveSettings(); + }); + }); + + setting.controlEl.children[setting.controlEl.children.length - 1].setAttr( + "style", + "flex-grow:1;width:170px;" + ); + + setting.addToggle((toggle) => + toggle + .setTooltip("uses a template file") + .setValue(template.useTemplateFile) + .onChange(async (value) => { + template.useTemplateFile = value; + await this.plugin.saveSettings(); + this.display(); + }) + ); + + const secondGroup = setting.controlEl.createDiv(); + secondGroup.setAttr("style", "display:flex;flex-grow:1;gap:var(--size-4-2);align-items:center;"); + secondGroup.appendChild(setting.controlEl.children[1]); + secondGroup.appendChild(setting.controlEl.children[1]); + } + + if (template.useTemplateFile && template.createNote) { + setting.addSearch((search: SearchComponent) => { + new FileSuggest(app, search.inputEl); + search + .setPlaceholder("template file path") + .setValue(template.templateFilePath) + .onChange(async (newFolder: string) => { + template.templateFilePath = newFolder; + await this.plugin.saveSettings(); + }); + }); + setting.controlEl.children[setting.controlEl.children.length - 1].setAttr( + "style", + "flex-grow:1;width:170px;" + ); + } else { + setting.addTextArea((text) => { + text.inputEl.setAttr( + "style", + "white-space:pre;overflow-wrap:normal;overflow:hidden;resize:none;flex-grow:1;width:220px;" + ); + text.inputEl.setAttr("rows", "2"); + + return text + .setPlaceholder("template string") + .setValue(template.templateString) + .onChange(async (value) => { + template.templateString = value; + await this.plugin.saveSettings(); + }); + }); + } + + setting.addExtraButton((button) => { + if (isDefaultTemplate) button.setDisabled(true); + button.extraSettingsEl.style.height = "min-content"; + return button + .setTooltip("delete template") + .setIcon("minus") + .onClick(async () => { + this.settings.templates.splice(i, 1); + await this.plugin.saveSettings(); + this.display(); + }); + }); + + const thirdGroup = setting.controlEl.createDiv(); + thirdGroup.setAttr("style", "display:flex;flex-grow:1;gap:var(--size-4-2);align-items:center;"); + thirdGroup.appendChild(setting.controlEl.children[setting.controlEl.children.length - 3]); + thirdGroup.appendChild(setting.controlEl.children[setting.controlEl.children.length - 2]); + } + + new Setting(containerEl).addExtraButton((button) => + button + .setTooltip("add template") + .setIcon("plus") + .onClick(async () => { + if (this.settings.templates.length == 21) + return new Notice( + "Easy buddy... I need to stop you right there. You can only have up to 20 templates. It's for your own good! (I think) If you really need more come and talk to me on GitHub. If you convince me I'll let you have more.", + 15000 + ); + + this.settings.templates.push({ + ...DEFAULT_TEMPLATE, + name: `Additional Template`, + }); + await this.plugin.saveSettings(); + this.display(); + }) + ); + } } diff --git a/src/utils/createNote.ts b/src/utils/createNote.ts index 9a2ab0f..e8e1472 100644 --- a/src/utils/createNote.ts +++ b/src/utils/createNote.ts @@ -1,33 +1,36 @@ -import { App, normalizePath, Notice } from "obsidian"; +import { App, normalizePath, Notice, TFile } from "obsidian"; export async function createNoteInFolder( app: App, title: string, content: string, - path: string + folderPath: string, + overrideExisting: boolean ): Promise { - if (!(await app.vault.adapter.exists(path))) { + if ( + !(await app.vault.adapter.exists(folderPath)) || + app.vault.getAbstractFileByPath(folderPath) instanceof TFile + ) { new Notice( "Aborted! The folder you specified in the settings to create this new note in does not exist. Please visit the plugin settings and change the path!", 15000 ); return null; } - path = normalizePath(`${path}/${title}.md`); - const file = app.vault.getAbstractFileByPath(path); - if (file) { - new Notice(`Aborted! '${path}' already exists.`); - return null; - } + const filePath = normalizePath(`${folderPath}/${title}.md`); + const file = app.vault.getAbstractFileByPath(filePath); - try { - await app.vault.create(path, content); - new Notice("New note created successfully."); - return path; - } catch (err) { - new Notice("Error creating new note... Please check the console logs for more information."); - console.error("Error creating new note:", err); + if (file && !overrideExisting) { + new Notice(`Aborted! '${filePath}' already exists.`); return null; + } else if (file && overrideExisting) { + await app.vault.modify(file as TFile, content); + new Notice(`Note successfully overwritten.`); + return filePath; + } else { + await app.vault.create(filePath, content); + new Notice("New note created successfully."); + return filePath; } } diff --git a/src/utils/suggesters/fileSuggest.ts b/src/utils/suggesters/fileSuggest.ts new file mode 100644 index 0000000..0776fa2 --- /dev/null +++ b/src/utils/suggesters/fileSuggest.ts @@ -0,0 +1,30 @@ +// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes + +import { TAbstractFile, TFile } from "obsidian"; +import { TextInputSuggest } from "./suggest"; + +export class FileSuggest extends TextInputSuggest { + getSuggestions(inputStr: string): TFile[] { + const abstractFiles = this.app.vault.getAllLoadedFiles(); + const files: TFile[] = []; + const lowerCaseInputStr = inputStr.toLowerCase(); + + abstractFiles.forEach((file: TAbstractFile) => { + if (file instanceof TFile && file.path.toLowerCase().contains(lowerCaseInputStr)) { + files.push(file); + } + }); + + return files; + } + + renderSuggestion(file: TFile, el: HTMLElement): void { + el.setText(file.path); + } + + selectSuggestion(file: TFile): void { + this.inputEl.value = file.path; + this.inputEl.trigger("input"); + this.close(); + } +} diff --git a/src/utils/templateModal.ts b/src/utils/templateModal.ts index aa4382c..1641697 100644 --- a/src/utils/templateModal.ts +++ b/src/utils/templateModal.ts @@ -1,4 +1,4 @@ -import { SuggestModal, Editor, App } from "obsidian"; +import { SuggestModal, Editor, App, TFile } from "obsidian"; import { Template, WikipediaSearchSettings } from "src/settings"; import { Article } from "./searchModal"; @@ -6,18 +6,52 @@ export abstract class TemplateModal extends SuggestModal