title: box-style comments with yasnippet
body: <p>I'm looking to write a <a href="https://code.google.com/p/yasnippet/" rel="nofollow noreferrer">yasnippet</a> template that would allow me to add a license header to a script buffer in Emacs. Kinda like <a href="https://github.com/jonatkinson/yasnippet-licenses" rel="nofollow noreferrer">this</a>, but a bit improved:</p>
  
  <ol>
  <li>The header needs to include per-user data, such as the date name and email of the copyright holder,
  which can be obtained with <a href="http://yasnippet.googlecode.com/svn/trunk/doc/snippet-development.html#embedded-emacs-lisp-code" rel="nofollow noreferrer">embedded elisp expansion</a> from yasnippet.</li>
  <li>The header needs to be commented with a syntax depending on the programming mode the file is currently in. There's already <a href="https://gist.github.com/636208/3b3c7e52a54f47f81f2ab183457f3c987568dfb7" rel="nofollow noreferrer">a gist of a snippet that does all that</a>. Basically it amounts to embedding <code>(comment-region (point-min) (point))</code> at the end of your snippet.</li>
  <li>Now, <strong>I want to change the comment-style to a box</strong>. See the emacs documentation for the <code>comment-style</code> variable, or, if you want to see what a box-style comment looks like, just call <code>M-x comment-box</code> on an active region: It calls <code>comment-region</code> with the right options.</li>
  </ol>
  
  <p>A first approach to do that is to setup the style by modifying the end of the previous snippet to:</p>
  
  <pre><code>(let ((comment-style 'box))
              (comment-region (point-min) (point)))
  </code></pre>
  
  <p>Unfortunately, the indentation gets screwed up, and <strong>my box isn't rectangular</strong>. If I start from snippet:</p>
  
  <pre><code>Copyright (c) ${1:`(nth 5 (decode-time))`}
  All rights reserved.
  
  Redistribution and use in source and binary forms, with or
  without modification, are permitted`
        (let ((comment-style 'box))
              (comment-region (point-min) (point)))`
  </code></pre>
  
  <p>The expansion of that snippet "breaks the box" (I'm debugging this snippet with ocaml comment syntax, not that it should matter):</p>
  
  <pre><code>(**************************************************************)
  (* Copyright (c) 2010                                    *)
  (* All rights reserved.                                       *)
  (*                                                            *)
  (* Redistribution and use in source and binary forms, with or *)
  (* without modification, are permitted     *)
  (**************************************************************)
  </code></pre>
  
  <ul>
  <li>At first I thought the second line was indented based on the size of the pre-expansion embedded code, but in that case, it should make the final <code>*)</code> of that line come 25 spaces too soon, not 4. </li>
  <li>If it indented based on <em>no</em> text being present at embedding point, the final <code>*)</code> should arrive 4 spaces too <em>late</em>, not too <em>soon</em>. </li>
  <li>Finally, I don't understand what's going on with the last line, in which there is <em>no embedded code expansion</em>: Usually I don't have any problem getting a square comment box from a paragraph with a short last line (either using <code>comment-box</code>, or the elisp function in the 1st comment-block of this question.</li>
  </ul>
  
  <p>I tried making the comment happen after snippet expansion, to avoid any side-effect, by adding it to <a href="http://yasnippet.googlecode.com/svn/trunk/doc/snippet-development.html#yas-after-exit-snippet-hook-and-yas-before-expand-snippet-hook" rel="nofollow noreferrer"><code>yas/after-exit-snippet-hook</code></a>, replacing the last function of the snippet above with:</p>
  
  <pre><code>(add-hook 'yas/after-exit-snippet-hook
        (let ((comment-style 'box))
              (comment-region (point-min) (point))) nil t)
  </code></pre>
  
  <p>But that didn't help. Even if it did, it would leave me with an expansion hook that would comment <strong>all</strong> the snippets I would want to use in that buffer, something I certainly do not want.</p>
  
  <p>I should also add that I tried to set <code>yas/indent-line</code> to <code>fixed</code>, by adding</p>
  
  <pre><code># expand-env: ((yas/indent-line 'fixed))
  </code></pre>
  
  <p>at the beginning of my snippet but that didn't change anything. Any ideas on how to get a <strong>rectangular</strong> box ?</p>
  
  <hr>
  
  <p><strong>Edit :</strong> We have <a href="https://stackoverflow.com/questions/4563788/box-style-comments-with-yasnippet/4583535#4583535">a very nice answer, along with a proposed fix,</a> (kudos &amp; thanks, Seiji !) but a question remains on how to adapt it to the case where one would want to reuse a field, say like the reuse of <code>$1</code> in:</p>
  
  <pre><code>Copyright (c) ${1:`(nth 5 (decode-time))`}
  All rights reserved.
  
  Redistribution and use in $1, in source and binary forms
  `(let ((comment-style 'box))
          (comment-region (point-min) (point-at-eol 0)))`
  </code></pre>
  
  <p>In that case, the template engine copies the (variable-length) value obtained for the field <code>$1</code>, namely <code>2011</code>, to the last line, at template expansion (after indentation), giving a comment line 2 characters too wide. It becomes hard to predict when writing the template that one should <em>remove</em> <strong>4</strong> characters at this line. Perhaps field reuse <em>and</em> correct indentation are too much to ask for simultaneously. Does any one see a way to do this, though ?</p>