From b5b281c2768205329433f4079b9d32b7d9314948 Mon Sep 17 00:00:00 2001 From: Andrej Lifinzew Date: Mon, 5 Sep 2022 13:37:51 +0200 Subject: [PATCH] CLI: Resolves #1728: Toggle short ids and mv notebooks (#6671) --- packages/app-cli/app/app-gui.js | 7 ++++ packages/app-cli/app/app.js | 1 + packages/app-cli/app/command-mv.js | 38 +++++++++++++++----- packages/app-cli/app/gui/FolderListWidget.js | 14 +++++++- packages/app-cli/app/gui/NoteListWidget.js | 11 +++++- 5 files changed, 60 insertions(+), 11 deletions(-) diff --git a/packages/app-cli/app/app-gui.js b/packages/app-cli/app/app-gui.js index 5a8903e23..e475e127e 100644 --- a/packages/app-cli/app/app-gui.js +++ b/packages/app-cli/app/app-gui.js @@ -375,6 +375,11 @@ class AppGui { this.showNoteMetadata(!this.widget('noteMetadata').shown); } + toggleFolderIds() { + this.widget('folderList').toggleShowIds(); + this.widget('noteList').toggleShowIds(); + } + widget(name) { if (name === 'root') return this.rootWidget_; return this.rootWidget_.childByName(name); @@ -498,6 +503,8 @@ class AppGui { } } else if (cmd === 'toggle_metadata') { this.toggleNoteMetadata(); + } else if (cmd === 'toggle_ids') { + this.toggleFolderIds(); } else if (cmd === 'enter_command_line_mode') { const cmd = await this.widget('statusBar').prompt(); if (!cmd) return; diff --git a/packages/app-cli/app/app.js b/packages/app-cli/app/app.js index 444f635be..6f6824fcf 100644 --- a/packages/app-cli/app/app.js +++ b/packages/app-cli/app/app.js @@ -332,6 +332,7 @@ class Application extends BaseApplication { { keys: [' '], command: 'todo toggle $n' }, { keys: ['tc'], type: 'function', command: 'toggle_console' }, { keys: ['tm'], type: 'function', command: 'toggle_metadata' }, + { keys: ['ti'], type: 'function', command: 'toggle_ids' }, { keys: ['/'], type: 'prompt', command: 'search ""', cursorPosition: -2 }, { keys: ['mn'], type: 'prompt', command: 'mknote ""', cursorPosition: -2 }, { keys: ['mt'], type: 'prompt', command: 'mktodo ""', cursorPosition: -2 }, diff --git a/packages/app-cli/app/command-mv.js b/packages/app-cli/app/command-mv.js index 4879e38f8..c7a34085c 100644 --- a/packages/app-cli/app/command-mv.js +++ b/packages/app-cli/app/command-mv.js @@ -7,25 +7,45 @@ const Note = require('@joplin/lib/models/Note').default; class Command extends BaseCommand { usage() { - return 'mv [notebook]'; + return 'mv [notebook]'; } description() { - return _('Moves the notes matching to [notebook].'); + return _('Moves the given (notes matching pattern in current notebook or one notebook) to [notebook]. If is subnotebook and [notebook] is "root", will make parent notebook'); } async action(args) { - const pattern = args['note']; + const pattern = args['item']; const destination = args['notebook']; + let folder = null; - const folder = await Folder.loadByField('title', destination); - if (!folder) throw new Error(_('Cannot find "%s".', destination)); + if (destination !== 'root') { + folder = await app().loadItem(BaseModel.TYPE_FOLDER, destination); + if (!folder) throw new Error(_('Cannot find "%s".', destination)); + } - const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern); - if (!notes.length) throw new Error(_('Cannot find "%s".', pattern)); + const destinationDuplicates = await Folder.search({ titlePattern: destination, limit: 2 }); + if (destinationDuplicates.length > 1) { + throw new Error(_('Ambiguous notebook "%s". Please use short notebook id instead - press "ti" to see the short notebook id' , destination)); + } - for (let i = 0; i < notes.length; i++) { - await Note.moveToFolder(notes[i].id, folder.id); + const itemFolder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern); + if (itemFolder) { + const sourceDuplicates = await Folder.search({ titlePattern: pattern, limit: 2 }); + if (sourceDuplicates.length > 1) { + throw new Error(_('Ambiguous notebook "%s". Please use notebook id instead - press "ti" to see the short notebook id or use $b for current selected notebook', pattern)); + } + if (destination === 'root') { + await Folder.moveToFolder(itemFolder.id, ''); + } else { + await Folder.moveToFolder(itemFolder.id, folder.id); + } + } else { + const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern); + if (notes.length === 0) throw new Error(_('Cannot find "%s".', pattern)); + for (let i = 0; i < notes.length; i++) { + await Note.moveToFolder(notes[i].id, folder.id); + } } } } diff --git a/packages/app-cli/app/gui/FolderListWidget.js b/packages/app-cli/app/gui/FolderListWidget.js index 9db40e94e..c9a694a26 100644 --- a/packages/app-cli/app/gui/FolderListWidget.js +++ b/packages/app-cli/app/gui/FolderListWidget.js @@ -19,13 +19,20 @@ class FolderListWidget extends ListWidget { this.updateIndexFromSelectedFolderId_ = false; this.updateItems_ = false; this.trimItemTitle = false; + this.showIds = false; this.itemRenderer = item => { const output = []; if (item === '-') { output.push('-'.repeat(this.innerWidth)); } else if (item.type_ === Folder.modelType()) { - output.push(' '.repeat(this.folderDepth(this.folders, item.id)) + Folder.displayTitle(item)); + output.push(' '.repeat(this.folderDepth(this.folders, item.id))); + + if (this.showIds) { + output.push(Folder.shortId(item.id)); + } + output.push(Folder.displayTitle(item)); + if (Setting.value('showNoteCounts')) { let noteCount = item.note_count; // Subtract children note_count from parent folder. @@ -132,6 +139,11 @@ class FolderListWidget extends ListWidget { this.invalidate(); } + toggleShowIds() { + this.showIds = !this.showIds; + this.invalidate(); + } + folderHasChildren_(folders, folderId) { for (let i = 0; i < folders.length; i++) { const folder = folders[i]; diff --git a/packages/app-cli/app/gui/NoteListWidget.js b/packages/app-cli/app/gui/NoteListWidget.js index 2d2166613..f8f1cfd6b 100644 --- a/packages/app-cli/app/gui/NoteListWidget.js +++ b/packages/app-cli/app/gui/NoteListWidget.js @@ -5,11 +5,15 @@ class NoteListWidget extends ListWidget { constructor() { super(); this.selectedNoteId_ = 0; + this.showIds = false; this.updateIndexFromSelectedNoteId_ = false; this.itemRenderer = note => { - let label = Note.displayTitle(note); // + ' ' + note.id; + let label = Note.displayTitle(note); + if (this.showIds) { + label = `${Note.shortId(note.id)} ${Note.displayTitle(note)}`; + } if (note.is_todo) { label = `[${note.todo_completed ? 'X' : ' '}] ${label}`; } @@ -22,6 +26,11 @@ class NoteListWidget extends ListWidget { this.selectedNoteId_ = v; } + toggleShowIds() { + this.showIds = !this.showIds; + this.invalidate(); + } + render() { if (this.updateIndexFromSelectedNoteId_) { const index = this.itemIndexByKey('id', this.selectedNoteId_);