ergoemacs / ergoemacs-mode

ergoemacs-mode
ergoemacs.github.io/
GNU General Public License v3.0
293 stars 35 forks source link

C-h m doesn't work with lvl1 theme: Wrong type argument: integer-or-marker-p, nil #469

Closed ghost closed 3 years ago

ghost commented 7 years ago

This is very similar to issue #466.

I am using GNU Emacs 25.1.2 and ergoemacs-mode-5.14.7.3 installed from elpa.

Steps to reproduce:

  1. emacs -q
  2. Evaluate the following code in scratch buffer:
(add-to-list 'load-path "/home/matthew/.emacs.d/elpa/ergoemacs-mode-5.14.7.3")
(setq ergoemacs-theme "lvl1")
(setq ergoemacs-keyboard-layout "us")
(require 'ergoemacs-mode)
(ergoemacs-mode 1)
  1. Set variable debug-on-error to t
  2. Try to open mode help: C-h m

I get the following output:

Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
  get-char-property(nil button)
  button-at(nil)
  help-xref-button(1 help-function-def emacs-lisp-mode "/usr/local/share/emacs/25.1/lisp/progmodes/elisp-mode.el")
  describe-mode()
  funcall-interactively(describe-mode)
  call-interactively(describe-mode nil nil)
  command-execute(describe-mode)
juster commented 6 years ago

TL;DR: I was able to work around this by setting the text-quoting-style variable to 'grave.

This has been bugging me as well. describe-function is also broken. I read through the elisp and it seems that a recent change to substitute-command-chars from a commit last year may have caused an incompatibility between the built-in substitute-command-chars function and the version that ergoemacs uses to override (via "advice").

Observe the following in a scratch buffer:

(ergoemacs-mode 0)
nil
(substitute-command-keys "`\\([^`']+\\)'")
"‘\\([^‘’]+\\)’"
(ergoemacs-mode 1)
t
(substitute-command-keys "`\\([^`']+\\)'")
"`\\([^`']+\\)'"

Look carefully at the values returned by each substitute-command-keys because they are different.

One common use in the elisp for substitute-command-keys has nothing whatsoever to do with command keys. Instead, this function is often used to normalize single quotes based on user preference. From the docs via describe-function:

Each ‘ and ` is replaced by left quote, and each ’ and ' is replaced by right quote. Left and right quote characters are specified by ‘text-quoting-style’.

The above scratch output is with the default (nil) value for text-quoting-style and causes the back tick and single-quote to be replaced by unicode equivalents (aka "curved"). The referenced commit for emacs above appears to be trying to resolve multi-byte problems, so maybe this was an unintended side-effect of that success.

I can trick the first substitute-command-keys function call into matching the ergoemacs version by setting the text-quoting-style to 'grave. This deftly avoids the larger problem, which is:

  1. When printing into the *Help* buffer, the describe functions use format-message which transforms single quotes into their unicode equivalents similar to substitute-command-keys.
  2. Shortly after printing to the help buffer, the code searches backwards for filenames inside those single quotes, using substitute-command-keys to transform the quotes in the regex equivalently.
  3. ergoemacs has quietly replaced substitute-command-keys (which does not appear to transform single quotes) and so produced a regular expression that does not match what was just printed.
  4. describe-function does not check to make sure the regular expression found the single quotes.
  5. describe-function attempts to make a clickable button from the regular expression match which failed. The nil value visible in the OP's stack trace is supposed to be the position returned by the search.
mattfidler commented 6 years ago

I will have to look into this. I think this unicorn quoting was introduced in 25.2, and the original substitute command keys advice was made before then.

mattfidler commented 3 years ago

lvl1 theme will no longer be supported