Add: promptCL*

This commit is contained in:
anseki 2015-04-17 18:08:22 +09:00
parent 69ce4ab6c2
commit 80da6fd081

View file

@ -35,7 +35,8 @@ var
print: void 0, print: void 0,
history: true, history: true,
cd: false, cd: false,
phContent: void 0 phContent: void 0,
preCheck: void 0
}, },
fdR = 'none', fdW, ttyR, isRawMode = false, fdR = 'none', fdW, ttyR, isRawMode = false,
@ -494,6 +495,7 @@ function margeOptions() {
// ================ function // ================ function
case 'print': // * * case 'print': // * *
case 'phContent': // * case 'phContent': // *
case 'preCheck': // *
options[optionName] = typeof value === 'function' ? value : void 0; options[optionName] = typeof value === 'function' ? value : void 0;
break; break;
// ================ other // ================ other
@ -662,14 +664,14 @@ function getPhCharlist(param) {
return text; return text;
} }
// cmd "arg" " a r g " 'a"r"g' "a""rg" "arg // cmd "arg" " a r g " "" 'a"r"g' "a""rg" "arg
function parseCL(cl) { function parseCl(cl) {
var reToken = new RegExp(/(\s*)(?:("|')(.*?)(?:\2|$)|(\S+))/g), matches, var reToken = new RegExp(/(\s*)(?:("|')(.*?)(?:\2|$)|(\S+))/g), matches,
taken = '', args = [], part; taken = '', args = [], part;
cl = cl.trim(); cl = cl.trim();
while ((matches = reToken.exec(cl))) { while ((matches = reToken.exec(cl))) {
part = matches[3] || matches[4]; part = matches[3] || matches[4] || '';
if (matches[1] && taken) { if (matches[1]) {
args.push(taken); args.push(taken);
taken = ''; taken = '';
} }
@ -679,9 +681,17 @@ function parseCL(cl) {
return args; return args;
} }
function getValidLine(options, preCheck) { function toBool(res, options) {
var res, forceNext, resCheck, limitMessage, return (
matches, histInput, args; (options.trueValue.length &&
isMatched(res, options.trueValue, options.caseSensitive)) ? true :
(options.falseValue.length &&
isMatched(res, options.falseValue, options.caseSensitive)) ? false : res);
}
function getValidLine(options) {
var res, forceNext, limitMessage,
matches, histInput, args, resCheck;
function _getPhContent(param) { return getPhContent(param, options); } function _getPhContent(param) { return getPhContent(param, options); }
function addDisplay(text) function addDisplay(text)
{ options.display += (/[^\r\n]$/.test(options.display) ? '\n' : '') + text; } { options.display += (/[^\r\n]$/.test(options.display) ? '\n' : '') + text; }
@ -715,8 +725,8 @@ function getValidLine(options, preCheck) {
} }
} }
if (options.cd && res) { if (!forceNext && options.cd && res) {
args = parseCL(res); args = parseCl(res);
switch (args[0].toLowerCase()) { switch (args[0].toLowerCase()) {
case 'cd': case 'cd':
if (args[1]) { if (args[1]) {
@ -737,8 +747,8 @@ function getValidLine(options, preCheck) {
} }
} }
if (preCheck) { if (!forceNext && options.preCheck) {
resCheck = preCheck(res, options); resCheck = options.preCheck(res, options);
res = resCheck.res; res = resCheck.res;
if (resCheck.forceNext) { forceNext = true; } // Don't switch to false. if (resCheck.forceNext) { forceNext = true; } // Don't switch to false.
} }
@ -756,14 +766,6 @@ function getValidLine(options, preCheck) {
return toBool(res, options); return toBool(res, options);
} }
function toBool(res, options) {
return (
(options.trueValue.length &&
isMatched(res, options.trueValue, options.caseSensitive)) ? true :
(options.falseValue.length &&
isMatched(res, options.falseValue, options.caseSensitive)) ? false : res);
}
// for dev // for dev
exports._DBG_set_useExt = function(val) { _DBG_useExt = val; }; exports._DBG_set_useExt = function(val) { _DBG_useExt = val; };
exports._DBG_set_checkOptions = function(val) { _DBG_checkOptions = val; }; exports._DBG_set_checkOptions = function(val) { _DBG_checkOptions = val; };
@ -1020,26 +1022,97 @@ exports.questionPath = function(query, options) {
return validPath; return validPath;
}; };
exports.promptSimShell = function(options) { // props: preCheck, args, hRes, limit
return exports.prompt(margeOptions({ function getClHandler(commandHandler, options) {
var clHandler = {}, hIndex = {};
if (typeof commandHandler === 'object') {
Object.keys(commandHandler).forEach(function(cmd) {
if (typeof commandHandler[cmd] === 'function') {
hIndex[options.caseSensitive ? cmd : cmd.toLowerCase()] = commandHandler[cmd];
}
});
clHandler.preCheck = function(res) {
var cmdKey;
clHandler.args = parseCl(res);
cmdKey = clHandler.args[0] || '';
if (!options.caseSensitive) { cmdKey = cmdKey.toLowerCase(); }
clHandler.hRes =
hIndex.hasOwnProperty(cmdKey) ?
hIndex[cmdKey].apply(res, clHandler.args.slice(1)) :
hIndex.hasOwnProperty('_') ? hIndex._.apply(res, clHandler.args) : null;
return {res: res, forceNext: false};
};
if (!hIndex.hasOwnProperty('_')) {
clHandler.limit = function() { // It's called after preCheck.
var cmdKey = clHandler.args[0] || '';
if (!options.caseSensitive) { cmdKey = cmdKey.toLowerCase(); }
return hIndex.hasOwnProperty(cmdKey);
};
}
} else {
clHandler.preCheck = function(res) {
clHandler.args = parseCl(res);
clHandler.hRes = typeof commandHandler === 'function' ?
commandHandler.apply(res, clHandler.args) : null;
return {res: res, forceNext: false};
};
}
return clHandler;
}
exports.promptCL = function(commandHandler, options) {
var readOptions = margeOptions({
// -------- default // -------- default
hideEchoBack: false, hideEchoBack: false,
limitMessage: 'Requested command is not available.',
caseSensitive: false,
history: true history: true
}, options, { }, options),
// -------- forced // -------- forced
prompt: (function() { // trueValue, falseValue are don't work.
return IS_WIN ? // preCheck, limit (by clHandler)
'${cwd}>' : clHandler = getClHandler(commandHandler, readOptions);
// 'user@host:cwd$ ' readOptions.limit = clHandler.limit;
(process.env.USER || '') + readOptions.preCheck = clHandler.preCheck;
(process.env.HOSTNAME ? exports.prompt(readOptions);
'@' + process.env.HOSTNAME.replace(/\..*$/, '') : '') + return clHandler.args;
':${cwdHome}$ ';
})()
}));
}; };
exports.promptCL = function(options) { exports.promptLoop = function(inputHandler, options) {
var readOptions = margeOptions({
// -------- default
hideEchoBack: false,
trueValue: null,
falseValue: null,
caseSensitive: false,
history: true
}, options);
while (true) { if (inputHandler(exports.prompt(readOptions))) { break; } }
return;
};
exports.promptCLLoop = function(commandHandler, options) {
var readOptions = margeOptions({
// -------- default
hideEchoBack: false,
limitMessage: 'Requested command is not available.',
caseSensitive: false,
history: true
}, options),
// -------- forced
// trueValue, falseValue are don't work.
// preCheck, limit (by clHandler)
clHandler = getClHandler(commandHandler, readOptions);
readOptions.limit = clHandler.limit;
readOptions.preCheck = clHandler.preCheck;
while (true) {
exports.prompt(readOptions);
if (clHandler.hRes) { break; }
}
return;
};
exports.promptSimShell = function(options) {
return exports.prompt(margeOptions({ return exports.prompt(margeOptions({
// -------- default // -------- default
hideEchoBack: false, hideEchoBack: false,
@ -1098,7 +1171,7 @@ exports.keyInPause = function(query, options) {
return; return;
}; };
exports.keyInSelect = function(query, items, options) { exports.keyInSelect = function(items, query, options) {
var readOptions = margeOptions({ var readOptions = margeOptions({
// -------- default // -------- default
hideEchoBack: false hideEchoBack: false