diff --git a/content/events.js b/content/events.js index da8faec4..1298b44d 100644 --- a/content/events.js +++ b/content/events.js @@ -851,7 +851,7 @@ function Events() //{{{ // // @param keys: a string like "2" to pass // if you want < to be taken literally, prepend it with a \\ - feedkeys: function (keys, noremap) + feedkeys: function (keys, noremap, silent) { var doc = window.document; var view = window.document.defaultView; @@ -859,74 +859,85 @@ function Events() //{{{ var wasFeeding = this.feedingKeys; this.feedingKeys = true; + var wasSilent = commandline.silent; + if(silent) + commandline.silent = silent; - noremap = !!noremap; - - for (var i = 0; i < keys.length; i++) + try { - var charCode = keys.charCodeAt(i); - var keyCode = 0; - var shift = false, ctrl = false, alt = false, meta = false; + noremap = !!noremap; - //if (charCode == 92) // the '\' key FIXME: support the escape key - if (charCode == 60 && !escapeKey) // the '<' key starts a complex key + for (var i = 0; i < keys.length; i++) { - var matches = keys.substr(i + 1).match(/([CSMAcsma]-)*([^>]+)/); - if (matches && matches[2]) + var charCode = keys.charCodeAt(i); + var keyCode = 0; + var shift = false, ctrl = false, alt = false, meta = false; + + //if (charCode == 92) // the '\' key FIXME: support the escape key + if (charCode == 60 && !escapeKey) // the '<' key starts a complex key { - if (matches[1]) // check for modifiers + var matches = keys.substr(i + 1).match(/([CSMAcsma]-)*([^>]+)/); + if (matches && matches[2]) { - ctrl = /[cC]-/.test(matches[1]); - alt = /[aA]-/.test(matches[1]); - shift = /[sS]-/.test(matches[1]); - meta = /[mM]-/.test(matches[1]); - } - if (matches[2].length == 1) - { - if (!ctrl && !alt && !shift && !meta) - return false; // an invalid key like - charCode = matches[2].charCodeAt(0); - } - else if (matches[2].toLowerCase() == "space") - { - charCode = 32; - } - else if (keyCode = getKeyCode(matches[2])) - { - charCode = 0; - } - else // an invalid key like was found, stop propagation here (like Vim) - { - break; - } + if (matches[1]) // check for modifiers + { + ctrl = /[cC]-/.test(matches[1]); + alt = /[aA]-/.test(matches[1]); + shift = /[sS]-/.test(matches[1]); + meta = /[mM]-/.test(matches[1]); + } + if (matches[2].length == 1) + { + if (!ctrl && !alt && !shift && !meta) + return false; // an invalid key like + charCode = matches[2].charCodeAt(0); + } + else if (matches[2].toLowerCase() == "space") + { + charCode = 32; + } + else if (keyCode = getKeyCode(matches[2])) + { + charCode = 0; + } + else // an invalid key like was found, stop propagation here (like Vim) + { + break; + } - i += matches[0].length + 1; + i += matches[0].length + 1; + } + } + else // a simple key + { + // FIXME: does not work for non A-Z keys like Ö,Ä,... + shift = (keys[i] >= "A" && keys[i] <= "Z"); } - } - else // a simple key - { - // FIXME: does not work for non A-Z keys like Ö,Ä,... - shift = (keys[i] >= "A" && keys[i] <= "Z"); - } - var elem = window.document.commandDispatcher.focusedElement; - if (!elem) - elem = window.content; + var elem = window.document.commandDispatcher.focusedElement; + if (!elem) + elem = window.content; - var evt = doc.createEvent("KeyEvents"); - evt.initKeyEvent("keypress", true, true, view, ctrl, alt, shift, meta, keyCode, charCode); - evt.noremap = noremap; - evt.isMacro = true; - elem.dispatchEvent(evt); - if (!this.feedingKeys) - break; - // stop feeding keys if page loading failed - if (modes.isReplaying && !waitForPageLoaded()) - break; - // else // a short break between keys often helps - // liberator.sleep(50); + var evt = doc.createEvent("KeyEvents"); + evt.initKeyEvent("keypress", true, true, view, ctrl, alt, shift, meta, keyCode, charCode); + evt.noremap = noremap; + evt.isMacro = true; + elem.dispatchEvent(evt); + if (!this.feedingKeys) + break; + // stop feeding keys if page loading failed + if (modes.isReplaying && !waitForPageLoaded()) + break; + // else // a short break between keys often helps + // liberator.sleep(50); + } + } + finally + { + this.feedingKeys = wasFeeding; + if(silent) + commandline.silent = wasSilent; } - this.feedingKeys = wasFeeding; return i == keys.length; }, diff --git a/content/mappings.js b/content/mappings.js index ea8ee89a..73a6b8a2 100644 --- a/content/mappings.js +++ b/content/mappings.js @@ -170,14 +170,15 @@ function Mappings() //{{{ // 2 args -> map arg1 to arg* function map(args, mode, noremap) { - if (!args) + if (!args.arguments.length) { mappings.list(mode); return; } // ?:\s+ <- don't remember; (...)? optional = rhs - var [, lhs, rhs] = args.match(/(\S+)(?:\s+(.+))?/); + let [lhs] = args.arguments; + let rhs = args.literalArg; if (!rhs) // list the mapping { @@ -189,11 +190,11 @@ function Mappings() //{{{ { mappings.addUserMap([m], [lhs], "User defined mapping", - function (count) { events.feedkeys((count > 1 ? count : "") + rhs, noremap); }, + function (count) { events.feedkeys((count > 1 ? count : "") + rhs, noremap, "" in args); }, { flags: Mappings.flags.COUNT, rhs: rhs, - noremap: noremap + noremap: noremap, }); } } @@ -201,10 +202,19 @@ function Mappings() //{{{ modeDescription = modeDescription ? " in " + modeDescription + " mode" : ""; + const opts = { + completer: function (filter) completion.userMapping(filter, modes), + options: [ + [["", ""], commands.OPTION_NOARG] + ], + argCount: 1, + literal: true + }; + commands.add([ch ? ch + "m[ap]" : "map"], "Map a key sequence" + modeDescription, function (args) { map(args, modes, false); }, - { completer: function (filter) completion.userMapping(filter, modes) }); + opts); commands.add([ch + "no[remap]"], "Map a key sequence without remapping keys" + modeDescription, diff --git a/content/ui.js b/content/ui.js index af91279c..67a13f59 100644 --- a/content/ui.js +++ b/content/ui.js @@ -94,6 +94,8 @@ function CommandLine() //{{{ }; var lastMowOutput = null; + var silent = false; + var completionList = new ItemList("liberator-completions"); var completions = []; // for the example command "open sometext| othertext" (| is the cursor pos): @@ -108,7 +110,7 @@ function CommandLine() //{{{ var statusTimer = new util.Timer(5, 100, function () statusline.updateProgress("match " + (completionIndex + 1) + " of " + completions.length)); var autocompleteTimer = new util.Timer(201, 300, function (command) { - if (modes.isReplaying) + if (events.feedingKeys) return; let [start, compl] = completion.ex(command); commandline.setCompletions(compl, start); @@ -549,6 +551,15 @@ function CommandLine() //{{{ get mode() (modes.extended == modes.EX) ? "cmd" : "search", + get silent() silent, + set silent(val) { + silent = val; + if(silent) + storage.styles.addSheet("silent-mode", "chrome://*", "#liberator-commandline > * { opacity: 0 }", true, true); + else + storage.styles.removeSheet("silent-mode", null, null, null, true); + }, + getCommand: function () { return commandWidget.value; @@ -717,7 +728,7 @@ function CommandLine() //{{{ let mode = currentExtendedMode; // save it here, as setMode() resets it currentExtendedMode = null; /* Don't let modes.pop trigger "cancel" */ inputHistory.add(command); - modes.pop(true); + modes.pop(!commandline.silent); autocompleteTimer.reset(); completionList.hide(); liberator.focusContent(false);