emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

One character key bindings in editing buffers


From: JJ
Subject: One character key bindings in editing buffers
Date: Mon, 30 Jul 2018 17:28:26 +0200

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)))
 
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]