c++-mode
, 只在打开文件后第一次使用yasnippet的时候出现, 现象:
snippet展开之后, 光标处于高亮文本上, 此时切换为中文输入法, 输入文字后, emacs报错, 错误信息:
ad-Advice-c-forward-sws: Wrong type argument: integer-or-marker-p, nil
好像是跟cc-mode冲突了.
测试的snippet如下:
# name: test snippet
# key: test
# --
// hello ${1:world}
最新版yasnippet, emacs26.
Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
c-forward-sws()
c-unfind-coalesced-tokens(87 92)
c-before-change(87 92)
delete-region(87 #<marker at 92 in c.cpp>)
(if (= (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (aref field 2)) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (aref field 3))) nil (delete-region (or from (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (aref field 2))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (aref field 3))))
yas--skip-and-clear(#s(yas--field :number 1 :start #<marker at 86 in c.cpp> :end #<marker at 92 in c.cpp> :parent-field nil :mirrors nil :transform nil :modified-p t :next nil) 87)
(progn (yas--skip-and-clear field end))
(if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end)))
(lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet))()
funcall((lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))
(let nil (funcall '(lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet))))
eval((let nil (funcall '(lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))))
(let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body)))))
(progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body))))))
(let ((envvar (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 1)))) (progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body)))))))
(progn (let ((envvar (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 1)))) (progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body))))))))
(unwind-protect (progn (let ((envvar (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 1)))) (progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body)))))))) (set-match-data save-match-data-internal 'evaporate))
(let ((save-match-data-internal (match-data))) (unwind-protect (progn (let ((envvar (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 1)))) (progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body)))))))) (set-match-data save-match-data-internal 'evaporate)))
(if (yas--snippet-live-p snippet) (let ((save-match-data-internal (match-data))) (unwind-protect (progn (let ((envvar (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 1)))) (progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body)))))))) (set-match-data save-match-data-internal 'evaporate))) (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!") (delete-overlay overlay))
(let* ((inhibit-modification-hooks nil) (yas--inhibit-overlay-hooks t) (field (overlay-get overlay 'yas--field)) (snippet (overlay-get yas--active-field-overlay 'yas--snippet))) (if (yas--snippet-live-p snippet) (let ((save-match-data-internal (match-data))) (unwind-protect (progn (let ((envvar (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 1)))) (progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body)))))))) (set-match-data save-match-data-internal 'evaporate))) (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!") (delete-overlay overlay)))
(if (or (not after\?) yas--inhibit-overlay-hooks (not (overlayp yas--active-field-overlay)) (not (overlay-buffer overlay)) (yas--undo-in-progress)) nil (let* ((inhibit-modification-hooks nil) (yas--inhibit-overlay-hooks t) (field (overlay-get overlay 'yas--field)) (snippet (overlay-get yas--active-field-overlay 'yas--snippet))) (if (yas--snippet-live-p snippet) (let ((save-match-data-internal (match-data))) (unwind-protect (progn (let ((envvar (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 1)))) (progn (let* ((syms (mapcar (function car) envvar)) (vals (mapcar (function (lambda (v-f) (eval (car (cdr v-f))))) envvar)) (body (function (lambda nil (if (yas--skip-and-clear-field-p field beg end length) (progn (yas--skip-and-clear field end))) (progn (or (and (memq (type-of field) cl-struct-yas--field-tags) t) (signal 'wrong-type-argument (list 'yas--field field))) (let* ((v field)) (aset v 7 t))) (yas--advance-end-maybe field (overlay-end overlay)) (save-excursion (yas--field-update-display field)) (yas--update-mirrors snippet)))) (binds nil)) (while syms (setq binds (cons (list (car-safe (prog1 syms (setq syms (cdr syms)))) (list 'quote (car-safe (prog1 vals (setq vals (cdr vals)))))) binds))) (eval (list 'let binds (list 'funcall (list 'quote body)))))))) (set-match-data save-match-data-internal 'evaporate))) (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!") (delete-overlay overlay))))
yas--on-field-overlay-modification(#<overlay from 86 to 92 in c.cpp> t 86 87 0)
self-insert-command(1)
funcall-interactively(self-insert-command 1)
call-interactively(self-insert-command nil nil)
command-execute(self-insert-command)
同样的配置文件同样的系统, emacs25没问题. 而且只在打开文件的第一个snippet出现, 后面就正常了.
从 Emacs -Q 试了下,像是遇到了同样的问题
Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
c-forward-sws()
c-unfind-coalesced-tokens(10 11)
c-before-change(10 11)
ns-delete-working-text()
ns-unput-working-text()
funcall-interactively(ns-unput-working-text)
call-interactively(ns-unput-working-text nil [(ns-unput-working-text)])
command-execute(ns-unput-working-text nil [(ns-unput-working-text)] t)
似乎是 cc-mode
跟 yasnippet 在某处起了冲突。
版本信息:
emacs-version
=> "27.0.50"
(chunyang-straight-git-version "yasnippet")
=> "0.12.2-41-g15761e8"
你是mac版本吗?我在mac里不能重现,配置文件一样。mac上的emacs是老一点的26,linux上是这几天刚编译的26。感觉像是emacs最近才引入的问题
是,不过终端里的 Emacs 照样能重现,可能跟平台没关。
(emacs-version)
=> "GNU Emacs 27.0.50 (build 13, x86_64-apple-darwin17.4.0, NS appkit-1561.20 Version 10.13.3 (Build 17D102))
of 2018-03-14"
emacs-repository-version
=> "4c33ad4a244db59bfe128aa54380904efdc775ba"
window-system
=> ns
直接从 Emacs -Q 重现,完全排除掉个人配置。
用 emacs-24.5.2 简单试了下,没能重现。
这个问题很重要,但没有好的解决办法。Emacs -Q 对于报告 Bug 非常必要。
Emacs -Q 没法安装包。你得自己想办法「安装」,有些包只有一个 Emacs Lisp 并且没有任意依赖,你可以:
$ emacs -Q -l yasnippet.el
如果有依赖的话,你可以看看包的作者有没有提供 Emacs -Q 的办法,Magit 有 M-x magit-emacs-Q-command
、Helm 有 emacs-helm.sh
,之外你就得手动设置 load-path
甚至还得考虑 byte-compile。
我暂时用 straight.el
作为包管理器,它的文档里有介绍 Emacs -Q 的办法,我自己也写了个命令干这事。
(defun chunyang-straight-emacs-Q-command (package)
(interactive
(list
(straight--select-package "Package" nil 'installed)))
(let ((cmd (mapconcat
#'shell-quote-argument
`(,(concat invocation-directory invocation-name)
"-Q" "--eval" "(setq debug-on-error t)"
"--load" "~/.emacs.d/straight/repos/straight.el/bootstrap.el"
"--eval" ,(format "(straight-use-package '%s)" package))
" ")))
(message
"Uncustomized %s command saved to kill-ring, please run it in a terminal"
package)
(kill-new cmd)))
1 个赞
emacs-25上不会出现. 另外26上用yasnippet 0.11.0也不会出现. 情况有点复杂
刚才又重现了一下, 这个问题竟然还会影响undo-tree, 不能undo了:
primitive-undo: Changes to be undone are outside visible portion of buffer
不过不是百分百重现, 用着有点担心
能否向上游上报一下问题? 我英文不行. 今天用了一次, 竟然会影响undo-tree, 导致不能undo, 还是有点严重的.
向哪个上游报告?Emacs?Yasnippet?
我没感受到什么影响,当然我不写 C++,也几乎不用 Yasnippet,我没更多的动力关注这个问题。
单纯这个问题倒还可以忍受, 主要是担心有潜在的其他问题, 引出一些非预期行为, 比如损坏文件或数据.
不过牵涉到中文输入法的问题, 确实很难上报, 他们不用输入法,
除了前面提到的能重现之外,我从来都没遇到过这个问题,或许是因为触发的条件很苛刻。
至于开发者能不能解决你的问题是你无法控制的,你该做的是把 Bug Report 写清楚。
报给yasnippet了, 也许他们能根据错误信息看出点什么
fontux
17
我不清楚你那边的具体情况,但有可能是默认的 c-noise-macro-name-re
(值为 "\\<\\>"
)可以匹配 中英文 字符串(如 "中a"
),导致下面的 (match-end 1)
返回 nil。
我完全不懂 c-mode
,你可以试试设置变量 c-noise-macro-names
和 c-noise-macro-with-parens-names
,看看会不会再重现该问题。
确实是这个地方报的错:
这行代码是不是有问题? 搜索的正则表达式里没有分组, (match-end 1) 永远都是nil, 是不是作者写错了?
fontux
19
你可以参考函数 c-make-noise-macro-regexps
,我还是不太理解 c-noise-macro-name-re
初值设为 "\\<\\>"
的意图。
没看那么多,就看到这个值有点异常,跟上游反馈了,他们应该会检查一下代码