fix(treesitter): don't add final newline if not present #35970

**Problem(?):** Buffers that (for whatever reason) aren't meant to have
a final newline are still parsed with a final newline in `treesitter.c`.

**Solution:** Don't add the newline to the last buffer line if it
shouldn't be there. (This more closely matches the approach of
`read_buffer_into()`.)

This allows us to, say, use a scratch buffer with `noeol` and `nofixeol`
behind the scenes in `get_string_parser()`.

...which would allow us to track injection trees with extmarks in that
case.

...which would allow us to not drop previous trees after reparsing a
different range with `get_parser():parse()`.

...which would prevent flickering when editing a buffer that has 2+
windows to it in view at a time.

...which would allow us to keep our sanity!!!

(one step at a time...)
This commit is contained in:
Riley Bruins
2025-10-01 17:31:52 -07:00
committed by GitHub
parent 89dc889c3d
commit b4016f4525
2 changed files with 64 additions and 6 deletions

View File

@@ -443,8 +443,9 @@ static const char *input_cb(void *payload, uint32_t byte_index, TSPoint position
*bytes_read = 0;
return "";
}
char *line = ml_get_buf(bp, (linenr_T)position.row + 1);
size_t len = (size_t)ml_get_buf_len(bp, (linenr_T)position.row + 1);
linenr_T lnum = (linenr_T)position.row + 1;
char *line = ml_get_buf(bp, lnum);
size_t len = (size_t)ml_get_buf_len(bp, lnum);
if (position.column > len) {
*bytes_read = 0;
return "";
@@ -456,10 +457,13 @@ static const char *input_cb(void *payload, uint32_t byte_index, TSPoint position
memchrsub(buf, '\n', NUL, tocopy);
*bytes_read = (uint32_t)tocopy;
if (tocopy < BUFSIZE) {
// now add the final \n. If it didn't fit, input_cb will be called again
// on the same line with advanced column.
buf[tocopy] = '\n';
(*bytes_read)++;
// now add the final \n, if it is meant to be present for this buffer. If it didn't fit,
// input_cb will be called again on the same line with advanced column.
if (lnum != bp->b_ml.ml_line_count || (!bp->b_p_bin && bp->b_p_fixeol)
|| (lnum != bp->b_no_eol_lnum && bp->b_p_eol)) {
buf[tocopy] = '\n';
(*bytes_read)++;
}
}
return buf;
#undef BUFSIZE