syntax_map_tests.rs

   1// use super::*;
   2// use crate::LanguageConfig;
   3// use rand::rngs::StdRng;
   4// use std::{env, ops::Range, sync::Arc};
   5// use text::Buffer;
   6// use tree_sitter::Node;
   7// use unindent::Unindent as _;
   8// use util::test::marked_text_ranges;
   9
  10// #[test]
  11// fn test_splice_included_ranges() {
  12//     let ranges = vec![ts_range(20..30), ts_range(50..60), ts_range(80..90)];
  13
  14//     let (new_ranges, change) = splice_included_ranges(
  15//         ranges.clone(),
  16//         &[54..56, 58..68],
  17//         &[ts_range(50..54), ts_range(59..67)],
  18//     );
  19//     assert_eq!(
  20//         new_ranges,
  21//         &[
  22//             ts_range(20..30),
  23//             ts_range(50..54),
  24//             ts_range(59..67),
  25//             ts_range(80..90),
  26//         ]
  27//     );
  28//     assert_eq!(change, 1..3);
  29
  30//     let (new_ranges, change) = splice_included_ranges(ranges.clone(), &[70..71, 91..100], &[]);
  31//     assert_eq!(
  32//         new_ranges,
  33//         &[ts_range(20..30), ts_range(50..60), ts_range(80..90)]
  34//     );
  35//     assert_eq!(change, 2..3);
  36
  37//     let (new_ranges, change) =
  38//         splice_included_ranges(ranges.clone(), &[], &[ts_range(0..2), ts_range(70..75)]);
  39//     assert_eq!(
  40//         new_ranges,
  41//         &[
  42//             ts_range(0..2),
  43//             ts_range(20..30),
  44//             ts_range(50..60),
  45//             ts_range(70..75),
  46//             ts_range(80..90)
  47//         ]
  48//     );
  49//     assert_eq!(change, 0..4);
  50
  51//     let (new_ranges, change) =
  52//         splice_included_ranges(ranges.clone(), &[30..50], &[ts_range(25..55)]);
  53//     assert_eq!(new_ranges, &[ts_range(25..55), ts_range(80..90)]);
  54//     assert_eq!(change, 0..1);
  55
  56//     // does not create overlapping ranges
  57//     let (new_ranges, change) =
  58//         splice_included_ranges(ranges.clone(), &[0..18], &[ts_range(20..32)]);
  59//     assert_eq!(
  60//         new_ranges,
  61//         &[ts_range(20..32), ts_range(50..60), ts_range(80..90)]
  62//     );
  63//     assert_eq!(change, 0..1);
  64
  65//     fn ts_range(range: Range<usize>) -> tree_sitter::Range {
  66//         tree_sitter::Range {
  67//             start_byte: range.start,
  68//             start_point: tree_sitter::Point {
  69//                 row: 0,
  70//                 column: range.start,
  71//             },
  72//             end_byte: range.end,
  73//             end_point: tree_sitter::Point {
  74//                 row: 0,
  75//                 column: range.end,
  76//             },
  77//         }
  78//     }
  79// }
  80
  81// #[gpui::test]
  82// fn test_syntax_map_layers_for_range() {
  83//     let registry = Arc::new(LanguageRegistry::test());
  84//     let language = Arc::new(rust_lang());
  85//     registry.add(language.clone());
  86
  87//     let mut buffer = Buffer::new(
  88//         0,
  89//         0,
  90//         r#"
  91//             fn a() {
  92//                 assert_eq!(
  93//                     b(vec![C {}]),
  94//                     vec![d.e],
  95//                 );
  96//                 println!("{}", f(|_| true));
  97//             }
  98//         "#
  99//         .unindent(),
 100//     );
 101
 102//     let mut syntax_map = SyntaxMap::new();
 103//     syntax_map.set_language_registry(registry.clone());
 104//     syntax_map.reparse(language.clone(), &buffer);
 105
 106//     assert_layers_for_range(
 107//         &syntax_map,
 108//         &buffer,
 109//         Point::new(2, 0)..Point::new(2, 0),
 110//         &[
 111//             "...(function_item ... (block (expression_statement (macro_invocation...",
 112//             "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 113//         ],
 114//     );
 115//     assert_layers_for_range(
 116//         &syntax_map,
 117//         &buffer,
 118//         Point::new(2, 14)..Point::new(2, 16),
 119//         &[
 120//             "...(function_item ...",
 121//             "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 122//             "...(array_expression (struct_expression ...",
 123//         ],
 124//     );
 125//     assert_layers_for_range(
 126//         &syntax_map,
 127//         &buffer,
 128//         Point::new(3, 14)..Point::new(3, 16),
 129//         &[
 130//             "...(function_item ...",
 131//             "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 132//             "...(array_expression (field_expression ...",
 133//         ],
 134//     );
 135//     assert_layers_for_range(
 136//         &syntax_map,
 137//         &buffer,
 138//         Point::new(5, 12)..Point::new(5, 16),
 139//         &[
 140//             "...(function_item ...",
 141//             "...(call_expression ... (arguments (closure_expression ...",
 142//         ],
 143//     );
 144
 145//     // Replace a vec! macro invocation with a plain slice, removing a syntactic layer.
 146//     let macro_name_range = range_for_text(&buffer, "vec!");
 147//     buffer.edit([(macro_name_range, "&")]);
 148//     syntax_map.interpolate(&buffer);
 149//     syntax_map.reparse(language.clone(), &buffer);
 150
 151//     assert_layers_for_range(
 152//             &syntax_map,
 153//             &buffer,
 154//             Point::new(2, 14)..Point::new(2, 16),
 155//             &[
 156//                 "...(function_item ...",
 157//                 "...(tuple_expression (call_expression ... arguments: (arguments (reference_expression value: (array_expression...",
 158//             ],
 159//         );
 160
 161//     // Put the vec! macro back, adding back the syntactic layer.
 162//     buffer.undo();
 163//     syntax_map.interpolate(&buffer);
 164//     syntax_map.reparse(language.clone(), &buffer);
 165
 166//     assert_layers_for_range(
 167//         &syntax_map,
 168//         &buffer,
 169//         Point::new(2, 14)..Point::new(2, 16),
 170//         &[
 171//             "...(function_item ...",
 172//             "...(tuple_expression (call_expression ... arguments: (arguments (macro_invocation...",
 173//             "...(array_expression (struct_expression ...",
 174//         ],
 175//     );
 176// }
 177
 178// #[gpui::test]
 179// fn test_dynamic_language_injection() {
 180//     let registry = Arc::new(LanguageRegistry::test());
 181//     let markdown = Arc::new(markdown_lang());
 182//     registry.add(markdown.clone());
 183//     registry.add(Arc::new(rust_lang()));
 184//     registry.add(Arc::new(ruby_lang()));
 185
 186//     let mut buffer = Buffer::new(
 187//         0,
 188//         0,
 189//         r#"
 190//             This is a code block:
 191
 192//             ```rs
 193//             fn foo() {}
 194//             ```
 195//         "#
 196//         .unindent(),
 197//     );
 198
 199//     let mut syntax_map = SyntaxMap::new();
 200//     syntax_map.set_language_registry(registry.clone());
 201//     syntax_map.reparse(markdown.clone(), &buffer);
 202//     assert_layers_for_range(
 203//             &syntax_map,
 204//             &buffer,
 205//             Point::new(3, 0)..Point::new(3, 0),
 206//             &[
 207//                 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",
 208//                 "...(function_item name: (identifier) parameters: (parameters) body: (block)...",
 209//             ],
 210//         );
 211
 212//     // Replace Rust with Ruby in code block.
 213//     let macro_name_range = range_for_text(&buffer, "rs");
 214//     buffer.edit([(macro_name_range, "ruby")]);
 215//     syntax_map.interpolate(&buffer);
 216//     syntax_map.reparse(markdown.clone(), &buffer);
 217//     assert_layers_for_range(
 218//             &syntax_map,
 219//             &buffer,
 220//             Point::new(3, 0)..Point::new(3, 0),
 221//             &[
 222//                 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",
 223//                 "...(call method: (identifier) arguments: (argument_list (call method: (identifier) arguments: (argument_list) block: (block)...",
 224//             ],
 225//         );
 226
 227//     // Replace Ruby with a language that hasn't been loaded yet.
 228//     let macro_name_range = range_for_text(&buffer, "ruby");
 229//     buffer.edit([(macro_name_range, "html")]);
 230//     syntax_map.interpolate(&buffer);
 231//     syntax_map.reparse(markdown.clone(), &buffer);
 232//     assert_layers_for_range(
 233//             &syntax_map,
 234//             &buffer,
 235//             Point::new(3, 0)..Point::new(3, 0),
 236//             &[
 237//                 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter..."
 238//             ],
 239//         );
 240//     assert!(syntax_map.contains_unknown_injections());
 241
 242//     registry.add(Arc::new(html_lang()));
 243//     syntax_map.reparse(markdown.clone(), &buffer);
 244//     assert_layers_for_range(
 245//             &syntax_map,
 246//             &buffer,
 247//             Point::new(3, 0)..Point::new(3, 0),
 248//             &[
 249//                 "...(fenced_code_block (fenced_code_block_delimiter) (info_string (language)) (code_fence_content) (fenced_code_block_delimiter...",
 250//                 "(fragment (text))",
 251//             ],
 252//         );
 253//     assert!(!syntax_map.contains_unknown_injections());
 254// }
 255
 256// #[gpui::test]
 257// fn test_typing_multiple_new_injections() {
 258//     let (buffer, syntax_map) = test_edit_sequence(
 259//         "Rust",
 260//         &[
 261//             "fn a() { dbg }",
 262//             "fn a() { dbg«!» }",
 263//             "fn a() { dbg!«()» }",
 264//             "fn a() { dbg!(«b») }",
 265//             "fn a() { dbg!(b«.») }",
 266//             "fn a() { dbg!(b.«c») }",
 267//             "fn a() { dbg!(b.c«()») }",
 268//             "fn a() { dbg!(b.c(«vec»)) }",
 269//             "fn a() { dbg!(b.c(vec«!»)) }",
 270//             "fn a() { dbg!(b.c(vec!«[]»)) }",
 271//             "fn a() { dbg!(b.c(vec![«d»])) }",
 272//             "fn a() { dbg!(b.c(vec![d«.»])) }",
 273//             "fn a() { dbg!(b.c(vec![d.«e»])) }",
 274//         ],
 275//     );
 276
 277//     assert_capture_ranges(
 278//         &syntax_map,
 279//         &buffer,
 280//         &["field"],
 281//         "fn a() { dbg!(b.«c»(vec![d.«e»])) }",
 282//     );
 283// }
 284
 285// #[gpui::test]
 286// fn test_pasting_new_injection_line_between_others() {
 287//     let (buffer, syntax_map) = test_edit_sequence(
 288//         "Rust",
 289//         &[
 290//             "
 291//                 fn a() {
 292//                     b!(B {});
 293//                     c!(C {});
 294//                     d!(D {});
 295//                     e!(E {});
 296//                     f!(F {});
 297//                     g!(G {});
 298//                 }
 299//             ",
 300//             "
 301//                 fn a() {
 302//                     b!(B {});
 303//                     c!(C {});
 304//                     d!(D {});
 305//                 «    h!(H {});
 306//                 »    e!(E {});
 307//                     f!(F {});
 308//                     g!(G {});
 309//                 }
 310//             ",
 311//         ],
 312//     );
 313
 314//     assert_capture_ranges(
 315//         &syntax_map,
 316//         &buffer,
 317//         &["struct"],
 318//         "
 319//         fn a() {
 320//             b!(«B {}»);
 321//             c!(«C {}»);
 322//             d!(«D {}»);
 323//             h!(«H {}»);
 324//             e!(«E {}»);
 325//             f!(«F {}»);
 326//             g!(«G {}»);
 327//         }
 328//         ",
 329//     );
 330// }
 331
 332// #[gpui::test]
 333// fn test_joining_injections_with_child_injections() {
 334//     let (buffer, syntax_map) = test_edit_sequence(
 335//         "Rust",
 336//         &[
 337//             "
 338//                 fn a() {
 339//                     b!(
 340//                         c![one.two.three],
 341//                         d![four.five.six],
 342//                     );
 343//                     e!(
 344//                         f![seven.eight],
 345//                     );
 346//                 }
 347//             ",
 348//             "
 349//                 fn a() {
 350//                     b!(
 351//                         c![one.two.three],
 352//                         d![four.five.six],
 353//                     ˇ    f![seven.eight],
 354//                     );
 355//                 }
 356//             ",
 357//         ],
 358//     );
 359
 360//     assert_capture_ranges(
 361//         &syntax_map,
 362//         &buffer,
 363//         &["field"],
 364//         "
 365//         fn a() {
 366//             b!(
 367//                 c![one.«two».«three»],
 368//                 d![four.«five».«six»],
 369//                 f![seven.«eight»],
 370//             );
 371//         }
 372//         ",
 373//     );
 374// }
 375
 376// #[gpui::test]
 377// fn test_editing_edges_of_injection() {
 378//     test_edit_sequence(
 379//         "Rust",
 380//         &[
 381//             "
 382//                 fn a() {
 383//                     b!(c!())
 384//                 }
 385//             ",
 386//             "
 387//                 fn a() {
 388//                     «d»!(c!())
 389//                 }
 390//             ",
 391//             "
 392//                 fn a() {
 393//                     «e»d!(c!())
 394//                 }
 395//             ",
 396//             "
 397//                 fn a() {
 398//                     ed!«[»c!()«]»
 399//                 }
 400//             ",
 401//         ],
 402//     );
 403// }
 404
 405// #[gpui::test]
 406// fn test_edits_preceding_and_intersecting_injection() {
 407//     test_edit_sequence(
 408//         "Rust",
 409//         &[
 410//             //
 411//             "const aaaaaaaaaaaa: B = c!(d(e.f));",
 412//             "const aˇa: B = c!(d(eˇ));",
 413//         ],
 414//     );
 415// }
 416
 417// #[gpui::test]
 418// fn test_non_local_changes_create_injections() {
 419//     test_edit_sequence(
 420//         "Rust",
 421//         &[
 422//             "
 423//                 // a! {
 424//                     static B: C = d;
 425//                 // }
 426//             ",
 427//             "
 428//                 ˇa! {
 429//                     static B: C = d;
 430//                 ˇ}
 431//             ",
 432//         ],
 433//     );
 434// }
 435
 436// #[gpui::test]
 437// fn test_creating_many_injections_in_one_edit() {
 438//     test_edit_sequence(
 439//         "Rust",
 440//         &[
 441//             "
 442//                 fn a() {
 443//                     one(Two::three(3));
 444//                     four(Five::six(6));
 445//                     seven(Eight::nine(9));
 446//                 }
 447//             ",
 448//             "
 449//                 fn a() {
 450//                     one«!»(Two::three(3));
 451//                     four«!»(Five::six(6));
 452//                     seven«!»(Eight::nine(9));
 453//                 }
 454//             ",
 455//             "
 456//                 fn a() {
 457//                     one!(Two::three«!»(3));
 458//                     four!(Five::six«!»(6));
 459//                     seven!(Eight::nine«!»(9));
 460//                 }
 461//             ",
 462//         ],
 463//     );
 464// }
 465
 466// #[gpui::test]
 467// fn test_editing_across_injection_boundary() {
 468//     test_edit_sequence(
 469//         "Rust",
 470//         &[
 471//             "
 472//                 fn one() {
 473//                     two();
 474//                     three!(
 475//                         three.four,
 476//                         five.six,
 477//                     );
 478//                 }
 479//             ",
 480//             "
 481//                 fn one() {
 482//                     two();
 483//                     th«irty_five![»
 484//                         three.four,
 485//                         five.six,
 486//                     «   seven.eight,
 487//                     ];»
 488//                 }
 489//             ",
 490//         ],
 491//     );
 492// }
 493
 494// #[gpui::test]
 495// fn test_removing_injection_by_replacing_across_boundary() {
 496//     test_edit_sequence(
 497//         "Rust",
 498//         &[
 499//             "
 500//                 fn one() {
 501//                     two!(
 502//                         three.four,
 503//                     );
 504//                 }
 505//             ",
 506//             "
 507//                 fn one() {
 508//                     t«en
 509//                         .eleven(
 510//                         twelve,
 511//                     »
 512//                         three.four,
 513//                     );
 514//                 }
 515//             ",
 516//         ],
 517//     );
 518// }
 519
 520// #[gpui::test]
 521// fn test_combined_injections_simple() {
 522//     let (buffer, syntax_map) = test_edit_sequence(
 523//         "ERB",
 524//         &[
 525//             "
 526//                 <body>
 527//                     <% if @one %>
 528//                         <div class=one>
 529//                     <% else %>
 530//                         <div class=two>
 531//                     <% end %>
 532//                     </div>
 533//                 </body>
 534//             ",
 535//             "
 536//                 <body>
 537//                     <% if @one %>
 538//                         <div class=one>
 539//                     ˇ else ˇ
 540//                         <div class=two>
 541//                     <% end %>
 542//                     </div>
 543//                 </body>
 544//             ",
 545//             "
 546//                 <body>
 547//                     <% if @one «;» end %>
 548//                     </div>
 549//                 </body>
 550//             ",
 551//         ],
 552//     );
 553
 554//     assert_capture_ranges(
 555//         &syntax_map,
 556//         &buffer,
 557//         &["tag", "ivar"],
 558//         "
 559//             <«body»>
 560//                 <% if «@one» ; end %>
 561//                 </«div»>
 562//             </«body»>
 563//         ",
 564//     );
 565// }
 566
 567// #[gpui::test]
 568// fn test_combined_injections_empty_ranges() {
 569//     test_edit_sequence(
 570//         "ERB",
 571//         &[
 572//             "
 573//                 <% if @one %>
 574//                 <% else %>
 575//                 <% end %>
 576//             ",
 577//             "
 578//                 <% if @one %>
 579//                 ˇ<% end %>
 580//             ",
 581//         ],
 582//     );
 583// }
 584
 585// #[gpui::test]
 586// fn test_combined_injections_edit_edges_of_ranges() {
 587//     let (buffer, syntax_map) = test_edit_sequence(
 588//         "ERB",
 589//         &[
 590//             "
 591//                 <%= one @two %>
 592//                 <%= three @four %>
 593//             ",
 594//             "
 595//                 <%= one @two %ˇ
 596//                 <%= three @four %>
 597//             ",
 598//             "
 599//                 <%= one @two %«>»
 600//                 <%= three @four %>
 601//             ",
 602//         ],
 603//     );
 604
 605//     assert_capture_ranges(
 606//         &syntax_map,
 607//         &buffer,
 608//         &["tag", "ivar"],
 609//         "
 610//             <%= one «@two» %>
 611//             <%= three «@four» %>
 612//         ",
 613//     );
 614// }
 615
 616// #[gpui::test]
 617// fn test_combined_injections_splitting_some_injections() {
 618//     let (_buffer, _syntax_map) = test_edit_sequence(
 619//         "ERB",
 620//         &[
 621//             r#"
 622//                 <%A if b(:c) %>
 623//                 d
 624//                 <% end %>
 625//                 eee
 626//                 <% f %>
 627//             "#,
 628//             r#"
 629//                 <%« AAAAAAA %>
 630//                 hhhhhhh
 631//                 <%=» if b(:c) %>
 632//                 d
 633//                 <% end %>
 634//                 eee
 635//                 <% f %>
 636//             "#,
 637//         ],
 638//     );
 639// }
 640
 641// #[gpui::test]
 642// fn test_combined_injections_editing_after_last_injection() {
 643//     test_edit_sequence(
 644//         "ERB",
 645//         &[
 646//             r#"
 647//                 <% foo %>
 648//                 <div></div>
 649//                 <% bar %>
 650//             "#,
 651//             r#"
 652//                 <% foo %>
 653//                 <div></div>
 654//                 <% bar %>«
 655//                 more text»
 656//             "#,
 657//         ],
 658//     );
 659// }
 660
 661// #[gpui::test]
 662// fn test_combined_injections_inside_injections() {
 663//     let (buffer, syntax_map) = test_edit_sequence(
 664//         "Markdown",
 665//         &[
 666//             r#"
 667//                 here is
 668//                 some
 669//                 ERB code:
 670
 671//                 ```erb
 672//                 <ul>
 673//                 <% people.each do |person| %>
 674//                     <li><%= person.name %></li>
 675//                     <li><%= person.age %></li>
 676//                 <% end %>
 677//                 </ul>
 678//                 ```
 679//             "#,
 680//             r#"
 681//                 here is
 682//                 some
 683//                 ERB code:
 684
 685//                 ```erb
 686//                 <ul>
 687//                 <% people«2».each do |person| %>
 688//                     <li><%= person.name %></li>
 689//                     <li><%= person.age %></li>
 690//                 <% end %>
 691//                 </ul>
 692//                 ```
 693//             "#,
 694//             // Inserting a comment character inside one code directive
 695//             // does not cause the other code directive to become a comment,
 696//             // because newlines are included in between each injection range.
 697//             r#"
 698//                 here is
 699//                 some
 700//                 ERB code:
 701
 702//                 ```erb
 703//                 <ul>
 704//                 <% people2.each do |person| %>
 705//                     <li><%= «# »person.name %></li>
 706//                     <li><%= person.age %></li>
 707//                 <% end %>
 708//                 </ul>
 709//                 ```
 710//             "#,
 711//         ],
 712//     );
 713
 714//     // Check that the code directive below the ruby comment is
 715//     // not parsed as a comment.
 716//     assert_capture_ranges(
 717//         &syntax_map,
 718//         &buffer,
 719//         &["method"],
 720//         "
 721//             here is
 722//             some
 723//             ERB code:
 724
 725//             ```erb
 726//             <ul>
 727//             <% people2.«each» do |person| %>
 728//                 <li><%= # person.name %></li>
 729//                 <li><%= person.«age» %></li>
 730//             <% end %>
 731//             </ul>
 732//             ```
 733//         ",
 734//     );
 735// }
 736
 737// #[gpui::test]
 738// fn test_empty_combined_injections_inside_injections() {
 739//     let (buffer, syntax_map) = test_edit_sequence(
 740//         "Markdown",
 741//         &[r#"
 742//             ```erb
 743//             hello
 744//             ```
 745
 746//             goodbye
 747//         "#],
 748//     );
 749
 750//     assert_layers_for_range(
 751//         &syntax_map,
 752//         &buffer,
 753//         Point::new(0, 0)..Point::new(5, 0),
 754//         &[
 755//             "...(paragraph)...",
 756//             "(template...",
 757//             "(fragment...",
 758//             // The ruby syntax tree should be empty, since there are
 759//             // no interpolations in the ERB template.
 760//             "(program)",
 761//         ],
 762//     );
 763// }
 764
 765// #[gpui::test(iterations = 50)]
 766// fn test_random_syntax_map_edits_rust_macros(rng: StdRng) {
 767//     let text = r#"
 768//         fn test_something() {
 769//             let vec = vec![5, 1, 3, 8];
 770//             assert_eq!(
 771//                 vec
 772//                     .into_iter()
 773//                     .map(|i| i * 2)
 774//                     .collect::<Vec<usize>>(),
 775//                 vec![
 776//                     5 * 2, 1 * 2, 3 * 2, 8 * 2
 777//                 ],
 778//             );
 779//         }
 780//     "#
 781//     .unindent()
 782//     .repeat(2);
 783
 784//     let registry = Arc::new(LanguageRegistry::test());
 785//     let language = Arc::new(rust_lang());
 786//     registry.add(language.clone());
 787
 788//     test_random_edits(text, registry, language, rng);
 789// }
 790
 791// #[gpui::test(iterations = 50)]
 792// fn test_random_syntax_map_edits_with_erb(rng: StdRng) {
 793//     let text = r#"
 794//         <div id="main">
 795//         <% if one?(:two) %>
 796//             <p class="three" four>
 797//             <%= yield :five %>
 798//             </p>
 799//         <% elsif Six.seven(8) %>
 800//             <p id="three" four>
 801//             <%= yield :five %>
 802//             </p>
 803//         <% else %>
 804//             <span>Ok</span>
 805//         <% end %>
 806//         </div>
 807//     "#
 808//     .unindent()
 809//     .repeat(5);
 810
 811//     let registry = Arc::new(LanguageRegistry::test());
 812//     let language = Arc::new(erb_lang());
 813//     registry.add(language.clone());
 814//     registry.add(Arc::new(ruby_lang()));
 815//     registry.add(Arc::new(html_lang()));
 816
 817//     test_random_edits(text, registry, language, rng);
 818// }
 819
 820// #[gpui::test(iterations = 50)]
 821// fn test_random_syntax_map_edits_with_heex(rng: StdRng) {
 822//     let text = r#"
 823//         defmodule TheModule do
 824//             def the_method(assigns) do
 825//                 ~H"""
 826//                 <%= if @empty do %>
 827//                     <div class="h-4"></div>
 828//                 <% else %>
 829//                     <div class="max-w-2xl w-full animate-pulse">
 830//                     <div class="flex-1 space-y-4">
 831//                         <div class={[@bg_class, "h-4 rounded-lg w-3/4"]}></div>
 832//                         <div class={[@bg_class, "h-4 rounded-lg"]}></div>
 833//                         <div class={[@bg_class, "h-4 rounded-lg w-5/6"]}></div>
 834//                     </div>
 835//                     </div>
 836//                 <% end %>
 837//                 """
 838//             end
 839//         end
 840//     "#
 841//     .unindent()
 842//     .repeat(3);
 843
 844//     let registry = Arc::new(LanguageRegistry::test());
 845//     let language = Arc::new(elixir_lang());
 846//     registry.add(language.clone());
 847//     registry.add(Arc::new(heex_lang()));
 848//     registry.add(Arc::new(html_lang()));
 849
 850//     test_random_edits(text, registry, language, rng);
 851// }
 852
 853// fn test_random_edits(
 854//     text: String,
 855//     registry: Arc<LanguageRegistry>,
 856//     language: Arc<Language>,
 857//     mut rng: StdRng,
 858// ) {
 859//     let operations = env::var("OPERATIONS")
 860//         .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
 861//         .unwrap_or(10);
 862
 863//     let mut buffer = Buffer::new(0, 0, text);
 864
 865//     let mut syntax_map = SyntaxMap::new();
 866//     syntax_map.set_language_registry(registry.clone());
 867//     syntax_map.reparse(language.clone(), &buffer);
 868
 869//     let mut reference_syntax_map = SyntaxMap::new();
 870//     reference_syntax_map.set_language_registry(registry.clone());
 871
 872//     log::info!("initial text:\n{}", buffer.text());
 873
 874//     for _ in 0..operations {
 875//         let prev_buffer = buffer.snapshot();
 876//         let prev_syntax_map = syntax_map.snapshot();
 877
 878//         buffer.randomly_edit(&mut rng, 3);
 879//         log::info!("text:\n{}", buffer.text());
 880
 881//         syntax_map.interpolate(&buffer);
 882//         check_interpolation(&prev_syntax_map, &syntax_map, &prev_buffer, &buffer);
 883
 884//         syntax_map.reparse(language.clone(), &buffer);
 885
 886//         reference_syntax_map.clear();
 887//         reference_syntax_map.reparse(language.clone(), &buffer);
 888//     }
 889
 890//     for i in 0..operations {
 891//         let i = operations - i - 1;
 892//         buffer.undo();
 893//         log::info!("undoing operation {}", i);
 894//         log::info!("text:\n{}", buffer.text());
 895
 896//         syntax_map.interpolate(&buffer);
 897//         syntax_map.reparse(language.clone(), &buffer);
 898
 899//         reference_syntax_map.clear();
 900//         reference_syntax_map.reparse(language.clone(), &buffer);
 901//         assert_eq!(
 902//             syntax_map.layers(&buffer).len(),
 903//             reference_syntax_map.layers(&buffer).len(),
 904//             "wrong number of layers after undoing edit {i}"
 905//         );
 906//     }
 907
 908//     let layers = syntax_map.layers(&buffer);
 909//     let reference_layers = reference_syntax_map.layers(&buffer);
 910//     for (edited_layer, reference_layer) in layers.into_iter().zip(reference_layers.into_iter()) {
 911//         assert_eq!(
 912//             edited_layer.node().to_sexp(),
 913//             reference_layer.node().to_sexp()
 914//         );
 915//         assert_eq!(edited_layer.node().range(), reference_layer.node().range());
 916//     }
 917// }
 918
 919// fn check_interpolation(
 920//     old_syntax_map: &SyntaxSnapshot,
 921//     new_syntax_map: &SyntaxSnapshot,
 922//     old_buffer: &BufferSnapshot,
 923//     new_buffer: &BufferSnapshot,
 924// ) {
 925//     let edits = new_buffer
 926//         .edits_since::<usize>(&old_buffer.version())
 927//         .collect::<Vec<_>>();
 928
 929//     for (old_layer, new_layer) in old_syntax_map
 930//         .layers
 931//         .iter()
 932//         .zip(new_syntax_map.layers.iter())
 933//     {
 934//         assert_eq!(old_layer.range, new_layer.range);
 935//         let Some(old_tree) = old_layer.content.tree() else {
 936//             continue;
 937//         };
 938//         let Some(new_tree) = new_layer.content.tree() else {
 939//             continue;
 940//         };
 941//         let old_start_byte = old_layer.range.start.to_offset(old_buffer);
 942//         let new_start_byte = new_layer.range.start.to_offset(new_buffer);
 943//         let old_start_point = old_layer.range.start.to_point(old_buffer).to_ts_point();
 944//         let new_start_point = new_layer.range.start.to_point(new_buffer).to_ts_point();
 945//         let old_node = old_tree.root_node_with_offset(old_start_byte, old_start_point);
 946//         let new_node = new_tree.root_node_with_offset(new_start_byte, new_start_point);
 947//         check_node_edits(
 948//             old_layer.depth,
 949//             &old_layer.range,
 950//             old_node,
 951//             new_node,
 952//             old_buffer,
 953//             new_buffer,
 954//             &edits,
 955//         );
 956//     }
 957
 958//     fn check_node_edits(
 959//         depth: usize,
 960//         range: &Range<Anchor>,
 961//         old_node: Node,
 962//         new_node: Node,
 963//         old_buffer: &BufferSnapshot,
 964//         new_buffer: &BufferSnapshot,
 965//         edits: &[text::Edit<usize>],
 966//     ) {
 967//         assert_eq!(old_node.kind(), new_node.kind());
 968
 969//         let old_range = old_node.byte_range();
 970//         let new_range = new_node.byte_range();
 971
 972//         let is_edited = edits
 973//             .iter()
 974//             .any(|edit| edit.new.start < new_range.end && edit.new.end > new_range.start);
 975//         if is_edited {
 976//             assert!(
 977//                 new_node.has_changes(),
 978//                 concat!(
 979//                     "failed to mark node as edited.\n",
 980//                     "layer depth: {}, old layer range: {:?}, new layer range: {:?},\n",
 981//                     "node kind: {}, old node range: {:?}, new node range: {:?}",
 982//                 ),
 983//                 depth,
 984//                 range.to_offset(old_buffer),
 985//                 range.to_offset(new_buffer),
 986//                 new_node.kind(),
 987//                 old_range,
 988//                 new_range,
 989//             );
 990//         }
 991
 992//         if !new_node.has_changes() {
 993//             assert_eq!(
 994//                 old_buffer
 995//                     .text_for_range(old_range.clone())
 996//                     .collect::<String>(),
 997//                 new_buffer
 998//                     .text_for_range(new_range.clone())
 999//                     .collect::<String>(),
