Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check yas--original-auto-fill-function before using it #873

Closed
wants to merge 1 commit into from
Closed

Check yas--original-auto-fill-function before using it #873

wants to merge 1 commit into from

Conversation

chep
Copy link

@chep chep commented Dec 6, 2017

Sometimes when using tramp, I've got an error (Symbol's function definition is
void: nil) because the variable yas--original-auto-fill-function is not
initialized.

A simple check of the value solved my problem.

@npostavs
Copy link
Collaborator

npostavs commented Dec 6, 2017

Can you explain how to reproduce the problem? I think the real bug is that yas--original-auto-fill-function is not being set.

@chep
Copy link
Author

chep commented Dec 6, 2017

I can't. I can't reproduce it when starting with emacs -Q and my configuration is not simple.
I'll try to find a way to reproduce it.

@npostavs
Copy link
Collaborator

npostavs commented Dec 6, 2017

Even if you can't reproduce with emacs -Q, if you can set debug-on-error and get a backtrace that could be helpful.

@chep
Copy link
Author

chep commented Jan 19, 2018

I just reproduced it but I don't know how.
It happens when I do a query-replace (M-%) and then press the spacebar (in the minibuffer).
It worked 1 hour ago, it is now broken...

Here is the backtrace:

Debugger entered--Lisp error: (void-function nil)
  nil()
  funcall(nil)
  (let ((yas--inhibit-overlay-hooks t)) (funcall yas--original-auto-fill-function))
  (let* ((orig-point (point)) (end (progn (forward-paragraph) (point))) (beg (progn (backward-paragraph) (point))) (snippets (yas-active-snippets beg end)) (remarkers nil) (reoverlays nil)) (let ((--dolist-tail-- snippets) snippet) (while --dolist-tail-- (setq snippet (car --dolist-tail--)) (let ((--dolist-tail-- (yas--collect-snippet-markers snippet)) m) (while --dolist-tail-- (setq m (car --dolist-tail--)) (if (and (<= beg m) (<= m end)) (progn (setq remarkers (cons (yas--snapshot-marker-location m beg end) remarkers)))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (setq reoverlays (cons (yas--snapshot-overlay-location (progn (or (and (memq (type-of snippet) cl-struct-yas--snippet-tags) t) (signal 'wrong-type-argument (list 'yas--snippet snippet))) (aref snippet 5)) beg end) reoverlays)) (setq --dolist-tail-- (cdr --dolist-tail--)))) (goto-char orig-point) (let ((yas--inhibit-overlay-hooks t)) (funcall yas--original-auto-fill-function)) (save-excursion (setq end (progn (forward-paragraph) (point))) (setq beg (progn (backward-paragraph) (point)))) (save-excursion (save-restriction (narrow-to-region beg end) (mapc (function yas--restore-marker-location) remarkers) (mapc (function yas--restore-overlay-location) reoverlays)) (mapc (function (lambda (snippet) (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 (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))))))))) snippets)))
  yas--auto-fill()
  internal-auto-fill()
  self-insert-command(1)
  funcall-interactively(self-insert-command 1)
  call-interactively(self-insert-command nil nil)
  command-execute(self-insert-command)
  read-from-minibuffer(#("Query replace (default (0), →  = 0;): " 27 30 (separator t face minibuffer-prompt display " → ")) nil nil nil nil "waitpid" t)
  query-replace-read-from("Query replace" nil)
  query-replace-read-args("Query replace" nil)
  byte-code("\301\302\010\203\024\0\010\303=\203\020\0\304\202\025\0\305\202\025\0\306\307 \203\036\0\310\202\037\0\306Q\311\"\211@\001A@\312\0038\307 \2051\0\313 \307 \2058\0\314 \315\006\0068\307 \205C\0\316 \257\007\207" [current-prefix-arg query-replace-read-args "Query replace" - " backward" " word" "" use-region-p " in region" nil 2 region-beginning region-end 3 region-noncontiguous-p] 8)
  call-interactively(query-replace nil nil)
  command-execute(query-replace)

@npostavs
Copy link
Collaborator

It happens when I do a query-replace (M-%) and then press the spacebar (in the minibuffer).
[...]

yas--auto-fill()
internal-auto-fill()
self-insert-command(1)
funcall-interactively(self-insert-command 1)
call-interactively(self-insert-command nil nil)
command-execute(self-insert-command)
read-from-minibuffer(#("Query replace (default (0), → = 0;): " 27 30 (separator t face minibuffer-prompt display " → ")) nil nil nil nil "waitpid" t)
query-replace-read-from("Query replace" nil)

Hmm, I don't think space is supposed to perform self-insert-command in a query replace buffer. Can you check the current buffer in those stack frames (move point to a line in the backtrace, then e (current-buffer)RET).

(defvar query-replace-map
  (let ((map (make-sparse-keymap)))
    (define-key map " " 'act)
  [...]

@npostavs
Copy link
Collaborator

npostavs commented Feb 2, 2018

@chep Are you using Emacs 26? Based on the properly escaped NUL bytes in your backtrace I guess you are. Could you try the following to hopefully catch where yas--original-auto-fill-function becomes nil? EDIT: this code is too eager, it will catch false positives. Don't use it.

(when nil ; don't use this
 (add-variable-watcher
 'yas--original-auto-fill-function
 (lambda (sym newval op where)
   (when (and (null newval) (eq auto-fill-function 'yas--auto-fill))
     (debug nil "yas--original-auto-fill-function unexpectedly nil!"))))
)

@chep
Copy link
Author

chep commented Feb 5, 2018

I'm using emacs 27 (master branch). The watcher is now in my .emacs file...

npostavs added a commit to npostavs/yasnippet that referenced this pull request Mar 17, 2018
* yasnippet.el (yas--watch-autofill): New variable watcher to catch
the problem.
(yas--auto-fill): If `yas--original-auto-fill-function' is nil, print
a warning with some info instead of signaling an error.
@npostavs
Copy link
Collaborator

I've now (conditionally) added the watcher to yasnippet, so you can remove it from your .emacs after updating #920.

@stardiviner
Copy link

I got following error today. Noticed yasnippet is updated, and I upgrade it. I have not changed yasnippet config recently.

Debugger entered: ("`yas--original-auto-fill-function' unexpectedly nil! Please report this backtrace (hit `c' to continue)")
  yas--watch-auto-fill(yas--original-auto-fill-function nil makunbound #<buffer *scratch*>)
  kill-all-local-variables()
  prog-mode()
  emacs-lisp-mode()
  lisp-interaction-mode()
  command-line()
  normal-top-level()

stardiviner referenced this pull request Mar 18, 2018
* yasnippet.el (yas--watch-auto-fill): New variable watcher to catch
the problem.
(yas--auto-fill): If `yas--original-auto-fill-function' is nil, print
a warning with some info instead of signaling an error.
@drot
Copy link

drot commented Mar 18, 2018

Managed to trigger it with Magit:

GNU Emacs 26.0.91 (build 1, i686-pc-linux-gnu, GTK+ Version 3.22.28) of 2018-03-15

Debugger entered: ("`yas--original-auto-fill-function' unexpectedly nil! Please report this backtrace (hit `c' to continue)")
  yas--watch-auto-fill(yas--original-auto-fill-function nil makunbound #<buffer COMMIT_EDITMSG>)
  kill-all-local-variables()
  normal-mode(t)
  git-commit-setup()
  git-commit-setup-check-buffer()
  run-hooks(find-file-hook)
  after-find-file(nil t)
  find-file-noselect-1(#<buffer COMMIT_EDITMSG> "~/dotfiles/.git/COMMIT_EDITMSG" nil nil "~/dotfiles/.git/COMMIT_EDITMSG" (2633930 2054))
  find-file-noselect("/home/drot/dotfiles/.git/COMMIT_EDITMSG")
  #f(compiled-function (files proc &optional nowait) "Find FILES and return a list of buffers created.\nFILES is an alist whose elements are (FILENAME . FILEPOS)\nwhere FILEPOS can be nil or a pair (LINENUMBER . COLUMNNUMBER).\nPROC is the client that requested this operation.\nNOWAIT non-nil means this client is not waiting for the results,\nso don't mark these buffers specially, just visit them normally." #<bytecode 0x200000000d498300>)((("/home/drot/dotfiles/.git/COMMIT_EDITMSG")) #<process server <1>> nil)
  apply(#f(compiled-function (files proc &optional nowait) "Find FILES and return a list of buffers created.\nFILES is an alist whose elements are (FILENAME . FILEPOS)\nwhere FILEPOS can be nil or a pair (LINENUMBER . COLUMNNUMBER).\nPROC is the client that requested this operation.\nNOWAIT non-nil means this client is not waiting for the results,\nso don't mark these buffers specially, just visit them normally." #<bytecode 0x200000000d498300>) ((("/home/drot/dotfiles/.git/COMMIT_EDITMSG")) #<process server <1>> nil))
  server-visit-files((("/home/drot/dotfiles/.git/COMMIT_EDITMSG")) #<process server <1>> nil)
  server-execute(#<process server <1>> (("/home/drot/dotfiles/.git/COMMIT_EDITMSG")) nil nil nil nil nil)
  #f(compiled-function () #<bytecode 0x200000000d4d0280>)()
  server-execute-continuation(#<process server <1>>)
  server-process-filter(#<process server <1>> "-dir /home/drot/dotfiles/ -current-frame -tty /dev/pts/1 dumb -file /home/drot/dotfiles/.git/COMMIT_EDITMSG \n")

@npostavs
Copy link
Collaborator

npostavs commented Mar 18, 2018

Ah, I should have tested out my debug code more thoroughly, the kill-all-local-variables case should be skipped. Pushed a new update for that (#921).

@npostavs
Copy link
Collaborator

As mentioned in #919 (comment), nobody seems to be hitting this anymore, so I'm going to close.

@npostavs npostavs closed this Apr 21, 2019
monnier added a commit that referenced this pull request Oct 27, 2023
Instead of using `setq` and storing the old value in
`yas--original-auto-fill-function`, use `add-function`.
This makes it virtually impossible for a bug like #873/#919 to appear.
Remove the left-over debug code we had added to try and track down
#873/#919.

This requires bumping the dependency on Emacs≥24.4.

(yas--original-auto-fill-function, yas--watch-auto-fill-backtrace):
Delete variables.
(yas--watch-auto-fill): Delete function.  Don't add it to variable watchers.
(yas--auto-fill-wrapper): Use `add-function`.
(yas-minor-mode): Use `remove-function`.
(yas--auto-fill): Adjust its calling convention for use with `:around`
in `add-function`.  Remove left-over debug code.
(yas--post-command-handler): Remove left-over debug code.
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants