From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: JJ Newsgroups: gmane.emacs.devel Subject: One character key bindings in editing buffers Date: Mon, 30 Jul 2018 17:28:26 +0200 Message-ID: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/html; charset=UTF-8 X-Trace: blaine.gmane.org 1532965411 28390 195.159.176.226 (30 Jul 2018 15:43:31 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 30 Jul 2018 15:43:31 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Jul 30 17:43:27 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1fkAKU-0007GM-0c for ged-emacs-devel@m.gmane.org; Mon, 30 Jul 2018 17:43:26 +0200 Original-Received: from localhost ([::1]:53363 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fkAMa-00059U-Ns for ged-emacs-devel@m.gmane.org; Mon, 30 Jul 2018 11:45:36 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:49181) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fkA62-00017g-R1 for emacs-devel@gnu.org; Mon, 30 Jul 2018 11:28:31 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fkA60-0001KD-4K for emacs-devel@gnu.org; Mon, 30 Jul 2018 11:28:30 -0400 Original-Received: from mout.gmx.com ([74.208.4.200]:49691) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fkA5z-0001Jv-SC for emacs-devel@gnu.org; Mon, 30 Jul 2018 11:28:28 -0400 Original-Received: from [193.15.16.4] ([193.15.16.4]) by web-mail.mail.com (3c-app-mailcom-lxa04.server.lan [10.76.45.5]) (via HTTP); Mon, 30 Jul 2018 17:28:26 +0200 Importance: normal Sensitivity: Normal X-Priority: 3 X-Provags-ID: V03:K1:bexndOlHytsJx3tEjL69woCaiTrXgWDBOSsaUws+nC3FdtAEhC6FXX/4Xd4h7oHp5c0gD phTN2zAfBEgiOOKgw2zsyOFd54jbdpGUaOG+CXF5/gX34dEG+FUyw62ErgNeHarJo39bss6bIbGM HdUXjytbszRJihSkP4LL7UBmG/UMjSyb6suwZtScgHrSYQHnw/6D4q01aJfVmx8grsMt3wtGHLR0 ixSZzSkePbQtuW78lQyiqCTlSPYPeHQgFpg45gZ1ezQoRoTe08FRiVlGDy+jYyxLWFOEd+MXkx0o Bc= X-UI-Out-Filterresults: notjunk:1;V01:K0:llo26G9H2cY=:vmdasMFOOpRQXW2dQcaMzb G4GEsL6sYk1O1y3U5mC2mtoMaRcNsUt2n/HvG/m8tQAFyXn79Ndo3cwexzaHyci/AUmGFs4Py Xvn7+9BhKfZEf7Ku11I9T64Ycl9W1e3EP9STTKYfbwWSTJXIgNqrOCvYqCCxmEnl8eZJsnZ/H CYt9ALsofaMVJbJDSSTmUAyE9S80mF1E9bsMgRGVyNiDDMx9ufK4qbjN5nn1LO69+c5tW5h0b GoUhtXbObJA6JKCHPp8UesvIRkmyEfNUfHWsT9VHpnPL0id/KkyHGHzmKQKzl8Gx+3C2Uudw3 DNnyhCTjaPdLx0vccLf/WNbpjIwqIohcKLOoRsU3na1wgHRvZo8joY1VEH0IU529TJVamuWcd bs90tQ8+slVx0FN/Imfe/OKAdskss9+aJ8S/RJtsd1TBmCzRKUUXNIXVblfVUnieJSDI6SSYt Nu0RaEk+v9pv3PhLCCI/f/QysXitfy6NdNGftvGjYspFN9eL++0o X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.208.4.200 X-Mailman-Approved-At: Mon, 30 Jul 2018 11:42:15 -0400 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:227999 Archived-At:
I post this here in case somebody finds this useful and maybe
even gets inspired and writes a proper package for this.
 
There are various packages optimizing keybindings (e.g. key
chord), but those require more than one keypresses in editing
buffers. The following technique replaces multikey bindings with
only one character even in editing buffers.
 
The idea is when typing in an editing buffer one very rarely
types only a single character without others preceding or
following it, so if only a single character is typed then it can
execute a command. If other characters are also typed then it
behaves as usual and inserts that character.
 
I've been using this every day in the last 3 weeks and it works
very well and it's one of the major convenience gains for me in
recent years using emacs.
 
The actual command bindings are up to the user, currently, I use
it mainly for VC and coding related stuff. When I write code then
I do diffs, logs, commits, reverts, etc. all day and this
technique replaced the default long bindings for me, e.g. in an
editor buffer I can simply type 'd' for diff, instead of 'C-x v
='.
 
Configuring it is only a matter of setting a variable either
globally, or locally in a mode hook.
 
For example, I use something similar to this:
 
    (setq char-hotkey-commands
          '((?r . vc-revert)
            (?d . vc-diff)
            (?l . vc-print-log)
            (?v . vc-next-action)))

It simply lists the keys with the corresponding commands.
 
And here's the minor mode which handles the defined keys when
activated in a buffer:
 
 
(setq char-hotkey-typing nil)
 
(defun char-hotkey ()
  (interactive)
  (if (and char-hotkey-mode
           (not char-hotkey-typing)
           (sit-for 0.5))
      (call-interactively (assoc-default last-command-event char-hotkey-commands))
    (call-interactively 'self-insert-command)))

(defun char-hotkey-wait-for-end ()
  (setq char-hotkey-typing t)
  (when (or (not (or (equal this-command 'self-insert-command)
                     (equal this-command 'char-hotkey)))
             (sit-for 0.5))
    (setq char-hotkey-typing nil)))
 
(define-minor-mode char-hotkey-mode
  "Char hotkey."
  :lighter " CH"
 
  (if char-hotkey-mode
      (progn
        (dolist (command char-hotkey-commands)
          (local-set-key (char-to-string (car command)) 'char-hotkey))
        (add-hook 'post-command-hook 'char-hotkey-wait-for-end nil t))
 
    (dolist (command char-hotkey-commands)
      (local-set-key (char-to-string (car command)) 'self-insert-command))
    (remove-hook 'post-command-hook 'char-hotkey-wait-for-end t)))