unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#50804: Command substitutions for keys without keymaps
@ 2021-09-25 18:01 Stefan Kangas
  2021-09-26  6:58 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Kangas @ 2021-09-25 18:01 UTC (permalink / raw)
  To: 50804

Severity: wishlist

We have "\\[foo]" command substitutions in `substitute-command-keys'.
This also puts the face help-key-binding on the replaced text, which
makes key bindings stand out more clearly.

We don't always have a keymap to refer to, because the keys are read
through `read-key' or similar.

For example, in ispell.el:

    (message (concat "C-h or ? for more options; SPC to leave "
                     "unchanged, Character to replace word")))

In other cases, we have the same situation in a docstring, for example
in `isearch-lax-whitespace'.

It would be nice if we could have some way of putting a face on such key
bindings, without having to fiddle with propertize.  For example:

    (message (substitute-command-keys
              (concat "\\[[C-h]] or \\[[?]] for more options;
\\[[SPC]] to leave "
                      "unchanged, Character to replace word"))))

I'm not sure about the notation.  Perhaps "\\[[...]]" is okay, or
perhaps we want some other delimiter.

And perhaps we would want support for this notation also in
`format-messages'?  I'm not sure, but I'm putting it out there.





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

* bug#50804: Command substitutions for keys without keymaps
  2021-09-25 18:01 bug#50804: Command substitutions for keys without keymaps Stefan Kangas
@ 2021-09-26  6:58 ` Lars Ingebrigtsen
  2021-09-28  0:41   ` Stefan Kangas
  0 siblings, 1 reply; 12+ messages in thread
From: Lars Ingebrigtsen @ 2021-09-26  6:58 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 50804

Stefan Kangas <stefan@marxist.se> writes:

> It would be nice if we could have some way of putting a face on such key
> bindings, without having to fiddle with propertize.  For example:
>
>     (message (substitute-command-keys
>               (concat "\\[[C-h]] or \\[[?]] for more options;
> \\[[SPC]] to leave "
>                       "unchanged, Character to replace word"))))

Makes sense to me.

> I'm not sure about the notation.  Perhaps "\\[[...]]" is okay, or
> perhaps we want some other delimiter.

What about...  \\`C-h'

Hm.  Possibly too confusing.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#50804: Command substitutions for keys without keymaps
  2021-09-26  6:58 ` Lars Ingebrigtsen
@ 2021-09-28  0:41   ` Stefan Kangas
  2021-09-28  5:27     ` Lars Ingebrigtsen
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Kangas @ 2021-09-28  0:41 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 50804

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> I'm not sure about the notation.  Perhaps "\\[[...]]" is okay, or
>> perhaps we want some other delimiter.
>
> What about...  \\`C-h'
>
> Hm.  Possibly too confusing.

Using some other delimiters than "\\[]" would probably be nice though,
because:

    (substitute-command-keys "\\[[C-h]]")
    => "M-x [C-h]"

    (substitute-command-keys "\\`C-h`")
    => "\\‘C-h‘"

The second one will be printed as "\‘C-h‘" on old versions, which isn't
perfect but not too bad.  Even if the extra "\" is distracting, it is at
least not actively misleading...





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

* bug#50804: Command substitutions for keys without keymaps
  2021-09-28  0:41   ` Stefan Kangas
@ 2021-09-28  5:27     ` Lars Ingebrigtsen
  2021-11-20 15:05       ` Stefan Kangas
  0 siblings, 1 reply; 12+ messages in thread
From: Lars Ingebrigtsen @ 2021-09-28  5:27 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 50804

Stefan Kangas <stefan@marxist.se> writes:

> The second one will be printed as "\‘C-h‘" on old versions, which isn't
> perfect but not too bad.  Even if the extra "\" is distracting, it is at
> least not actively misleading...

That's a good point.  So perhaps \\`C-h' does make sense in
`substitute-command-keys'.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#50804: Command substitutions for keys without keymaps
  2021-09-28  5:27     ` Lars Ingebrigtsen
