From 8914fccaba8655eb00f5809423c8ab75e0551acc Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Sat, 12 Jun 2021 20:39:45 -0700 Subject: [PATCH 01/14] Writing to file off-screen so it displays upon open Working around a bug/feature where the appendParagraph was not showing up in the Editor. It's better this way anyway, because I can ask the user whether to open it or not. :) --- jgclark.NoteHelpers/noteHelpers.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 22e651528..1879c74ae 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -65,13 +65,19 @@ async function showMessage(message, confirmTitle = 'OK') { return await CommandBar.showOptions([confirmTitle], message) } +// Show feedback Yes/No Question via Command Bar (@dwertheimer) +async function showMessageYesNo(message, choicesArray = ['Yes', 'No']) { + const answer = await CommandBar.showOptions(choicesArray, message) + return choicesArray[answer.index] +} + // Find a unique note title/filename so backlinks can work properly (@dwertheimer) function getUniqueNoteTitle(title) { let i = 0, res = [] while (++i === 1 || res.length > 0) { newtitle = i === 1 ? title : `${title} ${i}` - res = DataStore.projectNoteByTitle(newtitle,true,false) + res = DataStore.projectNoteByTitle(newtitle, true, false) } return newtitle } @@ -242,6 +248,8 @@ async function newNoteFromSelection() { // const origFileType = Editor.note.type //either "Notes" or "Calendar" const filename = DataStore.newNote(title, currentFolder) ?? '' + const newNote = await DataStore.projectNoteByFilename(filename) + const iblq = await CommandBar.showOptions( ['Yes', 'No'], 'Insert link to new file where selection was?', @@ -255,10 +263,11 @@ async function newNoteFromSelection() { Editor.replaceSelectionWithText(``) } } - await Editor.openNoteByFilename(filename) if (insertBackLink) - Editor.note.appendParagraph(`From [[${origFile}]]:`, 'empty') - Editor.note.appendParagraph(movedText, 'empty') + newNote.appendParagraph(`From [[${origFile}]]:`, 'empty') + newNote.appendParagraph(movedText, 'empty') + if ((await showMessageYesNo('New Note created. Open it now?')) === 'Yes') + await Editor.openNoteByFilename(filename) } else { console.log('\tError: undefined or empty title') } From b5665270e8b20210eb85859d1a81041f71d314c0 Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Sat, 12 Jun 2021 20:45:58 -0700 Subject: [PATCH 02/14] Updated version to 0.9.1 --- jgclark.NoteHelpers/README.md | 3 +++ jgclark.NoteHelpers/noteHelpers.js | 2 +- jgclark.NoteHelpers/plugin.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/jgclark.NoteHelpers/README.md b/jgclark.NoteHelpers/README.md index af9058f72..2098a2897 100644 --- a/jgclark.NoteHelpers/README.md +++ b/jgclark.NoteHelpers/README.md @@ -20,6 +20,9 @@ Templates should normally end with a linefeed character (`\n`). ## History +### v0.9.1, 12.6.2021 +- change: write text offscreen and ask user if they want to open newly created file + ### v0.9.0, 12.6.2021 - [add]: **/nns** command to add a new note from selection (and leave link to it in its place) (@dwertheimer) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 1879c74ae..cbbd6bd70 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -3,7 +3,7 @@ // Note Helpers plugin for NotePlan // Jonathan Clark & Eduard Metzger // /nns by @dwertheimer -// v0.9.0, 1.6.2021 +// v0.9.1, 1.6.2021 //-------------------------------------------------------------------------------------------------------------------- // Globals diff --git a/jgclark.NoteHelpers/plugin.json b/jgclark.NoteHelpers/plugin.json index 478c762fe..f3bdb41a3 100644 --- a/jgclark.NoteHelpers/plugin.json +++ b/jgclark.NoteHelpers/plugin.json @@ -6,7 +6,7 @@ "plugin.icon": "", "plugin.author": "Jonathan Clark & Eduard Metzger", "plugin.url": "https://github.com/NotePlan/plugins/tree/main/jgclark.NoteHelpers/", - "plugin.version": "0.9.0", + "plugin.version": "0.9.1", "plugin.changelog": "See plugin README.md", "plugin.dependencies": [], "plugin.script": "noteHelpers.js", From 308d00a8cf64fb0efe57bafacaa87d6d984b21bc Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Sun, 13 Jun 2021 07:44:46 -0700 Subject: [PATCH 03/14] minor clean-up No functional changes. Just making the Linter happier --- jgclark.NoteHelpers/noteHelpers.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index cbbd6bd70..0d4ee9542 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -74,12 +74,13 @@ async function showMessageYesNo(message, choicesArray = ['Yes', 'No']) { // Find a unique note title/filename so backlinks can work properly (@dwertheimer) function getUniqueNoteTitle(title) { let i = 0, - res = [] + res = [], + newTitle = title while (++i === 1 || res.length > 0) { - newtitle = i === 1 ? title : `${title} ${i}` - res = DataStore.projectNoteByTitle(newtitle, true, false) + newTitle = i === 1 ? title : `${title} ${i}` + res = DataStore.projectNoteByTitle(newTitle, true, false) } - return newtitle + return newTitle } //------------------------------------------------------------------ @@ -263,11 +264,15 @@ async function newNoteFromSelection() { Editor.replaceSelectionWithText(``) } } - if (insertBackLink) + if (insertBackLink) { newNote.appendParagraph(`From [[${origFile}]]:`, 'empty') + } newNote.appendParagraph(movedText, 'empty') - if ((await showMessageYesNo('New Note created. Open it now?')) === 'Yes') + if ( + (await showMessageYesNo('New Note created. Open it now?')) === 'Yes' + ) { await Editor.openNoteByFilename(filename) + } } else { console.log('\tError: undefined or empty title') } From 3aaa47ea7df9d970e79876588ae3e42911062309 Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Sun, 13 Jun 2021 08:44:13 -0700 Subject: [PATCH 04/14] Refining the title suggestions If item is a todo or list, etc. then don't delete it after using it for the title --- jgclark.NoteHelpers/noteHelpers.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 0d4ee9542..4bed5f3ca 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -206,16 +206,25 @@ globalThis.setTitleFromYAML = setTitleFromYAML // Create new note from currently selected text // and (optionally) leave backlink to it where selection was async function newNoteFromSelection() { - const { selectedLinesText, selectedText } = Editor - console.log('\nnewNoteFromSelection (running):') + const { selectedLinesText, selectedText, selectedParagraphs } = Editor + console.log( + `\nnewNoteFromSelection (running) ${selectedParagraphs.length} selected:`, + ) let currentFolder = '' if (selectedLinesText.length && selectedText !== '') { // Get title for this note - const stripHashes = /^\s*(#)* *(.*)/ - const firstLineArray = stripHashes.exec(selectedLinesText[0]) - const strippedFirstLine = - firstLineArray.length === 3 ? firstLineArray[2] : '' + console.log( + `1st Para Type = ${selectedParagraphs[0].type} = "${selectedParagraphs[0].content}"`, + ) + // const stripHashes = /^\s*(#)* *(.*)/ + // const firstLineArray = stripHashes.exec(selectedLinesText[0]) + // const strippedFirstLine = + // firstLineArray.length === 3 ? firstLineArray[2] : '' + + const isTextContent = + ['title', 'text', 'empty'].indexOf(selectedParagraphs[0].type) >= 0 + const strippedFirstLine = selectedParagraphs[0].content let title = await CommandBar.showInput( 'Title of new note ([enter] to use text below)', strippedFirstLine, @@ -223,7 +232,9 @@ async function newNoteFromSelection() { // If user just hit [enter], then use the first line as suggested if (!title) { title = strippedFirstLine - selectedLinesText.shift() + if (isTextContent) { + selectedLinesText.shift() + } } const movedText = selectedLinesText.join('\n') const uniqueTitle = getUniqueNoteTitle(title) From 0a802eeb7107f247f198286183b737b665dcd16e Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Sun, 13 Jun 2021 23:59:14 -0700 Subject: [PATCH 05/14] Added debug/testing code Stuck on how to open a file that's in a folder. Pushing code so Jonathan can see it with the console logs. --- jgclark.NoteHelpers/README.md | 2 +- jgclark.NoteHelpers/noteHelpers.js | 70 ++++++++++++++++++++---------- jgclark.NoteHelpers/plugin.json | 2 +- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/jgclark.NoteHelpers/README.md b/jgclark.NoteHelpers/README.md index 2098a2897..7b9030ae0 100644 --- a/jgclark.NoteHelpers/README.md +++ b/jgclark.NoteHelpers/README.md @@ -20,7 +20,7 @@ Templates should normally end with a linefeed character (`\n`). ## History -### v0.9.1, 12.6.2021 +### v0.9.2, 13.6.2021 - change: write text offscreen and ask user if they want to open newly created file ### v0.9.0, 12.6.2021 diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 4bed5f3ca..b1fc4a40a 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -3,7 +3,7 @@ // Note Helpers plugin for NotePlan // Jonathan Clark & Eduard Metzger // /nns by @dwertheimer -// v0.9.1, 1.6.2021 +// v0.9.2, 1.6.2021 //-------------------------------------------------------------------------------------------------------------------- // Globals @@ -206,16 +206,18 @@ globalThis.setTitleFromYAML = setTitleFromYAML // Create new note from currently selected text // and (optionally) leave backlink to it where selection was async function newNoteFromSelection() { + const version = `0.9.2` + console.log(`Running v${version}`) const { selectedLinesText, selectedText, selectedParagraphs } = Editor console.log( - `\nnewNoteFromSelection (running) ${selectedParagraphs.length} selected:`, + `\nnewNoteFromSelection (running v${version}) ${selectedParagraphs.length} selected:`, ) let currentFolder = '' if (selectedLinesText.length && selectedText !== '') { // Get title for this note console.log( - `1st Para Type = ${selectedParagraphs[0].type} = "${selectedParagraphs[0].content}"`, + `\t1st Para Type = ${selectedParagraphs[0].type} = "${selectedParagraphs[0].content}"`, ) // const stripHashes = /^\s*(#)* *(.*)/ // const firstLineArray = stripHashes.exec(selectedLinesText[0]) @@ -253,36 +255,56 @@ async function newNoteFromSelection() { // no Folders so go to root currentFolder = '/' } + console.log(`\tcurrentFolder=${currentFolder}`) if (title) { // Create new note in the specific folder const origFile = Editor.note.title || Editor.note.filename // Calendar notes have no title // const origFileType = Editor.note.type //either "Notes" or "Calendar" + console.log(`\torigFile:${origFile}`) + const filename = (await DataStore.newNote(title, currentFolder)) ?? '' + console.log(`\tnewNote returned Filename:${filename}`) + const fullPath = `${ + currentFolder !== '/' ? currentFolder + '/' : '' + }${filename}` + console.log(`\tAbout to open filename: "${fullPath}"`) + /* + // make a new note for this + let noteFilename = await DataStore.newNote(title, pref_folderToStore); + console.log(`\tnewNote filename: ${noteFilename}`); + noteFilename = `${pref_folderToStore}/${noteFilename}` ?? '(error)'; // NB: filename here = folder + filename - const filename = DataStore.newNote(title, currentFolder) ?? '' - const newNote = await DataStore.projectNoteByFilename(filename) + */ + const newNote = await DataStore.projectNoteByFilename(fullPath) + if (newNote) { + console.log(`\tnewNote=${newNote}\n\t${newNote.title}`) + console.log(`\tcontent=${newNote.content}`) - const iblq = await CommandBar.showOptions( - ['Yes', 'No'], - 'Insert link to new file where selection was?', - ) - const insertBackLink = iblq.index === 0 - if (Editor.replaceSelectionWithText) { - // for compatibility, make sure the function exists + const iblq = await CommandBar.showOptions( + ['Yes', 'No'], + 'Insert link to new file where selection was?', + ) + const insertBackLink = iblq.index === 0 + if (Editor.replaceSelectionWithText) { + // for compatibility, make sure the function exists + if (insertBackLink) { + Editor.replaceSelectionWithText(`[[${title}]]`) + } else { + Editor.replaceSelectionWithText(``) + } + } if (insertBackLink) { - Editor.replaceSelectionWithText(`[[${title}]]`) - } else { - Editor.replaceSelectionWithText(``) + newNote.appendParagraph(`From [[${origFile}]]:`, 'text') } - } - if (insertBackLink) { - newNote.appendParagraph(`From [[${origFile}]]:`, 'empty') - } - newNote.appendParagraph(movedText, 'empty') - if ( - (await showMessageYesNo('New Note created. Open it now?')) === 'Yes' - ) { - await Editor.openNoteByFilename(filename) + newNote.appendParagraph(movedText, 'empty') + if ( + (await showMessageYesNo('New Note created. Open it now?')) === 'Yes' + ) { + await Editor.openNoteByFilename(filename) + } + } else { + console.log(`\Could not open file: "${fullPath}"`) + showMessage(`Could not open file ${fullPath}`) } } else { console.log('\tError: undefined or empty title') diff --git a/jgclark.NoteHelpers/plugin.json b/jgclark.NoteHelpers/plugin.json index f3bdb41a3..affe2af65 100644 --- a/jgclark.NoteHelpers/plugin.json +++ b/jgclark.NoteHelpers/plugin.json @@ -6,7 +6,7 @@ "plugin.icon": "", "plugin.author": "Jonathan Clark & Eduard Metzger", "plugin.url": "https://github.com/NotePlan/plugins/tree/main/jgclark.NoteHelpers/", - "plugin.version": "0.9.1", + "plugin.version": "0.9.2", "plugin.changelog": "See plugin README.md", "plugin.dependencies": [], "plugin.script": "noteHelpers.js", From 06f5ded02f2cbd93da61197ea3104670167f8f26 Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Mon, 14 Jun 2021 09:05:44 -0700 Subject: [PATCH 06/14] Adding test code for @EduardMe debugging testing projectNoteByFilename --- jgclark.NoteHelpers/noteHelpers.js | 45 ++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index b1fc4a40a..4861b403c 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -264,18 +264,45 @@ async function newNoteFromSelection() { console.log(`\torigFile:${origFile}`) const filename = (await DataStore.newNote(title, currentFolder)) ?? '' console.log(`\tnewNote returned Filename:${filename}`) - const fullPath = `${ + + // Start Testing/debugging here + const noteOpener = async function (fullPath, desc) { + console.log(`\tAbout to open filename: "${fullPath}" (${desc})`) + const newNote = await DataStore.projectNoteByFilename(fullPath) + if (newNote) { + console.log(`\tWorked! ${fullPath} (${desc} version)`) + } else { + console.log( + `\tDidn't work! ${fullPath} (${desc}) returned ${newNote}`, + ) + } + return newNote + } + let fullPath = `${ currentFolder !== '/' ? currentFolder + '/' : '' }${filename}` - console.log(`\tAbout to open filename: "${fullPath}"`) - /* - // make a new note for this - let noteFilename = await DataStore.newNote(title, pref_folderToStore); - console.log(`\tnewNote filename: ${noteFilename}`); - noteFilename = `${pref_folderToStore}/${noteFilename}` ?? '(error)'; // NB: filename here = folder + filename - */ - const newNote = await DataStore.projectNoteByFilename(fullPath) + let newNote = await noteOpener(fullPath, 'no leading slash') + if (!newNote) { + fullPath = `${ + currentFolder !== '/' ? '/' + currentFolder + '/' : '' + }${filename}` + newNote = await noteOpener(fullPath, 'with leading slash') + } + if (!newNote) { + newNote = await noteOpener( + `${currentFolder}/${filename}`, + 'Jonathan way', + ) + } + if (!newNote) { + newNote = await noteOpener( + `${filename}`, + 'no folder path, filename only', + ) + } + // let newNote = await DataStore.projectNoteByFilename(fullPath) + if (newNote) { console.log(`\tnewNote=${newNote}\n\t${newNote.title}`) console.log(`\tcontent=${newNote.content}`) From ba73292a85a9218370b45743131d0429fccbec5b Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Mon, 14 Jun 2021 09:18:11 -0700 Subject: [PATCH 07/14] trying noteByFilename too Still not working --- jgclark.NoteHelpers/noteHelpers.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 4861b403c..da7b5227b 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -266,9 +266,15 @@ async function newNoteFromSelection() { console.log(`\tnewNote returned Filename:${filename}`) // Start Testing/debugging here - const noteOpener = async function (fullPath, desc) { + const noteOpener = async function ( + fullPath, + desc, + useProjNoteByFilename = true, + ) { console.log(`\tAbout to open filename: "${fullPath}" (${desc})`) - const newNote = await DataStore.projectNoteByFilename(fullPath) + const newNote = (await useProjNoteByFilename) + ? DataStore.projectNoteByFilename(fullPath) + : DataStore.noteByFilename(fullPath, 'Notes') if (newNote) { console.log(`\tWorked! ${fullPath} (${desc} version)`) } else { @@ -301,8 +307,19 @@ async function newNoteFromSelection() { 'no folder path, filename only', ) } + if (!newNote) { + newNote = await noteOpener( + `${currentFolder !== '/' ? currentFolder + '/' : ''}${filename}`, + 'using noteByFilename Instead', + false, + ) + } + // let newNote = await DataStore.projectNoteByFilename(fullPath) + if (!newNote) { + } + if (newNote) { console.log(`\tnewNote=${newNote}\n\t${newNote.title}`) console.log(`\tcontent=${newNote.content}`) From e3ee670861bb413d77ad2ca519f3144fdce92769 Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Mon, 14 Jun 2021 09:38:11 -0700 Subject: [PATCH 08/14] Using noteByFilename logging also --- jgclark.NoteHelpers/noteHelpers.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index da7b5227b..fbdc2cf30 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -271,12 +271,16 @@ async function newNoteFromSelection() { desc, useProjNoteByFilename = true, ) { - console.log(`\tAbout to open filename: "${fullPath}" (${desc})`) + console.log( + `\tAbout to open filename: "${fullPath}" (${desc}) using ${ + useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' + }`, + ) const newNote = (await useProjNoteByFilename) ? DataStore.projectNoteByFilename(fullPath) : DataStore.noteByFilename(fullPath, 'Notes') if (newNote) { - console.log(`\tWorked! ${fullPath} (${desc} version)`) + console.log(`\tWorked! ${fullPath} (${desc} version) `) } else { console.log( `\tDidn't work! ${fullPath} (${desc}) returned ${newNote}`, From 4417af88dd4ad36e61880dc59a9c673fd3216cda Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Mon, 14 Jun 2021 10:10:38 -0700 Subject: [PATCH 09/14] Added one more test --- jgclark.NoteHelpers/noteHelpers.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index fbdc2cf30..d36450446 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -280,10 +280,10 @@ async function newNoteFromSelection() { ? DataStore.projectNoteByFilename(fullPath) : DataStore.noteByFilename(fullPath, 'Notes') if (newNote) { - console.log(`\tWorked! ${fullPath} (${desc} version) `) + console.log(`\t\tWorked! ${fullPath} (${desc} version) `) } else { console.log( - `\tDidn't work! ${fullPath} (${desc}) returned ${newNote}`, + `\t\tDidn't work! ${fullPath} (${desc}) returned ${newNote}`, ) } return newNote @@ -318,7 +318,15 @@ async function newNoteFromSelection() { false, ) } - + if (!newNote) { + newNote = await noteOpener( + `${ + currentFolder !== '/' ? '/' + currentFolder + '/' : '' + }${filename}`, + 'using noteByFilename Instead, leading slash', + false, + ) + } // let newNote = await DataStore.projectNoteByFilename(fullPath) if (!newNote) { From 226974f51b87e00fbde65c8dd1d1f1aa1d21d839 Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Mon, 14 Jun 2021 10:15:04 -0700 Subject: [PATCH 10/14] log tweak --- jgclark.NoteHelpers/noteHelpers.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index d36450446..091e905af 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -283,7 +283,9 @@ async function newNoteFromSelection() { console.log(`\t\tWorked! ${fullPath} (${desc} version) `) } else { console.log( - `\t\tDidn't work! ${fullPath} (${desc}) returned ${newNote}`, + `\t\tDidn't work! ${ + useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' + } returned ${newNote}`, ) } return newNote From c5898b10caf73d181aac1bff00fd3a72030e876c Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Mon, 14 Jun 2021 20:22:43 -0700 Subject: [PATCH 11/14] Workarounds for API cache issue on projectNoteByFilename Moved question in the middle as a work-around so it should work on / and folder use cases. @jgclark pls let me know if you find anything else --- jgclark.NoteHelpers/noteHelpers.js | 113 ++++++++++------------------- 1 file changed, 38 insertions(+), 75 deletions(-) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 091e905af..71f053835 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -1,4 +1,4 @@ -// @flow +// @ flow //-------------------------------------------------------------------------------------------------------------------- // Note Helpers plugin for NotePlan // Jonathan Clark & Eduard Metzger @@ -201,6 +201,28 @@ function setTitleFromYAML() { } globalThis.setTitleFromYAML = setTitleFromYAML +// Start Testing/debugging here +async function noteOpener(fullPath, desc, useProjNoteByFilename = true) { + console.log( + `\tAbout to open filename: "${fullPath}" (${desc}) using ${ + useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' + }`, + ) + const newNote = (await useProjNoteByFilename) + ? DataStore.projectNoteByFilename(fullPath) + : DataStore.noteByFilename(fullPath, 'Notes') + if (newNote) { + console.log(`\t\tWorked! ${fullPath} (${desc} version) `) + } else { + console.log( + `\t\tDidn't work! ${ + useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' + } returned ${newNote}`, + ) + } + return newNote +} + //------------------------------------------------------------------ // @dwertheimer based on @jgclark's newNote // Create new note from currently selected text @@ -265,83 +287,23 @@ async function newNoteFromSelection() { const filename = (await DataStore.newNote(title, currentFolder)) ?? '' console.log(`\tnewNote returned Filename:${filename}`) - // Start Testing/debugging here - const noteOpener = async function ( - fullPath, - desc, - useProjNoteByFilename = true, - ) { - console.log( - `\tAbout to open filename: "${fullPath}" (${desc}) using ${ - useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' - }`, - ) - const newNote = (await useProjNoteByFilename) - ? DataStore.projectNoteByFilename(fullPath) - : DataStore.noteByFilename(fullPath, 'Notes') - if (newNote) { - console.log(`\t\tWorked! ${fullPath} (${desc} version) `) - } else { - console.log( - `\t\tDidn't work! ${ - useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' - } returned ${newNote}`, - ) - } - return newNote - } - let fullPath = `${ - currentFolder !== '/' ? currentFolder + '/' : '' + const fullPath = `${ + currentFolder !== '/' ? `${currentFolder}/` : '' }${filename}` - let newNote = await noteOpener(fullPath, 'no leading slash') - if (!newNote) { - fullPath = `${ - currentFolder !== '/' ? '/' + currentFolder + '/' : '' - }${filename}` - newNote = await noteOpener(fullPath, 'with leading slash') - } - if (!newNote) { - newNote = await noteOpener( - `${currentFolder}/${filename}`, - 'Jonathan way', - ) - } - if (!newNote) { - newNote = await noteOpener( - `${filename}`, - 'no folder path, filename only', - ) - } - if (!newNote) { - newNote = await noteOpener( - `${currentFolder !== '/' ? currentFolder + '/' : ''}${filename}`, - 'using noteByFilename Instead', - false, - ) - } - if (!newNote) { - newNote = await noteOpener( - `${ - currentFolder !== '/' ? '/' + currentFolder + '/' : '' - }${filename}`, - 'using noteByFilename Instead, leading slash', - false, - ) - } - // let newNote = await DataStore.projectNoteByFilename(fullPath) + // This question needs to be here after newNote and before noteOpener + // to force a cache refresh after newNote. This API bug will eventually be fixed. + const iblq = await CommandBar.showOptions( + ['Yes', 'No'], + 'Insert link to new file where selection was?', + ) - if (!newNote) { - } + const newNote = await noteOpener(fullPath, 'no leading slash') if (newNote) { console.log(`\tnewNote=${newNote}\n\t${newNote.title}`) console.log(`\tcontent=${newNote.content}`) - const iblq = await CommandBar.showOptions( - ['Yes', 'No'], - 'Insert link to new file where selection was?', - ) const insertBackLink = iblq.index === 0 if (Editor.replaceSelectionWithText) { // for compatibility, make sure the function exists @@ -351,18 +313,19 @@ async function newNoteFromSelection() { Editor.replaceSelectionWithText(``) } } + + newNote.appendParagraph(movedText, 'empty') if (insertBackLink) { - newNote.appendParagraph(`From [[${origFile}]]:`, 'text') + newNote.appendParagraph(`^^^ Moved from [[${origFile}]]:`, 'text') } - newNote.appendParagraph(movedText, 'empty') if ( (await showMessageYesNo('New Note created. Open it now?')) === 'Yes' ) { - await Editor.openNoteByFilename(filename) + await Editor.openNoteByFilename(fullPath) } } else { - console.log(`\Could not open file: "${fullPath}"`) - showMessage(`Could not open file ${fullPath}`) + console.log(`\tCould not open file: "${fullPath}"`) + showMessage(`\tCould not open file ${fullPath}`) } } else { console.log('\tError: undefined or empty title') From bc67728bf4192d7cb7b142d0bc3dd716edc1e89a Mon Sep 17 00:00:00 2001 From: David Wertheimer Date: Tue, 15 Jun 2021 01:02:32 -0700 Subject: [PATCH 12/14] Moved /nns to Filer Now that /nns is working, broke it out of the monolithic NoteHelpers and moved it to Filer. Tested both. --- jgclark.Filer/README.md | 3 + jgclark.Filer/plugin.json | 7 +- jgclark.Filer/script.js | 143 ++++++++++++++++++- jgclark.Filer/src/fileItems.js | 15 +- jgclark.Filer/src/helpers.js | 88 ++++++++++++ jgclark.Filer/src/index.js | 3 +- jgclark.Filer/src/newNoteFromSelection.js | 106 ++++++++++++++ jgclark.NoteHelpers/README.md | 4 +- jgclark.NoteHelpers/noteHelpers.js | 164 +--------------------- jgclark.NoteHelpers/plugin.json | 7 +- 10 files changed, 361 insertions(+), 179 deletions(-) create mode 100644 jgclark.Filer/src/helpers.js create mode 100644 jgclark.Filer/src/newNoteFromSelection.js diff --git a/jgclark.Filer/README.md b/jgclark.Filer/README.md index aa2299b83..c7d656cb1 100644 --- a/jgclark.Filer/README.md +++ b/jgclark.Filer/README.md @@ -14,6 +14,9 @@ It pops up the command bar to choose the note you want to move it to, followed b If you want to stop date backlinks being added change the line at the top of the plugin'\ `fileItems.js` file to: `const pref_addDateBacklink = false;` ## History + +### v0.4.0 15.6.2021 (@dwertheimer) +- add /nns (moved from NoteHelpers) ### v0.3.3, 11.6.2021 - remove restriction to move to just project notes - update code to work with today's API fixes diff --git a/jgclark.Filer/plugin.json b/jgclark.Filer/plugin.json index f6148a21b..27f89db84 100644 --- a/jgclark.Filer/plugin.json +++ b/jgclark.Filer/plugin.json @@ -5,7 +5,7 @@ "plugin.description": "Help file (move) the current paragraph, selected paragraphs, or heading and its section, to different notes. Please see website for more details.", "plugin.icon": "", "plugin.author": "jgclark", "plugin.url": "https://github.com/NotePlan/plugins/tree/main/jgclark.Filer", - "plugin.version": "0.3.3", + "plugin.version": "0.4.0", "plugin.dependencies": [], "plugin.script": "script.js", "plugin.isRemote": "false", @@ -19,6 +19,11 @@ "name": "mp", "description": "move (file) paragraphs to different notes", "jsFunction": "fileParas" + }, + { + "name": "nns", + "description": "New note from selection (and leave link to it in its place)", + "jsFunction": "newNoteFromSelection" } ], "plugin.preferences": [ diff --git a/jgclark.Filer/script.js b/jgclark.Filer/script.js index a736a7528..b59f96601 100644 --- a/jgclark.Filer/script.js +++ b/jgclark.Filer/script.js @@ -43,7 +43,7 @@ var exports = (function (exports) { } } // Print out all data for a paragraph (borrowed from EM) - // ----------------------------------------------------------------------------- + // @ flow // Helper Functions // Return list of all notes, sorted by changed date (newest to oldest) @@ -252,7 +252,148 @@ var exports = (function (exports) { } } // globalThis.fileParas = fileParas + //------------------------------------------------------------------ + + async function showMessage(message, confirmTitle = 'OK') { + return await CommandBar.showOptions([confirmTitle], message); + } // Show feedback Yes/No Question via Command Bar (@dwertheimer) + + async function showMessageYesNo(message, choicesArray = ['Yes', 'No']) { + const answer = await CommandBar.showOptions(choicesArray, message); + return choicesArray[answer.index]; + } + async function noteOpener(fullPath, desc, useProjNoteByFilename = true) { + console.log(`\tAbout to open filename: "${fullPath}" (${desc}) using ${useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename'}`); + const newNote = (await useProjNoteByFilename) ? DataStore.projectNoteByFilename(fullPath) : DataStore.noteByFilename(fullPath, 'Notes'); + + if (newNote) { + console.log(`\t\tOpened ${fullPath} (${desc} version) `); + } else { + console.log(`\t\tDidn't work! ${useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename'} returned ${newNote}`); + } + + return newNote; + } // Find a unique note title/filename so backlinks can work properly (@dwertheimer) + // Keep adding numbers to the end of a filename (if already taken) until it works + + function getUniqueNoteTitle(title) { + let i = 0, + res = [], + newTitle = title; + + while (++i === 1 || res.length > 0) { + newTitle = i === 1 ? title : `${title} ${i}`; + res = DataStore.projectNoteByTitle(newTitle, true, false); + } + + return newTitle; + } + async function chooseFolder(msg) { + let currentFolder; + const folders = DataStore.folders; // excludes Trash and Archive + + if (folders.length > 0) { + const re = await CommandBar.showOptions(folders, msg); + currentFolder = folders[re.index]; + } else { + // no Folders so go to root + currentFolder = '/'; + } + + console.log(`\tcurrentFolder=${currentFolder}`); + return currentFolder; + } + + // @ flow + async function newNoteFromSelection() { + const version = `0.4.0`; + console.log(`Running v${version}`); + const { + selectedLinesText, + selectedText, + selectedParagraphs + } = Editor; + console.log(`\nnewNoteFromSelection (running v${version}) ${selectedParagraphs.length} selected:`); + + if (selectedLinesText.length && selectedText !== '') { + // Get title for this note + console.log(`\t1st Para Type = ${selectedParagraphs[0].type} = "${selectedParagraphs[0].content}"`); + const isTextContent = ['title', 'text', 'empty'].indexOf(selectedParagraphs[0].type) >= 0; + const strippedFirstLine = selectedParagraphs[0].content; + let title = await CommandBar.showInput('Title of new note ([enter] to use text below)', strippedFirstLine); // If user just hit [enter], then use the first line as suggested + + if (!title) { + title = strippedFirstLine; + + if (isTextContent) { + selectedLinesText.shift(); + } + } + + const movedText = selectedLinesText.join('\n'); + const uniqueTitle = getUniqueNoteTitle(title); + + if (title !== uniqueTitle) { + await showMessage(`Title exists. Using "${uniqueTitle}" instead`); + title = uniqueTitle; + } + + const currentFolder = await chooseFolder('Select folder to add note in:'); + + if (title) { + // Create new note in the specific folder + const origFile = Editor.note.title || Editor.note.filename; // Calendar notes have no title + // const origFileType = Editor.note.type //either "Notes" or "Calendar" + + console.log(`\torigFile:${origFile}`); + const filename = (await DataStore.newNote(title, currentFolder)) ?? ''; + console.log(`\tnewNote returned Filename:${filename}`); + const fullPath = `${currentFolder !== '/' ? `${currentFolder}/` : ''}${filename}`; // This question needs to be here after newNote and before noteOpener + // to force a cache refresh after newNote. This API bug will eventually be fixed. + + const iblq = await CommandBar.showOptions(['Yes', 'No'], 'Insert link to new file where selection was?'); + const newNote = await noteOpener(fullPath, 'no leading slash'); + + if (newNote) { + console.log(`\tnewNote=${newNote}\n\t${newNote.title}`); + console.log(`\tcontent=${newNote.content}`); + const insertBackLink = iblq.index === 0; + + if (Editor.replaceSelectionWithText) { + // for compatibility, make sure the function exists + if (insertBackLink) { + Editor.replaceSelectionWithText(`[[${title}]]`); + } else { + Editor.replaceSelectionWithText(``); + } + } + + newNote.appendParagraph(movedText, 'empty'); + + if (insertBackLink) { + newNote.appendParagraph(`^^^ Moved from [[${origFile}]]:`, 'text'); + } + + if ((await showMessageYesNo('New Note created. Open it now?')) === 'Yes') { + await Editor.openNoteByFilename(fullPath); + } + } else { + console.log(`\tCould not open file: "${fullPath}"`); + showMessage(`\tCould not open file ${fullPath}`); + } + } else { + console.log('\tError: undefined or empty title'); + } + } else { + showMessage('No text was selected. Nothing to do.', "OK, I'll try again!"); + } + + console.log('\nnewNoteFromSelection (finished)'); + } + globalThis.newNoteFromSelection = newNoteFromSelection; + exports.fileParas = fileParas; + exports.newNoteFromSelection = newNoteFromSelection; Object.defineProperty(exports, '__esModule', { value: true }); diff --git a/jgclark.Filer/src/fileItems.js b/jgclark.Filer/src/fileItems.js index 12b11b56f..12b619201 100644 --- a/jgclark.Filer/src/fileItems.js +++ b/jgclark.Filer/src/fileItems.js @@ -1,11 +1,14 @@ -// @flow +// @ flow // ----------------------------------------------------------------------------- -// Plugin to help move selected pargraphs to other notes +// Plugin to help move selected paragraphs to other notes // Jonathan Clark // v0.3.3, 11.6.2021 // ----------------------------------------------------------------------------- -import { rangeToString, displayTitle } from '../../np.statistics/src/statsHelpers' +import { + rangeToString, + displayTitle, +} from '../../np.statistics/src/statsHelpers' // Preference that needs to get added when there is a proper config system const pref_addDateBacklink = true @@ -19,8 +22,8 @@ function allNotesSortedByChanged() { const calendarNotes = DataStore.calendarNotes.slice() const allNotes = projectNotes.concat(calendarNotes) const allNotesSortedByDate = allNotes.sort( - (first, second) => - second.changedDate - first.changedDate) // most recent first + (first, second) => second.changedDate - first.changedDate, + ) // most recent first return allNotesSortedByDate } @@ -114,7 +117,7 @@ export async function fileParas() { } parasToMove.push(p) } - console.log(` Found ${parasToMove.length-1} indented paras`) + console.log(` Found ${parasToMove.length - 1} indented paras`) } } diff --git a/jgclark.Filer/src/helpers.js b/jgclark.Filer/src/helpers.js new file mode 100644 index 000000000..73fdf1499 --- /dev/null +++ b/jgclark.Filer/src/helpers.js @@ -0,0 +1,88 @@ +//------------------------------------------------------------------ +// Helper functions +//------------------------------------------------------------------ +export function printNote(note) { + if (note == null) { + console.log('Note not found!') + return + } + + if (note.type === 'Notes') { + console.log( + `title: ${note.title ?? ''}\n\tfilename: ${ + note.filename ?? '' + }\n\thashtags: ${note.hashtags?.join(',') ?? ''}\n\tmentions: ${ + note.mentions?.join(',') ?? '' + }\n\tcreated: ${String(note.createdDate) ?? ''}\n\tchanged: ${ + String(note.changedDate) ?? '' + }`, + ) + } else { + console.log( + `date: ${String(note.createdDate) ?? ''}\n\tfilename: ${ + note.filename ?? '' + }\n\thashtags: ${note.hashtags?.join(',') ?? ''}\n\tmentions: ${ + note.mentions?.join(',') ?? '' + }`, + ) + } +} + +// Show feedback message using Command Bar (@dwertheimer) +export async function showMessage(message, confirmTitle = 'OK') { + return await CommandBar.showOptions([confirmTitle], message) +} + +// Show feedback Yes/No Question via Command Bar (@dwertheimer) +export async function showMessageYesNo(message, choicesArray = ['Yes', 'No']) { + const answer = await CommandBar.showOptions(choicesArray, message) + return choicesArray[answer.index] +} + +export async function noteOpener(fullPath, desc, useProjNoteByFilename = true) { + console.log( + `\tAbout to open filename: "${fullPath}" (${desc}) using ${ + useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' + }`, + ) + const newNote = (await useProjNoteByFilename) + ? DataStore.projectNoteByFilename(fullPath) + : DataStore.noteByFilename(fullPath, 'Notes') + if (newNote) { + console.log(`\t\tOpened ${fullPath} (${desc} version) `) + } else { + console.log( + `\t\tDidn't work! ${ + useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' + } returned ${newNote}`, + ) + } + return newNote +} + +// Find a unique note title/filename so backlinks can work properly (@dwertheimer) +// Keep adding numbers to the end of a filename (if already taken) until it works +export function getUniqueNoteTitle(title) { + let i = 0, + res = [], + newTitle = title + while (++i === 1 || res.length > 0) { + newTitle = i === 1 ? title : `${title} ${i}` + res = DataStore.projectNoteByTitle(newTitle, true, false) + } + return newTitle +} + +export async function chooseFolder(msg) { + let currentFolder + const folders = DataStore.folders // excludes Trash and Archive + if (folders.length > 0) { + const re = await CommandBar.showOptions(folders, msg) + currentFolder = folders[re.index] + } else { + // no Folders so go to root + currentFolder = '/' + } + console.log(`\tcurrentFolder=${currentFolder}`) + return currentFolder +} diff --git a/jgclark.Filer/src/index.js b/jgclark.Filer/src/index.js index 4c011e630..5154c8358 100644 --- a/jgclark.Filer/src/index.js +++ b/jgclark.Filer/src/index.js @@ -3,7 +3,8 @@ // ----------------------------------------------------------------------------- // Plugin to help move selected pargraphs to other notes // Jonathan Clark -// v0.3.3, 11.6.2021 +// v0.4, 15.6.2021 // ----------------------------------------------------------------------------- export { fileParas } from './fileItems' +export { newNoteFromSelection } from './newNoteFromSelection' diff --git a/jgclark.Filer/src/newNoteFromSelection.js b/jgclark.Filer/src/newNoteFromSelection.js new file mode 100644 index 000000000..6f7655f39 --- /dev/null +++ b/jgclark.Filer/src/newNoteFromSelection.js @@ -0,0 +1,106 @@ +// @ flow +//------------------------------------------------------------------ +// @dwertheimer based on @jgclark's newNote +// Create new note from currently selected text +// and (optionally) leave backlink to it where selection was +import { + showMessage, + showMessageYesNo, + noteOpener, + getUniqueNoteTitle, + chooseFolder, +} from './helpers' + +export async function newNoteFromSelection() { + const version = `0.4.0` + console.log(`Running v${version}`) + const { selectedLinesText, selectedText, selectedParagraphs } = Editor + console.log( + `\nnewNoteFromSelection (running v${version}) ${selectedParagraphs.length} selected:`, + ) + + if (selectedLinesText.length && selectedText !== '') { + // Get title for this note + console.log( + `\t1st Para Type = ${selectedParagraphs[0].type} = "${selectedParagraphs[0].content}"`, + ) + + const isTextContent = + ['title', 'text', 'empty'].indexOf(selectedParagraphs[0].type) >= 0 + const strippedFirstLine = selectedParagraphs[0].content + let title = await CommandBar.showInput( + 'Title of new note ([enter] to use text below)', + strippedFirstLine, + ) + // If user just hit [enter], then use the first line as suggested + if (!title) { + title = strippedFirstLine + if (isTextContent) { + selectedLinesText.shift() + } + } + const movedText = selectedLinesText.join('\n') + const uniqueTitle = getUniqueNoteTitle(title) + if (title !== uniqueTitle) { + await showMessage(`Title exists. Using "${uniqueTitle}" instead`) + title = uniqueTitle + } + const currentFolder = await chooseFolder('Select folder to add note in:') + + if (title) { + // Create new note in the specific folder + const origFile = Editor.note.title || Editor.note.filename // Calendar notes have no title + // const origFileType = Editor.note.type //either "Notes" or "Calendar" + console.log(`\torigFile:${origFile}`) + const filename = (await DataStore.newNote(title, currentFolder)) ?? '' + console.log(`\tnewNote returned Filename:${filename}`) + + const fullPath = `${ + currentFolder !== '/' ? `${currentFolder}/` : '' + }${filename}` + + // This question needs to be here after newNote and before noteOpener + // to force a cache refresh after newNote. This API bug will eventually be fixed. + const iblq = await CommandBar.showOptions( + ['Yes', 'No'], + 'Insert link to new file where selection was?', + ) + + const newNote = await noteOpener(fullPath, 'no leading slash') + + if (newNote) { + console.log(`\tnewNote=${newNote}\n\t${newNote.title}`) + console.log(`\tcontent=${newNote.content}`) + + const insertBackLink = iblq.index === 0 + if (Editor.replaceSelectionWithText) { + // for compatibility, make sure the function exists + if (insertBackLink) { + Editor.replaceSelectionWithText(`[[${title}]]`) + } else { + Editor.replaceSelectionWithText(``) + } + } + + newNote.appendParagraph(movedText, 'empty') + if (insertBackLink) { + newNote.appendParagraph(`^^^ Moved from [[${origFile}]]:`, 'text') + } + if ( + (await showMessageYesNo('New Note created. Open it now?')) === 'Yes' + ) { + await Editor.openNoteByFilename(fullPath) + } + } else { + console.log(`\tCould not open file: "${fullPath}"`) + showMessage(`\tCould not open file ${fullPath}`) + } + } else { + console.log('\tError: undefined or empty title') + } + } else { + showMessage('No text was selected. Nothing to do.', "OK, I'll try again!") + } + console.log('\nnewNoteFromSelection (finished)') +} +globalThis.newNoteFromSelection = newNoteFromSelection diff --git a/jgclark.NoteHelpers/README.md b/jgclark.NoteHelpers/README.md index 7b9030ae0..f8bc6a423 100644 --- a/jgclark.NoteHelpers/README.md +++ b/jgclark.NoteHelpers/README.md @@ -20,8 +20,8 @@ Templates should normally end with a linefeed character (`\n`). ## History -### v0.9.2, 13.6.2021 -- change: write text offscreen and ask user if they want to open newly created file +### v0.9.3, 15.6.2021 +- change: moved /nns (which was temporarily here) to Filer and cleaned up here ### v0.9.0, 12.6.2021 - [add]: **/nns** command to add a new note from selection (and leave link to it in its place) (@dwertheimer) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 71f053835..1c27e26ce 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -2,8 +2,7 @@ //-------------------------------------------------------------------------------------------------------------------- // Note Helpers plugin for NotePlan // Jonathan Clark & Eduard Metzger -// /nns by @dwertheimer -// v0.9.2, 1.6.2021 +// v0.9.3, 1.6.2021 //-------------------------------------------------------------------------------------------------------------------- // Globals @@ -60,30 +59,7 @@ async function selectFolder() { } globalThis.selectFolder = selectFolder -// Show feedback message using Command Bar (@dwertheimer) -async function showMessage(message, confirmTitle = 'OK') { - return await CommandBar.showOptions([confirmTitle], message) -} - -// Show feedback Yes/No Question via Command Bar (@dwertheimer) -async function showMessageYesNo(message, choicesArray = ['Yes', 'No']) { - const answer = await CommandBar.showOptions(choicesArray, message) - return choicesArray[answer.index] -} - -// Find a unique note title/filename so backlinks can work properly (@dwertheimer) -function getUniqueNoteTitle(title) { - let i = 0, - res = [], - newTitle = title - while (++i === 1 || res.length > 0) { - newTitle = i === 1 ? title : `${title} ${i}` - res = DataStore.projectNoteByTitle(newTitle, true, false) - } - return newTitle -} - -//------------------------------------------------------------------ +//----------------------------------------------------------------- // Command from Eduard to move a note to a different folder function moveNote(selectedFolder) { const { title, filename } = Editor @@ -200,139 +176,3 @@ function setTitleFromYAML() { printNote(Editor.note) } globalThis.setTitleFromYAML = setTitleFromYAML - -// Start Testing/debugging here -async function noteOpener(fullPath, desc, useProjNoteByFilename = true) { - console.log( - `\tAbout to open filename: "${fullPath}" (${desc}) using ${ - useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' - }`, - ) - const newNote = (await useProjNoteByFilename) - ? DataStore.projectNoteByFilename(fullPath) - : DataStore.noteByFilename(fullPath, 'Notes') - if (newNote) { - console.log(`\t\tWorked! ${fullPath} (${desc} version) `) - } else { - console.log( - `\t\tDidn't work! ${ - useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' - } returned ${newNote}`, - ) - } - return newNote -} - -//------------------------------------------------------------------ -// @dwertheimer based on @jgclark's newNote -// Create new note from currently selected text -// and (optionally) leave backlink to it where selection was -async function newNoteFromSelection() { - const version = `0.9.2` - console.log(`Running v${version}`) - const { selectedLinesText, selectedText, selectedParagraphs } = Editor - console.log( - `\nnewNoteFromSelection (running v${version}) ${selectedParagraphs.length} selected:`, - ) - let currentFolder = '' - - if (selectedLinesText.length && selectedText !== '') { - // Get title for this note - console.log( - `\t1st Para Type = ${selectedParagraphs[0].type} = "${selectedParagraphs[0].content}"`, - ) - // const stripHashes = /^\s*(#)* *(.*)/ - // const firstLineArray = stripHashes.exec(selectedLinesText[0]) - // const strippedFirstLine = - // firstLineArray.length === 3 ? firstLineArray[2] : '' - - const isTextContent = - ['title', 'text', 'empty'].indexOf(selectedParagraphs[0].type) >= 0 - const strippedFirstLine = selectedParagraphs[0].content - let title = await CommandBar.showInput( - 'Title of new note ([enter] to use text below)', - strippedFirstLine, - ) - // If user just hit [enter], then use the first line as suggested - if (!title) { - title = strippedFirstLine - if (isTextContent) { - selectedLinesText.shift() - } - } - const movedText = selectedLinesText.join('\n') - const uniqueTitle = getUniqueNoteTitle(title) - if (title !== uniqueTitle) { - await showMessage(`Title exists. Using "${uniqueTitle}" instead`) - title = uniqueTitle - } - const folders = DataStore.folders // excludes Trash and Archive - if (folders.length > 0) { - const re = await CommandBar.showOptions( - folders, - 'Select folder to add note in:', - ) - currentFolder = folders[re.index] - } else { - // no Folders so go to root - currentFolder = '/' - } - console.log(`\tcurrentFolder=${currentFolder}`) - - if (title) { - // Create new note in the specific folder - const origFile = Editor.note.title || Editor.note.filename // Calendar notes have no title - // const origFileType = Editor.note.type //either "Notes" or "Calendar" - console.log(`\torigFile:${origFile}`) - const filename = (await DataStore.newNote(title, currentFolder)) ?? '' - console.log(`\tnewNote returned Filename:${filename}`) - - const fullPath = `${ - currentFolder !== '/' ? `${currentFolder}/` : '' - }${filename}` - - // This question needs to be here after newNote and before noteOpener - // to force a cache refresh after newNote. This API bug will eventually be fixed. - const iblq = await CommandBar.showOptions( - ['Yes', 'No'], - 'Insert link to new file where selection was?', - ) - - const newNote = await noteOpener(fullPath, 'no leading slash') - - if (newNote) { - console.log(`\tnewNote=${newNote}\n\t${newNote.title}`) - console.log(`\tcontent=${newNote.content}`) - - const insertBackLink = iblq.index === 0 - if (Editor.replaceSelectionWithText) { - // for compatibility, make sure the function exists - if (insertBackLink) { - Editor.replaceSelectionWithText(`[[${title}]]`) - } else { - Editor.replaceSelectionWithText(``) - } - } - - newNote.appendParagraph(movedText, 'empty') - if (insertBackLink) { - newNote.appendParagraph(`^^^ Moved from [[${origFile}]]:`, 'text') - } - if ( - (await showMessageYesNo('New Note created. Open it now?')) === 'Yes' - ) { - await Editor.openNoteByFilename(fullPath) - } - } else { - console.log(`\tCould not open file: "${fullPath}"`) - showMessage(`\tCould not open file ${fullPath}`) - } - } else { - console.log('\tError: undefined or empty title') - } - } else { - showMessage('No text was selected. Nothing to do.', "OK, I'll try again!") - } - console.log('\nnewNoteFromSelection (finished)') -} -globalThis.newNoteFromSelection = newNoteFromSelection diff --git a/jgclark.NoteHelpers/plugin.json b/jgclark.NoteHelpers/plugin.json index affe2af65..284da7af8 100644 --- a/jgclark.NoteHelpers/plugin.json +++ b/jgclark.NoteHelpers/plugin.json @@ -6,7 +6,7 @@ "plugin.icon": "", "plugin.author": "Jonathan Clark & Eduard Metzger", "plugin.url": "https://github.com/NotePlan/plugins/tree/main/jgclark.NoteHelpers/", - "plugin.version": "0.9.2", + "plugin.version": "0.9.3", "plugin.changelog": "See plugin README.md", "plugin.dependencies": [], "plugin.script": "noteHelpers.js", @@ -27,11 +27,6 @@ "description": "Jump to the ## Done section. (Currently only works in main window.)", "jsFunction": "jumpToDone" }, - { - "name": "nns", - "description": "New note from selection (and leave link to it in its place)", - "jsFunction": "newNoteFromSelection" - } ], "plugin.preferences": [ ] From 2bdc2e90b9dba15a3ee7ee4520fc29249c8209e9 Mon Sep 17 00:00:00 2001 From: Jonathan Clark Date: Tue, 15 Jun 2021 10:20:35 +0100 Subject: [PATCH 13/14] Tweaks ready to commit --- jgclark.Filer/script.js | 6 +++--- jgclark.Filer/src/fileItems.js | 8 +++----- jgclark.Filer/src/helpers.js | 15 ++++++++++----- jgclark.Filer/src/newNoteFromSelection.js | 2 +- jgclark.NoteHelpers/README.md | 4 ++-- jgclark.NoteHelpers/noteHelpers.js | 6 +++--- jgclark.NoteHelpers/plugin.json | 2 +- 7 files changed, 23 insertions(+), 20 deletions(-) diff --git a/jgclark.Filer/script.js b/jgclark.Filer/script.js index b59f96601..9a2f6769e 100644 --- a/jgclark.Filer/script.js +++ b/jgclark.Filer/script.js @@ -43,7 +43,7 @@ var exports = (function (exports) { } } // Print out all data for a paragraph (borrowed from EM) - // @ flow + // ----------------------------------------------------------------------------- // Helper Functions // Return list of all notes, sorted by changed date (newest to oldest) @@ -250,7 +250,7 @@ var exports = (function (exports) { console.log(` Remove original para # ${i}`); note.removeParagraphAtIndex(i); } - } // globalThis.fileParas = fileParas + } //------------------------------------------------------------------ @@ -304,7 +304,7 @@ var exports = (function (exports) { return currentFolder; } - // @ flow + //------------------------------------------------------------------ async function newNoteFromSelection() { const version = `0.4.0`; console.log(`Running v${version}`); diff --git a/jgclark.Filer/src/fileItems.js b/jgclark.Filer/src/fileItems.js index 12b619201..da18fbdfc 100644 --- a/jgclark.Filer/src/fileItems.js +++ b/jgclark.Filer/src/fileItems.js @@ -1,4 +1,4 @@ -// @ flow +// @flow // ----------------------------------------------------------------------------- // Plugin to help move selected paragraphs to other notes // Jonathan Clark @@ -17,7 +17,7 @@ const pref_addDateBacklink = true // Helper Functions // Return list of all notes, sorted by changed date (newest to oldest) -function allNotesSortedByChanged() { +function allNotesSortedByChanged():Array { const projectNotes = DataStore.projectNotes.slice() const calendarNotes = DataStore.calendarNotes.slice() const allNotes = projectNotes.concat(calendarNotes) @@ -28,7 +28,7 @@ function allNotesSortedByChanged() { } // Convert paragraph(s) to single raw text string -function parasToText(paras) { +function parasToText(paras:Array):string { // console.log('parasToText: starting with ' + paras.length + ' paragraphs') let text = '' for (let i = 0; i < paras.length; i++) { @@ -213,5 +213,3 @@ export async function fileParas() { note.removeParagraphAtIndex(i) } } - -// globalThis.fileParas = fileParas diff --git a/jgclark.Filer/src/helpers.js b/jgclark.Filer/src/helpers.js index 73fdf1499..cd081352b 100644 --- a/jgclark.Filer/src/helpers.js +++ b/jgclark.Filer/src/helpers.js @@ -1,3 +1,5 @@ +// @flow + //------------------------------------------------------------------ // Helper functions //------------------------------------------------------------------ @@ -29,17 +31,20 @@ export function printNote(note) { } // Show feedback message using Command Bar (@dwertheimer) -export async function showMessage(message, confirmTitle = 'OK') { +export async function showMessage(message:string, confirmTitle:string = 'OK') { return await CommandBar.showOptions([confirmTitle], message) } // Show feedback Yes/No Question via Command Bar (@dwertheimer) -export async function showMessageYesNo(message, choicesArray = ['Yes', 'No']) { +export async function showMessageYesNo(message:string, choicesArray:Array = ['Yes', 'No']):Promise { const answer = await CommandBar.showOptions(choicesArray, message) return choicesArray[answer.index] } -export async function noteOpener(fullPath, desc, useProjNoteByFilename = true) { +export async function noteOpener( + fullPath: string, + desc: string, + useProjNoteByFilename: boolean = true): Promise { console.log( `\tAbout to open filename: "${fullPath}" (${desc}) using ${ useProjNoteByFilename ? 'projectNoteByFilename' : 'noteByFilename' @@ -62,7 +67,7 @@ export async function noteOpener(fullPath, desc, useProjNoteByFilename = true) { // Find a unique note title/filename so backlinks can work properly (@dwertheimer) // Keep adding numbers to the end of a filename (if already taken) until it works -export function getUniqueNoteTitle(title) { +export function getUniqueNoteTitle(title:string):string { let i = 0, res = [], newTitle = title @@ -73,7 +78,7 @@ export function getUniqueNoteTitle(title) { return newTitle } -export async function chooseFolder(msg) { +export async function chooseFolder(msg:string):Promise { let currentFolder const folders = DataStore.folders // excludes Trash and Archive if (folders.length > 0) { diff --git a/jgclark.Filer/src/newNoteFromSelection.js b/jgclark.Filer/src/newNoteFromSelection.js index 6f7655f39..698a37fa4 100644 --- a/jgclark.Filer/src/newNoteFromSelection.js +++ b/jgclark.Filer/src/newNoteFromSelection.js @@ -1,4 +1,4 @@ -// @ flow +// @flow //------------------------------------------------------------------ // @dwertheimer based on @jgclark's newNote // Create new note from currently selected text diff --git a/jgclark.NoteHelpers/README.md b/jgclark.NoteHelpers/README.md index f8bc6a423..efee9ff27 100644 --- a/jgclark.NoteHelpers/README.md +++ b/jgclark.NoteHelpers/README.md @@ -20,8 +20,8 @@ Templates should normally end with a linefeed character (`\n`). ## History -### v0.9.3, 15.6.2021 -- change: moved /nns (which was temporarily here) to Filer and cleaned up here +### v0.9.3, 15.6.2021 (@dwertheimer) +- change: moved **/nns** (which was temporarily here) to Filer and cleaned up here ### v0.9.0, 12.6.2021 - [add]: **/nns** command to add a new note from selection (and leave link to it in its place) (@dwertheimer) diff --git a/jgclark.NoteHelpers/noteHelpers.js b/jgclark.NoteHelpers/noteHelpers.js index 1c27e26ce..35491663a 100644 --- a/jgclark.NoteHelpers/noteHelpers.js +++ b/jgclark.NoteHelpers/noteHelpers.js @@ -1,4 +1,4 @@ -// @ flow +// @flow //-------------------------------------------------------------------------------------------------------------------- // Note Helpers plugin for NotePlan // Jonathan Clark & Eduard Metzger @@ -141,7 +141,7 @@ globalThis.jumpToDone = jumpToDone //------------------------------------------------------------------ // Set the title of a note from YAML, rather than the first line. -// NOTE: not currently working because of lack of API support yet (as of release 628) +// NOTE: not currently working because of lack of API support yet (as of release 636) // TODO: add following back into plugin.json to active this again: // { // "name": "Set title from YAML", @@ -171,7 +171,7 @@ function setTitleFromYAML() { } console.log(`\tnew title = ${newTitle}`) if (newTitle !== '') { - note.title = newTitle // TODO: setter not available not yet available (last checked on release 628) + note.title = newTitle // TODO: when setter available } printNote(Editor.note) } diff --git a/jgclark.NoteHelpers/plugin.json b/jgclark.NoteHelpers/plugin.json index 284da7af8..3bf6521c3 100644 --- a/jgclark.NoteHelpers/plugin.json +++ b/jgclark.NoteHelpers/plugin.json @@ -26,7 +26,7 @@ "name": "jd", "description": "Jump to the ## Done section. (Currently only works in main window.)", "jsFunction": "jumpToDone" - }, + } ], "plugin.preferences": [ ] From c5818fce81436d43c6ce58ae8d3df92b4d4be8ef Mon Sep 17 00:00:00 2001 From: Jonathan Clark Date: Tue, 15 Jun 2021 10:22:54 +0100 Subject: [PATCH 14/14] We missed README update --- jgclark.NoteHelpers/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/jgclark.NoteHelpers/README.md b/jgclark.NoteHelpers/README.md index efee9ff27..054a0529d 100644 --- a/jgclark.NoteHelpers/README.md +++ b/jgclark.NoteHelpers/README.md @@ -3,7 +3,6 @@ This plugin provides commands to help work with NotePlan notes: - `/mn`: which moves a note to a different folder the user selects - `/jh`: jumps the cursor to the heading of the current note that the user selects - `/jd`: simply jumps the cursor to the `## Done` section of the current note (if it exists) -- `/nns`: create a new note from selection (and leave link to it in its place) ## Configuration Before the configuration mechanism is available, you need to update the `jgclark.noteHelpers\noteHelpers.js` file in the plugin's folder directly. Update the following lines at the top of the file accordingly: