1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 22:47:59 +01:00

Register and selection magic.

This commit is contained in:
Kris Maglione
2011-10-09 23:52:00 -04:00
parent d444435600
commit 400ec6244b
4 changed files with 97 additions and 62 deletions

View File

@@ -26,22 +26,6 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
}); });
}, },
signals: {
"mappings.willExecute": function mappings_willExecute(map) {
if (this.currentRegister && !(this._currentMap && this._wait == util.yielders)) {
this._currentMap = map;
this._wait = util.yielders;
}
},
"mappings.executed": function mappings_executed(map) {
if (this._currentMap == map) {
this.currentRegister = null;
this._wait = util.yielders;
this._currentMap = null;
}
}
},
get registers() storage.newMap("registers", { privateData: true, store: true }), get registers() storage.newMap("registers", { privateData: true, store: true }),
get registerRing() storage.newArray("register-ring", { privateData: true, store: true }), get registerRing() storage.newArray("register-ring", { privateData: true, store: true }),
@@ -50,6 +34,18 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
// Fixme: Move off this object. // Fixme: Move off this object.
currentRegister: null, currentRegister: null,
/**
* Temporarily set the default register for the span of the next
* mapping.
*/
pushRegister: function pushRegister(arg) {
let restore = this.currentRegister;
this.currentRegister = arg;
mappings.afterCommands(2, function () {
this.currentRegister = restore;
}, this);
},
defaultRegister: "*", defaultRegister: "*",
selectionRegisters: { selectionRegisters: {
@@ -97,7 +93,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
* @param {string|Range|Selection|Node} value The value to save to * @param {string|Range|Selection|Node} value The value to save to
* the register. * the register.
*/ */
setRegister: function setRegister(name, value) { setRegister: function setRegister(name, value, verbose) {
if (name == null) if (name == null)
name = editor.currentRegister || editor.defaultRegister; name = editor.currentRegister || editor.defaultRegister;
@@ -110,7 +106,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
if (name == "_") if (name == "_")
; ;
else if (Set.has(this.selectionRegisters, name)) else if (Set.has(this.selectionRegisters, name))
dactyl.clipboardWrite(value.text, false, this.selectionRegisters[name]); dactyl.clipboardWrite(value.text, verbose, this.selectionRegisters[name]);
else if (!/^[0-9]$/.test(name)) else if (!/^[0-9]$/.test(name))
this.registers.set(name, value); this.registers.set(name, value);
else { else {
@@ -608,21 +604,21 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
} }
}), }),
extendRange: function extendRange(range, forward, re, sameWord, root) { extendRange: function extendRange(range, forward, re, sameWord, root, end) {
function advance(positive) { function advance(positive) {
while (true) { while (true) {
while (idx == text.length && (node = iterator.getNext())) { while (idx == text.length && (node = iterator.getNext())) {
if (node == iterator.start) if (node == iterator.start)
idx = range.endOffset; idx = range[offset];
offset = text.length; start = text.length;
text += node.textContent; text += node.textContent;
range.setEnd(node, idx - offset); range[set](node, idx - start);
} }
if (idx >= text.length || re.test(text[idx]) != positive) if (idx >= text.length || re.test(text[idx]) != positive)
break; break;
range.setEnd(range.endContainer, ++idx - offset); range[set](range[container], ++idx - start);
} }
} }
function retreat(positive) { function retreat(positive) {
@@ -630,21 +626,26 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
while (idx == 0 && (node = iterator.getPrev())) { while (idx == 0 && (node = iterator.getPrev())) {
let str = node.textContent; let str = node.textContent;
if (node == iterator.start) if (node == iterator.start)
idx = range.startOffset; idx = range[offset];
else else
idx = str.length; idx = str.length;
text = str + text; text = str + text;
range.setStart(node, idx); range[set](node, idx);
} }
if (idx == 0 || re.test(text[idx - 1]) != positive) if (idx == 0 || re.test(text[idx - 1]) != positive)
break; break;
range.setStart(range.startContainer, --idx); range[set](range[container], --idx);
} }
} }
if (end == null)
end = forward ? "end" : "start";
let [container, offset, set] = [end + "Container", end + "Offset",
"set" + util.capitalize(end)];
if (!root) if (!root)
for (root = range.startContainer; for (root = range[container];
root.parentNode instanceof Element && !DOM(root).isEditable; root.parentNode instanceof Element && !DOM(root).isEditable;
root = root.parentNode) root = root.parentNode)
; ;
@@ -653,13 +654,13 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
if (root instanceof Ci.nsIEditor) if (root instanceof Ci.nsIEditor)
root = root.rootElement; root = root.rootElement;
let node = range[forward ? "endContainer" : "startContainer"]; let node = range[container];
let iterator = Editor.TextsIterator(RangeFind.nodeContents(root), let iterator = Editor.TextsIterator(RangeFind.nodeContents(root),
node, !forward); node, !forward);
let text = ""; let text = "";
let idx = 0; let idx = 0;
let offset = 0; let start = 0;
if (forward) { if (forward) {
advance(true); advance(true);
@@ -886,11 +887,17 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
} }
function updateRange(editor, forward, re, modify, sameWord) { function updateRange(editor, forward, re, modify, sameWord) {
let range = Editor.extendRange(editor.selection.getRangeAt(0), let sel = editor.selection;
forward, re, sameWord, editor.rootElement); let range = sel.getRangeAt(0);
let end = range.endContainer == sel.focusNode && range.endOffset == sel.focusOffset;
if (range.collapsed)
end = forward;
Editor.extendRange(range, forward, re, sameWord,
editor.rootElement, end ? "end" : "start");
modify(range); modify(range);
editor.selection.removeAllRanges(); editor.selectionController.repaintSelection(editor.selectionController.SELECTION_NORMAL);
editor.selection.addRange(range);
} }
function clear(forward, re) function clear(forward, re)
@@ -979,13 +986,14 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
function ({ command, count, motion }) { function ({ command, count, motion }) {
let start = editor.selectedRange.cloneRange(); let start = editor.selectedRange.cloneRange();
editor._currentMap = null; mappings.pushCommand();
modes.push(modes.OPERATOR, null, { modes.push(modes.OPERATOR, null, {
forCommand: command, forCommand: command,
count: count, count: count,
leave: function leave(stack) { leave: function leave(stack) {
try {
if (stack.push || stack.fromEscape) if (stack.push || stack.fromEscape)
return; return;
@@ -1003,6 +1011,11 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
modes.push(mode); modes.push(mode);
}); });
} }
finally {
if (!stack.push)
mappings.popCommand();
}
}
}); });
}, },
{ count: true, type: "motion" }); { count: true, type: "motion" });
@@ -1011,7 +1024,7 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
desc, desc,
function ({ count, motion }) { function ({ count, motion }) {
dactyl.assert(caretOk || editor.isTextEdit); dactyl.assert(caretOk || editor.isTextEdit);
if (modes.isTextEdit) if (editor.isTextEdit)
doTxn(editor.selectedRange, editor); doTxn(editor.selectedRange, editor);
else else
cmd(editor, buffer.selection.getRangeAt(0)); cmd(editor, buffer.selection.getRangeAt(0));
@@ -1232,14 +1245,14 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
mappings.add([modes.COMMAND], mappings.add([modes.COMMAND],
['"'], "Bind a register to the next command", ['"'], "Bind a register to the next command",
function ({ arg }) { function ({ arg }) {
editor.currentRegister = arg; editor.pushRegister(arg);
}, },
{ arg: true }); { arg: true });
mappings.add([modes.INPUT], mappings.add([modes.INPUT],
["<C-'>", '<C-">'], "Bind a register to the next command", ["<C-'>", '<C-">'], "Bind a register to the next command",
function ({ arg }) { function ({ arg }) {
editor.currentRegister = arg; editor.pushRegister(arg);
}, },
{ arg: true }); { arg: true });

View File

@@ -135,6 +135,7 @@ var Map = Class("Map", {
try { try {
dactyl.triggerObserver("mappings.willExecute", this, args); dactyl.triggerObserver("mappings.willExecute", this, args);
mappings.pushCommand();
this.preExecute(args); this.preExecute(args);
this.executing = true; this.executing = true;
var res = repeat(); var res = repeat();
@@ -145,6 +146,7 @@ var Map = Class("Map", {
} }
finally { finally {
this.executing = false; this.executing = false;
mappings.popCommand();
this.postExecute(args); this.postExecute(args);
dactyl.triggerObserver("mappings.executed", this, args); dactyl.triggerObserver("mappings.executed", this, args);
} }
@@ -320,6 +322,31 @@ var MapHive = Class("MapHive", Contexts.Hive, {
*/ */
var Mappings = Module("mappings", { var Mappings = Module("mappings", {
init: function () { init: function () {
this.watches = [];
this._watchStack = 0;
this._yielders = 0;
},
afterCommands: function afterCommands(count, cmd, self) {
this.watches.push([cmd, self, Math.max(this._watchStack - 1, 0), count || 1]);
},
pushCommand: function pushCommand(cmd) {
this._watchStack++;
this._yielders = util.yielders;
},
popCommand: function popCommand(cmd) {
this._watchStack = Math.max(this._watchStack - 1, 0);
if (util.yielders > this._yielders)
this._watchStack = 0;
this.watches = this.watches.filter(function (elem) {
if (elem[2] <= this._watchStack)
elem[3]--;
if (elem[3] <= 0)
elem[0].call(elem[1] || null);
return elem[3] > 0;
}, this);
}, },
repeat: Modes.boundProperty(), repeat: Modes.boundProperty(),

View File

@@ -54,16 +54,9 @@ var Tabs = Module("tabs", {
enter: function enter() { enter: function enter() {
if (window.TabsInTitlebar) if (window.TabsInTitlebar)
window.TabsInTitlebar.allowedBy("dactyl", true); window.TabsInTitlebar.allowedBy("dactyl", true);
}
}, },
"mappings.executed": function mappings_executed() {
if (this._mappingCount && !--this._mappingCount)
dactyl.forceTarget = null;
},
},
_mappingCount: 0,
_alternates: Class.Memoize(function () [config.tabbrowser.mCurrentTab, null]), _alternates: Class.Memoize(function () [config.tabbrowser.mCurrentTab, null]),
cleanup: function cleanup() { cleanup: function cleanup() {
@@ -1116,8 +1109,10 @@ var Tabs = Module("tabs", {
mappings.add([modes.COMMAND], ["<C-t>", "<new-tab-next>"], mappings.add([modes.COMMAND], ["<C-t>", "<new-tab-next>"],
"Execute the next mapping in a new tab", "Execute the next mapping in a new tab",
function ({ count }) { function ({ count }) {
tabs._mappingCount = (count || 1) + 1;
dactyl.forceTarget = dactyl.NEW_TAB; dactyl.forceTarget = dactyl.NEW_TAB;
mappings.afterCommands((count || 1) + 1, function () {
dactyl.forceTarget = null;
});
}, },
{ count: true }); { count: true });

View File

@@ -1247,7 +1247,7 @@ var Buffer = Module("Buffer", {
return ""; return "";
let range = selection.getRangeAt(0).cloneRange(); let range = selection.getRangeAt(0).cloneRange();
if (range.collapsed && range.startContainer instanceof Ci.nsIDOMText) { if (range.collapsed) {
let re = options.get("iskeyword").regexp; let re = options.get("iskeyword").regexp;
Editor.extendRange(range, true, re, true); Editor.extendRange(range, true, re, true);
Editor.extendRange(range, false, re, true); Editor.extendRange(range, false, re, true);
@@ -1824,7 +1824,7 @@ var Buffer = Module("Buffer", {
events.listen(config.browser, "scroll", buffer.closure._updateBufferPosition, false); events.listen(config.browser, "scroll", buffer.closure._updateBufferPosition, false);
}, },
mappings: function initMappings(dactyl, modules, window) { mappings: function initMappings(dactyl, modules, window) {
let { Editor, Events, buffer, events, ex, mappings, modes, options, tabs } = modules; let { Editor, Events, buffer, editor, events, ex, mappings, modes, options, tabs } = modules;
mappings.add([modes.NORMAL], mappings.add([modes.NORMAL],
["y", "<yank-location>"], "Yank current location to the clipboard", ["y", "<yank-location>"], "Yank current location to the clipboard",
@@ -2094,7 +2094,7 @@ var Buffer = Module("Buffer", {
function () { function () {
let sel = buffer.currentWord; let sel = buffer.currentWord;
dactyl.assert(sel); dactyl.assert(sel);
dactyl.clipboardWrite(sel, true); editor.setRegister(null, sel, true);
}); });
// zooming // zooming