bug#41831: 26.3; Customize UI fails for defcustom with standard default of list heterogenous choice types

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view

bug#41831: 26.3; Customize UI fails for defcustom with standard default of list heterogenous choice types

Pierre Rouleau

- Not a crash issue.

- A potential customize UI problem dealing with lists with a choice of
  element types:
  - Specifying the default values that include elements of
    the first choice type works fine, but
  - Specifying the default value that include elements of the second or
    third choice type makes the *customize* UI report a *mismatch* warning
    and the UI does not allow editing of the value.
    - However, if I set the default to a list of only the types of the
      first choice, and via the *customize* buffer UI (which then works
      OK) I add manually add elements of the second or third choice, the
      UI let me and let me save the values which are then showing inside
      the `custom-set-variables' form properly.
      - Then if I open the *Customize* buffer again I can edit properly:
        I see the first lists of first choice type and the last element
        of the second choice type.

So, to me it would seem that either my data declaration is invalid and
should never be accepted, or I should be able to declare a default that
consists of a list with elements of different types.  But I am not able
to do that.  I first asked on StackExchange where I was answered that
this might be a bug.

My code declarations follows.  Notice the 4 commented-out lines
following the defcustom `standard' argument: if I activate this code
(and update the parens accordingly), the defcustom byte-compiles fine
but *customize* buffer UI fails reporting a mismatch and does not let
edit/delete entries.

;; beginning of code sample -{-

(defcustom pel-key-chords
  '((global "<>" ("<>\C-b"))
    (global             "[]"     ("[]\C-b"))
    (c-mode             "{}"     ("{\n\n}\C-p"))
    (c++-mode           "{}"     ("{\n\n}\C-p")))
  ;; (flyspell-mode    "4r"     flyspell-correct-word-before-point)
  ;; (flyspell-prog-mode "4r"     flyspell-correct-word-before-point)
  ;; (global             "6y"     pel-find-file-at-point-in-window)
  ;; (global             ".;"     pel-search-word-from-top))
  "List of key-chords activated when the key-chord-mode is turned on.
PEL provides a set of defaults.  You can replace, delete or add new
key-chord definitions to this default.

You can define *global* key-chords and mode-specific key-chords.
- Global key-chords are stored in the global key-map.
- Mode-specific key-chords are stored in the mode key-map of
  the specified mode when the mode is entered.

