Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a binding to get a keystring #658

Open
mgraham opened this issue May 7, 2015 · 2 comments
Open

Add a binding to get a keystring #658

mgraham opened this issue May 7, 2015 · 2 comments
Labels
priority: 3 - wishlist Issues which are not important and/or where it's unclear whether they're feasible.

Comments

@mgraham
Copy link

mgraham commented May 7, 2015

When editing Vim's config file, I can press CTRL-V and then press a key. This will show me the keycode for that key as Vim understands it.

For instance, with my wacky keyboard mapping, CAPS-A is mapped to F18 (don't ask). In Vim's insert mode, pressing CTRL-V followed by CAPS-A inserts <F18>.

However, in qutebrowser, pressing CAPS-A seems to insert the clipboard contents at the cursor position. I'd like to debug this.

Is there any way of seeing what key code qutebrowser is receiving?

The-Compiler added a commit that referenced this issue May 12, 2015
@The-Compiler
Copy link
Member

I just add a minimal script to print keypresses - use python3 -m scripts.keytester to launch it.

I'll probably add Ctrl-V to the input bar in the future though, as it's useful for keybindings indeed. Though that'd shadow Ctrl-V for pasting from clipboard...

@The-Compiler The-Compiler added the priority: 3 - wishlist Issues which are not important and/or where it's unclear whether they're feasible. label Oct 1, 2015
@The-Compiler
Copy link
Member

Partial patch by @Carpetsmoker in #958:

From 26e2999ca144bc9188f3bde120c9f0cddce31fcf Mon Sep 17 00:00:00 2001
From: Martin Tournoij <martin@arp242.net>
Date: Fri, 18 Sep 2015 14:15:01 +0200
Subject: [PATCH] Add a command to show the keystring for a key.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fixes at least part of #658. Note that this is not the same as <C-v> in
Vim. In Vim, <C-v> is used to insert keys (not show their keystring). You can do
cool stuff like <C-v>x07 to insert 0x07, or `<C-v>u2713` to insert ✓

Adding that to the input bar and/or insert mode in text forms is another thing
altogether...

I've mapped in to <C-k> by the way, as <C-v> is already taken...
---
 doc/help/commands.asciidoc       |  5 +++++
 qutebrowser/config/configdata.py |  3 +++
 qutebrowser/keyinput/modeman.py  | 28 +++++++++++++++++++++++++++-
 qutebrowser/utils/message.py     |  7 ++++++-
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc
index 0125229..6748345 100644
--- a/doc/help/commands.asciidoc
+++ b/doc/help/commands.asciidoc
@@ -813,6 +813,7 @@ How many steps to zoom out.
 |<<scroll-px,scroll-px>>|Scroll the current tab by 'count * dx/dy' pixels.
 |<<search-next,search-next>>|Continue the search to the ([count]th) next term.
 |<<search-prev,search-prev>>|Continue the search to the ([count]th) previous term.
+|<<show-keystring,show-keystring>>|Show the keystring for the next pressed key.
 |<<toggle-selection,toggle-selection>>|Toggle caret selection mode.
 |==============
 [[clear-keychain]]
@@ -1165,6 +1166,10 @@ Continue the search to the ([count]th) previous term.
 ==== count
 How many elements to ignore.

+[[show-keystring]]
+=== show-keystring
+Show the keystring for the next pressed key.
+
 [[toggle-selection]]
 === toggle-selection
 Toggle caret selection mode.
diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py
index 53c95bd..1b5b92e 100644
--- a/qutebrowser/config/configdata.py
+++ b/qutebrowser/config/configdata.py
@@ -1178,6 +1178,8 @@ def data(readonly=False):
 # with Shift. For special keys (with `<>`-signs), you need to explicitly add
 # `Shift-` to match a key pressed with shift.  You can bind multiple commands
 # by separating them with `;;`.
+#
+# You can use <Ctrl-k> to get the name of a key.
 """

 KEY_SECTION_DESC = {
@@ -1355,6 +1357,7 @@ def data(readonly=False):
         ('open qute:settings', ['Ss']),
         ('follow-selected', RETURN_KEYS),
         ('follow-selected -t', ['<Ctrl-Return>', '<Ctrl-Enter>']),
+        ('show-keystring', ['<Ctrl-k>']),
     ])),

     ('insert', collections.OrderedDict([
diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py
index 6906a87..f7fee55 100644
--- a/qutebrowser/keyinput/modeman.py
+++ b/qutebrowser/keyinput/modeman.py
@@ -28,7 +28,7 @@
 from qutebrowser.keyinput import modeparsers, keyparser
 from qutebrowser.config import config
 from qutebrowser.commands import cmdexc, cmdutils
-from qutebrowser.utils import usertypes, log, objreg, utils
+from qutebrowser.utils import usertypes, log, objreg, utils, message


 class KeyEvent:
@@ -125,6 +125,7 @@ class ModeManager(QObject):
         _releaseevents_to_pass: A set of KeyEvents where the keyPressEvent was
                                 passed through, so the release event should as
                                 well.
+        _show_key: Show the next pressed key, and don't do anything.

     Signals:
         entered: Emitted when a mode is entered.
@@ -143,6 +144,7 @@ def __init__(self, win_id, parent=None):
         super().__init__(parent)
         self._win_id = win_id
         self._parsers = {}
+        self._show_key = False
         self.mode = usertypes.KeyMode.normal
         self._releaseevents_to_pass = set()
         self._forward_unbound_keys = config.get(
@@ -310,6 +312,24 @@ def eventFilter(self, event):
         Return:
             True if event should be filtered, False otherwise.
         """
+
+        # The keypress to start "show key mode" also ends up here
+        if self._show_key == 1:
+            self._show_key = 2
+            return True
+
+        if self._show_key == 2:
+            key = utils.keyevent_to_string(event)
+
+            # Only modifier key
+            if key is not None:
+                if len(key) > 1:
+                    key = '<{}>'.format(key)
+                self._show_key = False
+                message.set_text(self._win_id, '')
+                message.info(self._win_id, 'Pressed key: {}'.format(key))
+            return True
+
         if self.mode is None:
             # We got events before mode is set, so just pass them through.
             return False
@@ -322,3 +342,9 @@ def eventFilter(self, event):
     def clear_keychain(self):
         """Clear the currently entered key chain."""
         self._parsers[self.mode].clear_keystring()
+
+    @cmdutils.register(instance='mode-manager', scope='window', hide=True)
+    def show_keystring(self):
+        """Show the keystring for the next pressed key."""
+        message.set_text(self._win_id, 'Press a key')
+        self._show_key = 1
diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py
index 26bd75b..48a4101 100644
--- a/qutebrowser/utils/message.py
+++ b/qutebrowser/utils/message.py
@@ -141,8 +141,13 @@ def info(win_id, message, immediately=True):
     _wrapper(win_id, 'info', message, immediately)


+def set_text(win_id, txt):
+    """Convienience function to set the normal text of the statusbar."""
+    _wrapper(win_id, 'set_text', txt)
+
+
 def set_cmd_text(win_id, txt):
-    """Convienience function to Set the statusbar command line to a text."""
+    """Convienience function to set the statusbar command line to a text."""
     _wrapper(win_id, 'set_cmd_text', txt)

My comments:


This seems to show k as K and Shift+k as <Shift+K>. That probably should show up as k or K instead.

Something like this would work:

txt = event.text()
if len(txt) == 1 and unicodedata.category(txt) != 'Cc':
    key = txt    
else:
    key = utils.keyevent_to_string(event)

I think it'd be nicer to make _show_key an enum, e.g. ShowKeyState = usertypes.enum('ShowKeyState', 'ignore, capture') on class level, and then something like this here:

if self._show_key == self.ShowKeyState.ignore:
    self._show_key = self.ShowKeyState.capture

...

Hm, I also wonder if this should really be a command (or a keybinding) in general - what about some workflow like this:

  • Invoke :bind without any key given
  • Key press prompt shows, user presses key
  • Commandline is filled with :bind <Key>

Is this functionality needed outside of :bind?

@The-Compiler The-Compiler changed the title How to see the keystroke that qutebrowser received? Add a binding to get a keystring Jul 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: 3 - wishlist Issues which are not important and/or where it's unclear whether they're feasible.
Projects
None yet
Development

No branches or pull requests

2 participants