@@ -169,7 +169,10 @@ impl Document {
169169 } ; 
170170
171171 Affected  { 
172-  affected_range :  TextRange :: new ( start,  end. min ( content_size) ) , 
172+  affected_range :  { 
173+  let  end = end. min ( content_size) ; 
174+  TextRange :: new ( start. min ( end) ,  end) 
175+  } , 
173176 affected_indices, 
174177 prev_index, 
175178 next_index, 
@@ -194,8 +197,6 @@ impl Document {
194197
195198 /// Applies a single change to the document and returns the affected statements 
196199fn  apply_change ( & mut  self ,  change :  & ChangeParams )  -> Vec < StatementChange >  { 
197-  tracing:: info!( "applying change: {:?}" ,  change) ; 
198- 
199200 // if range is none, we have a full change 
200201 if  change. range . is_none ( )  { 
201202 return  self . apply_full_change ( & change. text ) ; 
@@ -273,7 +274,7 @@ impl Document {
273274 new_stmt_text :  changed_content[ new_ranges[ 0 ] ] . to_string ( ) , 
274275 // change must be relative to the statement 
275276 change_text :  change. text . clone ( ) , 
276-  change_range, 
277+  change_range :  change_range . sub ( old_range . start ( ) ) , 
277278 } ) ) ; 
278279
279280 self . content  = new_content; 
@@ -526,7 +527,7 @@ mod tests {
526527 assert_eq ! ( changed. old_stmt_text,  "select ;" ) ; 
527528 assert_eq ! ( changed. new_stmt_text,  "select" ) ; 
528529 assert_eq ! ( changed. change_text,  "" ) ; 
529-  assert_eq ! ( changed. change_range,  TextRange :: new( 32 . into( ) ,  33 . into( ) ) ) ; 
530+  assert_eq ! ( changed. change_range,  TextRange :: new( 7 . into( ) ,  8 . into( ) ) ) ; 
530531 } 
531532 _ => panic ! ( "expected modified statement" ) , 
532533 } 
@@ -863,4 +864,76 @@ mod tests {
863864
864865 assert_document_integrity ( & doc) ; 
865866 } 
867+ 
868+  #[ test]  
869+  fn  remove_outside_of_content ( )  { 
870+  let  path = PgLspPath :: new ( "test.sql" ) ; 
871+  let  input = "select id from contacts;\n \n select * from contacts;" ; 
872+ 
873+  let  mut  d = Document :: new ( path. clone ( ) ,  input. to_string ( ) ,  1 ) ; 
874+ 
875+  assert_eq ! ( d. positions. len( ) ,  2 ) ; 
876+ 
877+  let  change1 = ChangeFileParams  { 
878+  path :  path. clone ( ) , 
879+  version :  2 , 
880+  changes :  vec ! [ ChangeParams  { 
881+  text:  "\n " . to_string( ) , 
882+  range:  Some ( TextRange :: new( 49 . into( ) ,  49 . into( ) ) ) , 
883+  } ] , 
884+  } ; 
885+ 
886+  d. apply_file_change ( & change1) ; 
887+ 
888+  assert_eq ! ( 
889+  d. content, 
890+  "select id from contacts;\n \n select * from contacts;\n " 
891+  ) ; 
892+ 
893+  let  change2 = ChangeFileParams  { 
894+  path :  path. clone ( ) , 
895+  version :  3 , 
896+  changes :  vec ! [ ChangeParams  { 
897+  text:  "\n " . to_string( ) , 
898+  range:  Some ( TextRange :: new( 50 . into( ) ,  50 . into( ) ) ) , 
899+  } ] , 
900+  } ; 
901+ 
902+  d. apply_file_change ( & change2) ; 
903+ 
904+  assert_eq ! ( 
905+  d. content, 
906+  "select id from contacts;\n \n select * from contacts;\n \n " 
907+  ) ; 
908+ 
909+  let  change5 = ChangeFileParams  { 
910+  path :  path. clone ( ) , 
911+  version :  6 , 
912+  changes :  vec ! [ ChangeParams  { 
913+  text:  "" . to_string( ) , 
914+  range:  Some ( TextRange :: new( 51 . into( ) ,  52 . into( ) ) ) , 
915+  } ] , 
916+  } ; 
917+ 
918+  let  changes = d. apply_file_change ( & change5) ; 
919+ 
920+  assert ! ( matches!( 
921+  changes[ 0 ] , 
922+  StatementChange :: Deleted ( Statement  {  .. } ) 
923+  ) ) ; 
924+ 
925+  assert ! ( matches!( 
926+  changes[ 1 ] , 
927+  StatementChange :: Added ( AddedStatement  {  .. } ) 
928+  ) ) ; 
929+ 
930+  assert_eq ! ( changes. len( ) ,  2 ) ; 
931+ 
932+  assert_eq ! ( 
933+  d. content, 
934+  "select id from contacts;\n \n select * from contacts;\n \n " 
935+  ) ; 
936+ 
937+  assert_document_integrity ( & d) ; 
938+  } 
866939} 
0 commit comments