Hi Emacs-devel team,
Currently, there seems to be a bug in CUA-mode, i.e. when `(setq cua-prefix-override-inhibit-delay nil)`, cut and copy do not work.
From the `cua-prefix-override-inhibit-delay` docs
> If non-nil, time in seconds to delay before overriding prefix key. If there is additional input within this time, the prefix key is used as a normal prefix key. So typing a key sequence quickly will inhibit overriding the prefix key. As a special case, if the prefix key is repeated within this time, the first prefix key is discarded, so typing a prefix key twice in quick succession will also inhibit overriding the prefix key.
> If the value is nil, use a shifted prefix key to inhibit the override."
So I assume that
(1) CUA-mode allows user `(setq cua-prefix-override-inhibit-delay nil)`.
(2) When `(setq cua-prefix-override-inhibit-delay nil)`, CUA-mode should disable the timer feature, and expect the user to use Shift instead, i.e. the old prefix key `C-x` -> new prefix key `C-S-x`.
Unfortunately, it is not the case. `(setq cua-prefix-override-inhibit-delay nil)` will cause a totally disabled CUA-mode feature, i.e. selecting a region and pressing `C-x` never cuts the region. This obviously breaks the docs behavior!
Noticed that in cua-base.el, the `cua--prefix-override-replay` pushes back the key `^X` to `unread-command-events` via `(setq unread-command-events (cons (cons 'no-record key) unread-command-events))`, but no one handles it in `cua--xxxx-keymap`. Yeah, when `(setq cua-prefix-override-inhibit-delay 0.2)`, there will be a timeout version keymap to handle
```
(define-key cua--cua-keys-keymap [(control x) timeout] #'kill-region)
(define-key cua--cua-keys-keymap [(control c) timeout] #'copy-region-as-kill)
```
but no 'no-record
version when `(setq cua-prefix-override-inhibit-delay nil)`
.
The following provides
a workaround.
It does `kill-region` and `copy-region-as-kill
` directly in `cua--prefix-override-keymap` when `
cua-prefix-override-inhibit-delay` is nil (or < 0).
```
(defun --sc-cua--prefix-override-ctl-x ()
(interactive)
(if (or (not (numberp cua-prefix-override-inhibit-delay))
(<= cua-prefix-override-inhibit-delay 0))
(call-interactively #'kill-region)
(call-interactively #'cua--prefix-override-handler)))
(defun --sc-cua--prefix-override-ctl-c ()
(interactive)
(if (or (not (numberp cua-prefix-override-inhibit-delay))
(<= cua-prefix-override-inhibit-delay 0))
(call-interactively #'copy-region-as-kill)
(call-interactively #'cua--prefix-override-handler)))
(defun --sc-cua--init-keymaps()
(define-key cua--prefix-override-keymap [(control x)] #'--sc-cua--prefix-override-ctl-x)
(define-key cua--prefix-override-keymap [(control c)] #'--sc-cua--prefix-override-ctl-c))
(advice-add 'cua--init-keymaps :after #'--sc-cua--init-keymaps)
```
It worked well on my
end, so I'm sharing it here in case someone is interested and hoping it can be merged upstream
(The `sc` defun prefix is just my naming space, so don't care about it)
.
The 2nd question someone might ask: Why do we have to set
`(setq cua-prefix-override-inhibit-delay nil)`
and use the Shift version as prefix keys? Why not keep the default value `0.2`?
The reason is that `0.2` prevents users from quick copy/cut operations!
Let's do a simple experiment:
1. Enable cua-mode and
`(setq cua-prefix-override-inhibit-delay 1)`.
2. You have two buffers, called BufferA and BufferB.
3. Go to
BufferA
and suppose there are two words in it, `Hello` and `World` in it.
4. Select the `Hello` and press Ctrl+C and wait 1 second.
5. Select the
`World`
and press Ctrl+X and quickly switch to BufferB (via mouse click tab in tab-line).
6. In BufferB, press
Ctrl+V.
The expected behavior is
the "World" is pasted but Emacs pastes
`Hello`. Reducing the `cua-prefix-override-inhibit-delay` value (e.g. `0.01`) can partially rescue the problem, but not much if someone is operating very
very
fast and
makes the problem hard to detect. That is
why we have to set
`(setq cua-prefix-override-inhibit-delay nil)`!
The user said that
> The symptoms are that I select some text (using the shifted arrowkeys), copy it with C-c, switch to another application (typically an input form in web browser) and paste. At this point I realise that mycopy operation failed, as I get a stale clipboard value pasted.
I guess the user's issue is related to this one.
Tested in GNU Emacs 28.2 on Windows (I believe the 29.3 has the same problem because `cua-base.el` is not much different except two defalias).
Thanks.
Best regards,
Siyuan Chen