unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* A possible CUA-mode bug about `cua-prefix-override-inhibit-delay` and its workaround
@ 2024-05-22  7:25 Siyuan Chen
  2024-05-24  7:28 ` Siyuan Chen
  2024-05-25  9:37 ` Eli Zaretskii
  0 siblings, 2 replies; 7+ messages in thread
From: Siyuan Chen @ 2024-05-22  7:25 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 4711 bytes --]

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

A possible related issue from
https://lists.gnu.org/archive/html/help-gnu-emacs/2016-06/msg00468.html

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

[-- Attachment #2: Type: text/html, Size: 12036 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-05-27 17:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-22  7:25 A possible CUA-mode bug about `cua-prefix-override-inhibit-delay` and its workaround Siyuan Chen
2024-05-24  7:28 ` Siyuan Chen
2024-05-25 17:35   ` Stefan Kangas
2024-05-27 10:20     ` Siyuan Chen
2024-05-27 17:33       ` Siyuan Chen
2024-05-27 17:38         ` Siyuan Chen
2024-05-25  9:37 ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).