@ 2021-11-20 15:05       ` Stefan Kangas
  2021-11-21  8:26         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Kangas @ 2021-11-20 15:05 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 50804

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Stefan Kangas <stefan@marxist.se> writes:
>
>> The second one will be printed as "\‘C-h‘" on old versions, which isn't
>> perfect but not too bad.  Even if the extra "\" is distracting, it is at
>> least not actively misleading...
>
> That's a good point.  So perhaps \\`C-h' does make sense in
> `substitute-command-keys'.

I found a patch of mine from March that I had forgotten about.  It uses
the syntax "\\[=y]" to mean the key "y" where, I guess, we could
stipulate that whatever comes after "=" is `key-valid-p'.

However, it breaks backwards incompatibility just as "\\[[y]]" would:

    (substitute-command-keys "\\[=k]")
    => "M-x =k"

    (substitute-command-keys "\\[[y]]")
    => "M-x [y]"

Which is just... wrong.  So either we say that, you know, don't use this
syntax in code intended for use in anything older Emacs 29, or we just
go with the new syntax \\`y`.

Given that I have a seemingly mostly working patch it should be easy to
fix it up whichever way we decide to go.  I hope.





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

* bug#50804: Command substitutions for keys without keymaps
  2021-11-20 15:05       ` Stefan Kangas
@ 2021-11-21  8:26         ` Lars Ingebrigtsen
  2021-11-21 13:35           ` Stefan Kangas
  0 siblings, 1 reply; 12+ messages in thread
From: Lars Ingebrigtsen @ 2021-11-21  8:26 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 50804

Stefan Kangas <stefan@marxist.se> writes:

> Which is just... wrong.  So either we say that, you know, don't use this
> syntax in code intended for use in anything older Emacs 29, or we just
> go with the new syntax \\`y`.

I'd be OK to go with the new syntax here.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#50804: Command substitutions for keys without keymaps
  2021-11-21  8:26         ` Lars Ingebrigtsen
@ 2021-11-21 13:35           ` Stefan Kangas
  2021-11-21 19:56             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Kangas @ 2021-11-21 13:35 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 50804

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

tags 50804 + patch
thanks

Lars Ingebrigtsen <larsi@gnus.org> writes:

> I'd be OK to go with the new syntax here.

Maybe something like the attached?

[-- Attachment #2: 0001-Add-new-format-for-literal-key-sequences-to-substitu.patch --]
[-- Type: text/x-diff, Size: 5639 bytes --]

From 9ed0baf9f889821f37ef6f661a440dab4761978f Mon Sep 17 00:00:00 2001
From: Stefan Kangas <stefan@marxist.se>
Date: Sun, 21 Nov 2021 14:12:26 +0100
Subject: [PATCH] Add new format for literal key sequences to
 substitute-command-keys

* lisp/help.el (substitute-command-keys): Add new format "\\`f'" for
literal key sequences.
* doc/lispref/help.texi (Keys in Documentation): Document the above
new substitution.

* test/lisp/help-tests.el
(help-tests-substitute-command-keys/literal-key-sequence):
(help-tests-substitute-command-keys/literal-key-sequence-errors): New
tests.
(help-tests-substitute-key-bindings/face-help-key-binding): Extend test.
---
 doc/lispref/help.texi   |  7 +++++++
 etc/NEWS                |  9 +++++++++
 lisp/help.el            | 20 ++++++++++++++++++++
 test/lisp/help-tests.el | 19 +++++++++++++++++++
 4 files changed, 55 insertions(+)

diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index a788852de7..1a9eb30fde 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -333,6 +333,13 @@ Keys in Documentation
 specifies @var{mapvar}'s value as the keymap for any following
 @samp{\[@var{command}]} sequences in this documentation string.
 
+@item \`@var{KEYSEQ}'
+stands for a key sequence @var{KEYSEQ}, which will use the same face
+as a command substitution.  This should be used only when a key
+sequence has no corresponding command, for example when it is read
+directly with @code{read-key-sequence}.  It must be a valid key
+sequence according to @code{key-valid-p}.
+
 @item `
 (grave accent) stands for a left quote.
 This generates a left single quotation mark, an apostrophe, or a grave
diff --git a/etc/NEWS b/etc/NEWS
index bfea4da8b9..afcc438001 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -716,6 +716,15 @@ syntax.
 This is like 'kbd', but only returns vectors instead of a mix of
 vectors and strings.
 
