on master help sign in
Significantly improve performance of `:reload` (#4457)
da355a3Pascal Kuthe
Cargo.lock+182−77
@@ -27,9 +27,9 @@ dependencies = [
27
27
28[[package]]
28[[package]]
29name = "aho-corasick"
29name = "aho-corasick"
30−version = "0.7.18"
30+version = "0.7.20"
31source = "registry+https://github.com/rust-lang/crates.io-index"
31source = "registry+https://github.com/rust-lang/crates.io-index"
32−checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
32+checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
33dependencies = [
33dependencies = [
34 "memchr",
34 "memchr",
35]
35]
@@ -80,9 +80,9 @@ dependencies = [
80
80
81[[package]]
81[[package]]
82name = "bumpalo"
82name = "bumpalo"
83−version = "3.11.0"
83+version = "3.11.1"
84source = "registry+https://github.com/rust-lang/crates.io-index"
84source = "registry+https://github.com/rust-lang/crates.io-index"
85−checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
85+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
86
86
87[[package]]
87[[package]]
88name = "bytecount"
88name = "bytecount"
@@ -92,9 +92,9 @@ checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
92
92
93[[package]]
93[[package]]
94name = "bytes"
94name = "bytes"
95−version = "1.2.1"
95+version = "1.3.0"
96source = "registry+https://github.com/rust-lang/crates.io-index"
96source = "registry+https://github.com/rust-lang/crates.io-index"
97−checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
97+checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
98
98
99[[package]]
99[[package]]
100name = "cassowary"
100name = "cassowary"
@@ -148,6 +148,16 @@ dependencies = [
148 "winapi",
148 "winapi",
149]
149]
150
150
151+[[package]]
152+name = "codespan-reporting"
153+version = "0.11.1"
154+source = "registry+https://github.com/rust-lang/crates.io-index"
155+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
156+dependencies = [
157+ "termcolor",
158+ "unicode-width",
159+]
160+
151[[package]]
161[[package]]
152name = "content_inspector"
162name = "content_inspector"
153version = "0.2.4"
163version = "0.2.4"
@@ -165,12 +175,11 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
165
175
166[[package]]
176[[package]]
167name = "crossbeam-utils"
177name = "crossbeam-utils"
168−version = "0.8.11"
178+version = "0.8.14"
169source = "registry+https://github.com/rust-lang/crates.io-index"
179source = "registry+https://github.com/rust-lang/crates.io-index"
170−checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
180+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
171dependencies = [
181dependencies = [
172 "cfg-if",
182 "cfg-if",
173− "once_cell",
174]
183]
175
184
176[[package]]
185[[package]]
@@ -199,6 +208,50 @@ dependencies = [
199 "winapi",
208 "winapi",
200]
209]
201
210
211+[[package]]
212+name = "cxx"
213+version = "1.0.82"
214+source = "registry+https://github.com/rust-lang/crates.io-index"
215+checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453"
216+dependencies = [
217+ "cc",
218+ "cxxbridge-flags",
219+ "cxxbridge-macro",
220+ "link-cplusplus",
221+]
222+
223+[[package]]
224+name = "cxx-build"
225+version = "1.0.82"
226+source = "registry+https://github.com/rust-lang/crates.io-index"
227+checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0"
228+dependencies = [
229+ "cc",
230+ "codespan-reporting",
231+ "once_cell",
232+ "proc-macro2",
233+ "quote",
234+ "scratch",
235+ "syn",
236+]
237+
238+[[package]]
239+name = "cxxbridge-flags"
240+version = "1.0.82"
241+source = "registry+https://github.com/rust-lang/crates.io-index"
242+checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71"
243+
244+[[package]]
245+name = "cxxbridge-macro"
246+version = "1.0.82"
247+source = "registry+https://github.com/rust-lang/crates.io-index"
248+checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470"
249+dependencies = [
250+ "proc-macro2",
251+ "quote",
252+ "syn",
253+]
254+
202[[package]]
255[[package]]
203name = "dirs-next"
256name = "dirs-next"
204version = "2.0.0"
257version = "2.0.0"
@@ -345,9 +398,9 @@ dependencies = [
345
398
346[[package]]
399[[package]]
347name = "getrandom"
400name = "getrandom"
348−version = "0.2.7"
401+version = "0.2.8"
349source = "registry+https://github.com/rust-lang/crates.io-index"
402source = "registry+https://github.com/rust-lang/crates.io-index"
350−checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
403+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
351dependencies = [
404dependencies = [
352 "cfg-if",
405 "cfg-if",
353 "libc",
406 "libc",
@@ -436,6 +489,7 @@ dependencies = [
436 "etcetera",
489 "etcetera",
437 "hashbrown 0.13.1",
490 "hashbrown 0.13.1",
438 "helix-loader",
491 "helix-loader",
492+ "imara-diff",
439 "log",
493 "log",
440 "once_cell",
494 "once_cell",
441 "quickcheck",
495 "quickcheck",
@@ -443,7 +497,6 @@ dependencies = [
443 "ropey",
497 "ropey",
444 "serde",
498 "serde",
445 "serde_json",
499 "serde_json",
446− "similar",
447 "slotmap",
500 "slotmap",
448 "smallvec",
501 "smallvec",
449 "smartstring",
502 "smartstring",
@@ -594,18 +647,28 @@ dependencies = [
594
647
595[[package]]
648[[package]]
596name = "iana-time-zone"
649name = "iana-time-zone"
597−version = "0.1.47"
650+version = "0.1.53"
598source = "registry+https://github.com/rust-lang/crates.io-index"
651source = "registry+https://github.com/rust-lang/crates.io-index"
599−checksum = "4c495f162af0bf17656d0014a0eded5f3cd2f365fdd204548c2869db89359dc7"
652+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
600dependencies = [
653dependencies = [
601 "android_system_properties",
654 "android_system_properties",
602 "core-foundation-sys",
655 "core-foundation-sys",
656+ "iana-time-zone-haiku",
603 "js-sys",
657 "js-sys",
604− "once_cell",
605 "wasm-bindgen",
658 "wasm-bindgen",
606 "winapi",
659 "winapi",
607]
660]
608
661
662+[[package]]
663+name = "iana-time-zone-haiku"
664+version = "0.1.1"
665+source = "registry+https://github.com/rust-lang/crates.io-index"
666+checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
667+dependencies = [
668+ "cxx",
669+ "cxx-build",
670+]
671+
609[[package]]
672[[package]]
610name = "idna"
673name = "idna"
611version = "0.3.0"
674version = "0.3.0"
@@ -634,6 +697,16 @@ dependencies = [
634 "winapi-util",
697 "winapi-util",
635]
698]
636
699
700+[[package]]
701+name = "imara-diff"
702+version = "0.1.5"
703+source = "registry+https://github.com/rust-lang/crates.io-index"
704+checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8"
705+dependencies = [
706+ "ahash 0.8.2",
707+ "hashbrown 0.12.3",
708+]
709+
637[[package]]
710[[package]]
638name = "indoc"
711name = "indoc"
639version = "1.0.7"
712version = "1.0.7"
@@ -651,15 +724,15 @@ dependencies = [
651
724
652[[package]]
725[[package]]
653name = "itoa"
726name = "itoa"
654−version = "1.0.3"
727+version = "1.0.4"
655source = "registry+https://github.com/rust-lang/crates.io-index"
728source = "registry+https://github.com/rust-lang/crates.io-index"
656−checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
729+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
657
730
658[[package]]
731[[package]]
659name = "js-sys"
732name = "js-sys"
660−version = "0.3.59"
733+version = "0.3.60"
661source = "registry+https://github.com/rust-lang/crates.io-index"
734source = "registry+https://github.com/rust-lang/crates.io-index"
662−checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
735+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
663dependencies = [
736dependencies = [
664 "wasm-bindgen",
737 "wasm-bindgen",
665]
738]
@@ -672,9 +745,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
672
745
673[[package]]
746[[package]]
674name = "libc"
747name = "libc"
675−version = "0.2.132"
748+version = "0.2.137"
676source = "registry+https://github.com/rust-lang/crates.io-index"
749source = "registry+https://github.com/rust-lang/crates.io-index"
677−checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
750+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
678
751
679[[package]]
752[[package]]
680name = "libloading"
753name = "libloading"
@@ -686,11 +759,20 @@ dependencies = [
686 "winapi",
759 "winapi",
687]
760]
688
761
762+[[package]]
763+name = "link-cplusplus"
764+version = "1.0.7"
765+source = "registry+https://github.com/rust-lang/crates.io-index"
766+checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
767+dependencies = [
768+ "cc",
769+]
770+
689[[package]]
771[[package]]
690name = "lock_api"
772name = "lock_api"
691−version = "0.4.8"
773+version = "0.4.9"
692source = "registry+https://github.com/rust-lang/crates.io-index"
774source = "registry+https://github.com/rust-lang/crates.io-index"
693−checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390"
775+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
694dependencies = [
776dependencies = [
695 "autocfg",
777 "autocfg",
696 "scopeguard",
778 "scopeguard",
@@ -726,18 +808,18 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
726
808
727[[package]]
809[[package]]
728name = "memmap2"
810name = "memmap2"
729−version = "0.5.7"
811+version = "0.5.8"
730source = "registry+https://github.com/rust-lang/crates.io-index"
812source = "registry+https://github.com/rust-lang/crates.io-index"
731−checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
813+checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc"
732dependencies = [
814dependencies = [
733 "libc",
815 "libc",
734]
816]
735
817
736[[package]]
818[[package]]
737name = "mio"
819name = "mio"
738−version = "0.8.4"
820+version = "0.8.5"
739source = "registry+https://github.com/rust-lang/crates.io-index"
821source = "registry+https://github.com/rust-lang/crates.io-index"
740−checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
822+checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
741dependencies = [
823dependencies = [
742 "libc",
824 "libc",
743 "log",
825 "log",
@@ -766,9 +848,9 @@ dependencies = [
766
848
767[[package]]
849[[package]]
768name = "num_cpus"
850name = "num_cpus"
769−version = "1.13.1"
851+version = "1.14.0"
770source = "registry+https://github.com/rust-lang/crates.io-index"
852source = "registry+https://github.com/rust-lang/crates.io-index"
771−checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
853+checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
772dependencies = [
854dependencies = [
773 "hermit-abi",
855 "hermit-abi",
774 "libc",
856 "libc",
@@ -792,9 +874,9 @@ dependencies = [
792
874
793[[package]]
875[[package]]
794name = "parking_lot_core"
876name = "parking_lot_core"
795−version = "0.9.3"
877+version = "0.9.4"
796source = "registry+https://github.com/rust-lang/crates.io-index"
878source = "registry+https://github.com/rust-lang/crates.io-index"
797−checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
879+checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
798dependencies = [
880dependencies = [
799 "cfg-if",
881 "cfg-if",
800 "libc",
882 "libc",
@@ -823,9 +905,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
823
905
824[[package]]
906[[package]]
825name = "proc-macro2"
907name = "proc-macro2"
826−version = "1.0.43"
908+version = "1.0.47"
827source = "registry+https://github.com/rust-lang/crates.io-index"
909source = "registry+https://github.com/rust-lang/crates.io-index"
828−checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
910+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
829dependencies = [
911dependencies = [
830 "unicode-ident",
912 "unicode-ident",
831]
913]
@@ -870,9 +952,9 @@ dependencies = [
870
952
871[[package]]
953[[package]]
872name = "rand_core"
954name = "rand_core"
873−version = "0.6.3"
955+version = "0.6.4"
874source = "registry+https://github.com/rust-lang/crates.io-index"
956source = "registry+https://github.com/rust-lang/crates.io-index"
875−checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
957+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
876dependencies = [
958dependencies = [
877 "getrandom",
959 "getrandom",
878]
960]
@@ -916,9 +998,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
916
998
917[[package]]
999[[package]]
918name = "regex-syntax"
1000name = "regex-syntax"
919−version = "0.6.27"
1001+version = "0.6.28"
920source = "registry+https://github.com/rust-lang/crates.io-index"
1002source = "registry+https://github.com/rust-lang/crates.io-index"
921−checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
1003+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
922
1004
923[[package]]
1005[[package]]
924name = "remove_dir_all"
1006name = "remove_dir_all"
@@ -960,20 +1042,26 @@ version = "1.1.0"
960source = "registry+https://github.com/rust-lang/crates.io-index"
1042source = "registry+https://github.com/rust-lang/crates.io-index"
961checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1043checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
962
1044
1045+[[package]]
1046+name = "scratch"
1047+version = "1.0.2"
1048+source = "registry+https://github.com/rust-lang/crates.io-index"
1049+checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
1050+
963[[package]]
1051[[package]]
964name = "serde"
1052name = "serde"
965−version = "1.0.147"
1053+version = "1.0.148"
966source = "registry+https://github.com/rust-lang/crates.io-index"
1054source = "registry+https://github.com/rust-lang/crates.io-index"
967−checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
1055+checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc"
968dependencies = [
1056dependencies = [
969 "serde_derive",
1057 "serde_derive",
970]
1058]
971
1059
972[[package]]
1060[[package]]
973name = "serde_derive"
1061name = "serde_derive"
974−version = "1.0.147"
1062+version = "1.0.148"
975source = "registry+https://github.com/rust-lang/crates.io-index"
1063source = "registry+https://github.com/rust-lang/crates.io-index"
976−checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
1064+checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c"
977dependencies = [
1065dependencies = [
978 "proc-macro2",
1066 "proc-macro2",
979 "quote",
1067 "quote",
@@ -982,9 +1070,9 @@ dependencies = [
982
1070
983[[package]]
1071[[package]]
984name = "serde_json"
1072name = "serde_json"
985−version = "1.0.88"
1073+version = "1.0.89"
986source = "registry+https://github.com/rust-lang/crates.io-index"
1074source = "registry+https://github.com/rust-lang/crates.io-index"
987−checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7"
1075+checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
988dependencies = [
1076dependencies = [
989 "itoa",
1077 "itoa",
990 "ryu",
1078 "ryu",
@@ -1044,12 +1132,6 @@ dependencies = [
1044 "tokio",
1132 "tokio",
1045]
1133]
1046
1134
1047−[[package]]
1048−name = "similar"
1049−version = "2.2.1"
1050−source = "registry+https://github.com/rust-lang/crates.io-index"
1051−checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
1052−
1053[[package]]
1135[[package]]
1054name = "slab"
1136name = "slab"
1055version = "0.4.7"
1137version = "0.4.7"
@@ -1121,9 +1203,9 @@ checksum = "9d9199fa80c817e074620be84374a520062ebac833f358d74b37060ce4a0f2c0"
1121
1203
1122[[package]]
1204[[package]]
1123name = "syn"
1205name = "syn"
1124−version = "1.0.99"
1206+version = "1.0.104"
1125source = "registry+https://github.com/rust-lang/crates.io-index"
1207source = "registry+https://github.com/rust-lang/crates.io-index"
1126−checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
1208+checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce"
1127dependencies = [
1209dependencies = [
1128 "proc-macro2",
1210 "proc-macro2",
1129 "quote",
1211 "quote",
@@ -1144,6 +1226,15 @@ dependencies = [
1144 "winapi",
1226 "winapi",
1145]
1227]
1146
1228
1229+[[package]]
1230+name = "termcolor"
1231+version = "1.1.3"
1232+source = "registry+https://github.com/rust-lang/crates.io-index"
1233+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
1234+dependencies = [
1235+ "winapi-util",
1236+]
1237+
1147[[package]]
1238[[package]]
1148name = "termini"
1239name = "termini"
1149version = "0.1.4"
1240version = "0.1.4"
@@ -1301,9 +1392,9 @@ checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7"
1301
1392
1302[[package]]
1393[[package]]
1303name = "unicode-ident"
1394name = "unicode-ident"
1304−version = "1.0.3"
1395+version = "1.0.5"
1305source = "registry+https://github.com/rust-lang/crates.io-index"
1396source = "registry+https://github.com/rust-lang/crates.io-index"
1306−checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
1397+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
1307
1398
1308[[package]]
1399[[package]]
1309name = "unicode-linebreak"
1400name = "unicode-linebreak"
@@ -1317,9 +1408,9 @@ dependencies = [
1317
1408
1318[[package]]
1409[[package]]
1319name = "unicode-normalization"
1410name = "unicode-normalization"
1320−version = "0.1.21"
1411+version = "0.1.22"
1321source = "registry+https://github.com/rust-lang/crates.io-index"
1412source = "registry+https://github.com/rust-lang/crates.io-index"
1322−checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6"
1413+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
1323dependencies = [
1414dependencies = [
1324 "tinyvec",
1415 "tinyvec",
1325]
1416]
@@ -1373,9 +1464,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
1373
1464
1374[[package]]
1465[[package]]
1375name = "wasm-bindgen"
1466name = "wasm-bindgen"
1376−version = "0.2.82"
1467+version = "0.2.83"
1377source = "registry+https://github.com/rust-lang/crates.io-index"
1468source = "registry+https://github.com/rust-lang/crates.io-index"
1378−checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
1469+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
1379dependencies = [
1470dependencies = [
1380 "cfg-if",
1471 "cfg-if",
1381 "wasm-bindgen-macro",
1472 "wasm-bindgen-macro",
@@ -1383,9 +1474,9 @@ dependencies = [
1383
1474
1384[[package]]
1475[[package]]
1385name = "wasm-bindgen-backend"
1476name = "wasm-bindgen-backend"
1386−version = "0.2.82"
1477+version = "0.2.83"
1387source = "registry+https://github.com/rust-lang/crates.io-index"
1478source = "registry+https://github.com/rust-lang/crates.io-index"
1388−checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
1479+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
1389dependencies = [
1480dependencies = [
1390 "bumpalo",
1481 "bumpalo",
1391 "log",
1482 "log",
@@ -1398,9 +1489,9 @@ dependencies = [
1398
1489
1399[[package]]
1490[[package]]
1400name = "wasm-bindgen-macro"
1491name = "wasm-bindgen-macro"
1401−version = "0.2.82"
1492+version = "0.2.83"
1402source = "registry+https://github.com/rust-lang/crates.io-index"
1493source = "registry+https://github.com/rust-lang/crates.io-index"
1403−checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
1494+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
1404dependencies = [
1495dependencies = [
1405 "quote",
1496 "quote",
1406 "wasm-bindgen-macro-support",
1497 "wasm-bindgen-macro-support",
@@ -1408,9 +1499,9 @@ dependencies = [
1408
1499
1409[[package]]
1500[[package]]
1410name = "wasm-bindgen-macro-support"
1501name = "wasm-bindgen-macro-support"
1411−version = "0.2.82"
1502+version = "0.2.83"
1412source = "registry+https://github.com/rust-lang/crates.io-index"
1503source = "registry+https://github.com/rust-lang/crates.io-index"
1413−checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
1504+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
1414dependencies = [
1505dependencies = [
1415 "proc-macro2",
1506 "proc-macro2",
1416 "quote",
1507 "quote",
@@ -1421,9 +1512,9 @@ dependencies = [
1421
1512
1422[[package]]
1513[[package]]
1423name = "wasm-bindgen-shared"
1514name = "wasm-bindgen-shared"
1424−version = "0.2.82"
1515+version = "0.2.83"
1425source = "registry+https://github.com/rust-lang/crates.io-index"
1516source = "registry+https://github.com/rust-lang/crates.io-index"
1426−checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
1517+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
1427
1518
1428[[package]]
1519[[package]]
1429name = "which"
1520name = "which"
@@ -1469,46 +1560,60 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1469
1560
1470[[package]]
1561[[package]]
1471name = "windows-sys"
1562name = "windows-sys"
1472−version = "0.36.1"
1563+version = "0.42.0"
1473source = "registry+https://github.com/rust-lang/crates.io-index"
1564source = "registry+https://github.com/rust-lang/crates.io-index"
1474−checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
1565+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
1475dependencies = [
1566dependencies = [
1567+ "windows_aarch64_gnullvm",
1476 "windows_aarch64_msvc",
1568 "windows_aarch64_msvc",
1477 "windows_i686_gnu",
1569 "windows_i686_gnu",
1478 "windows_i686_msvc",
1570 "windows_i686_msvc",
1479 "windows_x86_64_gnu",
1571 "windows_x86_64_gnu",
1572+ "windows_x86_64_gnullvm",
1480 "windows_x86_64_msvc",
1573 "windows_x86_64_msvc",
1481]
1574]
1482
1575
1576+[[package]]
1577+name = "windows_aarch64_gnullvm"
1578+version = "0.42.0"
1579+source = "registry+https://github.com/rust-lang/crates.io-index"
1580+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
1581+
1483[[package]]
1582[[package]]
1484name = "windows_aarch64_msvc"
1583name = "windows_aarch64_msvc"
1485−version = "0.36.1"
1584+version = "0.42.0"
1486source = "registry+https://github.com/rust-lang/crates.io-index"
1585source = "registry+https://github.com/rust-lang/crates.io-index"
1487−checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
1586+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
1488
1587
1489[[package]]
1588[[package]]
1490name = "windows_i686_gnu"
1589name = "windows_i686_gnu"
1491−version = "0.36.1"
1590+version = "0.42.0"
1492source = "registry+https://github.com/rust-lang/crates.io-index"
1591source = "registry+https://github.com/rust-lang/crates.io-index"
1493−checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
1592+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
1494
1593
1495[[package]]
1594[[package]]
1496name = "windows_i686_msvc"
1595name = "windows_i686_msvc"
1497−version = "0.36.1"
1596+version = "0.42.0"
1498source = "registry+https://github.com/rust-lang/crates.io-index"
1597source = "registry+https://github.com/rust-lang/crates.io-index"
1499−checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
1598+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
1500
1599
1501[[package]]
1600[[package]]
1502name = "windows_x86_64_gnu"
1601name = "windows_x86_64_gnu"
1503−version = "0.36.1"
1602+version = "0.42.0"
1603+source = "registry+https://github.com/rust-lang/crates.io-index"
1604+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
1605+
1606+[[package]]
1607+name = "windows_x86_64_gnullvm"
1608+version = "0.42.0"
1504source = "registry+https://github.com/rust-lang/crates.io-index"
1609source = "registry+https://github.com/rust-lang/crates.io-index"
1505−checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
1610+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
1506
1611
1507[[package]]
1612[[package]]
1508name = "windows_x86_64_msvc"
1613name = "windows_x86_64_msvc"
1509−version = "0.36.1"
1614+version = "0.42.0"
1510source = "registry+https://github.com/rust-lang/crates.io-index"
1615source = "registry+https://github.com/rust-lang/crates.io-index"
1511−checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
1616+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
1512
1617
1513[[package]]
1618[[package]]
1514name = "xtask"
1619name = "xtask"
helix-core/Cargo.toml+1−1
@@ -38,7 +38,7 @@ serde = { version = "1.0", features = ["derive"] }
38serde_json = "1.0"
38serde_json = "1.0"
39toml = "0.5"
39toml = "0.5"
40
40
41−similar = "2.2"
41+imara-diff = "0.1.0"
42
42
43encoding_rs = "0.8"
43encoding_rs = "0.8"
44
44
helix-core/src/diff.rs+203−45
@@ -1,58 +1,195 @@
1−use crate::{Rope, Transaction};
1+use std::ops::Range;
2+use std::time::Instant;
2
3
3−/// Compares `old` and `new` to generate a [`Transaction`] describing
4+use imara_diff::intern::InternedInput;
4−/// the steps required to get from `old` to `new`.
5+use imara_diff::Algorithm;
5−pub fn compare_ropes(old: &Rope, new: &Rope) -> Transaction {
6+use ropey::RopeSlice;
6− // `similar` only works on contiguous data, so a `Rope` has
7+
7− // to be temporarily converted into a `String`.
8+use crate::{ChangeSet, Rope, Tendril, Transaction};
8− let old_converted = old.to_string();
9+
9− let new_converted = new.to_string();
10+/// A `imara_diff::Sink` that builds a `ChangeSet` for a character diff of a hunk
10−
11+struct CharChangeSetBuilder<'a> {
11− // A timeout is set so after 1 seconds, the algorithm will start
12+ res: &'a mut ChangeSet,
12− // approximating. This is especially important for big `Rope`s or
13+ hunk: &'a InternedInput<char>,
13− // `Rope`s that are extremely dissimilar to each other.
14+ pos: u32,
14− let mut config = similar::TextDiff::configure();
15+}
15− config.timeout(std::time::Duration::from_secs(1));
16+
16−
17+impl imara_diff::Sink for CharChangeSetBuilder<'_> {
17− let diff = config.diff_chars(&old_converted, &new_converted);
18+ type Out = ();
18−
19+ fn process_change(&mut self, before: Range<u32>, after: Range<u32>) {
19− // The current position of the change needs to be tracked to
20+ self.res.retain((before.start - self.pos) as usize);
20− // construct the `Change`s.
21+ self.res.delete(before.len());
21− let mut pos = 0;
22+ self.pos = before.end;
22− Transaction::change(
23+
23− old,
24+ let res = self.hunk.after[after.start as usize..after.end as usize]
24− diff.ops()
25+ .iter()
26+ .map(|&token| self.hunk.interner[token])
27+ .collect();
28+
29+ self.res.insert(res);
30+ }
31+
32+ fn finish(self) -> Self::Out {
33+ self.res.retain(self.hunk.before.len() - self.pos as usize);
34+ }
35+}
36+
37+struct LineChangeSetBuilder<'a> {
38+ res: ChangeSet,
39+ after: RopeSlice<'a>,
40+ file: &'a InternedInput<RopeSlice<'a>>,
41+ current_hunk: InternedInput<char>,
42+ pos: u32,
43+}
44+
45+impl imara_diff::Sink for LineChangeSetBuilder<'_> {
46+ type Out = ChangeSet;
47+
48+ fn process_change(&mut self, before: Range<u32>, after: Range<u32>) {
49+ let len = self.file.before[self.pos as usize..before.start as usize]
25 .iter()
50 .iter()
26− .map(|op| op.as_tag_tuple())
51+ .map(|&it| self.file.interner[it].len_chars())
27− .filter_map(|(tag, old_range, new_range)| {
52+ .sum();
28− // `old_pos..pos` is equivalent to `start..end` for where
53+ self.res.retain(len);
29− // the change should be applied.
54+ self.pos = before.end;
30− let old_pos = pos;
55+
31− pos += old_range.end - old_range.start;
56+ // do not perform diffs on large hunks
32−
57+ let len_before = before.end - before.start;
33− match tag {
58+ let len_after = after.end - after.start;
34− // Semantically, inserts and replacements are the same thing.
59+
35− similar::DiffTag::Insert | similar::DiffTag::Replace => {
60+ // Pure insertions/removals do not require a character diff.
36− // This is the text from the `new` rope that should be
61+ // Very large changes are ignored because their character diff is expensive to compute
37− // inserted into `old`.
62+ // TODO adjust heuristic to detect large changes?
38− let text: &str = {
63+ if len_before == 0
39− let start = new.char_to_byte(new_range.start);
64+ || len_after == 0
40− let end = new.char_to_byte(new_range.end);
65+ || len_after > 5 * len_before
41− &new_converted[start..end]
66+ || 5 * len_after < len_before && len_before > 10
42− };
67+ || len_before + len_after > 200
43− Some((old_pos, pos, Some(text.into())))
68+ {
69+ let remove = self.file.before[before.start as usize..before.end as usize]
70+ .iter()
71+ .map(|&it| self.file.interner[it].len_chars())
72+ .sum();
73+ self.res.delete(remove);
74+ let mut fragment = Tendril::new();
75+ if len_after > 500 {
76+ // copying a rope line by line is slower then copying the entire
77+ // rope. Use to_string for very large changes instead..
78+ if self.file.after.len() == after.end as usize {
79+ if after.start == 0 {
80+ fragment = self.after.to_string().into();
81+ } else {
82+ let start = self.after.line_to_char(after.start as usize);
83+ fragment = self.after.slice(start..).to_string().into();
44 }
84 }
45− similar::DiffTag::Delete => Some((old_pos, pos, None)),
85+ } else if after.start == 0 {
46− similar::DiffTag::Equal => None,
86+ let end = self.after.line_to_char(after.end as usize);
87+ fragment = self.after.slice(..end).to_string().into();
88+ } else {
89+ let start = self.after.line_to_char(after.start as usize);
90+ let end = self.after.line_to_char(after.end as usize);
91+ fragment = self.after.slice(start..end).to_string().into();
47 }
92 }
48− }),
93+ } else {
49− )
94+ for &line in &self.file.after[after.start as usize..after.end as usize] {
95+ for chunk in self.file.interner[line].chunks() {
96+ fragment.push_str(chunk)
97+ }
98+ }
99+ };
100+ self.res.insert(fragment);
101+ } else {
102+ // for reasonably small hunks, generating a ChangeSet from char diff can save memory
103+ // TODO use a tokenizer (word diff?) for improved performance
104+ let hunk_before = self.file.before[before.start as usize..before.end as usize]
105+ .iter()
106+ .flat_map(|&it| self.file.interner[it].chars());
107+ let hunk_after = self.file.after[after.start as usize..after.end as usize]
108+ .iter()
109+ .flat_map(|&it| self.file.interner[it].chars());
110+ self.current_hunk.update_before(hunk_before);
111+ self.current_hunk.update_after(hunk_after);
112+
113+ // the histogram heuristic does not work as well
114+ // for characters because the same characters often reoccur
115+ // use myer diff instead
116+ imara_diff::diff(
117+ Algorithm::Myers,
118+ &self.current_hunk,
119+ CharChangeSetBuilder {
120+ res: &mut self.res,
121+ hunk: &self.current_hunk,
122+ pos: 0,
123+ },
124+ );
125+
126+ self.current_hunk.clear();
127+ }
128+ }
129+
130+ fn finish(mut self) -> Self::Out {
131+ let len = self.file.before[self.pos as usize..]
132+ .iter()
133+ .map(|&it| self.file.interner[it].len_chars())
134+ .sum();
135+
136+ self.res.retain(len);
137+ self.res
138+ }
139+}
140+
141+struct RopeLines<'a>(RopeSlice<'a>);
142+
143+impl<'a> imara_diff::intern::TokenSource for RopeLines<'a> {
144+ type Token = RopeSlice<'a>;
145+ // TODO: improve performance of lines iterator (https://github.com/cessen/ropey/issues/25)
146+ type Tokenizer = ropey::iter::Lines<'a>;
147+
148+ fn tokenize(&self) -> Self::Tokenizer {
149+ self.0.lines()
150+ }
151+
152+ fn estimate_tokens(&self) -> u32 {
153+ // we can provide a perfect estimate which is very nice for performance
154+ self.0.len_lines() as u32
155+ }
156+}
157+
158+/// Compares `old` and `new` to generate a [`Transaction`] describing
159+/// the steps required to get from `old` to `new`.
160+pub fn compare_ropes(before: &Rope, after: &Rope) -> Transaction {
161+ let start = Instant::now();
162+ let res = ChangeSet::with_capacity(32);
163+ let after = after.slice(..);
164+ let file = InternedInput::new(RopeLines(before.slice(..)), RopeLines(after));
165+ let builder = LineChangeSetBuilder {
166+ res,
167+ file: &file,
168+ after,
169+ pos: 0,
170+ current_hunk: InternedInput::default(),
171+ };
172+
173+ let res = imara_diff::diff(Algorithm::Histogram, &file, builder).into();
174+
175+ log::debug!(
176+ "rope diff took {}s",
177+ Instant::now().duration_since(start).as_secs_f64()
178+ );
179+ res
50}
180}
51
181
52#[cfg(test)]
182#[cfg(test)]
53mod tests {
183mod tests {
54 use super::*;
184 use super::*;
55
185
186+ fn test_identity(a: &str, b: &str) {
187+ let mut old = Rope::from(a);
188+ let new = Rope::from(b);
189+ compare_ropes(&old, &new).apply(&mut old);
190+ assert_eq!(old, new);
191+ }
192+
56 quickcheck::quickcheck! {
193 quickcheck::quickcheck! {
57 fn test_compare_ropes(a: String, b: String) -> bool {
194 fn test_compare_ropes(a: String, b: String) -> bool {
58 let mut old = Rope::from(a);
195 let mut old = Rope::from(a);
@@ -61,4 +198,25 @@ mod tests {
61 old == new
198 old == new
62 }
199 }
63 }
200 }
201+
202+ #[test]
203+ fn equal_files() {
204+ test_identity("foo", "foo");
205+ }
206+
207+ #[test]
208+ fn trailing_newline() {
209+ test_identity("foo\n", "foo");
210+ test_identity("foo", "foo\n");
211+ }
212+
213+ #[test]
214+ fn new_file() {
215+ test_identity("", "foo");
216+ }
217+
218+ #[test]
219+ fn deleted_file() {
220+ test_identity("foo", "");
221+ }
64}
222}
helix-core/src/transaction.rs+3−3
@@ -56,7 +56,7 @@ impl ChangeSet {
56 }
56 }
57
57
58 // Changeset builder operations: delete/insert/retain
58 // Changeset builder operations: delete/insert/retain
59− fn delete(&mut self, n: usize) {
59+ pub(crate) fn delete(&mut self, n: usize) {
60 use Operation::*;
60 use Operation::*;
61 if n == 0 {
61 if n == 0 {
62 return;
62 return;
@@ -71,7 +71,7 @@ impl ChangeSet {
71 }
71 }
72 }
72 }
73
73
74− fn insert(&mut self, fragment: Tendril) {
74+ pub(crate) fn insert(&mut self, fragment: Tendril) {
75 use Operation::*;
75 use Operation::*;
76
76
77 if fragment.is_empty() {
77 if fragment.is_empty() {
@@ -93,7 +93,7 @@ impl ChangeSet {
93 self.changes.push(new_last);
93 self.changes.push(new_last);
94 }
94 }
95
95
96− fn retain(&mut self, n: usize) {
96+ pub(crate) fn retain(&mut self, n: usize) {
97 use Operation::*;
97 use Operation::*;
98 if n == 0 {
98 if n == 0 {
99 return;
99 return;