CLI: Resolves #1728: Toggle short ids and mv notebooks (#6671)

pull/6823/head
Andrej Lifinzew 2022-09-05 13:37:51 +02:00 committed by GitHub
parent 80906cbdb3
commit b5b281c276
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 11 deletions

View File

@ -375,6 +375,11 @@ class AppGui {
this.showNoteMetadata(!this.widget('noteMetadata').shown); this.showNoteMetadata(!this.widget('noteMetadata').shown);
} }
toggleFolderIds() {
this.widget('folderList').toggleShowIds();
this.widget('noteList').toggleShowIds();
}
widget(name) { widget(name) {
if (name === 'root') return this.rootWidget_; if (name === 'root') return this.rootWidget_;
return this.rootWidget_.childByName(name); return this.rootWidget_.childByName(name);
@ -498,6 +503,8 @@ class AppGui {
} }
} else if (cmd === 'toggle_metadata') { } else if (cmd === 'toggle_metadata') {
this.toggleNoteMetadata(); this.toggleNoteMetadata();
} else if (cmd === 'toggle_ids') {
this.toggleFolderIds();
} else if (cmd === 'enter_command_line_mode') { } else if (cmd === 'enter_command_line_mode') {
const cmd = await this.widget('statusBar').prompt(); const cmd = await this.widget('statusBar').prompt();
if (!cmd) return; if (!cmd) return;

View File

@ -332,6 +332,7 @@ class Application extends BaseApplication {
{ keys: [' '], command: 'todo toggle $n' }, { keys: [' '], command: 'todo toggle $n' },
{ keys: ['tc'], type: 'function', command: 'toggle_console' }, { keys: ['tc'], type: 'function', command: 'toggle_console' },
{ keys: ['tm'], type: 'function', command: 'toggle_metadata' }, { keys: ['tm'], type: 'function', command: 'toggle_metadata' },
{ keys: ['ti'], type: 'function', command: 'toggle_ids' },
{ keys: ['/'], type: 'prompt', command: 'search ""', cursorPosition: -2 }, { keys: ['/'], type: 'prompt', command: 'search ""', cursorPosition: -2 },
{ keys: ['mn'], type: 'prompt', command: 'mknote ""', cursorPosition: -2 }, { keys: ['mn'], type: 'prompt', command: 'mknote ""', cursorPosition: -2 },
{ keys: ['mt'], type: 'prompt', command: 'mktodo ""', cursorPosition: -2 }, { keys: ['mt'], type: 'prompt', command: 'mktodo ""', cursorPosition: -2 },

View File

@ -7,25 +7,45 @@ const Note = require('@joplin/lib/models/Note').default;
class Command extends BaseCommand { class Command extends BaseCommand {
usage() { usage() {
return 'mv <note> [notebook]'; return 'mv <item> [notebook]';
} }
description() { description() {
return _('Moves the notes matching <note> to [notebook].'); return _('Moves the given <item> (notes matching pattern in current notebook or one notebook) to [notebook]. If <item> is subnotebook and [notebook] is "root", will make <item> parent notebook');
} }
async action(args) { async action(args) {
const pattern = args['note']; const pattern = args['item'];
const destination = args['notebook']; const destination = args['notebook'];
let folder = null;
const folder = await Folder.loadByField('title', destination); if (destination !== 'root') {
if (!folder) throw new Error(_('Cannot find "%s".', destination)); 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); const destinationDuplicates = await Folder.search({ titlePattern: destination, limit: 2 });
if (!notes.length) throw new Error(_('Cannot find "%s".', pattern)); 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++) { const itemFolder = await app().loadItem(BaseModel.TYPE_FOLDER, pattern);
await Note.moveToFolder(notes[i].id, folder.id); 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);
}
} }
} }
} }

View File

@ -19,13 +19,20 @@ class FolderListWidget extends ListWidget {
this.updateIndexFromSelectedFolderId_ = false; this.updateIndexFromSelectedFolderId_ = false;
this.updateItems_ = false; this.updateItems_ = false;
this.trimItemTitle = false; this.trimItemTitle = false;
this.showIds = false;
this.itemRenderer = item => { this.itemRenderer = item => {
const output = []; const output = [];
if (item === '-') { if (item === '-') {
output.push('-'.repeat(this.innerWidth)); output.push('-'.repeat(this.innerWidth));
} else if (item.type_ === Folder.modelType()) { } 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')) { if (Setting.value('showNoteCounts')) {
let noteCount = item.note_count; let noteCount = item.note_count;
// Subtract children note_count from parent folder. // Subtract children note_count from parent folder.
@ -132,6 +139,11 @@ class FolderListWidget extends ListWidget {
this.invalidate(); this.invalidate();
} }
toggleShowIds() {
this.showIds = !this.showIds;
this.invalidate();
}
folderHasChildren_(folders, folderId) { folderHasChildren_(folders, folderId) {
for (let i = 0; i < folders.length; i++) { for (let i = 0; i < folders.length; i++) {
const folder = folders[i]; const folder = folders[i];

View File

@ -5,11 +5,15 @@ class NoteListWidget extends ListWidget {
constructor() { constructor() {
super(); super();
this.selectedNoteId_ = 0; this.selectedNoteId_ = 0;
this.showIds = false;
this.updateIndexFromSelectedNoteId_ = false; this.updateIndexFromSelectedNoteId_ = false;
this.itemRenderer = note => { 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) { if (note.is_todo) {
label = `[${note.todo_completed ? 'X' : ' '}] ${label}`; label = `[${note.todo_completed ? 'X' : ' '}] ${label}`;
} }
@ -22,6 +26,11 @@ class NoteListWidget extends ListWidget {
this.selectedNoteId_ = v; this.selectedNoteId_ = v;
} }
toggleShowIds() {
this.showIds = !this.showIds;
this.invalidate();
}
render() { render() {
if (this.updateIndexFromSelectedNoteId_) { if (this.updateIndexFromSelectedNoteId_) {
const index = this.itemIndexByKey('id', this.selectedNoteId_); const index = this.itemIndexByKey('id', this.selectedNoteId_);