Minor changes on CLI

pull/41/head
Laurent Cozic 2017-07-17 18:46:09 +00:00
parent 6673baee91
commit 15e95bb0ab
9 changed files with 2181 additions and 23 deletions

View File

@ -329,7 +329,7 @@ class Application {
if (!this.currentFolder_) this.currentFolder_ = await Folder.defaultFolder(); if (!this.currentFolder_) this.currentFolder_ = await Folder.defaultFolder();
Setting.setValue('activeFolderId', this.currentFolder_ ? this.currentFolder_.id : ''); Setting.setValue('activeFolderId', this.currentFolder_ ? this.currentFolder_.id : '');
if (this.currentFolder_) await this.vorpal().exec('use ' + this.currentFolder_.title); if (this.currentFolder_) await this.vorpal().exec('use ' + this.escapeShellArg(this.currentFolder_.title));
// If we still have arguments, pass it to Vorpal and exit // If we still have arguments, pass it to Vorpal and exit
if (argv.length) { if (argv.length) {

View File

@ -20,21 +20,20 @@ function autocompleteFolders() {
}); });
} }
function autocompleteItems() { async function autocompleteItems() {
let promise = null; let items = [];
if (!app().currentFolder()) { if (!app().currentFolder()) {
promise = Folder.all(); items = await Folder.all();
} else { } else {
promise = Note.previews(app().currentFolder().id); items = await Note.previews(app().currentFolder().id);
} }
return promise.then((items) => { let output = [];
let output = []; for (let i = 0; i < items.length; i++) {
for (let i = 0; i < items.length; i++) { output.push(quotePromptArg(items[i].title));
output.push(quotePromptArg(items[i].title)); }
}
return output; return output;
});
} }
export { autocompleteFolders, autocompleteItems }; export { autocompleteFolders, autocompleteItems };

View File

