X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=common%2Fcontent%2Feditor.js;fp=common%2Fcontent%2Feditor.js;h=d2fe3224b9f063b010fe42eae926f1418a41df07;hb=70740024f9c028c1fd63e1a1850ab062ff956054;hp=e1df65370adea22d02da9706ae7bccabcc88d41c;hpb=718c614c183350706466e22939d0101ca4c87efe;p=dactyl.git diff --git a/common/content/editor.js b/common/content/editor.js index e1df653..d2fe322 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -1,3 +1,4 @@ +// Copyright (c) 2008-2011 Kris Maglione // Copyright (c) 2006-2009 by Martin Stubenschrott // // This work is licensed for reuse under an MIT license. Details are @@ -24,12 +25,6 @@ var Editor = Module("editor", { 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; @@ -189,61 +184,52 @@ var Editor = Module("editor", { } }, - // 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) @@ -252,7 +238,7 @@ var Editor = Module("editor", { 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); }, @@ -266,7 +252,7 @@ var Editor = Module("editor", { 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); @@ -281,10 +267,10 @@ var Editor = Module("editor", { 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") || ""; @@ -318,19 +304,25 @@ var Editor = Module("editor", { 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"); @@ -338,8 +330,7 @@ var Editor = Module("editor", { } if (!tmpfile.write(text)) - throw Error("Input contains characters not valid in the current " + - "file encoding"); + throw Error(_("io.cantEncode")); var lastUpdate = Date.now(); @@ -414,9 +405,9 @@ var Editor = Module("editor", { 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); @@ -658,19 +649,28 @@ var Editor = Module("editor", { mappings.add([modes.INPUT], [""], "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>", + "", "", "<*-Tab>"], + "Handled by " + config.host, + function () Events.PASS_THROUGH); + mappings.add([modes.INSERT], - ["", ""], "Expand insert mode abbreviation", + ["", ""], "Expand Insert mode abbreviation", function () { editor.expandAbbreviation(modes.INSERT); - return Events.PASS; + return Events.PASS_THROUGH; }); mappings.add([modes.INSERT], - ["", ""], "Expand insert mode abbreviation", + ["", ""], "Expand Insert mode abbreviation", function () { editor.expandAbbreviation(modes.INSERT); }); // text edit mode @@ -723,15 +723,15 @@ var Editor = Module("editor", { // 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); @@ -777,7 +777,7 @@ var Editor = Module("editor", { 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); }, @@ -786,7 +786,7 @@ var Editor = Module("editor", { 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); }, @@ -795,7 +795,7 @@ var Editor = Module("editor", { 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); }, @@ -804,7 +804,7 @@ var Editor = Module("editor", { 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); }, @@ -837,10 +837,10 @@ var Editor = Module("editor", { function bind() mappings.add.apply(mappings, [[modes.AUTOCOMPLETE]].concat(Array.slice(arguments))) - bind([""], "Return to INSERT mode", + bind([""], "Return to Insert mode", function () Events.PASS_THROUGH); - bind([""], "Return to INSERT mode", + bind([""], "Return to Insert mode", function () { events.feedkeys("", { skipmap: true }); }); bind([""], "Select the previous autocomplete result", @@ -859,7 +859,7 @@ var Editor = Module("editor", { options: function () { options.add(["editor"], "The external text editor", - "string", "gvim -f + ", { + "string", 'gvim -f + +"sil! call cursor(0, )" ', { format: function (obj, value) { let args = commands.parseArgs(value || this.value, { argCount: "*", allowUnknownOptions: true }) .map(util.compileMacro).filter(function (fmt) fmt.valid(obj)) @@ -868,7 +868,7 @@ var Editor = Module("editor", { 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);