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

yas--original-auto-fill-function can end up nil unexpectedly #919

Closed
nevsan opened this issue Mar 16, 2018 · 19 comments
Closed

yas--original-auto-fill-function can end up nil unexpectedly #919

nevsan opened this issue Mar 16, 2018 · 19 comments

Comments

@nevsan
Copy link

nevsan commented Mar 16, 2018

This is an issue that keeps showing up intermittently. Unfortunately, I cannot create an easy way to reproduce the issue since it shows up every other day after many hours of using Emacs, but I want to share it in case anyone has an idea. If it's important, I spend a lot of time using TRAMP to edit remote Python files.

The symptom is that my emacs session will suddenly get into a state where certain operations (like saving a buffer, or auto-completing a command in M-x with ivy) will get killed with an error saying 'Symbol’s function definition is void: nil' and I can't recover without restarting emacs.

After much debugging, I traced it to this line:

(funcall yas--original-auto-fill-function)

For whatever reason, yas--original-auto-fill-function ended up becoming nil. Even if I set it back to something like do-auto-fill for the buffer, it will still cause the error. In order to fix the error without restarting emacs, I found that I have to execute

(setq-default yas--original-auto-fill-function 'do-auto-fill)

If anyone more familiar with the inner workings of these functions has an idea how and why this would happen, I'm willing to try some things to see if they get rid of the problem.

Thank you!

=====================
Some info about my setup.

I'm running GNU Emacs 25.3.1 (x86_64-apple-darwin16.7.0, Carbon Version 157 AppKit 1504.83) of 2017-10-09 from the emacs-mac distribution with spacemacs.

@npostavs
Copy link
Collaborator

If you are running Emacs 26+, could you try adding this to your init: #873 (comment)

Hopefully that could catch where this thing gets set to nil.

and I can't recover without restarting emacs.

I think (setq auto-fill-function nil) should work? Or perhaps a full

(dolist (buf (buffer-list))
  (with-current-buffer buf (setq auto-fill-function nil)))

@nevsan
Copy link
Author

nevsan commented Mar 17, 2018

@npostavs #873 is exactly what I'm experiencing.

I just triggered it again (somehow). Neither of those commands recovered it, but the following did the trick

(setq-default yas--original-auto-fill-function 'do-auto-fill)

I'm not running Emacs 26 unfortunately, so I can't do the variable watcher. I might upgrade to 26, but in the mean time, let me know if you have any other thoughts.

@npostavs
Copy link
Collaborator

I'm puzzled that the loop wouldn't do the trick, or have you set the default-value of auto-fill-function?

Meanwhile, I've updated yasnippet to give a warning instead of an error in this case, so hopefully it will be less painful to deal with.#920.

@tollerm
Copy link

tollerm commented Mar 19, 2018

After last update the debugger is fired up with this message when exporting org file in Latex. Before it never happend.

@joaotavora
Copy link
Owner

After last update the debugger is fired up with this message when exporting org file in Latex.

Good :-). Now you should report the backtrace.

Before it never happened.

Because we didn't have this diagnostic code in place before

@npostavs
Copy link
Collaborator

npostavs commented Mar 19, 2018

After last update the debugger is fired up with this message when exporting org file in Latex. Before it never happend.

@tollerm If the backtrace has kill-all-local-variables in it, then please update yasnippet again, my initial diagnostric code was too eager (#921).

@tollerm
Copy link

tollerm commented Mar 19, 2018

This is (last part of) backtrace:

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 set #<buffer  *temp*>)
  make-local-variable(yas--original-auto-fill-function)
  org-element-parse-secondary-string("\\today" (bold code entity export-snippet inline-babel-call inline-src-block italic line-break latex-fragment link macro radio-target statistics-cookie strike-through subscript superscript target timestamp underline verbatim))

@joaotavora
Copy link
Owner

org-element-parse-secondary-string

@npostavs, looks legit though

@npostavs
Copy link
Collaborator

No, it's a false positive (but a new one), org-element-parse-secondary-string copies all the variables, so it just transitions through a state when yas--original-auto-fill-function is nil and auto-fill-function is yas--do-auto-fill. But it's just about to set yas--original-auto-fill-function to do-auto-fill.

New update in #922.

@nevsan
Copy link
Author

nevsan commented May 2, 2018

UPDATE: I'm now running Emacs 26 so I tried the variable watcher described in #873 and was able to catch the issue in the debugger:

Debugger entered: ("yas--original-auto-fill-function unexpectedly nil!")
  (progn (debug nil "yas--original-auto-fill-function unexpectedly nil!"))
  (if (and (null newval) (eq auto-fill-function 'yas--auto-fill)) (progn (debug nil "yas--original-auto-fill-function unexpectedly nil!")))
  (lambda (sym newval op where) (if (and (null newval) (eq auto-fill-function 'yas--auto-fill)) (progn (debug nil "yas--original-auto-fill-function unexpectedly nil!"))))(yas--original-auto-fill-function nil makunbound #<buffer file.py>)
  kill-all-local-variables()
  normal-mode(t)
  after-find-file(nil nil t nil nil)
  revert-buffer--default(nil t)
  revert-buffer(nil t)
  ask-user-about-supersession-threat(#("/ssh:some_server:/some/file.py" 1 4 (tramp-default t)))
  userlock--ask-user-about-supersession-threat(#("/ssh:some_server:/some/file.py" 1 4 (tramp-default t)))
  self-insert-command(1)
  newline(nil t)
  #f(compiled-function () (interactive "*") #<bytecode 0x400ba03f>)()
  ad-Advice-newline-and-indent(#f(compiled-function () (interactive "*") #<bytecode 0x400ba03f>))
  apply(ad-Advice-newline-and-indent #f(compiled-function () (interactive "*") #<bytecode 0x400ba03f>) nil)
  newline-and-indent()
  funcall-interactively(newline-and-indent)
  call-interactively(newline-and-indent nil nil)
  command-execute(newline-and-indent)

@npostavs
Copy link
Collaborator

npostavs commented May 2, 2018

@nevsan Ah, that's the false positive mentioned above. If you are running an updated yasnippet on a recent enough Emacs, it will add a variable watcher which avoids false positives (I hope). Unfortunately, so far it seems nobody has hit the true positive case...

@npostavs
Copy link
Collaborator

so far it seems nobody has hit the true positive case...

It's been almost a year, and still no reports. Perhaps it's dependent on a bug/quirk in some other package that has meanwhile been fixed.

I don't think there is any use keeping this open. The code to check for the condition is still present, so we can always open a new issue if anyone hits it.

@greg-minshall
Copy link

i'm a new user of yasnippet and of various other "completion" packages.

yasnippet (version 0.14.0-8-g5cbdbf0) -- pluskid/joaotavora/npostavs

i seem to be running into this fairly consistently. for example [M-x
consult-apropos], then entering "abc ", i get this error after typing
the blank.

the code in '(yas--auto-fill)' to produce a debug message calls
(lwarn), which recurses, eventually exceeding the stack limit or some
such.

Debugger entered--Lisp error: (error "Lisp nesting exceeds ‘max-lisp-eval-depth’")

at the risk of being very verbose, i'll post some details.

first, the debug message code seems to want to print two variables:

"yas--fil-fun-values"

((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>)
 (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>)
 (t nil))

"fill-fun-values"

((nil #<buffer *Backtrace*>)
 (yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>)
 (t yas--auto-fill))

the stack on the initial entry to (lwarn) looks like this:

* lwarn((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer  *Minibuf-1*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((nil #<buffer *Backtrace*>) (yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (t yas--auto-fill)) "")
  (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ((bufs ...)) (setq bufs (cons ... ...)))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell (assq yas--original-auto-fill-function yas--fill-fun-values)) (af-cell (assq auto-fill-function fill-fun-values))) (if (local-variable-p 'yas--original-auto-fill-function) (progn (if yf-cell ... ...))) (if (local-variable-p 'auto-fill-function) (progn (if af-cell ... ...)))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let (...) (mapc ... yas--watch-auto-fill-backtrace)) (save-current-buffer (set-buffer standard-output) (buffer-string))) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))
  (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let (...) (setq bufs ...))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell ...) (af-cell ...)) (if (local-variable-p ...) (progn ...)) (if (local-variable-p ...) (progn ...))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let ... ...) (save-current-buffer ... ...)) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))
  (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value ...)))) (fill-fun-values (list (list t (default-value ...)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ... ...)) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* (... ...) (if ... ...) (if ... ...)) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output ...)) (unwind-protect (progn ... ...) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))))
  (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 ...))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (setq reoverlays (cons (yas--snapshot-overlay-location (progn (or ... ...) (aref snippet 5)) beg end) reoverlays)) (setq --dolist-tail-- (cdr --dolist-tail--)))) (goto-char orig-point) (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t ...))) (fill-fun-values (list (list t ...))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- ...) buf) (while --dolist-tail-- (setq buf ...) (set-buffer buf) (let* ... ... ...) (setq --dolist-tail-- ...)))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let (...) (unwind-protect ... ...)) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))) (save-excursion (setq end (progn (forward-paragraph) (point))) (setq beg (progn (backward-paragraph) (point)))) (save-excursion (save-restriction (narrow-to-region beg end) (let ((--dolist-tail-- remarkers) remarker) (while --dolist-tail-- (setq remarker (car --dolist-tail--)) (set-marker (car remarker) (yas--goto-saved-location (cdr remarker))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (mapc #'yas--restore-overlay-location reoverlays)) (mapc #'(lambda (snippet) (let ((envvar ...)) (progn (let* ... ... ...)))) snippets)))
  yas--auto-fill()
  internal-auto-fill()
  self-insert-command(1 32)
  funcall-interactively(self-insert-command 1 32)
  call-interactively(self-insert-command nil nil)
  command-execute(self-insert-command)
  read-from-minibuffer("Apropos: " nil (keymap (9 . selectrum-insert-current-candidate) (10 . selectrum-submit-exact-input) (C-M-backspace . selectrum-backward-kill-sexp) (27 keymap (109 . selectrum-quick-select) (105 . selectrum-quick-insert) (113 . selectrum-cycle-display-style) (67108991 . selectrum-backward-kill-sexp)) (remap keymap (backward-kill-sexp . selectrum-backward-kill-sexp) (previous-matching-history-element . selectrum-select-from-history) (kill-ring-save . selectrum-kill-ring-save) (end-of-buffer . selectrum-goto-end) (beginning-of-buffer . selectrum-goto-beginning) (minibuffer-beginning-of-buffer . selectrum-goto-beginning) (scroll-up-command . selectrum-next-page) (scroll-down-command . selectrum-previous-page) (exit-minibuffer . selectrum-select-current-candidate) (next-line-or-history-element . selectrum-next-candidate) (previous-line-or-history-element . selectrum-previous-candidate) (next-line . selectrum-next-candidate) (previous-line . selectrum-previous-candidate) (minibuffer-keyboard-quit . abort-recursive-edit) (keyboard-quit . abort-recursive-edit)) keymap (remap keymap (previous-matching-history-element . selectrum-select-from-history)) (18 . helm-minibuffer-history) (menu-bar keymap (minibuf "Minibuf" keymap (previous menu-item "Previous History Item" previous-history-element :help "Put previous minibuffer history element in the min...") (next menu-item "Next History Item" next-history-element :help "Put next minibuffer history element in the minibuf...") (isearch-backward menu-item "Isearch History Backward" isearch-backward :help "Incrementally search minibuffer history backward") (isearch-forward menu-item "Isearch History Forward" isearch-forward :help "Incrementally search minibuffer history forward") (return menu-item "Enter" exit-minibuffer :key-sequence "\15" :help "Terminate input and exit minibuffer") (quit menu-item "Quit" abort-recursive-edit :help "Abort input and exit minibuffer") "Minibuf")) (10 . exit-minibuffer) (13 . exit-minibuffer) (7 . abort-recursive-edit) (C-tab . file-cache-minibuffer-complete) (9 . self-insert-command) (XF86Back . previous-history-element) (up . previous-line-or-history-element) (prior . previous-history-element) (XF86Forward . next-history-element) (down . next-line-or-history-element) (next . next-history-element) (27 keymap (60 . minibuffer-beginning-of-buffer) (114 . previous-matching-history-element) (115 . next-matching-history-element) (112 . previous-history-element) (110 . next-history-element))) nil consult--apropos-history #("fill-fun-values" 0 15 (fontified t)))
  selectrum--read("Apropos: " nil :initial-input nil :default-candidate #("fill-fun-values" 0 15 (fontified t)) :require-match nil :history consult--apropos-history :may-modify-candidates t :minibuffer-completion-table #f(compiled-function (str pred action) #<bytecode 0x158479b00f39>) :minibuffer-completion-predicate #f(compiled-function (x) #<bytecode 0x158478945d69>))
  selectrum-completing-read("Apropos: " #f(compiled-function (str pred action) #<bytecode 0x158479b00f39>) #f(compiled-function (x) #<bytecode 0x158478945d69>) nil nil consult--apropos-history #("fill-fun-values" 0 15 (fontified t)) nil)
  completing-read("Apropos: " #f(compiled-function (str pred action) #<bytecode 0x158479b00f39>) #f(compiled-function (x) #<bytecode 0x158478945d69>) nil nil consult--apropos-history #("fill-fun-values" 0 15 (fontified t)))
  #f(compiled-function () #<bytecode 0x158479b00e79>)()
  consult--with-preview-1(any nil #f(compiled-function (input cand) #<bytecode 0x158479b00e15>) #f(compiled-function (&rest args2) #<bytecode 0x158479b00e35>) #f(compiled-function () #<bytecode 0x158479b00e79>))
  #f(compiled-function (arg1 &rest rest) "Enhanced completing read function selecting from CANDIDATES.\n\nKeyword OPTIONS:\n\nPROMPT is the string which is shown as prompt message in the minibuffer.\nPREDICATE is a filter function called for each candidate.\nREQUIRE-MATCH equals t means that an exact match is required.\nHISTORY is the symbol of the history variable.\nDEFAULT is the default selected value.\nADD-HISTORY is a list of items to add to the history.\nCATEGORY is the completion category.\nSORT should be set to nil if the candidates are already sorted.\nLOOKUP is a lookup function passed the input, candidates and candidate string.\nANNOTATE is a function passed a candidate string to return an annotation.\nINITIAL is the initial input.\nDEFAULT-TOP must be nil if the default candidate should not be moved to the top.\nSTATE is the state function, see `consult--with-preview'.\nTITLE is a function passed a candidate string to return a grouping title.\nPREVIEW-KEY are the preview keys (nil, 'any, a single key or a list of keys).\nNARROW is an alist of narrowing prefix strings and description.\nKEYMAP is a command-specific keymap." #<bytecode 0x158478936f09>)([eww-buffer-select olc --cl-block-yas--template-content--cmacro-- CTCP-CLIENTINFO locals LOCK Undo eww-handle-link denied reftex-default-bibliography DYAN org-publish--store-crossrefs erc-readonly-mode-off-hook 0 vc-git-make-version-backups-p mml-secure-smime-sign-with-sender --cl-block-yas--snippet-previous-active-field-- biblio--selection-insert none-but-delete vc-src-log-switches winnow sgml-syntax-propertize HTML\ specific\ export\ settings ZZYA cl-print--preprocess Noto\ Sans\ Deseret infix-token :examined org-agenda-regexp-filter-preset vc-git-conflicted-files erc-away-nickname post-deadline xref-w-dedicated shr-parse-image-data Load\ snippets\.\.\. org--plot/radar-ticks message-kill-actions ibuffer-update --cl-block-yas--field-start-- \' is13194-to-ucs-telugu-hashtbl gnus-summary-catchup-from-here mh-msg-num-width-to-column VITAE request-list sgml-tag-name--cmacro ZZYX Exporting\ Code\ Blocks expired print-command ...] :prompt "Apropos: " :predicate #f(compiled-function (x) #<bytecode 0x158478945d69>) :history consult--apropos-history :category symbol :default #("fill-fun-values" 0 15 (fontified t)))
  apply(#f(compiled-function (arg1 &rest rest) "Enhanced completing read function selecting from CANDIDATES.\n\nKeyword OPTIONS:\n\nPROMPT is the string which is shown as prompt message in the minibuffer.\nPREDICATE is a filter function called for each candidate.\nREQUIRE-MATCH equals t means that an exact match is required.\nHISTORY is the symbol of the history variable.\nDEFAULT is the default selected value.\nADD-HISTORY is a list of items to add to the history.\nCATEGORY is the completion category.\nSORT should be set to nil if the candidates are already sorted.\nLOOKUP is a lookup function passed the input, candidates and candidate string.\nANNOTATE is a function passed a candidate string to return an annotation.\nINITIAL is the initial input.\nDEFAULT-TOP must be nil if the default candidate should not be moved to the top.\nSTATE is the state function, see `consult--with-preview'.\nTITLE is a function passed a candidate string to return a grouping title.\nPREVIEW-KEY are the preview keys (nil, 'any, a single key or a list of keys).\nNARROW is an alist of narrowing prefix strings and description.\nKEYMAP is a command-specific keymap." #<bytecode 0x158478936f09>) ([eww-buffer-select olc --cl-block-yas--template-content--cmacro-- CTCP-CLIENTINFO locals LOCK Undo eww-handle-link denied reftex-default-bibliography DYAN org-publish--store-crossrefs erc-readonly-mode-off-hook 0 vc-git-make-version-backups-p mml-secure-smime-sign-with-sender --cl-block-yas--snippet-previous-active-field-- biblio--selection-insert none-but-delete vc-src-log-switches winnow sgml-syntax-propertize HTML\ specific\ export\ settings ZZYA cl-print--preprocess Noto\ Sans\ Deseret infix-token :examined org-agenda-regexp-filter-preset vc-git-conflicted-files erc-away-nickname post-deadline xref-w-dedicated shr-parse-image-data Load\ snippets\.\.\. org--plot/radar-ticks message-kill-actions ibuffer-update --cl-block-yas--field-start-- \' is13194-to-ucs-telugu-hashtbl gnus-summary-catchup-from-here mh-msg-num-width-to-column VITAE request-list sgml-tag-name--cmacro ZZYX Exporting\ Code\ Blocks expired print-command ...] :prompt "Apropos: " :predicate #f(compiled-function (x) #<bytecode 0x158478945d69>) :history consult--apropos-history :category symbol :default #("fill-fun-values" 0 15 (fontified t))))
  consult--read([eww-buffer-select olc --cl-block-yas--template-content--cmacro-- CTCP-CLIENTINFO locals LOCK Undo eww-handle-link denied reftex-default-bibliography DYAN org-publish--store-crossrefs erc-readonly-mode-off-hook 0 vc-git-make-version-backups-p mml-secure-smime-sign-with-sender --cl-block-yas--snippet-previous-active-field-- biblio--selection-insert none-but-delete vc-src-log-switches winnow sgml-syntax-propertize HTML\ specific\ export\ settings ZZYA cl-print--preprocess Noto\ Sans\ Deseret infix-token :examined org-agenda-regexp-filter-preset vc-git-conflicted-files erc-away-nickname post-deadline xref-w-dedicated shr-parse-image-data Load\ snippets\.\.\. org--plot/radar-ticks message-kill-actions ibuffer-update --cl-block-yas--field-start-- \' is13194-to-ucs-telugu-hashtbl gnus-summary-catchup-from-here mh-msg-num-width-to-column VITAE request-list sgml-tag-name--cmacro ZZYX Exporting\ Code\ Blocks expired print-command ...] :prompt "Apropos: " :predicate #f(compiled-function (x) #<bytecode 0x158478945d69>) :history consult--apropos-history :category symbol :default #("fill-fun-values" 0 15 (fontified t)))
  consult-apropos()
  funcall-interactively(consult-apropos)
  call-interactively(consult-apropos record nil)
  command-execute(consult-apropos record)
  execute-extended-command(nil "consult-apropos" nil)
  funcall-interactively(execute-extended-command nil "consult-apropos" nil)
  call-interactively(execute-extended-command nil nil)
  command-execute(execute-extended-command)

and, here is a selection from the stack during the recursion:

* lwarn((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer *Warnings*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (nil #<buffer *Backtrace*>) (t yas--auto-fill)) "")
  (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ((bufs ...)) (setq bufs (cons ... ...)))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell (assq yas--original-auto-fill-function yas--fill-fun-values)) (af-cell (assq auto-fill-function fill-fun-values))) (if (local-variable-p 'yas--original-auto-fill-function) (progn (if yf-cell ... ...))) (if (local-variable-p 'auto-fill-function) (progn (if af-cell ... ...)))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let (...) (mapc ... yas--watch-auto-fill-backtrace)) (save-current-buffer (set-buffer standard-output) (buffer-string))) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))
  (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let (...) (setq bufs ...))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell ...) (af-cell ...)) (if (local-variable-p ...) (progn ...)) (if (local-variable-p ...) (progn ...))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let ... ...) (save-current-buffer ... ...)) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))
  (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value ...)))) (fill-fun-values (list (list t (default-value ...)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ... ...)) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* (... ...) (if ... ...) (if ... ...)) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output ...)) (unwind-protect (progn ... ...) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))))
  (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 ...))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (setq reoverlays (cons (yas--snapshot-overlay-location (progn (or ... ...) (aref snippet 5)) beg end) reoverlays)) (setq --dolist-tail-- (cdr --dolist-tail--)))) (goto-char orig-point) (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t ...))) (fill-fun-values (list (list t ...))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- ...) buf) (while --dolist-tail-- (setq buf ...) (set-buffer buf) (let* ... ... ...) (setq --dolist-tail-- ...)))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let (...) (unwind-protect ... ...)) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))) (save-excursion (setq end (progn (forward-paragraph) (point))) (setq beg (progn (backward-paragraph) (point)))) (save-excursion (save-restriction (narrow-to-region beg end) (let ((--dolist-tail-- remarkers) remarker) (while --dolist-tail-- (setq remarker (car --dolist-tail--)) (set-marker (car remarker) (yas--goto-saved-location (cdr remarker))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (mapc #'yas--restore-overlay-location reoverlays)) (mapc #'(lambda (snippet) (let ((envvar ...)) (progn (let* ... ... ...)))) snippets)))
  yas--auto-fill()
  internal-auto-fill()
  self-insert-command(1)
  newline()
  display-warning((yasnippet auto-fill bug) "‘yas--original-auto-fill-function’ unexpectedly ni..." :error)
  #f(compiled-function (type level message ...) #<bytecode 0x158478aeba79>)((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer *Warnings*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (nil #<buffer *Backtrace*>) (t yas--auto-fill)) "")
  apply(#f(compiled-function (type level message &rest args) #<bytecode 0x158478aeba79>) ((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer *Warnings*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (nil #<buffer *Backtrace*>) (t yas--auto-fill)) ""))
* lwarn((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer *Warnings*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (nil #<buffer *Backtrace*>) (t yas--auto-fill)) "")
  (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ((bufs ...)) (setq bufs (cons ... ...)))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell (assq yas--original-auto-fill-function yas--fill-fun-values)) (af-cell (assq auto-fill-function fill-fun-values))) (if (local-variable-p 'yas--original-auto-fill-function) (progn (if yf-cell ... ...))) (if (local-variable-p 'auto-fill-function) (progn (if af-cell ... ...)))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let (...) (mapc ... yas--watch-auto-fill-backtrace)) (save-current-buffer (set-buffer standard-output) (buffer-string))) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))
  (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let (...) (setq bufs ...))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell ...) (af-cell ...)) (if (local-variable-p ...) (progn ...)) (if (local-variable-p ...) (progn ...))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let ... ...) (save-current-buffer ... ...)) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))
  (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value ...)))) (fill-fun-values (list (list t (default-value ...)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ... ...)) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* (... ...) (if ... ...) (if ... ...)) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output ...)) (unwind-protect (progn ... ...) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))))
  (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 ...))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (setq reoverlays (cons (yas--snapshot-overlay-location (progn (or ... ...) (aref snippet 5)) beg end) reoverlays)) (setq --dolist-tail-- (cdr --dolist-tail--)))) (goto-char orig-point) (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t ...))) (fill-fun-values (list (list t ...))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- ...) buf) (while --dolist-tail-- (setq buf ...) (set-buffer buf) (let* ... ... ...) (setq --dolist-tail-- ...)))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let (...) (unwind-protect ... ...)) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))) (save-excursion (setq end (progn (forward-paragraph) (point))) (setq beg (progn (backward-paragraph) (point)))) (save-excursion (save-restriction (narrow-to-region beg end) (let ((--dolist-tail-- remarkers) remarker) (while --dolist-tail-- (setq remarker (car --dolist-tail--)) (set-marker (car remarker) (yas--goto-saved-location (cdr remarker))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (mapc #'yas--restore-overlay-location reoverlays)) (mapc #'(lambda (snippet) (let ((envvar ...)) (progn (let* ... ... ...)))) snippets)))
  yas--auto-fill()
  internal-auto-fill()
  self-insert-command(1)
  newline()
  display-warning((yasnippet auto-fill bug) "‘yas--original-auto-fill-function’ unexpectedly ni..." :error)
  #f(compiled-function (type level message ...) #<bytecode 0x158478aeba79>)((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer *Warnings*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (nil #<buffer *Backtrace*>) (t yas--auto-fill)) "")
  apply(#f(compiled-function (type level message &rest args) #<bytecode 0x158478aeba79>) ((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer *Warnings*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (nil #<buffer *Backtrace*>) (t yas--auto-fill)) ""))
* lwarn((yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." #<buffer *Warnings*> ((do-auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer *Org ASCII Export*>) (org-auto-fill-function #<buffer  *org-src-fontification:org-mode*> #<buffer ess-org-beamer.org> #<buffer ess-org.org>) (t nil)) ((yas--auto-fill #<buffer *changes to ~/work/2021/ess-intro/presentation-org-mode/*> #<buffer  *org-src-fontification:org-mode*> #<buffer *Org ASCII Export*> #<buffer ess-org-beamer.org>) (nil #<buffer *Backtrace*>) (t yas--auto-fill)) "")
  (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ((bufs ...)) (setq bufs (cons ... ...)))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell (assq yas--original-auto-fill-function yas--fill-fun-values)) (af-cell (assq auto-fill-function fill-fun-values))) (if (local-variable-p 'yas--original-auto-fill-function) (progn (if yf-cell ... ...))) (if (local-variable-p 'auto-fill-function) (progn (if af-cell ... ...)))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let (...) (mapc ... yas--watch-auto-fill-backtrace)) (save-current-buffer (set-buffer standard-output) (buffer-string))) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))
  (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value 'yas--original-auto-fill-function)))) (fill-fun-values (list (list t (default-value 'auto-fill-function)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let (...) (setq bufs ...))) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* ((yf-cell ...) (af-cell ...)) (if (local-variable-p ...) (progn ...)) (if (local-variable-p ...) (progn ...))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output (generate-new-buffer " *string-output*"))) (unwind-protect (progn (let ... ...) (save-current-buffer ... ...)) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))
  (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t (default-value ...)))) (fill-fun-values (list (list t (default-value ...)))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- (let ... ...)) buf) (while --dolist-tail-- (setq buf (car --dolist-tail--)) (set-buffer buf) (let* (... ...) (if ... ...) (if ... ...)) (setq --dolist-tail-- (cdr --dolist-tail--))))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let ((standard-output ...)) (unwind-protect (progn ... ...) (kill-buffer standard-output))) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))))
  (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 ...))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (setq reoverlays (cons (yas--snapshot-overlay-location (progn (or ... ...) (aref snippet 5)) beg end) reoverlays)) (setq --dolist-tail-- (cdr --dolist-tail--)))) (goto-char orig-point) (let ((yas--inhibit-overlay-hooks t)) (if yas--original-auto-fill-function (funcall yas--original-auto-fill-function) (let ((yas--fill-fun-values (list (list t ...))) (fill-fun-values (list (list t ...))) (print-length 3)) (save-current-buffer (let ((--dolist-tail-- ...) buf) (while --dolist-tail-- (setq buf ...) (set-buffer buf) (let* ... ... ...) (setq --dolist-tail-- ...)))) (lwarn '(yasnippet auto-fill bug) :error "`yas--original-auto-fill-function' unexpectedly ni..." (current-buffer) yas--fill-fun-values fill-fun-values (if (fboundp 'backtrace--print-frame) (let (...) (unwind-protect ... ...)) "")) (auto-fill-mode -1) (defvar warning-suppress-types) (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug))))) (save-excursion (setq end (progn (forward-paragraph) (point))) (setq beg (progn (backward-paragraph) (point)))) (save-excursion (save-restriction (narrow-to-region beg end) (let ((--dolist-tail-- remarkers) remarker) (while --dolist-tail-- (setq remarker (car --dolist-tail--)) (set-marker (car remarker) (yas--goto-saved-location (cdr remarker))) (setq --dolist-tail-- (cdr --dolist-tail--)))) (mapc #'yas--restore-overlay-location reoverlays)) (mapc #'(lambda (snippet) (let ((envvar ...)) (progn (let* ... ... ...)))) snippets)))
  yas--auto-fill()
  internal-auto-fill()
  self-insert-command(1)
  newline()

@greg-minshall
Copy link

oh, and by the way, i tried moving the call to (lwarn) to after turning off auto-fill-mode, changing warnings. assuming i did that correctly, i didn't see any difference in terms of the recursion.

also, i don't really know the protocol w.r.t. commenting on a closed issue. please let me know if i should open a new issue, or what i might try in terms of debugging.

@greg-minshall
Copy link

sorry. i rebuilt, and re-launched emacs. and, my "consistent" problem does not exhibit itself. false alarm?

@hardenedapple
Copy link

Hello there,
I've been hitting this for a while, but only recently found the time to get any more information than what was already present.
I believe that the first paragraph in the below elisp file should be able to reproduce this at will on emacs 26 (at least it does for me).

The second paragraph shows the strange emacs behaviour that I believe is responsible.

;; Observable bug is that `auto-fill-mode' gets turned off sometimes.
;; This is due to the disabling that happens in `yas--auto-fill'.  That happens
;; because `yas--original-auto-fill-function' is `nil'.
;; I get the relevant warning, but I don't get the full backtrace.

;; Start out with global of `do-auto-fill' and buffer local value of
;; `yas--auto-fill'.
(describe-variable 'auto-fill-function)
;; `let' sets the *buffer-local* `auto-fill-function'.
(let ((auto-fill-function 'test-symbol))
  ;; `revert-buffer' calls `normal-mode', which first uses
  ;; `kill-all-local-variables' so there is no longer a *buffer-local*
  ;; `auto-fill-function', then triggers the hooks so that `yas--minor-mode'
  ;; gets turned on.  `yas-minor-mode' manually calls `yas--auto-fill-wrapper',
  ;; which does a `setq' on `auto-fill-function'.
  ;;
  ;; That `setq' ends up setting the *global* value (because of the special
  ;; environment) and the `let' does not reset the *buffer-local* value since
  ;; there is no longer a buffer-local value.
  ;; I believe this should change in Emacs, so that if there is a buffer-local
  ;; let binding but there is no buffer-local variable any more the `setq'
  ;; should create a buffer-local variable as it does outside of a let binding.
  ;; (The `let' binding is not reset due in this special circumstance since the
  ;; local variable has been removed, it getting reset *may* be strange -- will
  ;; ask the emacs folk about it).
  (revert-buffer))
;; N.b. the above situation happens for me a lot when a file has changed
;; underneath my editing session and I call `newline'.
;; - `newline' let-binds `auto-fill-function'.
;; - `ask-user-about-supersession-threat' then checks if the buffer has been modified, and allows
;; me to call `revert-buffer' as one of the options.
(describe-variable 'auto-fill-function)
;; At this point things have already gone wrong, but the symptom has not been
;; seen.  When you start typing the `lwarn' triggers in `yas--auto-fill' then
;; turns off `auto-fill-mode'.  It's even later (when I type over the line and
;; emacs doesn't create a new line) that I notice the problem.
;; ... <start typing here> ...
;; Now `auto-fill-function' is `nil' buffer-locally, but is `yas--auto-fill'
;; globally, ready to affect new buffers that would get opened.
(describe-variable 'auto-fill-function)


;; N.b. the below identifies the emacs behaviour that causes the problematic
;; yasnippet behaviour.
;; Ensure that `auto-fill-function' has a buffer-local version and a global
;; version.
(setq auto-fill-function 'local-symbol)
(describe-variable 'auto-fill-function)
;; `auto-fill-function' is let-bound in the buffer scope
(let ((auto-fill-function 'temp-symbol))
  ;; Now there is no buffer-local variable for `auto-fill-function', but the
  ;; `let' unwrapping info is still there.
  (kill-local-variable 'auto-fill-function)
  ;; Since the check in the emacs source is
  ;; a) Is there a buffer-local variable.
  ;; b) Is there a let-binding shadowing the current variable.
  ;; Then this `setq' sets the *global* variable.
  (setq auto-fill-function 'other-symbol))
;; Exiting the `let' has special handling to avoid resetting a local variable
;; when the local variable was `let' bound, which means that overall the `setq'
;; set the global variable and the `let' has been lost.
(describe-variable 'auto-fill-function)


;; N.b. I think this is not a great Emacs behaviour and intend to eventually get
;; around to reporting it upstream.
;; I think in this situation where there is a *buffer-local* `let' binding but
;; there is currently no buffer-local version of the variable then the `setq'
;; should not set the global value, but should instead create a buffer-local
;; variable.
;; 
;; Setting the global value would not be a problem, if it did not persist
;; *after* the `let' binding has exited.  I would guess this was not the
;; intention of the rule about `let' bindings sometimes not triggering a `setq'
;; to create an automatic buffer-local variable.
;;
;; I believe this is the cause of a bug in yasnippet.  I've been hitting it when
;; - `newline' creates a `let' binding for `auto-fill-function'.
;; - `ask-user-about-supersession-threat' kicks in because the file has changed.
;; - `revert-buffer' is chosen.
;; - That triggers `normal-mode', which runs `kill-all-local-variables'.
;; - Then `yas-global-mode-enable-in-buffers' turns `yas-minor-mode' on.
;; - `yas--auto-fill-wrapper' attempts to set the buffer-local
;;   `auto-fill-function'.
;; https://github.com/joaotavora/yasnippet/issues/919

;; I.e. I think the final state after having done the above should be:
;; 1) Global value has not changed.
;; 2) Local value has not changed.
;;
;; While at the moment the state after the above is:
;; 1) Global value has been set to `other-symbol'.
;; 2) Local value has been removed.
;;
;; I currently have a hack in the emacs source code that does this by swapping
;; the use of `let_shadows_buffer_binding_p' in the `SYMBOL_FORWARDED' clause of
;; `set_internal' to a similar function which only returns `true' if there is a
;; `SPECPDL_LET_DEFAULT' binding, and does not return `true' for a
;; `SPECPDL_LET_LOCAL' binding.
;;
;; Frankly I don't know whether that's a good idea -- I just guessed at the
;; meanings of those two enum values.  However it does seem to work for me.

@joaotavora
Copy link
Owner

Thanks, @hardenedapple. I don't want to discourage you from investigation, but this repository has been without a maintainer for many months, so you're unlikely to get a useful reply here.

@hardenedapple
Copy link

Ah, ok -- thanks for the heads-up.
At least my post may help anyone else having the same problem understand what's happening ;-)

@hardenedapple
Copy link

For anyone who comes across this in the future:
I believe this problem should go away after the changes Stefan made in emacs master.
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=62419

monnier added a commit that referenced this issue 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 issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants