consult1.8安装后可以使用,重启emacs后,"consult-buffer"报错

emacs29.4,操作系统是macOS12.6.3。consult1.8安装(通过package-list-packages命令安装)后没重启emacs之前可以正常使用。 重启emacs后,"consult-buffer"报错:

Debugger entered--Lisp error: (wrong-type-argument stringp (1 2))
  compare-strings("\\" 0 1 (1 2) 0 1 nil)
  string-prefix-p("\\" (1 2))
  #f(compiled-function (y) #<bytecode -0x1398922ef53b9895>)("*")
  mapcar(#f(compiled-function (y) #<bytecode -0x1398922ef53b9895>) ("*" "+" "?"))
  #f(compiled-function (x) #<bytecode 0xde43d7b705f0478>)("")
  mapcan(#f(compiled-function (x) #<bytecode 0xde43d7b705f0478>) ("" "\\(" "\\(?:" "\\|" "^"))
  byte-code("\300\301\302\303\304\"\302\305\306\"#\207" [append (("\\<" . "\\b") ("\\>" . "\\b") ("\\_<" . "\\b") ("\\_>" . "\\b") ("\\`" . "^") ("\\'" . "$")) mapcan #f(compiled-function (x) #<bytecode 0xde43d7b705f0478>) ("" "\\(" "\\(?:" "\\|" "^") #f(compiled-function (x) #<bytecode -0x19cdb5742fa7ab9b>) (("\\|" . "|") ("\\(" . "(") ("\\)" . ")") ("\\{" . "{") ("\\}" . "}"))] 6)
  (defconst consult--convert-regexp-table (byte-code "\300\301\302\303\304\"\302\305\306\"#\207" [append (("\\<" . "\\b") ("\\>" . "\\b") ("\\_<" . "\\b") ("\\_>" . "\\b") ("\\`" . "^") ("\\'" . "$")) mapcan #f(compiled-function (x) #<bytecode 0xde43d7b705f0478>) ("" "\\(" "\\(?:" "\\|" "^") #f(compiled-function (x) #<bytecode -0x19cdb5742fa7ab9b>) (("\\|" . "|") ("\\(" . "(") ("\\)" . ")") ("\\{" . "{") ("\\}" . "}"))] 6) ("/Users/XXXX/.emacs.d/elpa/consult-20240824.800..." . 41943))
  autoload-do-load((autoload "consult" "Enhanced `switch-to-buffer' command with support for virtual buffers.\n\nThe command supports recent files, bookmarks, views and project files as\nvirtual buffers.  Buffers are previewed.  Narrowing to buffers (b), files (f),\nbookmarks (m) and project files (p) is supported via the corresponding\nkeys.  In order to determine the project-specific files and buffers, the\n`consult-project-function' is used.  The virtual buffer SOURCES\ndefault to `consult-buffer-sources'.  See `consult--multi' for the\nconfiguration of the virtual buffer sources.\n\n(fn &optional SOURCES)" t nil) consult-buffer)
  command-execute(consult-buffer record)
  execute-extended-command(nil "consult-buffer" "consult-bu")
  funcall-interactively(execute-extended-command nil "consult-buffer" "consult-bu")
  call-interactively(execute-extended-command nil nil)
  command-execute(execute-extended-command)

通过debug-init选项启动emacs,没有报错。 水平有限,前面这个报错trace看不出是哪儿的原因,求助~

先关掉 NativeComp 试一下呢?

小白,不太懂NativeComp,试着在early-init.el文件中加入如下内容:

(setq inhibit-automatic-native-compilation t)
(setq native-comp-jit-compilation nil)

没有效果。

.emacs.d/elpa/consult-xxx 删了重新下载试试

还是不行,删了重装之后,不重启之前可用。重启emacs之后,还报这个错。

估计下载的时候断网了

抱歉,之前搞错了,重启之后还是一样的报错。

那我等下看看,我估计是 consult 本身的问题

看了下,不是 consult 的问题,而是不知道什么原因导致你 Emacs 的 byte code 编译器或解释器有问题。这段 backtrace 对应的是,代码很简单而且数据是静态的,会报错只有可能是编译器有问题,而在我这 (Intel Mac Emacs 29.1,Windows Emacs 31.0) 没问题。

(defconst consult--convert-regexp-table
  (append
   ;; For simplicity, treat word beginning/end as word boundaries,
   ;; since PCRE does not make this distinction.  Usually the
   ;; context determines if \b is the beginning or the end.
   '(("\\<" . "\\b") ("\\>" . "\\b")
     ("\\_<" . "\\b") ("\\_>" . "\\b"))
   ;; Treat \` and \' as beginning and end of line.  This is more
   ;; widely supported and makes sense for line-based commands.
   '(("\\`" . "^") ("\\'" . "$"))
   ;; Historical: Unescaped *, +, ? are supported at the beginning
   (mapcan (lambda (x)
             (mapcar (lambda (y)
                       (cons (concat x y)
                             (concat (string-remove-prefix "\\" x) "\\" y)))
                     '("*" "+" "?")))
           '("" "\\(" "\\(?:" "\\|" "^"))
   ;; Different escaping
   (mapcan (lambda (x) `(,x (,(cdr x) . ,(car x))))
           '(("\\|" . "|")
             ("\\(" . "(") ("\\)" . ")")
             ("\\{" . "{") ("\\}" . "}"))))
  "Regexp conversion table.")

Emacs 是通过什么方式装的?然后如果把自已的配置去掉,或是换个版本的 Emacs 还能复现问题吗? 然后如果可能的话,找到 consult.elc 文件里 consult--convert-regexp-table 的字节码截图发上来

如果暂时没找到根源的话可以先把consult给加入禁止 native-comp 的名单:

;; Also remove `.local/eln-cache/<emacs-version>/consult-xxx.eln' file
(setq native-comp-jit-compilation-deny-list '("consult.*"))

我这里(emacs 31)不知道为什么会有 symbol's function definition is void: compat--cmpletion-metadata-get 的报错(vertico 需要 compat 30),就把compat加入禁止名单了。

这和 native comp 完全没关系,报错的是 byte code,实际上 native compiled function 出错后 backtrace 不会这么全的

这个我遇过,直接原因是 compat 包设计有问题没有向前兼容,用了条件编译还会受 emacs 31 自帯的 compat 包干扰,间接原因是你从低版本升上来的时候没有把 elpa 的包重新编译过,实际上也和 native comp 无关。

M-: (byte-recompile-directory package-user-dir nil 'force) 后就可以了

然后因为 31 自带了 compat,elpa 的也可以删了

2 个赞

Emacs 是通过什么方式装的? – 我是下载gnu emacs安装包之后,直接拖到应用程序里面安装的。

如果把自已的配置去掉,或是换个版本的 Emacs 还能复现问题吗? – 这个我晚上有空试下。

截图如下:

另外,我的emacs启动后,会自动打开compile log缓冲区,有一个warning:

我之前通过配置(setq warning-minimum-level :error)关掉了。和这个是不是有关系啊?

我看出来了。问题是因为编译的时候没正确应用 lexical-binding:t,编译出的 byte code 不对,warning 也是因为同样的原因。至于为什么会这样那只可能是你配置的原因了。

我配置里面没有配置过lexical-binding相关的内容,我目前不了解这个配置的含义,我研究下。感谢~

我没有搞明白lexical-binding的设置,偶然发现,直接把consult.elc这个文件删了,发现compile log中前面的报错,又通过(setq warning-minimum-level :error)把warning关掉,可以正常用了。 具体lexical-binding的配置,我再研究下,目前只搜到了在文件最前面加入;;; -*- lexical-binding: t; -*-对一个buffer设置的方法,好像没有找到如何全局开启。后面学习再深入的时候,再研究下。