3

I use fill-column in my dot-Emacs. And I have the following setting:

(turn-on-auto-fill)
(set-fill-column 60)

The result looks like this:

enter image description here

Every time when the input exceeds columnnumber 60, it will break and proceed further on the new line. Next to this, I use an YASnippet snippet, which will set up a proper structure for documentation of functions. The snippet is constructed as following:

#name : example of snippet foo bar
# --

#  EXAMPLE FOO BAR 
/* $1
*
*/
public function f$2($3) {

} # End scope f$2

However, with the fill-column setting enabled, I ran into weird problems:

enter image description here

When typing in the docstring, the sentence get stucked at the end. I've expected it to proceed on a new line (with a new comment tag before), when the current line gets too long. But this is not the case.

Furthermore, the weird thingy is that this problem is not anymore when I delete the mirror on the last line in the snippet:

#name : example of snippet foo bar
# --

#  EXAMPLE FOO BAR 
/* $1
*
*/
public function f$2($3) {

} 

Then I get this instead:

enter image description here

But why? Can anyone explain why the last line is causing an error with fill-column? I don't see any relationship between these two things.

And how can I get the latest line mirrored, without the docstring stucked on first line?

2
+50

You didn't mention which major mode this happens in, but I can see the problem using c-mode. Here is an (abridged) backtrace which you can get after setting debug-on-error:

Debugger entered--Lisp error: (args-out-of-range #<buffer xx> 66 66)...
  buffer-substring(#<marker at 66 in xx> #<marker at 66 in xx>)
  yas--field-text-for-display([cl-struct-yas--field 2 #<marker at 66 in xx> #<ma...
  (let* ((yas-text (yas--field-text-for-display field)) (yas-modified-p (progn (...
  yas--apply-transform([cl-struct-yas--mirror #<marker at 89 in xx> #<marker at ...
  ...
  yas--mirror-update-display([cl-struct-yas--mirror #<marker at 89 in xx> #<mark...
  ...
  yas--update-mirrors([cl-struct-yas--snippet ([cl-struct-yas--field 1 #<marker ...
  ...
  yas--on-field-overlay-modification(#<overlay from 26 to 41 in xx> t 37 37 1)
  delete-horizontal-space()
  #[nil ... [soft allow-auto-fill delete-horizontal-space ...
  c-indent-new-comment-line(t)
  default-indent-new-line(t)
  do-auto-fill()
  apply(do-auto-fill nil)
  c-mask-paragraph(nil t do-auto-fill)
  c-do-auto-fill()
  self-insert-command(1)
  call-interactively(self-insert-command nil nil)
  command-execute(self-insert-command)

Basically the problem is that yasnippet updates all mirrors when any field is modified. The filling code calls c-mask-paragraph which narrows the region to just that paragraph so the mirror updating fails.

The following advice can work around the problem:

(defun apply-with-widening (fun &rest args)
  (save-restriction
    (widen)
    (apply fun args)))
(advice-add 'yas--update-mirrors :around #'apply-with-widening)

I'm considering the fix at https://github.com/capitaomorte/yasnippet/pull/643

  • Noam, many thanks for your suggested fix. I tried it with your solution, and it's working! It's for the PHP-mode. I'm trying to learn from it, however my Elisp knowledge is somewhat limited. But I'm impressed by your solution. – ReneFroger Jan 6 '16 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.