1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 11:27:58 +01:00

Fix some hinting bugs.

--HG--
branch : key-processing
This commit is contained in:
Kris Maglione
2011-01-24 02:37:14 -05:00
parent 0a422502ba
commit b3d91db6b4
5 changed files with 119 additions and 82 deletions

View File

@@ -893,18 +893,17 @@ var CommandLine = Module("commandline", {
*/ */
input: function _input(prompt, callback, extra) { input: function _input(prompt, callback, extra) {
extra = extra || {}; extra = extra || {};
let closure = extra.closure || extra;
this._input = { this._input = {
submit: callback || closure.onAccept, submit: callback || extra.onAccept,
change: closure.onChange, change: extra.onChange,
complete: closure.completer, complete: extra.completer,
cancel: closure.onCancel cancel: extra.onCancel
}; };
modes.push(modes.COMMAND_LINE, modes.PROMPT | extra.extended, modes.push(modes.COMMAND_LINE, modes.PROMPT | extra.extended,
update(Object.create(extra), { update(Object.create(extra), {
onEvent: closure.onEvent || this.closure.onEvent, onEvent: extra.onEvent || this.extra.onEvent,
leave: function leave(stack) { leave: function leave(stack) {
commandline.leave(stack); commandline.leave(stack);
leave.supercall(extra, stack); leave.supercall(extra, stack);
@@ -965,7 +964,6 @@ var CommandLine = Module("commandline", {
for (let node in array.iterValues(event.target.children)) { for (let node in array.iterValues(event.target.children)) {
let group = node.getAttributeNS(NS, "group"); let group = node.getAttributeNS(NS, "group");
util.dump(node, group, group && !group.split(/\s+/).every(function (g) enabled[g]));
node.hidden = group && !group.split(/\s+/).every(function (g) enabled[g]); node.hidden = group && !group.split(/\s+/).every(function (g) enabled[g]);
} }
} }
@@ -1672,6 +1670,13 @@ var CommandLine = Module("commandline", {
[":"], "Enter command-line mode", [":"], "Enter command-line mode",
function () { commandline.open(":", "", modes.EX); }); function () { commandline.open(":", "", modes.EX); });
mappings.add([modes.COMMAND],
["g<lt>"], "Redisplay the last command output",
function () {
dactyl.assert(commandline._lastMowOutput, "No previous command output");
commandline._echoMultiline(commandline._lastMowOutput, commandline.HL_NORMAL);
});
let bind = function bind() let bind = function bind()
mappings.add.apply(mappings, [[modes.COMMAND_LINE]].concat(Array.slice(arguments))) mappings.add.apply(mappings, [[modes.COMMAND_LINE]].concat(Array.slice(arguments)))
@@ -1728,12 +1733,6 @@ var CommandLine = Module("commandline", {
bind(["<C-]>", "<C-5>"], "Expand command line abbreviation", bind(["<C-]>", "<C-5>"], "Expand command line abbreviation",
function () { editor.expandAbbreviation(modes.COMMAND_LINE); }); function () { editor.expandAbbreviation(modes.COMMAND_LINE); });
bind(["g<"], "Redisplay the last command output",
function () {
dactyl.assert(commandline._lastMowOutput, "No previous command output");
commandline._echoMultiline(commandline._lastMowOutput, commandline.HL_NORMAL);
});
let mow = modules.mow = { let mow = modules.mow = {
__noSuchMethod__: function (meth, args) Buffer[meth].apply(Buffer, [this.body].concat(args)) __noSuchMethod__: function (meth, args) Buffer[meth].apply(Buffer, [this.body].concat(args))
}; };

View File

@@ -51,9 +51,7 @@ var Editor = Module("editor", {
elem.scrollTop = top; elem.scrollTop = top;
elem.scrollLeft = left; elem.scrollLeft = left;
let event = elem.ownerDocument.createEvent("Event"); events.dispatch(elem, events.create(elem.ownerDocument, "input"));
event.initEvent("input", true, false);
events.dispatch(elem, event);
} }
}, },

View File

@@ -530,9 +530,10 @@ var Events = Module("events", {
* *
* @param {Document} doc The DOM document to associate this event with * @param {Document} doc The DOM document to associate this event with
* @param {Type} type The type of event (keypress, click, etc.) * @param {Type} type The type of event (keypress, click, etc.)
* @param {Object} opts The pseudo-event. * @param {Object} opts The pseudo-event. @optional
*/ */
create: function (doc, type, opts) { create: function (doc, type, opts) {
opts = opts || {};
var DEFAULTS = { var DEFAULTS = {
HTML: { HTML: {
type: type, bubbles: true, cancelable: false type: type, bubbles: true, cancelable: false
@@ -557,7 +558,7 @@ var Events = Module("events", {
} }
}; };
const TYPES = { const TYPES = {
change: "", change: "", input: "",
click: "Mouse", mousedown: "Mouse", mouseup: "Mouse", click: "Mouse", mousedown: "Mouse", mouseup: "Mouse",
mouseover: "Mouse", mouseout: "Mouse", mouseover: "Mouse", mouseout: "Mouse",
keypress: "Key", keyup: "Key", keydown: "Key" keypress: "Key", keyup: "Key", keydown: "Key"
@@ -566,7 +567,9 @@ var Events = Module("events", {
var evt = doc.createEvent((t || "HTML") + "Events"); var evt = doc.createEvent((t || "HTML") + "Events");
let defaults = DEFAULTS[t || "HTML"] let defaults = DEFAULTS[t || "HTML"]
evt["init" + t + "Event"].apply(evt, Object.keys(defaults).map(function (k) k in opts ? opts[k] : defaults[k])); evt["init" + t + "Event"].apply(evt, Object.keys(defaults)
.map(function (k) k in opts ? opts[k]
: defaults[k]));
return evt; return evt;
}, },
@@ -988,12 +991,28 @@ var Events = Module("events", {
}, },
*/ */
input: function onInput(event) {
delete event.originalTarget.dactylKeyPress;
},
// this keypress handler gets always called first, even if e.g. // this keypress handler gets always called first, even if e.g.
// the command-line has focus // the command-line has focus
// TODO: ...help me...please... // TODO: ...help me...please...
keypress: function onKeyPress(event) { keypress: function onKeyPress(event) {
event.dactylDefaultPrevented = event.getPreventDefault(); event.dactylDefaultPrevented = event.getPreventDefault();
// Hack to deal with <BS> and so forth not dispatching input
// events
if (event.originalTarget instanceof HTMLInputElement) {
let elem = event.originalTarget;
elem.dactylKeyPress = elem.value;
util.timeout(function () {
if ("dactylKeyPress" in elem && elem.value !== elem.dactylKeyPress)
events.dispatch(elem, events.create(elem.ownerDocument, "input"));
delete events.dactylKeyPress;
});
}
let duringFeed = this.duringFeed || []; let duringFeed = this.duringFeed || [];
this.duringFeed = []; this.duringFeed = [];
try { try {

View File

@@ -31,7 +31,7 @@ var HintSession = Class("HintSession", {
this.usedTabKey = false; this.usedTabKey = false;
this.validHints = []; // store the indices of the "hints" array with valid elements this.validHints = []; // store the indices of the "hints" array with valid elements
commandline.input(UTF8(this.mode.prompt) + ": ", null, this); commandline.input(UTF8(this.mode.prompt) + ": ", null, this.closure);
modes.extended = modes.HINTS; modes.extended = modes.HINTS;
this.top = opts.window || content; this.top = opts.window || content;
@@ -80,6 +80,17 @@ var HintSession = Class("HintSession", {
this.activeTimeout = null; this.activeTimeout = null;
}, },
_escapeNumbers: false,
get escapeNumbers() this._escapeNumbers,
set escapeNumbers(val) {
this.clearTimeout();
this._escapeNumbers = !!val;
if (val && this.usedTabKey)
this.hintNumber = 0;
this.updateStatusline();
},
/** /**
* Returns the hint string for a given number based on the values of * Returns the hint string for a given number based on the values of
* the 'hintkeys' option. * the 'hintkeys' option.
@@ -322,7 +333,7 @@ var HintSession = Class("HintSession", {
this.clearTimeout(); this.clearTimeout();
if (!this.escNumbers && this.isHintKey(key)) { if (!this.escapeNumbers && this.isHintKey(key)) {
this.prevInput = "number"; this.prevInput = "number";
let oldHintNumber = this.hintNumber; let oldHintNumber = this.hintNumber;
@@ -586,11 +597,61 @@ var HintSession = Class("HintSession", {
} }
}, },
backspace: function () {
this.clearTimeout();
if (this.prevInput !== "number")
return Events.PASS;
if (this.hintNumber > 0 && !this.usedTabKey) {
this.hintNumber = Math.floor(this.hintNumber / this.hintKeys.length);
if (this.hintNumber == 0)
this.prevInput = "text";
this.update(false);
}
else {
this.usedTabKey = false;
this.hintNumber = 0;
dactyl.beep();
}
return Events.KILL;
},
tab: function tab(previous) {
this.clearTimeout();
this.usedTabKey = true;
if (this.hintNumber == 0)
this.hintNumber = 1;
let oldId = this.hintNumber;
if (!previous) {
if (++this.hintNumber > this.validHints.length)
this.hintNumber = 1;
}
else {
if (--this.hintNumber < 1)
this.hintNumber = this.validHints.length;
}
this.showActiveHint(this.hintNumber, oldId);
this.updateStatusline();
},
update: function update(followFirst) {
this.clearTimeout();
this.updateStatusline();
if (this.docs.length == 0 && this.hintString.length > 0)
this.generate();
this.show();
this.process(followFirst);
},
/** /**
* Display the current status to the user. * Display the current status to the user.
*/ */
updateStatusline: function _updateStatusline() { updateStatusline: function _updateStatusline() {
statusline.updateInputBuffer((hints.escNumbers ? options["mapleader"] : "") + statusline.updateInputBuffer((this.escapeNumbers ? options["mapleader"] : "") +
(this.hintNumber ? this.getHintString(this.hintNumber) : "")); (this.hintNumber ? this.getHintString(this.hintNumber) : ""));
}, },
}); });
@@ -1034,79 +1095,26 @@ var Hints = Module("hints", {
function ({ count }) { hints.open("g;", { continue: true, count: count }); }, function ({ count }) { hints.open("g;", { continue: true, count: count }); },
{ count: true }); { count: true });
function update(followFirst) {
hints.clearTimeout();
hints._updateStatusline();
if (hints._docs.length == 0 && hints._hintString.length > 0)
hints._generate();
hints._showHints();
hints._processHints(followFirst);
}
mappings.add(modes.HINTS, ["<Return>"], mappings.add(modes.HINTS, ["<Return>"],
"Follow the selected hint", "Follow the selected hint",
function () { update(true); }); function () { hints.hintSession.update(true); });
function tab(previous) {
hints.clearTimeout();
this._usedTabKey = true;
if (this._hintNumber == 0)
this._hintNumber = 1;
let oldId = this._hintNumber;
if (!previous) {
if (++this._hintNumber > this._validHints.length)
this._hintNumber = 1;
}
else {
if (--this._hintNumber < 1)
this._hintNumber = this._validHints.length;
}
this._showActiveHint(this._hintNumber, oldId);
this._updateStatusline();
}
mappings.add(modes.HINTS, ["<Tab>"], mappings.add(modes.HINTS, ["<Tab>"],
"Focus the next matching hint", "Focus the next matching hint",
function () { tab.call(hints, false); }); function () { hints.hintSession.tab(false); });
mappings.add(modes.HINTS, ["<S-Tab>"], mappings.add(modes.HINTS, ["<S-Tab>"],
"Focus the previous matching hint", "Focus the previous matching hint",
function () { tab.call(hints, true); }); function () { hints.hintSession.tab(true); });
mappings.add(modes.HINTS, ["<BS>", "<C-h>"], mappings.add(modes.HINTS, ["<BS>", "<C-h>"],
"Delete the previous character", "Delete the previous character",
function () { function () hints.hintSession.backspace());
hints.clearTimeout();
if (hints.prevInput !== "number")
return Events.PASS;
if (hints._hintNumber > 0 && !hints._usedTabKey) {
hints._hintNumber = Math.floor(hints._hintNumber / hints.hintKeys.length);
if (hints._hintNumber == 0)
hints.prevInput = "text";
update(false);
}
else {
hints._usedTabKey = false;
hints._hintNumber = 0;
dactyl.beep();
}
return Events.KILL;
});
mappings.add(modes.HINTS, ["<Leader>"], mappings.add(modes.HINTS, ["<Leader>"],
"Toggle hint filtering", "Toggle hint filtering",
function () { function () {
hints.clearTimeout(); hints.hintSession.escapeNumbers = !hints.hintSession.escapeNumbers;
hints.escNumbers = !hints.escNumbers;
if (hints.escNumbers && hints._usedTabKey)
hints._hintNumber = 0;
hints._updateStatusline();
}); });
}, },
options: function () { options: function () {

View File

@@ -803,10 +803,23 @@ Class.prototype = {
}; };
memoize(Class.prototype, "closure", function () { memoize(Class.prototype, "closure", function () {
const self = this; const self = this;
function closure(fn) function () fn.apply(self, arguments); function closure(fn) function () {
for (let k in iter(properties(this), properties(this, true))) try {
return fn.apply(self, arguments);
}
catch (e) {
util.reportError(e);
}
}
iter(properties(this), properties(this, true)).forEach(function (k) {
if (!this.__lookupGetter__(k) && callable(this[k])) if (!this.__lookupGetter__(k) && callable(this[k]))
closure[k] = closure(this[k]); closure[k] = closure(this[k]);
else if (!(k in closure || k in Object.prototype))
Object.defineProperty(closure, k, {
get: function get_proxy() self[k],
set: function set_proxy(val) self[k] = val,
});
}, this);
return closure; return closure;
}); });