mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-22 08:07:59 +01:00
allow ^= to be used for prepending values to string options and for multiplying
number options
This commit is contained in:
@@ -182,7 +182,7 @@ vimperator.Commands = function() //{{{
|
|||||||
outer:
|
outer:
|
||||||
for (var i = 0; i < str.length; i++)
|
for (var i = 0; i < str.length; i++)
|
||||||
{
|
{
|
||||||
switch(str[i])
|
switch (str[i])
|
||||||
{
|
{
|
||||||
case "\"":
|
case "\"":
|
||||||
if (in_escape_key)
|
if (in_escape_key)
|
||||||
@@ -1111,7 +1111,7 @@ vimperator.Commands = function() //{{{
|
|||||||
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
||||||
var [lhs, rhs] = [matches[1], matches[2]];
|
var [lhs, rhs] = [matches[1], matches[2]];
|
||||||
if (rhs)
|
if (rhs)
|
||||||
vimperator.editor.addAbbreviation("!", lhs, rhs);
|
vimperator.editor.addAbbreviation("!", lhs, rhs);
|
||||||
else
|
else
|
||||||
vimperator.editor.listAbbreviations("!", lhs);
|
vimperator.editor.listAbbreviations("!", lhs);
|
||||||
},
|
},
|
||||||
@@ -1135,7 +1135,7 @@ vimperator.Commands = function() //{{{
|
|||||||
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
||||||
var [lhs, rhs] = [matches[1], matches[2]];
|
var [lhs, rhs] = [matches[1], matches[2]];
|
||||||
if (rhs)
|
if (rhs)
|
||||||
vimperator.editor.addAbbreviation("c", lhs, rhs);
|
vimperator.editor.addAbbreviation("c", lhs, rhs);
|
||||||
else
|
else
|
||||||
vimperator.editor.listAbbreviations("c", lhs);
|
vimperator.editor.listAbbreviations("c", lhs);
|
||||||
},
|
},
|
||||||
@@ -1157,7 +1157,7 @@ vimperator.Commands = function() //{{{
|
|||||||
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
||||||
var [lhs, rhs] = [matches[1], matches[2]];
|
var [lhs, rhs] = [matches[1], matches[2]];
|
||||||
if (rhs)
|
if (rhs)
|
||||||
vimperator.editor.addAbbreviation("i", lhs, rhs);
|
vimperator.editor.addAbbreviation("i", lhs, rhs);
|
||||||
else
|
else
|
||||||
vimperator.editor.listAbbreviations("i", lhs);
|
vimperator.editor.listAbbreviations("i", lhs);
|
||||||
},
|
},
|
||||||
@@ -1641,6 +1641,7 @@ vimperator.Commands = function() //{{{
|
|||||||
}
|
}
|
||||||
));
|
));
|
||||||
addDefaultCommand(new vimperator.Command(["se[t]"],
|
addDefaultCommand(new vimperator.Command(["se[t]"],
|
||||||
|
// TODO: support setting multiple options at once
|
||||||
function(args, special, count, modifiers)
|
function(args, special, count, modifiers)
|
||||||
{
|
{
|
||||||
if (special)
|
if (special)
|
||||||
@@ -1649,63 +1650,64 @@ vimperator.Commands = function() //{{{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var only_non_default = false; //used for :set to print non-default options
|
var only_non_default = false; // used for :set to print non-default options
|
||||||
if (!args)
|
if (!args)
|
||||||
{
|
{
|
||||||
args = "all?";
|
args = "all";
|
||||||
only_non_default = true;
|
only_non_default = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 2 3 4 5 6
|
// 1 2 3 4 5 6
|
||||||
var matches = args.match(/^\s*(no|inv)?([a-z]+)([?&!])?(([+-])?=(.*))?/);
|
var matches = args.match(/^\s*(no|inv)?([a-z]+)([?&!])?\s*(([+-^]?)=(.*))?\s*$/);
|
||||||
if (!matches)
|
if (!matches)
|
||||||
{
|
{
|
||||||
vimperator.echoerr("E518: Unknown option: " + args);
|
vimperator.echoerr("E518: Unknown option: " + args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var no = false;
|
var unset_boolean = false;
|
||||||
if (matches[1] == "no")
|
if (matches[1] == "no")
|
||||||
no = true;
|
unset_boolean = true;
|
||||||
|
|
||||||
var opt = matches[2];
|
|
||||||
|
|
||||||
|
var name = matches[2];
|
||||||
var all = false;
|
var all = false;
|
||||||
if (opt == "all")
|
if (name == "all")
|
||||||
all = true;
|
all = true;
|
||||||
|
|
||||||
var option = vimperator.options.get(opt);
|
var option = vimperator.options.get(name);
|
||||||
if (!option && !all)
|
if (!option && !all)
|
||||||
{
|
{
|
||||||
vimperator.echoerr("E518: Unknown option: " + opt);
|
vimperator.echoerr("E518: Unknown option: " + args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var value_given = !!matches[4];
|
||||||
|
|
||||||
var get = false;
|
var get = false;
|
||||||
if (all || matches[3] == "?" || (option.type != "boolean" && matches[4] === undefined))
|
if (all || matches[3] == "?" || (option.type != "boolean" && !value_given))
|
||||||
get = true;
|
get = true;
|
||||||
|
|
||||||
var reset = false;
|
var reset = false;
|
||||||
if (matches[3] == "&")
|
if (matches[3] == "&")
|
||||||
reset = true;
|
reset = true;
|
||||||
|
|
||||||
var invert = false;
|
var invert_boolean = false;
|
||||||
if (matches[1] == "inv" || matches[3] == "!")
|
if (matches[1] == "inv" || matches[3] == "!")
|
||||||
invert = true;
|
invert_boolean = true;
|
||||||
|
|
||||||
var oper = matches[5];
|
var operator = matches[5];
|
||||||
|
|
||||||
var val = matches[6];
|
var value = matches[6];
|
||||||
if (val === undefined)
|
if (value === undefined)
|
||||||
val = "";
|
value = "";
|
||||||
|
|
||||||
// reset a variable to its default value
|
// reset a variable to its default value
|
||||||
if (reset)
|
if (reset)
|
||||||
{
|
{
|
||||||
if (all)
|
if (all)
|
||||||
{
|
{
|
||||||
for (let opt in vimperator.options)
|
for (let option in vimperator.options)
|
||||||
opt.reset();
|
option.reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1728,68 +1730,116 @@ vimperator.Commands = function() //{{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// write access
|
// write access
|
||||||
|
// NOTE: the behaviour is generally Vim compatible but could be
|
||||||
|
// improved. i.e. Vim's behaviour is pretty sloppy to no real
|
||||||
|
// benefit
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var type = option.type;
|
var current_value = option.value;
|
||||||
if (type == "boolean")
|
var new_value;
|
||||||
|
|
||||||
|
switch (option.type)
|
||||||
{
|
{
|
||||||
if (matches[4])
|
case "boolean":
|
||||||
vimperator.echoerr("E474: Invalid argument: " + option.name + "=" + val);
|
if (value_given)
|
||||||
else if (invert)
|
|
||||||
option.value = !option.value;
|
|
||||||
else
|
|
||||||
option.value = !no;
|
|
||||||
}
|
|
||||||
else if (type == "number")
|
|
||||||
{
|
|
||||||
var num = parseInt(val, 10);
|
|
||||||
if (isNaN(num))
|
|
||||||
vimperator.echoerr("E521: Number required after =: " + option.name + "=" + val);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var cur_val = option.value;
|
|
||||||
if (oper == '+') num = cur_val + num;
|
|
||||||
if (oper == '-') num = cur_val - num;
|
|
||||||
// FIXME
|
|
||||||
if (option.validator != null && option.validator.call(this, num) == false)
|
|
||||||
vimperator.echoerr("E474: Invalid argument: " + option.name + "=" + val); // FIXME: need to be able to specify unique parse error messages
|
|
||||||
else // all checks passed, execute option handler
|
|
||||||
option.value = num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (type == "charlist" || type == "stringlist" || type == "string")
|
|
||||||
{
|
|
||||||
var cur_val = option.value;
|
|
||||||
if (type == "charlist" || type == "string")
|
|
||||||
{
|
|
||||||
if (oper == '+' && !cur_val.match(val))
|
|
||||||
val = cur_val + val;
|
|
||||||
if (oper == '-') val = cur_val.replace(val, '');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (oper == '+' && !cur_val.match(val) && cur_val.length > 0)
|
|
||||||
val = cur_val + ',' + val;
|
|
||||||
if (oper == '-')
|
|
||||||
{
|
{
|
||||||
val = cur_val.replace(new RegExp(',?' + val), '');
|
vimperator.echoerr("E474: Invalid argument: " + args);
|
||||||
val = val.replace(/^,?/, '');
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// FIXME
|
if (invert_boolean)
|
||||||
if (option.validator != null && option.validator.call(this, val) == false)
|
new_value = !option.value;
|
||||||
vimperator.echoerr("E474: Invalid argument: " + option.name + "=" + val);
|
else
|
||||||
else // all checks passed, execute option handler
|
new_value = !unset_boolean;
|
||||||
option.value = val;
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "number":
|
||||||
|
value = parseInt(value, 10);
|
||||||
|
|
||||||
|
if (isNaN(value))
|
||||||
|
{
|
||||||
|
vimperator.echoerr("E521: Number required after =: " + args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operator == "+")
|
||||||
|
new_value = current_value + value;
|
||||||
|
else if (operator == "-")
|
||||||
|
new_value = current_value - value;
|
||||||
|
else if (operator == "^")
|
||||||
|
new_value = current_value * value;
|
||||||
|
else
|
||||||
|
new_value = value;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "charlist":
|
||||||
|
if (operator == "+")
|
||||||
|
new_value = current_value.replace(new RegExp("[" + value + "]", "g"), "") + value;
|
||||||
|
else if (operator == "-")
|
||||||
|
new_value = current_value.replace(value, "");
|
||||||
|
else if (operator == "^")
|
||||||
|
// NOTE: Vim doesn't prepend if there's a match in the current value
|
||||||
|
new_value = value + current_value.replace(new RegExp("[" + value + "]", "g"), "");
|
||||||
|
else
|
||||||
|
new_value = value;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "stringlist":
|
||||||
|
if (operator == "+")
|
||||||
|
{
|
||||||
|
if (!current_value.match(value))
|
||||||
|
new_value = (current_value ? current_value + "," : "") + value;
|
||||||
|
else
|
||||||
|
new_value = current_value;
|
||||||
|
}
|
||||||
|
else if (operator == "-")
|
||||||
|
{
|
||||||
|
new_value = current_value.replace(new RegExp("^" + value + ",?|," + value), "");
|
||||||
|
}
|
||||||
|
else if (operator == "^")
|
||||||
|
{
|
||||||
|
if (!current_value.match(value))
|
||||||
|
new_value = value + (current_value ? "," : "") + current_value;
|
||||||
|
else
|
||||||
|
new_value = current_value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "string":
|
||||||
|
if (operator == "+")
|
||||||
|
new_value = current_value + value;
|
||||||
|
else if (operator == "-")
|
||||||
|
new_value = current_value.replace(value, "");
|
||||||
|
else if (operator == "^")
|
||||||
|
new_value = value + current_value;
|
||||||
|
else
|
||||||
|
new_value = value;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
vimperator.echoerr("E685: Internal error: option type `" + option.type + "' not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (option.isValidValue(new_value))
|
||||||
|
option.value = new_value;
|
||||||
else
|
else
|
||||||
vimperator.echoerr("E685: Internal error: option format `" + type + "' not supported");
|
// FIXME: need to be able to specify more specific errors
|
||||||
|
vimperator.echoerr("E474: Invalid argument: " + args);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
usage: ["se[t][!]", "se[t] {option}?", "se[t] [no]{option}", "se[t] {option}[+-]={value}", "se[t] {option}! | inv{option}", "se[t] {option}&"],
|
usage: ["se[t][!]", "se[t] {option}?", "se[t] [no]{option}", "se[t] {option}[+-]={value}", "se[t] {option}! | inv{option}", "se[t] {option}&"],
|
||||||
short_help: "Set an option",
|
short_help: "Set an option",
|
||||||
help: "Permanently change an option. In contrast to Vim options are currently stored throughout sessions.<br/>" +
|
help: "Permanently change an option.<br/>" +
|
||||||
"<code class=\"command\">:set</code> without an argument shows all Vimperator options which differ from their default values.<br/>" +
|
"<code class=\"command\">:set</code> without an argument shows all Vimperator options which differ from their default values.<br/>" +
|
||||||
"<code class=\"command\">:set!</code> without an argument shows all about:config preferences which differ from their default values.<br/>" +
|
"<code class=\"command\">:set!</code> without an argument shows all about:config preferences which differ from their default values.<br/>" +
|
||||||
"There are three types of options: boolean, number and string. " +
|
"There are three types of options: boolean, number and string. " +
|
||||||
@@ -1798,7 +1848,8 @@ vimperator.Commands = function() //{{{
|
|||||||
"<code class=\"command\">:set option!</code> and <code class=\"command\">:set invoption</code> invert the value of a boolean option.<br/>" +
|
"<code class=\"command\">:set option!</code> and <code class=\"command\">:set invoption</code> invert the value of a boolean option.<br/>" +
|
||||||
"<code class=\"command\">:set option?</code> or <code class=\"command\">:set option</code>(for string and list options) shows the current value of an option.<br/>" +
|
"<code class=\"command\">:set option?</code> or <code class=\"command\">:set option</code>(for string and list options) shows the current value of an option.<br/>" +
|
||||||
"<code class=\"command\">:set option&</code> resets an option to its default value.<br/>" +
|
"<code class=\"command\">:set option&</code> resets an option to its default value.<br/>" +
|
||||||
"<code class=\"command\">:set option+={value}</code> and <code class=\"command\">:set option-={value}</code> adds/subtracts {value} to a number option and append/remove {value} to a string option.<br/>" +
|
"<code class=\"command\">:set option+={value}</code>, <code class=\"command\">:set option^={value}</code> and <code class=\"command\">:set option-={value}</code> " +
|
||||||
|
"adds/multiplies/subtracts <code class=\"argument\">{value}</code> from a number option and appends/prepends/removes <code class=\"argument\">{value}</code> from a string option.<br/>" +
|
||||||
"<code class=\"command\">:set all</code> shows the current value of all options and <code class=\"command\">:set all&</code> resets all options to their default values.<br/>",
|
"<code class=\"command\">:set all</code> shows the current value of all options and <code class=\"command\">:set all&</code> resets all options to their default values.<br/>",
|
||||||
completer: function(filter) { return vimperator.completion.get_options_completions(filter); }
|
completer: function(filter) { return vimperator.completion.get_options_completions(filter); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,14 @@ vimperator.Option = function(names, type, extra_info) //{{{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isValidValue = function(value)
|
||||||
|
{
|
||||||
|
if (this.validator)
|
||||||
|
return this.validator(value);
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
this.reset = function()
|
this.reset = function()
|
||||||
{
|
{
|
||||||
this.value = this.default_value;
|
this.value = this.default_value;
|
||||||
@@ -461,8 +469,8 @@ vimperator.Options = function() //{{{
|
|||||||
short_help: "Set the external text editor",
|
short_help: "Set the external text editor",
|
||||||
help: "Sets the editor to run when <code class=\"mapping\"><C-i></code> " +
|
help: "Sets the editor to run when <code class=\"mapping\"><C-i></code> " +
|
||||||
"is pressed in INSERT and TEXTAREA modes. Note that Vimperator will " +
|
"is pressed in INSERT and TEXTAREA modes. Note that Vimperator will " +
|
||||||
"not behave correctly if the editor forks its own process, such as with "+
|
"not behave correctly if the editor forks its own process, such as with "+
|
||||||
"gvim without the -f argument.",
|
"gvim without the -f argument.",
|
||||||
default_value: "gvim -f"
|
default_value: "gvim -f"
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user