unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Siyuan Chen <chansey97@gmail.com>
To: emacs-devel@gnu.org
Subject: A possible CUA-mode bug about `cua-prefix-override-inhibit-delay` and its workaround
Date: Wed, 22 May 2024 15:25:20 +0800	[thread overview]
Message-ID: <CAHWTsYkBr=sZWLVgxjWdMJwMTY-nbcFkC93coEvA4GY2Y2=6Sw@mail.gmail.com> (raw)

[-- 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 --]

             reply	other threads:[~2024-05-22  7:25 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-22  7:25 Siyuan Chen [this message]
2024-05-24  7:28 ` A possible CUA-mode bug about `cua-prefix-override-inhibit-delay` and its workaround 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHWTsYkBr=sZWLVgxjWdMJwMTY-nbcFkC93coEvA4GY2Y2=6Sw@mail.gmail.com' \
    --to=chansey97@gmail.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).