Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions jgclark.Filer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion jgclark.Filer/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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": [
Expand Down
143 changes: 142 additions & 1 deletion jgclark.Filer/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,150 @@ var exports = (function (exports) {
console.log(` Remove original para # ${i}`);
note.removeParagraphAtIndex(i);
}
} // 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;
}

//------------------------------------------------------------------
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 });

Expand Down
19 changes: 10 additions & 9 deletions jgclark.Filer/src/fileItems.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// @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
Expand All @@ -14,18 +17,18 @@ const pref_addDateBacklink = true
// Helper Functions

// Return list of all notes, sorted by changed date (newest to oldest)
function allNotesSortedByChanged() {
function allNotesSortedByChanged():Array<TNote> {
const projectNotes = DataStore.projectNotes.slice()
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
}

// Convert paragraph(s) to single raw text string
function parasToText(paras) {
function parasToText(paras:Array<TParagraph>):string {
// console.log('parasToText: starting with ' + paras.length + ' paragraphs')
let text = ''
for (let i = 0; i < paras.length; i++) {
Expand Down Expand Up @@ -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`)
}
}

Expand Down Expand Up @@ -210,5 +213,3 @@ export async function fileParas() {
note.removeParagraphAtIndex(i)
}
}

// globalThis.fileParas = fileParas
93 changes: 93 additions & 0 deletions jgclark.Filer/src/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// @flow

//------------------------------------------------------------------
// 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:string, confirmTitle:string = 'OK') {
return await CommandBar.showOptions([confirmTitle], message)
}

// Show feedback Yes/No Question via Command Bar (@dwertheimer)
export async function showMessageYesNo(message:string, choicesArray:Array<string> = ['Yes', 'No']):Promise<string> {
const answer = await CommandBar.showOptions(choicesArray, message)
return choicesArray[answer.index]
}

export async function noteOpener(
fullPath: string,
desc: string,
useProjNoteByFilename: boolean = true): Promise<TNote> {
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:string):string {
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:string):Promise<string> {
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
}
3 changes: 2 additions & 1 deletion jgclark.Filer/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Loading