mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 01:47:58 +01:00
Register support with a crude kill ring.
This commit is contained in:
@@ -1759,8 +1759,7 @@ var ItemList = Class("ItemList", {
|
|||||||
set visible(val) this.container.collapsed = !val,
|
set visible(val) this.container.collapsed = !val,
|
||||||
|
|
||||||
get activeGroups() this.context.contextList
|
get activeGroups() this.context.contextList
|
||||||
.filter(function (c) c.message || c.incomplete
|
.filter(function (c) c.message || c.incomplete || c.items.length)
|
||||||
|| c.hasItems && c.items.length)
|
|
||||||
.map(this.getGroup, this),
|
.map(this.getGroup, this),
|
||||||
|
|
||||||
get selected() let (g = this.selectedGroup) g && g.selectedIdx != null &&
|
get selected() let (g = this.selectedGroup) g && g.selectedIdx != null &&
|
||||||
|
|||||||
@@ -339,16 +339,20 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
|
|||||||
* This is same as Firefox's readFromClipboard function, but is needed for
|
* This is same as Firefox's readFromClipboard function, but is needed for
|
||||||
* apps like Thunderbird which do not provide it.
|
* apps like Thunderbird which do not provide it.
|
||||||
*
|
*
|
||||||
|
* @param {string} which Which clipboard to write to. Either
|
||||||
|
* "global" or "selection". If not provided, both clipboards are
|
||||||
|
* updated.
|
||||||
|
* @optional
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
clipboardRead: function clipboardRead(getClipboard) {
|
clipboardRead: function clipboardRead(which) {
|
||||||
try {
|
try {
|
||||||
const { clipboard } = services;
|
const { clipboard } = services;
|
||||||
|
|
||||||
let transferable = services.Transferable();
|
let transferable = services.Transferable();
|
||||||
transferable.addDataFlavor("text/unicode");
|
transferable.addDataFlavor("text/unicode");
|
||||||
|
|
||||||
let source = clipboard[getClipboard || !clipboard.supportsSelectionClipboard() ?
|
let source = clipboard[which == "global" || !clipboard.supportsSelectionClipboard() ?
|
||||||
"kGlobalClipboard" : "kSelectionClipboard"];
|
"kGlobalClipboard" : "kSelectionClipboard"];
|
||||||
clipboard.getData(transferable, source);
|
clipboard.getData(transferable, source);
|
||||||
|
|
||||||
@@ -375,7 +379,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
|
|||||||
* @optional
|
* @optional
|
||||||
*/
|
*/
|
||||||
clipboardWrite: function clipboardWrite(str, verbose, which) {
|
clipboardWrite: function clipboardWrite(str, verbose, which) {
|
||||||
if (!which)
|
if (which == null)
|
||||||
services.clipboardHelper.copyString(str);
|
services.clipboardHelper.copyString(str);
|
||||||
else if (which == "selection" && !services.clipboard.supportsSelectionClipboard())
|
else if (which == "selection" && !services.clipboard.supportsSelectionClipboard())
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
// http://developer.mozilla.org/en/docs/Editor_Embedding_Guide
|
// http://developer.mozilla.org/en/docs/Editor_Embedding_Guide
|
||||||
|
|
||||||
/** @instance editor */
|
/** @instance editor */
|
||||||
var Editor = Module("editor", {
|
var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), {
|
||||||
init: function init(elem) {
|
init: function init(elem) {
|
||||||
if (elem)
|
if (elem)
|
||||||
this.element = elem;
|
this.element = elem;
|
||||||
@@ -26,6 +26,97 @@ var Editor = Module("editor", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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 registerRing() storage.newArray("register-ring", { privateData: true, store: true }),
|
||||||
|
|
||||||
|
// Fixme: Move off this object.
|
||||||
|
currentRegister: null,
|
||||||
|
|
||||||
|
defaultRegister: "*",
|
||||||
|
|
||||||
|
selectionRegisters: {
|
||||||
|
"*": "selection",
|
||||||
|
"+": "global"
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the register *name*.
|
||||||
|
*
|
||||||
|
* @param {string|number} name The name of the register to get.
|
||||||
|
* @returns {string|null}
|
||||||
|
* @see #setRegister
|
||||||
|
*/
|
||||||
|
getRegister: function getRegister(name) {
|
||||||
|
if (name == null)
|
||||||
|
name = editor.currentRegister || editor.defaultRegister;
|
||||||
|
|
||||||
|
if (name == '"')
|
||||||
|
name = 0;
|
||||||
|
if (name == "_")
|
||||||
|
var res = null;
|
||||||
|
else if (Set.has(this.selectionRegisters, name))
|
||||||
|
res = { text: dactyl.clipboardRead(this.selectionRegisters[name]) || "" };
|
||||||
|
else if (!/^[0-9]$/.test(name))
|
||||||
|
res = this.registers.get(name);
|
||||||
|
else
|
||||||
|
res = this.registerRing.get(name);
|
||||||
|
|
||||||
|
return res != null ? res.text : res;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of register *name* to value. The following
|
||||||
|
* registers have special semantics:
|
||||||
|
*
|
||||||
|
* * - Tied to the PRIMARY selection value on X11 systems.
|
||||||
|
* + - Tied to the primary global clipboard.
|
||||||
|
* _ - The null register. Never has any value.
|
||||||
|
* " - Equivalent to 0.
|
||||||
|
* 0-9 - These act as a kill ring. Setting any of them pushes the
|
||||||
|
* values of higher numbered registers up one slot.
|
||||||
|
*
|
||||||
|
* @param {string|number} name The name of the register to set.
|
||||||
|
* @param {string|Range|Selection|Node} value The value to save to
|
||||||
|
* the register.
|
||||||
|
*/
|
||||||
|
setRegister: function setRegister(name, value) {
|
||||||
|
if (name == null)
|
||||||
|
name = editor.currentRegister || editor.defaultRegister;
|
||||||
|
|
||||||
|
if (isinstance(value, [Ci.nsIDOMRange, Ci.nsIDOMNode, Ci.nsISelection]))
|
||||||
|
value = DOM.stringify(value);
|
||||||
|
value = { text: value, isLine: modes.extended & modes.LINE };
|
||||||
|
|
||||||
|
if (name == '"')
|
||||||
|
name = 0;
|
||||||
|
if (name == "_")
|
||||||
|
;
|
||||||
|
else if (Set.has(this.selectionRegisters, name))
|
||||||
|
dactyl.clipboardWrite(value.text, false, this.selectionRegisters[name]);
|
||||||
|
else if (!/^[0-9]$/.test(name))
|
||||||
|
this.registers.set(name, value);
|
||||||
|
else {
|
||||||
|
this.registerRing.insert(value, name);
|
||||||
|
this.registerRing.truncate(10);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
get isCaret() modes.getStack(1).main == modes.CARET,
|
get isCaret() modes.getStack(1).main == modes.CARET,
|
||||||
get isTextEdit() modes.getStack(1).main == modes.TEXT_EDIT,
|
get isTextEdit() modes.getStack(1).main == modes.TEXT_EDIT,
|
||||||
|
|
||||||
@@ -72,30 +163,44 @@ var Editor = Module("editor", {
|
|||||||
this.editor.setShouldTxnSetSelection(!val);
|
this.editor.setShouldTxnSetSelection(!val);
|
||||||
},
|
},
|
||||||
|
|
||||||
pasteClipboard: function pasteClipboard(clipboard) {
|
copy: function copy(range, name) {
|
||||||
let elem = this.element;
|
range = range || this.selection;
|
||||||
|
|
||||||
let text = dactyl.clipboardRead(clipboard);
|
if (!range.collapsed)
|
||||||
|
this.setRegister(name, range);
|
||||||
|
},
|
||||||
|
|
||||||
|
cut: function cut(range, name) {
|
||||||
|
if (range)
|
||||||
|
this.selectedRange = range;
|
||||||
|
|
||||||
|
if (!this.selection.isCollapsed)
|
||||||
|
this.setRegister(name, this.selection);
|
||||||
|
|
||||||
|
this.editor.deleteSelection(0);
|
||||||
|
},
|
||||||
|
|
||||||
|
paste: function paste(name) {
|
||||||
|
let text = this.getRegister(name);
|
||||||
dactyl.assert(text && this.editor instanceof Ci.nsIPlaintextEditor);
|
dactyl.assert(text && this.editor instanceof Ci.nsIPlaintextEditor);
|
||||||
|
|
||||||
this.editor.insertText(text);
|
this.editor.insertText(text);
|
||||||
},
|
},
|
||||||
|
|
||||||
// count is optional, defaults to 1
|
// count is optional, defaults to 1
|
||||||
executeCommand: function (cmd, count) {
|
executeCommand: function executeCommand(cmd, count) {
|
||||||
let controller = this.getController(cmd);
|
if (!callable(cmd)) {
|
||||||
dactyl.assert(callable(cmd) ||
|
var controller = this.getController(cmd);
|
||||||
controller &&
|
util.assert(controller &&
|
||||||
controller.supportsCommand(cmd) &&
|
controller.supportsCommand(cmd) &&
|
||||||
controller.isCommandEnabled(cmd));
|
controller.isCommandEnabled(cmd));
|
||||||
|
cmd = bind("doCommand", controller, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: better as a precondition
|
// XXX: better as a precondition
|
||||||
if (count == null)
|
if (count == null)
|
||||||
count = 1;
|
count = 1;
|
||||||
|
|
||||||
if (!callable(cmd))
|
|
||||||
cmd = bind("doCommand", controller, cmd);
|
|
||||||
|
|
||||||
let didCommand = false;
|
let didCommand = false;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
// some commands need this try/catch workaround, because a cmd_charPrevious triggered
|
// some commands need this try/catch workaround, because a cmd_charPrevious triggered
|
||||||
@@ -363,7 +468,21 @@ var Editor = Module("editor", {
|
|||||||
range.setStart(range.startContainer, range.endOffset - abbrev.lhs.length);
|
range.setStart(range.startContainer, range.endOffset - abbrev.lhs.length);
|
||||||
this.mungeRange(range, function () abbrev.expand(this.element), true);
|
this.mungeRange(range, function () abbrev.expand(this.element), true);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// nsIEditActionListener:
|
||||||
|
WillDeleteNode: util.wrapCallback(function WillDeleteNode(node) {
|
||||||
|
if (node.textContent)
|
||||||
|
this.setRegister(0, node);
|
||||||
|
}),
|
||||||
|
WillDeleteSelection: util.wrapCallback(function WillDeleteSelection(selection) {
|
||||||
|
if (!selection.isCollapsed)
|
||||||
|
this.setRegister(0, selection);
|
||||||
|
}),
|
||||||
|
WillDeleteText: util.wrapCallback(function WillDeleteText(node, start, length) {
|
||||||
|
if (length)
|
||||||
|
this.setRegister(0, node.textContent.substr(start, length));
|
||||||
|
})
|
||||||
}, {
|
}, {
|
||||||
TextsIterator: Class("TextsIterator", {
|
TextsIterator: Class("TextsIterator", {
|
||||||
init: function init(range, context, after) {
|
init: function init(range, context, after) {
|
||||||
@@ -575,6 +694,38 @@ var Editor = Module("editor", {
|
|||||||
bases: [modes.INSERT]
|
bases: [modes.INSERT]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
commands: function init_commands() {
|
||||||
|
commands.add(["reg[isters]"],
|
||||||
|
"List the contents of known registers",
|
||||||
|
function (args) {
|
||||||
|
completion.listCompleter("register", args[0]);
|
||||||
|
},
|
||||||
|
{ argCount: "*" });
|
||||||
|
},
|
||||||
|
completion: function init_completion() {
|
||||||
|
completion.register = function complete_register(context) {
|
||||||
|
context = context.fork("registers");
|
||||||
|
context.keys = { text: util.identity, description: editor.closure.getRegister };
|
||||||
|
|
||||||
|
context.match = function (r) !this.filter || ~this.filter.indexOf(r);
|
||||||
|
|
||||||
|
context.fork("clipboard", 0, this, function (ctxt) {
|
||||||
|
ctxt.match = context.match;
|
||||||
|
ctxt.title = ["Clipboard Registers"];
|
||||||
|
ctxt.completions = Object.keys(editor.selectionRegisters);
|
||||||
|
});
|
||||||
|
context.fork("kill-ring", 0, this, function (ctxt) {
|
||||||
|
ctxt.match = context.match;
|
||||||
|
ctxt.title = ["Kill Ring Registers"];
|
||||||
|
ctxt.completions = Array.slice("0123456789");
|
||||||
|
});
|
||||||
|
context.fork("user", 0, this, function (ctxt) {
|
||||||
|
ctxt.match = context.match;
|
||||||
|
ctxt.title = ["User Defined Registers"];
|
||||||
|
ctxt.completions = editor.registers.keys();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
mappings: function init_mappings() {
|
mappings: function init_mappings() {
|
||||||
|
|
||||||
Map.types["editor"] = {
|
Map.types["editor"] = {
|
||||||
@@ -676,9 +827,9 @@ var Editor = Module("editor", {
|
|||||||
editor.executeCommand("cmd_selectLineNext");
|
editor.executeCommand("cmd_selectLineNext");
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateRange(editor, forward, re, modify) {
|
function updateRange(editor, forward, re, modify, sameWord) {
|
||||||
let range = Editor.extendRange(editor.selection.getRangeAt(0),
|
let range = Editor.extendRange(editor.selection.getRangeAt(0),
|
||||||
forward, re, false, editor.rootElement);
|
forward, re, sameWord, editor.rootElement);
|
||||||
modify(range);
|
modify(range);
|
||||||
editor.selection.removeAllRanges();
|
editor.selection.removeAllRanges();
|
||||||
editor.selection.addRange(range);
|
editor.selection.addRange(range);
|
||||||
@@ -694,10 +845,11 @@ var Editor = Module("editor", {
|
|||||||
parent.input();
|
parent.input();
|
||||||
}
|
}
|
||||||
|
|
||||||
function move(forward, re)
|
function move(forward, re, sameWord)
|
||||||
function _move(editor) {
|
function _move(editor) {
|
||||||
updateRange(editor, forward, re,
|
updateRange(editor, forward, re,
|
||||||
function (range) { range.collapse(!forward); });
|
function (range) { range.collapse(!forward); },
|
||||||
|
sameWord);
|
||||||
}
|
}
|
||||||
function select(forward, re)
|
function select(forward, re)
|
||||||
function _select(editor) {
|
function _select(editor) {
|
||||||
@@ -706,7 +858,7 @@ var Editor = Module("editor", {
|
|||||||
}
|
}
|
||||||
function beginLine(editor_) {
|
function beginLine(editor_) {
|
||||||
editor.executeCommand("cmd_beginLine");
|
editor.executeCommand("cmd_beginLine");
|
||||||
move(true, /\S/)(editor_);
|
move(true, /\s/, true)(editor_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// COUNT CARET TEXT_EDIT VISUAL_TEXT_EDIT
|
// COUNT CARET TEXT_EDIT VISUAL_TEXT_EDIT
|
||||||
@@ -769,6 +921,7 @@ var Editor = Module("editor", {
|
|||||||
function ({ command, count, motion }) {
|
function ({ command, count, motion }) {
|
||||||
let start = editor.selectedRange.cloneRange();
|
let start = editor.selectedRange.cloneRange();
|
||||||
|
|
||||||
|
editor._currentMap = null;
|
||||||
modes.push(modes.OPERATOR, null, {
|
modes.push(modes.OPERATOR, null, {
|
||||||
forCommand: command,
|
forCommand: command,
|
||||||
|
|
||||||
@@ -786,6 +939,7 @@ var Editor = Module("editor", {
|
|||||||
doTxn(range, editor);
|
doTxn(range, editor);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
editor.currentRegister = null;
|
||||||
modes.delay(function () {
|
modes.delay(function () {
|
||||||
if (mode)
|
if (mode)
|
||||||
modes.push(mode);
|
modes.push(mode);
|
||||||
@@ -804,9 +958,9 @@ var Editor = Module("editor", {
|
|||||||
{ count: true, type: "motion" });
|
{ count: true, type: "motion" });
|
||||||
}
|
}
|
||||||
|
|
||||||
addMotionMap(["d", "x"], "Delete text", true, function (editor) { editor.editor.cut(); });
|
addMotionMap(["d", "x"], "Delete text", true, function (editor) { editor.cut(); });
|
||||||
addMotionMap(["c"], "Change text", true, function (editor) { editor.editor.cut(); }, modes.INSERT);
|
addMotionMap(["c"], "Change text", true, function (editor) { editor.cut(); }, modes.INSERT);
|
||||||
addMotionMap(["y"], "Yank text", false, function (editor, range) { dactyl.clipboardWrite(String(range)) });
|
addMotionMap(["y"], "Yank text", false, function (editor, range) { editor.copy(range); });
|
||||||
|
|
||||||
addMotionMap(["gu"], "Lowercase text", false,
|
addMotionMap(["gu"], "Lowercase text", false,
|
||||||
function (editor, range) {
|
function (editor, range) {
|
||||||
@@ -822,13 +976,13 @@ var Editor = Module("editor", {
|
|||||||
["c", "d", "y"], "Select the entire line",
|
["c", "d", "y"], "Select the entire line",
|
||||||
function ({ command, count }) {
|
function ({ command, count }) {
|
||||||
dactyl.assert(command == modes.getStack(0).params.forCommand);
|
dactyl.assert(command == modes.getStack(0).params.forCommand);
|
||||||
editor.executeCommand("cmd_beginLine", 1);
|
|
||||||
editor.executeCommand("cmd_selectLineNext", count || 1);
|
let sel = editor.selection;
|
||||||
let range = editor.selectedRange;
|
sel.modify("move", "backward", "lineboundary");
|
||||||
if (command == "c" && !range.collapsed) // Hack.
|
sel.modify("extend", "forward", "lineboundary");
|
||||||
if (range.endContainer instanceof Text &&
|
|
||||||
range.endContainer.textContent[range.endOffset - 1] == "\n")
|
if (command != "c")
|
||||||
editor.executeCommand("cmd_selectCharPrevious", 1);
|
sel.modify("extend", "forward", "character");
|
||||||
},
|
},
|
||||||
{ count: true, type: "operator" });
|
{ count: true, type: "operator" });
|
||||||
|
|
||||||
@@ -875,7 +1029,7 @@ var Editor = Module("editor", {
|
|||||||
function () { editor.executeCommand("cmd_deleteCharForward", 1); });
|
function () { editor.executeCommand("cmd_deleteCharForward", 1); });
|
||||||
|
|
||||||
bind(["<S-Insert>"], "Insert clipboard/selection",
|
bind(["<S-Insert>"], "Insert clipboard/selection",
|
||||||
function () { editor.pasteClipboard(); });
|
function () { editor.paste(); });
|
||||||
|
|
||||||
mappings.add([modes.INPUT],
|
mappings.add([modes.INPUT],
|
||||||
["<C-i>"], "Edit text field with an external editor",
|
["<C-i>"], "Edit text field with an external editor",
|
||||||
@@ -1005,11 +1159,25 @@ var Editor = Module("editor", {
|
|||||||
bind(["p"], "Paste clipboard contents",
|
bind(["p"], "Paste clipboard contents",
|
||||||
function ({ count }) {
|
function ({ count }) {
|
||||||
dactyl.assert(!editor.isCaret);
|
dactyl.assert(!editor.isCaret);
|
||||||
editor.executeCommand("cmd_paste", count || 1);
|
editor.executeCommand(modules.bind("paste", editor, null),
|
||||||
modes.pop(modes.TEXT_EDIT);
|
count || 1);
|
||||||
},
|
},
|
||||||
{ count: true });
|
{ count: true });
|
||||||
|
|
||||||
|
mappings.add([modes.TEXT_EDIT, modes.VISUAL],
|
||||||
|
['"'], "Bind a register to the next command",
|
||||||
|
function ({ arg }) {
|
||||||
|
editor.currentRegister = arg;
|
||||||
|
},
|
||||||
|
{ arg: true });
|
||||||
|
|
||||||
|
mappings.add([modes.INPUT],
|
||||||
|
["<C-'>", '<C-">'], "Bind a register to the next command",
|
||||||
|
function ({ arg }) {
|
||||||
|
editor.currentRegister = arg;
|
||||||
|
},
|
||||||
|
{ arg: true });
|
||||||
|
|
||||||
let bind = function bind(names, description, action, params)
|
let bind = function bind(names, description, action, params)
|
||||||
mappings.add([modes.TEXT_EDIT, modes.OPERATOR, modes.VISUAL],
|
mappings.add([modes.TEXT_EDIT, modes.OPERATOR, modes.VISUAL],
|
||||||
names, description,
|
names, description,
|
||||||
|
|||||||
@@ -191,6 +191,13 @@ var Events = Module("events", {
|
|||||||
this.listen(window, this.popups, "events", true);
|
this.listen(window, this.popups, "events", true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cleanup: function cleanup() {
|
||||||
|
let elem = dactyl.focusedElement;
|
||||||
|
if (DOM(elem).isEditable)
|
||||||
|
util.trapErrors("removeEditActionListener",
|
||||||
|
DOM(elem).editor, editor);
|
||||||
|
},
|
||||||
|
|
||||||
signals: {
|
signals: {
|
||||||
"browser.locationChange": function (webProgress, request, uri) {
|
"browser.locationChange": function (webProgress, request, uri) {
|
||||||
options.get("passkeys").flush();
|
options.get("passkeys").flush();
|
||||||
@@ -572,6 +579,10 @@ var Events = Module("events", {
|
|||||||
events: {
|
events: {
|
||||||
blur: function onBlur(event) {
|
blur: function onBlur(event) {
|
||||||
let elem = event.originalTarget;
|
let elem = event.originalTarget;
|
||||||
|
if (DOM(elem).isEditable)
|
||||||
|
util.trapErrors("removeEditActionListener",
|
||||||
|
DOM(elem).editor, editor);
|
||||||
|
|
||||||
if (elem instanceof Window && services.focus.activeWindow == null
|
if (elem instanceof Window && services.focus.activeWindow == null
|
||||||
&& document.commandDispatcher.focusedWindow !== window) {
|
&& document.commandDispatcher.focusedWindow !== window) {
|
||||||
// Deals with circumstances where, after the main window
|
// Deals with circumstances where, after the main window
|
||||||
@@ -592,6 +603,9 @@ var Events = Module("events", {
|
|||||||
// TODO: Merge with onFocusChange
|
// TODO: Merge with onFocusChange
|
||||||
focus: function onFocus(event) {
|
focus: function onFocus(event) {
|
||||||
let elem = event.originalTarget;
|
let elem = event.originalTarget;
|
||||||
|
if (DOM(elem).isEditable)
|
||||||
|
util.trapErrors("addEditActionListener",
|
||||||
|
DOM(elem).editor, editor);
|
||||||
|
|
||||||
if (elem == window)
|
if (elem == window)
|
||||||
overlay.activeWindow = window;
|
overlay.activeWindow = window;
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ var Map = Class("Map", {
|
|||||||
false);
|
false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
dactyl.triggerObserver("mappings.willExecute", this, args);
|
||||||
this.preExecute(args);
|
this.preExecute(args);
|
||||||
this.executing = true;
|
this.executing = true;
|
||||||
var res = repeat();
|
var res = repeat();
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
// given in the LICENSE.txt file included with this file.
|
// given in the LICENSE.txt file included with this file.
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||||
defineModule("completion", {
|
defineModule("completion", {
|
||||||
exports: ["CompletionContext", "Completion", "completion"]
|
exports: ["CompletionContext", "Completion", "completion"]
|
||||||
@@ -221,7 +219,7 @@ var CompletionContext = Class("CompletionContext", {
|
|||||||
},
|
},
|
||||||
get title() this.__title,
|
get title() this.__title,
|
||||||
|
|
||||||
get activeContexts() this.contextList.filter(function (c) c.hasItems && c.items.length),
|
get activeContexts() this.contextList.filter(function (c) c.items.length),
|
||||||
|
|
||||||
// Temporary
|
// Temporary
|
||||||
/**
|
/**
|
||||||
@@ -356,6 +354,7 @@ var CompletionContext = Class("CompletionContext", {
|
|||||||
yield ["context", function () self];
|
yield ["context", function () self];
|
||||||
yield ["result", quote ? function () quote[0] + util.trapErrors(1, quote, this.text) + quote[2]
|
yield ["result", quote ? function () quote[0] + util.trapErrors(1, quote, this.text) + quote[2]
|
||||||
: function () this.text];
|
: function () this.text];
|
||||||
|
yield ["texts", function () Array.concat(this.text)];
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let i in iter(this.keys, result(this.quote))) {
|
for (let i in iter(this.keys, result(this.quote))) {
|
||||||
@@ -862,10 +861,9 @@ var CompletionContext = Class("CompletionContext", {
|
|||||||
|
|
||||||
Filter: {
|
Filter: {
|
||||||
text: function (item) {
|
text: function (item) {
|
||||||
let text = item.texts || Array.concat(item.text);
|
let text = item.texts;
|
||||||
for (let [i, str] in Iterator(text)) {
|
for (let [i, str] in Iterator(text)) {
|
||||||
if (this.match(String(str))) {
|
if (this.match(String(str))) {
|
||||||
item.texts = text;
|
|
||||||
item.text = String(text[i]);
|
item.text = String(text[i]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1063,11 +1061,13 @@ var Completion = Module("completion", {
|
|||||||
context.title[0] += " " + _("completion.additional");
|
context.title[0] += " " + _("completion.additional");
|
||||||
context.filter = context.parent.filter; // FIXME
|
context.filter = context.parent.filter; // FIXME
|
||||||
context.completions = context.parent.completions;
|
context.completions = context.parent.completions;
|
||||||
|
|
||||||
// For items whose URL doesn't exactly match the filter,
|
// For items whose URL doesn't exactly match the filter,
|
||||||
// accept them if all tokens match either the URL or the title.
|
// accept them if all tokens match either the URL or the title.
|
||||||
// Filter out all directly matching strings.
|
// Filter out all directly matching strings.
|
||||||
let match = context.filters[0];
|
let match = context.filters[0];
|
||||||
context.filters[0] = function (item) !match.call(this, item);
|
context.filters[0] = function (item) !match.call(this, item);
|
||||||
|
|
||||||
// and all that don't match the tokens.
|
// and all that don't match the tokens.
|
||||||
let tokens = context.filter.split(/\s+/);
|
let tokens = context.filter.split(/\s+/);
|
||||||
context.filters.push(function (item) tokens.every(
|
context.filters.push(function (item) tokens.every(
|
||||||
@@ -1209,6 +1209,6 @@ var Completion = Module("completion", {
|
|||||||
|
|
||||||
endModule();
|
endModule();
|
||||||
|
|
||||||
} catch(e){ if (!e.stack) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
|
// catch(e){ if (!e.stack) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
|
// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
|
||||||
|
|||||||
@@ -819,7 +819,7 @@ var RangeFind = Class("RangeFind", {
|
|||||||
let start = a.compareBoundaryPoints(a.START_TO_START, b) < 0 ? a : b;
|
let start = a.compareBoundaryPoints(a.START_TO_START, b) < 0 ? a : b;
|
||||||
let end = a.compareBoundaryPoints(a.END_TO_END, b) > 0 ? a : b;
|
let end = a.compareBoundaryPoints(a.END_TO_END, b) > 0 ? a : b;
|
||||||
let res = start.cloneRange();
|
let res = start.cloneRange();
|
||||||
res.setEnd(end.startContainer, end.endOffset);
|
res.setEnd(end.endContainer, end.endOffset);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -93,12 +93,32 @@ var ArrayStore = Class("ArrayStore", StoreBase, {
|
|||||||
this.fireEvent("push", this._object.length);
|
this.fireEvent("push", this._object.length);
|
||||||
},
|
},
|
||||||
|
|
||||||
pop: function pop(value) {
|
pop: function pop(value, ord) {
|
||||||
var res = this._object.pop();
|
if (ord == null)
|
||||||
this.fireEvent("pop", this._object.length);
|
var res = this._object.pop();
|
||||||
|
else
|
||||||
|
res = this._object.splice(ord, 1)[0];
|
||||||
|
|
||||||
|
this.fireEvent("pop", this._object.length, ord);
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
shift: function shift(value) {
|
||||||
|
var res = this._object.shift();
|
||||||
|
this.fireEvent("shift", this._object.length);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
insert: function insert(value, ord) {
|
||||||
|
if (ord == 0)
|
||||||
|
this._object.unshift(value);
|
||||||
|
else
|
||||||
|
this._object = this._object.slice(0, ord)
|
||||||
|
.concat([value])
|
||||||
|
.concat(this._object.slice(ord));
|
||||||
|
this.fireEvent("insert", this._object.length, ord);
|
||||||
|
},
|
||||||
|
|
||||||
truncate: function truncate(length, fromEnd) {
|
truncate: function truncate(length, fromEnd) {
|
||||||
var res = this._object.length;
|
var res = this._object.length;
|
||||||
if (this._object.length > length) {
|
if (this._object.length > length) {
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
• Text editing improvements, including:
|
• Text editing improvements, including:
|
||||||
- Added t_gu, t_gU, and v_o mappings. [b8]
|
- Added t_gu, t_gU, and v_o mappings. [b8]
|
||||||
- Added o_c, o_d, and o_y mappings. [b8]
|
- Added o_c, o_d, and o_y mappings. [b8]
|
||||||
|
- Added register and basic kill ring support, t_" and I_<C-'>
|
||||||
|
mappings, and :registers command. [b8]
|
||||||
- Added operator modes and proper first class motion maps. [b8]
|
- Added operator modes and proper first class motion maps. [b8]
|
||||||
- Improved undo support for most mappings. [b8]
|
- Improved undo support for most mappings. [b8]
|
||||||
• General completion improvements
|
• General completion improvements
|
||||||
|
|||||||
@@ -13,15 +13,12 @@ BUGS:
|
|||||||
|
|
||||||
FEATURES:
|
FEATURES:
|
||||||
9 Add more tests.
|
9 Add more tests.
|
||||||
9 <C-o>/<C-i> should work as in Vim (i.e., save page positions as well as
|
|
||||||
locations in the history list).
|
|
||||||
9 clean up error message codes and document
|
9 clean up error message codes and document
|
||||||
9 option groups
|
9 option groups
|
||||||
9 global, window-local, tab-local, buffer-local, script-local groups
|
9 global, window-local, tab-local, buffer-local, script-local groups
|
||||||
9 add [count] support to :b* and :tab* commands where missing
|
9 add [count] support to :b* and :tab* commands where missing
|
||||||
8 wherever possible: get rid of dialogs and ask console-like dialog questions
|
8 wherever possible: get rid of dialogs and ask console-like dialog questions
|
||||||
or write error prompts directly on the webpage or with :echo()
|
or write error prompts directly on the webpage or with :echo()
|
||||||
8 registers
|
|
||||||
8 add support for filename special characters such as %
|
8 add support for filename special characters such as %
|
||||||
8 :redir and 'verbosefile'
|
8 :redir and 'verbosefile'
|
||||||
8 Add information to dactyl/HACKING file about testing and optimization
|
8 Add information to dactyl/HACKING file about testing and optimization
|
||||||
|
|||||||
Reference in New Issue
Block a user