1

I want C-d to act as a kind of modifier for the <left> and <right> arrow keys in a similar way to how Shift is a modifier that allows letters to be capitalized.

Shift Analogy

  • When I press a I get a
  • When I hold Shift and then press a I get A
  • When I hold Shift and then hold a I get AAAA...

Goal

  • while C-d is held down, <left> and <right> function as delete-backwards-char and delete-char respectively.
  • while C-d is held down, if <left> (or <right>) is also held down, then repeatedly call delete-backwards-char (or delete-char).

In other words, I want C-d to act as a sort of "delete-modifier" so that as long as C-d is held, I can press <left> and <right> to delete backwards and forwards. Note If C-d is not being held down, <left> and <right> should have their default behavior (moving backward and forward one character).


One of my perceived road-blocks is mentioned in the emacs manual on the topic of modifier keys:

Although only the Control and Meta modifier keys are commonly used, Emacs supports three other modifier keys. These are called Super, Hyper, and Alt.

I've had a terrible time in the past trying to get Super and Hyper to work correctly on any of (much less across) my computers, but even if I could get them working properly, I don't think these will be enough; if I use Super to act as the "delete-modifier", then I only have room for one or maybe two more before I've run out of the default modifiers emacs has to offer.

If I wanted (in addition to a "delete-modifier") a "search-modifier" that allowed me to hold down C-s and then use <left> and <right> to search backwards and forwards, then Super and Hyper would have their hands full.


I want to make extensive use of this type of functionality, and I really want to believe that if the computer games I played as a child could implement something like it, then a tool as praised for its customizability as emacs could do the same, but so far the consensus among people I ask is that they do not really know if its even possible to implement this kind of functionality.


Edit

The closest I can get on my own is to use hydra:

(global-unset-key (kbd "C-d"))
(defhydra hydra-delete (global-map "C-d")
  "delete"
  ("C-<left>" delete-backward-char) 
  ("C-<right>" delete-char))

The problem with this is that if I accidentally press any key other than <left> and <right> after holding down C-d, I'll be kicked out of this 'deletion' mode, and the only way to step back in is hold down C-d again. In practice this behavior is a lot less natural than the modifier functionality of the Shift key.

Ideally, if I hold down C-d, as long as C-d is held down, <left> and <right> do what they are bound to do, but if a key is not bound to anything, pressing it while C-d is held down does nothing.

Nika
  • 111
  • 3
  • I think the answer is that you can't do what you want. But I hope someone will contradict my impression and provide a solution! – Drew Jul 05 '22 at 17:07
  • You might be able to use a [hydra](https://github.com/abo-abo/hydra). – NickD Jul 05 '22 at 20:55
  • @NickD Actually I am using hydra at the moment. When I use hydra to bind `` to `delete-backwards-char`, if I accidentally press another key, it kicks me out of that 'mode' and I would have to `C-d` again to use `` again. Ideally, as long as `C-d` is held down, I can press whichever keys I want and all the unbound ones do nothing but the bound ones (like ``) do what they are bound to do. I'll make an edit to make this a little more clear. – Nika Jul 05 '22 at 21:03
  • Creating modifiers is not something that Emacs can do: you'll have to talk to your desktop environment/window manager/window system to do that - it may not be possible: I don't know. All I know is that Emacs cannot *create* modifier keys: they are below its consciousness horizon (so to speak). AFAIK (and that may not be far enough), X11 provides 8 modifier keys (do `xmodmap -pm` to see them), but I don't know if you can define more or how to do so if possible. Other environments *will* differ. All these are questions for another site (possibly SuperUser SE). – NickD Jul 06 '22 at 02:19
  • Well, you are just saying that behaviour with `hydra` is no different from [the behaviour with `repeat-mode`](https://emacs.stackexchange.com/a/72442/31220). This is not surprising ... Below the hood, they are doing the same / similar things. One key difference is `hydra` is NOT part of `Emacs` and has to be installed separately, but `repeat-mode` comes with `Emacs`. –  Jul 06 '22 at 05:53
  • More specifically (seeing as how it's new), `repeat-mode` comes with Emacs 28+. – phils Aug 05 '22 at 07:04
  • For the original description, what's supposed to happen if you press or hold down `C-d` *without* `` or ``? And how is that to be differentiated from your combo keystrokes? And if the answer is "`C-d` on its own does nothing", then do you actually care whether it's held down or not? (Because if not, then "modifiers" are irrelevant, and you're simply dealing with a very ordinary prefix key binding.) – phils Aug 05 '22 at 07:10

1 Answers1

0

What you are trying to modify is the behaviour of arrow keys.

;; Shifted Arrow deletes respective direction
(setq shift-select-mode shift-select-mode) ; no-op

;; S => Shift
(global-set-key (kbd "S-<right>") 'delete-char)
(global-set-key (kbd "S-<left>") 'delete-backward-char)

;; Arrow key with Control depressed, searches for a simple string in
;; respective direction

;; (lookup-key global-map (kbd "C-s") ) => isearch-forward
;; (lookup-key global-map (kbd "C-r") ) => isearch-backward

;; (lookup-key isearch-mode-map (kbd "C-s") ) =>  'isearch-repeat-forward
;; (lookup-key isearch-mode-map (kbd "C-r") ) =>  'isearch-repeat-backward

(global-set-key (kbd "C-<right>") 'isearch-forward)
(global-set-key (kbd "C-<left>") 'isearch-backward)

(define-key isearch-mode-map (kbd "C-<right>") 'isearch-repeat-forward)
(define-key isearch-mode-map (kbd "C-<left>") 'isearch-repeat-backward)

;; Arrow key with Control and Shift depressed, searches for a regexp
;; in respective direction

(global-set-key (kbd "C-S-<right>") (lambda ()
                      (interactive)
                      (isearch-forward t)))
(global-set-key (kbd "C-S-<left>") (lambda ()
                     (interactive)
                     (isearch-backward t)))

(define-key isearch-mode-map (kbd "C-S-<right>") 'isearch-repeat-forward)
(define-key isearch-mode-map (kbd "C-S-<left>") 'isearch-repeat-backward)

;; Same as above.  With <right> replaced with <down>, and <left> replaced with <up>

(global-set-key (kbd "C-<down>") 'isearch-forward)
(global-set-key (kbd "C-<up>") 'isearch-backward)

(define-key isearch-mode-map (kbd "C-<down>") 'isearch-repeat-forward)
(define-key isearch-mode-map (kbd "C-<up>") 'isearch-repeat-backward)

(global-set-key (kbd "C-S-<down>") (lambda ()
                     (interactive)
                     (isearch-forward t)))
(global-set-key (kbd "C-S-<up>") (lambda ()
                   (interactive)
                   (isearch-backward t)))

(define-key isearch-mode-map (kbd "C-S-<down>") 'isearch-repeat-forward)
(define-key isearch-mode-map (kbd "C-S-<up>") 'isearch-repeat-backward)