1000//                 concat!(
1001//                     "mismatched text for node\n",
1002//                     "layer depth: {}, old layer range: {:?}, new layer range: {:?},\n",
1003//                     "node kind: {}, old node range:{:?}, new node range:{:?}",
1004//                 ),
1005//                 depth,
1006//                 range.to_offset(old_buffer),
1007//                 range.to_offset(new_buffer),
1008//                 new_node.kind(),
1009//                 old_range,
1010//                 new_range,
1011//             );
1012//         }
1013
1014//         for i in 0..new_node.child_count() {
1015//             check_node_edits(
1016//                 depth,
1017//                 range,
1018//                 old_node.child(i).unwrap(),
1019//                 new_node.child(i).unwrap(),
1020//                 old_buffer,
1021//                 new_buffer,
1022//                 edits,
1023//             )
1024//         }
1025//     }
1026// }
1027
1028// fn test_edit_sequence(language_name: &str, steps: &[&str]) -> (Buffer, SyntaxMap) {
1029//     let registry = Arc::new(LanguageRegistry::test());
1030//     registry.add(Arc::new(elixir_lang()));
1031//     registry.add(Arc::new(heex_lang()));
1032//     registry.add(Arc::new(rust_lang()));
1033//     registry.add(Arc::new(ruby_lang()));
1034//     registry.add(Arc::new(html_lang()));
1035//     registry.add(Arc::new(erb_lang()));
1036//     registry.add(Arc::new(markdown_lang()));
1037
1038//     let language = registry
1039//         .language_for_name(language_name)
1040//         .now_or_never()
1041//         .unwrap()
1042//         .unwrap();
1043//     let mut buffer = Buffer::new(0, 0, Default::default());
1044
1045//     let mut mutated_syntax_map = SyntaxMap::new();
1046//     mutated_syntax_map.set_language_registry(registry.clone());
1047//     mutated_syntax_map.reparse(language.clone(), &buffer);
1048
1049//     for (i, marked_string) in steps.into_iter().enumerate() {
1050//         let marked_string = marked_string.unindent();
1051//         log::info!("incremental parse {i}: {marked_string:?}");
1052//         buffer.edit_via_marked_text(&marked_string);
1053
1054//         // Reparse the syntax map
1055//         mutated_syntax_map.interpolate(&buffer);
1056//         mutated_syntax_map.reparse(language.clone(), &buffer);
1057
1058//         // Create a second syntax map from scratch
1059//         log::info!("fresh parse {i}: {marked_string:?}");
1060//         let mut reference_syntax_map = SyntaxMap::new();
1061//         reference_syntax_map.set_language_registry(registry.clone());
1062//         reference_syntax_map.reparse(language.clone(), &buffer);
1063
1064//         // Compare the mutated syntax map to the new syntax map
1065//         let mutated_layers = mutated_syntax_map.layers(&buffer);
1066//         let reference_layers = reference_syntax_map.layers(&buffer);
1067//         assert_eq!(
1068//             mutated_layers.len(),
1069//             reference_layers.len(),
1070//             "wrong number of layers at step {i}"
1071//         );
1072//         for (edited_layer, reference_layer) in
1073//             mutated_layers.into_iter().zip(reference_layers.into_iter())
1074//         {
1075//             assert_eq!(
1076//                 edited_layer.node().to_sexp(),
1077//                 reference_layer.node().to_sexp(),
1078//                 "different layer at step {i}"
1079//             );
1080//             assert_eq!(
1081//                 edited_layer.node().range(),
1082//                 reference_layer.node().range(),
1083//                 "different layer at step {i}"
1084//             );
1085//         }
1086//     }
1087
1088//     (buffer, mutated_syntax_map)
1089// }
1090
1091// fn html_lang() -> Language {
1092//     Language::new(
1093//         LanguageConfig {
1094//             name: "HTML".into(),
1095//             path_suffixes: vec!["html".to_string()],
1096//             ..Default::default()
1097//         },
1098//         Some(tree_sitter_html::language()),
1099//     )
1100//     .with_highlights_query(
1101//         r#"
1102//             (tag_name) @tag
1103//             (erroneous_end_tag_name) @tag
1104//             (attribute_name) @property
1105//         "#,
1106//     )
1107//     .unwrap()
1108// }
1109
1110// fn ruby_lang() -> Language {
1111//     Language::new(
1112//         LanguageConfig {
1113//             name: "Ruby".into(),
1114//             path_suffixes: vec!["rb".to_string()],
1115//             ..Default::default()
1116//         },
1117//         Some(tree_sitter_ruby::language()),
1118//     )
1119//     .with_highlights_query(
1120//         r#"
1121//             ["if" "do" "else" "end"] @keyword
1122//             (instance_variable) @ivar
1123//             (call method: (identifier) @method)
1124//         "#,
1125//     )
1126//     .unwrap()
1127// }
1128
1129// fn erb_lang() -> Language {
1130//     Language::new(
1131//         LanguageConfig {
1132//             name: "ERB".into(),
1133//             path_suffixes: vec!["erb".to_string()],
1134//             ..Default::default()
1135//         },
1136//         Some(tree_sitter_embedded_template::language()),
1137//     )
1138//     .with_highlights_query(
1139//         r#"
1140//             ["<%" "%>"] @keyword
1141//         "#,
1142//     )
1143//     .unwrap()
1144//     .with_injection_query(
1145//         r#"
1146//             (
1147//                 (code) @content
1148//                 (#set! "language" "ruby")
1149//                 (#set! "combined")
1150//             )
1151
1152//             (
1153//                 (content) @content
1154//                 (#set! "language" "html")
1155//                 (#set! "combined")
1156//             )
1157//         "#,
1158//     )
1159//     .unwrap()
1160// }
1161
1162// fn rust_lang() -> Language {
1163//     Language::new(
1164//         LanguageConfig {
1165//             name: "Rust".into(),
1166//             path_suffixes: vec!["rs".to_string()],
1167//             ..Default::default()
1168//         },
1169//         Some(tree_sitter_rust::language()),
1170//     )
1171//     .with_highlights_query(
1172//         r#"
1173//             (field_identifier) @field
1174//             (struct_expression) @struct
1175//         "#,
1176//     )
1177//     .unwrap()
1178//     .with_injection_query(
1179//         r#"
1180//             (macro_invocation
1181//                 (token_tree) @content
1182//                 (#set! "language" "rust"))
1183//         "#,
1184//     )
1185//     .unwrap()
1186// }
1187
1188// fn markdown_lang() -> Language {
1189//     Language::new(
1190//         LanguageConfig {
1191//             name: "Markdown".into(),
1192//             path_suffixes: vec!["md".into()],
1193//             ..Default::default()
1194//         },
1195//         Some(tree_sitter_markdown::language()),
1196//     )
1197//     .with_injection_query(
1198//         r#"
1199//             (fenced_code_block
1200//                 (info_string
1201//                     (language) @language)
1202//                 (code_fence_content) @content)
1203//         "#,
1204//     )
1205//     .unwrap()
1206// }
1207
1208// fn elixir_lang() -> Language {
1209//     Language::new(
1210//         LanguageConfig {
1211//             name: "Elixir".into(),
1212//             path_suffixes: vec!["ex".into()],
1213//             ..Default::default()
1214//         },
1215//         Some(tree_sitter_elixir::language()),
1216//     )
1217//     .with_highlights_query(
1218//         r#"
1219
1220//         "#,
1221//     )
1222//     .unwrap()
1223// }
1224
1225// fn heex_lang() -> Language {
1226//     Language::new(
1227//         LanguageConfig {
1228//             name: "HEEx".into(),
1229//             path_suffixes: vec!["heex".into()],
1230//             ..Default::default()
1231//         },
1232//         Some(tree_sitter_heex::language()),
1233//     )
1234//     .with_injection_query(
1235//         r#"
1236//         (
1237//           (directive
1238//             [
1239//               (partial_expression_value)
1240//               (expression_value)
1241//               (ending_expression_value)
1242//             ] @content)
1243//           (#set! language "elixir")
1244//           (#set! combined)
1245//         )
1246
1247//         ((expression (expression_value) @content)
1248//          (#set! language "elixir"))
1249//         "#,
1250//     )
1251//     .unwrap()
1252// }
1253
1254// fn range_for_text(buffer: &Buffer, text: &str) -> Range<usize> {
1255//     let start = buffer.as_rope().to_string().find(text).unwrap();
1256//     start..start + text.len()
1257// }
1258
1259// #[track_caller]
1260// fn assert_layers_for_range(
1261//     syntax_map: &SyntaxMap,
1262//     buffer: &BufferSnapshot,
1263//     range: Range<Point>,
1264//     expected_layers: &[&str],
1265// ) {
1266//     let layers = syntax_map
1267//         .layers_for_range(range, &buffer)
1268//         .collect::<Vec<_>>();
1269//     assert_eq!(
1270//         layers.len(),
1271//         expected_layers.len(),
1272//         "wrong number of layers"
1273//     );
1274//     for (i, (layer, expected_s_exp)) in layers.iter().zip(expected_layers.iter()).enumerate() {
1275//         let actual_s_exp = layer.node().to_sexp();
1276//         assert!(
1277//             string_contains_sequence(
1278//                 &actual_s_exp,
1279//                 &expected_s_exp.split("...").collect::<Vec<_>>()
1280//             ),
1281//             "layer {i}:\n\nexpected: {expected_s_exp}\nactual:   {actual_s_exp}",
1282//         );
1283//     }
1284// }
1285
1286// fn assert_capture_ranges(
1287//     syntax_map: &SyntaxMap,
1288//     buffer: &BufferSnapshot,
1289//     highlight_query_capture_names: &[&str],
1290//     marked_string: &str,
1291// ) {
1292//     let mut actual_ranges = Vec::<Range<usize>>::new();
1293//     let captures = syntax_map.captures(0..buffer.len(), buffer, |grammar| {
1294//         grammar.highlights_query.as_ref()
1295//     });
1296//     let queries = captures
1297//         .grammars()
1298//         .iter()
1299//         .map(|grammar| grammar.highlights_query.as_ref().unwrap())
1300//         .collect::<Vec<_>>();
1301//     for capture in captures {
1302//         let name = &queries[capture.grammar_index].capture_names()[capture.index as usize];
1303//         if highlight_query_capture_names.contains(&name.as_str()) {
1304//             actual_ranges.push(capture.node.byte_range());
1305//         }
1306//     }
1307
1308//     let (text, expected_ranges) = marked_text_ranges(&marked_string.unindent(), false);
1309//     assert_eq!(text, buffer.text());
1310//     assert_eq!(actual_ranges, expected_ranges);
1311// }
1312
1313// pub fn string_contains_sequence(text: &str, parts: &[&str]) -> bool {
1314//     let mut last_part_end = 0;
1315//     for part in parts {
1316//         if let Some(start_ix) = text[last_part_end..].find(part) {
1317//             last_part_end = start_ix + part.len();
1318//         } else {
1319//             return false;
1320//         }
1321//     }
1322//     true
1323// }