Subject: bug#54074: 29.0.50; Feature request emacs keymap-set and minor-modes

From: Ergus <[email-masked]>
Date: Sun, 20 Feb 2022 20:04:31 +0100

Hi:

1)

Recently I have seen that many packages have a pattern where a global
minor mode adds a set of keybindings to another (like isearch or
minibuffer). The issue comes when they want to disable the mode, because
sometimes they need to iterate or loop over, and then emacs looses the
previous binding unless they also adds more code to remember it when set
and then bring it back when unset.

So far with nested keymaps this could be solved, but there is not any
clean way to do that; so my request is to extend the new keymap-set to
set keymap without a prefix in another...

The idea is more or less to enable the developers of packages to do
something like:

```
(defvar-keymap my-mode-isearch-map
     ...)

(define-minor-mode my-mode
    :global t
    (if my-mode
        (keymap-set isearch-mode-map <something> my-mode-isearch-map)
      (keymap-unset isearch-mode-map <something>)))
```

With that then could be trivial to implemented something like
use-packages :bind, so

(define-minor-mode my-mode
    :global t
    :keymap (my-mode-map
             :map isearch-mode-map my-mode-isearch-map))

or similar... I am wondering how nobody have requested this before, when
it is a very common issue I find in many packages around.

2)

Something similar happens to some variables that are modified in minor
modes and then should be restored... this forces sometimes to restart
emacs... (for example completion-styles in fido-mode or some hooks that
are always added and then need to be removed... all these is very
mechanic and increases code and sources of errors...).

The best approach for this one is to save the original value in an alist
and assign with a wrapper around setq...  and use a loop when disabling
the mode to restore the original values.... it is not perfect, but works
in many cases...

To restore the original value they check if the current vars's value is
the same that was set (to assert it was not changed latter).

This way if I try fido-mode and I don't like it, then not restart is
needed to assert that completion-styles is what I had before...

Maybe we could consider to add some api for these functionalities...

Does it makes sense??

In GNU Emacs 29.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.31, cairo version 1.17.4)
 of 2022-02-20 built on Ergus
Repository revision: e6f541f2383cf860c6a2d6c8d366c21a3b8de2d0
Repository branch: master
System Description: Arch Linux

Configured using:
 'configure --prefix=/home/ergo/.local/ --with-mailutils --with-json
 --with-x-toolkit=gtk3 --with-xft --with-wide-int --with-modules
 --with-cairo --with-harfbuzz --with-native-compilation --with-pgtk'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER
PGTK PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS
WEBP XIM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  electric-pair-mode: t
  global-auto-revert-mode: t
  xclip-mode: t
  flyspell-mode: t
  company-mode: t
  flycheck-mode: t
  diff-hl-margin-mode: t
  composable-mark-mode: t
  composable-mode: t
  repeat-mode: t
  xterm-mouse-mode: t
  my/consult-mode: t
  vertico-mouse-mode: t
  vertico-mode: t
  minibuffer-depth-indicate-mode: t
  winner-mode: t
  save-place-mode: t
  delete-selection-mode: t
  savehist-mode: t
  global-display-fill-column-indicator-mode: t
  display-fill-column-indicator-mode: t
  global-display-line-numbers-mode: t
  display-line-numbers-mode: t
  which-key-mode: t
  override-global-mode: t
  eldoc-mode: t
  show-paren-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  context-menu-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  size-indication-mode: t
  column-number-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t

Load-path shadows:
~/gits/emacs_clones/composable/composable-mark hides /home/ergo/.config/emacs/elpa/composable-20201024.1458/composable-mark
~/gits/emacs_clones/composable/composable hides /home/ergo/.config/emacs/elpa/composable-20201024.1458/composable
/home/ergo/.config/emacs/elpa/transient-20220216.2303/transient hides /home/ergo/.local/share/emacs/29.0.50/lisp/transient

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media rmc puny
rfc822 mml mml-sec password-cache epa derived epg rfc6068 epg-config
gnus-util text-property-search time-date mm-decode mm-bodies mm-encode
mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047
rfc2045 ietf-drums mm-util mail-prsvr mail-utils vertico-directory
elec-pair autorevert filenotify xclip flyspell-correct flyspell ispell
company-semantic company-template company-capf company flycheck
ansi-color json map find-func dash pcase diff-hl-margin diff-hl-dired
advice dired-x dired dired-loaddefs diff-hl log-view pcvs-util vc-dir
ewoc vc vc-dispatcher diff-mode vertico-repeat cape comp comp-cstr
warnings term/tmux term/xterm xterm init composable composable-mark
repeat xt-mouse simple-16-theme edmacro kmacro vertico-mouse vertico
mb-depth winner ring saveplace delsel savehist
display-fill-column-indicator display-line-numbers diminish which-key
cl-extra help-mode use-package use-package-ensure use-package-delight
use-package-diminish use-package-bind-key bind-key easy-mmode
use-package-core disp-table info ede/auto eieio-base cl-seq eieio seq
subr-x byte-opt bytecomp byte-compile cconv eieio-core cl-macs gv
eieio-loaddefs cl-loaddefs cl-lib tex-site rx slime-autoloads early-init
iso-transl tooltip eldoc paren electric uniquify ediff-hook vc-hooks
lisp-float-type elisp-mode mwheel term/pgtk-win pgtk-win term/common-win
tool-bar dnd fontset image regexp-opt fringe tabulated-list replace
newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar
rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock
font-lock syntax font-core term/tty-colors frame minibuffer cl-generic
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray
cl-preloaded nadvice button loaddefs faces cus-face macroexp files
window text-properties overlay sha1 md5 base64 format env code-pages
mule custom widget keymap hashtable-print-readable backquote threads
dbusbind inotify dynamic-setting system-font-setting font-render-setting
cairo gtk pgtk lcms2 multi-tty make-network-process native-compile
emacs)

Memory information:
((conses 16 198940 54047)
 (symbols 48 15486 0)
 (strings 32 59909 31324)
 (string-bytes 1 2103818)
 (vectors 16 30201)
 (vector-slots 8 452967 284466)
 (floats 8 109 1121)
 (intervals 56 726 0)
 (buffers 992 11))