doomemacs icon indicating copy to clipboard operation
doomemacs copied to clipboard

js-ts-mode block-comment auto-continuation Args out of range error

Open TomFryersMidsummer opened this issue 3 months ago • 4 comments

I confirm that...

  • [x] I searched the issue tracker and found no similar issues.

  • [x] I searched the documentation, FAQ, discussion board, and Google for solutions to my issue.

  • [x] I read the debugging guide and researched the issue to the best of my ability.

  • [x] My issue can be observed on the latest available commit of Doom.

  • [x] My issue can be observed on a stable release of Emacs (i.e. doesn't end in .50, .60, or .90.99)

Describe your issue

Pressing return at the end of a line inside a block comment (most likely JSDoc, but it doesn't seem to matter) in javascript-mode inserts a new line.

/**
 * fish|
 */
function foo() {
    return 5;
}

becomes

/**
 * fish
 * |
 */
function foo() {
    return 5;
}

However, in js-ts-mode, the result is instead

/**
 * fish
|
 */
function foo() {
    return 5;
}

with an error: Args out of range: #<buffer *new*>, 0, 3.

Here is the backtrace:

Debugger entered--Lisp error: (args-out-of-range #<buffer *new*> 0 3)
  match-string(0)
  #f(compiled-function (n parent bol &rest _) #<bytecode 0x38b3914738c5aaa>)(nil #<treesit-node comment in 1-17> 13)
  treesit--simple-indent-eval((prev-adaptive-prefix nil #<treesit-node comment in 1-17> 13))
  treesit-simple-indent(nil #<treesit-node comment in 1-17> 13)
  treesit--indent-1()
  treesit-indent()
  indent-according-to-mode()
  comment-indent-new-line(nil)
  funcall(comment-indent-new-line nil)
  (progn (funcall comment-line-break-function nil) t)
  (if (and +default-want-RET-continue-comments (doom-point-in-comment-p) (functionp comment-line-break-function)) (progn (funcall comment-line-break-function nil) t))
  +default--newline-indent-and-continue-comments-a()
  apply(+default--newline-indent-and-continue-comments-a nil)
  newline-and-indent()
  funcall-interactively(newline-and-indent)
  command-execute(newline-and-indent)

Possibly relatedly, using g w to wrap text in a block comment in js-ts-mode doesn't insert an asterisk, as it does in javascript-mode, so you end up with, for instance

/**
 * fish fish fish fish fish fish fish fish fish fish fish fish fish fish fish
   fish fish fish fish fish fish fish fish fish
 */
function foo() {
    return 5;
}

I've only started seeing this since all the JavaScript changes over the past few days. But I didn't use Tree Sitter before that.

The issues doesn't exist with line comments.

Steps to reproduce

  1. Enable the (javascript +tree-sitter) module.
  2. Open Emacs.
  3. Create a new buffer, with SPC b N.
  4. Copy
/**
 * fish
 */
function foo() {
    return 5;
}
  1. Paste, with p.
  2. Enter js-ts-mode, with SPC :, js-ts-mode, RET.
  3. Put your cursor on the end of the fish line (2 G $).
  4. Enter insert mode with a.
  5. Press RET.
  6. Observe that Emacs has inserted a totally empty line.

System information

https://pastebin.com/URcBjn1w

TomFryersMidsummer avatar Sep 02 '25 08:09 TomFryersMidsummer

As of https://github.com/doomemacs/doomemacs/commit/b4b661ca207b53790a715eb1fadab6c85c360722 this should be resolved. Let me know if that isn't the case and I'll reopen it. Thanks for bringing it to my attention!

hlissner avatar Sep 02 '25 09:09 hlissner

Thanks for jumping on it so quickly!

I've updated to the latest commit, but unfortunately the fix doesn't seem to have worked for me: I get exactly the same backtrace as before (module the #<bytecode 0x...> address).

TomFryersMidsummer avatar Sep 02 '25 10:09 TomFryersMidsummer

After more testing, it seems I can reproduce this only on Emacs 29.x. It works fine in 30.x and 31.x, and with any version of the javascript and jsdoc grammars. So it seems js-ts-mode's implementation is to blame (in particular, its tree-sitter indentation rules), but I haven't identified any fix for it yet. typescript-ts-mode and tsx-ts-mode don't have this issue (though they have a different problem to do with over-aggressive insertion of /** */ pairs).

In any case, this needs more investigation, but for the time being, your best option is to upgrade to Emacs 30.x or newer.

hlissner avatar Sep 02 '25 13:09 hlissner

I've updated to Emacs 30.1 and it does indeed seem to fix the behaviour when inserting a new line.

fill-region still doesn't seem to insert asterisks in js-ts-mode or typescript-ts-mode, but that's a lesser issue (and perhaps separate).

I'm guessing it's because adaptive-fill-regex is

"[ 	]*\\(//+\\|\\**\\)[ 	]*\\([-–!|#%;>*·•‣⁃◦ 	]*\\)"

in js-mode but

"\\s-*\\(//+\\|\\**\\)[-–!|#%;>*·•‣⁃◦ 	]*"

in js-ts-mode and typescript-ts-mode.

treesit.el.gz seems to have some references to this variable.

TomFryersMidsummer avatar Sep 11 '25 08:09 TomFryersMidsummer