if (NILP (lisp_ranges)) return;
Lisp_Object new_ranges_head = lisp_ranges;
+ Lisp_Object prev_cons = Qnil;
FOR_EACH_TAIL_SAFE (lisp_ranges)
{
new_ranges_head = XCDR (new_ranges_head);
else if (beg >= visible_end)
{
- /* Even the beg is after visible_end, dicard this range and all
+ /* Even the beg is after visible_end, discard this range and all
the ranges after it. */
- XSETCDR (range, Qnil);
+ if (NILP (prev_cons))
+ new_ranges_head = Qnil;
+ else
+ XSETCDR (prev_cons, Qnil);
break;
}
else
if (end > visible_end)
XSETCDR (range, make_fixnum (visible_end));
}
+ prev_cons = lisp_ranges;
}
XTS_PARSER (parser)->last_set_ranges = new_ranges_head;
if (NILP (new_ranges_head))
{
+ /* We are in a weird situation here: none of the previous ranges
+ overlaps with the new visible region. We don't have any good
+ options, so just throw the towel: just remove ranges and hope
+ lisp world will soon update with reasonable ranges or just
+ delete this parser. */
bool success;
success = ts_parser_set_included_ranges (XTS_PARSER (parser)->parser,
NULL, 0);
(should (equal '((16 . 28)) (treesit-query-range
'javascript query nil nil '(1 . -1)))))))
+(ert-deftest treesit-range-fixup-after-edit ()
+ "Tests if Emacs can fix OOB ranges after deleting text or narrowing."
+ (skip-unless (treesit-language-available-p 'json))
+ (with-temp-buffer
+ (let ((parser (treesit-parser-create 'json)))
+ (insert "11111111111111111111")
+ (treesit-parser-set-included-ranges parser '((1 . 20)))
+ (treesit-parser-root-node parser)
+ (should (equal (treesit-parser-included-ranges parser)
+ '((1 . 20))))
+
+ (narrow-to-region 5 15)
+ (should (equal (treesit-parser-included-ranges parser)
+ '((5 . 15))))
+
+ (widen)
+ ;; Trickier ranges
+ ;; 11111111111111111111
+ ;; [ ] [ ]
+ ;; { narrow }
+ (treesit-parser-set-included-ranges parser '((1 . 7) (10 . 15)))
+ (should (equal (treesit-parser-included-ranges parser)
+ '((1 . 7) (10 . 15))))
+ (narrow-to-region 5 13)
+ (should (equal (treesit-parser-included-ranges parser)
+ '((5 . 7) (10 . 13))))
+
+ ;; Narrow in front.
+ (widen)
+ (treesit-parser-set-included-ranges parser '((4 . 17)))
+ ;; 11111111111111111111
+ ;; [ ]
+ ;; { } narrow
+ (narrow-to-region 1 8)
+ (should (equal (treesit-parser-included-ranges parser)
+ '((4 . 8))))
+
+ ;; Narrow in back.
+ (widen)
+ (treesit-parser-set-included-ranges parser '((4 . 17)))
+ ;; 11111111111111111111
+ ;; [ ]
+ ;; { } narrow
+ (narrow-to-region 15 20)
+ (should (equal (treesit-parser-included-ranges parser)
+ '((15 . 17))))
+
+ ;; No overlap
+ (widen)
+ (treesit-parser-set-included-ranges parser '((15 . 20)))
+ ;; 11111111111111111111
+ ;; [ ]
+ ;; { } narrow
+ (narrow-to-region 1 10)
+ (should (equal (treesit-parser-included-ranges parser)
+ nil)))))
+
;;; Multiple language
(ert-deftest treesit-multi-lang ()