+// Copyright (c) 2008-2011 Kris Maglione <maglione.k at Gmail>
// Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
//
// This work is licensed for reuse under an MIT license. Details are
selectedText: function () String(Editor.getEditor(null).selection),
pasteClipboard: function (clipboard, toStart) {
- // TODO: I don't think this is needed anymore? --djk
- if (util.OS.isWindows) {
- this.executeCommand("cmd_paste");
- return;
- }
-
let elem = dactyl.focusedElement;
if (elem.inputField)
elem = elem.inputField;
}
},
- // returns the position of char
- findCharForward: function (ch, count) {
- if (!Editor.getEditor())
+ findChar: function (key, count, backward) {
+
+ let editor = Editor.getEditor();
+ if (!editor)
return -1;
- let text = Editor.getEditor().value;
// XXX
if (count == null)
count = 1;
- for (let i = Editor.getEditor().selectionEnd + 1; i < text.length; i++) {
- if (text[i] == "\n")
- break;
- if (text[i] == ch)
- count--;
- if (count == 0)
- return i + 1; // always position the cursor after the char
- }
+ let code = events.fromString(key)[0].charCode;
+ util.assert(code);
+ let char = String.fromCharCode(code);
- dactyl.beep();
- return -1;
- },
-
- // returns the position of char
- findCharBackward: function (ch, count) {
- if (!Editor.getEditor())
- return -1;
-
- let text = Editor.getEditor().value;
- // XXX
- if (count == null)
- count = 1;
+ let text = editor.value;
+ let caret = editor.selectionEnd;
+ if (backward) {
+ let end = text.lastIndexOf("\n", caret);
+ while (caret > end && caret >= 0 && count--)
+ caret = text.lastIndexOf(char, caret - 1);
+ }
+ else {
+ let end = text.indexOf("\n", caret);
+ if (end == -1)
+ end = text.length;
- for (let i = Editor.getEditor().selectionStart - 1; i >= 0; i--) {
- if (text[i] == "\n")
- break;
- if (text[i] == ch)
- count--;
- if (count == 0)
- return i;
+ while (caret < end && caret >= 0 && count--)
+ caret = text.indexOf(char, caret + 1);
}
- dactyl.beep();
- return -1;
+ if (count > 0)
+ caret = -1;
+ if (caret == -1)
+ dactyl.beep();
+ return caret;
},
/**
* Edits the given file in the external editor as specified by the
* 'editor' option.
*
- * @param {object|File|string} args An object specifying the file,
- * line, and column to edit. If a non-object is specified, it is
- * treated as the file parameter of the object.
+ * @param {object|File|string} args An object specifying the file, line,
+ * and column to edit. If a non-object is specified, it is treated as
+ * the file parameter of the object.
* @param {boolean} blocking If true, this function does not return
- * until the editor exits.
+ * until the editor exits.
*/
editFileExternally: function (args, blocking) {
if (!isObject(args) || args instanceof File)
let args = options.get("editor").format(args);
- dactyl.assert(args.length >= 1, _("editor.noEditor"));
+ dactyl.assert(args.length >= 1, _("option.notSet", "editor"));
io.run(args.shift(), args, blocking);
},
let line, column;
if (!forceEditing && textBox && textBox.type == "password") {
- commandline.input("Editing a password field externally will reveal the password. Would you like to continue? (yes/[no]): ",
+ commandline.input(_("editor.prompt.editPassword") + " ",
function (resp) {
if (resp && resp.match(/^y(es)?$/i))
editor.editFieldExternally(true);
column = 1 + pre.replace(/[^]*\n/, "").length;
}
else {
- var editor = window.GetCurrentEditor ? GetCurrentEditor()
- : Editor.getEditor(document.commandDispatcher.focusedWindow);
- dactyl.assert(editor);
- text = Array.map(editor.rootElement.childNodes, function (e) util.domToString(e, true)).join("");
+ var editor_ = window.GetCurrentEditor ? GetCurrentEditor()
+ : Editor.getEditor(document.commandDispatcher.focusedWindow);
+ dactyl.assert(editor_);
+ text = Array.map(editor_.rootElement.childNodes, function (e) util.domToString(e, true)).join("");
}
let origGroup = textBox && textBox.getAttributeNS(NS, "highlight") || "";
lastUpdate = Date.now();
let val = tmpfile.read();
- if (textBox)
+ if (textBox) {
textBox.value = val;
+
+ textBox.setAttributeNS(NS, "modifiable", true);
+ util.computedStyle(textBox).MozUserInput;
+ events.dispatch(textBox, events.create(textBox.ownerDocument, "input", {}));
+ textBox.removeAttributeNS(NS, "modifiable");
+ }
else {
- while (editor.rootElement.firstChild)
- editor.rootElement.removeChild(editor.rootElement.firstChild);
- editor.rootElement.innerHTML = val;
+ while (editor_.rootElement.firstChild)
+ editor_.rootElement.removeChild(editor_.rootElement.firstChild);
+ editor_.rootElement.innerHTML = val;
}
}
try {
var tmpfile = io.createTempFile();
if (!tmpfile)
- throw Error("Couldn't create temporary file");
+ throw Error(_("io.cantCreateTempFile"));
if (textBox) {
highlight.highlightNode(textBox, origGroup + " EditorEditing");
}
if (!tmpfile.write(text))
- throw Error("Input contains characters not valid in the current " +
- "file encoding");
+ throw Error(_("io.cantEncode"));
var lastUpdate = Date.now();
elem = dactyl.focusedElement || document.commandDispatcher.focusedWindow;
dactyl.assert(elem);
- if (elem instanceof Element)
- return elem.QueryInterface(Ci.nsIDOMNSEditableElement).editor;
try {
+ if (elem instanceof Element)
+ return elem.QueryInterface(Ci.nsIDOMNSEditableElement).editor;
return elem.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIEditingSession)
.getEditorForWindow(elem);
mappings.add([modes.INPUT],
["<C-t>"], "Edit text field in Vi mode",
function () {
+ dactyl.assert(dactyl.focusedElement);
dactyl.assert(!editor.isTextEdit);
modes.push(modes.TEXT_EDIT);
});
+ // Ugh.
+ mappings.add([modes.INPUT, modes.CARET],
+ ["<*-CR>", "<*-BS>", "<*-Del>", "<*-Left>", "<*-Right>", "<*-Up>", "<*-Down>",
+ "<*-Home>", "<*-End>", "<*-PageUp>", "<*-PageDown>",
+ "<M-c>", "<M-v>", "<*-Tab>"],
+ "Handled by " + config.host,
+ function () Events.PASS_THROUGH);
+
mappings.add([modes.INSERT],
- ["<Space>", "<Return>"], "Expand insert mode abbreviation",
+ ["<Space>", "<Return>"], "Expand Insert mode abbreviation",
function () {
editor.expandAbbreviation(modes.INSERT);
- return Events.PASS;
+ return Events.PASS_THROUGH;
});
mappings.add([modes.INSERT],
- ["<C-]>", "<C-5>"], "Expand insert mode abbreviation",
+ ["<C-]>", "<C-5>"], "Expand Insert mode abbreviation",
function () { editor.expandAbbreviation(modes.INSERT); });
// text edit mode
// visual mode
mappings.add([modes.CARET, modes.TEXT_EDIT],
- ["v"], "Start visual mode",
+ ["v"], "Start Visual mode",
function () { modes.push(modes.VISUAL); });
mappings.add([modes.VISUAL],
- ["v", "V"], "End visual mode",
+ ["v", "V"], "End Visual mode",
function () { modes.pop(); });
mappings.add([modes.TEXT_EDIT],
- ["V"], "Start visual line mode",
+ ["V"], "Start Visual Line mode",
function () {
modes.push(modes.VISUAL, modes.LINE);
editor.executeCommand("cmd_beginLine", 1);
mappings.add([modes.TEXT_EDIT, modes.VISUAL],
["f"], "Move to a character on the current line after the cursor",
function ({ arg, count }) {
- let pos = editor.findCharForward(arg, Math.max(count, 1));
+ let pos = editor.findChar(arg, Math.max(count, 1));
if (pos >= 0)
editor.moveToPosition(pos, true, modes.main == modes.VISUAL);
},
mappings.add([modes.TEXT_EDIT, modes.VISUAL],
["F"], "Move to a character on the current line before the cursor",
function ({ arg, count }) {
- let pos = editor.findCharBackward(arg, Math.max(count, 1));
+ let pos = editor.findChar(arg, Math.max(count, 1), true);
if (pos >= 0)
editor.moveToPosition(pos, false, modes.main == modes.VISUAL);
},
mappings.add([modes.TEXT_EDIT, modes.VISUAL],
["t"], "Move before a character on the current line",
function ({ arg, count }) {
- let pos = editor.findCharForward(arg, Math.max(count, 1));
+ let pos = editor.findChar(arg, Math.max(count, 1));
if (pos >= 0)
editor.moveToPosition(pos - 1, true, modes.main == modes.VISUAL);
},
mappings.add([modes.TEXT_EDIT, modes.VISUAL],
["T"], "Move before a character on the current line, backwards",
function ({ arg, count }) {
- let pos = editor.findCharBackward(arg, Math.max(count, 1));
+ let pos = editor.findChar(arg, Math.max(count, 1), true);
if (pos >= 0)
editor.moveToPosition(pos + 1, false, modes.main == modes.VISUAL);
},
function bind() mappings.add.apply(mappings,
[[modes.AUTOCOMPLETE]].concat(Array.slice(arguments)))
- bind(["<Esc>"], "Return to INSERT mode",
+ bind(["<Esc>"], "Return to Insert mode",
function () Events.PASS_THROUGH);
- bind(["<C-[>"], "Return to INSERT mode",
+ bind(["<C-[>"], "Return to Insert mode",
function () { events.feedkeys("<Esc>", { skipmap: true }); });
bind(["<Up>"], "Select the previous autocomplete result",
options: function () {
options.add(["editor"],
"The external text editor",
- "string", "gvim -f +<line> <file>", {
+ "string", 'gvim -f +<line> +"sil! call cursor(0, <column>)" <file>', {
format: function (obj, value) {
let args = commands.parseArgs(value || this.value, { argCount: "*", allowUnknownOptions: true })
.map(util.compileMacro).filter(function (fmt) fmt.valid(obj))
args.push(obj["file"]);
return args;
},
- has: function (key) set.has(util.compileMacro(this.value).seen, key),
+ has: function (key) Set.has(util.compileMacro(this.value).seen, key),
validator: function (value) {
this.format({}, value);
return Object.keys(util.compileMacro(value).seen).every(function (k) ["column", "file", "line"].indexOf(k) >= 0);