++++
+** New substitution in docstrings and 'substitute-command-keys'.  Use
+Use "\\`KEYSEQ'" to insert a literal key sequence "KEYSEQ"
+(e.g. "C-k") in a docstring or when calling 'substitute-command-keys',
+which will use the same face as a command substitution.  This should
+be used only when a key sequence has no corresponding command, for
+example when it is read directly with 'read-key-sequence'.  It must be
+a valid key sequence according to 'key-valid-p'.
+
 +++
 ** New function 'file-name-split'.
 This returns a list of all the components of a file name.
diff --git a/lisp/help.el b/lisp/help.el
index bc3d4773da..9122d96271 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1078,6 +1078,9 @@ substitute-command-keys
 keystroke sequence that invokes COMMAND, or \"M-x COMMAND\" if COMMAND
 is not on any keys.  Keybindings will use the face `help-key-binding'.
 
+Each substring of the form \\\\=`KEYBINDING' will be replaced by
+KEYBINDING and use the `help-key-binding' face.
+
 Each substring of the form \\\\={MAPVAR} is replaced by a summary of
 the value of MAPVAR as a keymap.  This summary is similar to the one
 produced by ‘describe-bindings’.  The summary ends in two newlines
@@ -1130,6 +1133,23 @@ substitute-command-keys
                 (delete-char 2)
                 (ignore-errors
                   (forward-char 1)))
+               ((and (= (following-char) ?`)
+                     (save-excursion
+                       (prog1 (search-forward "'" nil t)
+                         (setq end-point (- (point) 2)))))
+                (goto-char orig-point)
+                (delete-char 2)
+                (goto-char (1- end-point))
+                (delete-char 1)
+                ;; (backward-char 1)
+                (let ((k (buffer-substring-no-properties orig-point (point))))
+                  (cond ((= (length k) 0)
+                         (error "Empty key sequence in substitution"))
+                        ((not (key-valid-p k))
+                         (error "Invalid key sequence in substitution: `%s'" k))))
+                (add-text-properties orig-point (point)
+                                     '( face help-key-binding
+                                        font-lock-face help-key-binding)))
                ;; 1C. \[foo] is replaced with the keybinding.
                ((and (= (following-char) ?\[)
                      (save-excursion
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
index 982750f479..281d97ee92 100644
--- a/test/lisp/help-tests.el
+++ b/test/lisp/help-tests.el
@@ -88,6 +88,25 @@ help-tests-substitute-command-keys/commands
    (test "\\[emacs-version]\\[next-line]" "M-x emacs-versionC-n")
    (test-re "\\[emacs-version]`foo'" "M-x emacs-version[`'‘]foo['’]")))
 
+(ert-deftest help-tests-substitute-command-keys/literal-key-sequence ()
+  "Literal replacement."
+  (with-substitute-command-keys-test
+   (test "\\`C-m'" "C-m")
+   (test "\\`C-m'\\`C-j'" "C-mC-j")
+   (test "foo\\`C-m'bar\\`C-j'baz" "fooC-mbarC-jbaz")))
+
+(ert-deftest help-tests-substitute-command-keys/literal-key-sequence-errors ()
+  (should-error (substitute-command-keys "\\`'"))
+  (should-error (substitute-command-keys "\\`c-c'"))
+  (should-error (substitute-command-keys "\\`<foo bar baz>'")))
+
+(ert-deftest help-tests-substitute-key-bindings/face-help-key-binding ()
+  (should (eq (get-text-property 0 'face (substitute-command-keys "\\[next-line]"))
+              'help-key-binding))
+  (should (eq (get-text-property 0 'face (substitute-command-keys "\\`f'"))
+              'help-key-binding)))
+
+
 (ert-deftest help-tests-substitute-command-keys/keymaps ()
   (with-substitute-command-keys-test
    (test-re "\\{minibuffer-local-must-match-map}"
-- 
2.30.2


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

* bug#50804: Command substitutions for keys without keymaps
  2021-11-21 13:35           ` Stefan Kangas
@ 2021-11-21 19:56             ` Lars Ingebrigtsen
  2021-11-22  5:48               ` Stefan Kangas
  0 siblings, 1 reply; 12+ messages in thread
From: Lars Ingebrigtsen @ 2021-11-21 19:56 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 50804

Stefan Kangas <stefan@marxist.se> writes:

> Maybe something like the attached?

Makes sense to me.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#50804: Command substitutions for keys without keymaps
  2021-11-21 19:56             ` Lars Ingebrigtsen
@ 2021-11-22  5:48               ` Stefan Kangas
  2021-11-22 15:10                 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Kangas @ 2021-11-22  5:48 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 50804

close 50804 29.1
thanks

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Makes sense to me.

Thanks, pushed (commit 1aef1a6673).





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

* bug#50804: Command substitutions for keys without keymaps
  2021-11-22  5:48               ` Stefan Kangas
@ 2021-11-22 15:10                 ` Eli Zaretskii
  2021-11-22 15:15                   ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2021-11-22 15:10 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: larsi, 50804

> From: Stefan Kangas <stefan@marxist.se>
> Date: Mon, 22 Nov 2021 06:48:29 +0100
> Cc: 50804@debbugs.gnu.org
> 
> Lars Ingebrigtsen <larsi@gnus.org> writes:
> 
> > Makes sense to me.
> 
> Thanks, pushed (commit 1aef1a6673).

The NEWS entry says:

  ** New substitution in docstrings and 'substitute-command-keys'.
  Use "\\`KEYSEQ'" to insert a literal key sequence "KEYSEQ"
  (e.g. "C-k") in a docstring or when calling 'substitute-command-keys',

Shouldn't that be "\\`C-k" instead?





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

* bug#50804: Command substitutions for keys without keymaps
  2021-11-22 15:10                 ` Eli Zaretskii
@ 2021-11-22 15:15                   ` Eli Zaretskii
  2021-11-22 15:29                     ` Stefan Kangas
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2021-11-22 15:15 UTC (permalink / raw)
  To: stefan; +Cc: larsi, 50804

> Date: Mon, 22 Nov 2021 17:10:13 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: larsi@gnus.org, 50804@debbugs.gnu.org
> 
>   ** New substitution in docstrings and 'substitute-command-keys'.
>   Use "\\`KEYSEQ'" to insert a literal key sequence "KEYSEQ"
>   (e.g. "C-k") in a docstring or when calling 'substitute-command-keys',
> 
> Shouldn't that be "\\`C-k" instead?

Actually, it should be "\\`C-k'", right?  (And I'd drop the outer
quotes, as they muddy the waters.)






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

* bug#50804: Command substitutions for keys without keymaps
  2021-11-22 15:15                   ` Eli Zaretskii
@ 2021-11-22 15:29                     ` Stefan Kangas
  0 siblings, 0 replies; 12+ messages in thread
From: Stefan Kangas @ 2021-11-22 15:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Lars Ingebrigtsen, 50804

Eli Zaretskii <eliz@gnu.org> writes:

> >   ** New substitution in docstrings and 'substitute-command-keys'.
> >   Use "\\`KEYSEQ'" to insert a literal key sequence "KEYSEQ"
> >   (e.g. "C-k") in a docstring or when calling 'substitute-command-keys',
> >
> > Shouldn't that be "\\`C-k" instead?
>
> Actually, it should be "\\`C-k'", right?  (And I'd drop the outer
> quotes, as they muddy the waters.)

Yup, that's better, thanks.  Now fixed on master.





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

end of thread, other threads:[~2021-11-22 15:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-25 18:01 bug#50804: Command substitutions for keys without keymaps Stefan Kangas
2021-09-26  6:58 ` Lars Ingebrigtsen
2021-09-28  0:41   ` Stefan Kangas
2021-09-28  5:27     ` Lars Ingebrigtsen
2021-11-20 15:05       ` Stefan Kangas
2021-11-21  8:26         ` Lars Ingebrigtsen
2021-11-21 13:35           ` Stefan Kangas
2021-11-21 19:56             ` Lars Ingebrigtsen
2021-11-22  5:48               ` Stefan Kangas
2021-11-22 15:10                 ` Eli Zaretskii
2021-11-22 15:15                   ` Eli Zaretskii
2021-11-22 15:29                     ` Stefan Kangas

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