mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Removed vorpal
This commit is contained in:
parent
60c8b7530b
commit
9ed22265ba
@ -14,7 +14,8 @@ import { _, setLocale, defaultLocale, closestSupportedLocale } from 'lib/locale.
|
||||
import os from 'os';
|
||||
import fs from 'fs-extra';
|
||||
import yargParser from 'yargs-parser';
|
||||
import omelette from 'omelette';
|
||||
import { handleAutocompletion } from './autocompletion.js';
|
||||
import { cliUtils } from './cli-utils.js';
|
||||
|
||||
class Application {
|
||||
|
||||
@ -22,12 +23,11 @@ class Application {
|
||||
this.showPromptString_ = true;
|
||||
this.logger_ = new Logger();
|
||||
this.dbLogger_ = new Logger();
|
||||
this.autocompletion_ = { active: false };
|
||||
this.commands_ = {};
|
||||
this.commandMetadata_ = null;
|
||||
}
|
||||
|
||||
// vorpal() {
|
||||
// return this.vorpal_;
|
||||
// }
|
||||
|
||||
currentFolder() {
|
||||
return this.currentFolder_;
|
||||
}
|
||||
@ -120,12 +120,6 @@ class Application {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if (arg == '--redraw-disabled') {
|
||||
// vorpalUtils.setRedrawEnabled(false);
|
||||
// argv.splice(0, 1);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (arg == '--update-geolocation-disabled') {
|
||||
Note.updateGeolocationEnabled_ = false;
|
||||
argv.splice(0, 1);
|
||||
@ -151,6 +145,34 @@ class Application {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--autocompletion') {
|
||||
this.autocompletion_.active = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--autocompletion') {
|
||||
this.autocompletion_.active = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--ac-current') {
|
||||
if (!nextArg) throw new Error(_('Usage: %s', '--ac-current <num>'));
|
||||
this.autocompletion_.current = nextArg;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg == '--ac-line') {
|
||||
if (!nextArg) throw new Error(_('Usage: %s', '--ac-line <line>'));
|
||||
let line = nextArg.replace(/\|__QUOTE__\|/g, '"');
|
||||
line = line.split('|__SEP__|');
|
||||
this.autocompletion_.line = line;
|
||||
argv.splice(0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.length && arg[0] == '-') {
|
||||
throw new Error(_('Unknown flag: %s', arg));
|
||||
} else {
|
||||
@ -199,63 +221,6 @@ class Application {
|
||||
}
|
||||
}
|
||||
|
||||
loadCommands_() {
|
||||
return;
|
||||
|
||||
this.onLocaleChanged(); // Ensures that help and exit commands are translated
|
||||
|
||||
fs.readdirSync(__dirname).forEach((path) => {
|
||||
if (path.indexOf('command-') !== 0) return;
|
||||
const ext = fileExtension(path)
|
||||
if (ext != 'js') return;
|
||||
|
||||
let CommandClass = require('./' + path);
|
||||
let cmd = new CommandClass();
|
||||
if (!cmd.enabled()) return;
|
||||
|
||||
let vorpalCmd = this.vorpal().command(cmd.usage(), cmd.description());
|
||||
vorpalCmd.__commandObject = cmd;
|
||||
|
||||
// TODO: maybe remove if the PR is not merged
|
||||
if ('disableTypeCasting' in vorpalCmd) vorpalCmd.disableTypeCasting();
|
||||
|
||||
for (let i = 0; i < cmd.aliases().length; i++) {
|
||||
vorpalCmd.alias(cmd.aliases()[i]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < cmd.options().length; i++) {
|
||||
let options = cmd.options()[i];
|
||||
if (options.length == 2) vorpalCmd.option(options[0], options[1]);
|
||||
if (options.length == 3) vorpalCmd.option(options[0], options[1], options[2]);
|
||||
if (options.length > 3) throw new Error('Invalid number of option arguments');
|
||||
}
|
||||
|
||||
if (cmd.autocomplete()) vorpalCmd.autocomplete(cmd.autocomplete());
|
||||
|
||||
let actionFn = async function(args, end) {
|
||||
try {
|
||||
const fn = cmd.action.bind(this);
|
||||
await fn(args);
|
||||
} catch (error) {
|
||||
this.log(error);
|
||||
}
|
||||
vorpalUtils.redrawDone();
|
||||
end();
|
||||
};
|
||||
|
||||
vorpalCmd.action(actionFn);
|
||||
|
||||
let cancelFn = async function() {
|
||||
const fn = cmd.cancel.bind(this);
|
||||
await fn();
|
||||
};
|
||||
|
||||
vorpalCmd.cancel(cancelFn);
|
||||
|
||||
if (cmd.hidden()) vorpalCmd.hidden();
|
||||
});
|
||||
}
|
||||
|
||||
baseModelListener(action) {
|
||||
switch (action.type) {
|
||||
|
||||
@ -270,6 +235,47 @@ class Application {
|
||||
}
|
||||
}
|
||||
|
||||
loadAllCommands() {
|
||||
fs.readdirSync(__dirname).forEach((path) => {
|
||||
if (path.indexOf('command-') !== 0) return;
|
||||
const ext = fileExtension(path)
|
||||
if (ext != 'js') return;
|
||||
|
||||
let CommandClass = require('./' + path);
|
||||
let cmd = new CommandClass();
|
||||
if (!cmd.enabled()) return;
|
||||
|
||||
this.commands_[cmd.name()] = cmd;
|
||||
});
|
||||
}
|
||||
|
||||
async commandMetadata() {
|
||||
if (this.commandMetadata_) return this.commandMetadata_;
|
||||
|
||||
const storage = require('node-persist');
|
||||
await storage.init({ dir: 'commandMetadata', ttl: 1000 * 60 * 60 * 24 });
|
||||
|
||||
let output = await storage.getItem('metadata');
|
||||
if (Setting.value('env') != 'dev' && output) {
|
||||
this.commandMetadata_ = output;
|
||||
return Object.assign({}, this.commandMetadata_);
|
||||
}
|
||||
|
||||
this.loadAllCommands();
|
||||
|
||||
output = {};
|
||||
for (let n in this.commands_) {
|
||||
if (!this.commands_.hasOwnProperty(n)) continue;
|
||||
const cmd = this.commands_[n];
|
||||
output[n] = cmd.metadata();
|
||||
}
|
||||
|
||||
await storage.setItem('metadata', output);
|
||||
|
||||
this.commandMetadata_ = output;
|
||||
return Object.assign({}, this.commandMetadata_);
|
||||
}
|
||||
|
||||
findCommandByName(name) {
|
||||
let CommandClass = null;
|
||||
try {
|
||||
@ -288,98 +294,11 @@ class Application {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
makeCommandArgs(cmd, argv) {
|
||||
let cmdUsage = cmd.usage();
|
||||
cmdUsage = yargParser(cmdUsage);
|
||||
let output = {};
|
||||
|
||||
let options = cmd.options();
|
||||
let booleanFlags = [];
|
||||
let aliases = {};
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].length != 2) throw new Error('Invalid options: ' + options[i]);
|
||||
let flags = options[i][0];
|
||||
let text = options[i][1];
|
||||
|
||||
flags = this.parseFlags(flags);
|
||||
|
||||
if (!flags.arg) {
|
||||
booleanFlags.push(flags.short);
|
||||
if (flags.long) booleanFlags.push(flags.long);
|
||||
}
|
||||
|
||||
if (flags.short && flags.long) {
|
||||
aliases[flags.long] = [flags.short];
|
||||
}
|
||||
}
|
||||
|
||||
let args = yargParser(argv, {
|
||||
boolean: booleanFlags,
|
||||
alias: aliases,
|
||||
});
|
||||
|
||||
for (let i = 1; i < cmdUsage['_'].length; i++) {
|
||||
const a = this.parseCommandArg(cmdUsage['_'][i]);
|
||||
if (a.required && !args['_'][i]) throw new Error('Missing required arg: ' + a.name);
|
||||
if (i >= a.length) {
|
||||
output[a.name] = null;
|
||||
} else {
|
||||
output[a.name] = args['_'][i];
|
||||
}
|
||||
}
|
||||
|
||||
let argOptions = {};
|
||||
for (let key in args) {
|
||||
if (!args.hasOwnProperty(key)) continue;
|
||||
if (key == '_') continue;
|
||||
argOptions[key] = args[key];
|
||||
}
|
||||
|
||||
output.options = argOptions;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
parseFlags(flags) {
|
||||
let output = {};
|
||||
flags = flags.split(',');
|
||||
for (let i = 0; i < flags.length; i++) {
|
||||
let f = flags[i].trim();
|
||||
|
||||
if (f.substr(0, 2) == '--') {
|
||||
f = f.split(' ');
|
||||
output.long = f[0].substr(2).trim();
|
||||
if (f.length == 2) {
|
||||
output.arg = this.parseCommandArg(f[1].trim());
|
||||
}
|
||||
} else if (f.substr(0, 1) == '-') {
|
||||
output.short = f.substr(1);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
parseCommandArg(arg) {
|
||||
if (arg.length <= 2) throw new Error('Invalid command arg: ' + arg);
|
||||
|
||||
const c1 = arg[0];
|
||||
const c2 = arg[arg.length - 1];
|
||||
const name = arg.substr(1, arg.length - 2);
|
||||
|
||||
if (c1 == '<' && c2 == '>') {
|
||||
return { required: true, name: name };
|
||||
} else if (c1 == '[' && c2 == ']') {
|
||||
return { required: false, name: name };
|
||||
} else {
|
||||
throw new Error('Invalid command arg: ' + arg);
|
||||
}
|
||||
}
|
||||
|
||||
async execCommand(argv) {
|
||||
if (!argv.length) throw new Error('Empty command');
|
||||
const commandName = argv[0];
|
||||
const command = this.findCommandByName(commandName);
|
||||
const cmdArgs = this.makeCommandArgs(command, argv);
|
||||
const cmdArgs = cliUtils.makeCommandArgs(command, argv);
|
||||
await command.action(cmdArgs);
|
||||
}
|
||||
|
||||
@ -438,109 +357,22 @@ class Application {
|
||||
|
||||
setLocale(Setting.value('locale'));
|
||||
|
||||
//this.loadCommands_();
|
||||
|
||||
let currentFolderId = Setting.value('activeFolderId');
|
||||
this.currentFolder_ = null;
|
||||
if (currentFolderId) this.currentFolder_ = await Folder.load(currentFolderId);
|
||||
if (!this.currentFolder_) this.currentFolder_ = await Folder.defaultFolder();
|
||||
Setting.setValue('activeFolderId', this.currentFolder_ ? this.currentFolder_.id : '');
|
||||
|
||||
|
||||
|
||||
const completion = omelette(`joplindev <title>`);
|
||||
|
||||
// Bind events for every template part.
|
||||
completion.on('title', ({ before, reply }) => {
|
||||
const child_process = require('child_process');
|
||||
const stdout = child_process.execSync('joplindev autocompletion --before "' + before + '" notes');
|
||||
reply(JSON.parse(stdout));
|
||||
});
|
||||
|
||||
// Initialize the omelette.
|
||||
completion.init()
|
||||
|
||||
|
||||
// const omelCommand = ({ before, reply }) => {
|
||||
// reply([ 'cat', 'ls' ]);
|
||||
// }
|
||||
|
||||
// const omelTitle = ({ reply }) => {
|
||||
// if (this.currentFolder_) {
|
||||
// Note.previews(this.currentFolder_.id).then((notes) => {
|
||||
// console.info(notes.length);
|
||||
// const output = notes.map((n) => n.title);
|
||||
// reply(['aa']);
|
||||
// //reply(output);
|
||||
// });
|
||||
// } else {
|
||||
// reply([]);
|
||||
// }
|
||||
// }
|
||||
|
||||
// omelette`joplindev ${omelCommand} ${omelTitle}`.init()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (this.autocompletion_.active) {
|
||||
let items = await handleAutocompletion(this.autocompletion_);
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
items[i] = items[i].replace(/ /g, '\\ ');
|
||||
}
|
||||
console.info(items.join("\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
this.execCommand(argv);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 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 (argv.length) {
|
||||
// let cmd = this.shellArgsToString(argv);
|
||||
// await this.vorpal().exec(cmd);
|
||||
// } else {
|
||||
|
||||
// setInterval(() => {
|
||||
// reg.scheduleSync(0);
|
||||
// }, 1000 * 60 * 5);
|
||||
|
||||
// this.updatePrompt();
|
||||
// this.vorpal().show();
|
||||
// this.vorpal().history(Setting.value('appId')); // Enables persistent history
|
||||
// if (!this.currentFolder()) {
|
||||
// this.vorpal().log(_('No notebook is defined. Create one with `mkbook <notebook>`.'));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
87
CliClient/app/autocompletion.js
Normal file
87
CliClient/app/autocompletion.js
Normal file
@ -0,0 +1,87 @@
|
||||
import { app } from './app.js';
|
||||
import { Note } from 'lib/models/note.js';
|
||||
import { Folder } from 'lib/models/folder.js';
|
||||
import { cliUtils } from './cli-utils.js';
|
||||
import yargParser from 'yargs-parser';
|
||||
|
||||
async function handleAutocompletion(autocompletion) {
|
||||
let args = autocompletion.line.slice();
|
||||
args.splice(0, 1);
|
||||
let current = autocompletion.current - 1;
|
||||
const currentWord = args[current];
|
||||
|
||||
// Auto-complete the command name
|
||||
|
||||
if (current == 0) {
|
||||
const metadata = await app().commandMetadata();
|
||||
let commandNames = [];
|
||||
for (let n in metadata) {
|
||||
if (!metadata.hasOwnProperty(n)) continue;
|
||||
const md = metadata[n];
|
||||
if (md.hidden) continue;
|
||||
if (currentWord == n) return [n];
|
||||
if (n.indexOf(currentWord) === 0) commandNames.push(n);
|
||||
}
|
||||
return commandNames;
|
||||
}
|
||||
|
||||
const commandName = args[0];
|
||||
const metadata = await app().commandMetadata();
|
||||
const md = metadata[commandName];
|
||||
const options = md && md.options ? md.options : [];
|
||||
|
||||
// Auto-complete the command options
|
||||
|
||||
if (!currentWord) return [];
|
||||
|
||||
const includeLongs = currentWord.length == 1 ? currentWord.substr(0, 1) == '-' : currentWord.substr(0, 2) == '--';
|
||||
const includeShorts = currentWord.length <= 2 && currentWord.substr(0, 1) == '-' && currentWord.substr(0, 2) != '--';
|
||||
|
||||
if (includeLongs || includeShorts) {
|
||||
const output = [];
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
const flags = cliUtils.parseFlags(options[i][0]);
|
||||
const long = flags.long ? '--' + flags.long : null;
|
||||
const short = flags.short ? '-' + flags.short : null;
|
||||
if (includeLongs && long && long.indexOf(currentWord) === 0) output.push(long);
|
||||
if (includeShorts && short && short.indexOf(currentWord) === 0) output.push(short);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// Auto-complete the command arguments
|
||||
|
||||
let argIndex = -1;
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const w = args[i];
|
||||
if (i == 0 || w.indexOf('-') == 0) {
|
||||
continue;
|
||||
}
|
||||
argIndex++;
|
||||
}
|
||||
|
||||
if (argIndex < 0) return [];
|
||||
|
||||
let cmdUsage = yargParser(md.usage)['_'];
|
||||
cmdUsage.splice(0, 1);
|
||||
|
||||
if (cmdUsage.length <= argIndex) return [];
|
||||
|
||||
let argName = cmdUsage[argIndex];
|
||||
argName = cliUtils.parseCommandArg(argName).name;
|
||||
|
||||
if (argName == 'note') {
|
||||
if (!app().currentFolder()) return [];
|
||||
const notes = await Note.previews(app().currentFolder().id, { titlePattern: currentWord + '*' });
|
||||
return notes.map((n) => n.title);
|
||||
}
|
||||
|
||||
if (argName == 'notebook') {
|
||||
const folders = await Folder.search({ titlePattern: currentWord + '*' });
|
||||
return folders.map((n) => n.title);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
export { handleAutocompletion };
|
@ -34,6 +34,20 @@ class BaseCommand {
|
||||
|
||||
async cancel() {}
|
||||
|
||||
name() {
|
||||
let r = this.usage().split(' ');
|
||||
return r[0];
|
||||
}
|
||||
|
||||
metadata() {
|
||||
return {
|
||||
name: this.name(),
|
||||
usage: this.usage(),
|
||||
options: this.options(),
|
||||
hidden: this.hidden(),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { BaseCommand };
|
@ -1,41 +1,127 @@
|
||||
import yargParser from 'yargs-parser';
|
||||
const stringPadding = require('string-padding');
|
||||
|
||||
const cliUtils = {
|
||||
const cliUtils = {};
|
||||
|
||||
printArray: function(logFunction, rows, headers = null) {
|
||||
if (!rows.length) return '';
|
||||
cliUtils.printArray = function(logFunction, rows, headers = null) {
|
||||
if (!rows.length) return '';
|
||||
|
||||
const ALIGN_LEFT = 0;
|
||||
const ALIGN_RIGHT = 1;
|
||||
const ALIGN_LEFT = 0;
|
||||
const ALIGN_RIGHT = 1;
|
||||
|
||||
let colWidths = [];
|
||||
let colAligns = [];
|
||||
let colWidths = [];
|
||||
let colAligns = [];
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
|
||||
for (let j = 0; j < row.length; j++) {
|
||||
let item = row[j];
|
||||
let width = item ? item.toString().length : 0;
|
||||
let align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
|
||||
if (!colWidths[j] || colWidths[j] < width) colWidths[j] = width;
|
||||
if (colAligns.length <= j) colAligns[j] = align;
|
||||
for (let j = 0; j < row.length; j++) {
|
||||
let item = row[j];
|
||||
let width = item ? item.toString().length : 0;
|
||||
let align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
|
||||
if (!colWidths[j] || colWidths[j] < width) colWidths[j] = width;
|
||||
if (colAligns.length <= j) colAligns[j] = align;
|
||||
}
|
||||
}
|
||||
|
||||
let lines = [];
|
||||
for (let row = 0; row < rows.length; row++) {
|
||||
let line = [];
|
||||
for (let col = 0; col < colWidths.length; col++) {
|
||||
let item = rows[row][col];
|
||||
let width = colWidths[col];
|
||||
let dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
|
||||
line.push(stringPadding(item, width, ' ', dir));
|
||||
}
|
||||
logFunction(line.join(' '));
|
||||
}
|
||||
}
|
||||
|
||||
cliUtils.parseFlags = function(flags) {
|
||||
let output = {};
|
||||
flags = flags.split(',');
|
||||
for (let i = 0; i < flags.length; i++) {
|
||||
let f = flags[i].trim();
|
||||
|
||||
if (f.substr(0, 2) == '--') {
|
||||
f = f.split(' ');
|
||||
output.long = f[0].substr(2).trim();
|
||||
if (f.length == 2) {
|
||||
output.arg = cliUtils.parseCommandArg(f[1].trim());
|
||||
}
|
||||
} else if (f.substr(0, 1) == '-') {
|
||||
output.short = f.substr(1);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
cliUtils.parseCommandArg = function(arg) {
|
||||
if (arg.length <= 2) throw new Error('Invalid command arg: ' + arg);
|
||||
|
||||
const c1 = arg[0];
|
||||
const c2 = arg[arg.length - 1];
|
||||
const name = arg.substr(1, arg.length - 2);
|
||||
|
||||
if (c1 == '<' && c2 == '>') {
|
||||
return { required: true, name: name };
|
||||
} else if (c1 == '[' && c2 == ']') {
|
||||
return { required: false, name: name };
|
||||
} else {
|
||||
throw new Error('Invalid command arg: ' + arg);
|
||||
}
|
||||
}
|
||||
|
||||
cliUtils.makeCommandArgs = function(cmd, argv) {
|
||||
let cmdUsage = cmd.usage();
|
||||
cmdUsage = yargParser(cmdUsage);
|
||||
let output = {};
|
||||
|
||||
let options = cmd.options();
|
||||
let booleanFlags = [];
|
||||
let aliases = {};
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
if (options[i].length != 2) throw new Error('Invalid options: ' + options[i]);
|
||||
let flags = options[i][0];
|
||||
let text = options[i][1];
|
||||
|
||||
flags = cliUtils.parseFlags(flags);
|
||||
|
||||
if (!flags.arg) {
|
||||
booleanFlags.push(flags.short);
|
||||
if (flags.long) booleanFlags.push(flags.long);
|
||||
}
|
||||
|
||||
let lines = [];
|
||||
for (let row = 0; row < rows.length; row++) {
|
||||
let line = [];
|
||||
for (let col = 0; col < colWidths.length; col++) {
|
||||
let item = rows[row][col];
|
||||
let width = colWidths[col];
|
||||
let dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
|
||||
line.push(stringPadding(item, width, ' ', dir));
|
||||
}
|
||||
logFunction(line.join(' '));
|
||||
if (flags.short && flags.long) {
|
||||
aliases[flags.long] = [flags.short];
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
let args = yargParser(argv, {
|
||||
boolean: booleanFlags,
|
||||
alias: aliases,
|
||||
});
|
||||
|
||||
for (let i = 1; i < cmdUsage['_'].length; i++) {
|
||||
const a = cliUtils.parseCommandArg(cmdUsage['_'][i]);
|
||||
if (a.required && !args['_'][i]) throw new Error('Missing required arg: ' + a.name);
|
||||
if (i >= a.length) {
|
||||
output[a.name] = null;
|
||||
} else {
|
||||
output[a.name] = args['_'][i];
|
||||
}
|
||||
}
|
||||
|
||||
let argOptions = {};
|
||||
for (let key in args) {
|
||||
if (!args.hasOwnProperty(key)) continue;
|
||||
if (key == '_') continue;
|
||||
argOptions[key] = args[key];
|
||||
}
|
||||
|
||||
output.options = argOptions;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
export { cliUtils };
|
@ -16,6 +16,7 @@ class Command extends BaseCommand {
|
||||
options() {
|
||||
return [
|
||||
[ '--before <before>', 'before' ],
|
||||
[ '--multiline', 'multiline' ],
|
||||
];
|
||||
}
|
||||
|
||||
@ -24,16 +25,28 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
console.info(args);
|
||||
|
||||
let output = [];
|
||||
if (args.type == 'notes') {
|
||||
// TODO:
|
||||
if (!app().currentFolder()) throw new Error('no current folder');
|
||||
let options = {};
|
||||
// this.log(JSON.stringify(['XX'+args.options.before+'XX', 'aa','bb']));
|
||||
// return;
|
||||
|
||||
//console.info(args.options.before);
|
||||
if (args.options.before) options.titlePattern = args.options.before + '*';
|
||||
const notes = await Note.previews(app().currentFolder().id, options);
|
||||
output = notes.map((n) => n.title);
|
||||
}
|
||||
this.log(JSON.stringify(output));
|
||||
|
||||
if (args.options.multiline) {
|
||||
output = output.map((s) => s.replace(/ /g, '\\ '));
|
||||
this.log(output.join("\n"));
|
||||
} else {
|
||||
this.log(JSON.stringify(output));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import { autocompleteItems } from './autocomplete.js';
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'cat <title>';
|
||||
return 'cat <note>';
|
||||
}
|
||||
|
||||
description() {
|
||||
@ -27,7 +27,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let title = args['title'];
|
||||
let title = args['note'];
|
||||
|
||||
let item = await app().loadItem(BaseModel.TYPE_NOTE, title, { parent: app().currentFolder() });
|
||||
if (!item) throw new Error(_('Cannot find "%s".', title));
|
||||
|
@ -9,11 +9,11 @@ import { autocompleteItems } from './autocomplete.js';
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'cp <pattern> [notebook]';
|
||||
return 'cp <note> [notebook]';
|
||||
}
|
||||
|
||||
description() {
|
||||
return _('Duplicates the notes matching <pattern> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.');
|
||||
return _('Duplicates the notes matching <note> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.');
|
||||
}
|
||||
|
||||
autocomplete() {
|
||||
@ -30,8 +30,8 @@ class Command extends BaseCommand {
|
||||
|
||||
if (!folder) throw new Error(_('Cannot find "%s".', args['notebook']));
|
||||
|
||||
const notes = await app().loadItems(BaseModel.TYPE_NOTE, args['pattern']);
|
||||
if (!notes.length) throw new Error(_('Cannot find "%s".', args['pattern']));
|
||||
const notes = await app().loadItems(BaseModel.TYPE_NOTE, args['note']);
|
||||
if (!notes.length) throw new Error(_('Cannot find "%s".', args['note']));
|
||||
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
const newNote = await Note.copyToFolder(notes[i].id, folder.id);
|
||||
|
@ -11,7 +11,7 @@ import { autocompleteItems } from './autocomplete.js';
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'edit <title>';
|
||||
return 'edit <note>';
|
||||
}
|
||||
|
||||
description() {
|
||||
@ -40,7 +40,7 @@ class Command extends BaseCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
let title = args['title'];
|
||||
let title = args['note'];
|
||||
|
||||
if (!app().currentFolder()) throw new Error(_('No active notebook.'));
|
||||
let note = await app().loadItem(BaseModel.TYPE_NOTE, title);
|
||||
@ -70,8 +70,6 @@ class Command extends BaseCommand {
|
||||
|
||||
this.log(_('Starting to edit note. Close the editor to get back to the prompt.'));
|
||||
|
||||
//app().vorpal().hide();
|
||||
|
||||
await fs.writeFile(tempFilePath, content);
|
||||
|
||||
let watchTimeout = null;
|
||||
|
@ -1,148 +0,0 @@
|
||||
import { time } from 'lib/time-utils.js';
|
||||
import stringPadding from 'string-padding';
|
||||
|
||||
const vorpalUtils = {};
|
||||
|
||||
let vorpal_ = null;
|
||||
let redrawStarted_ = false;
|
||||
let redrawLastUpdateTime_ = 0;
|
||||
let redrawLastLog_ = null;
|
||||
let redrawEnabled_ = true;
|
||||
let errorStackTraceEnabled_ = false;
|
||||
|
||||
function initialize(vorpal) {
|
||||
vorpal_ = vorpal;
|
||||
}
|
||||
|
||||
function printArray(commandInstance, rows, headers = null) {
|
||||
if (!rows.length) return '';
|
||||
|
||||
const ALIGN_LEFT = 0;
|
||||
const ALIGN_RIGHT = 1;
|
||||
|
||||
let colWidths = [];
|
||||
let colAligns = [];
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i];
|
||||
|
||||
for (let j = 0; j < row.length; j++) {
|
||||
let item = row[j];
|
||||
let width = item ? item.toString().length : 0;
|
||||
let align = typeof item == 'number' ? ALIGN_RIGHT : ALIGN_LEFT;
|
||||
if (!colWidths[j] || colWidths[j] < width) colWidths[j] = width;
|
||||
if (colAligns.length <= j) colAligns[j] = align;
|
||||
}
|
||||
}
|
||||
|
||||
let lines = [];
|
||||
for (let row = 0; row < rows.length; row++) {
|
||||
let line = [];
|
||||
for (let col = 0; col < colWidths.length; col++) {
|
||||
let item = rows[row][col];
|
||||
let width = colWidths[col];
|
||||
let dir = colAligns[col] == ALIGN_LEFT ? stringPadding.RIGHT : stringPadding.LEFT;
|
||||
line.push(stringPadding(item, width, ' ', dir));
|
||||
}
|
||||
commandInstance.log(line.join(' '));
|
||||
}
|
||||
}
|
||||
|
||||
function redrawEnabled() {
|
||||
// // Always disabled for now - doesn't play well with command.cancel()
|
||||
// // function (it makes the whole app quit instead of just the
|
||||
// // current command).
|
||||
return false;
|
||||
|
||||
return redrawEnabled_;
|
||||
}
|
||||
|
||||
function setRedrawEnabled(v) {
|
||||
redrawEnabled_ = v;
|
||||
}
|
||||
|
||||
function setStackTraceEnabled(v) {
|
||||
errorStackTraceEnabled_ = v;
|
||||
}
|
||||
|
||||
function redraw(s) {
|
||||
if (!redrawEnabled()) {
|
||||
const now = time.unixMs();
|
||||
if (now - redrawLastUpdateTime_ > 4000) {
|
||||
if (vorpal_.activeCommand) {
|
||||
vorpal_.activeCommand.log(s);
|
||||
} else {
|
||||
vorpal_.log(s);
|
||||
}
|
||||
redrawLastUpdateTime_ = now;
|
||||
redrawLastLog_ = null;
|
||||
} else {
|
||||
redrawLastLog_ = s;
|
||||
}
|
||||
} else {
|
||||
vorpal_.ui.redraw(s);
|
||||
}
|
||||
|
||||
redrawStarted_ = true;
|
||||
}
|
||||
|
||||
function redrawDone() {
|
||||
if (!redrawStarted_) return;
|
||||
|
||||
if (!redrawEnabled()) {
|
||||
if (redrawLastLog_) {
|
||||
if (vorpal_.activeCommand) {
|
||||
vorpal_.activeCommand.log(redrawLastLog_);
|
||||
} else {
|
||||
vorpal_.log(redrawLastLog_);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vorpal_.ui.redraw.done();
|
||||
}
|
||||
|
||||
redrawLastLog_ = null;
|
||||
redrawStarted_ = false;
|
||||
}
|
||||
|
||||
function log(commandInstance, o) {
|
||||
if (errorStackTraceEnabled_) {
|
||||
commandInstance.log(o);
|
||||
} else {
|
||||
if (o instanceof Error) {
|
||||
commandInstance.log(o.message);
|
||||
} else {
|
||||
commandInstance.log(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cmdPromptConfirm(commandInstance, message) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let options = {
|
||||
type: 'confirm',
|
||||
name: 'ok',
|
||||
default: false, // This needs to be false so that, when pressing Ctrl+C, the prompt returns false
|
||||
message: message,
|
||||
};
|
||||
|
||||
commandInstance.prompt(options, (result) => {
|
||||
if (result.ok) {
|
||||
resolve(true);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
vorpalUtils.initialize = initialize;
|
||||
vorpalUtils.printArray = printArray;
|
||||
vorpalUtils.redraw = redraw;
|
||||
vorpalUtils.redrawDone = redrawDone;
|
||||
vorpalUtils.setRedrawEnabled = setRedrawEnabled;
|
||||
vorpalUtils.setStackTraceEnabled = setStackTraceEnabled;
|
||||
vorpalUtils.log = log;
|
||||
vorpalUtils.cmdPromptConfirm = cmdPromptConfirm;
|
||||
|
||||
export { vorpalUtils };
|
@ -15,6 +15,7 @@
|
||||
"app-module-path": "^2.2.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"cache-require-paths": "^0.3.0",
|
||||
"flat-cache": "^1.2.2",
|
||||
"follow-redirects": "^1.2.4",
|
||||
"form-data": "^2.1.4",
|
||||
"fs-extra": "^3.0.1",
|
||||
@ -25,8 +26,8 @@
|
||||
"mkdirp": "^0.5.1",
|
||||
"moment": "^2.18.1",
|
||||
"moment-timezone": "^0.5.13",
|
||||
"node-cache": "^4.1.1",
|
||||
"node-fetch": "^1.7.1",
|
||||
"omelette": "^0.4.4",
|
||||
"os-tmpdir": "^1.0.2",
|
||||
"promise": "^7.1.1",
|
||||
"proper-lockfile": "^2.0.1",
|
||||
@ -40,7 +41,6 @@
|
||||
"string-to-stream": "^1.1.0",
|
||||
"tcp-port-used": "^0.1.2",
|
||||
"uuid": "^3.0.1",
|
||||
"vorpal": "^1.12.0",
|
||||
"yargs-parser": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -2141,21 +2141,6 @@ verror@1.3.6:
|
||||
dependencies:
|
||||
extsprintf "1.0.2"
|
||||
|
||||
vorpal@^1.12.0:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/vorpal/-/vorpal-1.12.0.tgz#4be7b2a4e48f8fcfc9cf3648c419d311c522159d"
|
||||
dependencies:
|
||||
babel-polyfill "^6.3.14"
|
||||
chalk "^1.1.0"
|
||||
in-publish "^2.0.0"
|
||||
inquirer "0.11.0"
|
||||
lodash "^4.5.1"
|
||||
log-update "^1.0.2"
|
||||
minimist "^1.2.0"
|
||||
node-localstorage "^0.6.0"
|
||||
strip-ansi "^3.0.0"
|
||||
wrap-ansi "^2.0.0"
|
||||
|
||||
wide-align@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710"
|
||||
|
@ -109,7 +109,7 @@ class Logger {
|
||||
let serializedObject = this.objectsToString(...object);
|
||||
Logger.fsDriver().appendFileSync(target.path, line + serializedObject + "\n");
|
||||
} else if (target.type == 'vorpal') {
|
||||
target.vorpal.log(...object);
|
||||
//target.vorpal.log(...object);
|
||||
} else if (target.type == 'database') {
|
||||
let msg = this.objectsToString(...object);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user