@ -1,6 +1,7 @@
import { BaseCommand } from './base-command.js'; import { BaseCommand } from './base-command.js';
import { app } from './app.js'; import { app } from './app.js';
import { _ } from 'lib/locale.js'; import { _ } from 'lib/locale.js';
import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js'; import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js'; import { Note } from 'lib/models/note.js';
import { autocompleteFolders } from './autocomplete.js'; import { autocompleteFolders } from './autocomplete.js';
@ -25,7 +26,7 @@ class Command extends BaseCommand {
['-r, --reverse', 'Reverses the sorting order.'], ['-r, --reverse', 'Reverses the sorting order.'],
['-t, --type <type>', 'Displays only the items of the specific type(s). Can be `n` for notes, `t` for todos, or `nt` for notes and todos (eg. `-tt` would display only the todos, while `-ttd` would display notes and todos.'], ['-t, --type <type>', 'Displays only the items of the specific type(s). Can be `n` for notes, `t` for todos, or `nt` for notes and todos (eg. `-tt` would display only the todos, while `-ttd` would display notes and todos.'],
['-f, --format <format>', 'Either "text" or "json"'], ['-f, --format <format>', 'Either "text" or "json"'],
['-l, --long', 'Use long list format. Format is NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for todos), TITLE'], ['-l, --long', 'Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for todos), TITLE'],
]; ];
} }
@ -80,11 +81,15 @@ class Command extends BaseCommand {
let seenTitles = []; let seenTitles = [];
let rows = []; let rows = [];
let shortIdShown = false;
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
let item = items[i]; let item = items[i];
let row = []; let row = [];
if (options.long) { if (options.long) {
row.push(BaseModel.shortId(item.id));
shortIdShown = true;
if (modelType == Folder.modelType()) { if (modelType == Folder.modelType()) {
row.push(await Folder.noteCount(item.id)); row.push(await Folder.noteCount(item.id));
} }
@ -93,8 +98,8 @@ class Command extends BaseCommand {
} }
let title = item.title + suffix; let title = item.title + suffix;
if (seenTitles.indexOf(item.title) >= 0 || !item.title) { if (!shortIdShown && (seenTitles.indexOf(item.title) >= 0 || !item.title)) {
title += ' (' + item.id.substr(0,4) + ')'; title += ' (' + BaseModel.shortId(item.id) + ')';
} else { } else {
seenTitles.push(item.title); seenTitles.push(item.title);
} }

View File

@ -13,10 +13,6 @@ class Command extends BaseCommand {
return 'Creates a new note.'; return 'Creates a new note.';
} }
aliases() {
return ['touch'];
}
async action(args) { async action(args) {
if (!app().currentFolder()) throw new Error(_('Notes can only be created within a notebook.')); if (!app().currentFolder()) throw new Error(_('Notes can only be created within a notebook.'));

View File

@ -40,6 +40,7 @@ class Command extends BaseCommand {
const ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('Delete notebook "%s"?', folder.title)); const ok = force ? true : await vorpalUtils.cmdPromptConfirm(this, _('Delete notebook "%s"?', folder.title));
if (!ok) return; if (!ok) return;
await Folder.delete(folder.id); await Folder.delete(folder.id);
await app().refreshCurrentFolder();
} else { } else {
const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern); const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
if (!notes.length) throw new Error(_('No note matchin pattern "%s"', pattern)); if (!notes.length) throw new Error(_('No note matchin pattern "%s"', pattern));

View File

@ -7,6 +7,11 @@ import { vorpalUtils } from './vorpal-utils.js';
class Command extends BaseCommand { class Command extends BaseCommand {
constructor() {
super();
this.syncTarget_ = null;
}
usage() { usage() {
return 'sync'; return 'sync';
} }
@ -17,12 +22,16 @@ class Command extends BaseCommand {
options() { options() {
return [ return [
['--target <target>', 'Sync to provided target (defaults to sync.target config value)'],
['--random-failures', 'For debugging purposes. Do not use.'], ['--random-failures', 'For debugging purposes. Do not use.'],
]; ];
} }
async action(args) { async action(args) {
let sync = await app().synchronizer(Setting.value('sync.target')); this.syncTarget_ = Setting.value('sync.target');
if (args.options.target) this.syncTarget_ = args.options.target;
let sync = await app().synchronizer(this.syncTarget_);
let options = { let options = {
onProgress: (report) => { onProgress: (report) => {
@ -36,7 +45,7 @@ class Command extends BaseCommand {
randomFailures: args.options['random-failures'] === true, randomFailures: args.options['random-failures'] === true,
}; };
this.log(_('Synchronization target: %s', Setting.value('sync.target'))); this.log(_('Synchronization target: %s', this.syncTarget_));
if (!sync) throw new Error(_('Cannot initialize synchronizer.')); if (!sync) throw new Error(_('Cannot initialize synchronizer.'));
@ -51,10 +60,14 @@ class Command extends BaseCommand {
} }
async cancel() { async cancel() {
const target = this.syncTarget_ ? this.syncTarget_ : Setting.value('sync.target');
vorpalUtils.redrawDone(); vorpalUtils.redrawDone();
this.log(_('Cancelling...')); this.log(_('Cancelling...'));
let sync = await app().synchronizer(Setting.value('sync.target')); let sync = await app().synchronizer(target);
sync.cancel(); sync.cancel();
this.syncTarget_ = null;
} }
} }

View File

@ -8,4 +8,5 @@ cp "$CLIENT_DIR/package.json" "$CLIENT_DIR/build"
# Always keep this as the last line so that the exit # Always keep this as the last line so that the exit
# code of build.sh is the same as the build command: # code of build.sh is the same as the build command:
npm run build #npm run build
yarn run build

2139
CliClient/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -102,6 +102,10 @@ class BaseModel {
return this.loadByField('id', id); return this.loadByField('id', id);
} }
static shortId(id) {
return id.substr(0, 4);
}
static loadByPartialId(partialId) { static loadByPartialId(partialId) {
return this.modelSelectOne('SELECT * FROM `' + this.tableName() + '` WHERE `id` LIKE ?', [partialId + '%']); return this.modelSelectOne('SELECT * FROM `' + this.tableName() + '` WHERE `id` LIKE ?', [partialId + '%']);
} }