@@ -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
196199 fn 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