The `pel-key-chords' value is a list of objects.
- Each object is a list of 3 items.
  - The first item is either:
    - global   : this key-chord is global
    - A major mode name that identifies the major mode
      where the key-chord must be activated.
      For example:  c++-mode
  - The second item is the 2 characters used for the key-chord.
    Do not quote the characters.
    You can specify control characters to identify special keys:
    - for <tab>, type: C-q C-i
    - for RET,   type: C-q C-m
    - It's not possible to identify the function keys here.
  - The third item describes the action for the key-chord.
    It can be expressed using one of 3 ways, selected by the
    Value Menu:
    - 0: expansion keys:
         Type the keys you want as replacement. You can
         place several keys on a line, or spread them on several
         lines.  You can identify control keys by entering the
         kbd-style like C-b (by typing 'C', '-', then 'b')
         or by placing the control code by typing C-q C-b.
         Unfortunately it is currently not possible to identify
         a keystroke involving other modifiers or combination of
         modifiers; the PEL code is not able to properly recognize it
         to pass it to the key-chord function.
         Use the lambda form instead.
         BTW, if you know how to fix that please don't hesitate
         to either let me know or submit a pull-request.
    - 1: command:
         Type the name of the Emacs interactive function you want
         to execute when the key-chord is hit.
    - 2: lambda:
         This is the most flexible way.  Here you write any elisp
         code you need inside a lambda expression that take no
         argument.   You can call any elisp function in here."
  :group 'pel-pkg-for-key-chord
  :type '(repeat
            :tag "expansion-keys"
            (symbol       :tag "mode" :value global)
            (string       :tag "chars")
             (key-sequence :tag "key")))
            :tag "command"
            (symbol       :tag "mode" :value global)
            (string       :tag "chars")
            (function     :tag "command"))
            :tag "lambda"
            (symbol       :tag "mode" :value global)
            (string       :tag "chars")
            (function     :tag "elisp-code"
                          :value (lambda () (interactive) <YOUR CODE HERE>))))))

;; end of code sample -}-


In GNU Emacs 26.3 (build 1, x86_64-apple-darwin18.2.0, NS appkit-1671.20 Version 10.14.3 (Build 18D109))
of 2019-09-02 built on builder10-14.porkrind.org
Windowing system distributor 'Apple', version 10.3.1671
Recent messages:
Wrote /Users/roup/dev/elisp/pel/pel--options.el
Saving file /Users/roup/dev/elisp/pel/pel--options.el...
Wrote /Users/roup/dev/elisp/pel/pel--options.el
Mark set
Saving file /Users/roup/dev/elisp/pel/pel--options.el...
Wrote /Users/roup/dev/elisp/pel/pel--options.el
Mark set
Saving file /Users/roup/dev/elisp/pel/pel--options.el...
Wrote /Users/roup/dev/elisp/pel/pel--options.el
Quit [4 times]

Configured using:
'configure --with-ns '--enable-locallisppath=/Library/Application
Support/Emacs/site-lisp' --with-modules'

Configured features:

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

Major mode: Emacs-Lisp

Minor modes in effect:
  global-magit-file-mode: t
  magit-auto-revert-mode: t
  global-git-commit-mode: t
  override-global-mode: t
  shell-dirtrack-mode: t
  async-bytecomp-package-mode: t
  show-paren-mode: t
  text-scale-mode: t
  global-undo-tree-mode: t
  undo-tree-mode: t
  winner-mode: t
  which-key-mode: t
  diff-auto-refine-mode: t
  global-anzu-mode: t
  anzu-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-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
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
/Users/roup/.emacs.d/utils/highlight-defined hides /Users/roup/.emacs.d/elpa/highlight-defined-20181106.1718/highlight-defined
/Users/roup/.emacs.d/utils/popup-kill-ring hides /Users/roup/.emacs.d/elpa/popup-kill-ring-20131020.1854/popup-kill-ring
/Users/roup/.emacs.d/utils/pos-tip hides /Users/roup/.emacs.d/elpa/pos-tip-20191227.1356/pos-tip
/Users/roup/.emacs.d/elpa/let-alist-1.0.6/let-alist hides /Applications/Emacs.app/Contents/Resources/lisp/emacs-lisp/let-alist

(shadow sort mail-extr emacsbug sendmail checkdoc pel-frame-control
flyspell pel-spell ispell dumb-jump hippie-exp pel-hideshow hideshow
desktop+ desktop-registry desktop frameset monky view bindat
magit-submodule magit-obsolete magit-blame magit-stash magit-reflog
magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote
magit-commit magit-sequence magit-notes magit-worktree magit-tag
magit-merge magit-branch magit-reset magit-files magit-refs magit-status
magit magit-repos magit-apply magit-wip magit-log which-func magit-diff
smerge-mode magit-core magit-autorevert autorevert filenotify
magit-margin magit-transient magit-process magit-mode git-commit
magit-git magit-section with-editor server nhexl-mode hexl sr-speedbar
xr pel-search-regexp visual-regexp-steroids visual-regexp pcre2el rxt
re-builder regex-tool multiple-cursors mc-hide-unmatched-lines-mode
mc-separate-operations rectangular-region-mode mc-mark-pop mc-mark-more
mc-cycle-cursors mc-edit-lines multiple-cursors-core rect lice
ztree-diff ztree-diff-model ztree-dir ztree-view ztree-util neotree
vline smooth-scrolling bind-key free-keys pel-pathmng
display-line-numbers pel-emacs ascii-table pel-help hide-comnt
expand-region subword-mode-expansions text-mode-expansions
cc-mode-expansions the-org-mode-expansions python-el-fgallina-expansions
er-basic-expansions expand-region-core expand-region-custom
graphviz-dot-mode highlight-defined macrostep rainbow-delimiters
parinfer ediff-merg ediff-wind ediff-diff ediff-mult ediff-help
ediff-init ediff-util ediff mode-local parinferlib julia-snail
julia-snail-parser julia-mode julia-mode-latexsubs parsec spinner exunit
alchemist alchemist-macroexpand alchemist-company alchemist-help
alchemist-complete company-dabbrev-code company-dabbrev
alchemist-refcard alchemist-phoenix alchemist-compile alchemist-iex
alchemist-message alchemist-hooks alchemist-hex alchemist-mix
alchemist-info alchemist-goto alchemist-scope alchemist-eval
alchemist-interact alchemist-server alchemist-execute alchemist-report
alchemist-test-mode alchemist-project alchemist-file alchemist-key
alchemist-utils elixir-mode elixir-format pkg-info epl elixir-smie smie
lfe-mode erlang-flymake flymake-proc flymake edts-start edts-mode
edts-xref edts-dialyzer edts-debug-mode edts-debug-list-processes-mode
edts-debug-list-interpreted-mode edts-debug-list-breakpoint-mode
edts-debug edts-shell edts-plugin edts-refactor edts-project edts-alist
edts-complete edts-complete-keyword-source edts-complete-record-source
edts-complete-macro-source edts-complete-module-source
edts-complete-built-in-function-source edts-man woman man
edts-complete-local-function-source edts-complete-variable-source
edts-code edts-face edts edts-navigate edts-event edts-api edts-rpc
edts-log ferl edts-doc auto-highlight-symbol erlang-start erlang tempo
align company-dcd popwin company ac-dcd flycheck-dmd-dub flycheck
yasnippet auto-complete d-mode cc-mode cc-fonts cc-guess cc-menus
cc-styles cc-align pel-applescript apples-mode counsel-osx-app
goto-last-change cc-cmds cc-engine cargo cargo-process markdown-mode
racer f rust-mode rx elpy elpy-rpc pyvenv esh-var esh-io esh-cmd esh-opt
esh-ext esh-proc esh-arg esh-groups eshell esh-module esh-mode esh-util
elpy-shell elpy-profile elpy-django elpy-refactor python json files-x
esup esup-child benchmark slime etags arc-mode archive-mode hyperspec
c-eldoc cl org-element avl-tree generator org org-macro org-footnote
org-pcomplete org-list org-faces org-entities noutline outline
org-version ob-emacs-lisp ob ob-tangle org-src ob-ref ob-lob ob-table
ob-keys ob-exp ob-comint ob-core ob-eval org-compat org-macs
org-loaddefs cal-menu calendar cal-loaddefs dired-narrow
dired-hacks-utils use-package-ensure use-package-core popup-kill-ring
pos-tip popup hl-line vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs
tramp-cache tramp-sh tramp tramp-compat tramp-loaddefs trampver shell
pcomplete parse-time rg pcase rg-info-hack rg-menu transient rg-ibuffer
rg-result wgrep-rg wgrep s rg-history rg-header grep pel-kbmacros vterm
term disp-table ehelp vterm-module pel-comment-adorn pel-comment pel-rst
rst pel-text-insert log-edit pcvs-util add-log vc-dir ewoc helm-mode
helm-files helm-buffers helm-occur helm-tags helm-locate helm-grep
helm-regexp helm-utils helm-help helm-types helm-config helm-easymenu
async-bytecomp helm helm-source eieio-compat helm-multi-match helm-lib
async edebug vc pel-lisp jka-compr paren imenu pel-text-transform pulse
face-remap pel-font misearch multi-isearch magit-utils crm dash
browse-url pel-undo undo-tree diff pel-mark pel-indent cc-vars cc-defs
debug pel-ccp pel-numkpad ace-window subr-x avy cl-print eieio-opt
speedbar sb-image ezimage dframe find-func help-fns key-chord two-column
iso-transl repeat ibuf-ext ibuffer ibuffer-loaddefs warnings autoload
radix-tree executable time-stamp copyright pp vc-dispatcher vc-hg
cus-edit cus-start cus-load wid-edit lisp-mnt pel-search pel-window
pel-read pel-navigate cap-words superword subword pel-scroll mm-archive
message format-spec rfc822 mml mml-sec epa derived epg gnus-util rmail
rmail-loaddefs mailabbrev gmm-utils mailheader mm-decode mm-bodies
mm-encode mail-utils network-stream starttls url-http tls gnutls
mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr url-gw
nsm rmc puny url-cache url-auth url url-proxy url-privacy url-expand
url-methods url-history url-cookie url-domsuf url-util mailcap windmove
framemove winner hydra lv bm counsel xdg xref project dired-x dired
dired-loaddefs compile comint ansi-color swiper cl-extra help-mode ivy
delsel ring ivy-faces ivy-overlay colir color ido pel-completion pel-seq
pel-prompt which-key vc-git diff-mode easy-mmode map elec-pair pel_keys
anzu thingatpt pel-imenu pel-cursor pel-commonlisp pel-autoload
pel--options pel--macros pel--base pel finder-inf edmacro kmacro
slime-autoloads info package easymenu epg-config url-handlers url-parse
auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs
password-cache url-vars seq byte-opt gv bytecomp byte-compile cconv
benchmark-init advice cl-loaddefs cl-lib time-date tooltip eldoc
electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/ns-win
ns-win ucs-normalize mule-util term/common-win tool-bar dnd fontset
image regexp-opt fringe tabulated-list replace newcomment text-mode
elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow
isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu
font-core term/tty-colors frame 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 charscript charprop case-table epa-hook
jka-cmpr-hook help simple abbrev obarray minibuffer cl-preloaded nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote threads kqueue cocoa ns multi-tty
make-network-process emacs)

Memory information:
((conses 16 2861657 321118)
(symbols 48 79381 2)
(miscs 40 82136 17181)
(strings 32 350988 22531)
(string-bytes 1 10221691)
(vectors 16 138257)
(vector-slots 8 2694369 169356)
(floats 8 1064 2306)
(intervals 56 281724 22233)
(buffers 992 78))

Reply | Threaded
Open this post in threaded view

bug#41831: 26.3; Customize UI fails for defcustom with standard default of list heterogenous choice types

Mauro Aranda
Hello Pierre.

Pierre Rouleau <[hidden email]> writes:

> (defcustom pel-key-chords
>   '((global "<>" ("<>\C-b"))
>     (global             "[]"     ("[]\C-b"))
>     (c-mode             "{}"     ("{\n\n}\C-p"))
>     (c++-mode           "{}"     ("{\n\n}\C-p")))
>   ;; (flyspell-mode    "4r"     flyspell-correct-word-before-point)
>   ;; (flyspell-prog-mode "4r"     flyspell-correct-word-before-point)
>   ;; (global             "6y"     pel-find-file-at-point-in-window)
>   ;; (global             ".;"     pel-search-word-from-top))

My guess is that the functions you are using here are not known to be
defined by the time you want to customize the variable.  In other words,
`functionp' returns nil for these symbols at that time.

I followed this recipe:
1. Start emacs -Q

2. In the *scratch* buffer, I evaluated the following:
(defcustom pel-key-chords
  '((global "<>" ("<>\C-b"))
    (c-mode "{}" ("{\n\n}\C-p"))
    (flyspell-mode "4r" flyspell-correct-word-before-point)
    (global ".;" pel-search-word-from-top))
  :type '(repeat
   :tag "expansion-keys"
   (symbol :tag "mode" :value global)
   (string :tag "chars")
   (repeat (key-sequence :tag "key")))
   :tag "command"
   (symbol :tag "mode" :value global)
   (string :tag "chars")
   (function :tag "command")))))

3. M-x customize-option RET pel-key-chords
That gives me the mismatch message.  At this time, flyspell isn't
loaded, and `pel-search-word-from-top' is not defined.

4. C-x k RET, to kill the customize buffer.

5. Eval:
(require 'flyspell)
(defun pel-search-word-from-top ()

6. Again: M-x customize-option RET pel-key-chords
Now I see the customize buffer as expected, with the state being

Would you try the above, to check if my guess is correct?