From 583c2a5456263865c8aaf8b260909bfe431db549 Mon Sep 17 00:00:00 2001 From: gavincrawford <94875769+gavincrawford@users.noreply.github.com> Date: Sun, 27 Nov 2022 08:36:52 -0700 Subject: [PATCH 001/132] Fix Go variable indentation (#4906) --- runtime/queries/go/indents.scm | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/queries/go/indents.scm b/runtime/queries/go/indents.scm index d75417d9..8bfc7c3f 100644 --- a/runtime/queries/go/indents.scm +++ b/runtime/queries/go/indents.scm @@ -16,6 +16,7 @@ (block) (type_switch_statement) (expression_switch_statement) + (var_declaration) ] @indent [ From bf908cc4a11b7567800b2e3d5b48b5b29a330911 Mon Sep 17 00:00:00 2001 From: Chickenkeeper Date: Mon, 28 Nov 2022 01:11:12 +0000 Subject: [PATCH 002/132] Update CSS syntax highlighting (#4882) --- languages.toml | 2 +- runtime/queries/css/highlights.scm | 115 +++++++++++++++++------------ 2 files changed, 69 insertions(+), 48 deletions(-) diff --git a/languages.toml b/languages.toml index d616ce9e..756315cd 100644 --- a/languages.toml +++ b/languages.toml @@ -426,7 +426,7 @@ indent = { tab-width = 2, unit = " " } [[grammar]] name = "css" -source = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "94e10230939e702b4fa3fa2cb5c3bc7173b95d07" } +source = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" } [[language]] name = "scss" diff --git a/runtime/queries/css/highlights.scm b/runtime/queries/css/highlights.scm index 4dfc0c66..b5262e8f 100644 --- a/runtime/queries/css/highlights.scm +++ b/runtime/queries/css/highlights.scm @@ -1,64 +1,85 @@ (comment) @comment -(tag_name) @tag -(nesting_selector) @tag -(universal_selector) @tag +[ + (tag_name) + (nesting_selector) + (universal_selector) +] @tag -"~" @operator -">" @operator -"+" @operator -"-" @operator -"*" @operator -"/" @operator -"=" @operator -"^=" @operator -"|=" @operator -"~=" @operator -"$=" @operator -"*=" @operator +[ + "~" + ">" + "+" + "-" + "*" + "/" + "=" + "^=" + "|=" + "~=" + "$=" + "*=" +] @operator -"and" @operator -"or" @operator -"not" @operator -"only" @operator - -(attribute_selector (plain_value) @string) -(pseudo_element_selector (tag_name) @attribute) -(pseudo_class_selector (class_name) @attribute) - -(class_name) @variable.other.member -(id_name) @variable.other.member -(namespace_name) @variable.other.member -(property_name) @variable.other.member -(feature_name) @variable.other.member - -(attribute_name) @attribute - -(function_name) @function +[ + "and" + "not" + "only" + "or" +] @keyword.operator ((property_name) @variable (#match? @variable "^--")) ((plain_value) @variable (#match? @variable "^--")) -"@media" @keyword -"@import" @keyword -"@charset" @keyword -"@namespace" @keyword -"@supports" @keyword -"@keyframes" @keyword -(at_keyword) @keyword -(to) @keyword -(from) @keyword -(important) @keyword +(attribute_name) @attribute +(class_name) @label +(feature_name) @variable.other.member +(function_name) @function +(id_name) @label +(namespace_name) @namespace +(property_name) @variable.other.member + +[ + "@charset" + "@import" + "@keyframes" + "@media" + "@namespace" + "@supports" + (at_keyword) + (from) + (important) + (to) +] @keyword + +[ + "#" + "." +] @punctuation (string_value) @string +((color_value) "#") @string.special (color_value) @string.special (integer_value) @constant.numeric.integer (float_value) @constant.numeric.float -(unit) @type -"#" @punctuation.delimiter -"," @punctuation.delimiter -":" @punctuation.delimiter +[ + ")" + "(" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "," + ";" + ":" + "::" +] @punctuation.delimiter + +(plain_value) @constant From a549328ef29b9f0911b04e9517bf55962d32dea2 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Mon, 28 Nov 2022 02:51:26 +0100 Subject: [PATCH 003/132] bump ropey to 1.5.1-alpha --- Cargo.lock | 4 ++-- helix-core/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 616c5317..1d0ee4df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -931,9 +931,9 @@ dependencies = [ [[package]] name = "ropey" -version = "1.5.0" +version = "1.5.1-alpha" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd22239fafefc42138ca5da064f3c17726a80d2379d817a3521240e78dd0064" +checksum = "917e62c0dee8926492dd13164b3cefaad2b0e03ab49f48c0d41635797a7409b3" dependencies = [ "smallvec", "str_indices", diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index eb886c90..09665b91 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -17,7 +17,7 @@ integration = [] [dependencies] helix-loader = { version = "0.6", path = "../helix-loader" } -ropey = { version = "1.5", default-features = false, features = ["simd"] } +ropey = { version = "1.5.1-alpha", default-features = false, features = ["simd"] } smallvec = "1.10" smartstring = "1.0.1" unicode-segmentation = "1.10" From da355a3231174ac019b43a31958b73e818e6463f Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Mon, 28 Nov 2022 03:20:54 +0100 Subject: [PATCH 004/132] Significantly improve performance of `:reload` (#4457) * bump ropey to 1.5.1-alpha * significantly improve performance of :reload --- Cargo.lock | 259 ++++++++++++++++++++++++---------- helix-core/Cargo.toml | 2 +- helix-core/src/diff.rs | 248 ++++++++++++++++++++++++++------ helix-core/src/transaction.rs | 6 +- 4 files changed, 389 insertions(+), 126 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d0ee4df..05a0396f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,9 +27,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytecount" @@ -92,9 +92,9 @@ checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cassowary" @@ -148,6 +148,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "content_inspector" version = "0.2.4" @@ -165,12 +175,11 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -199,6 +208,50 @@ dependencies = [ "winapi", ] +[[package]] +name = "cxx" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -345,9 +398,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -436,6 +489,7 @@ dependencies = [ "etcetera", "hashbrown 0.13.1", "helix-loader", + "imara-diff", "log", "once_cell", "quickcheck", @@ -443,7 +497,6 @@ dependencies = [ "ropey", "serde", "serde_json", - "similar", "slotmap", "smallvec", "smartstring", @@ -594,18 +647,28 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.47" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c495f162af0bf17656d0014a0eded5f3cd2f365fdd204548c2869db89359dc7" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", - "once_cell", "wasm-bindgen", "winapi", ] +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "idna" version = "0.3.0" @@ -634,6 +697,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "imara-diff" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8" +dependencies = [ + "ahash 0.8.2", + "hashbrown 0.12.3", +] + [[package]] name = "indoc" version = "1.0.7" @@ -651,15 +724,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -672,9 +745,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.132" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "libloading" @@ -686,11 +759,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + [[package]] name = "lock_api" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -726,18 +808,18 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" +checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" dependencies = [ "libc", ] [[package]] name = "mio" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", @@ -766,9 +848,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ "hermit-abi", "libc", @@ -792,9 +874,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if", "libc", @@ -823,9 +905,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -870,9 +952,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -916,9 +998,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -960,20 +1042,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + [[package]] name = "serde" -version = "1.0.147" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" dependencies = [ "proc-macro2", "quote", @@ -982,9 +1070,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa", "ryu", @@ -1044,12 +1132,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "similar" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" - [[package]] name = "slab" version = "0.4.7" @@ -1121,9 +1203,9 @@ checksum = "9d9199fa80c817e074620be84374a520062ebac833f358d74b37060ce4a0f2c0" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" dependencies = [ "proc-macro2", "quote", @@ -1144,6 +1226,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "termini" version = "0.1.4" @@ -1301,9 +1392,9 @@ checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7" [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-linebreak" @@ -1317,9 +1408,9 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] @@ -1373,9 +1464,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1383,9 +1474,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -1398,9 +1489,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1408,9 +1499,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -1421,9 +1512,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "which" @@ -1469,46 +1560,60 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ + "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", + "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" [[package]] name = "xtask" diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 09665b91..31b6546f 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -38,7 +38,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" toml = "0.5" -similar = "2.2" +imara-diff = "0.1.0" encoding_rs = "0.8" diff --git a/helix-core/src/diff.rs b/helix-core/src/diff.rs index 6960c679..c754da30 100644 --- a/helix-core/src/diff.rs +++ b/helix-core/src/diff.rs @@ -1,58 +1,195 @@ -use crate::{Rope, Transaction}; +use std::ops::Range; +use std::time::Instant; -/// Compares `old` and `new` to generate a [`Transaction`] describing -/// the steps required to get from `old` to `new`. -pub fn compare_ropes(old: &Rope, new: &Rope) -> Transaction { - // `similar` only works on contiguous data, so a `Rope` has - // to be temporarily converted into a `String`. - let old_converted = old.to_string(); - let new_converted = new.to_string(); - - // A timeout is set so after 1 seconds, the algorithm will start - // approximating. This is especially important for big `Rope`s or - // `Rope`s that are extremely dissimilar to each other. - let mut config = similar::TextDiff::configure(); - config.timeout(std::time::Duration::from_secs(1)); - - let diff = config.diff_chars(&old_converted, &new_converted); - - // The current position of the change needs to be tracked to - // construct the `Change`s. - let mut pos = 0; - Transaction::change( - old, - diff.ops() +use imara_diff::intern::InternedInput; +use imara_diff::Algorithm; +use ropey::RopeSlice; + +use crate::{ChangeSet, Rope, Tendril, Transaction}; + +/// A `imara_diff::Sink` that builds a `ChangeSet` for a character diff of a hunk +struct CharChangeSetBuilder<'a> { + res: &'a mut ChangeSet, + hunk: &'a InternedInput, + pos: u32, +} + +impl imara_diff::Sink for CharChangeSetBuilder<'_> { + type Out = (); + fn process_change(&mut self, before: Range, after: Range) { + self.res.retain((before.start - self.pos) as usize); + self.res.delete(before.len()); + self.pos = before.end; + + let res = self.hunk.after[after.start as usize..after.end as usize] + .iter() + .map(|&token| self.hunk.interner[token]) + .collect(); + + self.res.insert(res); + } + + fn finish(self) -> Self::Out { + self.res.retain(self.hunk.before.len() - self.pos as usize); + } +} + +struct LineChangeSetBuilder<'a> { + res: ChangeSet, + after: RopeSlice<'a>, + file: &'a InternedInput>, + current_hunk: InternedInput, + pos: u32, +} + +impl imara_diff::Sink for LineChangeSetBuilder<'_> { + type Out = ChangeSet; + + fn process_change(&mut self, before: Range, after: Range) { + let len = self.file.before[self.pos as usize..before.start as usize] .iter() - .map(|op| op.as_tag_tuple()) - .filter_map(|(tag, old_range, new_range)| { - // `old_pos..pos` is equivalent to `start..end` for where - // the change should be applied. - let old_pos = pos; - pos += old_range.end - old_range.start; - - match tag { - // Semantically, inserts and replacements are the same thing. - similar::DiffTag::Insert | similar::DiffTag::Replace => { - // This is the text from the `new` rope that should be - // inserted into `old`. - let text: &str = { - let start = new.char_to_byte(new_range.start); - let end = new.char_to_byte(new_range.end); - &new_converted[start..end] - }; - Some((old_pos, pos, Some(text.into()))) + .map(|&it| self.file.interner[it].len_chars()) + .sum(); + self.res.retain(len); + self.pos = before.end; + + // do not perform diffs on large hunks + let len_before = before.end - before.start; + let len_after = after.end - after.start; + + // Pure insertions/removals do not require a character diff. + // Very large changes are ignored because their character diff is expensive to compute + // TODO adjust heuristic to detect large changes? + if len_before == 0 + || len_after == 0 + || len_after > 5 * len_before + || 5 * len_after < len_before && len_before > 10 + || len_before + len_after > 200 + { + let remove = self.file.before[before.start as usize..before.end as usize] + .iter() + .map(|&it| self.file.interner[it].len_chars()) + .sum(); + self.res.delete(remove); + let mut fragment = Tendril::new(); + if len_after > 500 { + // copying a rope line by line is slower then copying the entire + // rope. Use to_string for very large changes instead.. + if self.file.after.len() == after.end as usize { + if after.start == 0 { + fragment = self.after.to_string().into(); + } else { + let start = self.after.line_to_char(after.start as usize); + fragment = self.after.slice(start..).to_string().into(); } - similar::DiffTag::Delete => Some((old_pos, pos, None)), - similar::DiffTag::Equal => None, + } else if after.start == 0 { + let end = self.after.line_to_char(after.end as usize); + fragment = self.after.slice(..end).to_string().into(); + } else { + let start = self.after.line_to_char(after.start as usize); + let end = self.after.line_to_char(after.end as usize); + fragment = self.after.slice(start..end).to_string().into(); } - }), - ) + } else { + for &line in &self.file.after[after.start as usize..after.end as usize] { + for chunk in self.file.interner[line].chunks() { + fragment.push_str(chunk) + } + } + }; + self.res.insert(fragment); + } else { + // for reasonably small hunks, generating a ChangeSet from char diff can save memory + // TODO use a tokenizer (word diff?) for improved performance + let hunk_before = self.file.before[before.start as usize..before.end as usize] + .iter() + .flat_map(|&it| self.file.interner[it].chars()); + let hunk_after = self.file.after[after.start as usize..after.end as usize] + .iter() + .flat_map(|&it| self.file.interner[it].chars()); + self.current_hunk.update_before(hunk_before); + self.current_hunk.update_after(hunk_after); + + // the histogram heuristic does not work as well + // for characters because the same characters often reoccur + // use myer diff instead + imara_diff::diff( + Algorithm::Myers, + &self.current_hunk, + CharChangeSetBuilder { + res: &mut self.res, + hunk: &self.current_hunk, + pos: 0, + }, + ); + + self.current_hunk.clear(); + } + } + + fn finish(mut self) -> Self::Out { + let len = self.file.before[self.pos as usize..] + .iter() + .map(|&it| self.file.interner[it].len_chars()) + .sum(); + + self.res.retain(len); + self.res + } +} + +struct RopeLines<'a>(RopeSlice<'a>); + +impl<'a> imara_diff::intern::TokenSource for RopeLines<'a> { + type Token = RopeSlice<'a>; + // TODO: improve performance of lines iterator (https://github.com/cessen/ropey/issues/25) + type Tokenizer = ropey::iter::Lines<'a>; + + fn tokenize(&self) -> Self::Tokenizer { + self.0.lines() + } + + fn estimate_tokens(&self) -> u32 { + // we can provide a perfect estimate which is very nice for performance + self.0.len_lines() as u32 + } +} + +/// Compares `old` and `new` to generate a [`Transaction`] describing +/// the steps required to get from `old` to `new`. +pub fn compare_ropes(before: &Rope, after: &Rope) -> Transaction { + let start = Instant::now(); + let res = ChangeSet::with_capacity(32); + let after = after.slice(..); + let file = InternedInput::new(RopeLines(before.slice(..)), RopeLines(after)); + let builder = LineChangeSetBuilder { + res, + file: &file, + after, + pos: 0, + current_hunk: InternedInput::default(), + }; + + let res = imara_diff::diff(Algorithm::Histogram, &file, builder).into(); + + log::debug!( + "rope diff took {}s", + Instant::now().duration_since(start).as_secs_f64() + ); + res } #[cfg(test)] mod tests { use super::*; + fn test_identity(a: &str, b: &str) { + let mut old = Rope::from(a); + let new = Rope::from(b); + compare_ropes(&old, &new).apply(&mut old); + assert_eq!(old, new); + } + quickcheck::quickcheck! { fn test_compare_ropes(a: String, b: String) -> bool { let mut old = Rope::from(a); @@ -61,4 +198,25 @@ mod tests { old == new } } + + #[test] + fn equal_files() { + test_identity("foo", "foo"); + } + + #[test] + fn trailing_newline() { + test_identity("foo\n", "foo"); + test_identity("foo", "foo\n"); + } + + #[test] + fn new_file() { + test_identity("", "foo"); + } + + #[test] + fn deleted_file() { + test_identity("foo", ""); + } } diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index 3fb39413..482fd6d9 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -56,7 +56,7 @@ impl ChangeSet { } // Changeset builder operations: delete/insert/retain - fn delete(&mut self, n: usize) { + pub(crate) fn delete(&mut self, n: usize) { use Operation::*; if n == 0 { return; @@ -71,7 +71,7 @@ impl ChangeSet { } } - fn insert(&mut self, fragment: Tendril) { + pub(crate) fn insert(&mut self, fragment: Tendril) { use Operation::*; if fragment.is_empty() { @@ -93,7 +93,7 @@ impl ChangeSet { self.changes.push(new_last); } - fn retain(&mut self, n: usize) { + pub(crate) fn retain(&mut self, n: usize) { use Operation::*; if n == 0 { return; From 5c213f7de4df551284cf46631508b1b0d5244a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20B=C3=BCnnig?= Date: Mon, 28 Nov 2022 16:19:16 +0100 Subject: [PATCH 005/132] fix(grammar): Add `block_comment` and `comment_environment` injection for latex comments (#4922) --- runtime/queries/latex/injections.scm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/runtime/queries/latex/injections.scm b/runtime/queries/latex/injections.scm index d3fdb0ca..10137468 100644 --- a/runtime/queries/latex/injections.scm +++ b/runtime/queries/latex/injections.scm @@ -1,2 +1,6 @@ -((line_comment) @injection.content - (#set! injection.language "comment")) +([ + (comment) + (line_comment) + (block_comment) + (comment_environment) + ] @injection.content (#set! injection.language "comment")) From 04df9e444523ced5d3bedbe34e2f622d675cccb2 Mon Sep 17 00:00:00 2001 From: Kirawi <67773714+kirawi@users.noreply.github.com> Date: Mon, 28 Nov 2022 20:07:47 -0500 Subject: [PATCH 006/132] delete outdated reference to cessen/ropey#25 (#4928) --- helix-core/src/diff.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/helix-core/src/diff.rs b/helix-core/src/diff.rs index c754da30..a5d6d722 100644 --- a/helix-core/src/diff.rs +++ b/helix-core/src/diff.rs @@ -142,7 +142,6 @@ struct RopeLines<'a>(RopeSlice<'a>); impl<'a> imara_diff::intern::TokenSource for RopeLines<'a> { type Token = RopeSlice<'a>; - // TODO: improve performance of lines iterator (https://github.com/cessen/ropey/issues/25) type Tokenizer = ropey::iter::Lines<'a>; fn tokenize(&self) -> Self::Tokenizer { From df5457a6e71b58a39e198642efd7be0c4963153d Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 10:33:51 -0600 Subject: [PATCH 007/132] Remove eager application of transactions to all views --- helix-term/src/ui/editor.rs | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 73712503..6c8ee2d9 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1337,9 +1337,7 @@ impl Component for EditorView { cx.editor.status_msg = None; let mode = cx.editor.mode(); - let (view, doc) = current!(cx.editor); - let original_doc_id = doc.id(); - let original_doc_revision = doc.get_current_revision(); + let (view, _) = current!(cx.editor); let focus = view.id; if let Some(on_next_key) = self.on_next_key.take() { @@ -1415,31 +1413,13 @@ impl Component for EditorView { let view = view_mut!(cx.editor, focus); let doc = doc_mut!(cx.editor, &view.doc); + view.ensure_cursor_in_view(doc, config.scrolloff); + // Store a history state if not in insert mode. This also takes care of // committing changes when leaving insert mode. if mode != Mode::Insert { doc.append_changes_to_history(view.id); } - - // If the current document has been changed, apply the changes to all views. - // This ensures that selections in jumplists follow changes. - if doc.id() == original_doc_id - && doc.get_current_revision() != original_doc_revision - { - if let Some(transaction) = - doc.history.get_mut().changes_since(original_doc_revision) - { - let doc = doc!(cx.editor, &original_doc_id); - for (view, _focused) in cx.editor.tree.views_mut() { - view.apply(&transaction, doc); - } - } - } - - let view = view_mut!(cx.editor, focus); - let doc = doc_mut!(cx.editor, &view.doc); - - view.ensure_cursor_in_view(doc, config.scrolloff); } EventResult::Consumed(callback) From 4d1f5389f99013be99b9498fd3fee78eec6217f3 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 10:46:42 -0600 Subject: [PATCH 008/132] Revert "Don't apply transactions to Views in undo/redo" This reverts commit fd00f3a70eb626242bb2fcc9bddf2c4d94580a9a. --- helix-term/src/commands.rs | 8 ++++---- helix-term/src/commands/typed.rs | 4 ++-- helix-view/src/document.rs | 24 ++++++++++++------------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 5c6807f0..0817ca73 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3321,7 +3321,7 @@ fn undo(cx: &mut Context) { let count = cx.count(); let (view, doc) = current!(cx.editor); for _ in 0..count { - if !doc.undo(view.id) { + if !doc.undo(view) { cx.editor.set_status("Already at oldest change"); break; } @@ -3332,7 +3332,7 @@ fn redo(cx: &mut Context) { let count = cx.count(); let (view, doc) = current!(cx.editor); for _ in 0..count { - if !doc.redo(view.id) { + if !doc.redo(view) { cx.editor.set_status("Already at newest change"); break; } @@ -3344,7 +3344,7 @@ fn earlier(cx: &mut Context) { let (view, doc) = current!(cx.editor); for _ in 0..count { // rather than doing in batch we do this so get error halfway - if !doc.earlier(view.id, UndoKind::Steps(1)) { + if !doc.earlier(view, UndoKind::Steps(1)) { cx.editor.set_status("Already at oldest change"); break; } @@ -3356,7 +3356,7 @@ fn later(cx: &mut Context) { let (view, doc) = current!(cx.editor); for _ in 0..count { // rather than doing in batch we do this so get error halfway - if !doc.later(view.id, UndoKind::Steps(1)) { + if !doc.later(view, UndoKind::Steps(1)) { cx.editor.set_status("Already at newest change"); break; } diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 351692fd..89c310fa 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -481,7 +481,7 @@ fn earlier( let uk = args.join(" ").parse::().map_err(|s| anyhow!(s))?; let (view, doc) = current!(cx.editor); - let success = doc.earlier(view.id, uk); + let success = doc.earlier(view, uk); if !success { cx.editor.set_status("Already at oldest change"); } @@ -500,7 +500,7 @@ fn later( let uk = args.join(" ").parse::().map_err(|s| anyhow!(s))?; let (view, doc) = current!(cx.editor); - let success = doc.later(view.id, uk); + let success = doc.later(view, uk); if !success { cx.editor.set_status("Already at newest change"); } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 0eb54f25..08708528 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -857,11 +857,11 @@ impl Document { success } - fn undo_redo_impl(&mut self, view_id: ViewId, undo: bool) -> bool { + fn undo_redo_impl(&mut self, view: &mut View, undo: bool) -> bool { let mut history = self.history.take(); let txn = if undo { history.undo() } else { history.redo() }; let success = if let Some(txn) = txn { - self.apply_impl(txn, view_id) + self.apply_impl(txn, view.id) && view.apply(txn, self) } else { false }; @@ -875,13 +875,13 @@ impl Document { } /// Undo the last modification to the [`Document`]. Returns whether the undo was successful. - pub fn undo(&mut self, view_id: ViewId) -> bool { - self.undo_redo_impl(view_id, true) + pub fn undo(&mut self, view: &mut View) -> bool { + self.undo_redo_impl(view, true) } /// Redo the last modification to the [`Document`]. Returns whether the redo was successful. - pub fn redo(&mut self, view_id: ViewId) -> bool { - self.undo_redo_impl(view_id, false) + pub fn redo(&mut self, view: &mut View) -> bool { + self.undo_redo_impl(view, false) } pub fn savepoint(&mut self) { @@ -894,7 +894,7 @@ impl Document { } } - fn earlier_later_impl(&mut self, view_id: ViewId, uk: UndoKind, earlier: bool) -> bool { + fn earlier_later_impl(&mut self, view: &mut View, uk: UndoKind, earlier: bool) -> bool { let txns = if earlier { self.history.get_mut().earlier(uk) } else { @@ -902,7 +902,7 @@ impl Document { }; let mut success = false; for txn in txns { - if self.apply_impl(&txn, view_id) { + if self.apply_impl(&txn, view.id) && view.apply(&txn, self) { success = true; } } @@ -914,13 +914,13 @@ impl Document { } /// Undo modifications to the [`Document`] according to `uk`. - pub fn earlier(&mut self, view_id: ViewId, uk: UndoKind) -> bool { - self.earlier_later_impl(view_id, uk, true) + pub fn earlier(&mut self, view: &mut View, uk: UndoKind) -> bool { + self.earlier_later_impl(view, uk, true) } /// Redo modifications to the [`Document`] according to `uk`. - pub fn later(&mut self, view_id: ViewId, uk: UndoKind) -> bool { - self.earlier_later_impl(view_id, uk, false) + pub fn later(&mut self, view: &mut View, uk: UndoKind) -> bool { + self.earlier_later_impl(view, uk, false) } /// Commit pending changes to history From 056a19a003a290b7914c7b442ebd640b93eaba0c Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 10:45:17 -0600 Subject: [PATCH 009/132] Sync changes between doc and view on switch --- helix-view/src/editor.rs | 7 ++++++- helix-view/src/view.rs | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 6eaa89aa..e54c7497 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -959,7 +959,8 @@ impl Editor { fn _refresh(&mut self) { let config = self.config(); for (view, _) in self.tree.views_mut() { - let doc = &self.documents[&view.doc]; + let doc = doc_mut!(self, &view.doc); + view.sync_changes(doc); view.ensure_cursor_in_view(doc, config.scrolloff) } } @@ -971,6 +972,7 @@ impl Editor { let doc = doc_mut!(self, &doc_id); doc.ensure_view_init(view.id); + view.sync_changes(doc); align_view(doc, view, Align::Center); } @@ -1239,6 +1241,9 @@ impl Editor { // within view if prev_id != view_id { self.mode = Mode::Normal; + let view = view_mut!(self, view_id); + let doc = doc_mut!(self, &view.doc); + view.sync_changes(doc); self.ensure_cursor_in_view(view_id); } } diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index c917a1ab..845a5458 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -3,7 +3,10 @@ use helix_core::{ pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction, }; -use std::{collections::VecDeque, fmt}; +use std::{ + collections::{HashMap, VecDeque}, + fmt, +}; const JUMP_LIST_CAPACITY: usize = 30; @@ -102,6 +105,11 @@ pub struct View { pub object_selections: Vec, /// GutterTypes used to fetch Gutter (constructor) and width for rendering gutters: Vec, + /// A mapping between documents and the last history revision the view was updated at. + /// Changes between documents and views are synced lazily when switching windows. This + /// mapping keeps track of the last applied history revision so that only new changes + /// are applied. + doc_revisions: HashMap, } impl fmt::Debug for View { @@ -126,6 +134,7 @@ impl View { last_modified_docs: [None, None], object_selections: Vec::new(), gutters: gutter_types, + doc_revisions: HashMap::new(), } } @@ -349,10 +358,33 @@ impl View { /// Applies a [`Transaction`] to the view. /// Instead of calling this function directly, use [crate::apply_transaction] /// which applies a transaction to the [`Document`] and view together. - pub fn apply(&mut self, transaction: &Transaction, doc: &Document) -> bool { + pub fn apply(&mut self, transaction: &Transaction, doc: &mut Document) { self.jumps.apply(transaction, doc); - // TODO: remove the boolean return. This is unused. - true + self.doc_revisions + .insert(doc.id(), doc.get_current_revision()); + } + + pub fn sync_changes(&mut self, doc: &mut Document) { + let latest_revision = doc.get_current_revision(); + let current_revision = *self + .doc_revisions + .entry(doc.id()) + .or_insert(latest_revision); + + if current_revision == latest_revision { + return; + } + + log::debug!( + "Syncing view {:?} between {} and {}", + self.id, + current_revision, + latest_revision + ); + + if let Some(transaction) = doc.history.get_mut().changes_since(current_revision) { + self.apply(&transaction, doc); + } } } From 53c28556436ffcf8ad5a68c40b53d9aa11669510 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 12:47:51 -0600 Subject: [PATCH 010/132] Remove calls to View::apply in undo/redo/earlier/later --- helix-view/src/document.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 08708528..4b264b13 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -861,7 +861,7 @@ impl Document { let mut history = self.history.take(); let txn = if undo { history.undo() } else { history.redo() }; let success = if let Some(txn) = txn { - self.apply_impl(txn, view.id) && view.apply(txn, self) + self.apply_impl(txn, view.id) } else { false }; @@ -902,7 +902,7 @@ impl Document { }; let mut success = false; for txn in txns { - if self.apply_impl(&txn, view.id) && view.apply(&txn, self) { + if self.apply_impl(&txn, view.id) { success = true; } } From 2709ce33324cf6d4612c61609f336cf5937b6cac Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 12:48:14 -0600 Subject: [PATCH 011/132] Sync changes with view in undo/redo/earlier/later --- helix-view/src/document.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 4b264b13..17503553 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -870,6 +870,8 @@ impl Document { if success { // reset changeset to fix len self.changes = ChangeSet::new(self.text()); + // Sync with changes with the jumplist selections. + view.sync_changes(self); } success } @@ -909,6 +911,8 @@ impl Document { if success { // reset changeset to fix len self.changes = ChangeSet::new(self.text()); + // Sync with changes with the jumplist selections. + view.sync_changes(self); } success } From 9a9e462183cb60bff6450f17173e6b18eadbbfb2 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 12:47:26 -0600 Subject: [PATCH 012/132] Call View::apply within Document::append_changes_to_history --- helix-term/src/commands.rs | 8 ++++---- helix-term/src/commands/lsp.rs | 5 +++-- helix-term/src/commands/typed.rs | 8 ++++---- helix-term/src/ui/editor.rs | 4 ++-- helix-view/src/document.rs | 9 ++++++--- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 0817ca73..a6f88362 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2564,7 +2564,7 @@ async fn make_format_callback( if let Ok(format) = format { if doc.version() == doc_version { apply_transaction(&format, doc, view); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); doc.detect_indent_and_line_ending(); view.ensure_cursor_in_view(doc, scrolloff); } else { @@ -3365,7 +3365,7 @@ fn later(cx: &mut Context) { fn commit_undo_checkpoint(cx: &mut Context) { let (view, doc) = current!(cx.editor); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); } // Yank / Paste @@ -3677,7 +3677,7 @@ fn replace_selections_with_clipboard_impl( }); apply_transaction(&transaction, doc, view); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); } Err(e) => return Err(e.context("Couldn't get system clipboard contents")), } @@ -4884,7 +4884,7 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) { let transaction = Transaction::change(doc.text(), changes.into_iter()) .with_selection(Selection::new(ranges, selection.primary_index())); apply_transaction(&transaction, doc, view); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); } // after replace cursor may be out of bounds, do this to diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index 8faf1d08..1f80de5f 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -760,8 +760,9 @@ pub fn apply_workspace_edit( text_edits, offset_encoding, ); - apply_transaction(&transaction, doc, view_mut!(editor, view_id)); - doc.append_changes_to_history(view_id); + let view = view_mut!(editor, view_id); + apply_transaction(&transaction, doc, view); + doc.append_changes_to_history(view); }; if let Some(ref changes) = workspace_edit.changes { diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 89c310fa..2fa903a7 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -464,7 +464,7 @@ fn set_line_ending( }), ); apply_transaction(&transaction, doc, view); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); Ok(()) } @@ -909,7 +909,7 @@ fn replace_selections_with_clipboard_impl( }); apply_transaction(&transaction, doc, view); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); Ok(()) } Err(e) => Err(e.context("Couldn't get system clipboard contents")), @@ -1573,7 +1573,7 @@ fn sort_impl( ); apply_transaction(&transaction, doc, view); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); Ok(()) } @@ -1617,7 +1617,7 @@ fn reflow( }); apply_transaction(&transaction, doc, view); - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); view.ensure_cursor_in_view(doc, scrolloff); Ok(()) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 6c8ee2d9..7bda74d2 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1319,7 +1319,7 @@ impl Component for EditorView { // Store a history state if not in insert mode. Otherwise wait till we exit insert // to include any edits to the paste in the history state. if mode != Mode::Insert { - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); } EventResult::Consumed(None) @@ -1418,7 +1418,7 @@ impl Component for EditorView { // Store a history state if not in insert mode. This also takes care of // committing changes when leaving insert mode. if mode != Mode::Insert { - doc.append_changes_to_history(view.id); + doc.append_changes_to_history(view); } } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 17503553..ad47f838 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -641,7 +641,7 @@ impl Document { // of the encoding. let transaction = helix_core::diff::compare_ropes(self.text(), &rope); apply_transaction(&transaction, self, view); - self.append_changes_to_history(view.id); + self.append_changes_to_history(view); self.reset_modified(); self.detect_indent_and_line_ending(); @@ -928,7 +928,7 @@ impl Document { } /// Commit pending changes to history - pub fn append_changes_to_history(&mut self, view_id: ViewId) { + pub fn append_changes_to_history(&mut self, view: &mut View) { if self.changes.is_empty() { return; } @@ -938,7 +938,7 @@ impl Document { // Instead of doing this messy merge we could always commit, and based on transaction // annotations either add a new layer or compose into the previous one. let transaction = - Transaction::from(changes).with_selection(self.selection(view_id).clone()); + Transaction::from(changes).with_selection(self.selection(view.id).clone()); // HAXX: we need to reconstruct the state as it was before the changes.. let old_state = self.old_state.take().expect("no old_state available"); @@ -946,6 +946,9 @@ impl Document { let mut history = self.history.take(); history.commit_revision(&transaction, &old_state); self.history.set(history); + + // Update jumplist entries in the view. + view.apply(&transaction, self); } pub fn id(&self) -> DocumentId { From 9387dfafedfc7051e7682cfdbec09b5b91c76918 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 12:46:36 -0600 Subject: [PATCH 013/132] Use lowest common ancestor search in History::changes_since --- helix-core/src/history.rs | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/helix-core/src/history.rs b/helix-core/src/history.rs index 82509242..b99e969f 100644 --- a/helix-core/src/history.rs +++ b/helix-core/src/history.rs @@ -122,32 +122,16 @@ impl History { /// Returns the changes since the given revision composed into a transaction. /// Returns None if there are no changes between the current and given revisions. pub fn changes_since(&self, revision: usize) -> Option { - use std::cmp::Ordering::*; + let lca = self.lowest_common_ancestor(revision, self.current); + let up = self.path_up(revision, lca); + let down = self.path_up(self.current, lca); + let up_txns = up + .iter() + .rev() + .map(|&n| self.revisions[n].inversion.clone()); + let down_txns = down.iter().map(|&n| self.revisions[n].transaction.clone()); - match revision.cmp(&self.current) { - Equal => None, - Less => { - let mut child = self.revisions[revision].last_child?.get(); - let mut transaction = self.revisions[child].transaction.clone(); - while child != self.current { - child = self.revisions[child].last_child?.get(); - transaction = transaction.compose(self.revisions[child].transaction.clone()); - } - Some(transaction) - } - Greater => { - let mut inversion = self.revisions[revision].inversion.clone(); - let mut parent = self.revisions[revision].parent; - while parent != self.current { - parent = self.revisions[parent].parent; - if parent == 0 { - return None; - } - inversion = inversion.compose(self.revisions[parent].inversion.clone()); - } - Some(inversion) - } - } + up_txns.chain(down_txns).reduce(|acc, tx| tx.compose(acc)) } /// Undo the last edit. From 4802f26a232b2eed5f4af05a540a4735edd199ee Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 27 Nov 2022 13:47:52 -0600 Subject: [PATCH 014/132] Add a test case for undo/redo across splits --- helix-term/tests/test/splits.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/helix-term/tests/test/splits.rs b/helix-term/tests/test/splits.rs index a51de365..a34a24b7 100644 --- a/helix-term/tests/test/splits.rs +++ b/helix-term/tests/test/splits.rs @@ -151,5 +151,15 @@ async fn test_changes_in_splits_apply_to_all_views() -> anyhow::Result<()> { // was not updated and after the `kd` step, pointed outside of the document. test(("#[|]#", "v[wkdqd", "#[|]#")).await?; + // Transactions are applied to the views for windows lazily when they are focused. + // This case panics if the transactions and inversions are not applied in the + // correct order as we switch between windows. + test(( + "#[|]#", + "[[[vuuuwUUUquuu", + "#[|]#", + )) + .await?; + Ok(()) } From 260341ed801a894141db2fd4e66c7159d06b665e Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Mon, 28 Nov 2022 09:36:41 -0600 Subject: [PATCH 015/132] Sync all document changes on view focus --- helix-view/src/editor.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index e54c7497..5a1ac6b1 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1241,10 +1241,13 @@ impl Editor { // within view if prev_id != view_id { self.mode = Mode::Normal; - let view = view_mut!(self, view_id); - let doc = doc_mut!(self, &view.doc); - view.sync_changes(doc); self.ensure_cursor_in_view(view_id); + + // Update jumplist selections with new document changes. + for (view, _focused) in self.tree.views_mut() { + let doc = doc_mut!(self, &view.doc); + view.sync_changes(doc); + } } } From 607c74efde40812caa6379a05fcb28f259ea2c8e Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Tue, 29 Nov 2022 10:15:55 -0600 Subject: [PATCH 016/132] Handle disambiguated keycodes (#4887) Media keys are sent despite `DISAMBIGUATE_ESCAPE_CODES` being unset. Previously we panicked on these. This change translates the disambiguated keys from crossterm so that they do not cause a panic. --- helix-view/src/input.rs | 142 ++++++++++++++++++++++++- helix-view/src/keyboard.rs | 205 +++++++++++++++++++++++++++++++++++-- 2 files changed, 335 insertions(+), 12 deletions(-) diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index 30fa72c4..bda0520e 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -4,7 +4,7 @@ use helix_core::unicode::{segmentation::UnicodeSegmentation, width::UnicodeWidth use serde::de::{self, Deserialize, Deserializer}; use std::fmt; -pub use crate::keyboard::{KeyCode, KeyModifiers}; +pub use crate::keyboard::{KeyCode, KeyModifiers, MediaKeyCode, ModifierKeyCode}; #[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)] pub enum Event { @@ -119,6 +119,40 @@ pub(crate) mod keys { pub(crate) const MINUS: &str = "minus"; pub(crate) const LESS_THAN: &str = "lt"; pub(crate) const GREATER_THAN: &str = "gt"; + pub(crate) const CAPS_LOCK: &str = "capslock"; + pub(crate) const SCROLL_LOCK: &str = "scrolllock"; + pub(crate) const NUM_LOCK: &str = "numlock"; + pub(crate) const PRINT_SCREEN: &str = "printscreen"; + pub(crate) const PAUSE: &str = "pause"; + pub(crate) const MENU: &str = "menu"; + pub(crate) const KEYPAD_BEGIN: &str = "keypadbegin"; + pub(crate) const PLAY: &str = "play"; + pub(crate) const PAUSE_MEDIA: &str = "pausemedia"; + pub(crate) const PLAY_PAUSE: &str = "playpause"; + pub(crate) const REVERSE: &str = "reverse"; + pub(crate) const STOP: &str = "stop"; + pub(crate) const FAST_FORWARD: &str = "fastforward"; + pub(crate) const REWIND: &str = "rewind"; + pub(crate) const TRACK_NEXT: &str = "tracknext"; + pub(crate) const TRACK_PREVIOUS: &str = "trackprevious"; + pub(crate) const RECORD: &str = "record"; + pub(crate) const LOWER_VOLUME: &str = "lowervolume"; + pub(crate) const RAISE_VOLUME: &str = "raisevolume"; + pub(crate) const MUTE_VOLUME: &str = "mutevolume"; + pub(crate) const LEFT_SHIFT: &str = "leftshift"; + pub(crate) const LEFT_CONTROL: &str = "leftcontrol"; + pub(crate) const LEFT_ALT: &str = "leftalt"; + pub(crate) const LEFT_SUPER: &str = "leftsuper"; + pub(crate) const LEFT_HYPER: &str = "lefthyper"; + pub(crate) const LEFT_META: &str = "leftmeta"; + pub(crate) const RIGHT_SHIFT: &str = "rightshift"; + pub(crate) const RIGHT_CONTROL: &str = "rightcontrol"; + pub(crate) const RIGHT_ALT: &str = "rightalt"; + pub(crate) const RIGHT_SUPER: &str = "rightsuper"; + pub(crate) const RIGHT_HYPER: &str = "righthyper"; + pub(crate) const RIGHT_META: &str = "rightmeta"; + pub(crate) const ISO_LEVEL_3_SHIFT: &str = "isolevel3shift"; + pub(crate) const ISO_LEVEL_5_SHIFT: &str = "isolevel5shift"; } impl fmt::Display for KeyEvent { @@ -163,6 +197,44 @@ impl fmt::Display for KeyEvent { KeyCode::Char('>') => f.write_str(keys::GREATER_THAN)?, KeyCode::F(i) => f.write_fmt(format_args!("F{}", i))?, KeyCode::Char(c) => f.write_fmt(format_args!("{}", c))?, + KeyCode::CapsLock => f.write_str(keys::CAPS_LOCK)?, + KeyCode::ScrollLock => f.write_str(keys::SCROLL_LOCK)?, + KeyCode::NumLock => f.write_str(keys::NUM_LOCK)?, + KeyCode::PrintScreen => f.write_str(keys::PRINT_SCREEN)?, + KeyCode::Pause => f.write_str(keys::PAUSE)?, + KeyCode::Menu => f.write_str(keys::MENU)?, + KeyCode::KeypadBegin => f.write_str(keys::KEYPAD_BEGIN)?, + KeyCode::Media(MediaKeyCode::Play) => f.write_str(keys::PLAY)?, + KeyCode::Media(MediaKeyCode::Pause) => f.write_str(keys::PAUSE_MEDIA)?, + KeyCode::Media(MediaKeyCode::PlayPause) => f.write_str(keys::PLAY_PAUSE)?, + KeyCode::Media(MediaKeyCode::Stop) => f.write_str(keys::STOP)?, + KeyCode::Media(MediaKeyCode::Reverse) => f.write_str(keys::REVERSE)?, + KeyCode::Media(MediaKeyCode::FastForward) => f.write_str(keys::FAST_FORWARD)?, + KeyCode::Media(MediaKeyCode::Rewind) => f.write_str(keys::REWIND)?, + KeyCode::Media(MediaKeyCode::TrackNext) => f.write_str(keys::TRACK_NEXT)?, + KeyCode::Media(MediaKeyCode::TrackPrevious) => f.write_str(keys::TRACK_PREVIOUS)?, + KeyCode::Media(MediaKeyCode::Record) => f.write_str(keys::RECORD)?, + KeyCode::Media(MediaKeyCode::LowerVolume) => f.write_str(keys::LOWER_VOLUME)?, + KeyCode::Media(MediaKeyCode::RaiseVolume) => f.write_str(keys::RAISE_VOLUME)?, + KeyCode::Media(MediaKeyCode::MuteVolume) => f.write_str(keys::MUTE_VOLUME)?, + KeyCode::Modifier(ModifierKeyCode::LeftShift) => f.write_str(keys::LEFT_SHIFT)?, + KeyCode::Modifier(ModifierKeyCode::LeftControl) => f.write_str(keys::LEFT_CONTROL)?, + KeyCode::Modifier(ModifierKeyCode::LeftAlt) => f.write_str(keys::LEFT_ALT)?, + KeyCode::Modifier(ModifierKeyCode::LeftSuper) => f.write_str(keys::LEFT_SUPER)?, + KeyCode::Modifier(ModifierKeyCode::LeftHyper) => f.write_str(keys::LEFT_HYPER)?, + KeyCode::Modifier(ModifierKeyCode::LeftMeta) => f.write_str(keys::LEFT_META)?, + KeyCode::Modifier(ModifierKeyCode::RightShift) => f.write_str(keys::RIGHT_SHIFT)?, + KeyCode::Modifier(ModifierKeyCode::RightControl) => f.write_str(keys::RIGHT_CONTROL)?, + KeyCode::Modifier(ModifierKeyCode::RightAlt) => f.write_str(keys::RIGHT_ALT)?, + KeyCode::Modifier(ModifierKeyCode::RightSuper) => f.write_str(keys::RIGHT_SUPER)?, + KeyCode::Modifier(ModifierKeyCode::RightHyper) => f.write_str(keys::RIGHT_HYPER)?, + KeyCode::Modifier(ModifierKeyCode::RightMeta) => f.write_str(keys::RIGHT_META)?, + KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift) => { + f.write_str(keys::ISO_LEVEL_3_SHIFT)? + } + KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift) => { + f.write_str(keys::ISO_LEVEL_5_SHIFT)? + } }; Ok(()) } @@ -192,6 +264,40 @@ impl UnicodeWidthStr for KeyEvent { KeyCode::F(1..=9) => 2, KeyCode::F(_) => 3, KeyCode::Char(c) => c.width().unwrap_or(0), + KeyCode::CapsLock => keys::CAPS_LOCK.len(), + KeyCode::ScrollLock => keys::SCROLL_LOCK.len(), + KeyCode::NumLock => keys::NUM_LOCK.len(), + KeyCode::PrintScreen => keys::PRINT_SCREEN.len(), + KeyCode::Pause => keys::PAUSE.len(), + KeyCode::Menu => keys::MENU.len(), + KeyCode::KeypadBegin => keys::KEYPAD_BEGIN.len(), + KeyCode::Media(MediaKeyCode::Play) => keys::PLAY.len(), + KeyCode::Media(MediaKeyCode::Pause) => keys::PAUSE_MEDIA.len(), + KeyCode::Media(MediaKeyCode::PlayPause) => keys::PLAY_PAUSE.len(), + KeyCode::Media(MediaKeyCode::Stop) => keys::STOP.len(), + KeyCode::Media(MediaKeyCode::Reverse) => keys::REVERSE.len(), + KeyCode::Media(MediaKeyCode::FastForward) => keys::FAST_FORWARD.len(), + KeyCode::Media(MediaKeyCode::Rewind) => keys::REWIND.len(), + KeyCode::Media(MediaKeyCode::TrackNext) => keys::TRACK_NEXT.len(), + KeyCode::Media(MediaKeyCode::TrackPrevious) => keys::TRACK_PREVIOUS.len(), + KeyCode::Media(MediaKeyCode::Record) => keys::RECORD.len(), + KeyCode::Media(MediaKeyCode::LowerVolume) => keys::LOWER_VOLUME.len(), + KeyCode::Media(MediaKeyCode::RaiseVolume) => keys::RAISE_VOLUME.len(), + KeyCode::Media(MediaKeyCode::MuteVolume) => keys::MUTE_VOLUME.len(), + KeyCode::Modifier(ModifierKeyCode::LeftShift) => keys::LEFT_SHIFT.len(), + KeyCode::Modifier(ModifierKeyCode::LeftControl) => keys::LEFT_CONTROL.len(), + KeyCode::Modifier(ModifierKeyCode::LeftAlt) => keys::LEFT_ALT.len(), + KeyCode::Modifier(ModifierKeyCode::LeftSuper) => keys::LEFT_SUPER.len(), + KeyCode::Modifier(ModifierKeyCode::LeftHyper) => keys::LEFT_HYPER.len(), + KeyCode::Modifier(ModifierKeyCode::LeftMeta) => keys::LEFT_META.len(), + KeyCode::Modifier(ModifierKeyCode::RightShift) => keys::RIGHT_SHIFT.len(), + KeyCode::Modifier(ModifierKeyCode::RightControl) => keys::RIGHT_CONTROL.len(), + KeyCode::Modifier(ModifierKeyCode::RightAlt) => keys::RIGHT_ALT.len(), + KeyCode::Modifier(ModifierKeyCode::RightSuper) => keys::RIGHT_SUPER.len(), + KeyCode::Modifier(ModifierKeyCode::RightHyper) => keys::RIGHT_HYPER.len(), + KeyCode::Modifier(ModifierKeyCode::RightMeta) => keys::RIGHT_META.len(), + KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift) => keys::ISO_LEVEL_3_SHIFT.len(), + KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift) => keys::ISO_LEVEL_5_SHIFT.len(), }; if self.modifiers.contains(KeyModifiers::SHIFT) { width += 2; @@ -235,6 +341,40 @@ impl std::str::FromStr for KeyEvent { keys::MINUS => KeyCode::Char('-'), keys::LESS_THAN => KeyCode::Char('<'), keys::GREATER_THAN => KeyCode::Char('>'), + keys::CAPS_LOCK => KeyCode::CapsLock, + keys::SCROLL_LOCK => KeyCode::ScrollLock, + keys::NUM_LOCK => KeyCode::NumLock, + keys::PRINT_SCREEN => KeyCode::PrintScreen, + keys::PAUSE => KeyCode::Pause, + keys::MENU => KeyCode::Menu, + keys::KEYPAD_BEGIN => KeyCode::KeypadBegin, + keys::PLAY => KeyCode::Media(MediaKeyCode::Play), + keys::PAUSE_MEDIA => KeyCode::Media(MediaKeyCode::Pause), + keys::PLAY_PAUSE => KeyCode::Media(MediaKeyCode::PlayPause), + keys::STOP => KeyCode::Media(MediaKeyCode::Stop), + keys::REVERSE => KeyCode::Media(MediaKeyCode::Reverse), + keys::FAST_FORWARD => KeyCode::Media(MediaKeyCode::FastForward), + keys::REWIND => KeyCode::Media(MediaKeyCode::Rewind), + keys::TRACK_NEXT => KeyCode::Media(MediaKeyCode::TrackNext), + keys::TRACK_PREVIOUS => KeyCode::Media(MediaKeyCode::TrackPrevious), + keys::RECORD => KeyCode::Media(MediaKeyCode::Record), + keys::LOWER_VOLUME => KeyCode::Media(MediaKeyCode::LowerVolume), + keys::RAISE_VOLUME => KeyCode::Media(MediaKeyCode::RaiseVolume), + keys::MUTE_VOLUME => KeyCode::Media(MediaKeyCode::MuteVolume), + keys::LEFT_SHIFT => KeyCode::Modifier(ModifierKeyCode::LeftShift), + keys::LEFT_CONTROL => KeyCode::Modifier(ModifierKeyCode::LeftControl), + keys::LEFT_ALT => KeyCode::Modifier(ModifierKeyCode::LeftAlt), + keys::LEFT_SUPER => KeyCode::Modifier(ModifierKeyCode::LeftSuper), + keys::LEFT_HYPER => KeyCode::Modifier(ModifierKeyCode::LeftHyper), + keys::LEFT_META => KeyCode::Modifier(ModifierKeyCode::LeftMeta), + keys::RIGHT_SHIFT => KeyCode::Modifier(ModifierKeyCode::RightShift), + keys::RIGHT_CONTROL => KeyCode::Modifier(ModifierKeyCode::RightControl), + keys::RIGHT_ALT => KeyCode::Modifier(ModifierKeyCode::RightAlt), + keys::RIGHT_SUPER => KeyCode::Modifier(ModifierKeyCode::RightSuper), + keys::RIGHT_HYPER => KeyCode::Modifier(ModifierKeyCode::RightHyper), + keys::RIGHT_META => KeyCode::Modifier(ModifierKeyCode::RightMeta), + keys::ISO_LEVEL_3_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift), + keys::ISO_LEVEL_5_SHIFT => KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift), single if single.chars().count() == 1 => KeyCode::Char(single.chars().next().unwrap()), function if function.len() > 1 && function.starts_with('F') => { let function: String = function.chars().skip(1).collect(); diff --git a/helix-view/src/keyboard.rs b/helix-view/src/keyboard.rs index 84cfebf1..cf673e11 100644 --- a/helix-view/src/keyboard.rs +++ b/helix-view/src/keyboard.rs @@ -53,6 +53,164 @@ impl From for KeyModifiers { } } +/// Represents a media key (as part of [`KeyCode::Media`]). +#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)] +pub enum MediaKeyCode { + /// Play media key. + Play, + /// Pause media key. + Pause, + /// Play/Pause media key. + PlayPause, + /// Reverse media key. + Reverse, + /// Stop media key. + Stop, + /// Fast-forward media key. + FastForward, + /// Rewind media key. + Rewind, + /// Next-track media key. + TrackNext, + /// Previous-track media key. + TrackPrevious, + /// Record media key. + Record, + /// Lower-volume media key. + LowerVolume, + /// Raise-volume media key. + RaiseVolume, + /// Mute media key. + MuteVolume, +} + +#[cfg(feature = "term")] +impl From for crossterm::event::MediaKeyCode { + fn from(media_key_code: MediaKeyCode) -> Self { + use crossterm::event::MediaKeyCode as CMediaKeyCode; + + match media_key_code { + MediaKeyCode::Play => CMediaKeyCode::Play, + MediaKeyCode::Pause => CMediaKeyCode::Pause, + MediaKeyCode::PlayPause => CMediaKeyCode::PlayPause, + MediaKeyCode::Reverse => CMediaKeyCode::Reverse, + MediaKeyCode::Stop => CMediaKeyCode::Stop, + MediaKeyCode::FastForward => CMediaKeyCode::FastForward, + MediaKeyCode::Rewind => CMediaKeyCode::Rewind, + MediaKeyCode::TrackNext => CMediaKeyCode::TrackNext, + MediaKeyCode::TrackPrevious => CMediaKeyCode::TrackPrevious, + MediaKeyCode::Record => CMediaKeyCode::Record, + MediaKeyCode::LowerVolume => CMediaKeyCode::LowerVolume, + MediaKeyCode::RaiseVolume => CMediaKeyCode::RaiseVolume, + MediaKeyCode::MuteVolume => CMediaKeyCode::MuteVolume, + } + } +} + +#[cfg(feature = "term")] +impl From for MediaKeyCode { + fn from(val: crossterm::event::MediaKeyCode) -> Self { + use crossterm::event::MediaKeyCode as CMediaKeyCode; + + match val { + CMediaKeyCode::Play => MediaKeyCode::Play, + CMediaKeyCode::Pause => MediaKeyCode::Pause, + CMediaKeyCode::PlayPause => MediaKeyCode::PlayPause, + CMediaKeyCode::Reverse => MediaKeyCode::Reverse, + CMediaKeyCode::Stop => MediaKeyCode::Stop, + CMediaKeyCode::FastForward => MediaKeyCode::FastForward, + CMediaKeyCode::Rewind => MediaKeyCode::Rewind, + CMediaKeyCode::TrackNext => MediaKeyCode::TrackNext, + CMediaKeyCode::TrackPrevious => MediaKeyCode::TrackPrevious, + CMediaKeyCode::Record => MediaKeyCode::Record, + CMediaKeyCode::LowerVolume => MediaKeyCode::LowerVolume, + CMediaKeyCode::RaiseVolume => MediaKeyCode::RaiseVolume, + CMediaKeyCode::MuteVolume => MediaKeyCode::MuteVolume, + } + } +} + +/// Represents a media key (as part of [`KeyCode::Modifier`]). +#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)] +pub enum ModifierKeyCode { + /// Left Shift key. + LeftShift, + /// Left Control key. + LeftControl, + /// Left Alt key. + LeftAlt, + /// Left Super key. + LeftSuper, + /// Left Hyper key. + LeftHyper, + /// Left Meta key. + LeftMeta, + /// Right Shift key. + RightShift, + /// Right Control key. + RightControl, + /// Right Alt key. + RightAlt, + /// Right Super key. + RightSuper, + /// Right Hyper key. + RightHyper, + /// Right Meta key. + RightMeta, + /// Iso Level3 Shift key. + IsoLevel3Shift, + /// Iso Level5 Shift key. + IsoLevel5Shift, +} + +#[cfg(feature = "term")] +impl From for crossterm::event::ModifierKeyCode { + fn from(modifier_key_code: ModifierKeyCode) -> Self { + use crossterm::event::ModifierKeyCode as CModifierKeyCode; + + match modifier_key_code { + ModifierKeyCode::LeftShift => CModifierKeyCode::LeftShift, + ModifierKeyCode::LeftControl => CModifierKeyCode::LeftControl, + ModifierKeyCode::LeftAlt => CModifierKeyCode::LeftAlt, + ModifierKeyCode::LeftSuper => CModifierKeyCode::LeftSuper, + ModifierKeyCode::LeftHyper => CModifierKeyCode::LeftHyper, + ModifierKeyCode::LeftMeta => CModifierKeyCode::LeftMeta, + ModifierKeyCode::RightShift => CModifierKeyCode::RightShift, + ModifierKeyCode::RightControl => CModifierKeyCode::RightControl, + ModifierKeyCode::RightAlt => CModifierKeyCode::RightAlt, + ModifierKeyCode::RightSuper => CModifierKeyCode::RightSuper, + ModifierKeyCode::RightHyper => CModifierKeyCode::RightHyper, + ModifierKeyCode::RightMeta => CModifierKeyCode::RightMeta, + ModifierKeyCode::IsoLevel3Shift => CModifierKeyCode::IsoLevel3Shift, + ModifierKeyCode::IsoLevel5Shift => CModifierKeyCode::IsoLevel5Shift, + } + } +} + +#[cfg(feature = "term")] +impl From for ModifierKeyCode { + fn from(val: crossterm::event::ModifierKeyCode) -> Self { + use crossterm::event::ModifierKeyCode as CModifierKeyCode; + + match val { + CModifierKeyCode::LeftShift => ModifierKeyCode::LeftShift, + CModifierKeyCode::LeftControl => ModifierKeyCode::LeftControl, + CModifierKeyCode::LeftAlt => ModifierKeyCode::LeftAlt, + CModifierKeyCode::LeftSuper => ModifierKeyCode::LeftSuper, + CModifierKeyCode::LeftHyper => ModifierKeyCode::LeftHyper, + CModifierKeyCode::LeftMeta => ModifierKeyCode::LeftMeta, + CModifierKeyCode::RightShift => ModifierKeyCode::RightShift, + CModifierKeyCode::RightControl => ModifierKeyCode::RightControl, + CModifierKeyCode::RightAlt => ModifierKeyCode::RightAlt, + CModifierKeyCode::RightSuper => ModifierKeyCode::RightSuper, + CModifierKeyCode::RightHyper => ModifierKeyCode::RightHyper, + CModifierKeyCode::RightMeta => ModifierKeyCode::RightMeta, + CModifierKeyCode::IsoLevel3Shift => ModifierKeyCode::IsoLevel3Shift, + CModifierKeyCode::IsoLevel5Shift => ModifierKeyCode::IsoLevel5Shift, + } + } +} + /// Represents a key. #[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)] pub enum KeyCode { @@ -94,6 +252,24 @@ pub enum KeyCode { Null, /// Escape key. Esc, + /// CapsLock key. + CapsLock, + /// ScrollLock key. + ScrollLock, + /// NumLock key. + NumLock, + /// PrintScreen key. + PrintScreen, + /// Pause key. + Pause, + /// Menu key. + Menu, + /// KeypadBegin key. + KeypadBegin, + /// A media key. + Media(MediaKeyCode), + /// A modifier key. + Modifier(ModifierKeyCode), } #[cfg(feature = "term")] @@ -119,6 +295,15 @@ impl From for crossterm::event::KeyCode { KeyCode::Char(character) => CKeyCode::Char(character), KeyCode::Null => CKeyCode::Null, KeyCode::Esc => CKeyCode::Esc, + KeyCode::CapsLock => CKeyCode::CapsLock, + KeyCode::ScrollLock => CKeyCode::ScrollLock, + KeyCode::NumLock => CKeyCode::NumLock, + KeyCode::PrintScreen => CKeyCode::PrintScreen, + KeyCode::Pause => CKeyCode::Pause, + KeyCode::Menu => CKeyCode::Menu, + KeyCode::KeypadBegin => CKeyCode::KeypadBegin, + KeyCode::Media(media_key_code) => CKeyCode::Media(media_key_code.into()), + KeyCode::Modifier(modifier_key_code) => CKeyCode::Modifier(modifier_key_code.into()), } } } @@ -147,17 +332,15 @@ impl From for KeyCode { CKeyCode::Char(character) => KeyCode::Char(character), CKeyCode::Null => KeyCode::Null, CKeyCode::Esc => KeyCode::Esc, - CKeyCode::CapsLock - | CKeyCode::ScrollLock - | CKeyCode::NumLock - | CKeyCode::PrintScreen - | CKeyCode::Pause - | CKeyCode::Menu - | CKeyCode::KeypadBegin - | CKeyCode::Media(_) - | CKeyCode::Modifier(_) => unreachable!( - "Shouldn't get this key without enabling DISAMBIGUATE_ESCAPE_CODES in crossterm" - ), + CKeyCode::CapsLock => KeyCode::CapsLock, + CKeyCode::ScrollLock => KeyCode::ScrollLock, + CKeyCode::NumLock => KeyCode::NumLock, + CKeyCode::PrintScreen => KeyCode::PrintScreen, + CKeyCode::Pause => KeyCode::Pause, + CKeyCode::Menu => KeyCode::Menu, + CKeyCode::KeypadBegin => KeyCode::KeypadBegin, + CKeyCode::Media(media_key_code) => KeyCode::Media(media_key_code.into()), + CKeyCode::Modifier(modifier_key_code) => KeyCode::Modifier(modifier_key_code.into()), } } } From 664d08e70d02a3e3917ddc69e66b5fc826a0caf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20S=C3=A1?= Date: Tue, 29 Nov 2022 23:30:06 +0000 Subject: [PATCH 017/132] Fix ayu theme cursor issue (#4764) --- runtime/themes/ayu_dark.toml | 3 +-- runtime/themes/ayu_light.toml | 3 +-- runtime/themes/ayu_mirage.toml | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/runtime/themes/ayu_dark.toml b/runtime/themes/ayu_dark.toml index 3b989f82..b297a3ab 100644 --- a/runtime/themes/ayu_dark.toml +++ b/runtime/themes/ayu_dark.toml @@ -10,7 +10,6 @@ "string.regexp" = "orange" "string.special" = "yellow" "comment" = { fg = "gray", modifiers = ["italic"] } -"comment.block.documentation" = { fg = "blue", modifiers = ["italic"] } "variable" = "foreground" "label" = "orange" "punctuation" = "foreground" @@ -34,7 +33,7 @@ # Interface "ui.background"= { bg = "background" } -"ui.cursor" = { modifiers = ["reversed"] } +"ui.cursor" = { fg = "dark_gray", bg = "orange" } "ui.cursor.match" = "orange" "ui.linenr" = "dark_gray" "ui.linenr.selected" = "gray" diff --git a/runtime/themes/ayu_light.toml b/runtime/themes/ayu_light.toml index 6a801951..ab0283fb 100644 --- a/runtime/themes/ayu_light.toml +++ b/runtime/themes/ayu_light.toml @@ -10,7 +10,6 @@ "string.regexp" = "orange" "string.special" = "yellow" "comment" = { fg = "gray", modifiers = ["italic"] } -"comment.block.documentation" = { fg = "blue", modifiers = ["italic"] } "variable" = "foreground" "label" = "orange" "punctuation" = "foreground" @@ -34,7 +33,7 @@ # Interface "ui.background"= { bg = "background" } -"ui.cursor" = { modifiers = ["reversed"] } +"ui.cursor" = { fg = "dark_gray", bg = "orange" } "ui.cursor.match" = "orange" "ui.linenr" = "dark_gray" "ui.linenr.selected" = "gray" diff --git a/runtime/themes/ayu_mirage.toml b/runtime/themes/ayu_mirage.toml index b1abd9a3..d6af12fa 100644 --- a/runtime/themes/ayu_mirage.toml +++ b/runtime/themes/ayu_mirage.toml @@ -10,7 +10,6 @@ "string.regexp" = "orange" "string.special" = "yellow" "comment" = { fg = "gray", modifiers = ["italic"] } -"comment.block.documentation" = { fg = "blue", modifiers = ["italic"] } "variable" = "foreground" "label" = "orange" "punctuation" = "foreground" @@ -34,7 +33,7 @@ # Interface "ui.background"= { bg = "background" } -"ui.cursor" = { modifiers = ["reversed"] } +"ui.cursor" = { fg = "dark_gray", bg = "orange" } "ui.cursor.match" = "orange" "ui.linenr" = "dark_gray" "ui.linenr.selected" = "gray" From 67415e096ea70173d30550803559eb2347ed04d6 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 30 Nov 2022 08:27:08 -0600 Subject: [PATCH 018/132] Fix file-types declaration for racket (#4915) Both the racket and scheme entries used the rkt file-extension. This commit removes that entry for scheme and so that the racket entry takes precedence. We explicitly point to the scheme grammar now and setup queries that inherit from scheme. This should enable using the racket language server configuration. --- book/src/generated/lang-support.md | 2 +- languages.toml | 3 ++- runtime/queries/racket/highlights.scm | 1 + runtime/queries/racket/injections.scm | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 runtime/queries/racket/highlights.scm create mode 100644 runtime/queries/racket/injections.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 487057e6..b1fde001 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -95,7 +95,7 @@ | python | ✓ | ✓ | ✓ | `pylsp` | | qml | ✓ | | ✓ | `qmlls` | | r | ✓ | | | `R` | -| racket | | | | `racket` | +| racket | ✓ | | | `racket` | | regex | ✓ | | | | | rescript | ✓ | ✓ | | `rescript-language-server` | | rmarkdown | ✓ | | ✓ | `R` | diff --git a/languages.toml b/languages.toml index 756315cd..4eb8a4da 100644 --- a/languages.toml +++ b/languages.toml @@ -880,6 +880,7 @@ file-types = ["rkt"] shebangs = ["racket"] comment-token = ";" language-server = { command = "racket", args = ["-l", "racket-langserver"] } +grammar = "scheme" [[language]] name = "comment" @@ -1526,7 +1527,7 @@ source = { git = "https://github.com/metio/tree-sitter-ssh-client-config", rev = name = "scheme" scope = "source.scheme" injection-regex = "scheme" -file-types = ["ss", "rkt"] # "scm", +file-types = ["ss"] # "scm", roots = [] comment-token = ";" indent = { tab-width = 2, unit = " " } diff --git a/runtime/queries/racket/highlights.scm b/runtime/queries/racket/highlights.scm new file mode 100644 index 00000000..e11eb788 --- /dev/null +++ b/runtime/queries/racket/highlights.scm @@ -0,0 +1 @@ +; inherits: scheme diff --git a/runtime/queries/racket/injections.scm b/runtime/queries/racket/injections.scm new file mode 100644 index 00000000..e11eb788 --- /dev/null +++ b/runtime/queries/racket/injections.scm @@ -0,0 +1 @@ +; inherits: scheme From 5a3ff742218aac32c3af08993f0edb623631fc72 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Thu, 1 Dec 2022 09:35:23 +0100 Subject: [PATCH 019/132] Show (git) diff signs in gutter (#3890) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Show (git) diff signs in gutter (#3890) Avoid string allocation when git diffing Incrementally diff using changesets refactor diffs to be provider indepndent and improve git implementation remove dependency on zlib-ng switch to asynchronus diffing with similar Update helix-vcs/Cargo.toml fix toml formatting Co-authored-by: Ivan Tham fix typo in documentation use ropey reexpors from helix-core fix crash when creating new file remove useless use if io::Cursor fix spelling mistakes implement suggested improvement to repository loading improve git test isolation remove lefover comments Co-authored-by: univerz fixed spelling mistake minor cosmetic changes fix: set self.differ to None if decoding the diff_base fails fixup formatting Co-authored-by: Ivan Tham reload diff_base when file is reloaded from disk switch to imara-diff Fixup formatting Co-authored-by: Blaž Hrastnik Redraw buffer whenever a diff is updated. Only store hunks instead of changes for individual lines to easily allow jumping between them Update to latest gitoxide version Change default diff gutter position Only update gutter after timeout * update diff gutter synchronously, with a timeout * Apply suggestions from code review Co-authored-by: Blaž Hrastnik Co-authored-by: Michael Davis * address review comments and ensure lock is always aquired * remove configuration for redraw timeout Co-authored-by: Blaž Hrastnik Co-authored-by: Michael Davis --- Cargo.lock | 878 +++++++++++++++++++++++++++++- Cargo.toml | 1 + book/src/configuration.md | 2 +- helix-core/src/lib.rs | 2 +- helix-term/Cargo.toml | 3 + helix-term/src/application.rs | 50 +- helix-term/src/commands/typed.rs | 11 +- helix-term/src/ui/editor.rs | 2 +- helix-vcs/Cargo.toml | 28 + helix-vcs/src/diff.rs | 198 +++++++ helix-vcs/src/diff/line_cache.rs | 130 +++++ helix-vcs/src/diff/worker.rs | 207 +++++++ helix-vcs/src/diff/worker/test.rs | 149 +++++ helix-vcs/src/git.rs | 80 +++ helix-vcs/src/git/test.rs | 121 ++++ helix-vcs/src/lib.rs | 51 ++ helix-view/Cargo.toml | 2 + helix-view/src/document.rs | 52 +- helix-view/src/editor.rs | 75 ++- helix-view/src/gutter.rs | 55 +- helix-view/src/view.rs | 15 +- 21 files changed, 2036 insertions(+), 76 deletions(-) create mode 100644 helix-vcs/Cargo.toml create mode 100644 helix-vcs/src/diff.rs create mode 100644 helix-vcs/src/diff/line_cache.rs create mode 100644 helix-vcs/src/diff/worker.rs create mode 100644 helix-vcs/src/diff/worker/test.rs create mode 100644 helix-vcs/src/git.rs create mode 100644 helix-vcs/src/git/test.rs create mode 100644 helix-vcs/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 05a0396f..2e021197 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.7.6" @@ -55,6 +61,15 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -78,12 +93,43 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "bstr" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca0852af221f458706eb0725c03e4ed6c46af9ac98e6a689d5e634215d594dd" +dependencies = [ + "memchr", + "once_cell", + "regex-automata", + "serde", +] + +[[package]] +name = "btoi" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97c0869a9faa81f8bbf8102371105d6d0a7b79167a04c340b04ab16892246a11" +dependencies = [ + "num-traits", +] + [[package]] name = "bumpalo" version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +[[package]] +name = "byte-unit" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581ad4b3d627b0c09a0ccb2912148f839acaca0b93cf54cbe42b6c674e86079c" +dependencies = [ + "serde", + "utf8-width", +] + [[package]] name = "bytecount" version = "0.6.3" @@ -96,12 +142,27 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +[[package]] +name = "bytesize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c58ec36aac5066d5ca17df51b3e70279f5670a72102f5752cb7e7c856adfc70" + [[package]] name = "cassowary" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +[[package]] +name = "castaway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +dependencies = [ + "rustversion", +] + [[package]] name = "cc" version = "1.0.77" @@ -148,6 +209,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "clru" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "218d6bd3dde8e442a975fa1cd233c0e5fded7596bccfe39f58eca98d22421e0a" + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -158,6 +225,17 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "compact_str" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5138945395949e7dfba09646dc9e766b548ff48e23deb5246890e6b64ae9e1b9" +dependencies = [ + "castaway", + "itoa", + "ryu", +] + [[package]] name = "content_inspector" version = "0.2.4" @@ -173,6 +251,15 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-utils" version = "0.8.14" @@ -252,6 +339,28 @@ dependencies = [ "syn", ] +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown 0.12.3", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -262,6 +371,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -336,6 +456,28 @@ dependencies = [ "log", ] +[[package]] +name = "filetime" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys", +] + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -407,6 +549,498 @@ dependencies = [ "wasi", ] +[[package]] +name = "git-actor" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d4ce09c0a6c71c044700e5932877667f427f007b77e6c39ab49aebc4719e25" +dependencies = [ + "bstr 1.0.1", + "btoi", + "git-date", + "itoa", + "nom", + "quick-error", +] + +[[package]] +name = "git-attributes" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c62e66a042c6b39c6dbfa3be37d134900d99ff9c54bbe489ed560a573895d5d" +dependencies = [ + "bstr 1.0.1", + "compact_str", + "git-features", + "git-glob", + "git-path", + "git-quote", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "git-bitmap" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327098a7ad27ae298d7e71602dbd4375cc828d755d10a720e4be0be1b4ec38f0" +dependencies = [ + "quick-error", +] + +[[package]] +name = "git-chunk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b2bc1635b660ad6e30379a84a4946590a3c124b747107c2cca1d9dbb98f588" +dependencies = [ + "thiserror", +] + +[[package]] +name = "git-command" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e4b01997b6551554fdac6f02277d0d04c3e869daa649bedd06d38c86f11dc42" +dependencies = [ + "bstr 1.0.1", +] + +[[package]] +name = "git-config" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd8603e953bd4c9bf310e74e43697400f5542f1cc75fad46fbd7427135a9534f" +dependencies = [ + "bstr 1.0.1", + "git-config-value", + "git-features", + "git-glob", + "git-path", + "git-ref", + "git-sec", + "memchr", + "nom", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "git-config-value" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f276bfe5806b414915112f1eec0f006206cdf5b8cc9bbb44ef7e52286dc3eb" +dependencies = [ + "bitflags", + "bstr 1.0.1", + "git-path", + "libc", + "thiserror", +] + +[[package]] +name = "git-credentials" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f540186ea56fd075ba2b923180ebf4318e66ceaeac0a2a518e75dab8517d339" +dependencies = [ + "bstr 1.0.1", + "git-command", + "git-config-value", + "git-path", + "git-prompt", + "git-sec", + "git-url", + "thiserror", +] + +[[package]] +name = "git-date" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37881e9725df41e15d16216d3a0cee251fd8a39d425f75b389112df5c7f20f3d" +dependencies = [ + "bstr 1.0.1", + "itoa", + "thiserror", + "time", +] + +[[package]] +name = "git-diff" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a88666a0ae4365b55a0cbf2efde68d2a4cff0747894ad229403bd60b0b2abc5" +dependencies = [ + "git-hash", + "git-object", + "imara-diff", + "thiserror", +] + +[[package]] +name = "git-discover" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881e4136d5599cfdb79d8ef60d650823d1a563589fa493d8e4961e64d78a79f2" +dependencies = [ + "bstr 1.0.1", + "git-hash", + "git-path", + "git-ref", + "git-sec", + "thiserror", +] + +[[package]] +name = "git-features" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be88ae837674c71b30c6517c6f5f1335f8135bb8a9ffef20000d211933bed08" +dependencies = [ + "crc32fast", + "flate2", + "git-hash", + "libc", + "once_cell", + "prodash", + "quick-error", + "sha1_smol", + "walkdir", +] + +[[package]] +name = "git-glob" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d756430237112f8c89049236f60fdcdb0005127b1f7e531d40984e4fe7daa90" +dependencies = [ + "bitflags", + "bstr 1.0.1", +] + +[[package]] +name = "git-hash" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d46e6c2d1e8da4438a87bf516a6761b300964a353541fea61e96b3c7b34554" +dependencies = [ + "hex", + "thiserror", +] + +[[package]] +name = "git-index" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "821583c2d12b1e864694eb0bf1cca10ff6a3f45966f5f834e0f921b496dbe7cb" +dependencies = [ + "atoi", + "bitflags", + "bstr 1.0.1", + "filetime", + "git-bitmap", + "git-features", + "git-hash", + "git-lock", + "git-object", + "git-traverse", + "itoa", + "memmap2", + "smallvec", + "thiserror", +] + +[[package]] +name = "git-lock" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0fe10bf961f62b1335b4c07785e64fb4d86c5ed367dc7cd9360f13c3eb7c78" +dependencies = [ + "fastrand", + "git-tempfile", + "quick-error", +] + +[[package]] +name = "git-mailmap" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb3f85ce84b2328aeb3124a809f7b3a63e59c4d63c227dba7a9cdf6fca6c0987" +dependencies = [ + "bstr 1.0.1", + "git-actor", + "quick-error", +] + +[[package]] +name = "git-object" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9469a8c00d8bb500ee76a12e455bb174b4ddf71674713335dd1a84313723f7b3" +dependencies = [ + "bstr 1.0.1", + "btoi", + "git-actor", + "git-features", + "git-hash", + "git-validate", + "hex", + "itoa", + "nom", + "smallvec", + "thiserror", +] + +[[package]] +name = "git-odb" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaaea7031ac7d8dfee232a16d7114395d118226214fb03fe4e15d1f4d62a88a6" +dependencies = [ + "arc-swap", + "git-features", + "git-hash", + "git-object", + "git-pack", + "git-path", + "git-quote", + "parking_lot", + "tempfile", + "thiserror", +] + +[[package]] +name = "git-pack" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc4386dff835ffdc3697c3558111f708fd7b7695c42a4347f2d211cf3246c8e1" +dependencies = [ + "bytesize", + "clru", + "dashmap", + "git-chunk", + "git-diff", + "git-features", + "git-hash", + "git-object", + "git-path", + "git-tempfile", + "git-traverse", + "hash_hasher", + "memmap2", + "parking_lot", + "smallvec", + "thiserror", +] + +[[package]] +name = "git-path" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "425dc1022690be13e6c5bde4b7e04d9504d323605ec314cd367cebf38a812572" +dependencies = [ + "bstr 1.0.1", + "thiserror", +] + +[[package]] +name = "git-prompt" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa6947935c0671342277bc883ff0687978477b570c1ffe2200b9ba5ac8afdd9f" +dependencies = [ + "git-command", + "git-config-value", + "nix", + "parking_lot", + "thiserror", +] + +[[package]] +name = "git-quote" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea17931d07cbe447f371bbdf45ff03c30ea86db43788166655a5302df87ecfc" +dependencies = [ + "bstr 1.0.1", + "btoi", + "quick-error", +] + +[[package]] +name = "git-ref" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "638c9e454bacb2965a43f05b4a383c8f66dc64f3a770bd0324b221c2a20e121d" +dependencies = [ + "git-actor", + "git-features", + "git-hash", + "git-lock", + "git-object", + "git-path", + "git-tempfile", + "git-validate", + "memmap2", + "nom", + "thiserror", +] + +[[package]] +name = "git-refspec" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9497af773538ae8cfda053ff7dd0a9e6c28d333ba653040f54b8b4ee32f14187" +dependencies = [ + "bstr 1.0.1", + "git-hash", + "git-revision", + "git-validate", + "smallvec", + "thiserror", +] + +[[package]] +name = "git-repository" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeb43e59612e493af6a433bf0a960de0042c8aa6f4e4c4cb414f03b97e296b82" +dependencies = [ + "byte-unit", + "clru", + "git-actor", + "git-attributes", + "git-config", + "git-credentials", + "git-date", + "git-diff", + "git-discover", + "git-features", + "git-glob", + "git-hash", + "git-index", + "git-lock", + "git-mailmap", + "git-object", + "git-odb", + "git-pack", + "git-path", + "git-prompt", + "git-ref", + "git-refspec", + "git-revision", + "git-sec", + "git-tempfile", + "git-traverse", + "git-url", + "git-validate", + "git-worktree", + "log", + "once_cell", + "signal-hook", + "smallvec", + "thiserror", + "unicode-normalization", +] + +[[package]] +name = "git-revision" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efd31c63c3745b5dba5ec7109eec41a9c717f4e1e797fe0ef93098f33f31b25" +dependencies = [ + "bstr 1.0.1", + "git-date", + "git-hash", + "git-object", + "hash_hasher", + "thiserror", +] + +[[package]] +name = "git-sec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c79769f6546814d0774db7295c768441016b7e40bdd414fa8dfae2c616a1892" +dependencies = [ + "bitflags", + "dirs", + "git-path", + "libc", + "windows", +] + +[[package]] +name = "git-tempfile" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d23bc6129de3cbd81e6c9d0d685b5540c6b41bd9fa0cc38f381bc300743d708" +dependencies = [ + "dashmap", + "libc", + "once_cell", + "signal-hook", + "signal-hook-registry", + "tempfile", +] + +[[package]] +name = "git-traverse" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d0c4dd773c69f294f43ace8373d48eb770129791f104c6857fa8cac0505af89" +dependencies = [ + "git-hash", + "git-object", + "hash_hasher", + "thiserror", +] + +[[package]] +name = "git-url" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b7f8323196840e7932f5b60e1d9c1d6c140fd806bc512f8beedc3f990a1f81" +dependencies = [ + "bstr 1.0.1", + "git-features", + "git-path", + "home", + "thiserror", + "url", +] + +[[package]] +name = "git-validate" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5439d6aa0de838dfadd74a71e97a9e23ebc719fd11a9ab6788b835b112c8c3d" +dependencies = [ + "bstr 1.0.1", + "thiserror", +] + +[[package]] +name = "git-worktree" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45bcc69c36a29cfa283710b7901877ab251d658935f5a41ed824416af500e0ed" +dependencies = [ + "bstr 1.0.1", + "git-attributes", + "git-features", + "git-glob", + "git-hash", + "git-index", + "git-object", + "git-path", + "io-close", + "thiserror", +] + [[package]] name = "globset" version = "0.4.9" @@ -414,7 +1048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" dependencies = [ "aho-corasick", - "bstr", + "bstr 0.2.17", "fnv", "log", "regex", @@ -436,7 +1070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1345f8d33c89f2d5b081f2f2a41175adef9fd0bed2fea6a26c96c2deb027e58e" dependencies = [ "aho-corasick", - "bstr", + "bstr 0.2.17", "grep-matcher", "log", "regex", @@ -450,7 +1084,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48852bd08f9b4eb3040ecb6d2f4ade224afe880a9a0909c5563cc59fa67932cc" dependencies = [ - "bstr", + "bstr 0.2.17", "bytecount", "encoding_rs", "encoding_rs_io", @@ -459,6 +1093,12 @@ dependencies = [ "memmap2", ] +[[package]] +name = "hash_hasher" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74721d007512d0cb3338cd20f0654ac913920061a4c4d0d8708edb3f2a698c0c" + [[package]] name = "hashbrown" version = "0.12.3" @@ -576,6 +1216,7 @@ dependencies = [ "helix-loader", "helix-lsp", "helix-tui", + "helix-vcs", "helix-view", "ignore", "indoc", @@ -608,6 +1249,19 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "helix-vcs" +version = "0.6.0" +dependencies = [ + "git-repository", + "helix-core", + "imara-diff", + "log", + "parking_lot", + "tempfile", + "tokio", +] + [[package]] name = "helix-view" version = "0.6.0" @@ -624,6 +1278,7 @@ dependencies = [ "helix-loader", "helix-lsp", "helix-tui", + "helix-vcs", "log", "once_cell", "serde", @@ -645,6 +1300,27 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "home" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408" +dependencies = [ + "winapi", +] + +[[package]] +name = "human_format" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86cce260d758a9aa3d7c4b99d55c815a540f8a37514ba6046ab6be402a157cb0" + [[package]] name = "iana-time-zone" version = "0.1.53" @@ -722,6 +1398,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-close" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "itoa" version = "1.0.4" @@ -815,6 +1501,21 @@ dependencies = [ "libc", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.5" @@ -827,6 +1528,28 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nix" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -856,6 +1579,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.16.0" @@ -912,6 +1644,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prodash" +version = "21.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e13d7bd38cdab08b3a8b780cedcc54238c84fdca4084eb188807b308bcf11e6" +dependencies = [ + "bytesize", + "human_format", +] + [[package]] name = "pulldown-cmark" version = "0.9.2" @@ -923,6 +1665,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quickcheck" version = "1.0.3" @@ -1021,6 +1769,12 @@ dependencies = [ "str_indices", ] +[[package]] +name = "rustversion" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" + [[package]] name = "ryu" version = "1.0.11" @@ -1090,6 +1844,12 @@ dependencies = [ "syn", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "signal-hook" version = "0.3.14" @@ -1293,6 +2053,35 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1384,6 +2173,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +[[package]] +name = "unicode-bom" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63ec69f541d875b783ca40184d655f2927c95f0bffd486faa83cd3ac3529ec32" + [[package]] name = "unicode-general-category" version = "0.6.0" @@ -1439,6 +2234,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" + [[package]] name = "version_check" version = "0.9.4" @@ -1558,57 +2359,114 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e30acc718a52fb130fec72b1cb5f55ffeeec9253e1b785e94db222178a6acaa1" +dependencies = [ + "windows_aarch64_gnullvm 0.40.0", + "windows_aarch64_msvc 0.40.0", + "windows_i686_gnu 0.40.0", + "windows_i686_msvc 0.40.0", + "windows_x86_64_gnu 0.40.0", + "windows_x86_64_gnullvm 0.40.0", + "windows_x86_64_msvc 0.40.0", +] + [[package]] name = "windows-sys" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.0", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm 0.42.0", + "windows_x86_64_msvc 0.42.0", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3caa4a1a16561b714323ca6b0817403738583033a6a92e04c5d10d4ba37ca10" + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +[[package]] +name = "windows_aarch64_msvc" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328973c62dfcc50fb1aaa8e7100676e0b642fe56bac6bafff3327902db843ab4" + [[package]] name = "windows_aarch64_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +[[package]] +name = "windows_i686_gnu" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa5b09fad70f0df85dea2ac2a525537e415e2bf63ee31cf9b8e263645ee9f3c1" + [[package]] name = "windows_i686_gnu" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +[[package]] +name = "windows_i686_msvc" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1ad4031c1a98491fa195d8d43d7489cb749f135f2e5c4eed58da094bd0d876" + [[package]] name = "windows_i686_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +[[package]] +name = "windows_x86_64_gnu" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520ff37edd72da8064b49d2281182898e17f0688ae9f4070bca27e4b5c162ac7" + [[package]] name = "windows_x86_64_gnu" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046e5b82215102c44fd75f488f1b9158973d02aa34d06ed85c23d6f5520a2853" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +[[package]] +name = "windows_x86_64_msvc" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0c9c6df55dd1bfa76e131cef44bdd8ec9c819ef3611f04dfe453fd5bfeda28" + [[package]] name = "windows_x86_64_msvc" version = "0.42.0" diff --git a/Cargo.toml b/Cargo.toml index 9e985ddc..ecf6848e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "helix-lsp", "helix-dap", "helix-loader", + "helix-vcs", "xtask", ] diff --git a/book/src/configuration.md b/book/src/configuration.md index e4854cda..0890d283 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -46,7 +46,7 @@ on unix operating systems. | `line-number` | Line number display: `absolute` simply shows each line's number, while `relative` shows the distance from the current line. When unfocused or in insert mode, `relative` will still show absolute line numbers. | `absolute` | | `cursorline` | Highlight all lines with a cursor. | `false` | | `cursorcolumn` | Highlight all columns with a cursor. | `false` | -| `gutters` | Gutters to display: Available are `diagnostics` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "spacer", "line-numbers"]` | +| `gutters` | Gutters to display: Available are `diagnostics` and `diff` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "spacer", "line-numbers", "spacer", "diff"]` | | `auto-completion` | Enable automatic pop up of auto-completion. | `true` | | `auto-format` | Enable automatic formatting on save. | `true` | | `auto-save` | Enable automatic saving on focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal. | `false` | diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 5f60c048..0e76ebbb 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -83,7 +83,7 @@ pub fn find_root(root: Option<&str>, root_markers: &[String]) -> std::path::Path top_marker.map_or(current_dir, |a| a.to_path_buf()) } -pub use ropey::{str_utils, Rope, RopeBuilder, RopeSlice}; +pub use ropey::{self, str_utils, Rope, RopeBuilder, RopeSlice}; // pub use tendril::StrTendril as Tendril; pub use smartstring::SmartString; diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 485cabe9..30bfc7ea 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -17,8 +17,10 @@ build = true app = true [features] +default = ["git"] unicode-lines = ["helix-core/unicode-lines"] integration = [] +git = ["helix-vcs/git"] [[bin]] name = "hx" @@ -29,6 +31,7 @@ helix-core = { version = "0.6", path = "../helix-core" } helix-view = { version = "0.6", path = "../helix-view" } helix-lsp = { version = "0.6", path = "../helix-lsp" } helix-dap = { version = "0.6", path = "../helix-dap" } +helix-vcs = { version = "0.6", path = "../helix-vcs" } helix-loader = { version = "0.6", path = "../helix-loader" } anyhow = "1" diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 99d3af18..dc12ba3c 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -274,16 +274,27 @@ impl Application { } #[cfg(feature = "integration")] - fn render(&mut self) {} + async fn render(&mut self) {} #[cfg(not(feature = "integration"))] - fn render(&mut self) { + async fn render(&mut self) { let mut cx = crate::compositor::Context { editor: &mut self.editor, jobs: &mut self.jobs, scroll: None, }; + // Acquire mutable access to the redraw_handle lock + // to ensure that there are no tasks running that want to block rendering + drop(cx.editor.redraw_handle.1.write().await); + cx.editor.needs_redraw = false; + { + // exhaust any leftover redraw notifications + let notify = cx.editor.redraw_handle.0.notified(); + tokio::pin!(notify); + notify.enable(); + } + let area = self .terminal .autoresize() @@ -304,7 +315,7 @@ impl Application { where S: Stream> + Unpin, { - self.render(); + self.render().await; self.last_render = Instant::now(); loop { @@ -329,18 +340,18 @@ impl Application { biased; Some(event) = input_stream.next() => { - self.handle_terminal_events(event); + self.handle_terminal_events(event).await; } Some(signal) = self.signals.next() => { self.handle_signals(signal).await; } Some(callback) = self.jobs.futures.next() => { self.jobs.handle_callback(&mut self.editor, &mut self.compositor, callback); - self.render(); + self.render().await; } Some(callback) = self.jobs.wait_futures.next() => { self.jobs.handle_callback(&mut self.editor, &mut self.compositor, callback); - self.render(); + self.render().await; } event = self.editor.wait_event() => { let _idle_handled = self.handle_editor_event(event).await; @@ -445,25 +456,25 @@ impl Application { self.compositor.resize(area); self.terminal.clear().expect("couldn't clear terminal"); - self.render(); + self.render().await; } signal::SIGUSR1 => { self.refresh_config(); - self.render(); + self.render().await; } _ => unreachable!(), } } - pub fn handle_idle_timeout(&mut self) { + pub async fn handle_idle_timeout(&mut self) { let mut cx = crate::compositor::Context { editor: &mut self.editor, jobs: &mut self.jobs, scroll: None, }; let should_render = self.compositor.handle_event(&Event::IdleTimeout, &mut cx); - if should_render { - self.render(); + if should_render || self.editor.needs_redraw { + self.render().await; } } @@ -536,11 +547,11 @@ impl Application { match event { EditorEvent::DocumentSaved(event) => { self.handle_document_write(event); - self.render(); + self.render().await; } EditorEvent::ConfigEvent(event) => { self.handle_config_events(event); - self.render(); + self.render().await; } EditorEvent::LanguageServerMessage((id, call)) => { self.handle_language_server_message(call, id).await; @@ -548,19 +559,19 @@ impl Application { let last = self.editor.language_servers.incoming.is_empty(); if last || self.last_render.elapsed() > LSP_DEADLINE { - self.render(); + self.render().await; self.last_render = Instant::now(); } } EditorEvent::DebuggerEvent(payload) => { let needs_render = self.editor.handle_debugger_message(payload).await; if needs_render { - self.render(); + self.render().await; } } EditorEvent::IdleTimer => { self.editor.clear_idle_timer(); - self.handle_idle_timeout(); + self.handle_idle_timeout().await; #[cfg(feature = "integration")] { @@ -572,7 +583,10 @@ impl Application { false } - pub fn handle_terminal_events(&mut self, event: Result) { + pub async fn handle_terminal_events( + &mut self, + event: Result, + ) { let mut cx = crate::compositor::Context { editor: &mut self.editor, jobs: &mut self.jobs, @@ -596,7 +610,7 @@ impl Application { }; if should_redraw && !self.editor.should_close() { - self.render(); + self.render().await; } } diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 2fa903a7..9f848efd 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1028,10 +1028,12 @@ fn reload( } let scrolloff = cx.editor.config().scrolloff; + let redraw_handle = cx.editor.redraw_handle.clone(); let (view, doc) = current!(cx.editor); - doc.reload(view).map(|_| { - view.ensure_cursor_in_view(doc, scrolloff); - }) + doc.reload(view, &cx.editor.diff_providers, redraw_handle) + .map(|_| { + view.ensure_cursor_in_view(doc, scrolloff); + }) } fn reload_all( @@ -1066,7 +1068,8 @@ fn reload_all( // Every doc is guaranteed to have at least 1 view at this point. let view = view_mut!(cx.editor, view_ids[0]); - doc.reload(view)?; + let redraw_handle = cx.editor.redraw_handle.clone(); + doc.reload(view, &cx.editor.diff_providers, redraw_handle)?; for view_id in view_ids { let view = view_mut!(cx.editor, view_id); diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 7bda74d2..32c8fe91 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -730,7 +730,7 @@ impl EditorView { let mut text = String::with_capacity(8); for gutter_type in view.gutters() { - let gutter = gutter_type.style(editor, doc, view, theme, is_focused); + let mut gutter = gutter_type.style(editor, doc, view, theme, is_focused); let width = gutter_type.width(view, doc); text.reserve(width); // ensure there's enough space for the gutter for (i, line) in (view.offset.row..(last_line + 1)).enumerate() { diff --git a/helix-vcs/Cargo.toml b/helix-vcs/Cargo.toml new file mode 100644 index 00000000..c114666d --- /dev/null +++ b/helix-vcs/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "helix-vcs" +version = "0.6.0" +authors = ["Blaž Hrastnik "] +edition = "2021" +license = "MPL-2.0" +categories = ["editor"] +repository = "https://github.com/helix-editor/helix" +homepage = "https://helix-editor.com" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +helix-core = { version = "0.6", path = "../helix-core" } + +tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] } +parking_lot = "0.12" + +git-repository = { version = "0.26", default-features = false , optional = true } +imara-diff = "0.1.5" + +log = "0.4" + +[features] +git = ["git-repository"] + +[dev-dependencies] +tempfile = "3.3" \ No newline at end of file diff --git a/helix-vcs/src/diff.rs b/helix-vcs/src/diff.rs new file mode 100644 index 00000000..b1acd1f2 --- /dev/null +++ b/helix-vcs/src/diff.rs @@ -0,0 +1,198 @@ +use std::ops::Range; +use std::sync::Arc; + +use helix_core::Rope; +use imara_diff::Algorithm; +use parking_lot::{Mutex, MutexGuard}; +use tokio::sync::mpsc::{unbounded_channel, UnboundedSender}; +use tokio::sync::{Notify, OwnedRwLockReadGuard, RwLock}; +use tokio::task::JoinHandle; +use tokio::time::Instant; + +use crate::diff::worker::DiffWorker; + +mod line_cache; +mod worker; + +type RedrawHandle = (Arc, Arc>); + +/// A rendering lock passed to the differ the prevents redraws from occurring +struct RenderLock { + pub lock: OwnedRwLockReadGuard<()>, + pub timeout: Option, +} + +struct Event { + text: Rope, + is_base: bool, + render_lock: Option, +} + +#[derive(Clone, Debug)] +pub struct DiffHandle { + channel: UnboundedSender, + render_lock: Arc>, + hunks: Arc>>, + inverted: bool, +} + +impl DiffHandle { + pub fn new(diff_base: Rope, doc: Rope, redraw_handle: RedrawHandle) -> DiffHandle { + DiffHandle::new_with_handle(diff_base, doc, redraw_handle).0 + } + + fn new_with_handle( + diff_base: Rope, + doc: Rope, + redraw_handle: RedrawHandle, + ) -> (DiffHandle, JoinHandle<()>) { + let (sender, receiver) = unbounded_channel(); + let hunks: Arc>> = Arc::default(); + let worker = DiffWorker { + channel: receiver, + hunks: hunks.clone(), + new_hunks: Vec::default(), + redraw_notify: redraw_handle.0, + diff_finished_notify: Arc::default(), + }; + let handle = tokio::spawn(worker.run(diff_base, doc)); + let differ = DiffHandle { + channel: sender, + hunks, + inverted: false, + render_lock: redraw_handle.1, + }; + (differ, handle) + } + + pub fn invert(&mut self) { + self.inverted = !self.inverted; + } + + pub fn hunks(&self) -> FileHunks { + FileHunks { + hunks: self.hunks.lock(), + inverted: self.inverted, + } + } + + /// Updates the document associated with this redraw handle + /// This function is only intended to be called from within the rendering loop + /// if called from elsewhere it may fail to acquire the render lock and panic + pub fn update_document(&self, doc: Rope, block: bool) -> bool { + // unwrap is ok here because the rendering lock is + // only exclusively locked during redraw. + // This function is only intended to be called + // from the core rendering loop where no redraw can happen in parallel + let lock = self.render_lock.clone().try_read_owned().unwrap(); + let timeout = if block { + None + } else { + Some(Instant::now() + tokio::time::Duration::from_millis(SYNC_DIFF_TIMEOUT)) + }; + self.update_document_impl(doc, self.inverted, Some(RenderLock { lock, timeout })) + } + + pub fn update_diff_base(&self, diff_base: Rope) -> bool { + self.update_document_impl(diff_base, !self.inverted, None) + } + + fn update_document_impl( + &self, + text: Rope, + is_base: bool, + render_lock: Option, + ) -> bool { + let event = Event { + text, + is_base, + render_lock, + }; + self.channel.send(event).is_ok() + } +} + +/// synchronous debounce value should be low +/// so we can update synchronously most of the time +const DIFF_DEBOUNCE_TIME_SYNC: u64 = 1; +/// maximum time that rendering should be blocked until the diff finishes +const SYNC_DIFF_TIMEOUT: u64 = 12; +const DIFF_DEBOUNCE_TIME_ASYNC: u64 = 96; +const ALGORITHM: Algorithm = Algorithm::Histogram; +const MAX_DIFF_LINES: usize = 64 * u16::MAX as usize; +// cap average line length to 128 for files with MAX_DIFF_LINES +const MAX_DIFF_BYTES: usize = MAX_DIFF_LINES * 128; + +/// A single change in a file potentially spanning multiple lines +/// Hunks produced by the differs are always ordered by their position +/// in the file and non-overlapping. +/// Specifically for any two hunks `x` and `y` the following properties hold: +/// +/// ``` no_compile +/// assert!(x.before.end <= y.before.start); +/// assert!(x.after.end <= y.after.start); +/// ``` +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct Hunk { + pub before: Range, + pub after: Range, +} + +impl Hunk { + /// Can be used instead of `Option::None` for better performance + /// because lines larger then `i32::MAX` are not supported by `imara-diff` anyways. + /// Has some nice properties where it usually is not necessary to check for `None` separately: + /// Empty ranges fail contains checks and also fails smaller then checks. + pub const NONE: Hunk = Hunk { + before: u32::MAX..u32::MAX, + after: u32::MAX..u32::MAX, + }; + + /// Inverts a change so that `before` + pub fn invert(&self) -> Hunk { + Hunk { + before: self.after.clone(), + after: self.before.clone(), + } + } + + pub fn is_pure_insertion(&self) -> bool { + self.before.is_empty() + } + + pub fn is_pure_removal(&self) -> bool { + self.after.is_empty() + } +} + +/// A list of changes in a file sorted in ascending +/// non-overlapping order +#[derive(Debug)] +pub struct FileHunks<'a> { + hunks: MutexGuard<'a, Vec>, + inverted: bool, +} + +impl FileHunks<'_> { + pub fn is_inverted(&self) -> bool { + self.inverted + } + + /// Returns the `Hunk` for the `n`th change in this file. + /// if there is no `n`th change `Hunk::NONE` is returned instead. + pub fn nth_hunk(&self, n: u32) -> Hunk { + match self.hunks.get(n as usize) { + Some(hunk) if self.inverted => hunk.invert(), + Some(hunk) => hunk.clone(), + None => Hunk::NONE, + } + } + + pub fn len(&self) -> u32 { + self.hunks.len() as u32 + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} diff --git a/helix-vcs/src/diff/line_cache.rs b/helix-vcs/src/diff/line_cache.rs new file mode 100644 index 00000000..c3ee5daa --- /dev/null +++ b/helix-vcs/src/diff/line_cache.rs @@ -0,0 +1,130 @@ +//! This modules encapsulates a tiny bit of unsafe code that +//! makes diffing significantly faster and more ergonomic to implement. +//! This code is necessary because diffing requires quick random +//! access to the lines of the text that is being diffed. +//! +//! Therefore it is best to collect the `Rope::lines` iterator into a vec +//! first because access to the vec is `O(1)` where `Rope::line` is `O(log N)`. +//! However this process can allocate a (potentially quite large) vector. +//! +//! To avoid reallocation for every diff, the vector is reused. +//! However the RopeSlice references the original rope and therefore forms a self-referential data structure. +//! A transmute is used to change the lifetime of the slice to static to circumvent that project. +use std::mem::transmute; + +use helix_core::{Rope, RopeSlice}; +use imara_diff::intern::{InternedInput, Interner}; + +use super::{MAX_DIFF_BYTES, MAX_DIFF_LINES}; + +/// A cache that stores the `lines` of a rope as a vector. +/// It allows safely reusing the allocation of the vec when updating the rope +pub(crate) struct InternedRopeLines { + diff_base: Rope, + doc: Rope, + num_tokens_diff_base: u32, + interned: InternedInput>, +} + +impl InternedRopeLines { + pub fn new(diff_base: Rope, doc: Rope) -> InternedRopeLines { + let mut res = InternedRopeLines { + interned: InternedInput { + before: Vec::with_capacity(diff_base.len_lines()), + after: Vec::with_capacity(doc.len_lines()), + interner: Interner::new(diff_base.len_lines() + doc.len_lines()), + }, + diff_base, + doc, + // will be populated by update_diff_base_impl + num_tokens_diff_base: 0, + }; + res.update_diff_base_impl(); + res + } + + /// Updates the `diff_base` and optionally the document if `doc` is not None + pub fn update_diff_base(&mut self, diff_base: Rope, doc: Option) { + self.interned.clear(); + self.diff_base = diff_base; + if let Some(doc) = doc { + self.doc = doc + } + if !self.is_too_large() { + self.update_diff_base_impl(); + } + } + + /// Updates the `doc` without reinterning the `diff_base`, this function + /// is therefore significantly faster than `update_diff_base` when only the document changes. + pub fn update_doc(&mut self, doc: Rope) { + // Safety: we clear any tokens that were added after + // the interning of `self.diff_base` finished so + // all lines that refer to `self.doc` have been purged. + + self.interned + .interner + .erase_tokens_after(self.num_tokens_diff_base.into()); + + self.doc = doc; + if self.is_too_large() { + self.interned.after.clear(); + } else { + self.update_doc_impl(); + } + } + + fn update_diff_base_impl(&mut self) { + // Safety: This transmute is safe because it only transmutes a lifetime, which has no effect. + // The backing storage for the RopeSlices referred to by the lifetime is stored in `self.diff_base`. + // Therefore as long as `self.diff_base` is not dropped/replaced this memory remains valid. + // `self.diff_base` is only changed in `self.update_diff_base`, which clears the interner. + // When the interned lines are exposed to consumer in `self.diff_input`, the lifetime is bounded to a reference to self. + // That means that on calls to update there exist no references to `self.interned`. + let before = self + .diff_base + .lines() + .map(|line: RopeSlice| -> RopeSlice<'static> { unsafe { transmute(line) } }); + self.interned.update_before(before); + self.num_tokens_diff_base = self.interned.interner.num_tokens(); + // the has to be interned again because the interner was fully cleared + self.update_doc_impl() + } + + fn update_doc_impl(&mut self) { + // Safety: This transmute is save because it only transmutes a lifetime, which has no effect. + // The backing storage for the RopeSlices referred to by the lifetime is stored in `self.doc`. + // Therefore as long as `self.doc` is not dropped/replaced this memory remains valid. + // `self.doc` is only changed in `self.update_doc`, which clears the interner. + // When the interned lines are exposed to consumer in `self.diff_input`, the lifetime is bounded to a reference to self. + // That means that on calls to update there exist no references to `self.interned`. + let after = self + .doc + .lines() + .map(|line: RopeSlice| -> RopeSlice<'static> { unsafe { transmute(line) } }); + self.interned.update_after(after); + } + + fn is_too_large(&self) -> bool { + // bound both lines and bytes to avoid huge files with few (but huge) lines + // or huge file with tiny lines. While this makes no difference to + // diff itself (the diff performance only depends on the number of tokens) + // the interning runtime depends mostly on filesize and is actually dominant + // for large files + self.doc.len_lines() > MAX_DIFF_LINES + || self.diff_base.len_lines() > MAX_DIFF_LINES + || self.doc.len_bytes() > MAX_DIFF_BYTES + || self.diff_base.len_bytes() > MAX_DIFF_BYTES + } + + /// Returns the `InternedInput` for performing the diff. + /// If `diff_base` or `doc` is so large that performing a diff could slow the editor + /// this function returns `None`. + pub fn interned_lines(&self) -> Option<&InternedInput> { + if self.is_too_large() { + None + } else { + Some(&self.interned) + } + } +} diff --git a/helix-vcs/src/diff/worker.rs b/helix-vcs/src/diff/worker.rs new file mode 100644 index 00000000..b8659c9b --- /dev/null +++ b/helix-vcs/src/diff/worker.rs @@ -0,0 +1,207 @@ +use std::mem::swap; +use std::ops::Range; +use std::sync::Arc; + +use helix_core::{Rope, RopeSlice}; +use imara_diff::intern::InternedInput; +use parking_lot::Mutex; +use tokio::sync::mpsc::UnboundedReceiver; +use tokio::sync::Notify; +use tokio::time::{timeout, timeout_at, Duration}; + +use crate::diff::{ + Event, RenderLock, ALGORITHM, DIFF_DEBOUNCE_TIME_ASYNC, DIFF_DEBOUNCE_TIME_SYNC, +}; + +use super::line_cache::InternedRopeLines; +use super::Hunk; + +#[cfg(test)] +mod test; + +pub(super) struct DiffWorker { + pub channel: UnboundedReceiver, + pub hunks: Arc>>, + pub new_hunks: Vec, + pub redraw_notify: Arc, + pub diff_finished_notify: Arc, +} + +impl DiffWorker { + async fn accumulate_events(&mut self, event: Event) -> (Option, Option) { + let mut accumulator = EventAccumulator::new(); + accumulator.handle_event(event).await; + accumulator + .accumulate_debounced_events( + &mut self.channel, + self.redraw_notify.clone(), + self.diff_finished_notify.clone(), + ) + .await; + (accumulator.doc, accumulator.diff_base) + } + + pub async fn run(mut self, diff_base: Rope, doc: Rope) { + let mut interner = InternedRopeLines::new(diff_base, doc); + if let Some(lines) = interner.interned_lines() { + self.perform_diff(lines); + } + self.apply_hunks(); + while let Some(event) = self.channel.recv().await { + let (doc, diff_base) = self.accumulate_events(event).await; + + let process_accumulated_events = || { + if let Some(new_base) = diff_base { + interner.update_diff_base(new_base, doc) + } else { + interner.update_doc(doc.unwrap()) + } + + if let Some(lines) = interner.interned_lines() { + self.perform_diff(lines) + } + }; + + // Calculating diffs is computationally expensive and should + // not run inside an async function to avoid blocking other futures. + // Note: tokio::task::block_in_place does not work during tests + #[cfg(test)] + process_accumulated_events(); + #[cfg(not(test))] + tokio::task::block_in_place(process_accumulated_events); + + self.apply_hunks(); + } + } + + /// update the hunks (used by the gutter) by replacing it with `self.new_hunks`. + /// `self.new_hunks` is always empty after this function runs. + /// To improve performance this function tries to reuse the allocation of the old diff previously stored in `self.line_diffs` + fn apply_hunks(&mut self) { + swap(&mut *self.hunks.lock(), &mut self.new_hunks); + self.diff_finished_notify.notify_waiters(); + self.new_hunks.clear(); + } + + fn perform_diff(&mut self, input: &InternedInput) { + imara_diff::diff(ALGORITHM, input, |before: Range, after: Range| { + self.new_hunks.push(Hunk { before, after }) + }) + } +} + +struct EventAccumulator { + diff_base: Option, + doc: Option, + render_lock: Option, +} + +impl<'a> EventAccumulator { + fn new() -> EventAccumulator { + EventAccumulator { + diff_base: None, + doc: None, + render_lock: None, + } + } + + async fn handle_event(&mut self, event: Event) { + let dst = if event.is_base { + &mut self.diff_base + } else { + &mut self.doc + }; + + *dst = Some(event.text); + + // always prefer the most synchronous requested render mode + if let Some(render_lock) = event.render_lock { + match &mut self.render_lock { + Some(RenderLock { timeout, .. }) => { + // A timeout of `None` means that the render should + // always wait for the diff to complete (so no timeout) + // remove the existing timeout, otherwise keep the previous timeout + // because it will be shorter then the current timeout + if render_lock.timeout.is_none() { + timeout.take(); + } + } + None => self.render_lock = Some(render_lock), + } + } + } + + async fn accumulate_debounced_events( + &mut self, + channel: &mut UnboundedReceiver, + redraw_notify: Arc, + diff_finished_notify: Arc, + ) { + let async_debounce = Duration::from_millis(DIFF_DEBOUNCE_TIME_ASYNC); + let sync_debounce = Duration::from_millis(DIFF_DEBOUNCE_TIME_SYNC); + loop { + // if we are not blocking rendering use a much longer timeout + let debounce = if self.render_lock.is_none() { + async_debounce + } else { + sync_debounce + }; + + if let Ok(Some(event)) = timeout(debounce, channel.recv()).await { + self.handle_event(event).await; + } else { + break; + } + } + + // setup task to trigger the rendering + match self.render_lock.take() { + // diff is performed outside of the rendering loop + // request a redraw after the diff is done + None => { + tokio::spawn(async move { + diff_finished_notify.notified().await; + redraw_notify.notify_one(); + }); + } + // diff is performed inside the rendering loop + // block redraw until the diff is done or the timeout is expired + Some(RenderLock { + lock, + timeout: Some(timeout), + }) => { + tokio::spawn(async move { + let res = { + // Acquire a lock on the redraw handle. + // The lock will block the rendering from occurring while held. + // The rendering waits for the diff if it doesn't time out + timeout_at(timeout, diff_finished_notify.notified()).await + }; + // we either reached the timeout or the diff is finished, release the render lock + drop(lock); + if res.is_ok() { + // Diff finished in time we are done. + return; + } + // Diff failed to complete in time log the event + // and wait until the diff occurs to trigger an async redraw + log::warn!("Diff computation timed out, update of diffs might appear delayed"); + diff_finished_notify.notified().await; + redraw_notify.notify_one(); + }); + } + // a blocking diff is performed inside the rendering loop + // block redraw until the diff is done + Some(RenderLock { + lock, + timeout: None, + }) => { + tokio::spawn(async move { + diff_finished_notify.notified().await; + // diff is done release the lock + drop(lock) + }); + } + }; + } +} diff --git a/helix-vcs/src/diff/worker/test.rs b/helix-vcs/src/diff/worker/test.rs new file mode 100644 index 00000000..14442426 --- /dev/null +++ b/helix-vcs/src/diff/worker/test.rs @@ -0,0 +1,149 @@ +use helix_core::Rope; +use tokio::task::JoinHandle; + +use crate::diff::{DiffHandle, Hunk}; + +impl DiffHandle { + fn new_test(diff_base: &str, doc: &str) -> (DiffHandle, JoinHandle<()>) { + DiffHandle::new_with_handle( + Rope::from_str(diff_base), + Rope::from_str(doc), + Default::default(), + ) + } + async fn into_diff(self, handle: JoinHandle<()>) -> Vec { + let hunks = self.hunks; + // dropping the channel terminates the task + drop(self.channel); + handle.await.unwrap(); + let hunks = hunks.lock(); + Vec::clone(&*hunks) + } +} + +#[tokio::test] +async fn append_line() { + let (differ, handle) = DiffHandle::new_test("foo\n", "foo\nbar\n"); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[Hunk { + before: 1..1, + after: 1..2 + }] + ) +} + +#[tokio::test] +async fn prepend_line() { + let (differ, handle) = DiffHandle::new_test("foo\n", "bar\nfoo\n"); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[Hunk { + before: 0..0, + after: 0..1 + }] + ) +} + +#[tokio::test] +async fn modify() { + let (differ, handle) = DiffHandle::new_test("foo\nbar\n", "foo bar\nbar\n"); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[Hunk { + before: 0..1, + after: 0..1 + }] + ) +} + +#[tokio::test] +async fn delete_line() { + let (differ, handle) = DiffHandle::new_test("foo\nfoo bar\nbar\n", "foo\nbar\n"); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[Hunk { + before: 1..2, + after: 1..1 + }] + ) +} + +#[tokio::test] +async fn delete_line_and_modify() { + let (differ, handle) = DiffHandle::new_test("foo\nbar\ntest\nfoo", "foo\ntest\nfoo bar"); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[ + Hunk { + before: 1..2, + after: 1..1 + }, + Hunk { + before: 3..4, + after: 2..3 + }, + ] + ) +} + +#[tokio::test] +async fn add_use() { + let (differ, handle) = DiffHandle::new_test( + "use ropey::Rope;\nuse tokio::task::JoinHandle;\n", + "use ropey::Rope;\nuse ropey::RopeSlice;\nuse tokio::task::JoinHandle;\n", + ); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[Hunk { + before: 1..1, + after: 1..2 + },] + ) +} + +#[tokio::test] +async fn update_document() { + let (differ, handle) = DiffHandle::new_test("foo\nbar\ntest\nfoo", "foo\nbar\ntest\nfoo"); + differ.update_document(Rope::from_str("foo\ntest\nfoo bar"), false); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[ + Hunk { + before: 1..2, + after: 1..1 + }, + Hunk { + before: 3..4, + after: 2..3 + }, + ] + ) +} + +#[tokio::test] +async fn update_base() { + let (differ, handle) = DiffHandle::new_test("foo\ntest\nfoo bar", "foo\ntest\nfoo bar"); + differ.update_diff_base(Rope::from_str("foo\nbar\ntest\nfoo")); + let line_diffs = differ.into_diff(handle).await; + assert_eq!( + &line_diffs, + &[ + Hunk { + before: 1..2, + after: 1..1 + }, + Hunk { + before: 3..4, + after: 2..3 + }, + ] + ) +} diff --git a/helix-vcs/src/git.rs b/helix-vcs/src/git.rs new file mode 100644 index 00000000..82b2b558 --- /dev/null +++ b/helix-vcs/src/git.rs @@ -0,0 +1,80 @@ +use std::path::Path; + +use git::objs::tree::EntryMode; +use git::sec::trust::DefaultForLevel; +use git::{Commit, ObjectId, Repository, ThreadSafeRepository}; +use git_repository as git; + +use crate::DiffProvider; + +#[cfg(test)] +mod test; + +pub struct Git; + +impl Git { + fn open_repo(path: &Path, ceiling_dir: Option<&Path>) -> Option { + // custom open options + let mut git_open_opts_map = git::sec::trust::Mapping::::default(); + + // don't use the global git configs (not needed) + let config = git::permissions::Config { + system: false, + git: false, + user: false, + env: true, + includes: true, + git_binary: false, + }; + // change options for config permissions without touching anything else + git_open_opts_map.reduced = git_open_opts_map.reduced.permissions(git::Permissions { + config, + ..git::Permissions::default_for_level(git::sec::Trust::Reduced) + }); + git_open_opts_map.full = git_open_opts_map.full.permissions(git::Permissions { + config, + ..git::Permissions::default_for_level(git::sec::Trust::Full) + }); + + let mut open_options = git::discover::upwards::Options::default(); + if let Some(ceiling_dir) = ceiling_dir { + open_options.ceiling_dirs = vec![ceiling_dir.to_owned()]; + } + + ThreadSafeRepository::discover_with_environment_overrides_opts( + path, + open_options, + git_open_opts_map, + ) + .ok() + } +} + +impl DiffProvider for Git { + fn get_diff_base(&self, file: &Path) -> Option> { + debug_assert!(!file.exists() || file.is_file()); + debug_assert!(file.is_absolute()); + + // TODO cache repository lookup + let repo = Git::open_repo(file.parent()?, None)?.to_thread_local(); + let head = repo.head_commit().ok()?; + let file_oid = find_file_in_commit(&repo, &head, file)?; + + let file_object = repo.find_object(file_oid).ok()?; + Some(file_object.detach().data) + } +} + +/// Finds the object that contains the contents of a file at a specific commit. +fn find_file_in_commit(repo: &Repository, commit: &Commit, file: &Path) -> Option { + let repo_dir = repo.work_dir()?; + let rel_path = file.strip_prefix(repo_dir).ok()?; + let tree = commit.tree().ok()?; + let tree_entry = tree.lookup_entry_by_path(rel_path).ok()??; + match tree_entry.mode() { + // not a file, everything is new, do not show diff + EntryMode::Tree | EntryMode::Commit | EntryMode::Link => None, + // found a file + EntryMode::Blob | EntryMode::BlobExecutable => Some(tree_entry.object_id()), + } +} diff --git a/helix-vcs/src/git/test.rs b/helix-vcs/src/git/test.rs new file mode 100644 index 00000000..d6e9af08 --- /dev/null +++ b/helix-vcs/src/git/test.rs @@ -0,0 +1,121 @@ +use std::{fs::File, io::Write, path::Path, process::Command}; + +use tempfile::TempDir; + +use crate::{DiffProvider, Git}; + +fn exec_git_cmd(args: &str, git_dir: &Path) { + let res = Command::new("git") + .arg("-C") + .arg(git_dir) // execute the git command in this directory + .args(args.split_whitespace()) + .env_remove("GIT_DIR") + .env_remove("GIT_ASKPASS") + .env_remove("SSH_ASKPASS") + .env("GIT_TERMINAL_PROMPT", "false") + .env("GIT_AUTHOR_DATE", "2000-01-01 00:00:00 +0000") + .env("GIT_AUTHOR_EMAIL", "author@example.com") + .env("GIT_AUTHOR_NAME", "author") + .env("GIT_COMMITTER_DATE", "2000-01-02 00:00:00 +0000") + .env("GIT_COMMITTER_EMAIL", "committer@example.com") + .env("GIT_COMMITTER_NAME", "committer") + .env("GIT_CONFIG_COUNT", "2") + .env("GIT_CONFIG_KEY_0", "commit.gpgsign") + .env("GIT_CONFIG_VALUE_0", "false") + .env("GIT_CONFIG_KEY_1", "init.defaultBranch") + .env("GIT_CONFIG_VALUE_1", "main") + .output() + .unwrap_or_else(|_| panic!("`git {args}` failed")); + if !res.status.success() { + println!("{}", String::from_utf8_lossy(&res.stdout)); + eprintln!("{}", String::from_utf8_lossy(&res.stderr)); + panic!("`git {args}` failed (see output above)") + } +} + +fn create_commit(repo: &Path, add_modified: bool) { + if add_modified { + exec_git_cmd("add -A", repo); + } + exec_git_cmd("commit -m message", repo); +} + +fn empty_git_repo() -> TempDir { + let tmp = tempfile::tempdir().expect("create temp dir for git testing"); + exec_git_cmd("init", tmp.path()); + exec_git_cmd("config user.email test@helix.org", tmp.path()); + exec_git_cmd("config user.name helix-test", tmp.path()); + tmp +} + +#[test] +fn missing_file() { + let temp_git = empty_git_repo(); + let file = temp_git.path().join("file.txt"); + File::create(&file).unwrap().write_all(b"foo").unwrap(); + + assert_eq!(Git.get_diff_base(&file), None); +} + +#[test] +fn unmodified_file() { + let temp_git = empty_git_repo(); + let file = temp_git.path().join("file.txt"); + let contents = b"foo".as_slice(); + File::create(&file).unwrap().write_all(contents).unwrap(); + create_commit(temp_git.path(), true); + assert_eq!(Git.get_diff_base(&file), Some(Vec::from(contents))); +} + +#[test] +fn modified_file() { + let temp_git = empty_git_repo(); + let file = temp_git.path().join("file.txt"); + let contents = b"foo".as_slice(); + File::create(&file).unwrap().write_all(contents).unwrap(); + create_commit(temp_git.path(), true); + File::create(&file).unwrap().write_all(b"bar").unwrap(); + + assert_eq!(Git.get_diff_base(&file), Some(Vec::from(contents))); +} + +/// Test that `get_file_head` does not return content for a directory. +/// This is important to correctly cover cases where a directory is removed and replaced by a file. +/// If the contents of the directory object were returned a diff between a path and the directory children would be produced. +#[test] +fn directory() { + let temp_git = empty_git_repo(); + let dir = temp_git.path().join("file.txt"); + std::fs::create_dir(&dir).expect(""); + let file = dir.join("file.txt"); + let contents = b"foo".as_slice(); + File::create(&file).unwrap().write_all(contents).unwrap(); + + create_commit(temp_git.path(), true); + + std::fs::remove_dir_all(&dir).unwrap(); + File::create(&dir).unwrap().write_all(b"bar").unwrap(); + assert_eq!(Git.get_diff_base(&dir), None); +} + +/// Test that `get_file_head` does not return content for a symlink. +/// This is important to correctly cover cases where a symlink is removed and replaced by a file. +/// If the contents of the symlink object were returned a diff between a path and the actual file would be produced (bad ui). +#[cfg(any(unix, windows))] +#[test] +fn symlink() { + #[cfg(unix)] + use std::os::unix::fs::symlink; + #[cfg(not(unix))] + use std::os::windows::fs::symlink_file as symlink; + let temp_git = empty_git_repo(); + let file = temp_git.path().join("file.txt"); + let contents = b"foo".as_slice(); + File::create(&file).unwrap().write_all(contents).unwrap(); + let file_link = temp_git.path().join("file_link.txt"); + symlink("file.txt", &file_link).unwrap(); + + create_commit(temp_git.path(), true); + assert_eq!(Git.get_diff_base(&file_link), None); + assert_eq!(Git.get_diff_base(&file), Some(Vec::from(contents))); +} diff --git a/helix-vcs/src/lib.rs b/helix-vcs/src/lib.rs new file mode 100644 index 00000000..97320d32 --- /dev/null +++ b/helix-vcs/src/lib.rs @@ -0,0 +1,51 @@ +use std::path::Path; + +#[cfg(feature = "git")] +pub use git::Git; +#[cfg(not(feature = "git"))] +pub use Dummy as Git; + +#[cfg(feature = "git")] +mod git; + +mod diff; + +pub use diff::{DiffHandle, Hunk}; + +pub trait DiffProvider { + /// Returns the data that a diff should be computed against + /// if this provider is used. + /// The data is returned as raw byte without any decoding or encoding performed + /// to ensure all file encodings are handled correctly. + fn get_diff_base(&self, file: &Path) -> Option>; +} + +#[doc(hidden)] +pub struct Dummy; +impl DiffProvider for Dummy { + fn get_diff_base(&self, _file: &Path) -> Option> { + None + } +} + +pub struct DiffProviderRegistry { + providers: Vec>, +} + +impl DiffProviderRegistry { + pub fn get_diff_base(&self, file: &Path) -> Option> { + self.providers + .iter() + .find_map(|provider| provider.get_diff_base(file)) + } +} + +impl Default for DiffProviderRegistry { + fn default() -> Self { + // currently only git is supported + // TODO make this configurable when more providers are added + let git: Box = Box::new(Git); + let providers = vec![git]; + DiffProviderRegistry { providers } + } +} diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index a2a88001..13d5da0e 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -21,6 +21,7 @@ helix-loader = { version = "0.6", path = "../helix-loader" } helix-lsp = { version = "0.6", path = "../helix-lsp" } helix-dap = { version = "0.6", path = "../helix-dap" } crossterm = { version = "0.25", optional = true } +helix-vcs = { version = "0.6", path = "../helix-vcs" } # Conversion traits once_cell = "1.16" @@ -43,6 +44,7 @@ log = "~0.4" which = "4.2" + [target.'cfg(windows)'.dependencies] clipboard-win = { version = "4.4", features = ["std"] } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index ad47f838..856e5628 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -3,6 +3,8 @@ use futures_util::future::BoxFuture; use futures_util::FutureExt; use helix_core::auto_pairs::AutoPairs; use helix_core::Range; +use helix_vcs::{DiffHandle, DiffProviderRegistry}; + use serde::de::{self, Deserialize, Deserializer}; use serde::Serialize; use std::borrow::Cow; @@ -24,6 +26,7 @@ use helix_core::{ DEFAULT_LINE_ENDING, }; +use crate::editor::RedrawHandle; use crate::{apply_transaction, DocumentId, Editor, View, ViewId}; /// 8kB of buffer space for encoding and decoding `Rope`s. @@ -133,6 +136,8 @@ pub struct Document { diagnostics: Vec, language_server: Option>, + + diff_handle: Option, } use std::{fmt, mem}; @@ -371,6 +376,7 @@ impl Document { last_saved_revision: 0, modified_since_accessed: false, language_server: None, + diff_handle: None, } } @@ -624,16 +630,20 @@ impl Document { } /// Reload the document from its path. - pub fn reload(&mut self, view: &mut View) -> Result<(), Error> { + pub fn reload( + &mut self, + view: &mut View, + provider_registry: &DiffProviderRegistry, + redraw_handle: RedrawHandle, + ) -> Result<(), Error> { let encoding = &self.encoding; - let path = self.path().filter(|path| path.exists()); - - // If there is no path or the path no longer exists. - if path.is_none() { - bail!("can't find file to reload from"); - } + let path = self + .path() + .filter(|path| path.exists()) + .ok_or_else(|| anyhow!("can't find file to reload from"))? + .to_owned(); - let mut file = std::fs::File::open(path.unwrap())?; + let mut file = std::fs::File::open(&path)?; let (rope, ..) = from_reader(&mut file, Some(encoding))?; // Calculate the difference between the buffer and source text, and apply it. @@ -646,6 +656,11 @@ impl Document { self.detect_indent_and_line_ending(); + match provider_registry.get_diff_base(&path) { + Some(diff_base) => self.set_diff_base(diff_base, redraw_handle), + None => self.diff_handle = None, + } + Ok(()) } @@ -787,6 +802,10 @@ impl Document { if !transaction.changes().is_empty() { self.version += 1; + // start computing the diff in parallel + if let Some(diff_handle) = &self.diff_handle { + diff_handle.update_document(self.text.clone(), false); + } // generate revert to savepoint if self.savepoint.is_some() { @@ -1046,6 +1065,23 @@ impl Document { server.is_initialized().then(|| server) } + pub fn diff_handle(&self) -> Option<&DiffHandle> { + self.diff_handle.as_ref() + } + + /// Intialize/updates the differ for this document with a new base. + pub fn set_diff_base(&mut self, diff_base: Vec, redraw_handle: RedrawHandle) { + if let Ok((diff_base, _)) = from_reader(&mut diff_base.as_slice(), Some(self.encoding)) { + if let Some(differ) = &self.diff_handle { + differ.update_diff_base(diff_base); + return; + } + self.diff_handle = Some(DiffHandle::new(diff_base, self.text.clone(), redraw_handle)) + } else { + self.diff_handle = None; + } + } + #[inline] /// Tree-sitter AST tree pub fn syntax(&self) -> Option<&Syntax> { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 5a1ac6b1..973cf82e 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -9,6 +9,7 @@ use crate::{ tree::{self, Tree}, Align, Document, DocumentId, View, ViewId, }; +use helix_vcs::DiffProviderRegistry; use futures_util::stream::select_all::SelectAll; use futures_util::{future, StreamExt}; @@ -26,7 +27,10 @@ use std::{ }; use tokio::{ - sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, + sync::{ + mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, + Notify, RwLock, + }, time::{sleep, Duration, Instant, Sleep}, }; @@ -454,6 +458,8 @@ pub enum GutterType { LineNumbers, /// Show one blank space Spacer, + /// Highlight local changes + Diff, } impl std::str::FromStr for GutterType { @@ -464,6 +470,7 @@ impl std::str::FromStr for GutterType { "diagnostics" => Ok(Self::Diagnostics), "spacer" => Ok(Self::Spacer), "line-numbers" => Ok(Self::LineNumbers), + "diff" => Ok(Self::Diff), _ => anyhow::bail!("Gutter type can only be `diagnostics` or `line-numbers`."), } } @@ -600,6 +607,8 @@ impl Default for Config { GutterType::Diagnostics, GutterType::Spacer, GutterType::LineNumbers, + GutterType::Spacer, + GutterType::Diff, ], middle_click_paste: true, auto_pairs: AutoPairConfig::default(), @@ -681,6 +690,7 @@ pub struct Editor { pub macro_replaying: Vec, pub language_servers: helix_lsp::Registry, pub diagnostics: BTreeMap>, + pub diff_providers: DiffProviderRegistry, pub debugger: Option, pub debugger_events: SelectAll>, @@ -711,8 +721,15 @@ pub struct Editor { pub exit_code: i32, pub config_events: (UnboundedSender, UnboundedReceiver), + /// Allows asynchronous tasks to control the rendering + /// The `Notify` allows asynchronous tasks to request the editor to perform a redraw + /// The `RwLock` blocks the editor from performing the render until an exclusive lock can be aquired + pub redraw_handle: RedrawHandle, + pub needs_redraw: bool, } +pub type RedrawHandle = (Arc, Arc>); + #[derive(Debug)] pub enum EditorEvent { DocumentSaved(DocumentSavedEventResult), @@ -785,6 +802,7 @@ impl Editor { theme: theme_loader.default(), language_servers: helix_lsp::Registry::new(), diagnostics: BTreeMap::new(), + diff_providers: DiffProviderRegistry::default(), debugger: None, debugger_events: SelectAll::new(), breakpoints: HashMap::new(), @@ -803,6 +821,8 @@ impl Editor { auto_pairs, exit_code: 0, config_events: unbounded_channel(), + redraw_handle: Default::default(), + needs_redraw: false, } } @@ -1109,7 +1129,9 @@ impl Editor { let mut doc = Document::open(&path, None, Some(self.syn_loader.clone()))?; let _ = Self::launch_language_server(&mut self.language_servers, &mut doc); - + if let Some(diff_base) = self.diff_providers.get_diff_base(&path) { + doc.set_diff_base(diff_base, self.redraw_handle.clone()); + } self.new_document(doc) }; @@ -1348,24 +1370,39 @@ impl Editor { } pub async fn wait_event(&mut self) -> EditorEvent { - tokio::select! { - biased; + // the loop only runs once or twice and would be better implemented with a recursion + const generic + // however due to limitations with async functions that can not be implemented right now + loop { + tokio::select! { + biased; + + Some(event) = self.save_queue.next() => { + self.write_count -= 1; + return EditorEvent::DocumentSaved(event) + } + Some(config_event) = self.config_events.1.recv() => { + return EditorEvent::ConfigEvent(config_event) + } + Some(message) = self.language_servers.incoming.next() => { + return EditorEvent::LanguageServerMessage(message) + } + Some(event) = self.debugger_events.next() => { + return EditorEvent::DebuggerEvent(event) + } - Some(event) = self.save_queue.next() => { - self.write_count -= 1; - EditorEvent::DocumentSaved(event) - } - Some(config_event) = self.config_events.1.recv() => { - EditorEvent::ConfigEvent(config_event) - } - Some(message) = self.language_servers.incoming.next() => { - EditorEvent::LanguageServerMessage(message) - } - Some(event) = self.debugger_events.next() => { - EditorEvent::DebuggerEvent(event) - } - _ = &mut self.idle_timer => { - EditorEvent::IdleTimer + _ = self.redraw_handle.0.notified() => { + if !self.needs_redraw{ + self.needs_redraw = true; + let timeout = Instant::now() + Duration::from_millis(96); + if timeout < self.idle_timer.deadline(){ + self.idle_timer.as_mut().reset(timeout) + } + } + } + + _ = &mut self.idle_timer => { + return EditorEvent::IdleTimer + } } } } diff --git a/helix-view/src/gutter.rs b/helix-view/src/gutter.rs index 61a17791..377518fb 100644 --- a/helix-view/src/gutter.rs +++ b/helix-view/src/gutter.rs @@ -12,7 +12,7 @@ fn count_digits(n: usize) -> usize { std::iter::successors(Some(n), |&n| (n >= 10).then(|| n / 10)).count() } -pub type GutterFn<'doc> = Box Option - - - + \ No newline at end of file From 39ce82b7a59de8adcb1626151b1ce8fe7b7a4a8e Mon Sep 17 00:00:00 2001 From: lesleyrs <19632758+lesleyrs@users.noreply.github.com> Date: Fri, 2 Dec 2022 15:02:29 +0100 Subject: [PATCH 031/132] Add Ctrl-i alias for Windows (#4961) --- helix-term/src/keymap/default.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index 118764d9..c0d17a87 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -198,7 +198,7 @@ pub fn default() -> HashMap { // z family for save/restore/combine from/to sels from register - "tab" => jump_forward, // tab == + "C-i" | "tab" => jump_forward, // tab == "C-o" => jump_backward, "C-s" => save_selection, From d0bc38d6fa60e36ef317e8bbbaa11aeb30470ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Fri, 2 Dec 2022 15:06:35 +0100 Subject: [PATCH 032/132] feat(lang): bump tree-sitter-go (#4969) Update tree-sitter-go to latest with updated support for generics. See: https://github.com/tree-sitter/tree-sitter-go/compare/0fa917a7022d1cd2e9b779a6a8fc5dc7fad69c75..05900faa3cdb5d2d8c8bd5e77ee698487e0a8611 for full diff. --- languages.toml | 2 +- runtime/queries/go/indents.scm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/languages.toml b/languages.toml index 4eb8a4da..9664d93a 100644 --- a/languages.toml +++ b/languages.toml @@ -301,7 +301,7 @@ args = { mode = "local", processId = "{0}" } [[grammar]] name = "go" -source = { git = "https://github.com/tree-sitter/tree-sitter-go", rev = "0fa917a7022d1cd2e9b779a6a8fc5dc7fad69c75" } +source = { git = "https://github.com/tree-sitter/tree-sitter-go", rev = "05900faa3cdb5d2d8c8bd5e77ee698487e0a8611" } [[language]] name = "gomod" diff --git a/runtime/queries/go/indents.scm b/runtime/queries/go/indents.scm index 8bfc7c3f..f72ec9e8 100644 --- a/runtime/queries/go/indents.scm +++ b/runtime/queries/go/indents.scm @@ -5,7 +5,7 @@ (type_spec) (func_literal) (literal_value) - (element) + (literal_element) (keyed_element) (expression_case) (default_case) From 59b886cf5e89dadfd73d93b638b2c552ce5537f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?alex=20=E5=AD=99=E6=AC=A3=E4=B9=90?= Date: Fri, 2 Dec 2022 22:24:00 +0800 Subject: [PATCH 033/132] nightfox theme: Use brighter colors for diff scopes (#4966) --- runtime/themes/nightfox.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/themes/nightfox.toml b/runtime/themes/nightfox.toml index 131cab19..c4cbbce0 100644 --- a/runtime/themes/nightfox.toml +++ b/runtime/themes/nightfox.toml @@ -140,10 +140,10 @@ # Diff ============================== # Version control changes. -"diff.plus" = "green-dim" # Additions. -"diff.minus" = "red-dim" # Deletions. -"diff.delta" = "blue-dim" # Modifications. -"diff.delta.moved" = "cyan-dim" # Renamed or moved files. +"diff.plus" = "green" # Additions. +"diff.minus" = "red" # Deletions. +"diff.delta" = "blue" # Modifications. +"diff.delta.moved" = "cyan" # Renamed or moved files. # color palette [palette] From b677c6a019f893c7ed8b9b84d136c50e5445315a Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Sat, 3 Dec 2022 03:05:15 +0100 Subject: [PATCH 034/132] Add logo with text included (#4973) --- README.md | 10 +++-- logo_dark.svg | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ logo_light.svg | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 logo_dark.svg create mode 100644 logo_light.svg diff --git a/README.md b/README.md index 3555b539..b06e8222 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@
-Logo - -# Helix +

+ + + + Helix + +

[![Build status](https://github.com/helix-editor/helix/actions/workflows/build.yml/badge.svg)](https://github.com/helix-editor/helix/actions) [![GitHub Release](https://img.shields.io/github/v/release/helix-editor/helix)](https://github.com/helix-editor/helix/releases/latest) diff --git a/logo_dark.svg b/logo_dark.svg new file mode 100644 index 00000000..f6e94f1b --- /dev/null +++ b/logo_dark.svg @@ -0,0 +1,115 @@ + + diff --git a/logo_light.svg b/logo_light.svg new file mode 100644 index 00000000..cdd5ddb8 --- /dev/null +++ b/logo_light.svg @@ -0,0 +1,115 @@ + + From 224a024d3997035d04bf7b2f7424a472ff9936b8 Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Fri, 2 Dec 2022 18:26:01 -0800 Subject: [PATCH 035/132] Update zenburn theme for git gutters (#4977) --- runtime/themes/zenburn.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/themes/zenburn.toml b/runtime/themes/zenburn.toml index affb9f56..63f4ac72 100644 --- a/runtime/themes/zenburn.toml +++ b/runtime/themes/zenburn.toml @@ -37,9 +37,9 @@ "ui.virtual.indent-guide" = "#4f4f4f" -"diff.plus" = {fg = "#709080", bg = "#313c36", modifiers = ["bold"] } -"diff.delta" = "#333333" -"diff.minus" = {fg = "#333333", bg = "#464646"} +"diff.plus" = {fg = "#709080"} +"diff.delta" = {fg = "#464646"} +"diff.minus" = {fg = "#cc9393"} "diagnostic" = {bg = "statusbg"} "diagnostic.error" = { fg = "errorfg", bg = "errorbg"} From dc00291b4888f7ffad43fd544259227d0dbbf6fb Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 3 Dec 2022 03:26:10 +0100 Subject: [PATCH 036/132] Update Doom Acario for git gutters (#4979) Edited the diff.delta from green to blue. --- runtime/themes/doom_acario_dark.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/themes/doom_acario_dark.toml b/runtime/themes/doom_acario_dark.toml index c38c93ee..95dc78e0 100644 --- a/runtime/themes/doom_acario_dark.toml +++ b/runtime/themes/doom_acario_dark.toml @@ -41,7 +41,7 @@ 'diff.plus' = { fg = 'green' } 'diff.minus' = { fg = 'red' } -'diff.delta' = { fg = 'green' } +'diff.delta' = { fg = 'blue' } 'ui.background'= { bg = 'bg' } 'ui.cursor' = { bg = 'orange', fg = 'bg-alt' } From bcdb475b71b0fbabce57344ac8d2575c23b1bbe0 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 2 Dec 2022 21:09:08 -0600 Subject: [PATCH 037/132] Fix transaction composition order in History::changes_since (#4981) * Add a undo/redo split test case for crossing branches * history: Switch up/down transaction chaining order The old code tends to work in practice because, usually, either up_txns or down_txns are empty. When both have contents though, we can run into a panic trying to compose them all since they will disagree on the length of the text. This fixes the panic test case in the parent commit. --- helix-core/src/history.rs | 2 +- helix-term/tests/test/splits.rs | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/helix-core/src/history.rs b/helix-core/src/history.rs index b99e969f..1aac38d9 100644 --- a/helix-core/src/history.rs +++ b/helix-core/src/history.rs @@ -131,7 +131,7 @@ impl History { .map(|&n| self.revisions[n].inversion.clone()); let down_txns = down.iter().map(|&n| self.revisions[n].transaction.clone()); - up_txns.chain(down_txns).reduce(|acc, tx| tx.compose(acc)) + down_txns.chain(up_txns).reduce(|acc, tx| tx.compose(acc)) } /// Undo the last edit. diff --git a/helix-term/tests/test/splits.rs b/helix-term/tests/test/splits.rs index a34a24b7..96ced21a 100644 --- a/helix-term/tests/test/splits.rs +++ b/helix-term/tests/test/splits.rs @@ -161,5 +161,30 @@ async fn test_changes_in_splits_apply_to_all_views() -> anyhow::Result<()> { )) .await?; + // See . + // This sequence undoes part of the history and then adds new changes, creating a + // new branch in the history tree. `View::sync_changes` applies transactions down + // and up to the lowest common ancestor in the path between old and new revision + // numbers. If we apply these up/down transactions in the wrong order, this case + // panics. + // The key sequence: + // * 3[ Create three empty lines so we are at the end of the document. + // * v Create a split and save that point at the end of the document + // in the jumplist. + // * w Switch back to the first window. + // * uu Undo twice (not three times which would bring us back to the + // root of the tree). + // * 3[ Create three empty lines. Now the end of the document is past + // where it was on step 1. + // * q Close window 1, focusing window 2 and causing a sync. This step + // panics if we don't apply in the right order. + // * %d Clean up the buffer. + test(( + "#[|]#", + "3[vwuu3[q%d", + "#[|]#", + )) + .await?; + Ok(()) } From 2123e91e56caccf60b9285f30bc2f2f12952520a Mon Sep 17 00:00:00 2001 From: Aleksey Kuznetsov Date: Sat, 3 Dec 2022 19:24:43 +0500 Subject: [PATCH 038/132] Enable auto format for css and scss files (#4987) provideFormatter enables capability in LS and auto-format performs format on save --- languages.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/languages.toml b/languages.toml index 9664d93a..d214a082 100644 --- a/languages.toml +++ b/languages.toml @@ -422,6 +422,8 @@ injection-regex = "css" file-types = ["css", "scss"] roots = [] language-server = { command = "vscode-css-language-server", args = ["--stdio"] } +auto-format = true +config = { "provideFormatter" = true } indent = { tab-width = 2, unit = " " } [[grammar]] @@ -435,6 +437,8 @@ injection-regex = "scss" file-types = ["scss"] roots = [] language-server = { command = "vscode-css-language-server", args = ["--stdio"] } +auto-format = true +config = { "provideFormatter" = true } indent = { tab-width = 2, unit = " " } [[grammar]] From 326a0dab069b65463db90e2647287c1e5b6b66aa Mon Sep 17 00:00:00 2001 From: Jens Getreu Date: Sun, 4 Dec 2022 03:03:42 +0100 Subject: [PATCH 039/132] Autumn theme: adjust some gray colors (#4996) --- runtime/themes/autumn.toml | 12 ++++++------ runtime/themes/autumn_night.toml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime/themes/autumn.toml b/runtime/themes/autumn.toml index b13aeef2..fe80261a 100644 --- a/runtime/themes/autumn.toml +++ b/runtime/themes/autumn.toml @@ -10,13 +10,13 @@ "ui.background" = { bg = "my_gray0" } "ui.menu" = { fg = "my_white", bg = "my_gray2" } "ui.menu.selected" = { fg = "my_gray2", bg = "my_gray5" } -"ui.linenr" = { fg = "my_gray4", bg = "my_gray2" } +"ui.linenr" = { fg = "my_gray3", bg = "my_gray0" } "ui.popup" = { bg = "my_gray2" } -"ui.window" = { fg = "my_gray4", bg = "my_gray2" } -"ui.linenr.selected" = { fg = "my_gray6", bg = "my_gray1"} +"ui.window" = { fg = "my_gray3", bg = "my_gray2" } +"ui.linenr.selected" = { fg = "my_gray6", bg = "my_gray0"} "ui.selection" = { bg = "my_gray3" } "comment" = { fg = "my_gray4", modifiers = ["italic"] } -"ui.cursorline" = { bg = "my_gray2" } +"ui.cursorline" = { bg = "my_gray3" } "ui.statusline" = { fg = "my_gray6", bg = "my_gray2" } "ui.statusline.inactive" = { fg = 'my_gray4', bg = 'my_gray2' } "ui.statusline.insert" = {fg = "my_black", bg = "my_gray5", modifiers = ["bold"]} @@ -62,7 +62,7 @@ "diff.minus" = "my_red" "diagnostic" = { modifiers = ["underlined"] } -"ui.gutter" = { bg = "my_gray2" } +"ui.gutter" = { bg = "my_gray0" } "hint" = "my_gray5" "debug" = "my_yellow2" "info" = "my_yellow2" @@ -77,7 +77,7 @@ my_gray2 = "#323232" # Lighter Background (Used for status bars, line numbe my_gray3 = "#505050" # Selection Background my_gray4 = "#7c7c7c" # Comments, Invisibles, Line Highlighting my_gray5 = "#a8a8a8" # Dark Foreground (Used for status bars) -my_gray6 = "#c0c0c0" # Light Foreground (Not often used) +my_gray6 = "#c8c8c8" # Light Foreground (Not often used) my_gray7 = "#e8e8e8" # Light Background (Not often used) my_white = "#F3F2CC" # Default Foreground, Caret, Delimiters, Operators my_white2 = "#F3F2CC" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted diff --git a/runtime/themes/autumn_night.toml b/runtime/themes/autumn_night.toml index 2f398dc9..d01f5356 100644 --- a/runtime/themes/autumn_night.toml +++ b/runtime/themes/autumn_night.toml @@ -10,13 +10,13 @@ "ui.background" = { bg = "my_gray0" } "ui.menu" = { fg = "my_white", bg = "my_gray2" } "ui.menu.selected" = { fg = "my_gray2", bg = "my_gray5" } -"ui.linenr" = { fg = "my_gray4", bg = "my_gray2" } +"ui.linenr" = { fg = "my_gray3", bg = "my_gray0" } "ui.popup" = { bg = "my_gray2" } -"ui.window" = { fg = "my_gray4", bg = "my_gray2" } -"ui.linenr.selected" = { fg = "my_gray6", bg = "my_gray1"} +"ui.window" = { fg = "my_gray3", bg = "my_gray2" } +"ui.linenr.selected" = { fg = "my_gray6", bg = "my_gray0"} "ui.selection" = { bg = "my_gray3" } "comment" = { fg = "my_gray4", modifiers = ["italic"] } -"ui.cursorline" = { bg = "my_gray2" } +"ui.cursorline" = { bg = "my_gray3" } "ui.statusline" = { fg = "my_gray6", bg = "my_gray2" } "ui.statusline.inactive" = { fg = 'my_gray4', bg = 'my_gray2' } "ui.statusline.insert" = {fg = "my_black", bg = "my_gray5", modifiers = ["bold"]} @@ -62,7 +62,7 @@ "diff.minus" = "my_red" "diagnostic" = { modifiers = ["underlined"] } -"ui.gutter" = { bg = "my_gray2" } +"ui.gutter" = { bg = "my_gray0" } "hint" = "my_gray5" "debug" = "my_yellow2" "info" = "my_yellow2" @@ -77,7 +77,7 @@ my_gray2 = "#1a1a1a" # Lighter Background (Used for status bars, line numbe my_gray3 = "#323232" # Selection Background my_gray4 = "#7c7c7c" # Comments, Invisibles, Line Highlighting my_gray5 = "#aaaaaa" # Dark Foreground (Used for status bars) -my_gray6 = "#c0c0c0" # Light Foreground (Not often used) +my_gray6 = "#c4c4c4" # Light Foreground (Not often used) my_gray7 = "#e8e8e8" # Light Background (Not often used) my_white = "#F3F2CC" # Default Foreground, Caret, Delimiters, Operators my_white2 = "#F3F2CC" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted From e9d0645f66c6254e82c2b50000eb5660c128f26b Mon Sep 17 00:00:00 2001 From: PORTALSURFER <41680373+PORTALSURFER@users.noreply.github.com> Date: Sun, 4 Dec 2022 03:06:40 +0100 Subject: [PATCH 040/132] Adjusted hex themes for new gutter diff colors (#4990) * added 2 themes * diff feature fixes adjusted the skin to better work with the new diff coloring features propagates to child skins like - hex_toxic * fine tuning so it all is a bit softer * fine tuning to be softer * added new version, lavender --- runtime/themes/hex_lavender.toml | 31 ++++++++++++++++++++++++++++++ runtime/themes/hex_steel.toml | 33 ++++++++++++++++++-------------- runtime/themes/hex_toxic.toml | 10 +++++----- 3 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 runtime/themes/hex_lavender.toml diff --git a/runtime/themes/hex_lavender.toml b/runtime/themes/hex_lavender.toml new file mode 100644 index 00000000..974c486c --- /dev/null +++ b/runtime/themes/hex_lavender.toml @@ -0,0 +1,31 @@ +inherits = "hex_steel" + +[palette] +t1 = "#0e0e0d" +t2 = "#121311" +t3 = "#2b3444" # +t4 = "#61586f" +t5 = "#686e73" +t6 = "#878480" +t7 = "#897dca" +t8 = "#7b89a3" +t9 = "#bcb6ba" +t10 = "#9db2b8" +t11 = "#a0c7cf" + +highlight = "#ff2e5f" +highlight_two = "#0affa9" +highlight_three = "#29bbff" + +black = "#000000" + +selection = "#290019" + +comment = "#9aacfe" +comment_doc = "#0affa9" + +error = "#ff0900" +warning = "#ffbf00" +display = "#57ff89" +info = "#dad7d5" +# diff --git a/runtime/themes/hex_steel.toml b/runtime/themes/hex_steel.toml index 06e91d01..7a2183f8 100644 --- a/runtime/themes/hex_steel.toml +++ b/runtime/themes/hex_steel.toml @@ -1,5 +1,5 @@ -"comment" = { fg = "highlight_three" } -"comment.block.documentation" = { bg = "t4", modifiers = ["italic"] } +"comment" = { fg = "comment" } +"comment.block.documentation" = { bg = "comment_doc", modifiers = ["italic"] } "constant" = { fg = "t11" } "function" = { fg = "t10" } @@ -20,18 +20,19 @@ "variable" = { fg = "t4" } "label" = { fg = "t4" } -"diff.plus" = { fg = "t4" } -"diff.delta" = { fg = "t4" } -"diff.minus" = { fg = "t4" } +"diff.plus" = { fg = "diff_plus" } +"diff.delta" = { fg = "diff_delta" } +"diff.delta.moved" = { fg = "diff_delta_moved" } +"diff.minus" = { fg = "diff_minus" } "ui.cursor.insert" = { fg = "t2", bg = "highlight" } "ui.cursor.select" = { fg = "t2", bg = "highlight_two" } "ui.cursor" = { fg = "t1", bg = "highlight_three" } -"ui.cursor.match" = { fg = "highlight", bg = "t1", modifiers = ["bold"] } +"ui.cursor.match" = { fg = "highlight", bg = "selection", modifiers = ["bold"] } -"ui.linenr" = { fg = "t3", bg = "t1" } -"ui.linenr.selected" = { fg = "highlight_three", bg = "t1" } -"ui.gutter" = { bg = "t1" } +"ui.linenr" = { fg = "t3", bg = "t2" } +"ui.linenr.selected" = { fg = "highlight_three", bg = "t2" } +"ui.gutter" = { bg = "t2" } "ui.background" = { fg = "t4", bg = "t2" } "ui.background.separator" = { fg = "t3" } @@ -76,8 +77,8 @@ "markup.raw" = { fg = "t4" } [palette] -t1 = "#0f0b0b" -t2 = "#161010" +t1 = "#0e0e0d" +t2 = "#1d1e1b" t3 = "#5b5555" t4 = "#656869" t5 = "#727b7c" @@ -95,11 +96,15 @@ highlight_three = "#d4d987" selection = "#032d4a" black = "#000000" - -comment = "#396884" +comment = "#d4d987" comment_doc = "#234048" error = "#ff0900" warning = "#ffbf00" -display = "#57ff89" +display = "#42baff" info = "#dad7d5" + +diff_minus = "#ff0900" +diff_delta = "#0078bd" +diff_plus = "#87a800" +diff_delta_moved = "#0048bd" diff --git a/runtime/themes/hex_toxic.toml b/runtime/themes/hex_toxic.toml index 3cd878be..33bfa6e5 100644 --- a/runtime/themes/hex_toxic.toml +++ b/runtime/themes/hex_toxic.toml @@ -2,7 +2,7 @@ inherits = "hex_steel" [palette] t1 = "#101719" -t2 = "#152432" +t2 = "#1b2a32" t3 = "#4b5968" t4 = "#8792ab" t5 = "#6f91bc" @@ -13,15 +13,15 @@ t9 = "#b3ccd0" t10 = "#b0d4d8" t11 = "#ffbf52" -highlight = "#ff2e5f" +highlight = "#ff0a50" highlight_two = "#0affa9" -highlight_three = "#d7ff52" +highlight_three = "#f8ed8b" black = "#000000" -selection = "#290019" +selection = "#382e1e" -comment = "#396884" +comment = "#61bdd1" comment_doc = "#234048" error = "#ff0900" From c13c6d56b6eb0e117cb92ba4011155b519befde6 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sat, 3 Dec 2022 20:07:17 -0600 Subject: [PATCH 041/132] Use logo for contrib icon (#4982) --- contrib/helix.png | Bin 1838 -> 15785 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/contrib/helix.png b/contrib/helix.png index bef00b98418a3fefcf56a5d45fafb1403e26e996..a9b699a4606926465926e8020eb5ce94cffb2ddb 100644 GIT binary patch literal 15785 zcmZ{L1yEd1@aEfH+}&M*6C^+g?hrhUa5P*h)xEOyd{eZY2 z*+{8M0YGgW=7R+?;y0a@;yYCU@O=RQ&=3H)Lp*}+0Kg|60N67JfH!FXKkkPj zcrgmDdHD!EhqV?pdf;@Q)GXxXxSswPNaMRrC_PkGWPR%!3H;#0NW**}*`x{;FMB(u z>~=aa@cMayrJ(U8eSYbV9T=d4pTghaJ8Nyem-35xXZY2oKZ%J`QPH-D1w)d98U7t@ zMCU*q#;BD}fV7%r$I)!NSExCk8jmL|W&jwHqp3iSu!FmWh*4<2>5z$jP&N6zp`ONi!tTKt&Pg&@eb2-7S!8}E8i5kg}f5aqt51<4pR{j!k`O&SPr~T-N z_Q#O5%h%fVql&TfzKxUo?m1u#lXo&~8k-k``k%tIkOH_0lws>0l4u5DhxbwH7EA#N+xHd)bKp*KOkJU%ji7RFg z!DO0m(!GiF;A6Q{{FBVgw5CQu`~8+ASzsw0AHIoptv`7V?GQu~P2(*Jiz;TOk&2_& zMykMQfLoAtRCeQ!vJq7obbk3+-G<+gY$DA7+;0cN8StI;HWTyM@HO_`{wDQOhKo!x z7(aE;)6u=n+o6R;!%fUf^09sh#)S{GHOx2PHBf72E_`PKj|q;$OXQkmWUEkPDdO?5 zTvvV6c^L77X54Qrf+dlpz~;PTXvR@B#yS#liYP>9K3mnh!b_42z+s^T4|=nWy6H>g zun%vgk(wYF|Efc>;$|!1}b*r+@}mi5DO_khBXp{WU!-0`3^EkFo#=)Ce3c2D5Amu zWdHdLrKPWv=CYwnDr>+JD~%-AqA6)1#FmCu@G$HR5 zE(^4vKvX1eLRp&t7K1*t6q9-J(O=)oT~%WUBV%r>k79N?U@C< z2nDC#;rNl?RN6FC{O!TAgY#T|9r*d$&dAh*6$RAm^Re*y{0s!QE670?$Wdm?(H)4R zhkHpL>0C&gLznaP)zf$n-MHU8cOiTNQ03zse2@EwaOJ$&Kl_naika#g@8u2wXvb6> z;6yqi+N_T(mLpb5<#C@|&-&~<9>dDM)qeLzDi=eN9!ny`f$Sd%PS<8=?^nc7a*0k{ z;4ZT7YYS-E$8aacn+m>?|D!4KUBlFzpDAzN+k6A3vjB8a!S1g7FXp6?@0U4P4GBQu zv2Rx#z}MeqFHPjiWzX~Iv4i*1Qho^?kZg6<5wCB%`j}9K3{JwoA9_a-IrHgoD!l>A zsS|5(4St7zDy_nbf5SK|r{!>Rh8*ClH6Bx1pWfstqB~ytfqn)OuvrTyhIjt!KrIB= zN@!0RPl3oUxFDg(K^JIXPuWYT>g_L;GHj8U+x;fq>*PvSlEUAtSOe8rkcH6sn|&Pz z282Kq)`@|6#pwo)dBS$)c8^B-t8?VxZWIz@FUtwR{;zwfP4RDw;OuJ@?Ux{7)fI*n z{qTMM2l$STJt^ZIgcN)ok{^Id_D;7{LB@J3R6uFgO(gw#SkNy~S_gCrOGFMp=0uJy zOyv$x6op!D^Q=&;yjn2~{oFTZTQN_o_=R4=P?X!AGAd=SVP0Qrn)W@*H%_E2MV;&* zmI16dPGQE`|EZ&=k&{@l^A#PFdEb>iYepTTlgI&| z&S@p0%Ezf>&fxc?UvZfNsIY#4kED8{puvqU++E5BAJmL~UktVL2bv#c9HxyWZWFqYX_i^=C3VFEwFR(6&Cm|D<NP7T4o_Y7n0Wp0JG1%ZaP*2wM_OjH8+Vp{SYvQ7gPjff5}d zJKgYm3LGcvq?GWH$hAFu0pv%)93$OP&2!#8sgl*qX@5W0Cs6IQUY2T)kCo#KeDQ|; zBxt52-M@~Q>u)Ad1`VQs7+&-)0<8s&C5lR*TqNg#8nn$|Owu@HMl5P?EdCNvsoEyy z@&G&1bF;;_c&sn1fjjW_YRB~mY*llf%*&Du*ko%uE-8xxcgD@-FqFJ>%|Y|}lV#{G z%(HOr85E+DT^s458X#(azm(#$-)O~Wq1?>E7NQ=sgu~hW+d*Xq$?|iEpw*pyFGe%< ziO6i=b0gCAU?4^_Ni$_W%_kwLs(72fQ&B5#j`VKJLEYU5vro5QiqN#iA1ec zw&upVK3adlj+~42Bvi%)BtJUykENZk6Yh?$}ca zJn0mUHf1Q?=iQCoeE0BYRlejBi2%eZ&z;jq0g@&T!aEgH>lJ`Kh>C4*?c;z~EX?!S zucP91h>@7%EdCY*I?3`~_c?vT86s>u@;!}6$l>fpsKD{BSS-fo{KyhnyGUDB;&kl%KWdQm{ ze_`q}c61pUUZGx?uQ;xN*V;kE$eC`7p3Z{Z4*AmZ7)k1HsI*q;F&MsTmgh>QMeG}l zB??(uaR6@1es=trByp=H)4Ab)!LV(Rqs%XLw^g{b`DcW`4_|HWE&p8cQGD!WwfGzv z-UiZ2Pgx7u>NI>{cQ#65>Vg7yrSeynp^O7bLcISvBymc;S|JAeo|c3eU!YwVFihv&{!*n`26i%cpWMJ@o_4pyWt%!NTlFHn{wo=YuzI|R8` zitu7>cR3x%*ch4n5>+DlcJ9NF@20nP43g@mLPYt?*O;l=Nn_(*W<^+4cX^ZFFB!p- zGAxg|#wT+JwO9H_Ml%TV!anp`xWjeJlRWA3G!0o(!L(TMYMZS z5=`qf)a{>Fo9a+s6MOT-(jcPBdyD=b6wx}`y*gA3jBc$9W+f%Z9vtR$0&O8*aW9$u zZOOlWeZTt5A2^Ur)t-VTiThz{VgL^*sz}&{RdwFVZ3(`6@uTVo7v=(Ge8EQATRsI{ z^WnDltDRz<8k6U+?#(X)E_j-CsAKX0zC95Kjx(|B@86LayR;8A!>FFWL?N%o1+ks8 ziZ#AWF2T;fnCTc=3$&qteU|-Z{_&JbBiS3EHXlZgOFXTZ$0My72Hg0!OYo+LUhNg5 z70D-S-mP|g3rl5kdwRNc33-;Bb&_db6H`JPD^GjlL%hixW(=&w4#>;=LeXmMy?u(u zLQI3QuLt?pqf3!{Cku`f+R`UBR*v;n84kRN<&TlMeR6}*cI6-`B2i7kvaFDi7Y|e# zBn|#9$_`n}e^}hLnVD&Kg1;*oKMHW6@)v9^g$Mdw+ILBQdAQ69mx#O1fjMI@Op#Mc z&y;!F{@(pWE>75!S(m71!iPGW_lL$Y^pD-SmA|9!wrh^*Uf+p4&M#6C@|Q)dxQbrd zETy%Ft6IWl!V8qbCrn-GJL;|a^G&c`+e;c$Q73vt6YuXf1{AG1Eym^=jlTr@Vc(#* zDwaIpBa6}t6!iApeo0~oK22DPeia|e4E%7QNW6xYve}s z9)7d+4HZqR$fc24D^bu=z3UJ+3;b>F;RBa-OZs)|>*f92x%=}F!CFu=ax<|7BZe-L zI%F%FhN8jAv406Z?R{X?bem~JH67Kv&bx@ z0;rlk3(igGcM3-qz#ACuh>b^+OyIHFv)7C-tCn|67L@Ym%0B@@lhcqiS_A*M(A3wB+0r5qwxDBoCx zTZ&YgL?h1Uhuq<9L5M~}w;ZWE7Ho$fdx zSLYWuK_{f~`NXPjF#gPCr?E4JBR;HJ167W-bgWX!P-=(Aa|t^=jj2nqs!y3KGT z_Qj4KyLS#j*heO3XLu?s$G~WA_Qxw8^u{gQCkN_Vff(CS&s&pn$>mpA9G}nC4K}Ou z&w~4*t#8H7awM(HZ?A9%)|DIMdk!MVEB3?mJtfbh&0~6 zBj@1!a;7EE=y)m#mOvc8RFYaRU8qy_2gP`u^2(dxU^vY9>fcSIm8e+tCBe>PO85twF1Y)@#!XY>d2B06~sgiqzYC47{w z-zgTg5@N5XGrWOp_=8?!OQ8*jSfGFpCAH)Jm}uWT-ckmt!RGjJxAk^9gMO#wbtl&r z7FTeskQaEDN+fN-go@&S8vhy=w>Cy>bso`sGfpR5EOPe| zHsRkm>r695tCEW+U)^5zn`jy>@P4Iij6tj%?ACI8^@{Dk`X^%<47g7x4)|Gq`$Hl|{0C7!+$9tW@vn zIOYwDMII!VJN0T@(vRvtZ9H|Tr#s_wJ?LU-qgvb6+)t zn6*^SBtgxgX~_z~*9xM|6vrWL)@L%(tk>cAl?p>UZFx%v17I z#iK%@G~!e-%#;hzYkxp_VSRNttOXmiTO0O>E7@^bEU?sjO735bDff)QXxe6uyjYCY z*pqsWCWJOR-d(=(tpt9V7)4=fOA+H*1flUmpK)0u<~qm{P@j-EZT(!g%ezJ&X4i&% z(B#BSS*(pSTsmLfoT_b0(D`Nqzx;ouTy)WdW|P!L`ksm7b0c+tsfZfn30`ywyiT-*cy$+BS!l;Qz#%Om6;{7>9q_{zB4cr2FN$6@In{ zrkE*EHtp1>1p_KT_-s0pe;9rt^~WdeHh%G4X@WOg!hBldTqc`*v_-i;=Ta7$m{cAt zHBwBBz#dHhPJ+#liovwu-8)}XUU%|sib9*6XFef|83J1!EyOx1ohXzJRN>b=xIf1 z_}_@=iJE<0e+_VF7|N8cpjU5U@`+@Rx5CKb+dB;Sg7>|*?S2=_0lS)D*U60OQ&CzS zD*(12*q3S=9b_0H}nAix7AuXVCYS+d^ zQ0#veFB{J45!n*u(m%M{{nK({QSlAG$iN~LhB_&ro{rVFEg3!PU6t)+P4U1q>cTH( zX@TIciK7Z~;?NKOV$?(bvDGn_G7Nyrp$@eVG%|_il5qVV1hGtYLVL3tLkOe^G=vrZ z&`6nf>aUkTmpNaS9*DK{ccb>Zw_f60RwW6Xk7xo)`2r6GwdsjOC4Sg|^uAK3){ zEm!p5x=0i30dIPWzFh2INL>A+G~UiaWJ=H=xcL4`GTbC_t*#bbC9~>$Dfp$fZrAgP zt+^+EdhgI2pIQz}p$s{3Dk#o$1`mf8sIJr}K3Ec<#xOhFu8+6)!L9F4k4L)YSnvs& z6&mT0XpkP+t5DY6mR2oH_gcfUWk$aC1?Kf$t+%fI6w*Lu3$Y!(C*Z-|p=~hXrH>Lx zF{0b)i437=@!VRj+*?X#o__hU1o>adR6L5bt>lfsFr=BWN9hOA`=S{4%XcnnCSwLE_k9I__ zv{VhJEl&6Mc2i+5uhI?MaL5ZZGo)}#q7sYmso+zwe5hgnV0oKQBdo!C8X7&I&}V(g z+{WMPhWR|@ezz&K_J*6~&m%Wo z3Jsh?Bza5n5mxlEMR7dgnwk{|L?K}~v#B6?D>%VuxwCwOTc-Y6*!~{S_qD^miOVMu zio=vI3YjV{?oIY4Nn*(kNZWq;p*Ws$&*g{`fV1#EVHztESyYExM6?CF!~b@u zLPuNMI|QQuL-Flc-1=~sI=x-XTxIV&01L0%f{EC_asuK7na<$3PP*hXw3G&O91hPP zzjdw*fcm9%6=T?r(qUH@63fI%d9W+}n;Z-;0)QL&x5&PqEA;?TFsH^vfK=VoHw~Q% zjQXher!QOl1a7mSnks@29%GKM9Ly|SDuM?8_H=y=X!G;#VQcqGkWk(NcNle9kd#lE zIyna_sRDX$OsYgoEwY}qIg!p?xGROT$6YOx$bAB0R(3Y~XpG#1@1rUk9HM!XaGZ*dKALWdC-(tEp7g!;PEk2x(%$hpv6#szKUJ4W9}!ul=UzK4gJv zn!8NSnf{0u@5!CcYR^X4V}qP7HSW={gTS$`XVDjMS_V;;qWbF(9QS0N>rgsGTD%P@ zmR^^jl<##vNMd(ny~iS5y?abX@bukJ2$|+VP#{1Oeik2zWI9|l^te&FW}q%K>XQ~7 zh<9s_+fSzb=~ahHzkmr>Z2drpAOhl_o)A?D512@bfrAK0RwA!S1~LpEvIlrNJ&Ye5tLKt$H@2Lf#s*g#w{hyQ5LY=rHy=aW^vu6RA}m1=rNrpsxrDWuLDyi?L! zbgY(_x~!n98DS?cQ~k8Y@Bz1m;G%`)V9F*|DEM@et5*C?cvLKFtcd+k7KJoX@L1M} zvfT@R&ahoLDc$#8Z8Vu8wkk}vD$jv*a24Snu+C#*_(mLmFdmE=JB5~7iz?Gk`9t-K z3%?qReZeRCqVx+N_%uCR_uLox6&=b3Vrm4CKiU*tK^e0SKOjKX>FeS7e1S*-puoSf zspmnYHBKDS#z^%l_=#`K5quYAnInddX#?+X6=kHn&)(T7d?xq?C1tkXzf7PSKjo~= ztQZNpk+&|pqZQC|3AtmuCKs|=CCYnEflfq@QND-SQp8lu!B+fXAPi;2)I9(ATox}c z9~-oKMh}V4|2uFyIXN7^VAa;LSRz4>ZCBJrr?8%LL#UKd*};hMN%yCNd03vA&neZv z#xMV6@^tjALukR*hoCX zA%}0$GI51CQDlvUp3KCQ2O=H#Cfzviz_zZ1#b()-dqz*4DrHFgR6gfUI+9OfrS9)v ziObZ0dpAdRrXS|fLGSWiDR`)-qxpRqqjCeoPkP>|Q=F4@oELg~mLTSX5HHU>+2nT$ z_3xA{N>#rwn~fWm<-ujFg*hRUnfJtMfgTXM#I;yn8OGXAr&$>(|NQ8+Mb*jT233sH zorgdj{w@|Q8i(@>{61Qdyl!F;MWhudo-yP6U6!?xmZFyFvSG0(LG!y6ZJjDe`-sdQ zgwl1ZkTQPE>Qaw4LNkP>tonW_ z@)toDvTl0)F?ziRLC-gLV2L1gk&QH(6#eRWlF^)>vO`4iv>6z~SHTlh@bAulleh#uyNQf_?e`+ZZ~bG{dS z=N=f2i+)HoYjGQ8kG=#_O>F;0m->N8w*!+l?wxQ|;m6QW-JHHp`XD)JjIxQkX@# z;Yl=ewYb*y^+D+J+cgj{3-7yatxtiEPg%8B^+Uu_sGm_->-U3U`VJli80|KI$1*xv>u2iZ5_RgkN~frRbi4KG6JBneL#d$(H}W#$Td?LEiBFi#E$i=+k3TuUgnmDCPD}Q z(Yl}FOq4%_{e}3n;kZe`4w>H#mnD}MePkE^5YF{Fn+p$Lw$9!*1@Pg$%AO@>F3sqj4adG}^o;=sTX7&JVVuKh>9n1$)UhoNLaz0$0 za=Ny&bI8sdcKa2*G8@(l^iY{-BxbH9f~NdxYbcwDbe(xJHA}63wc+@eJAim_gHuLO zh}TjEVja`9l*{rX;y3({X1h|f5BAc+!cX&nKfl-Zu@K<`Oh>w$QY*&?W5WcQPJ1R> zhqI6Lyc|l(it04-uAu`K(E5=K(Z8n#?gGTv;h(78S%FmAKzJ_agCN03#>t!s@?Gkk zfx}OQMakbya!|j#_n3W~cTL4Bx^Di=mNd zs=JrQuAk~|=HGIPL4(;vGcZWX7mmqwBV5l!+68IZVI+SHIx&(2P_UL~2FFxYliv3r zzzXe4P?YwiC*z0Kf>N@#o<~~?a=8eKc?SQ_yjrq*?(#6cwKVs{pQ7jo=?ybNE2Npf zRCRXhGX??=)ItVy*-cmh?GgCZ0`D}paYr`>#%Aiz)Jj>)Y8lXF2&R-S zBqaz6s}GDnIG|;%?ZCF_)Q$=#(68jY{4LOtFx1SD(N3zDT3@kDJ+@dsuPsS*H$hx# zxD3w|%1|P9tUH;HMYe}J5VxzxzcA#Wt2O3%IfQsYYrCKyHLX<~LnRBC#%^x~7>D5e?Yat@u?+O7h0qgz+uJB(XTan8BUe`HecN0wI`H5niNA zmW)?T8x`A)V@QG9&0oNl$z;)~+==TLQ7)s|3r1s4u>xTLpY%CnwPdsp+X;iA;Y zV+ym{eYzz(%e`0Xm;WESD*gJ);Eq9$5Pq|2Tz0QlpMIm2oP~jPss;GGl?iwK5NV3U z66n6hk#y;F3ZoHj?s@f5w!qz@Qe2zPOaD`B42(^?d~xNLI$7}?%uiGMmt6xC=NWs^ zo%!H&$HB4Rs?jrJiUwBk2($Vx->_-JP^YBHgF&yNM&Q#DL-TpW^kIQAsW?O<|JP$+ zr^)YC1Cfk_B)?JxuZuaO5f9ulrw{KDOcVYUzyaHj%?MoM|MNQ_T0Vn~KA5yP{o!#P zfrRw_uDi@X`&w{7Mz}78EtK1lClgeC?sY=Xp_)$qxl^w@kGb`VMO=+YBox;W<^?Z0 z=7taF;{9&&G{bU=Wn0cfxb^n0rtbHn-kz8}9AY`kBpNvcjY6}9Fgv(x-ttpGX9cf$ zZx~9LV?e!%Q2uXG)CFiAmIW!736&%FN;hpx)Lf&fYIRGD#1-_T#s~gVI@Z!}c#p50 zotFk+fpfGPFpp8b_fZ`GxLnW*IzpOH-<-H7WljvfsdYA`XHERPl9c^=yc{VnSxKE; zq&^dmx7maK4rH??8f0bo&kNOggzuvXVirIYwru|g)!!=N%tCOdt&Jf?9h%+6*z`Mmmfs$(CN%SkvT$t;O`GDg(8TW#=rWj^}F#H_Fq!QwYQX4 z$j6Z}r!E&+%+ROhoUFTzc9WZ~u_s@~4^QWF(L)O!k%TeRFsP^-{N1F8K9cuP_KeKD zstYPUYyXod|6gouNJAQIubf)7xvn7VBL!4A6l4{#U!1KE6_dmG(2kPwt+-g&wrIq;nMEk2U5yDHb%3S{H$0+M3_UM zKyCff6VgJ8Qr5f*vQ)=^9?Z3*(4th)NP&J;jK)32Eq=6RlzzN_T`Y?+tVHj^DrMfz zzAnqU8@^a7E?)elwxTvh`L1{)wCy*3G?|)j&zlt0nPa5p5F9)QQ1jFHfa2%KvVymv z;lIG##n_Yn=q|;_M-)42580^JXzgk-=OV-9aDq@XjI*!;GECUZ1%VIV6OEUwmRtY= z>8}{e4NFz^9-goai8_7DSC3R>9QjVID=)rSgiyW)ZiO+;u)vZcA0?%Y{%_btT}2Q> zBzOh`zBVgBrl}!Hd`sfWe6;X#)dVlpF=Ak!ad^g9M@{RenImEez52&T#x!=pp4%n| zf!Fv+e^vF)Ll7iHn|H$MUtb{IAe}g@tdt(Ie~`__Y|k4X98T&E#}9)qLNdg zl*9pyH6|cJii~@kpU0)|3v1dDeLAP#vPy-b4(~R@609}nwJTmF-#bzmj3P{L$U2gH z^q7_Y1g%DLHBfG-F$*XZp)feTy+%}0JBDxa8t5M}va_vdf9-pI87@ulG{aLCWD_SA zj{W6|tzWeR(ghL6Sa{*e-;LgAjx2eX!gHDsgRm+}%UL{G6M ze{5JhuT=^>L0-=)XXZkL63(Uzhe>G{CBp|I-G-jvt@z3y+f|J$vl-(=!`c*_m zTFe{4B=VRGo*b7h0d>DDJ);Z}P>s-z@+=cwNq%)6-v&gcw)WJ@x5yXwn{mX)U-lM} zH$ZHR%fo-+mw6=+OwA`wX>k|77vgp3Z-?~*7NDh0oa~lAQOBg2Pf2PZ(nLW?7XJo6 z=7=59O~q9)O+QgQ<|tz5UHXW~J8Qfye$_C4>9tV*B?8w8k+&^i7{wgK`==ER>7%gN zhGYHr-p=!WWm>lktu3c^z=e>+6Sywg$yasRRGs845SYpqjpGH=Y>3+x;LB*JnEvVc zb=~pkw!|ywVengxh|BZF&e!tEWY+jLL}r_UV{0FN5MzL zgAujH59{k`0e$G zy~)JYe>Lnxqz&*m4Yj^OYes2PSazB9^ zj1!hD)P$NqEFO|(9a(4O{xZ#A3fZ@>-6!`o=ckK$&&Zq*bdjr7TUFd#idq5s4fSxh z#`jaKlsxNd>s5Gr2aw-( zs~u&GozE%10ON6yl!8bsFTKd@-U)RgNkGp7UEj4X9sE)dqPN%NMT=zkg02F7A|xZY z?CXyvg;8p@QzuXZ>@+W0gRM(0s8m&v=-x~L%B}PinCfR6dFQOs<|ne#d3l+dagJlA@0g|!l7w^MRoW+aVjG2DmpQ!7qTN> z2Y-Z1JNV3y1x-yX4(T=hnRLM=q@BS?7qyo%o?W2}sdwWiTq3;uLcnhd>WG>V(If;r zj^J*;WEuEK4vIh>qh>u};!#R=*Y<&j8$INk?Tq)~);w%Tang!_b(ph64Bzd(T5jHhn>@z4 zZZT%oVB~=Ca6LqMAUCfx2rf}c2t6VEcZzqZtpW;UWJkBQqLgvHKPhU`W+9vkKRcFB zK!1*w>Jn8tvVwB0&#qgpB042>qiMVJa{Pj&1%bbK-WscHZZutT&D_ehemowGk5G<1 zf#)EWGi^I1zb0+VTRGBN)c*SHU(sA1(Pn9*X-4Y_nF?_jQ z#jDoeb+?{7d>W`wMQ&K&7Y}g9_$me+U3Y=MN_q);=8&e*oUqm84uBHV3P)R8g_)o1 zrjmnp_Gx^vM=A9&4kG9J8MgVsR@kmJy0T8nUlgUG5F5<@;ydUi8W(S)#dsTGVWZP? zxGM{k-9`*i?*SmH-(KMxp#MS=SL6G%d$@z^m!EeB=eENt6f9;$oThN2fVRRMir|SE z(lIs~p_p4ValKqE1Qz73TeP`hbzM*rs06F%3)dGs*a-Ua0}1`QUqV+is?-6Z?<+!Z zAZS!xnATg`p9stUxg$r(T|InxZTSmv?hOw|KlT8_w}r)8)Df=c8guR{UZw8LXe4<# zCs_pqb?o1U^h-LO)fHEIsb`D%&yg0gN4HY4YW^TWYa=`qopjD2o8*%Ei5*kh+F825zmm`=G=s^US z`FRu4(-jD>h|B8bj~jYEJe3|sqk-C*J>RQILz@uUGgx)`-cL9qLqB^YQW)me6=iN8m~nxadBs!xHD;GS|S{(OC4b|ME||$F*0RXk_(O<&4%04 z_2+HEz`zPBk*tVv!2)*gAYy%FQHURjo*7SA?+B+o0SJmH^fJCX3T7affj9gUxu0^= zoY%eh;S0(AY>v4}u3S1Evhz`ghG>Jzc>gSCTDkno*!<)zn>io58R&^qF^?6+;%xH% zxG(kO#dWr5v`D|MMWw}T8avW##?=FD`8;hi%`_Tw{@_j}4P1WZLsD);jgqD|5+Q41 zCxSeHSZsz^pt<(NyZJpxnOUli8Lxea%@ONw;2@bx7jY`}oK1VnO;tmmW z=DbwdEfTpm=^IAZ@jJ@L{zim{4Mla0(Nu#Jugibx^So{=!LtFO=t$rRea!Wa{mHjSd2Vc@PhJlj^)^_hE43#916>L@56VvIM(pEc zLCr&(K&_iB$yvYkXf%=f7s2688B~x7eU*B`hiaIiNvI?iOvd+}fIBUh=|Z+|d_81yU7n7jvEKz*=LoeUnlQK%aelxB!4luD$K5~HQa9srm4eMW&w4a7bAbinj!0sJOpY7`G{e=c+HBQx3*RbrI>1H*VilUv z)g(7u_Y!6S$QRbYpZ+EvD|PExB}RkW+Esmy4G83f;>9Q7s)HN7A7a0hcK`&VltjFZ zqF)I*n*TE*l=m*K`_^P3SR#MDB8w-hRe}#o6GX{+5>l3fn-${#Cm2aF>Qm!HUU_g( z>sBu6O5>~nZU$Q0+DwyqiYGJLW3AV}xKHPPStFN|t;4u3-IFyZIk_%9+_yt02b{%R zmKsXtAeXuIiMlADsH^%_|G36CwP?0dA?_#J+oO=0ab9^Nr;Z#D?J)Lr487OWK;`!D zfH6uud#M4+uhm02^XAf|$nLMlqT~&;=!Yw#ygfHPCCgFBXZlD}Av;a5f3QtSEktE= z_6!Cv_O6Bzip`9c3f6+AE}zx?&C>y3xiNDaAvmtn&Fp^o#``*)C#9k8uHpj+$bM{Hl2>5HQp zxrFZf#udFPL0MWPq8)&qBWcrZQ`C#$8l(9k-w=+<-IPtb+G6Bdgw6=Mssg%duR}Ji z6wLANY$@XBe&pWK?`*^5+RjZiy649jk${!%TPwwgE@q5G$gP+wiF2MD`e108U=jT5 zh<$;e&?;ac=={1VmNvSK*=R8Tq(IIFAaqmc`B~}|4H2uOaz8zo{1&Z{N6!#c7L6iC z=#7&gQ938dwDKuXbaGPcjB!WD&qs&L=Qks?xjjf6QCPYQuU$0n_DI@KjibfCRQT)c z8;x4?lGGT%k#A)~%gnj*T68C#(7fezP(#a5E(-+t^Anr>56pFA%cU`c+{_%rPB4ud zR=r@@n)CV<7mA2ukwN9^47n(7)-3eh5=k|JJdp`Z+6Q(O4>M>-qHaiJGCM_p;HFTA zC$V$IEEhZn5h@G%{y-d{)%GVytfC3ta#!>xk&;%QWZ%@xOc|5oq~(vMn+aw8rVx$f zEg#R;9N8lgpG1Akj1DFAeP!l%fz65htq)gw=cTi|H@mAg%VYX`Tsr!EvY+k?cqwt^ z;3Rkv<{{W12otjkWEwZu&#Ht(m#&Eby_UCIe}$n=beKA~qE&x-8xb~&@WhHcmlafceG&fhh5GS$ zV}T(QPo$%a&6u``ldn|__|T9L65VLZh=#e0cT`~9?|XW%b0~!&hN>??1i-{}&@+7c zr3SJ5ZapvxBhg}5o7UAZxsgp{=K4nw3CEC-rqz!1FCVvW*rRP&k0Ef%{Ov&6REZig zp>*~ugm&>K+zUSAt^onR&}4}v1|gy@=q2lQ=z*y3Bi!Vj5TiqPGM~L+{|L3jX9AwS zx#A2n!;2C2%la(wW+978v9vx1aRiy!Lr&l0y@iMM8>^4jhzr2S!^g+P%g4pTug&}F z&8t^$`1lcV*&807m>jD=|CfLhqU!R4&;MWGp=Ta(;u&E5KRtNZIa#}VSU9=0ff85vgq}f`VA4A9@001~furR&K zN7A9gVf;upy3r2+U{U}cZ%e@AQFp>aeFK7g0N`wHTrS3fZhWf8bM%Uts{A+9*PQZ; zE~1hVW2zG6xZfqOM`*SD5H8kLRME&H2X=L3_f#dOH`E@lC8PGhuS-nolDraEQ@t_u z`;vOl)j>`uB4i zcN4NaF8H1AR2Cc3rZ=YPr&j6(CvF*qB}w`e>^+ShqY8^*!`%ZmzY%t7HyB$e`S zC|s_#ewZxrtq;RVto4+CgsT;kHaKZ}A2zX_$m`k&so``->!?TwwtAdeyd@1^hh!Gd z#Ud|R&p}yO0q2-0&ldtZWz_M>>p$R2Q!tI%sp5J;w{<|kCMD=YEwfUExz)**iL*Zm zpM_uo2N~Dd=r~|x%yAQjMnf+n^4r(Hudjb(a51AR8-g)e;Z+OtTxZ z_;8;aL?3TdQ~=Q*WlpfNb-sUG3ILA42&N_u(UadwUfq=^NT+xfiNC->O@hP7A1vI4 z1IdO_xvLuMOs;xvZkVz`l-SXTJoML;cXbjsMIGj+)0SHX)?dp(X7IZMTMkyiPT+yj zLEH>IyO2Nr-}3CX?#d>PjWlXfl6)0M{dvLD#vTgSU;6CU)2TVDK%#!r=h-MKIf_5G zD<2kIXx+~O`dC;{QC)FRaj*)7e~v3(On7q|ODq<)Jt89u!jP7-S6VgB|G;}k=joQd zsuY4WALI6Ns&HI+Dp(k9eB-LPH_R4F}&$b0%{=JeCHW7G^e2-_t#z8+IlOBEhPICUYs zuJB4!cv8&$5TV0o3-yxCA)tT{lIiv5Zv3S08qCBAXjmDV9rD{jYIddfyWj6eXnA*p znvq-|tyWghClcsYvy-)7dNTsFB)$Hq!e)FA(q^x^A1NN-#yH=vn4g$++Q~fa+wny8 zPH^w%DTLOY_Rt!Gzxt#=(azgHJ8sTyaA=(cgL=c>JL7E#6aca1u1>>(97#nrp3AQ9 zr1@oXp!LsR&YnY3lXOR5#f-rLc zY79Wp;1<2lb@OaVO(wD=WZzpMAIpG~0KQdHiiAIOO&&IWn&pzI;V60R zEHthOId<-^l{KT&-pb_F48*h1CrGNIy=ze}V0fVUv=sW+S!}qARY{3d-Gut6b@gs` z{oU|e^@a~SlrRJ1_I|E`<4EDM$4T8&ftGSEp^TRe!xM9?VvFS>*O^Kxx<;H4nLV;fue-%O2prY(QXmq|3V>56$A zPlS-YwM}%C0TFFv&16*)l>H`FgwJ^Vl~@=P)9fO0F6T?z-?MGgnf2NY!{yi6zfz5N2gUuSP!qeFbaqsHlcPZ=vtvNMz{H2bwR#F=9jdqavm# zjywH8S>mU*_JUED+k|<)W(L$TK9HOV6YWQfjrfmJ7U|NS%Z&tne~ Xz Date: Sun, 4 Dec 2022 16:45:31 +0100 Subject: [PATCH 042/132] Add support for single-line comments to scss (#5003) --- runtime/queries/scss/highlights.scm | 2 +- runtime/queries/scss/injections.scm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/queries/scss/highlights.scm b/runtime/queries/scss/highlights.scm index 89cce494..8ba00a88 100644 --- a/runtime/queries/scss/highlights.scm +++ b/runtime/queries/scss/highlights.scm @@ -1,4 +1,4 @@ -(comment) @comment +[(comment) (single_line_comment)] @comment "~" @operator ">" @operator diff --git a/runtime/queries/scss/injections.scm b/runtime/queries/scss/injections.scm index 321c90ad..350ea9e7 100644 --- a/runtime/queries/scss/injections.scm +++ b/runtime/queries/scss/injections.scm @@ -1,2 +1,2 @@ -((comment) @injection.content +([(comment) (single_line_comment)] @injection.content (#set! injection.language "comment")) From 417676953bce6a4be91f4b8da35ed0e361b585ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 5 Dec 2022 14:40:41 +0900 Subject: [PATCH 043/132] Add basic support for common lisp --- languages.toml | 15 +++++++++++++-- runtime/queries/common-lisp/highlights.scm | 1 + runtime/queries/common-lisp/injections.scm | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 runtime/queries/common-lisp/highlights.scm create mode 100644 runtime/queries/common-lisp/injections.scm diff --git a/languages.toml b/languages.toml index d214a082..325a39df 100644 --- a/languages.toml +++ b/languages.toml @@ -878,14 +878,25 @@ source = { git = "https://github.com/ganezdragon/tree-sitter-perl", rev = "0ac2c [[language]] name = "racket" -scope = "source.rkt" +scope = "source.racket" roots = [] -file-types = ["rkt"] +file-types = ["rkt", "rktd", "rktl", "scrbl"] shebangs = ["racket"] comment-token = ";" language-server = { command = "racket", args = ["-l", "racket-langserver"] } grammar = "scheme" +[[language]] +name = "common-lisp" +scope = "source.lisp" +roots = [] +file-types = ["lisp", "asd", "cl", "l", "lsp", "ny"," podsl", "sexp"] +shebangs = ["lisp", "sbcl", "ccl", "clisp", "ecl"] +comment-token = ";" +indent = { tab-width = 2, unit = " " } +language-server = { command = "cl-lsp", args = [ "stdio" ] } +grammar = "scheme" + [[language]] name = "comment" scope = "scope.comment" diff --git a/runtime/queries/common-lisp/highlights.scm b/runtime/queries/common-lisp/highlights.scm new file mode 100644 index 00000000..e11eb788 --- /dev/null +++ b/runtime/queries/common-lisp/highlights.scm @@ -0,0 +1 @@ +; inherits: scheme diff --git a/runtime/queries/common-lisp/injections.scm b/runtime/queries/common-lisp/injections.scm new file mode 100644 index 00000000..e11eb788 --- /dev/null +++ b/runtime/queries/common-lisp/injections.scm @@ -0,0 +1 @@ +; inherits: scheme From 03ca18b377c1dfd78e8ff6bfac6d418de237923b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 5 Dec 2022 15:02:13 +0900 Subject: [PATCH 044/132] Update language support docs --- book/src/generated/lang-support.md | 1 + 1 file changed, 1 insertion(+) diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index b1fde001..ccfd18c0 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -12,6 +12,7 @@ | clojure | ✓ | | | `clojure-lsp` | | cmake | ✓ | ✓ | ✓ | `cmake-language-server` | | comment | ✓ | | | | +| common-lisp | ✓ | | | `cl-lsp` | | cpon | ✓ | | ✓ | | | cpp | ✓ | ✓ | ✓ | `clangd` | | css | ✓ | | | `vscode-css-language-server` | From 1e31bc3f77040d4a3663b8b6bf72d8d3a632b88a Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Mon, 5 Dec 2022 14:18:42 +0100 Subject: [PATCH 045/132] Reduce log message about diff timeout from warn to info (#5012) --- helix-vcs/src/diff/worker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-vcs/src/diff/worker.rs b/helix-vcs/src/diff/worker.rs index b8659c9b..f4bb4dbf 100644 --- a/helix-vcs/src/diff/worker.rs +++ b/helix-vcs/src/diff/worker.rs @@ -185,7 +185,7 @@ impl<'a> EventAccumulator { } // Diff failed to complete in time log the event // and wait until the diff occurs to trigger an async redraw - log::warn!("Diff computation timed out, update of diffs might appear delayed"); + log::info!("Diff computation timed out, update of diffs might appear delayed"); diff_finished_notify.notified().await; redraw_notify.notify_one(); }); From b0f20f13e3a606cba35cc70144f045a22b5b38bc Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Mon, 5 Dec 2022 14:46:59 +0100 Subject: [PATCH 046/132] fix git diff when core.autocrlf is enabled (#4995) --- helix-vcs/src/git.rs | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/helix-vcs/src/git.rs b/helix-vcs/src/git.rs index 82b2b558..432159b6 100644 --- a/helix-vcs/src/git.rs +++ b/helix-vcs/src/git.rs @@ -17,14 +17,17 @@ impl Git { // custom open options let mut git_open_opts_map = git::sec::trust::Mapping::::default(); - // don't use the global git configs (not needed) + // On windows various configuration options are bundled as part of the installations + // This path depends on the install location of git and therefore requires some overhead to lookup + // This is basically only used on windows and has some overhead hence it's disabled on other platforms. + // `gitoxide` doesn't use this as default let config = git::permissions::Config { - system: false, - git: false, - user: false, + system: true, + git: true, + user: true, env: true, includes: true, - git_binary: false, + git_binary: cfg!(windows), }; // change options for config permissions without touching anything else git_open_opts_map.reduced = git_open_opts_map.reduced.permissions(git::Permissions { @@ -61,7 +64,29 @@ impl DiffProvider for Git { let file_oid = find_file_in_commit(&repo, &head, file)?; let file_object = repo.find_object(file_oid).ok()?; - Some(file_object.detach().data) + let mut data = file_object.detach().data; + // convert LF to CRLF if configured to avoid showing every line as changed + if repo + .config_snapshot() + .boolean("core.autocrlf") + .unwrap_or(false) + { + let mut normalized_file = Vec::with_capacity(data.len()); + let mut at_cr = false; + for &byte in &data { + if byte == b'\n' { + // if this is a LF instead of a CRLF (last byte was not a CR) + // insert a new CR to generate a CRLF + if !at_cr { + normalized_file.push(b'\r'); + } + } + at_cr = byte == b'\r'; + normalized_file.push(byte) + } + data = normalized_file + } + Some(data) } } From f712d316e5d210e95f9d297651f1d753646c26d2 Mon Sep 17 00:00:00 2001 From: two-six Date: Mon, 5 Dec 2022 14:48:20 +0100 Subject: [PATCH 047/132] Update Acme and Nord Light for git gutters (#4999) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update acme.toml * Update nord_light.toml * Update runtime/themes/nord_light.toml Co-authored-by: Blaž Hrastnik * Update acme.toml Co-authored-by: Blaž Hrastnik --- runtime/themes/acme.toml | 3 +++ runtime/themes/nord_light.toml | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/runtime/themes/acme.toml b/runtime/themes/acme.toml index d3be695c..696a4a9b 100644 --- a/runtime/themes/acme.toml +++ b/runtime/themes/acme.toml @@ -22,6 +22,9 @@ "diagnostic.hint" = {bg="white", modifiers=["bold"]} "ui.bufferline" = { fg = "indent", bg = "acme_bar_bg" } "ui.bufferline.active" = { fg = "black", bg = "acme_bg" } +"diff.plus" = {fg = "green"} +"diff.delta" = {fg = "acme_bar_bg"} +"diff.minus" = {fg = "red"} [palette] white = "#ffffff" diff --git a/runtime/themes/nord_light.toml b/runtime/themes/nord_light.toml index 5270fe34..eb947d03 100644 --- a/runtime/themes/nord_light.toml +++ b/runtime/themes/nord_light.toml @@ -58,6 +58,10 @@ "markup.link.text" = {fg="nord12"} "markup.quote" = {fg="nord3", modifiers=["italic"]} +"diff.plus" = {fg = "nord14"} +"diff.delta" = {fg = "nord13"} +"diff.minus" = {fg = "nord11"} + [palette] nord0 = "#2E3440" From 5781aa026417bc6539b80b451da4a99a7057bbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Mon, 5 Dec 2022 16:16:25 +0100 Subject: [PATCH 048/132] feat(highlights): go builtin funcs and types (#5010) Add highlight scopes for golang built-in functions and types. Based on https://pkg.go.dev/builtin. --- runtime/queries/go/highlights.scm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runtime/queries/go/highlights.scm b/runtime/queries/go/highlights.scm index 4ff8675b..927bd95b 100644 --- a/runtime/queries/go/highlights.scm +++ b/runtime/queries/go/highlights.scm @@ -1,5 +1,9 @@ ; Function calls +(call_expression + function: (identifier) @function.builtin + (match? @function.builtin "^(append|cap|close|complex|copy|delete|imag|len|make|new|panic|print|println|real|recover)$")) + (call_expression function: (identifier) @function) @@ -24,6 +28,9 @@ (parameter_declaration (identifier) @variable.parameter) (variadic_parameter_declaration (identifier) @variable.parameter) +((type_identifier) @type.builtin + (match? @type.builtin "^(any|bool|byte|comparable|complex128|complex64|error|float32|float64|int|int16|int32|int64|int8|rune|string|uint|uint16|uint32|uint64|uint8|uintptr)$")) + (type_identifier) @type (field_identifier) @variable.other.member (identifier) @variable From 5691ada822a7c6e27f8890ee25f52a9262caddd2 Mon Sep 17 00:00:00 2001 From: VuiMuich Date: Mon, 5 Dec 2022 23:28:20 +0100 Subject: [PATCH 049/132] Change diff colors for serika themes (#5015) --- runtime/themes/serika-dark.toml | 2 +- runtime/themes/serika-light.toml | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/runtime/themes/serika-dark.toml b/runtime/themes/serika-dark.toml index 88e4cf6d..2b4000ac 100644 --- a/runtime/themes/serika-dark.toml +++ b/runtime/themes/serika-dark.toml @@ -61,7 +61,7 @@ "diff.plus" = { fg = "green" } "diff.delta" = { fg = "orange" } -"diff.minus" = { fg = "red" } +"diff.minus" = { fg = "nasty-red" } "markup.heading" = { fg = "purple", modifiers = ["bold"] } "markup.list" = "cyan" diff --git a/runtime/themes/serika-light.toml b/runtime/themes/serika-light.toml index a00274bb..ad830d92 100644 --- a/runtime/themes/serika-light.toml +++ b/runtime/themes/serika-light.toml @@ -59,9 +59,9 @@ "error" = "nasty-red" "diagnostic" = { fg = "nasty-red", modifiers = ["underlined"] } -"diff.plus" = { fg = "green" } -"diff.delta" = { fg = "orange" } -"diff.minus" = { fg = "red" } +"diff.plus" = { fg = "bg_green" +"diff.delta" = { fg = "bg_blue" } +"diff.minus" = { fg = "nasty-red" } "markup.heading" = { fg = "purple", modifiers = ["bold"] } "markup.list" = "cyan" @@ -72,7 +72,6 @@ "markup.quote" = { fg = "yellow", modifiers = ["italic"] } "markup.raw" = { fg = "fg" } - [palette] bg0 = "#e1e1e3" From 7210c58a51a16c0ae3c9d77211ed1a25e039bd9e Mon Sep 17 00:00:00 2001 From: nosa <96927121+n0s4@users.noreply.github.com> Date: Tue, 6 Dec 2022 01:13:41 +0000 Subject: [PATCH 050/132] Change default TS object bindings (#3782) * Change default TS object bindings Changes 'match inside/around' bindings for: - type definition from `c` to `t` - comments from `o` to `c` - tests from `t` to `T` Also changes those for the `]` / `[` bindings. * Update docs for changed keybinds Co-authored-by: Michael Davis --- book/src/keymap.md | 14 +++++++------- helix-term/src/commands.rs | 16 ++++++++-------- helix-term/src/keymap/default.rs | 12 ++++++------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 6523b09f..c3c09f4c 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -297,7 +297,7 @@ Displays documentation for item under cursor. | ---- | ----------- | | `Ctrl-u` | Scroll up | | `Ctrl-d` | Scroll down | - + #### Unimpaired Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaired). @@ -310,14 +310,14 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire | `]D` | Go to last diagnostic in document (**LSP**) | `goto_last_diag` | | `]f` | Go to next function (**TS**) | `goto_next_function` | | `[f` | Go to previous function (**TS**) | `goto_prev_function` | -| `]c` | Go to next class (**TS**) | `goto_next_class` | -| `[c` | Go to previous class (**TS**) | `goto_prev_class` | +| `]t` | Go to next type definition (**TS**) | `goto_next_class` | +| `[t` | Go to previous type definition (**TS**) | `goto_prev_class` | | `]a` | Go to next argument/parameter (**TS**) | `goto_next_parameter` | | `[a` | Go to previous argument/parameter (**TS**) | `goto_prev_parameter` | -| `]o` | Go to next comment (**TS**) | `goto_next_comment` | -| `[o` | Go to previous comment (**TS**) | `goto_prev_comment` | -| `]t` | Go to next test (**TS**) | `goto_next_test` | -| `]t` | Go to previous test (**TS**) | `goto_prev_test` | +| `]c` | Go to next comment (**TS**) | `goto_next_comment` | +| `[c` | Go to previous comment (**TS**) | `goto_prev_comment` | +| `]T` | Go to next test (**TS**) | `goto_next_test` | +| `]T` | Go to previous test (**TS**) | `goto_prev_test` | | `]p` | Go to next paragraph | `goto_next_paragraph` | | `[p` | Go to previous paragraph | `goto_prev_paragraph` | | `[Space` | Add newline above | `add_newline_above` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 4cd27119..31a2f582 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -402,8 +402,8 @@ impl MappableCommand { select_textobject_inner, "Select inside object", goto_next_function, "Goto next function", goto_prev_function, "Goto previous function", - goto_next_class, "Goto next class", - goto_prev_class, "Goto previous class", + goto_next_class, "Goto next type definition", + goto_prev_class, "Goto previous type definition", goto_next_parameter, "Goto next parameter", goto_prev_parameter, "Goto previous parameter", goto_next_comment, "Goto next comment", @@ -4520,11 +4520,11 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { match ch { 'w' => textobject::textobject_word(text, range, objtype, count, false), 'W' => textobject::textobject_word(text, range, objtype, count, true), - 'c' => textobject_treesitter("class", range), + 't' => textobject_treesitter("class", range), 'f' => textobject_treesitter("function", range), 'a' => textobject_treesitter("parameter", range), - 'o' => textobject_treesitter("comment", range), - 't' => textobject_treesitter("test", range), + 'c' => textobject_treesitter("comment", range), + 'T' => textobject_treesitter("test", range), 'p' => textobject::textobject_paragraph(text, range, objtype, count), 'm' => textobject::textobject_pair_surround_closest( text, range, objtype, count, @@ -4552,11 +4552,11 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { ("w", "Word"), ("W", "WORD"), ("p", "Paragraph"), - ("c", "Class (tree-sitter)"), + ("t", "Type definition (tree-sitter)"), ("f", "Function (tree-sitter)"), ("a", "Argument/parameter (tree-sitter)"), - ("o", "Comment (tree-sitter)"), - ("t", "Test (tree-sitter)"), + ("c", "Comment (tree-sitter)"), + ("T", "Test (tree-sitter)"), ("m", "Closest surrounding pair to cursor"), (" ", "... or any character acting as a pair"), ]; diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index c0d17a87..b6d9ea10 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -101,10 +101,10 @@ pub fn default() -> HashMap { "d" => goto_prev_diag, "D" => goto_first_diag, "f" => goto_prev_function, - "c" => goto_prev_class, + "t" => goto_prev_class, "a" => goto_prev_parameter, - "o" => goto_prev_comment, - "t" => goto_prev_test, + "c" => goto_prev_comment, + "T" => goto_prev_test, "p" => goto_prev_paragraph, "space" => add_newline_above, }, @@ -112,10 +112,10 @@ pub fn default() -> HashMap { "d" => goto_next_diag, "D" => goto_last_diag, "f" => goto_next_function, - "c" => goto_next_class, + "t" => goto_next_class, "a" => goto_next_parameter, - "o" => goto_next_comment, - "t" => goto_next_test, + "c" => goto_next_comment, + "T" => goto_next_test, "p" => goto_next_paragraph, "space" => add_newline_below, }, From 2077f5e26a4cdaadde4b505fc64eadb9e6849c0d Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Mon, 5 Dec 2022 19:29:40 -0600 Subject: [PATCH 051/132] Apply completion edits to all cursors (#4496) Completion edits - either basic `insert_text` strings or structured `text_edit`s - are assumed by the LSP spec to apply to the current cursor (or at least the trigger point). We can use the range (if any) and text given by the Language Server to create a transaction that changes all ranges in the current selection though, allowing auto- complete to affect multiple cursors. --- helix-lsp/src/lib.rs | 38 ++++++++++++++++++++++++++++++++- helix-term/src/ui/completion.rs | 31 +++++++++++++++++++++------ 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index abc930f8..f714395f 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -57,7 +57,7 @@ pub enum OffsetEncoding { pub mod util { use super::*; - use helix_core::{diagnostic::NumberOrString, Range, Rope, Transaction}; + use helix_core::{diagnostic::NumberOrString, Range, Rope, Selection, Tendril, Transaction}; /// Converts a diagnostic in the document to [`lsp::Diagnostic`]. /// @@ -196,6 +196,42 @@ pub mod util { Some(Range::new(start, end)) } + /// Creates a [Transaction] from the [lsp::TextEdit] in a completion response. + /// The transaction applies the edit to all cursors. + pub fn generate_transaction_from_completion_edit( + doc: &Rope, + selection: &Selection, + edit: lsp::TextEdit, + offset_encoding: OffsetEncoding, + ) -> Transaction { + let replacement: Option = if edit.new_text.is_empty() { + None + } else { + Some(edit.new_text.into()) + }; + + let text = doc.slice(..); + let primary_cursor = selection.primary().cursor(text); + + let start_offset = match lsp_pos_to_pos(doc, edit.range.start, offset_encoding) { + Some(start) => start as i128 - primary_cursor as i128, + None => return Transaction::new(doc), + }; + let end_offset = match lsp_pos_to_pos(doc, edit.range.end, offset_encoding) { + Some(end) => end as i128 - primary_cursor as i128, + None => return Transaction::new(doc), + }; + + Transaction::change_by_selection(doc, selection, |range| { + let cursor = range.cursor(text); + ( + (cursor as i128 + start_offset) as usize, + (cursor as i128 + end_offset) as usize, + replacement.clone(), + ) + }) + } + pub fn generate_transaction_from_edits( doc: &Rope, mut edits: Vec, diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index ebb4fb46..c54990e8 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -1,5 +1,5 @@ use crate::compositor::{Component, Context, Event, EventResult}; -use helix_view::{apply_transaction, editor::CompleteAction}; +use helix_view::{apply_transaction, editor::CompleteAction, ViewId}; use tui::buffer::Buffer as Surface; use tui::text::Spans; @@ -107,6 +107,7 @@ impl Completion { let menu = Menu::new(items, (), move |editor: &mut Editor, item, event| { fn item_to_transaction( doc: &Document, + view_id: ViewId, item: &CompletionItem, offset_encoding: helix_lsp::OffsetEncoding, start_offset: usize, @@ -121,9 +122,10 @@ impl Completion { } }; - util::generate_transaction_from_edits( + util::generate_transaction_from_completion_edit( doc.text(), - vec![edit], + doc.selection(view_id), + edit, offset_encoding, // TODO: should probably transcode in Client ) } else { @@ -132,10 +134,23 @@ impl Completion { // in these cases we need to check for a common prefix and remove it let prefix = Cow::from(doc.text().slice(start_offset..trigger_offset)); let text = text.trim_start_matches::<&str>(&prefix); - Transaction::change( - doc.text(), - vec![(trigger_offset, trigger_offset, Some(text.into()))].into_iter(), - ) + + // TODO: this needs to be true for the numbers to work out correctly + // in the closure below. It's passed in to a callback as this same + // formula, but can the value change between the LSP request and + // response? If it does, can we recover? + debug_assert!( + doc.selection(view_id) + .primary() + .cursor(doc.text().slice(..)) + == trigger_offset + ); + + Transaction::change_by_selection(doc.text(), doc.selection(view_id), |range| { + let cursor = range.cursor(doc.text().slice(..)); + + (cursor, cursor, Some(text.into())) + }) }; transaction @@ -164,6 +179,7 @@ impl Completion { let transaction = item_to_transaction( doc, + view.id, item, offset_encoding, start_offset, @@ -185,6 +201,7 @@ impl Completion { let transaction = item_to_transaction( doc, + view.id, item, offset_encoding, start_offset, From dbed90c5a65f435c7886f27b17cbad9cd8492355 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:30:04 +0900 Subject: [PATCH 052/132] build(deps): bump git-repository from 0.26.0 to 0.29.0 (#5016) Bumps [git-repository](https://github.com/Byron/gitoxide) from 0.26.0 to 0.29.0. - [Release notes](https://github.com/Byron/gitoxide/releases) - [Changelog](https://github.com/Byron/gitoxide/blob/main/CHANGELOG.md) - [Commits](https://github.com/Byron/gitoxide/compare/git-repository-v0.26.0...git-repository-v0.29.0) --- updated-dependencies: - dependency-name: git-repository dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 132 +++++++++++++++++++++---------------------- helix-vcs/Cargo.toml | 2 +- 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e021197..a3746f56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "git-actor" -version = "0.13.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d4ce09c0a6c71c044700e5932877667f427f007b77e6c39ab49aebc4719e25" +checksum = "ac9fb99c934ed45a62d9ae1e7b21949f2d869d1b82a07dcbf16ed61daa665870" dependencies = [ "bstr 1.0.1", "btoi", @@ -565,9 +565,9 @@ dependencies = [ [[package]] name = "git-attributes" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c62e66a042c6b39c6dbfa3be37d134900d99ff9c54bbe489ed560a573895d5d" +checksum = "82e98446a2bf0eb5c8f29fa828d6529510a6fadeb59ce14ca98e58fa7e1e0199" dependencies = [ "bstr 1.0.1", "compact_str", @@ -581,36 +581,36 @@ dependencies = [ [[package]] name = "git-bitmap" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327098a7ad27ae298d7e71602dbd4375cc828d755d10a720e4be0be1b4ec38f0" +checksum = "44304093ac66a0ada1b243c15c3a503a165a1d0f50bec748f4e5a9b84a0d0722" dependencies = [ "quick-error", ] [[package]] name = "git-chunk" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b2bc1635b660ad6e30379a84a4946590a3c124b747107c2cca1d9dbb98f588" +checksum = "3090baa2f4a3fe488a9b3e31090b83259aaf930bf0634af34c18117274f8f1a8" dependencies = [ "thiserror", ] [[package]] name = "git-command" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e4b01997b6551554fdac6f02277d0d04c3e869daa649bedd06d38c86f11dc42" +checksum = "a6b98a6312fef79b326c0a6e15d576c2bd30f7f9d0b7964998d166049e0d7b9e" dependencies = [ "bstr 1.0.1", ] [[package]] name = "git-config" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8603e953bd4c9bf310e74e43697400f5542f1cc75fad46fbd7427135a9534f" +checksum = "bd1d13179bcf3dd68e83404f91a8d01c618f54eb97ef36c68ee5e6f30183a681" dependencies = [ "bstr 1.0.1", "git-config-value", @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "git-config-value" -version = "0.8.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f276bfe5806b414915112f1eec0f006206cdf5b8cc9bbb44ef7e52286dc3eb" +checksum = "64561e9700f1fc737fa3c1c4ea55293be70dba98e45c54cf3715cb180f37a566" dependencies = [ "bitflags", "bstr 1.0.1", @@ -642,9 +642,9 @@ dependencies = [ [[package]] name = "git-credentials" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f540186ea56fd075ba2b923180ebf4318e66ceaeac0a2a518e75dab8517d339" +checksum = "621dd60288ae7b8f80bb0704f46d4d2b76fc1ec980a7804e48b02d94a927e331" dependencies = [ "bstr 1.0.1", "git-command", @@ -658,9 +658,9 @@ dependencies = [ [[package]] name = "git-date" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37881e9725df41e15d16216d3a0cee251fd8a39d425f75b389112df5c7f20f3d" +checksum = "e33db9f4462b565a33507aee113f3383bf16b988d2c573f07691e34302b7aa0a" dependencies = [ "bstr 1.0.1", "itoa", @@ -670,9 +670,9 @@ dependencies = [ [[package]] name = "git-diff" -version = "0.21.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a88666a0ae4365b55a0cbf2efde68d2a4cff0747894ad229403bd60b0b2abc5" +checksum = "82f77407381267be95f1b26acfb32007258af342ee61729bb4271b1869bf5bb2" dependencies = [ "git-hash", "git-object", @@ -682,9 +682,9 @@ dependencies = [ [[package]] name = "git-discover" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881e4136d5599cfdb79d8ef60d650823d1a563589fa493d8e4961e64d78a79f2" +checksum = "2c2cfd1272824b126c6997ef479a71288d00fae14dc5144dfc48658f4dd24fbe" dependencies = [ "bstr 1.0.1", "git-hash", @@ -696,9 +696,9 @@ dependencies = [ [[package]] name = "git-features" -version = "0.23.1" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be88ae837674c71b30c6517c6f5f1335f8135bb8a9ffef20000d211933bed08" +checksum = "d7bdbe755d2129bc609437b6b18af1116f146128dda6070c15c0aa50201ac17c" dependencies = [ "crc32fast", "flate2", @@ -713,9 +713,9 @@ dependencies = [ [[package]] name = "git-glob" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d756430237112f8c89049236f60fdcdb0005127b1f7e531d40984e4fe7daa90" +checksum = "ef858611602fce54b51e45671ca72f07fe6a3c0e24a0539c66b75dfd4d84bd77" dependencies = [ "bitflags", "bstr 1.0.1", @@ -723,9 +723,9 @@ dependencies = [ [[package]] name = "git-hash" -version = "0.9.11" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d46e6c2d1e8da4438a87bf516a6761b300964a353541fea61e96b3c7b34554" +checksum = "1532d82bf830532f8d545c5b7b568e311e3593f16cf7ee9dd0ce03c74b12b99d" dependencies = [ "hex", "thiserror", @@ -733,9 +733,9 @@ dependencies = [ [[package]] name = "git-index" -version = "0.7.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "821583c2d12b1e864694eb0bf1cca10ff6a3f45966f5f834e0f921b496dbe7cb" +checksum = "a87c32d2e012ee316d4037b2151e5893599379ff1fc2c6adb36d2d4d1c461e2c" dependencies = [ "atoi", "bitflags", @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "git-lock" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0fe10bf961f62b1335b4c07785e64fb4d86c5ed367dc7cd9360f13c3eb7c78" +checksum = "89e4f05b8a68c3a5dd83a6651c76be384e910fe283072184fdab9d77f87ccec2" dependencies = [ "fastrand", "git-tempfile", @@ -766,9 +766,9 @@ dependencies = [ [[package]] name = "git-mailmap" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb3f85ce84b2328aeb3124a809f7b3a63e59c4d63c227dba7a9cdf6fca6c0987" +checksum = "480eecdfaf1bfd05973678520d182dc07afa25b133db18c52575fb65b782b7ba" dependencies = [ "bstr 1.0.1", "git-actor", @@ -777,9 +777,9 @@ dependencies = [ [[package]] name = "git-object" -version = "0.22.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9469a8c00d8bb500ee76a12e455bb174b4ddf71674713335dd1a84313723f7b3" +checksum = "ce0f14f9cd8f0782e843898a2fb7b0c2f5a6e37bd4cdff4409bb8ec698597dad" dependencies = [ "bstr 1.0.1", "btoi", @@ -796,9 +796,9 @@ dependencies = [ [[package]] name = "git-odb" -version = "0.35.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaaea7031ac7d8dfee232a16d7114395d118226214fb03fe4e15d1f4d62a88a6" +checksum = "13493da6cf0326454215414d29f933a1e26bdba3b9b60ad8cdcbe06f0639584b" dependencies = [ "arc-swap", "git-features", @@ -814,9 +814,9 @@ dependencies = [ [[package]] name = "git-pack" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc4386dff835ffdc3697c3558111f708fd7b7695c42a4347f2d211cf3246c8e1" +checksum = "fa8391cbf293f0f8ffbb5e324f25741f5e1e2d35fb87b89ab222a025661e0454" dependencies = [ "bytesize", "clru", @@ -838,9 +838,9 @@ dependencies = [ [[package]] name = "git-path" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "425dc1022690be13e6c5bde4b7e04d9504d323605ec314cd367cebf38a812572" +checksum = "5f60cbc13bc0fdd95df5f4b80437197e2853116792894b1bf38d1a6b4a64f8c9" dependencies = [ "bstr 1.0.1", "thiserror", @@ -848,9 +848,9 @@ dependencies = [ [[package]] name = "git-prompt" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6947935c0671342277bc883ff0687978477b570c1ffe2200b9ba5ac8afdd9f" +checksum = "21c6aaeb3f0f8de91f5e0eb950282c6508e05babcedef768db5a6f085d6e5242" dependencies = [ "git-command", "git-config-value", @@ -861,9 +861,9 @@ dependencies = [ [[package]] name = "git-quote" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea17931d07cbe447f371bbdf45ff03c30ea86db43788166655a5302df87ecfc" +checksum = "1dd11f4e7f251ab297545faa4c5a4517f4985a43b9c16bf96fa49107f58e837f" dependencies = [ "bstr 1.0.1", "btoi", @@ -872,9 +872,9 @@ dependencies = [ [[package]] name = "git-ref" -version = "0.18.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "638c9e454bacb2965a43f05b4a383c8f66dc64f3a770bd0324b221c2a20e121d" +checksum = "22484043921e699edc170415789f1b882c8f3546e1fbbc447a0043ef07e088c4" dependencies = [ "git-actor", "git-features", @@ -891,9 +891,9 @@ dependencies = [ [[package]] name = "git-refspec" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9497af773538ae8cfda053ff7dd0a9e6c28d333ba653040f54b8b4ee32f14187" +checksum = "ac2e8f36e7d5d48903b60051dfb75aedfc4ea9ba66bdffa7a9081e8d276b0107" dependencies = [ "bstr 1.0.1", "git-hash", @@ -905,9 +905,9 @@ dependencies = [ [[package]] name = "git-repository" -version = "0.26.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb43e59612e493af6a433bf0a960de0042c8aa6f4e4c4cb414f03b97e296b82" +checksum = "a89cec253dd3fba44694f7468d907506a52d0055850ecd7d84f4bac07f00e73f" dependencies = [ "byte-unit", "clru", @@ -948,9 +948,9 @@ dependencies = [ [[package]] name = "git-revision" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efd31c63c3745b5dba5ec7109eec41a9c717f4e1e797fe0ef93098f33f31b25" +checksum = "e629289b0d7f7f2f2e46248527f5cac838e6a7cb9507eab06fc8473082db6cb6" dependencies = [ "bstr 1.0.1", "git-date", @@ -962,9 +962,9 @@ dependencies = [ [[package]] name = "git-sec" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c79769f6546814d0774db7295c768441016b7e40bdd414fa8dfae2c616a1892" +checksum = "1ecb370efde58da72827909292284b5c5b885e0621a342515a36976b0b3bf660" dependencies = [ "bitflags", "dirs", @@ -975,9 +975,9 @@ dependencies = [ [[package]] name = "git-tempfile" -version = "2.0.6" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d23bc6129de3cbd81e6c9d0d685b5540c6b41bd9fa0cc38f381bc300743d708" +checksum = "a6bb4dee86c8cae5a078cfaac3b004ef99c31548ed86218f23a7ff9b4b74f3be" dependencies = [ "dashmap", "libc", @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "git-traverse" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0c4dd773c69f294f43ace8373d48eb770129791f104c6857fa8cac0505af89" +checksum = "2d2746935c92d252e24f9d345e0a981510596faceb7edae821b9e4c8c35c285b" dependencies = [ "git-hash", "git-object", @@ -1001,9 +1001,9 @@ dependencies = [ [[package]] name = "git-url" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b7f8323196840e7932f5b60e1d9c1d6c140fd806bc512f8beedc3f990a1f81" +checksum = "7dbd91c55b1b03a833ff8278776fed272918cd61cd48efe9a97ad1fea7ef93ec" dependencies = [ "bstr 1.0.1", "git-features", @@ -1015,9 +1015,9 @@ dependencies = [ [[package]] name = "git-validate" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5439d6aa0de838dfadd74a71e97a9e23ebc719fd11a9ab6788b835b112c8c3d" +checksum = "cdf83bae632fc064ca938ebfb987364d9083b7f98b1476805f0a2d5eebb48686" dependencies = [ "bstr 1.0.1", "thiserror", @@ -1025,9 +1025,9 @@ dependencies = [ [[package]] name = "git-worktree" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45bcc69c36a29cfa283710b7901877ab251d658935f5a41ed824416af500e0ed" +checksum = "2eae0e0b1050208e611d5fac0d8366b29ef3f83849767ff9c4bcf570f0d5dc2b" dependencies = [ "bstr 1.0.1", "git-attributes", diff --git a/helix-vcs/Cargo.toml b/helix-vcs/Cargo.toml index c114666d..e54cf828 100644 --- a/helix-vcs/Cargo.toml +++ b/helix-vcs/Cargo.toml @@ -16,7 +16,7 @@ helix-core = { version = "0.6", path = "../helix-core" } tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] } parking_lot = "0.12" -git-repository = { version = "0.26", default-features = false , optional = true } +git-repository = { version = "0.29", default-features = false , optional = true } imara-diff = "0.1.5" log = "0.4" From 952f292d252bdc135f10b1ffa52734d5242d2c60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:30:11 +0900 Subject: [PATCH 053/132] build(deps): bump serde from 1.0.148 to 1.0.149 (#5017) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.148 to 1.0.149. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.148...v1.0.149) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3746f56..014834e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1804,18 +1804,18 @@ checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" [[package]] name = "serde" -version = "1.0.148" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.148" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" dependencies = [ "proc-macro2", "quote", From 453a75a3739338348024b6c676231aef9ef6cb7b Mon Sep 17 00:00:00 2001 From: Narazaki Shuji Date: Tue, 6 Dec 2022 11:16:08 +0900 Subject: [PATCH 054/132] fix: align view after jumplist_picker (#3743) * Add `View::ensure_cursor_in_view_center` to adjust view after searching and jumping Also `offset_coodrs_to_in_view` was refactored to reduce duplicated position calculations. * Fix a wrong offset calculation in `offset_coords_to_in_view_center` It ignored `scrolloff` if `centering` is false. --- helix-term/src/commands.rs | 15 +++---- helix-view/src/view.rs | 89 +++++++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 37 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 31a2f582..26389026 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1667,12 +1667,7 @@ fn search_impl( }; doc.set_selection(view.id, selection); - // TODO: is_cursor_in_view does the same calculation as ensure_cursor_in_view - if view.is_cursor_in_view(doc, 0) { - view.ensure_cursor_in_view(doc, scrolloff); - } else { - align_view(doc, view, Align::Center) - } + view.ensure_cursor_in_view_center(doc, scrolloff); }; } @@ -2434,8 +2429,10 @@ fn jumplist_picker(cx: &mut Context) { (), |cx, meta, action| { cx.editor.switch(meta.id, action); + let config = cx.editor.config(); let (view, doc) = current!(cx.editor); doc.set_selection(view.id, meta.selection.clone()); + view.ensure_cursor_in_view_center(doc, config.scrolloff); }, |editor, meta| { let doc = &editor.documents.get(&meta.id)?; @@ -4205,6 +4202,7 @@ fn match_brackets(cx: &mut Context) { fn jump_forward(cx: &mut Context) { let count = cx.count(); + let config = cx.editor.config(); let view = view_mut!(cx.editor); let doc_id = view.doc; @@ -4218,12 +4216,13 @@ fn jump_forward(cx: &mut Context) { } doc.set_selection(view.id, selection); - align_view(doc, view, Align::Center); + view.ensure_cursor_in_view_center(doc, config.scrolloff); }; } fn jump_backward(cx: &mut Context) { let count = cx.count(); + let config = cx.editor.config(); let (view, doc) = current!(cx.editor); let doc_id = doc.id(); @@ -4237,7 +4236,7 @@ fn jump_backward(cx: &mut Context) { } doc.set_selection(view.id, selection); - align_view(doc, view, Align::Center); + view.ensure_cursor_in_view_center(doc, config.scrolloff); }; } diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index ecc8e8be..c09d502d 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -1,4 +1,4 @@ -use crate::{editor::GutterType, graphics::Rect, Document, DocumentId, ViewId}; +use crate::{align_view, editor::GutterType, graphics::Rect, Align, Document, DocumentId, ViewId}; use helix_core::{ pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction, }; @@ -169,6 +169,15 @@ impl View { &self, doc: &Document, scrolloff: usize, + ) -> Option<(usize, usize)> { + self.offset_coords_to_in_view_center(doc, scrolloff, false) + } + + pub fn offset_coords_to_in_view_center( + &self, + doc: &Document, + scrolloff: usize, + centering: bool, ) -> Option<(usize, usize)> { let cursor = doc .selection(self.id) @@ -180,47 +189,69 @@ impl View { let inner_area = self.inner_area(doc); let last_line = (self.offset.row + inner_area.height as usize).saturating_sub(1); - - // - 1 so we have at least one gap in the middle. - // a height of 6 with padding of 3 on each side will keep shifting the view back and forth - // as we type - let scrolloff = scrolloff.min(inner_area.height.saturating_sub(1) as usize / 2); - let last_col = self.offset.col + inner_area.width.saturating_sub(1) as usize; - let row = if line > last_line.saturating_sub(scrolloff) { - // scroll down - self.offset.row + line - (last_line.saturating_sub(scrolloff)) - } else if line < self.offset.row + scrolloff { - // scroll up - line.saturating_sub(scrolloff) - } else { - self.offset.row + let new_offset = |scrolloff: usize| { + // - 1 so we have at least one gap in the middle. + // a height of 6 with padding of 3 on each side will keep shifting the view back and forth + // as we type + let scrolloff = scrolloff.min(inner_area.height.saturating_sub(1) as usize / 2); + + let row = if line > last_line.saturating_sub(scrolloff) { + // scroll down + self.offset.row + line - (last_line.saturating_sub(scrolloff)) + } else if line < self.offset.row + scrolloff { + // scroll up + line.saturating_sub(scrolloff) + } else { + self.offset.row + }; + + let col = if col > last_col.saturating_sub(scrolloff) { + // scroll right + self.offset.col + col - (last_col.saturating_sub(scrolloff)) + } else if col < self.offset.col + scrolloff { + // scroll left + col.saturating_sub(scrolloff) + } else { + self.offset.col + }; + (row, col) }; - - let col = if col > last_col.saturating_sub(scrolloff) { - // scroll right - self.offset.col + col - (last_col.saturating_sub(scrolloff)) - } else if col < self.offset.col + scrolloff { - // scroll left - col.saturating_sub(scrolloff) + let current_offset = (self.offset.row, self.offset.col); + if centering { + // return None if cursor is out of view + let offset = new_offset(0); + (offset == current_offset).then(|| { + if scrolloff == 0 { + offset + } else { + new_offset(scrolloff) + } + }) } else { - self.offset.col - }; - if row == self.offset.row && col == self.offset.col { - None - } else { - Some((row, col)) + // return None if cursor is in (view - scrolloff) + let offset = new_offset(scrolloff); + (offset != current_offset).then(|| offset) // TODO: use 'then_some' when 1.62 <= MSRV } } pub fn ensure_cursor_in_view(&mut self, doc: &Document, scrolloff: usize) { - if let Some((row, col)) = self.offset_coords_to_in_view(doc, scrolloff) { + if let Some((row, col)) = self.offset_coords_to_in_view_center(doc, scrolloff, false) { self.offset.row = row; self.offset.col = col; } } + pub fn ensure_cursor_in_view_center(&mut self, doc: &Document, scrolloff: usize) { + if let Some((row, col)) = self.offset_coords_to_in_view_center(doc, scrolloff, true) { + self.offset.row = row; + self.offset.col = col; + } else { + align_view(doc, self, Align::Center); + } + } + pub fn is_cursor_in_view(&mut self, doc: &Document, scrolloff: usize) -> bool { self.offset_coords_to_in_view(doc, scrolloff).is_none() } From af532147c97987d6170dc06a52aa3434ebf1b9d4 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Tue, 6 Dec 2022 15:18:33 +0100 Subject: [PATCH 055/132] Add command/keybinding to jump between hunks (#4650) * add command and keybding to jump to next/prev hunk * add textobject for change * Update helix-vcs/src/diff.rs Co-authored-by: Michael Davis * select entire hunk instead of first char * fix selection range Co-authored-by: Michael Davis --- book/src/keymap.md | 4 + book/src/usage.md | 1 + helix-term/src/commands.rs | 121 +++++++++++++++++++++++++++++++ helix-term/src/keymap/default.rs | 4 + helix-vcs/src/diff.rs | 81 +++++++++++++++++++++ 5 files changed, 211 insertions(+) diff --git a/book/src/keymap.md b/book/src/keymap.md index c3c09f4c..139e8fdd 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -320,6 +320,10 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire | `]T` | Go to previous test (**TS**) | `goto_prev_test` | | `]p` | Go to next paragraph | `goto_next_paragraph` | | `[p` | Go to previous paragraph | `goto_prev_paragraph` | +| `]g` | Go to next change | `goto_next_change` | +| `[g` | Go to previous change | `goto_prev_change` | +| `]G` | Go to first change | `goto_first_change` | +| `[G` | Go to last change | `goto_last_change` | | `[Space` | Add newline above | `add_newline_above` | | `]Space` | Add newline below | `add_newline_below` | diff --git a/book/src/usage.md b/book/src/usage.md index 646bf926..a6eb9ec1 100644 --- a/book/src/usage.md +++ b/book/src/usage.md @@ -143,6 +143,7 @@ though, we climb the syntax tree and then take the previous selection. So | `a` | Argument/parameter | | `o` | Comment | | `t` | Test | +| `g` | Change | > NOTE: `f`, `c`, etc need a tree-sitter grammar active for the current document and a special tree-sitter query file to work properly. [Only diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 26389026..1843e7a2 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3,6 +3,7 @@ pub(crate) mod lsp; pub(crate) mod typed; pub use dap::*; +use helix_vcs::Hunk; pub use lsp::*; use tui::text::Spans; pub use typed::*; @@ -308,6 +309,10 @@ impl MappableCommand { goto_last_diag, "Goto last diagnostic", goto_next_diag, "Goto next diagnostic", goto_prev_diag, "Goto previous diagnostic", + goto_next_change, "Goto next change", + goto_prev_change, "Goto previous change", + goto_first_change, "Goto first change", + goto_last_change, "Goto last change", goto_line_start, "Goto line start", goto_line_end, "Goto line end", goto_next_buffer, "Goto next buffer", @@ -2912,6 +2917,100 @@ fn goto_prev_diag(cx: &mut Context) { goto_pos(editor, pos); } +fn goto_first_change(cx: &mut Context) { + goto_first_change_impl(cx, false); +} + +fn goto_last_change(cx: &mut Context) { + goto_first_change_impl(cx, true); +} + +fn goto_first_change_impl(cx: &mut Context, reverse: bool) { + let editor = &mut cx.editor; + let (_, doc) = current!(editor); + if let Some(handle) = doc.diff_handle() { + let hunk = { + let hunks = handle.hunks(); + let idx = if reverse { + hunks.len().saturating_sub(1) + } else { + 0 + }; + hunks.nth_hunk(idx) + }; + if hunk != Hunk::NONE { + let pos = doc.text().line_to_char(hunk.after.start as usize); + goto_pos(editor, pos) + } + } +} + +fn goto_next_change(cx: &mut Context) { + goto_next_change_impl(cx, Direction::Forward) +} + +fn goto_prev_change(cx: &mut Context) { + goto_next_change_impl(cx, Direction::Backward) +} + +fn goto_next_change_impl(cx: &mut Context, direction: Direction) { + let count = cx.count() as u32 - 1; + let motion = move |editor: &mut Editor| { + let (view, doc) = current!(editor); + let doc_text = doc.text().slice(..); + let diff_handle = if let Some(diff_handle) = doc.diff_handle() { + diff_handle + } else { + editor.set_status("Diff is not available in current buffer"); + return; + }; + + let selection = doc.selection(view.id).clone().transform(|range| { + let cursor_line = range.cursor_line(doc_text) as u32; + + let hunks = diff_handle.hunks(); + let hunk_idx = match direction { + Direction::Forward => hunks + .next_hunk(cursor_line) + .map(|idx| (idx + count).min(hunks.len() - 1)), + Direction::Backward => hunks + .prev_hunk(cursor_line) + .map(|idx| idx.saturating_sub(count)), + }; + // TODO refactor with let..else once MSRV reaches 1.65 + let hunk_idx = if let Some(hunk_idx) = hunk_idx { + hunk_idx + } else { + return range; + }; + let hunk = hunks.nth_hunk(hunk_idx); + + let hunk_start = doc_text.line_to_char(hunk.after.start as usize); + let hunk_end = if hunk.after.is_empty() { + hunk_start + 1 + } else { + doc_text.line_to_char(hunk.after.end as usize) + }; + let new_range = Range::new(hunk_start, hunk_end); + if editor.mode == Mode::Select { + let head = if new_range.head < range.anchor { + new_range.anchor + } else { + new_range.head + }; + + Range::new(range.anchor, head) + } else { + new_range.with_direction(direction) + } + }); + + doc.set_selection(view.id, selection) + }; + motion(cx.editor); + cx.editor.last_motion = Some(Motion(Box::new(motion))); +} + pub mod insert { use super::*; pub type Hook = fn(&Rope, &Selection, char) -> Option; @@ -4515,6 +4614,27 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { ) }; + if ch == 'g' && doc.diff_handle().is_none() { + editor.set_status("Diff is not available in current buffer"); + return; + } + + let textobject_change = |range: Range| -> Range { + let diff_handle = doc.diff_handle().unwrap(); + let hunks = diff_handle.hunks(); + let line = range.cursor_line(text); + let hunk_idx = if let Some(hunk_idx) = hunks.hunk_at(line as u32, false) { + hunk_idx + } else { + return range; + }; + let hunk = hunks.nth_hunk(hunk_idx).after; + + let start = text.line_to_char(hunk.start as usize); + let end = text.line_to_char(hunk.end as usize); + Range::new(start, end).with_direction(range.direction()) + }; + let selection = doc.selection(view.id).clone().transform(|range| { match ch { 'w' => textobject::textobject_word(text, range, objtype, count, false), @@ -4528,6 +4648,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { 'm' => textobject::textobject_pair_surround_closest( text, range, objtype, count, ), + 'g' => textobject_change(range), // TODO: cancel new ranges if inconsistent surround matches across lines ch if !ch.is_ascii_alphanumeric() => { textobject::textobject_pair_surround(text, range, objtype, ch, count) diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index b6d9ea10..ebcd125a 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -100,6 +100,8 @@ pub fn default() -> HashMap { "[" => { "Left bracket" "d" => goto_prev_diag, "D" => goto_first_diag, + "g" => goto_prev_change, + "G" => goto_first_change, "f" => goto_prev_function, "t" => goto_prev_class, "a" => goto_prev_parameter, @@ -111,6 +113,8 @@ pub fn default() -> HashMap { "]" => { "Right bracket" "d" => goto_next_diag, "D" => goto_last_diag, + "g" => goto_next_change, + "G" => goto_last_change, "f" => goto_next_function, "t" => goto_next_class, "a" => goto_next_parameter, diff --git a/helix-vcs/src/diff.rs b/helix-vcs/src/diff.rs index b1acd1f2..9c6a362f 100644 --- a/helix-vcs/src/diff.rs +++ b/helix-vcs/src/diff.rs @@ -195,4 +195,85 @@ impl FileHunks<'_> { pub fn is_empty(&self) -> bool { self.len() == 0 } + + pub fn next_hunk(&self, line: u32) -> Option { + let hunk_range = if self.inverted { + |hunk: &Hunk| hunk.before.clone() + } else { + |hunk: &Hunk| hunk.after.clone() + }; + + let res = self + .hunks + .binary_search_by_key(&line, |hunk| hunk_range(hunk).start); + + match res { + // Search found a hunk that starts exactly at this line, return the next hunk if it exists. + Ok(pos) if pos + 1 == self.hunks.len() => None, + Ok(pos) => Some(pos as u32 + 1), + + // No hunk starts exactly at this line, so the search returns + // the position where a hunk starting at this line should be inserted. + // That position is exactly the position of the next hunk or the end + // of the list if no such hunk exists + Err(pos) if pos == self.hunks.len() => None, + Err(pos) => Some(pos as u32), + } + } + + pub fn prev_hunk(&self, line: u32) -> Option { + let hunk_range = if self.inverted { + |hunk: &Hunk| hunk.before.clone() + } else { + |hunk: &Hunk| hunk.after.clone() + }; + let res = self + .hunks + .binary_search_by_key(&line, |hunk| hunk_range(hunk).end); + + match res { + // Search found a hunk that ends exactly at this line (so it does not include the current line). + // We can usually just return that hunk, however a special case for empty hunk is necessary + // which represents a pure removal. + // Removals are technically empty but are still shown as single line hunks + // and as such we must jump to the previous hunk (if it exists) if we are already inside the removal + Ok(pos) if !hunk_range(&self.hunks[pos]).is_empty() => Some(pos as u32), + + // No hunk ends exactly at this line, so the search returns + // the position where a hunk ending at this line should be inserted. + // That position before this one is exactly the position of the previous hunk + Err(0) | Ok(0) => None, + Err(pos) | Ok(pos) => Some(pos as u32 - 1), + } + } + + pub fn hunk_at(&self, line: u32, include_removal: bool) -> Option { + let hunk_range = if self.inverted { + |hunk: &Hunk| hunk.before.clone() + } else { + |hunk: &Hunk| hunk.after.clone() + }; + + let res = self + .hunks + .binary_search_by_key(&line, |hunk| hunk_range(hunk).start); + + match res { + // Search found a hunk that starts exactly at this line, return it + Ok(pos) => Some(pos as u32), + + // No hunk starts exactly at this line, so the search returns + // the position where a hunk starting at this line should be inserted. + // The previous hunk contains this hunk if it exists and doesn't end before this line + Err(0) => None, + Err(pos) => { + let hunk = hunk_range(&self.hunks[pos - 1]); + if hunk.end > line || include_removal && hunk.start == line && hunk.is_empty() { + Some(pos as u32 - 1) + } else { + None + } + } + } + } } From e9d43c284bb717e3de5aec7312d985a088ede7ea Mon Sep 17 00:00:00 2001 From: Kristoffer Flottorp <2630397+krfl@users.noreply.github.com> Date: Wed, 7 Dec 2022 02:08:34 +0100 Subject: [PATCH 056/132] Fleetish theme renamed to fleet dark and adjusted to match official theme. (#4997) * remove fleetish.toml * add fleet_dark.toml * adjust colors for tags and markup lists * Add type.enum.variant * correct color for focused elements * adjust builtins and keywords Co-authored-by: krfl --- .../themes/{fleetish.toml => fleet_dark.toml} | 93 ++++++++++--------- 1 file changed, 51 insertions(+), 42 deletions(-) rename runtime/themes/{fleetish.toml => fleet_dark.toml} (52%) diff --git a/runtime/themes/fleetish.toml b/runtime/themes/fleet_dark.toml similarity index 52% rename from runtime/themes/fleetish.toml rename to runtime/themes/fleet_dark.toml index 159daf87..f885e4eb 100644 --- a/runtime/themes/fleetish.toml +++ b/runtime/themes/fleet_dark.toml @@ -1,8 +1,13 @@ -# Author: Kristoffer Flottorp -# A take on the JetBrains Fleet theme sprinkled with some creative freedom +# Fleet Dark +# A take on the JetBrains Fleet theme. Feel free to contribute +# Original author: @krfl +# Contributors: +# @matoous + +"attribute" = "green" "type" = "light_blue" -"type.builtin" = "orange" +"type.enum.variant" = "purple" "constructor" = "yellow" "constant" = "cyan" # "constant.builtin" = {} # .boolean @@ -16,55 +21,55 @@ "comment" = "light_gray" # .line # "comment.block" = {} # .documentation "variable" = "light" # .builtin +"variable.builtin" = { fg = "red", modifiers = ["underlined"] } "variable.parameter" = "light" # "variable.other" = {} # .member -"variable.other.member" = "yellow" +"variable.other.member" = "purple" "label" = "yellow" "punctuation" = "light" # .delimiter / .bracket "keyword" = "cyan" # .operator / .directive / .function -"keyword.control" = "yellow" # .conditional / .repeat / .import / .return / .exception +# "keyword.control" = "cyan" # .conditional / .repeat / .import / .return / .exception +"keyword.control.exception" = "purple" "operator" = "light" "function" = "yellow" "function.macro" = "green" "function.builtin" = "green" "function.special" = "green" "function.method" = "light" -"tag" = "green" +#"function.declaration.method" = { fg = "lightest", modifiers = ["bold"] } #depends on #4892 +"tag" = "light_blue" "special" = "green" "namespace" = "light" # used in theming +# "markup" = {} # .normal / .quote / .raw # "markup.normal" = {} # .completion / .hover -# "markup.raw.inline" = {} # .completion / .hover -"markup" = "purple" # .quote -"markup.bold" = { fg = "purple", modifiers = ["bold"] } -"markup.italic" = { fg = "purple", modifiers = ["italic"] } -"markup.heading" = "light" # .marker -"markup.heading.1" = "yellow" -"markup.heading.2" = "green" -"markup.heading.3" = "pink" -"markup.heading.4" = "purple" -"markup.heading.5" = "cyan" -"markup.heading.6" = "light_blue" -"markup.list" = "cyan" # .unnumbered / .numbered -"markup.link" = "green" -"markup.link.url" = "pink" +"markup.bold" = { fg = "lightest", modifiers = ["bold"] } +"markup.italic" = { modifiers = ["italic"] } +"markup.heading" = { fg = "cyan", modifiers = ["bold"] } # .marker / .1 / .2 / .3 / .4 / .5 / .6 +"markup.list" = "pink" # .unnumbered / .numbered +"markup.list.numbered" = "cyan" +"markup.list.unnumbered" = "cyan" +# "markup.link" = "green" +"markup.link.url" = { fg = "pink", modifiers = ['italic', 'underlined'] } "markup.link.text" = "cyan" -"markup.link.label" = "yellow" -"markup.raw" = "pink" # .inline -"markup.raw.block" = "orange" +"markup.link.label" = "purple" +"markup.quote" = "pink" +"markup.raw" = "pink" +"markup.raw.inline" = "cyan" # .completion / .hover +"markup.raw.block" = "pink" -"diff.plus" = "cyan" -"diff.minus" = "yellow" -"diff.delta" = "purple" +"diff.plus" = "diff_plus" +"diff.minus" = "red_accent" +"diff.delta" = "blue_accent" # ui specific -"ui.background" = { bg = "#0d0d0d" } # .separator +"ui.background" = { bg = "background" } # .separator "ui.cursor" = { bg = "dark_gray", modifiers = ["reversed"] } # .insert / .select / .match / .primary -"ui.cursor.match" = { fg = "light", bg = "blue_accent" } # .insert / .select / .match / .primary +"ui.cursor.match" = { fg = "light", bg = "selection" } # .insert / .select / .match / .primary "ui.cursorline" = { bg = "darker" } "ui.linenr" = "dark_gray" -"ui.linenr.selected" = { fg = "light_gray", bg = "darker" } +"ui.linenr.selected" = { fg = "light", bg = "darker" } "ui.statusline" = { fg = "light", bg = "darker" } # .inactive / .normal / .insert / .select "ui.statusline.inactive" = { fg = "dark", bg = "darker" } "ui.statusline.normal" = { fg = "lightest", bg = "darker"} @@ -74,27 +79,28 @@ "ui.window" = { fg = "dark", bg = "darkest" } "ui.help" = { fg = "light", bg = "darkest" } "ui.text" = "light" # .focus / .info +"ui.text.focus" = { fg = "lightest", bg = "focus" } "ui.virtual" = "dark" # .whitespace "ui.virtual.ruler" = { bg = "darker"} -"ui.menu" = { fg = "light", bg = "darker" } # .selected -"ui.menu.selected" = { fg = "lightest", bg = "blue_accent" } # .selected +"ui.menu" = { fg = "light", bg = "darkest" } # .selected +"ui.menu.selected" = { fg = "lightest", bg = "focus" } # .selected "ui.selection" = { bg = "darker" } # .primary -"ui.selection.primary" = { bg = "select" } # .primary +"ui.selection.primary" = { bg = "selection" } "hint" = "blue" "info" = "yellow_accent" "warning" = "orange_accent" -"error" = "red" +"error" = "red_error" "diagnostic" = { modifiers = [] } -"diagnostic.hint" = { underline = { color = "light", style = "curl" } } -"diagnostic.info" = { underline = { color = "blue", style = "curl" } } -"diagnostic.warning" = { underline = { color = "yellow", style = "curl" } } -"diagnostic.error" = { underline = { color = "red", style = "curl" } } +"diagnostic.hint" = { underline = { color = "light", style = "line" } } +"diagnostic.info" = { underline = { color = "blue_accent", style = "line" } } +"diagnostic.warning" = { underline = { color = "yellow_accent", style = "line" } } +"diagnostic.error" = { underline = { color = "red_error", style = "line" } } [palette] +background = "#181818" darkest = "#1e1e1e" -darker = "#262626" +darker = "#292929" dark = "#898989" -select = "#102f5b" light = "#d6d6dd" lightest = "#ffffff" @@ -109,13 +115,16 @@ green = "#afcb85" cyan = "#78d0bd" orange = "#efb080" yellow = "#e5c995" -red = "#f44747" +red = "#CC7C8A" blue_accent = "#2197F3" pink_accent = "#E44C7A" green_accent = "#00AF99" orange_accent = "#EE7F25" yellow_accent = "#DEA407" +red_accent = "#F44747" -# variables intended for future updates -checkmark = "#44B254" +red_error = "#EB5F6A" +selection = "#1F3661" +diff_plus = "#5A9F81" +focus = "#204474" From d3f670c0e2d8800bfeacb76a5b96753ac6529170 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Wed, 7 Dec 2022 10:11:45 +0800 Subject: [PATCH 057/132] Use OSC 52 for tmux copy (#5027) --- helix-view/src/clipboard.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index 19fade69..4f83fb4d 100644 --- a/helix-view/src/clipboard.rs +++ b/helix-view/src/clipboard.rs @@ -136,7 +136,7 @@ pub fn get_clipboard_provider() -> Box { } else if env_var_is_set("TMUX") && binary_exists("tmux") { command_provider! { paste => "tmux", "save-buffer", "-"; - copy => "tmux", "load-buffer", "-"; + copy => "tmux", "load-buffer", "-w", "-"; } } else { Box::new(provider::FallbackProvider::new()) From 96ff64a84a4948b0aa85a453276cb0091fb9c792 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Tue, 6 Dec 2022 20:54:50 -0600 Subject: [PATCH 058/132] Add changelog notes for 22.12 (#4822) * Add changelog notes for 22.12 * Bump VERSION to 22.12 --- CHANGELOG.md | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 287 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56d85751..dc91c9ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,289 @@ +# 22.12 (2022-12-06) + +This is a great big release filled with changes from a 99 contributors. A big _thank you_ to you all! + +As usual, the following is a summary of each of the changes since the last release. +For the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.08.1..22.12). + +Breaking changes: + +- Remove readline-like navigation bindings from the default insert mode keymap ([e12690e](https://github.com/helix-editor/helix/commit/e12690e), [#3811](https://github.com/helix-editor/helix/pull/3811), [#3827](https://github.com/helix-editor/helix/pull/3827), [#3915](https://github.com/helix-editor/helix/pull/3915), [#4088](https://github.com/helix-editor/helix/pull/4088)) +- Rename `append_to_line` as `insert_at_line_end` and `prepend_to_line` as `insert_at_line_start` ([#3753](https://github.com/helix-editor/helix/pull/3753)) +- Swap diagnostic picker and debug mode bindings in the space keymap ([#4229](https://github.com/helix-editor/helix/pull/4229)) +- Select newly inserted text on paste or from shell commands ([#4458](https://github.com/helix-editor/helix/pull/4458), [#4608](https://github.com/helix-editor/helix/pull/4608), [#4619](https://github.com/helix-editor/helix/pull/4619), [#4824](https://github.com/helix-editor/helix/pull/4824)) +- Select newly inserted surrounding characters on `ms` ([#4752](https://github.com/helix-editor/helix/pull/4752)) +- Exit select-mode after executing `replace_*` commands ([#4554](https://github.com/helix-editor/helix/pull/4554)) +- Exit select-mode after executing surround commands ([#4858](https://github.com/helix-editor/helix/pull/4858)) +- Change tree-sitter text-object keys ([#3782](https://github.com/helix-editor/helix/pull/3782)) +- Rename `fleetish` theme to `fleet_dark` ([#4997](https://github.com/helix-editor/helix/pull/4997)) + +Features: + +- Bufferline ([#2759](https://github.com/helix-editor/helix/pull/2759)) +- Support underline styles and colors ([#4061](https://github.com/helix-editor/helix/pull/4061), [98c121c](https://github.com/helix-editor/helix/commit/98c121c)) +- Inheritance for themes ([#3067](https://github.com/helix-editor/helix/pull/3067), [#4096](https://github.com/helix-editor/helix/pull/4096)) +- Cursorcolumn ([#4084](https://github.com/helix-editor/helix/pull/4084)) +- Overhauled system for writing files and quiting ([#2267](https://github.com/helix-editor/helix/pull/2267), [#4397](https://github.com/helix-editor/helix/pull/4397)) +- Autosave when terminal loses focus ([#3178](https://github.com/helix-editor/helix/pull/3178)) +- Use OSC52 as a fallback for the system clipboard ([#3220](https://github.com/helix-editor/helix/pull/3220)) +- Show git diffs in the gutter ([#3890](https://github.com/helix-editor/helix/pull/3890), [#5012](https://github.com/helix-editor/helix/pull/5012), [#4995](https://github.com/helix-editor/helix/pull/4995)) +- Add a logo ([dc1ec56](https://github.com/helix-editor/helix/commit/dc1ec56)) +- Multi-cursor completion ([#4496](https://github.com/helix-editor/helix/pull/4496)) + +Commands: + +- `file_picker_in_current_directory` (`F`) ([#3701](https://github.com/helix-editor/helix/pull/3701)) +- `:lsp-restart` to restart the current document's language server ([#3435](https://github.com/helix-editor/helix/pull/3435), [#3972](https://github.com/helix-editor/helix/pull/3972)) +- `join_selections_space` (`A-j`) which joins selections and selects the joining whitespace ([#3549](https://github.com/helix-editor/helix/pull/3549)) +- `:update` to write the current file if it is modified ([#4426](https://github.com/helix-editor/helix/pull/4426)) +- `:lsp-workspace-command` for picking LSP commands to execute ([#3140](https://github.com/helix-editor/helix/pull/3140)) +- `extend_prev_word_end` - the extend variant for `move_prev_word_end` ([7468fa2](https://github.com/helix-editor/helix/commit/7468fa2)) +- `make_search_word_bounded` which adds regex word boundaries to the current search register value ([#4322](https://github.com/helix-editor/helix/pull/4322)) +- `:reload-all` - `:reload` for all open buffers ([#4663](https://github.com/helix-editor/helix/pull/4663), [#4901](https://github.com/helix-editor/helix/pull/4901)) +- `goto_next_change` (`]g`), `goto_prev_change` (`[g`), `goto_first_change` (`[G`), `goto_last_change` (`]G`) textobjects for jumping between VCS changes ([#4650](https://github.com/helix-editor/helix/pull/4650)) + +Usability improvements and fixes: + +- Don't log 'LSP not defined' errors in the logfile ([1caba2d](https://github.com/helix-editor/helix/commit/1caba2d)) +- Look for the external formatter program before invoking it ([#3670](https://github.com/helix-editor/helix/pull/3670)) +- Don't send LSP didOpen events for documents without URLs ([44b4479](https://github.com/helix-editor/helix/commit/44b4479)) +- Fix off-by-one in `extend_line_above` command ([#3689](https://github.com/helix-editor/helix/pull/3689)) +- Use the original scroll offset when opening a split ([1acdfaa](https://github.com/helix-editor/helix/commit/1acdfaa)) +- Handle auto-formatting failures and save the file anyway ([#3684](https://github.com/helix-editor/helix/pull/3684)) +- Ensure the cursor is in view after `:reflow` ([#3733](https://github.com/helix-editor/helix/pull/3733)) +- Add default rulers and reflow config for git commit messages ([#3738](https://github.com/helix-editor/helix/pull/3738)) +- Improve grammar fetching and building output ([#3773](https://github.com/helix-editor/helix/pull/3773)) +- Add a `text` language to language completion ([cc47d3f](https://github.com/helix-editor/helix/commit/cc47d3f)) +- Improve error handling for `:set-language` ([e8add6f](https://github.com/helix-editor/helix/commit/e8add6f)) +- Improve error handling for `:config-reload` ([#3668](https://github.com/helix-editor/helix/pull/3668)) +- Improve error handling when passing improper ranges to syntax highlighting ([#3826](https://github.com/helix-editor/helix/pull/3826)) +- Render `` tags as raw markup in markdown ([#3425](https://github.com/helix-editor/helix/pull/3425)) +- Remove border around the LSP code-actions popup ([#3444](https://github.com/helix-editor/helix/pull/3444)) +- Canonicalize the path to the runtime directory ([#3794](https://github.com/helix-editor/helix/pull/3794)) +- Add a `themelint` xtask for linting themes ([#3234](https://github.com/helix-editor/helix/pull/3234)) +- Re-sort LSP diagnostics after applying transactions ([#3895](https://github.com/helix-editor/helix/pull/3895), [#4319](https://github.com/helix-editor/helix/pull/4319)) +- Add a command-line flag to specify the log file ([#3807](https://github.com/helix-editor/helix/pull/3807)) +- Track source and tag information in LSP diagnostics ([#3898](https://github.com/helix-editor/helix/pull/3898), [1df32c9](https://github.com/helix-editor/helix/commit/1df32c9)) +- Fix theme returning to normal when exiting the `:theme` completion ([#3644](https://github.com/helix-editor/helix/pull/3644)) +- Improve error messages for invalid commands in the keymap ([#3931](https://github.com/helix-editor/helix/pull/3931)) +- Deduplicate regexs in `search_selection` command ([#3941](https://github.com/helix-editor/helix/pull/3941)) +- Split the finding of LSP root and config roots ([#3929](https://github.com/helix-editor/helix/pull/3929)) +- Ensure that the cursor is within view after auto-formatting ([#4047](https://github.com/helix-editor/helix/pull/4047)) +- Add pseudo-pending to commands with on-next-key callbacks ([#4062](https://github.com/helix-editor/helix/pull/4062), [#4077](https://github.com/helix-editor/helix/pull/4077)) +- Add live preview to `:goto` ([#2982](https://github.com/helix-editor/helix/pull/2982)) +- Show regex compilation failure in a popup ([#3049](https://github.com/helix-editor/helix/pull/3049)) +- Add 'cycled to end' and 'no more matches' for search ([#3176](https://github.com/helix-editor/helix/pull/3176), [#4101](https://github.com/helix-editor/helix/pull/4101)) +- Add extending behavior to tree-sitter textobjects ([#3266](https://github.com/helix-editor/helix/pull/3266)) +- Add `ui.gutter.selected` option for themes ([#3303](https://github.com/helix-editor/helix/pull/3303)) +- Make statusline mode names configurable ([#3311](https://github.com/helix-editor/helix/pull/3311)) +- Add a statusline element for total line count ([#3960](https://github.com/helix-editor/helix/pull/3960)) +- Add extending behavior to `goto_window_*` commands ([#3985](https://github.com/helix-editor/helix/pull/3985)) +- Fix a panic in signature help when the preview is too large ([#4030](https://github.com/helix-editor/helix/pull/4030)) +- Add command names to the command palette ([#4071](https://github.com/helix-editor/helix/pull/4071), [#4223](https://github.com/helix-editor/helix/pull/4223), [#4495](https://github.com/helix-editor/helix/pull/4495)) +- Find the LSP workspace root from the current document's path ([#3553](https://github.com/helix-editor/helix/pull/3553)) +- Add an option to skip indent-guide levels ([#3819](https://github.com/helix-editor/helix/pull/3819), [2c36e33](https://github.com/helix-editor/helix/commit/2c36e33)) +- Change focus to modified docs on quit ([#3872](https://github.com/helix-editor/helix/pull/3872)) +- Respond to `USR1` signal by reloading config ([#3952](https://github.com/helix-editor/helix/pull/3952)) +- Exit gracefully when the close operation fails ([#4081](https://github.com/helix-editor/helix/pull/4081)) +- Fix goto/view center mismatch ([#4135](https://github.com/helix-editor/helix/pull/4135)) +- Highlight the current file picker document on idle-timeout ([#3172](https://github.com/helix-editor/helix/pull/3172), [a85e386](https://github.com/helix-editor/helix/commit/a85e386)) +- Apply transactions to jumplist selections ([#4186](https://github.com/helix-editor/helix/pull/4186), [#4227](https://github.com/helix-editor/helix/pull/4227), [#4733](https://github.com/helix-editor/helix/pull/4733), [#4865](https://github.com/helix-editor/helix/pull/4865), [#4912](https://github.com/helix-editor/helix/pull/4912), [#4965](https://github.com/helix-editor/helix/pull/4965), [#4981](https://github.com/helix-editor/helix/pull/4981)) +- Use space as a separator for fuzzy matcher ([#3969](https://github.com/helix-editor/helix/pull/3969)) +- Overlay all diagnostics with highest severity on top ([#4113](https://github.com/helix-editor/helix/pull/4113)) +- Avoid re-parsing unmodified tree-sitter injections ([#4146](https://github.com/helix-editor/helix/pull/4146)) +- Add extending captures for indentation, re-enable python indentation ([#3382](https://github.com/helix-editor/helix/pull/3382), [3e84434](https://github.com/helix-editor/helix/commit/3e84434)) +- Only allow either `--vsplit` or `--hsplit` CLI flags at once ([#4202](https://github.com/helix-editor/helix/pull/4202)) +- Fix append cursor location when selection anchor is at the end of the document ([#4147](https://github.com/helix-editor/helix/pull/4147)) +- Improve selection yanking message ([#4275](https://github.com/helix-editor/helix/pull/4275)) +- Log failures to load tree-sitter grammars as errors ([#4315](https://github.com/helix-editor/helix/pull/4315)) +- Fix rendering of lines longer than 65,536 columns ([#4172](https://github.com/helix-editor/helix/pull/4172)) +- Skip searching `.git` in `global_search` ([#4334](https://github.com/helix-editor/helix/pull/4334)) +- Display tree-sitter scopes in a popup ([#4337](https://github.com/helix-editor/helix/pull/4337)) +- Fix deleting a word from the end of the buffer ([#4328](https://github.com/helix-editor/helix/pull/4328)) +- Pretty print the syntax tree in `:tree-sitter-subtree` ([#4295](https://github.com/helix-editor/helix/pull/4295), [#4606](https://github.com/helix-editor/helix/pull/4606)) +- Allow specifying suffixes for file-type detection ([#2455](https://github.com/helix-editor/helix/pull/2455), [#4414](https://github.com/helix-editor/helix/pull/4414)) +- Fix multi-byte auto-pairs ([#4024](https://github.com/helix-editor/helix/pull/4024)) +- Improve sort scoring for LSP code-actions and completions ([#4134](https://github.com/helix-editor/helix/pull/4134)) +- Fix the handling of quotes within shellwords ([#4098](https://github.com/helix-editor/helix/pull/4098)) +- Fix `delete_word_backward` and `delete_word_forward` on newlines ([#4392](https://github.com/helix-editor/helix/pull/4392)) +- Fix 'no entry found for key' crash on `:write-all` ([#4384](https://github.com/helix-editor/helix/pull/4384)) +- Remove lowercase requirement for tree-sitter grammars ([#4346](https://github.com/helix-editor/helix/pull/4346)) +- Resolve LSP completion items on idle-timeout ([#4406](https://github.com/helix-editor/helix/pull/4406), [#4797](https://github.com/helix-editor/helix/pull/4797)) +- Render diagnostics in the file picker preview ([#4324](https://github.com/helix-editor/helix/pull/4324)) +- Fix terminal freezing on `shell_insert_output` ([#4156](https://github.com/helix-editor/helix/pull/4156)) +- Allow use of the count in the repeat operator (`.`) ([#4450](https://github.com/helix-editor/helix/pull/4450)) +- Show the current theme name on `:theme` with no arguments ([#3740](https://github.com/helix-editor/helix/pull/3740)) +- Fix rendering in very large terminals ([#4318](https://github.com/helix-editor/helix/pull/4318)) +- Sort LSP preselected items to the top of the completion menu ([#4480](https://github.com/helix-editor/helix/pull/4480)) +- Trim braces and quotes from paths in goto-file ([#4370](https://github.com/helix-editor/helix/pull/4370)) +- Prevent automatic signature help outside of insert mode ([#4456](https://github.com/helix-editor/helix/pull/4456)) +- Fix freezes with external programs that process stdin and stdout concurrently ([#4180](https://github.com/helix-editor/helix/pull/4180)) +- Make `scroll` aware of tabs and wide characters ([#4519](https://github.com/helix-editor/helix/pull/4519)) +- Correctly handle escaping in `command_mode` completion ([#4316](https://github.com/helix-editor/helix/pull/4316), [#4587](https://github.com/helix-editor/helix/pull/4587), [#4632](https://github.com/helix-editor/helix/pull/4632)) +- Fix `delete_char_backward` for paired characters ([#4558](https://github.com/helix-editor/helix/pull/4558)) +- Fix crash from two windows editing the same document ([#4570](https://github.com/helix-editor/helix/pull/4570)) +- Fix pasting from the blackhole register ([#4497](https://github.com/helix-editor/helix/pull/4497)) +- Support LSP insertReplace completion items ([1312682](https://github.com/helix-editor/helix/commit/1312682)) +- Dynamically resize the line number gutter width ([#3469](https://github.com/helix-editor/helix/pull/3469)) +- Fix crash for unknown completion item kinds ([#4658](https://github.com/helix-editor/helix/pull/4658)) +- Re-enable `format_selections` for single selection ranges ([d4f5cab](https://github.com/helix-editor/helix/commit/d4f5cab)) +- Limit the number of in-progress tree-sitter query matches ([#4707](https://github.com/helix-editor/helix/pull/4707), [#4830](https://github.com/helix-editor/helix/pull/4830)) +- Use the special `#` register with `increment`/`decrement` to change by range number ([#4418](https://github.com/helix-editor/helix/pull/4418)) +- Add a statusline element to show number of selected chars ([#4682](https://github.com/helix-editor/helix/pull/4682)) +- Add a statusline element showing global LSP diagnostic warning and error counts ([#4569](https://github.com/helix-editor/helix/pull/4569)) +- Add a scrollbar to popups ([#4449](https://github.com/helix-editor/helix/pull/4449)) +- Prefer shorter matches in fuzzy matcher scoring ([#4698](https://github.com/helix-editor/helix/pull/4698)) +- Use key-sequence format for command palette keybinds ([#4712](https://github.com/helix-editor/helix/pull/4712)) +- Remove prefix filtering from autocompletion menu ([#4578](https://github.com/helix-editor/helix/pull/4578)) +- Focus on the parent buffer when closing a split ([#4766](https://github.com/helix-editor/helix/pull/4766)) +- Handle language server termination ([#4797](https://github.com/helix-editor/helix/pull/4797), [#4852](https://github.com/helix-editor/helix/pull/4852)) +- Allow `r`/`t`/`f` to work on tab characters ([#4817](https://github.com/helix-editor/helix/pull/4817)) +- Show a preview for scratch buffers in the buffer picker ([#3454](https://github.com/helix-editor/helix/pull/3454)) +- Set a limit of entries in the jumplist ([#4750](https://github.com/helix-editor/helix/pull/4750)) +- Re-use shell outputs when inserting or appending shell output ([#3465](https://github.com/helix-editor/helix/pull/3465)) +- Check LSP server provider capabilities ([#3554](https://github.com/helix-editor/helix/pull/3554)) +- Improve tree-sitter parsing performance on files with many language layers ([#4716](https://github.com/helix-editor/helix/pull/4716)) +- Move indentation to the next line when using `` on a line with only whitespace ([#4854](https://github.com/helix-editor/helix/pull/4854)) +- Remove selections for closed views from all documents ([#4888](https://github.com/helix-editor/helix/pull/4888)) +- Improve performance of the `:reload` command ([#4457](https://github.com/helix-editor/helix/pull/4457)) +- Properly handle media keys ([#4887](https://github.com/helix-editor/helix/pull/4887)) +- Support LSP diagnostic data field ([#4935](https://github.com/helix-editor/helix/pull/4935)) +- Handle C-i keycode as tab ([#4961](https://github.com/helix-editor/helix/pull/4961)) +- Fix view alignment for jumplist picker jumps ([#3743](https://github.com/helix-editor/helix/pull/3743)) +- Use OSC52 for tmux clipboard provider ([#5027](https://github.com/helix-editor/helix/pull/5027)) + +Themes: + +- Add `varua` ([#3610](https://github.com/helix-editor/helix/pull/3610), [#4964](https://github.com/helix-editor/helix/pull/4964)) +- Update `boo_berry` ([#3653](https://github.com/helix-editor/helix/pull/3653)) +- Add `rasmus` ([#3728](https://github.com/helix-editor/helix/pull/3728)) +- Add `papercolor_dark` ([#3742](https://github.com/helix-editor/helix/pull/3742)) +- Update `monokai_pro_spectrum` ([#3814](https://github.com/helix-editor/helix/pull/3814)) +- Update `nord` ([#3792](https://github.com/helix-editor/helix/pull/3792)) +- Update `fleetish` ([#3844](https://github.com/helix-editor/helix/pull/3844), [#4487](https://github.com/helix-editor/helix/pull/4487), [#4813](https://github.com/helix-editor/helix/pull/4813)) +- Update `flatwhite` ([#3843](https://github.com/helix-editor/helix/pull/3843)) +- Add `darcula` ([#3739](https://github.com/helix-editor/helix/pull/3739)) +- Update `papercolor` ([#3938](https://github.com/helix-editor/helix/pull/3938), [#4317](https://github.com/helix-editor/helix/pull/4317)) +- Add bufferline colors to multiple themes ([#3881](https://github.com/helix-editor/helix/pull/3881)) +- Add `gruvbox_dark_hard` ([#3948](https://github.com/helix-editor/helix/pull/3948)) +- Add `onedarker` ([#3980](https://github.com/helix-editor/helix/pull/3980), [#4060](https://github.com/helix-editor/helix/pull/4060)) +- Add `dark_high_contrast` ([#3312](https://github.com/helix-editor/helix/pull/3312)) +- Update `bogster` ([#4121](https://github.com/helix-editor/helix/pull/4121), [#4264](https://github.com/helix-editor/helix/pull/4264)) +- Update `sonokai` ([#4089](https://github.com/helix-editor/helix/pull/4089)) +- Update `ayu_*` themes ([#4140](https://github.com/helix-editor/helix/pull/4140), [#4109](https://github.com/helix-editor/helix/pull/4109), [#4662](https://github.com/helix-editor/helix/pull/4662), [#4764](https://github.com/helix-editor/helix/pull/4764)) +- Update `everforest` ([#3998](https://github.com/helix-editor/helix/pull/3998)) +- Update `monokai_pro_octagon` ([#4247](https://github.com/helix-editor/helix/pull/4247)) +- Add `heisenberg` ([#4209](https://github.com/helix-editor/helix/pull/4209)) +- Add `bogster_light` ([#4265](https://github.com/helix-editor/helix/pull/4265)) +- Update `pop-dark` ([#4323](https://github.com/helix-editor/helix/pull/4323)) +- Update `rose_pine` ([#4221](https://github.com/helix-editor/helix/pull/4221)) +- Add `kanagawa` ([#4300](https://github.com/helix-editor/helix/pull/4300)) +- Add `hex_steel`, `hex_toxic` and `hex_lavendar` ([#4367](https://github.com/helix-editor/helix/pull/4367), [#4990](https://github.com/helix-editor/helix/pull/4990)) +- Update `tokyonight` and `tokyonight_storm` ([#4415](https://github.com/helix-editor/helix/pull/4415)) +- Update `gruvbox` ([#4626](https://github.com/helix-editor/helix/pull/4626)) +- Update `dark_plus` ([#4661](https://github.com/helix-editor/helix/pull/4661), [#4678](https://github.com/helix-editor/helix/pull/4678)) +- Add `zenburn` ([#4613](https://github.com/helix-editor/helix/pull/4613), [#4977](https://github.com/helix-editor/helix/pull/4977)) +- Update `monokai_pro` ([#4789](https://github.com/helix-editor/helix/pull/4789)) +- Add `mellow` ([#4770](https://github.com/helix-editor/helix/pull/4770)) +- Add `nightfox` ([#4769](https://github.com/helix-editor/helix/pull/4769), [#4966](https://github.com/helix-editor/helix/pull/4966)) +- Update `doom_acario_dark` ([#4979](https://github.com/helix-editor/helix/pull/4979)) +- Update `autumn` ([#4996](https://github.com/helix-editor/helix/pull/4996)) +- Update `acme` ([#4999](https://github.com/helix-editor/helix/pull/4999)) +- Update `nord_light` ([#4999](https://github.com/helix-editor/helix/pull/4999)) +- Update `serika_*` ([#5015](https://github.com/helix-editor/helix/pull/5015)) + +LSP configurations: + +- Switch to `openscad-lsp` for OpenScad ([#3750](https://github.com/helix-editor/helix/pull/3750)) +- Support Jsonnet ([#3748](https://github.com/helix-editor/helix/pull/3748)) +- Support Markdown ([#3499](https://github.com/helix-editor/helix/pull/3499)) +- Support Bass ([#3771](https://github.com/helix-editor/helix/pull/3771)) +- Set roots configuration for Elixir and HEEx ([#3917](https://github.com/helix-editor/helix/pull/3917), [#3959](https://github.com/helix-editor/helix/pull/3959)) +- Support Purescript ([#4242](https://github.com/helix-editor/helix/pull/4242)) +- Set roots configuration for Julia ([#4361](https://github.com/helix-editor/helix/pull/4361)) +- Support D ([#4372](https://github.com/helix-editor/helix/pull/4372)) +- Increase default language server timeout for Julia ([#4575](https://github.com/helix-editor/helix/pull/4575)) +- Use ElixirLS for HEEx ([#4679](https://github.com/helix-editor/helix/pull/4679)) +- Support Bicep ([#4403](https://github.com/helix-editor/helix/pull/4403)) +- Switch to `nil` for Nix ([433ccef](https://github.com/helix-editor/helix/commit/433ccef)) +- Support QML ([#4842](https://github.com/helix-editor/helix/pull/4842)) +- Enable auto-format for CSS ([#4987](https://github.com/helix-editor/helix/pull/4987)) +- Support CommonLisp ([4176769](https://github.com/helix-editor/helix/commit/4176769)) + +New languages: + +- SML ([#3692](https://github.com/helix-editor/helix/pull/3692)) +- Jsonnet ([#3714](https://github.com/helix-editor/helix/pull/3714)) +- Godot resource ([#3759](https://github.com/helix-editor/helix/pull/3759)) +- Astro ([#3829](https://github.com/helix-editor/helix/pull/3829)) +- SSH config ([#2455](https://github.com/helix-editor/helix/pull/2455), [#4538](https://github.com/helix-editor/helix/pull/4538)) +- Bass ([#3771](https://github.com/helix-editor/helix/pull/3771)) +- WAT (WebAssembly text format) ([#4040](https://github.com/helix-editor/helix/pull/4040), [#4542](https://github.com/helix-editor/helix/pull/4542)) +- Purescript ([#4242](https://github.com/helix-editor/helix/pull/4242)) +- D ([#4372](https://github.com/helix-editor/helix/pull/4372), [#4562](https://github.com/helix-editor/helix/pull/4562)) +- VHS ([#4486](https://github.com/helix-editor/helix/pull/4486)) +- KDL ([#4481](https://github.com/helix-editor/helix/pull/4481)) +- XML ([#4518](https://github.com/helix-editor/helix/pull/4518)) +- WIT ([#4525](https://github.com/helix-editor/helix/pull/4525)) +- ENV ([#4536](https://github.com/helix-editor/helix/pull/4536)) +- INI ([#4538](https://github.com/helix-editor/helix/pull/4538)) +- Bicep ([#4403](https://github.com/helix-editor/helix/pull/4403), [#4751](https://github.com/helix-editor/helix/pull/4751)) +- QML ([#4842](https://github.com/helix-editor/helix/pull/4842)) +- CommonLisp ([4176769](https://github.com/helix-editor/helix/commit/4176769)) + +Updated languages and queries: + +- Zig ([#3621](https://github.com/helix-editor/helix/pull/3621), [#4745](https://github.com/helix-editor/helix/pull/4745)) +- Rust ([#3647](https://github.com/helix-editor/helix/pull/3647), [#3729](https://github.com/helix-editor/helix/pull/3729), [#3927](https://github.com/helix-editor/helix/pull/3927), [#4073](https://github.com/helix-editor/helix/pull/4073), [#4510](https://github.com/helix-editor/helix/pull/4510), [#4659](https://github.com/helix-editor/helix/pull/4659), [#4717](https://github.com/helix-editor/helix/pull/4717)) +- Solidity ([20ed8c2](https://github.com/helix-editor/helix/commit/20ed8c2)) +- Fish ([#3704](https://github.com/helix-editor/helix/pull/3704)) +- Elixir ([#3645](https://github.com/helix-editor/helix/pull/3645), [#4333](https://github.com/helix-editor/helix/pull/4333), [#4821](https://github.com/helix-editor/helix/pull/4821)) +- Diff ([#3708](https://github.com/helix-editor/helix/pull/3708)) +- Nix ([665e27f](https://github.com/helix-editor/helix/commit/665e27f), [1fe3273](https://github.com/helix-editor/helix/commit/1fe3273)) +- Markdown ([#3749](https://github.com/helix-editor/helix/pull/3749), [#4078](https://github.com/helix-editor/helix/pull/4078), [#4483](https://github.com/helix-editor/helix/pull/4483), [#4478](https://github.com/helix-editor/helix/pull/4478)) +- GDScript ([#3760](https://github.com/helix-editor/helix/pull/3760)) +- JSX and TSX ([#3853](https://github.com/helix-editor/helix/pull/3853), [#3973](https://github.com/helix-editor/helix/pull/3973)) +- Ruby ([#3976](https://github.com/helix-editor/helix/pull/3976), [#4601](https://github.com/helix-editor/helix/pull/4601)) +- R ([#4031](https://github.com/helix-editor/helix/pull/4031)) +- WGSL ([#3996](https://github.com/helix-editor/helix/pull/3996), [#4079](https://github.com/helix-editor/helix/pull/4079)) +- C# ([#4118](https://github.com/helix-editor/helix/pull/4118), [#4281](https://github.com/helix-editor/helix/pull/4281), [#4213](https://github.com/helix-editor/helix/pull/4213)) +- Twig ([#4176](https://github.com/helix-editor/helix/pull/4176)) +- Lua ([#3552](https://github.com/helix-editor/helix/pull/3552)) +- C/C++ ([#4079](https://github.com/helix-editor/helix/pull/4079), [#4278](https://github.com/helix-editor/helix/pull/4278), [#4282](https://github.com/helix-editor/helix/pull/4282)) +- Cairo ([17488f1](https://github.com/helix-editor/helix/commit/17488f1), [431f9c1](https://github.com/helix-editor/helix/commit/431f9c1), [09a6df1](https://github.com/helix-editor/helix/commit/09a6df1)) +- Rescript ([#4356](https://github.com/helix-editor/helix/pull/4356)) +- Zig ([#4409](https://github.com/helix-editor/helix/pull/4409)) +- Scala ([#4353](https://github.com/helix-editor/helix/pull/4353), [#4697](https://github.com/helix-editor/helix/pull/4697), [#4701](https://github.com/helix-editor/helix/pull/4701)) +- LaTeX ([#4528](https://github.com/helix-editor/helix/pull/4528), [#4922](https://github.com/helix-editor/helix/pull/4922)) +- SQL ([#4529](https://github.com/helix-editor/helix/pull/4529)) +- Python ([#4560](https://github.com/helix-editor/helix/pull/4560)) +- Bash/Zsh ([#4582](https://github.com/helix-editor/helix/pull/4582)) +- Nu ([#4583](https://github.com/helix-editor/helix/pull/4583)) +- Julia ([#4588](https://github.com/helix-editor/helix/pull/4588)) +- Typescript ([#4703](https://github.com/helix-editor/helix/pull/4703)) +- Meson ([#4572](https://github.com/helix-editor/helix/pull/4572)) +- Haskell ([#4800](https://github.com/helix-editor/helix/pull/4800)) +- CMake ([#4809](https://github.com/helix-editor/helix/pull/4809)) +- HTML ([#4829](https://github.com/helix-editor/helix/pull/4829), [#4881](https://github.com/helix-editor/helix/pull/4881)) +- Java ([#4886](https://github.com/helix-editor/helix/pull/4886)) +- Go ([#4906](https://github.com/helix-editor/helix/pull/4906), [#4969](https://github.com/helix-editor/helix/pull/4969), [#5010](https://github.com/helix-editor/helix/pull/5010)) +- CSS ([#4882](https://github.com/helix-editor/helix/pull/4882)) +- Racket ([#4915](https://github.com/helix-editor/helix/pull/4915)) +- SCSS ([#5003](https://github.com/helix-editor/helix/pull/5003)) + +Packaging: + +- Filter relevant source files in the Nix flake ([#3657](https://github.com/helix-editor/helix/pull/3657)) +- Build a binary for `aarch64-linux` in the release CI ([038a91d](https://github.com/helix-editor/helix/commit/038a91d)) +- Build an AppImage for `aarch64-linux` in the release CI ([b738031](https://github.com/helix-editor/helix/commit/b738031)) +- Enable CI builds for `riscv64-linux` ([#3685](https://github.com/helix-editor/helix/pull/3685)) +- Support preview releases in CI ([0090a2d](https://github.com/helix-editor/helix/commit/0090a2d)) +- Strip binaries built in CI ([#3780](https://github.com/helix-editor/helix/pull/3780)) +- Fix the development shell for the Nix Flake on `aarch64-darwin` ([#3810](https://github.com/helix-editor/helix/pull/3810)) +- Raise the MSRV and create an MSRV policy ([#3896](https://github.com/helix-editor/helix/pull/3896), [#3913](https://github.com/helix-editor/helix/pull/3913), [#3961](https://github.com/helix-editor/helix/pull/3961)) +- Fix Fish completions for `--config` and `--log` flags ([#3912](https://github.com/helix-editor/helix/pull/3912)) +- Use builtin filenames option in Bash completion ([#4648](https://github.com/helix-editor/helix/pull/4648)) + # 22.08.1 (2022-09-01) This is a patch release that fixes a panic caused by closing splits or buffers. ([#3633](https://github.com/helix-editor/helix/pull/3633)) diff --git a/VERSION b/VERSION index b9ed4c22..e70b3aeb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -22.08.1 \ No newline at end of file +22.12 \ No newline at end of file From 9d4236941d581a1a9ed017db294fd3413a670b84 Mon Sep 17 00:00:00 2001 From: Alexander Brevig Date: Wed, 7 Dec 2022 12:29:56 +0100 Subject: [PATCH 059/132] fix(theme): serika toml syntax valid (#5038) --- runtime/themes/serika-light.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/themes/serika-light.toml b/runtime/themes/serika-light.toml index ad830d92..99d4b7f1 100644 --- a/runtime/themes/serika-light.toml +++ b/runtime/themes/serika-light.toml @@ -59,7 +59,7 @@ "error" = "nasty-red" "diagnostic" = { fg = "nasty-red", modifiers = ["underlined"] } -"diff.plus" = { fg = "bg_green" +"diff.plus" = { fg = "bg_green" } "diff.delta" = { fg = "bg_blue" } "diff.minus" = { fg = "nasty-red" } From a4de86e7afc0da3d847d467a21ff4fb67a51d620 Mon Sep 17 00:00:00 2001 From: Alexander Brevig Date: Wed, 7 Dec 2022 12:30:46 +0100 Subject: [PATCH 060/132] fix(theme): git gutter for flatwhite (#5036) --- runtime/themes/flatwhite.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/themes/flatwhite.toml b/runtime/themes/flatwhite.toml index d4c837b6..2fdc66d0 100644 --- a/runtime/themes/flatwhite.toml +++ b/runtime/themes/flatwhite.toml @@ -77,9 +77,9 @@ "ui.popup" = { fg = "base1", bg = "base6" } "ui.window" = { fg = "base1", bg = "base6" } -"diff.plus" = { bg = "diff_add" } -"diff.delta" = { bg = "diff_change" } -"diff.minus" = { bg = "diff_delete" } +"diff.plus" = { fg = "diff_add" } +"diff.delta" = { fg = "diff_change" } +"diff.minus" = { fg = "diff_delete" } [palette] base1 = "#605a52" From f8b75a245a390fc3772d59cafe04ccaaa53c9ca9 Mon Sep 17 00:00:00 2001 From: Jens Getreu Date: Thu, 8 Dec 2022 02:48:01 +0100 Subject: [PATCH 061/132] Autumn theme: use new features (#5051) Co-authored-by: Jens Getreu --- runtime/themes/autumn.toml | 3 +- runtime/themes/autumn_night.toml | 62 +------------------------------- 2 files changed, 3 insertions(+), 62 deletions(-) diff --git a/runtime/themes/autumn.toml b/runtime/themes/autumn.toml index fe80261a..501675da 100644 --- a/runtime/themes/autumn.toml +++ b/runtime/themes/autumn.toml @@ -58,10 +58,11 @@ "markup.raw" = "my_green" "diff.plus" = "my_green" -"diff.delta" = "my_white" +"diff.delta" = "my_gray4" "diff.minus" = "my_red" "diagnostic" = { modifiers = ["underlined"] } +"diagnostic.error" = { underline = { style = "curl", color = "my_red" } } "ui.gutter" = { bg = "my_gray0" } "hint" = "my_gray5" "debug" = "my_yellow2" diff --git a/runtime/themes/autumn_night.toml b/runtime/themes/autumn_night.toml index d01f5356..c26cc777 100644 --- a/runtime/themes/autumn_night.toml +++ b/runtime/themes/autumn_night.toml @@ -7,67 +7,7 @@ # Jens Getreu ported and optimised the color theme for the Helix editor. # Author: Jens Getreu -"ui.background" = { bg = "my_gray0" } -"ui.menu" = { fg = "my_white", bg = "my_gray2" } -"ui.menu.selected" = { fg = "my_gray2", bg = "my_gray5" } -"ui.linenr" = { fg = "my_gray3", bg = "my_gray0" } -"ui.popup" = { bg = "my_gray2" } -"ui.window" = { fg = "my_gray3", bg = "my_gray2" } -"ui.linenr.selected" = { fg = "my_gray6", bg = "my_gray0"} -"ui.selection" = { bg = "my_gray3" } -"comment" = { fg = "my_gray4", modifiers = ["italic"] } -"ui.cursorline" = { bg = "my_gray3" } -"ui.statusline" = { fg = "my_gray6", bg = "my_gray2" } -"ui.statusline.inactive" = { fg = 'my_gray4', bg = 'my_gray2' } -"ui.statusline.insert" = {fg = "my_black", bg = "my_gray5", modifiers = ["bold"]} -"ui.statusline.normal" = {fg = "my_gray6", bg = "my_gray2"} -"ui.statusline.select" = {fg = "my_gray6", bg = "my_black", modifiers = ["bold"]} -"ui.cursor" = { fg = "my_gray5", modifiers = ["reversed"] } -"ui.cursor.primary" = { fg = "my_white", modifiers = ["reversed"] } -"ui.cursorline.primary" = { bg = "my_black" } -"ui.cursorline.secondary" = { bg = "my_black" } -"ui.text" = "my_white" -"operator" = "my_white" -"ui.text.focus" = "my_white" -"variable" = "my_white3" -"constant.numeric" = "my_turquoise" -"constant" = "my_white3" -"attribute" = "my_turquoise" -"type" = { fg = "my_white3", modifiers = ["italic"] } -"ui.cursor.match" = { fg = "my_white3", modifiers = ["underlined"] } -"string" = "my_green" -"variable.other.member" = "my_brown" -"constant.character.escape" = "my_turquoise" -"function" = "my_yellow1" -"constructor" = "my_yellow1" -"special" = "my_yellow1" -"keyword" = "my_red" -"label" = "my_red" -"namespace" = "my_white3" -"ui.help" = { fg = "my_gray6", bg = "my_gray2" } -"ui.virtual.whitespace" = { fg = "my_gray5" } -"ui.virtual.ruler" = { bg = "my_gray1" } - -"markup.heading" = "my_yellow1" -"markup.list" = "my_white2" -"markup.bold" = { modifiers = ["bold"] } -"markup.italic" = { modifiers = ["italic"] } -"markup.link.url" = "my_turquoise2" -"markup.link.text" = "my_white2" -"markup.quote" = "my_brown" -"markup.raw" = "my_green" - -"diff.plus" = "my_green" -"diff.delta" = "my_white" -"diff.minus" = "my_red" - -"diagnostic" = { modifiers = ["underlined"] } -"ui.gutter" = { bg = "my_gray0" } -"hint" = "my_gray5" -"debug" = "my_yellow2" -"info" = "my_yellow2" -"warning" = "my_yellow2" -"error" = "my_red" +inherits = "autumn" [palette] my_black = "#111111" # Cursorline From 36eff1da8cdc4efc9cec362311718fa6a4c75563 Mon Sep 17 00:00:00 2001 From: LeoniePhiline <22329650+LeoniePhiline@users.noreply.github.com> Date: Fri, 9 Dec 2022 03:58:15 +0100 Subject: [PATCH 062/132] fix(tutor): Capitalize first letter of a sentence (#5075) --- runtime/tutor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/tutor b/runtime/tutor index d977e078..418c4195 100644 --- a/runtime/tutor +++ b/runtime/tutor @@ -96,7 +96,7 @@ _________________________________________________________________ 2. Move to a place in the line which is missing text and type i to enter Insert mode. Keys you type will now type text. 3. Enter the missing text. - 4. type Escape to exit Insert mode and return to Normal mode. + 4. Type Escape to exit Insert mode and return to Normal mode. 5. Repeat until the line matches the line below it. --> Th stce misg so. From d91464208958b6f44b431d244e0f369d7907ba59 Mon Sep 17 00:00:00 2001 From: cor Date: Fri, 9 Dec 2022 04:48:56 +0100 Subject: [PATCH 063/132] use curl underlines for gruvbox_dark_hard (#5066) --- runtime/themes/gruvbox_dark_hard.toml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/runtime/themes/gruvbox_dark_hard.toml b/runtime/themes/gruvbox_dark_hard.toml index 708ca2b2..27d9ab9b 100644 --- a/runtime/themes/gruvbox_dark_hard.toml +++ b/runtime/themes/gruvbox_dark_hard.toml @@ -39,6 +39,12 @@ "info" = { fg = "aqua1", bg = "bg1" } "hint" = { fg = "blue1", bg = "bg1" } +"diagnostic" = { modifiers = ["underlined"] } +"diagnostic.error" = { underline = { style = "curl", color = "red0" } } +"diagnostic.warning" = { underline = { style = "curl", color = "orange1" } } +"diagnostic.info" = { underline = { style = "curl", color = "aqua1" } } +"diagnostic.hint" = { underline = { style = "curl", color = "blue1" } } + "ui.background" = { bg = "bg0" } "ui.linenr" = { fg = "bg4" } "ui.linenr.selected" = { fg = "yellow1" } @@ -61,8 +67,6 @@ "ui.virtual.whitespace" = "bg2" "ui.virtual.ruler" = { bg = "bg1" } -"diagnostic" = { modifiers = ["underlined"] } - "markup.heading" = "aqua1" "markup.bold" = { modifiers = ["bold"] } "markup.italic" = { modifiers = ["italic"] } From 6798a6651f9d314eacefddfd051661b030ca9d78 Mon Sep 17 00:00:00 2001 From: ath3 <45574139+ath3@users.noreply.github.com> Date: Fri, 9 Dec 2022 04:55:15 +0100 Subject: [PATCH 064/132] Only write newlines in menu selection popup if the lsp returns detail (#4902) --- helix-term/src/ui/completion.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index c54990e8..11d7886a 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -411,7 +411,7 @@ impl Component for Completion { "```{}\n{}\n```\n{}", language, option.detail.as_deref().unwrap_or_default(), - contents.clone() + contents ), cx.editor.syn_loader.clone(), ) @@ -421,15 +421,14 @@ impl Component for Completion { value: contents, })) => { // TODO: set language based on doc scope - Markdown::new( - format!( - "```{}\n{}\n```\n{}", - language, - option.detail.as_deref().unwrap_or_default(), - contents.clone() - ), - cx.editor.syn_loader.clone(), - ) + if let Some(detail) = &option.detail.as_deref() { + Markdown::new( + format!("```{}\n{}\n```\n{}", language, detail, contents), + cx.editor.syn_loader.clone(), + ) + } else { + Markdown::new(contents.to_string(), cx.editor.syn_loader.clone()) + } } None if option.detail.is_some() => { // TODO: copied from above From 8abed3bd78200fc5f7e3890fd853c17ce518d157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Fri, 9 Dec 2022 04:57:03 +0100 Subject: [PATCH 065/132] feat(lsp): pass client_info on initialization (#4904) Pass client name ('helix') and client version (version / git hash) to LSP server on initialization. --- Cargo.lock | 1 + helix-loader/build.rs | 20 ++++++++++++++++++++ helix-loader/src/lib.rs | 2 ++ helix-lsp/Cargo.toml | 1 + helix-lsp/src/client.rs | 6 +++++- helix-term/build.rs | 21 --------------------- helix-term/src/main.rs | 5 +++-- 7 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 014834e4..b204214f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1187,6 +1187,7 @@ dependencies = [ "futures-executor", "futures-util", "helix-core", + "helix-loader", "log", "lsp-types", "serde", diff --git a/helix-loader/build.rs b/helix-loader/build.rs index e0ebd1c4..c4b89e6b 100644 --- a/helix-loader/build.rs +++ b/helix-loader/build.rs @@ -1,6 +1,26 @@ +use std::borrow::Cow; +use std::process::Command; + +const VERSION: &str = include_str!("../VERSION"); + fn main() { + let git_hash = Command::new("git") + .args(["rev-parse", "HEAD"]) + .output() + .ok() + .filter(|output| output.status.success()) + .and_then(|x| String::from_utf8(x.stdout).ok()); + + let version: Cow<_> = match git_hash { + Some(git_hash) => format!("{} ({})", VERSION, &git_hash[..8]).into(), + None => VERSION.into(), + }; + println!( "cargo:rustc-env=BUILD_TARGET={}", std::env::var("TARGET").unwrap() ); + + println!("cargo:rerun-if-changed=../VERSION"); + println!("cargo:rustc-env=VERSION_AND_GIT_HASH={}", version); } diff --git a/helix-loader/src/lib.rs b/helix-loader/src/lib.rs index a02a59af..29a9f2e7 100644 --- a/helix-loader/src/lib.rs +++ b/helix-loader/src/lib.rs @@ -4,6 +4,8 @@ pub mod grammar; use etcetera::base_strategy::{choose_base_strategy, BaseStrategy}; use std::path::PathBuf; +pub const VERSION_AND_GIT_HASH: &str = env!("VERSION_AND_GIT_HASH"); + pub static RUNTIME_DIR: once_cell::sync::Lazy = once_cell::sync::Lazy::new(runtime_dir); static CONFIG_FILE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 41884e73..05c5467e 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -13,6 +13,7 @@ homepage = "https://helix-editor.com" [dependencies] helix-core = { version = "0.6", path = "../helix-core" } +helix-loader = { version = "0.6", path = "../helix-loader" } anyhow = "1.0" futures-executor = "0.3" diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 2c2c7c88..90fd2f21 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -5,6 +5,7 @@ use crate::{ }; use helix_core::{find_root, ChangeSet, Rope}; +use helix_loader::{self, VERSION_AND_GIT_HASH}; use lsp_types as lsp; use serde::Deserialize; use serde_json::Value; @@ -376,7 +377,10 @@ impl Client { ..Default::default() }, trace: None, - client_info: None, + client_info: Some(lsp::ClientInfo { + name: String::from("helix"), + version: Some(String::from(VERSION_AND_GIT_HASH)), + }), locale: None, // TODO }; diff --git a/helix-term/build.rs b/helix-term/build.rs index 719113ff..b47dae8e 100644 --- a/helix-term/build.rs +++ b/helix-term/build.rs @@ -1,30 +1,9 @@ use helix_loader::grammar::{build_grammars, fetch_grammars}; -use std::borrow::Cow; -use std::process::Command; - -const VERSION: &str = include_str!("../VERSION"); fn main() { - let git_hash = Command::new("git") - .args(["rev-parse", "HEAD"]) - .output() - .ok() - .filter(|output| output.status.success()) - .and_then(|x| String::from_utf8(x.stdout).ok()); - - let version: Cow<_> = match git_hash { - Some(git_hash) => format!("{} ({})", VERSION, &git_hash[..8]).into(), - None => VERSION.into(), - }; - if std::env::var("HELIX_DISABLE_AUTO_GRAMMAR_BUILD").is_err() { fetch_grammars().expect("Failed to fetch tree-sitter grammars"); build_grammars(Some(std::env::var("TARGET").unwrap())) .expect("Failed to compile tree-sitter grammars"); } - - println!("cargo:rerun-if-changed=../runtime/grammars/"); - println!("cargo:rerun-if-changed=../VERSION"); - - println!("cargo:rustc-env=VERSION_AND_GIT_HASH={}", version); } diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs index 96b695c6..aac5c537 100644 --- a/helix-term/src/main.rs +++ b/helix-term/src/main.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Error, Result}; use crossterm::event::EventStream; +use helix_loader::VERSION_AND_GIT_HASH; use helix_term::application::Application; use helix_term::args::Args; use helix_term::config::Config; @@ -74,7 +75,7 @@ FLAGS: --hsplit Splits all given files horizontally into different windows ", env!("CARGO_PKG_NAME"), - env!("VERSION_AND_GIT_HASH"), + VERSION_AND_GIT_HASH, env!("CARGO_PKG_AUTHORS"), env!("CARGO_PKG_DESCRIPTION"), logpath.display(), @@ -89,7 +90,7 @@ FLAGS: } if args.display_version { - println!("helix {}", env!("VERSION_AND_GIT_HASH")); + println!("helix {}", VERSION_AND_GIT_HASH); std::process::exit(0); } From 2ea20a23e26a771e095972bdda673d491b4aacc5 Mon Sep 17 00:00:00 2001 From: Jummit Date: Fri, 9 Dec 2022 05:02:34 +0100 Subject: [PATCH 066/132] Fix LSP completions ignoring auto-completion option (#5042) --- helix-term/src/commands.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 1843e7a2..2bac5be0 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3049,6 +3049,11 @@ pub mod insert { } fn language_server_completion(cx: &mut Context, ch: char) { + let config = cx.editor.config(); + if !config.auto_completion { + return; + } + use helix_lsp::lsp; // if ch matches completion char, trigger completion let doc = doc_mut!(cx.editor); From 16e13b9789359282cb6c2681262f46fb1b70134b Mon Sep 17 00:00:00 2001 From: TotalKrill Date: Fri, 9 Dec 2022 05:09:23 +0100 Subject: [PATCH 067/132] allow specifying environment for language servers in language.toml (#4004) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stephen Wakely Co-authored-by: Stephen Wakely Co-authored-by: Blaž Hrastnik --- book/src/languages.md | 3 ++- helix-core/src/syntax.rs | 2 ++ helix-lsp/src/client.rs | 3 +++ helix-lsp/src/lib.rs | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/book/src/languages.md b/book/src/languages.md index 133e6447..e45ef910 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -39,7 +39,7 @@ injection-regex = "^mylang$" file-types = ["mylang", "myl"] comment-token = "#" indent = { tab-width = 2, unit = " " } -language-server = { command = "mylang-lsp", args = ["--stdio"] } +language-server = { command = "mylang-lsp", args = ["--stdio"], environment = { "ENV1" = "value1", "ENV2" = "value2" } } formatter = { command = "mylang-formatter" , args = ["--stdin"] } ``` @@ -99,6 +99,7 @@ The `language-server` field takes the following keys: | `args` | A list of arguments to pass to the language server binary | | `timeout` | The maximum time a request to the language server may take, in seconds. Defaults to `20` | | `language-id` | The language name to pass to the language server. Some language servers support multiple languages and use this field to determine which one is being served in a buffer | +| `environment` | Any environment variables that will be used when starting the language server `{ "KEY1" = "Value1", "KEY2" = "Value2" }` | The top-level `config` field is used to configure the LSP initialization options. A `format` sub-table within `config` can be used to pass extra formatting options to diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 8dc34a3e..41ab23e1 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -207,6 +207,8 @@ pub struct LanguageServerConfiguration { #[serde(default)] #[serde(skip_serializing_if = "Vec::is_empty")] pub args: Vec, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + pub environment: HashMap, #[serde(default = "default_timeout")] pub timeout: u64, pub language_id: Option, diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 90fd2f21..dd2581c6 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -42,10 +42,12 @@ pub struct Client { impl Client { #[allow(clippy::type_complexity)] + #[allow(clippy::too_many_arguments)] pub fn start( cmd: &str, args: &[String], config: Option, + server_environment: HashMap, root_markers: &[String], id: usize, req_timeout: u64, @@ -55,6 +57,7 @@ impl Client { let cmd = which::which(cmd).map_err(|err| anyhow::anyhow!(err))?; let process = Command::new(cmd) + .envs(server_environment) .args(args) .stdin(Stdio::piped()) .stdout(Stdio::piped()) diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index f714395f..8418896c 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -550,6 +550,7 @@ fn start_client( &ls_config.command, &ls_config.args, config.config.clone(), + ls_config.environment.clone(), &config.roots, id, ls_config.timeout, From 37e7dd1df598312727aadb5c74919fd196fecffc Mon Sep 17 00:00:00 2001 From: two-six Date: Fri, 9 Dec 2022 05:11:25 +0100 Subject: [PATCH 068/132] Update `diagnostic.error` background for acme theme (#5019) --- runtime/themes/acme.toml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/themes/acme.toml b/runtime/themes/acme.toml index 696a4a9b..e1785f4a 100644 --- a/runtime/themes/acme.toml +++ b/runtime/themes/acme.toml @@ -17,9 +17,9 @@ "ui.menu" = {fg="black", bg="acme_bg"} "ui.menu.selected" = {bg="selected"} "ui.window" = {bg="acme_bg"} -"diagnostic.error" = {bg="white", modifiers=["bold"]} -"diagnostic.warning" = {bg="white", modifiers=["bold"]} -"diagnostic.hint" = {bg="white", modifiers=["bold"]} +"diagnostic.error" = {bg="red", fg="white", modifiers=["bold"]} +"diagnostic.warning" = {bg="orange", fg="black", modifiers=["bold"]} +"diagnostic.hint" = {fg="gray", modifiers=["bold"]} "ui.bufferline" = { fg = "indent", bg = "acme_bar_bg" } "ui.bufferline.active" = { fg = "black", bg = "acme_bg" } "diff.plus" = {fg = "green"} @@ -37,3 +37,5 @@ cursor = "#444444" red = "#a0342f" green = "#065905" indent = "#aaaaaa" +orange = "#f0ad4e" +gray = "#777777" From d14de277092d7eab555ea2abc1435101d12e308c Mon Sep 17 00:00:00 2001 From: "Felipe S. S. Schneider" <37125+schneiderfelipe@users.noreply.github.com> Date: Fri, 9 Dec 2022 01:33:08 -0300 Subject: [PATCH 069/132] Add support for the BibTeX file format (#5064) --- book/src/generated/lang-support.md | 1 + languages.toml | 28 ++++++++++++++++ runtime/queries/bibtex/highlights.scm | 47 +++++++++++++++++++++++++++ runtime/queries/bibtex/locals.scm | 0 runtime/queries/bibtex/tags.scm | 0 5 files changed, 76 insertions(+) create mode 100644 runtime/queries/bibtex/highlights.scm create mode 100644 runtime/queries/bibtex/locals.scm create mode 100644 runtime/queries/bibtex/tags.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index ccfd18c0..28dafd7a 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -5,6 +5,7 @@ | bash | ✓ | | | `bash-language-server` | | bass | ✓ | | | `bass` | | beancount | ✓ | | | | +| bibtex | ✓ | | | `texlab` | | bicep | ✓ | | | `bicep-langserver` | | c | ✓ | ✓ | ✓ | `clangd` | | c-sharp | ✓ | ✓ | | `OmniSharp` | diff --git a/languages.toml b/languages.toml index 325a39df..96d92ce8 100644 --- a/languages.toml +++ b/languages.toml @@ -576,6 +576,34 @@ indent = { tab-width = 4, unit = "\t" } name = "latex" source = { git = "https://github.com/latex-lsp/tree-sitter-latex", rev = "8c75e93cd08ccb7ce1ccab22c1fbd6360e3bcea6" } +[[language]] +name = "bibtex" +scope = "source.bib" +injection-regex = "bib" +file-types = ["bib"] +roots = [] +comment-token = "%" +language-server = { command = "texlab" } +indent = { tab-width = 4, unit = "\t" } +auto-format = true + +[language.formatter] +command = 'bibtex-tidy' +args = [ + "-", + "--curly", + "--drop-all-caps", + "--remove-empty-fields", + "--sort-fields", + "--sort=year,author,id", + "--strip-enclosing-braces", + "--trailing-commas", +] + +[[grammar]] +name = "bibtex" +source = { git = "https://github.com/latex-lsp/tree-sitter-bibtex", rev = "ccfd77db0ed799b6c22c214fe9d2937f47bc8b34" } + [[language]] name = "lean" scope = "source.lean" diff --git a/runtime/queries/bibtex/highlights.scm b/runtime/queries/bibtex/highlights.scm new file mode 100644 index 00000000..db1ab70c --- /dev/null +++ b/runtime/queries/bibtex/highlights.scm @@ -0,0 +1,47 @@ +[ + (string_type) + (preamble_type) + (entry_type) +] @keyword + +[ + (junk) + (comment) +] @comment + +[ + "=" + "#" +] @operator + +(command) @function.builtin + +(number) @constant.numeric + +(field + name: (identifier) @variable.builtin) + +(token + (identifier) @variable.parameter) + +[ + (brace_word) + (quote_word) +] @string + +[ + (key_brace) + (key_paren) +] @attribute + +(string + name: (identifier) @constant) + +[ + "{" + "}" + "(" + ")" +] @punctuation.bracket + +"," @punctuation.delimiter diff --git a/runtime/queries/bibtex/locals.scm b/runtime/queries/bibtex/locals.scm new file mode 100644 index 00000000..e69de29b diff --git a/runtime/queries/bibtex/tags.scm b/runtime/queries/bibtex/tags.scm new file mode 100644 index 00000000..e69de29b From f323ffabcc5846f647e3ba1d3d2ff5dec95257bd Mon Sep 17 00:00:00 2001 From: Danilo Spinella Date: Sat, 10 Dec 2022 01:40:27 +0100 Subject: [PATCH 070/132] Treat patches as diff files (#5085) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 96d92ce8..06af52bd 100644 --- a/languages.toml +++ b/languages.toml @@ -1083,7 +1083,7 @@ source = { git = "https://github.com/the-mikedavis/tree-sitter-git-commit", rev name = "diff" scope = "source.diff" roots = [] -file-types = ["diff"] +file-types = ["diff", "patch"] injection-regex = "diff" comment-token = "#" indent = { tab-width = 2, unit = " " } From 0e8ea13696206aa8ad289d539a5df62f34a73dec Mon Sep 17 00:00:00 2001 From: Ollie Charles Date: Sat, 10 Dec 2022 20:03:18 +0000 Subject: [PATCH 071/132] Add Haskell text objects (#5061) --- book/src/generated/lang-support.md | 2 +- runtime/queries/haskell/textobjects.scm | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 runtime/queries/haskell/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 28dafd7a..4dca8104 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -51,7 +51,7 @@ | gowork | ✓ | | | `gopls` | | graphql | ✓ | | | | | hare | ✓ | | | | -| haskell | ✓ | | | `haskell-language-server-wrapper` | +| haskell | ✓ | ✓ | | `haskell-language-server-wrapper` | | hcl | ✓ | | ✓ | `terraform-ls` | | heex | ✓ | ✓ | | `elixir-ls` | | html | ✓ | | | `vscode-html-language-server` | diff --git a/runtime/queries/haskell/textobjects.scm b/runtime/queries/haskell/textobjects.scm new file mode 100644 index 00000000..9870dc4a --- /dev/null +++ b/runtime/queries/haskell/textobjects.scm @@ -0,0 +1,13 @@ +(comment) @comment.inside + +[ + (adt) + (decl_type) + (newtype) +] @class.around + +((signature)? (function rhs:(_) @function.inside)) @function.around +(exp_lambda) @function.around + +(adt (type_variable) @parameter.inside) +(patterns (_) @parameter.inside) From 70d78123b94d93c801171ac3dd29e2a493feee20 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Sun, 11 Dec 2022 11:20:34 +0100 Subject: [PATCH 072/132] properly handle detachted git worktrees (#5097) --- helix-core/src/lib.rs | 2 +- helix-loader/src/grammar.rs | 2 +- helix-loader/src/lib.rs | 2 +- helix-term/src/ui/mod.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 0e76ebbb..ee174e69 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -69,7 +69,7 @@ pub fn find_root(root: Option<&str>, root_markers: &[String]) -> std::path::Path top_marker = Some(ancestor); } - if ancestor.join(".git").is_dir() { + if ancestor.join(".git").exists() { // Top marker is repo root if not root marker was detected yet if top_marker.is_none() { top_marker = Some(ancestor); diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs index 833616e0..2aa92475 100644 --- a/helix-loader/src/grammar.rs +++ b/helix-loader/src/grammar.rs @@ -263,7 +263,7 @@ fn fetch_grammar(grammar: GrammarConfiguration) -> Result { ))?; // create the grammar dir contains a git directory - if !grammar_dir.join(".git").is_dir() { + if !grammar_dir.join(".git").exists() { git(&grammar_dir, ["init"])?; } diff --git a/helix-loader/src/lib.rs b/helix-loader/src/lib.rs index 29a9f2e7..80d44a82 100644 --- a/helix-loader/src/lib.rs +++ b/helix-loader/src/lib.rs @@ -97,7 +97,7 @@ pub fn find_local_config_dirs() -> Vec { let mut directories = Vec::new(); for ancestor in current_dir.ancestors() { - if ancestor.join(".git").is_dir() { + if ancestor.join(".git").exists() { directories.push(ancestor.to_path_buf()); // Don't go higher than repo if we're in one break; diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index f61c4c45..107e48dd 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -207,7 +207,7 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi // Cap the number of files if we aren't in a git project, preventing // hangs when using the picker in your home directory - let files: Vec<_> = if root.join(".git").is_dir() { + let files: Vec<_> = if root.join(".git").exists() { files.collect() } else { // const MAX: usize = 8192; From cdc54f50a2ceb62c9f1c38b939ca988ff0e96855 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 11 Dec 2022 09:04:08 -0600 Subject: [PATCH 073/132] Reset mode when changing buffers (#5072) * Reset mode when changing buffers This is similar to the change in e4c9d4082a139aac3aea4506918171b96e81f5b9: reset the editor to normal mode when changing buffers. Usually the editor is already in normal mode but it's possible to setup insert-mode keybindings that change buffers. * Move normal mode entering code to Editor This should be called internally in the Editor when changing documents (Editor::switch) or changing focuses (Editor::focus). --- helix-term/src/commands.rs | 57 +------------------------------ helix-view/src/editor.rs | 70 +++++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 57 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 2bac5be0..1310417e 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2672,62 +2672,7 @@ fn open_above(cx: &mut Context) { } fn normal_mode(cx: &mut Context) { - if cx.editor.mode == Mode::Normal { - return; - } - - cx.editor.mode = Mode::Normal; - let (view, doc) = current!(cx.editor); - - try_restore_indent(doc, view); - - // if leaving append mode, move cursor back by 1 - if doc.restore_cursor { - let text = doc.text().slice(..); - let selection = doc.selection(view.id).clone().transform(|range| { - Range::new( - range.from(), - graphemes::prev_grapheme_boundary(text, range.to()), - ) - }); - - doc.set_selection(view.id, selection); - doc.restore_cursor = false; - } -} - -fn try_restore_indent(doc: &mut Document, view: &mut View) { - use helix_core::chars::char_is_whitespace; - use helix_core::Operation; - - fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool { - if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = - changes - { - move_pos + inserted_str.len() == pos - && inserted_str.starts_with('\n') - && inserted_str.chars().skip(1).all(char_is_whitespace) - && pos == line_end_pos // ensure no characters exists after current position - } else { - false - } - } - - let doc_changes = doc.changes().changes(); - let text = doc.text().slice(..); - let range = doc.selection(view.id).primary(); - let pos = range.cursor(text); - let line_end_pos = line_end_char_index(&text, range.cursor_line(text)); - - if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) { - // Removes tailing whitespaces. - let transaction = - Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| { - let line_start_pos = text.line_to_char(range.cursor_line(text)); - (line_start_pos, pos, None) - }); - apply_transaction(&transaction, doc, view); - } + cx.editor.enter_normal_mode(); } // Store a jump on the jumplist. diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 973cf82e..c13a6673 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1005,6 +1005,8 @@ impl Editor { return; } + self.enter_normal_mode(); + match action { Action::Replace => { let (view, doc) = current_ref!(self); @@ -1025,6 +1027,9 @@ impl Editor { let (view, doc) = current!(self); let view_id = view.id; + // Append any outstanding changes to history in the old document. + doc.append_changes_to_history(view); + if remove_empty_scratch { // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable // borrow, invalidating direct access to `doc.id`. @@ -1262,7 +1267,7 @@ impl Editor { // if leaving the view: mode should reset and the cursor should be // within view if prev_id != view_id { - self.mode = Mode::Normal; + self.enter_normal_mode(); self.ensure_cursor_in_view(view_id); // Update jumplist selections with new document changes. @@ -1427,4 +1432,67 @@ impl Editor { Ok(()) } + + /// Switches the editor into normal mode. + pub fn enter_normal_mode(&mut self) { + use helix_core::{graphemes, Range}; + + if self.mode == Mode::Normal { + return; + } + + self.mode = Mode::Normal; + let (view, doc) = current!(self); + + try_restore_indent(doc, view); + + // if leaving append mode, move cursor back by 1 + if doc.restore_cursor { + let text = doc.text().slice(..); + let selection = doc.selection(view.id).clone().transform(|range| { + Range::new( + range.from(), + graphemes::prev_grapheme_boundary(text, range.to()), + ) + }); + + doc.set_selection(view.id, selection); + doc.restore_cursor = false; + } + } +} + +fn try_restore_indent(doc: &mut Document, view: &mut View) { + use helix_core::{ + chars::char_is_whitespace, line_ending::line_end_char_index, Operation, Transaction, + }; + + fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool { + if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = + changes + { + move_pos + inserted_str.len() == pos + && inserted_str.starts_with('\n') + && inserted_str.chars().skip(1).all(char_is_whitespace) + && pos == line_end_pos // ensure no characters exists after current position + } else { + false + } + } + + let doc_changes = doc.changes().changes(); + let text = doc.text().slice(..); + let range = doc.selection(view.id).primary(); + let pos = range.cursor(text); + let line_end_pos = line_end_char_index(&text, range.cursor_line(text)); + + if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) { + // Removes tailing whitespaces. + let transaction = + Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| { + let line_start_pos = text.line_to_char(range.cursor_line(text)); + (line_start_pos, pos, None) + }); + crate::apply_transaction(&transaction, doc, view); + } } From c5bfb792b2a26545f6515a1e7b62d4f37b10841e Mon Sep 17 00:00:00 2001 From: Slug <106496265+GreasySlug@users.noreply.github.com> Date: Mon, 12 Dec 2022 03:14:10 +0900 Subject: [PATCH 074/132] update(theme): adjust base16_transparent and dark_high_contrast (#5105) --- book/src/themes.md | 2 +- runtime/themes/base16_transparent.toml | 45 +++++++++++++------------ runtime/themes/dark_high_contrast.toml | 46 ++++++++++++++------------ 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/book/src/themes.md b/book/src/themes.md index 392b5f8c..322caea5 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -103,7 +103,7 @@ Some styles might not be supported by your terminal emulator. | `line` | | `curl` | | `dashed` | -| `dot` | +| `dotted` | | `double_line` | diff --git a/runtime/themes/base16_transparent.toml b/runtime/themes/base16_transparent.toml index 0c6d924f..f8ee0890 100644 --- a/runtime/themes/base16_transparent.toml +++ b/runtime/themes/base16_transparent.toml @@ -1,27 +1,28 @@ # Author: GreasySlug <9619abgoni@gmail.com> +# This theme is base on base16_theme(Author: NNB ) "ui.background" = { fg = "white"} "ui.background.separator" = { fg = "gray" } -"ui.menu" = { fg = "gray" } +"ui.menu" = { fg = "white" } "ui.menu.selected" = { modifiers = ["reversed"] } "ui.menu.scroll" = { fg = "light-gray" } "ui.linenr" = { fg = "light-gray" } "ui.linenr.selected" = { fg = "white", modifiers = ["bold"] } "ui.popup" = { fg = "white" } "ui.window" = { fg = "white" } -"ui.selection" = { modifiers = [ "reversed"] } -"comment" = { fg = "gray", modifiers = ["italic"] } +"ui.selection" = { bg = "gray" } +"comment" = "light-gray" "ui.statusline" = { fg = "white" } "ui.statusline.inactive" = { fg = "gray" } -"ui.statusline.normal" = { fg = "blue", modifiers = ["reversed"] } -"ui.statusline.insert" = { fg = "green", modifiers = ["reversed"] } -"ui.statusline.select" = { fg = "magenta", modifiers = ["reversed"] } +"ui.statusline.normal" = { fg = "black", bg = "blue" } +"ui.statusline.insert" = { fg = "black", bg = "green" } +"ui.statusline.select" = { fg = "black", bg = "magenta" } "ui.help" = { fg = "light-gray" } "ui.cursor" = { modifiers = ["reversed"] } -"ui.cursor.match" = { fg = "light-yellow", modifiers = ["underlined"] } +"ui.cursor.match" = { fg = "light-yellow", underline = { color = "light-yellow", style = "line" } } "ui.cursor.primary" = { modifiers = ["reversed", "slow_blink"] } "ui.cursor.secondary" = { modifiers = ["reversed"] } -"ui.virtual.ruler" = { fg = "gray", modifiers = ["reversed"] } +"ui.virtual.ruler" = { bg = "gray" } "ui.virtual.whitespace" = "gray" "ui.virtual.indent-guide" = "gray" @@ -44,7 +45,7 @@ "markup.list" = "light-red" "markup.bold" = { fg = "light-yellow", modifiers = ["bold"] } "markup.italic" = { fg = "light-magenta", modifiers = ["italic"] } -"markup.link.url" = { fg = "yellow", modifiers = ["underlined"] } +"markup.link.url" = { fg = "yellow", underline = { color = "yellow", style = "line"} } "markup.link.text" = "light-red" "markup.quote" = "light-cyan" "markup.raw" = "green" @@ -53,19 +54,19 @@ "markup.select" = { fg = "magenta" } "diff.plus" = "light-green" -"diff.delta" = "yellow" +"diff.delta" = "light-blue" +"diff.delta.moved" = "blue" "diff.minus" = "light-red" -"ui.gutter" = "gray" -"info" = "light-blue" -"hint" = "gray" -"debug" = "gray" -"warning" = "yellow" -"error" = "light-red" +"ui.gutter" = "gray" +"info" = "light-blue" +"hint" = "light-gray" +"debug" = "light-gray" +"warning" = "light-yellow" +"error" = "light-red" -"diagnostic" = { modifiers = ["underlined"] } -"diagnostic.info" = { fg = "light-blue", modifiers = ["underlined"] } -"diagnostic.hint" = { fg = "gray", modifiers = ["underlined"] } -"diagnostic.debug" ={ fg ="gray", modifiers = ["underlined"] } -"diagnostic.warning" = { fg = "yellow", modifiers = ["underlined"] } -"diagnostic.error" = { fg ="light-red", modifiers = ["underlined"] } +"diagnostic.info" = { underline = { color = "light-blue", style = "dotted" } } +"diagnostic.hint" = { underline = { color = "light-gray", style = "double_line" } } +"diagnostic.debug" = { underline ={ color ="light-gray", style = "dashed" } } +"diagnostic.warning" = { underline = { color = "light-yellow", style = "curl" } } +"diagnostic.error" = { underline = { color ="light-red", style = "curl" } } diff --git a/runtime/themes/dark_high_contrast.toml b/runtime/themes/dark_high_contrast.toml index c65750f4..1c911eb5 100644 --- a/runtime/themes/dark_high_contrast.toml +++ b/runtime/themes/dark_high_contrast.toml @@ -9,29 +9,29 @@ "ui.text.focus" = { modifiers = ["reversed"] } # file picker selected "ui.virtual.whitespace" = "gray" -"ui.virtual.ruler" = { fg = "gray", bg = "white", modifiers = ["reversed"] } +"ui.virtual.ruler" = { fg = "white", bg = "gray" } "ui.virtual.indent-guide" = "white" "ui.statusline" = { fg = "white", bg = "deep_blue" } -"ui.statusline.inactive" = { fg = "gray" } +"ui.statusline.inactive" = { fg = "gray", bg = "deep_blue" } "ui.statusline.normal" = { fg = "black", bg = "aqua" } "ui.statusline.insert" = { fg = "black", bg = "orange" } "ui.statusline.select" = { fg = "black", bg = "purple" } -# "ui.statusline.separator" = { fg = "aqua", bg = "white" } +"ui.statusline.separator" = { fg = "aqua", bg = "white" } "ui.cursor" = { fg = "black", bg = "white" } "ui.cursor.insert" = { fg = "black", bg = "white" } "ui.cursor.select" = { fg = "black", bg = "white" } "ui.cursor.match" = { bg = "white", modifiers = ["dim"] } "ui.cursor.primary" = { fg = "black", bg = "white", modifiers = ["slow_blink"] } - "ui.cursor.secondary" = "white" -"ui.cursorline.primary" = { fg = "orange", modifiers = ["underlined"] } -"ui.cursorline.secondary" = { fg = "orange", modifiers = ["underlined"] } -"ui.selection" = { fg = "deep_blue", bg = "white" } +"ui.cursorline.primary" = { bg = "deep_blue", underline = { color = "orange", style = "double_line" } } +"ui.cursorline.secondary" = { bg = "dark_blue", underline = { color = "white", style = "line" } } +"ui.selection" = { fg = "dark_blue", bg = "white" } +"ui.selection.primary" = { fg = "deep_blue", bg = "white" } "ui.menu" = { fg = "white", bg = "deep_blue" } -"ui.menu.selected" = { fg = "orange", modifiers = ["underlined"] } +"ui.menu.selected" = { fg = "orange", underline = { style = "line" } } "ui.menu.scroll" = { fg = "aqua", bg = "black" } "ui.help" = { fg = "white", bg = "deep_blue" } @@ -39,15 +39,16 @@ "ui.popup.info" = { fg = "white", bg = "deep_blue" } "ui.gutter" = { bg = "black" } +"ui.gutter.selected" = { bg = "black" } "ui.linenr" = { fg = "white", bg = "black" } "ui.linenr.selected" = { fg = "orange", bg = "black", modifiers = ["bold"] } # Diagnostic -"diagnostic" = "white" -"diagnostic.info" = { bg = "white", modifiers = ["underlined"] } -"diagnostic.hint" = { fg = "yellow", modifiers = ["underlined"] } -"diagnostic.warning" = { fg = "orange", modifiers = ["underlined"] } -"diagnostic.error" = { fg = "red", modifiers = ["underlined"] } +"diagnostic" = { fg = "white" } +"diagnostic.info" = { underline = { color = "white", style = "dotted" } } +"diagnostic.hint" = { underline = { color = "yellow", style = "dashed" } } +"diagnostic.warning" = { underline = { color = "orange", style = "curl" } } +"diagnostic.error" = { underline = { color = "red", style = "curl" } } "info" = "white" "hint" = "yellow" "warning" = "orange" @@ -59,31 +60,31 @@ "diff.minus" = "pink" # Syntax high light -"type" = { fg = "emerald_green" } +"type" = "emerald_green" "type.buildin" = "emerald_green" -"comment" = { fg = "white" } +"comment" = "white" "operator" = "white" -"variable" = { fg = "aqua" } +"variable" = "aqua" "variable.other.member" = "brown" "constant" = "aqua" "constant.numeric" = "emerald_green" -"attributes" = { fg = "blue" } +"attributes" = "blue" "namespace" = "blue" "string" = "brown" -"string.special.url" = { fg = "brown", modifiers =["underlined"]} +"string.special.url" = "brown" "constant.character.escape" = "yellow" "constructor" = "aqua" -"keyword" = { fg = "blue", modifiers = ["underlined"] } +"keyword" = "blue" "keyword.control" = "purple" "function" = "yellow" "label" = "blue" # Markup -"markup.heading" = { fg = "yellow", modifiers = ["bold", "underlined"] } -"markup.list" = { fg = "pink" } +"markup.heading" = { fg = "yellow", modifiers = ["bold"], underline = { color = "yellow", style = "double_line"} } +"markup.list" = "pink" "markup.bold" = { fg = "emerald_green", modifiers = ["bold"] } "markup.italic" = { fg = "blue", modifiers = ["italic"] } -"markup.link.url" = { fg = "blue", modifiers = ["underlined"] } +"markup.link.url" = { fg = "blue", underline = { color = "blue", style = "line" } } "markup.link.text" = "pink" "markup.quote" = "yellow" "markup.raw" = "brown" @@ -94,6 +95,7 @@ gray = "#585858" white = "#ffffff" blue = "#66a4ff" deep_blue = "#142743" +dark_blue = "#0d1a2d" aqua = "#6fc3df" purple = "#c586c0" red = "#b65f5f" From a34ba071be0a48a35f36ada7759dee53d783e57b Mon Sep 17 00:00:00 2001 From: garlic0x1 <43155857+garlic0x1@users.noreply.github.com> Date: Sun, 11 Dec 2022 19:59:27 -0600 Subject: [PATCH 075/132] Fix commonlisp filetypes typo and auto-pairs (#5091) --- languages.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 06af52bd..dae675df 100644 --- a/languages.toml +++ b/languages.toml @@ -918,13 +918,19 @@ grammar = "scheme" name = "common-lisp" scope = "source.lisp" roots = [] -file-types = ["lisp", "asd", "cl", "l", "lsp", "ny"," podsl", "sexp"] +file-types = ["lisp", "asd", "cl", "l", "lsp", "ny", "podsl", "sexp"] shebangs = ["lisp", "sbcl", "ccl", "clisp", "ecl"] comment-token = ";" indent = { tab-width = 2, unit = " " } language-server = { command = "cl-lsp", args = [ "stdio" ] } grammar = "scheme" +[language.auto-pairs] +'(' = ')' +'{' = '}' +'[' = ']' +'"' = '"' + [[language]] name = "comment" scope = "scope.comment" From d5ab974d38fd5565a63c8d7c35967c77c0e434d0 Mon Sep 17 00:00:00 2001 From: Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Date: Mon, 12 Dec 2022 02:59:53 +0100 Subject: [PATCH 076/132] chore(book): link repository (#5101) --- book/book.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/book/book.toml b/book/book.toml index 2277a0bd..9835145c 100644 --- a/book/book.toml +++ b/book/book.toml @@ -9,3 +9,4 @@ edit-url-template = "https://github.com/helix-editor/helix/tree/master/book/{pat cname = "docs.helix-editor.com" default-theme = "colibri" preferred-dark-theme = "colibri" +git-repository-url = "https://github.com/helix-editor/helix" From 0b960216433956503e9e6fe5220523eb1970eaee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Schl=C3=B6gl?= Date: Mon, 12 Dec 2022 03:06:24 +0100 Subject: [PATCH 077/132] Add `:pipe-to` typable command that ignores shell output (#4931) --- book/src/generated/typable-cmd.md | 1 + helix-term/src/commands/typed.rs | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 6390ef85..66e6ac03 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -71,4 +71,5 @@ | `:insert-output` | Run shell command, inserting output before each selection. | | `:append-output` | Run shell command, appending output after each selection. | | `:pipe` | Pipe each selection to the shell command. | +| `:pipe-to` | Pipe each selection to the shell command, ignoring output. | | `:run-shell-command`, `:sh` | Run a shell command | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 03fcaa55..2119a48d 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1741,13 +1741,30 @@ fn insert_output( Ok(()) } +fn pipe_to( + cx: &mut compositor::Context, + args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + pipe_impl(cx, args, event, &ShellBehavior::Ignore) +} + fn pipe(cx: &mut compositor::Context, args: &[Cow], event: PromptEvent) -> anyhow::Result<()> { + pipe_impl(cx, args, event, &ShellBehavior::Replace) +} + +fn pipe_impl( + cx: &mut compositor::Context, + args: &[Cow], + event: PromptEvent, + behavior: &ShellBehavior, +) -> anyhow::Result<()> { if event != PromptEvent::Validate { return Ok(()); } ensure!(!args.is_empty(), "Shell command required"); - shell(cx, &args.join(" "), &ShellBehavior::Replace); + shell(cx, &args.join(" "), behavior); Ok(()) } @@ -2292,6 +2309,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: pipe, completer: None, }, + TypableCommand { + name: "pipe-to", + aliases: &[], + doc: "Pipe each selection to the shell command, ignoring output.", + fun: pipe_to, + completer: None, + }, TypableCommand { name: "run-shell-command", aliases: &["sh"], From bae890d8faa993333d81e662b6f0a6bc5e921a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 12 Dec 2022 17:49:57 +0900 Subject: [PATCH 078/132] Update tree-sitter-scheme --- languages.toml | 2 +- runtime/queries/rust/highlights.scm | 11 +++++- runtime/queries/scheme/highlights.scm | 55 +++++++++++++-------------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/languages.toml b/languages.toml index dae675df..e6bc344c 100644 --- a/languages.toml +++ b/languages.toml @@ -1583,7 +1583,7 @@ indent = { tab-width = 2, unit = " " } [[grammar]] name = "scheme" -source = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "27fb77db05f890c2823b4bd751c6420378df146b" } +source = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "c0741320bfca6b7b5b7a13b5171275951e96a842" } [[language]] name = "v" diff --git a/runtime/queries/rust/highlights.scm b/runtime/queries/rust/highlights.scm index 5606e93d..d3c29270 100644 --- a/runtime/queries/rust/highlights.scm +++ b/runtime/queries/rust/highlights.scm @@ -5,8 +5,6 @@ ; overrides are unnecessary. ; ------- - - ; ------- ; Types ; ------- @@ -241,6 +239,14 @@ +(attribute + (identifier) @_macro + arguments: (token_tree (identifier) @constant.numeric.integer) + (#eq? @_macro "derive") +) +@special + + ; ------- ; Functions ; ------- @@ -271,6 +277,7 @@ ; --- ; Macros ; --- + (attribute (identifier) @function.macro) (attribute diff --git a/runtime/queries/scheme/highlights.scm b/runtime/queries/scheme/highlights.scm index 3b7a4275..46819374 100644 --- a/runtime/queries/scheme/highlights.scm +++ b/runtime/queries/scheme/highlights.scm @@ -2,29 +2,40 @@ (character) @constant.character (boolean) @constant.builtin.boolean -[(string) - (character)] @string +(string) @string (escape_sequence) @constant.character.escape -[(comment) - (block_comment) - (directive)] @comment +(comment) @comment.line +(block_comment) @comment.block +(directive) @keyword.directive -[(boolean) - (character)] @constant +; operators -((symbol) @function.builtin - (#match? @function.builtin "^(eqv\\?|eq\\?|equal\\?)")) ; TODO +((symbol) @operator + (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) ; keywords -((symbol) @keyword.conditional - (#match? @keyword.conditional "^(if|cond|case|when|unless)$")) +(list + . + ((symbol) @keyword.conditional + (#match? @keyword.conditional "^(if|cond|case|when|unless)$" + ))) -((symbol) @keyword - (#match? @keyword - "^(define|lambda|begin|do|define-syntax|and|or|if|cond|case|when|unless|else|=>|let|let*|let-syntax|let-values|let*-values|letrec|letrec*|letrec-syntax|set!|syntax-rules|identifier-syntax|quote|unquote|quote-splicing|quasiquote|unquote-splicing|delay|assert|library|export|import|rename|only|except|prefix)$")) +(list + . + (symbol) @keyword + (#match? @keyword + "^(define-syntax|let\\*|lambda|λ|case|=>|quote-splicing|unquote-splicing|set!|let|letrec|letrec-syntax|let-values|let\\*-values|do|else|define|cond|syntax-rules|unquote|begin|quote|let-syntax|and|if|quasiquote|letrec|delay|or|when|unless|identifier-syntax|assert|library|export|import|rename|only|except|prefix)$" + )) + +(list + . + (symbol) @function.builtin + (#match? @function.builtin + "^(caar|cadr|call-with-input-file|call-with-output-file|cdar|cddr|list|open-input-file|open-output-file|with-input-from-file|with-output-to-file|\\*|\\+|-|/|<|<=|=|>|>=|abs|acos|angle|append|apply|asin|assoc|assq|assv|atan|boolean\\?|caaaar|caaadr|caaar|caadar|caaddr|caadr|cadaar|cadadr|cadar|caddar|cadddr|caddr|call-with-current-continuation|call-with-values|car|cdaaar|cdaadr|cdaar|cdadar|cdaddr|cdadr|cddaar|cddadr|cddar|cdddar|cddddr|cdddr|cdr|ceiling|char->integer|char-alphabetic\\?|char-ci<=\\?|char-ci<\\?|char-ci=\\?|char-ci>=\\?|char-ci>\\?|char-downcase|char-lower-case\\?|char-numeric\\?|char-ready\\?|char-upcase|char-upper-case\\?|char-whitespace\\?|char<=\\?|char<\\?|char=\\?|char>=\\?|char>\\?|char\\?|close-input-port|close-output-port|complex\\?|cons|cos|current-error-port|current-input-port|current-output-port|denominator|display|dynamic-wind|eof-object\\?|eq\\?|equal\\?|eqv\\?|eval|even\\?|exact->inexact|exact\\?|exp|expt|floor|flush-output|for-each|force|gcd|imag-part|inexact->exact|inexact\\?|input-port\\?|integer->char|integer\\?|interaction-environment|lcm|length|list->string|list->vector|list-ref|list-tail|list\\?|load|log|magnitude|make-polar|make-rectangular|make-string|make-vector|map|max|member|memq|memv|min|modulo|negative\\?|newline|not|null-environment|null\\?|number->string|number\\?|numerator|odd\\?|output-port\\?|pair\\?|peek-char|positive\\?|procedure\\?|quotient|rational\\?|rationalize|read|read-char|real-part|real\\?|remainder|reverse|round|scheme-report-environment|set-car!|set-cdr!|sin|sqrt|string|string->list|string->number|string->symbol|string-append|string-ci<=\\?|string-ci<\\?|string-ci=\\?|string-ci>=\\?|string-ci>\\?|string-copy|string-fill!|string-length|string-ref|string-set!|string<=\\?|string<\\?|string=\\?|string>=\\?|string>\\?|string\\?|substring|symbol->string|symbol\\?|tan|transcript-off|transcript-on|truncate|values|vector|vector->list|vector-fill!|vector-length|vector-ref|vector-set!|vector\\?|write|write-char|zero\\?)$" + )) ; special forms @@ -47,26 +58,16 @@ . (list (list - (symbol) @variable)) + (symbol) @variable.parameter)) (#match? @_f "^(let|let\\*|let-syntax|let-values|let\\*-values|letrec|letrec\\*|letrec-syntax)$")) -; operators - -(list - . - (symbol) @operator - (#match? @operator "^([+*/<>=-]|(<=)|(>=))$")) - ; quote -(abbreviation - "'" (symbol)) @constant - (list . (symbol) @_f - (#eq? @_f "quote")) @symbol + (#eq? @_f "quote")) @string.symbol ; library @@ -89,12 +90,10 @@ ((symbol) @variable.builtin (#eq? @variable.builtin "...")) -(symbol) @variable ((symbol) @variable.builtin (#eq? @variable.builtin ".")) (symbol) @variable - ["(" ")" "[" "]" "{" "}"] @punctuation.bracket From f995f2610b3ad3aa68cec42ea14ce067a1ed3655 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Dec 2022 17:20:26 -0600 Subject: [PATCH 079/132] build(deps): bump serde from 1.0.149 to 1.0.150 (#5138) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.149 to 1.0.150. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.149...v1.0.150) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b204214f..040a039c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1805,18 +1805,18 @@ checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" [[package]] name = "serde" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" dependencies = [ "proc-macro2", "quote", From fa436fa680b5bcf6d46666a03ae23b94a74e0414 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Dec 2022 17:25:05 -0600 Subject: [PATCH 080/132] build(deps): bump tokio from 1.22.0 to 1.23.0 (#5137) Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.22.0 to 1.23.0. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.22.0...tokio-1.23.0) --- updated-dependencies: - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- helix-lsp/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 040a039c..6ae0a71f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2100,9 +2100,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", @@ -2115,7 +2115,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys", ] [[package]] diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 05c5467e..d04edcd5 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -23,6 +23,6 @@ lsp-types = { version = "0.93", features = ["proposed"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.22", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } +tokio = { version = "1.23", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } tokio-stream = "0.1.11" which = "4.2" From 00092a29c4f8ca7402455a9a494147ee3521bd4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 13 Dec 2022 15:07:20 +0900 Subject: [PATCH 081/132] Use dtolnay/rust-toolchain in more places --- .github/workflows/build.yml | 9 ++------ .github/workflows/release.yml | 42 ++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index deeff80e..3a4896f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,10 +44,7 @@ jobs: uses: actions/checkout@v3 - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true + uses: dtolnay/rust-toolchain@1.61 - uses: Swatinem/rust-cache@v2 @@ -76,10 +73,8 @@ jobs: uses: actions/checkout@v3 - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 + uses: dtolnay/rust-toolchain@1.61 with: - profile: minimal - override: true components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c242f089..8c105bfc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,10 +26,7 @@ jobs: uses: actions/checkout@v3 - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true + uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 @@ -47,6 +44,16 @@ jobs: dist: name: Dist needs: [fetch-grammars] + env: + # For some builds, we use cross to test on 32-bit and big-endian + # systems. + CARGO: cargo + # When CARGO is set to CROSS, this is set to `--target matrix.target`. + TARGET_FLAGS: + # When CARGO is set to CROSS, TARGET_DIR includes matrix.target. + TARGET_DIR: ./target + # Emit backtraces on panics. + RUST_BACKTRACE: 1 runs-on: ${{ matrix.os }} strategy: fail-fast: false # don't fail other jobs if one fails @@ -107,12 +114,10 @@ jobs: tar xJf grammars/grammars.tar.xz -C runtime/grammars/sources - name: Install ${{ matrix.rust }} toolchain - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} - override: true # Install a pre-release version of Cross # TODO: We need to pre-install Cross because we need cross-rs/cross#591 to @@ -120,15 +125,20 @@ jobs: # 0.3.0, which includes cross-rs/cross#591, is released. - name: Install Cross if: "matrix.cross" - run: cargo install cross --git https://github.com/cross-rs/cross.git --rev 47df5c76e7cba682823a0b6aa6d95c17b31ba63a + run: | + cargo install cross --git https://github.com/cross-rs/cross.git --rev 47df5c76e7cba682823a0b6aa6d95c17b31ba63a + echo "CARGO=cross" >> $GITHUB_ENV + # echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV + # echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV + + - name: Show command used for Cargo + run: | + echo "cargo command is: ${{ env.CARGO }}" + echo "target flag is: ${{ env.TARGET_FLAGS }}" - name: Run cargo test - uses: actions-rs/cargo@v1 if: "!matrix.skip_tests" - with: - use-cross: ${{ matrix.cross }} - command: test - args: --release --locked --target ${{ matrix.target }} --workspace + run: ${{ env.CARGO }} test --release --locked --target ${{ matrix.target }} --workspace - name: Set profile.release.strip = true shell: bash @@ -139,11 +149,7 @@ jobs: EOF - name: Build release binary - uses: actions-rs/cargo@v1 - with: - use-cross: ${{ matrix.cross }} - command: build - args: --release --locked --target ${{ matrix.target }} + run: ${{ env.CARGO }} build --release --locked --target ${{ matrix.target }} - name: Build AppImage shell: bash From e6fce860b10faab1cb50b7709a67ded113364392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 13 Dec 2022 15:08:24 +0900 Subject: [PATCH 082/132] Use latest github runner images --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8c105bfc..9518a537 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,17 +61,17 @@ jobs: build: [x86_64-linux, x86_64-macos, x86_64-windows] #, x86_64-win-gnu, win32-msvc include: - build: x86_64-linux - os: ubuntu-20.04 + os: ubuntu-latest rust: stable target: x86_64-unknown-linux-gnu cross: false - build: aarch64-linux - os: ubuntu-20.04 + os: ubuntu-latest rust: stable target: aarch64-unknown-linux-gnu cross: true - build: riscv64-linux - os: ubuntu-20.04 + os: ubuntu-latest rust: stable target: riscv64gc-unknown-linux-gnu cross: true @@ -81,7 +81,7 @@ jobs: target: x86_64-apple-darwin cross: false - build: x86_64-windows - os: windows-2019 + os: windows-latest rust: stable target: x86_64-pc-windows-msvc cross: false From 0f2ae35a1336d5fef823127dc134ed5675e5b9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 13 Dec 2022 15:14:40 +0900 Subject: [PATCH 083/132] ci: Merge two jobs --- .github/workflows/build.yml | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3a4896f1..0d6fcb3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,13 +98,13 @@ jobs: uses: actions/checkout@v3 - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true + uses: dtolnay/rust-toolchain@1.61 - uses: Swatinem/rust-cache@v2 + - name: Validate queries + run: cargo xtask query-check + - name: Generate docs run: cargo xtask docgen @@ -115,20 +115,3 @@ jobs: || (echo "Run 'cargo xtask docgen', commit the changes and push again" \ && exit 1) - queries: - name: Tree-sitter queries - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Install stable toolchain - uses: helix-editor/rust-toolchain@v1 - with: - profile: minimal - override: true - - - uses: Swatinem/rust-cache@v2 - - - name: Generate docs - run: cargo xtask query-check From 436296b76c671446aab8863b467155ff9e94d4fc Mon Sep 17 00:00:00 2001 From: Erasin Date: Wed, 14 Dec 2022 21:51:00 +0800 Subject: [PATCH 084/132] Add Mermaid.js for markdown support (#5147) --- book/src/generated/lang-support.md | 1 + languages.toml | 13 ++ runtime/queries/mermaid/highlights.scm | 187 +++++++++++++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 runtime/queries/mermaid/highlights.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 4dca8104..fa7b6edd 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -77,6 +77,7 @@ | make | ✓ | | | | | markdown | ✓ | | | `marksman` | | markdown.inline | ✓ | | | | +| mermaid | ✓ | | | | | meson | ✓ | | ✓ | | | mint | | | | `mint` | | nickel | ✓ | | ✓ | `nls` | diff --git a/languages.toml b/languages.toml index e6bc344c..e28476d3 100644 --- a/languages.toml +++ b/languages.toml @@ -2043,3 +2043,16 @@ grammar = "qmljs" [[grammar]] name = "qmljs" source = { git = "https://github.com/yuja/tree-sitter-qmljs", rev = "0b2b25bcaa7d4925d5f0dda16f6a99c588a437f1" } + +[[language]] +name = "mermaid" +scope = "source.mermaid" +injection-regex = "mermaid" +file-types = ["mermaid"] +roots = [] +comment-token = "%%" +indent = { tab-width = 4, unit = " " } + +[[grammar]] +name = "mermaid" +source = { git = "https://github.com/monaqa/tree-sitter-mermaid", rev = "d787c66276e7e95899230539f556e8b83ee16f6d" } diff --git a/runtime/queries/mermaid/highlights.scm b/runtime/queries/mermaid/highlights.scm new file mode 100644 index 00000000..b546d39f --- /dev/null +++ b/runtime/queries/mermaid/highlights.scm @@ -0,0 +1,187 @@ +[ + "sequenceDiagram" + "classDiagram" + "classDiagram-v2" + "stateDiagram" + "stateDiagram-v2" + "gantt" + "pie" + "flowchart" + "erdiagram" + + "participant" + "as" + "activate" + "deactivate" + "note " + "over" + "link" + "links" + ; "left of" + ; "right of" + "properties" + "details" + "title" + "loop" + "rect" + "opt" + "alt" + "else" + "par" + "and" + "end" + (sequence_stmt_autonumber) + (note_placement_left) + (note_placement_right) + + "class" + + "state " + + "dateformat" + "inclusiveenddates" + "topaxis" + "axisformat" + "includes" + "excludes" + "todaymarker" + "title" + "section" + + "direction" + "subgraph" + + ] @keyword + +[ + (comment) + ] @comment + +(flow_vertex_id) @type +(flow_arrow_text) @label +(flow_text_literal) @string + +[ + ":" + (sequence_signal_plus_sign) + (sequence_signal_minus_sign) + + (class_visibility_public) + (class_visibility_private) + (class_visibility_protected) + (class_visibility_internal) + + (state_division) + ] @punctuation.delimiter + +[ + "(" + ")" + "{" + "}" + ] @punctuation.bracket + +[ + "-->" + (solid_arrow) + (dotted_arrow) + (solid_open_arrow) + (dotted_open_arrow) + (solid_cross) + (dotted_cross) + (solid_point) + (dotted_point) + ] @operator + +[ + (class_reltype_aggregation) + (class_reltype_extension) + (class_reltype_composition) + (class_reltype_dependency) + (class_linetype_solid) + (class_linetype_dotted) + "&" + ] @operator + +(sequence_actor) @variable +(sequence_text) @string + +(class_name) @type +(class_label) @string +(class_method_line) @function.method + +(state_name) @variable + +(gantt_section) @markup.heading +(gantt_task_text) @variable.builtin +(gantt_task_data) @string + +[ + (class_annotation_line) + (class_stmt_annotation) + (class_generics) + + (state_annotation_fork) + (state_annotation_join) + (state_annotation_choice) + ] @type + +(directive) @keyword.directive + +(pie_label) @string +(pie_value) @constant.numeric + +[ +(flowchart_direction_lr) +(flowchart_direction_rl) +(flowchart_direction_tb) +(flowchart_direction_bt) + ] @constant + +(flow_vertex_id) @variable + +[ + (flow_link_arrow) + (flow_link_arrow_start) + ] @operator + +(flow_link_arrowtext "|" @punctuation.bracket) + +(flow_vertex_square [ "[" "]" ] @punctuation.bracket ) +(flow_vertex_circle ["((" "))"] @punctuation.bracket ) +(flow_vertex_ellipse ["(-" "-)"] @punctuation.bracket ) +(flow_vertex_stadium ["([" "])"] @punctuation.bracket ) +(flow_vertex_subroutine ["[[" "]]"] @punctuation.bracket ) +(flow_vertex_rect ["[|" "|]"] @punctuation.bracket ) +(flow_vertex_cylinder ["[(" ")]"] @punctuation.bracket ) +(flow_vertex_round ["(" ")"] @punctuation.bracket ) +(flow_vertex_diamond ["{" "}"] @punctuation.bracket ) +(flow_vertex_hexagon ["{{" "}}"] @punctuation.bracket ) +(flow_vertex_odd [">" "]"] @punctuation.bracket ) +(flow_vertex_trapezoid ["[/" "\\]"] @punctuation.bracket ) +(flow_vertex_inv_trapezoid ["[\\" "/]"] @punctuation.bracket ) +(flow_vertex_leanright ["[/" "/]"] @punctuation.bracket ) +(flow_vertex_leanleft ["[\\" "\\]"] @punctuation.bracket ) + +(flow_stmt_subgraph ["[" "]"] @punctuation.bracket ) + +[ + (er_cardinarity_zero_or_one) + (er_cardinarity_zero_or_more) + (er_cardinarity_one_or_more) + (er_cardinarity_only_one) + (er_reltype_non_identifying) + (er_reltype_identifying) + ] @operator + +(er_entity_name) @variable + +(er_attribute_type) @type +(er_attribute_name) @variable + +[ + (er_attribute_key_type_pk) + (er_attribute_key_type_fk) + ] @keyword + +(er_attribute_comment) @string From 012fc12f97f4e8e0fc38af351388e41e8bc142d8 Mon Sep 17 00:00:00 2001 From: gavincrawford <94875769+gavincrawford@users.noreply.github.com> Date: Wed, 14 Dec 2022 07:42:11 -0700 Subject: [PATCH 085/132] Add Bash indents (#5149) --- book/src/generated/lang-support.md | 2 +- runtime/queries/bash/indents.scm | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 runtime/queries/bash/indents.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index fa7b6edd..1400fa87 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -2,7 +2,7 @@ | --- | --- | --- | --- | --- | | astro | ✓ | | | | | awk | ✓ | ✓ | | `awk-language-server` | -| bash | ✓ | | | `bash-language-server` | +| bash | ✓ | | ✓ | `bash-language-server` | | bass | ✓ | | | `bass` | | beancount | ✓ | | | | | bibtex | ✓ | | | `texlab` | diff --git a/runtime/queries/bash/indents.scm b/runtime/queries/bash/indents.scm new file mode 100644 index 00000000..f2077037 --- /dev/null +++ b/runtime/queries/bash/indents.scm @@ -0,0 +1,11 @@ +[ + (function_definition) + (if_statement) + (for_statement) + (case_statement) + (pipeline) +] @indent + +[ + "}" +] @outdent From db939801ebf299f11a6a52bdff7a3c9bfb87fc34 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 15 Dec 2022 02:49:49 -0600 Subject: [PATCH 086/132] Improve error message handling for theme loading failures (#5073) The error messages for a theme that failed to be deserialized (or otherwise failed to load) were covered up by the context/with_context calls: * The log message for a bad theme configured in config.toml would only say "Failed to deserilaize theme" * Selecting a bad theme via :theme would show "Theme does not exist" With these changes, we let the TOML deserializer errors bubble up, so the error messages can now say the line number of a duplicated key - and that key's name - when a theme fails to load because of a duplicated key. Providing a theme which does not exist to :theme still gives a helpful error message: "No such file or directory." --- helix-term/src/commands/typed.rs | 2 +- helix-view/src/theme.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 2119a48d..cb387fcb 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -777,7 +777,7 @@ fn theme( .editor .theme_loader .load(theme_name) - .with_context(|| "Theme does not exist")?; + .map_err(|err| anyhow::anyhow!("Could not load theme: {}", err))?; if !(true_color || theme.is_16_color()) { bail!("Unsupported theme: theme requires true color support"); } diff --git a/helix-view/src/theme.rs b/helix-view/src/theme.rs index f1219ec5..b2c8a79f 100644 --- a/helix-view/src/theme.rs +++ b/helix-view/src/theme.rs @@ -136,8 +136,9 @@ impl Loader { // Loads the theme data as `toml::Value` first from the user_dir then in default_dir fn load_toml(&self, path: PathBuf) -> Result { let data = std::fs::read(&path)?; + let value = toml::from_slice(data.as_slice())?; - toml::from_slice(data.as_slice()).context("Failed to deserialize theme") + Ok(value) } // Returns the path to the theme with the name From c64debc7412c0769db8186694bd89f85ea057b1b Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Tue, 19 Jul 2022 21:28:14 +0530 Subject: [PATCH 087/132] Add force_score() for scoring picker items without optimizations --- helix-term/src/ui/picker.rs | 45 +++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 5e9ca3d8..8b5d20ec 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -469,34 +469,41 @@ impl Picker { self.matches.sort_unstable(); } else { - let query = FuzzyQuery::new(pattern); - self.matches.clear(); - self.matches.extend( - self.options - .iter() - .enumerate() - .filter_map(|(index, option)| { - let text = option.filter_text(&self.editor_data); - - query - .fuzzy_match(&text, &self.matcher) - .map(|score| PickerMatch { - index, - score, - len: text.chars().count(), - }) - }), - ); - self.matches.sort_unstable(); + self.force_score(); } log::debug!("picker score {:?}", Instant::now().duration_since(now)); // reset cursor position self.cursor = 0; + let pattern = self.prompt.line(); self.previous_pattern.clone_from(pattern); } + pub fn force_score(&mut self) { + let pattern = self.prompt.line(); + + let query = FuzzyQuery::new(pattern); + self.matches.clear(); + self.matches.extend( + self.options + .iter() + .enumerate() + .filter_map(|(index, option)| { + let text = option.filter_text(&self.editor_data); + + query + .fuzzy_match(&text, &self.matcher) + .map(|score| PickerMatch { + index, + score, + len: text.chars().count(), + }) + }), + ); + self.matches.sort_unstable(); + } + /// Move the cursor by a number of lines, either down (`Forward`) or up (`Backward`) pub fn move_by(&mut self, amount: usize, direction: Direction) { let len = self.matches.len(); From 914d2944997e11cf76eeabfe43f9031aeb2b1721 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Tue, 19 Jul 2022 21:49:02 +0530 Subject: [PATCH 088/132] Add DynamicPicker for updating options on every key --- helix-term/src/ui/mod.rs | 2 +- helix-term/src/ui/overlay.rs | 4 ++ helix-term/src/ui/picker.rs | 74 +++++++++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 107e48dd..5b5924bf 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -19,7 +19,7 @@ pub use completion::Completion; pub use editor::EditorView; pub use markdown::Markdown; pub use menu::Menu; -pub use picker::{FileLocation, FilePicker, Picker}; +pub use picker::{DynamicPicker, FileLocation, FilePicker, Picker}; pub use popup::Popup; pub use prompt::{Prompt, PromptEvent}; pub use spinner::{ProgressSpinners, Spinner}; diff --git a/helix-term/src/ui/overlay.rs b/helix-term/src/ui/overlay.rs index 0b8a93ae..5b2bc806 100644 --- a/helix-term/src/ui/overlay.rs +++ b/helix-term/src/ui/overlay.rs @@ -69,4 +69,8 @@ impl Component for Overlay { let dimensions = (self.calc_child_size)(area); self.content.cursor(dimensions, ctx) } + + fn id(&self) -> Option<&'static str> { + self.content.id() + } } diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 8b5d20ec..821a282c 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -3,6 +3,7 @@ use crate::{ ctrl, key, shift, ui::{self, fuzzy_match::FuzzyQuery, EditorView}, }; +use futures_util::future::BoxFuture; use tui::{ buffer::Buffer as Surface, widgets::{Block, BorderType, Borders}, @@ -22,7 +23,7 @@ use helix_view::{ Document, DocumentId, Editor, }; -use super::menu::Item; +use super::{menu::Item, overlay::Overlay}; pub const MIN_AREA_WIDTH_FOR_PREVIEW: u16 = 72; /// Biggest file size to preview in bytes @@ -751,3 +752,74 @@ impl Component for Picker { self.prompt.cursor(area, editor) } } + +/// Returns a new list of options to replace the contents of the picker +/// when called with the current picker query, +pub type DynQueryCallback = + Box BoxFuture<'static, anyhow::Result>>>; + +/// A picker that updates its contents via a callback whenever the +/// query string changes. Useful for live grep, workspace symbols, etc. +pub struct DynamicPicker { + file_picker: FilePicker, + query_callback: DynQueryCallback, +} + +impl DynamicPicker { + pub const ID: &'static str = "dynamic-picker"; + + pub fn new(file_picker: FilePicker, query_callback: DynQueryCallback) -> Self { + Self { + file_picker, + query_callback, + } + } +} + +impl Component for DynamicPicker { + fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) { + self.file_picker.render(area, surface, cx); + } + + fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult { + let prev_query = self.file_picker.picker.prompt.line().to_owned(); + let event_result = self.file_picker.handle_event(event, cx); + let current_query = self.file_picker.picker.prompt.line(); + + if *current_query == prev_query || matches!(event_result, EventResult::Ignored(_)) { + return event_result; + } + + let new_options = (self.query_callback)(current_query.to_owned(), cx.editor); + + cx.jobs.callback(async move { + let new_options = new_options.await?; + let callback = + crate::job::Callback::EditorCompositor(Box::new(move |_editor, compositor| { + // Wrapping of pickers in overlay is done outside the picker code, + // so this is fragile and will break if wrapped in some other widget. + let picker = match compositor.find_id::>>(Self::ID) { + Some(overlay) => &mut overlay.content.file_picker.picker, + None => return, + }; + picker.options = new_options; + picker.cursor = 0; + picker.force_score(); + })); + anyhow::Ok(callback) + }); + EventResult::Consumed(None) + } + + fn cursor(&self, area: Rect, ctx: &Editor) -> (Option, CursorKind) { + self.file_picker.cursor(area, ctx) + } + + fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> { + self.file_picker.required_size(viewport) + } + + fn id(&self) -> Option<&'static str> { + Some(Self::ID) + } +} From d1f717eb8d02205ce224292f157bfe1bddd1f6db Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Tue, 19 Jul 2022 22:15:03 +0530 Subject: [PATCH 089/132] Re-request workspace symbols on keypress in picker Most language servers limit the number of workspace symbols that are returned with an empty query even though all symbols are supposed to be returned, according to the spec (for perfomance reasons). This patch adds a workspace symbol picker based on a dynamic picker that allows re-requesting the symbols on every keypress (i.e. when the picker query text changes). The old behavior has been completely replaced, and I have only tested with rust-analyzer so far. --- helix-term/src/commands/lsp.rs | 50 ++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index 810e3adf..8052dcac 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -1,3 +1,4 @@ +use futures_util::FutureExt; use helix_lsp::{ block_on, lsp::{self, CodeAction, CodeActionOrCommand, DiagnosticSeverity, NumberOrString}, @@ -14,7 +15,8 @@ use helix_view::{apply_transaction, document::Mode, editor::Action, theme::Style use crate::{ compositor::{self, Compositor}, ui::{ - self, lsp::SignatureHelp, overlay::overlayed, FileLocation, FilePicker, Popup, PromptEvent, + self, lsp::SignatureHelp, overlay::overlayed, DynamicPicker, FileLocation, FilePicker, + Popup, PromptEvent, }, }; @@ -384,10 +386,48 @@ pub fn workspace_symbol_picker(cx: &mut Context) { cx.callback( future, move |_editor, compositor, response: Option>| { - if let Some(symbols) = response { - let picker = sym_picker(symbols, current_url, offset_encoding); - compositor.push(Box::new(overlayed(picker))) - } + let symbols = match response { + Some(s) => s, + None => return, + }; + let picker = sym_picker(symbols, current_url, offset_encoding); + let get_symbols = |query: String, editor: &mut Editor| { + let doc = doc!(editor); + let language_server = match doc.language_server() { + Some(s) => s, + None => { + // This should not generally happen since the picker will not + // even open in the first place if there is no server. + return async move { Err(anyhow::anyhow!("LSP not active")) }.boxed(); + } + }; + let symbol_request = match language_server.workspace_symbols(query) { + Some(future) => future, + None => { + // This should also not happen since the language server must have + // supported workspace symbols before to reach this block. + return async move { + Err(anyhow::anyhow!( + "Language server does not support workspace symbols" + )) + } + .boxed(); + } + }; + + let future = async move { + let json = symbol_request.await?; + let response: Option> = + serde_json::from_value(json)?; + + response.ok_or_else(|| { + anyhow::anyhow!("No response for workspace symbols from language server") + }) + }; + future.boxed() + }; + let dyn_picker = DynamicPicker::new(picker, Box::new(get_symbols)); + compositor.push(Box::new(overlayed(dyn_picker))) }, ) } From a7daa02346789e43af51db2b944b0dc516354a29 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 7 Dec 2022 16:27:31 -0600 Subject: [PATCH 090/132] DynamicPicker: Use idle-timeout as debounce This change uses the idle-timeout event to trigger fetching new results in the DynamicPicker, so idle-timeout becomes a sort of debounce. This prevents querying the language server overly aggressively. --- helix-term/src/ui/picker.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 821a282c..35597843 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -763,6 +763,7 @@ pub type DynQueryCallback = pub struct DynamicPicker { file_picker: FilePicker, query_callback: DynQueryCallback, + query: String, } impl DynamicPicker { @@ -772,6 +773,7 @@ impl DynamicPicker { Self { file_picker, query_callback, + query: String::new(), } } } @@ -782,14 +784,15 @@ impl Component for DynamicPicker { } fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult { - let prev_query = self.file_picker.picker.prompt.line().to_owned(); let event_result = self.file_picker.handle_event(event, cx); let current_query = self.file_picker.picker.prompt.line(); - if *current_query == prev_query || matches!(event_result, EventResult::Ignored(_)) { + if !matches!(event, Event::IdleTimeout) || self.query == *current_query { return event_result; } + self.query.clone_from(current_query); + let new_options = (self.query_callback)(current_query.to_owned(), cx.editor); cx.jobs.callback(async move { From 35cf972ce459eda6ceffb7a7c256a4bc9f4e6e39 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 7 Dec 2022 16:24:32 -0600 Subject: [PATCH 091/132] DynamicPicker: Reset idle timeout on refresh If the new results shown by the picker select a file that hasn't been previewed before, the idle timeout would not trigger highlighting on that file. With this change, we reset the idle timeout and allow that file to be highlighted on the next idle timeout event. --- helix-term/src/ui/picker.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 35597843..2d471aae 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -798,7 +798,7 @@ impl Component for DynamicPicker { cx.jobs.callback(async move { let new_options = new_options.await?; let callback = - crate::job::Callback::EditorCompositor(Box::new(move |_editor, compositor| { + crate::job::Callback::EditorCompositor(Box::new(move |editor, compositor| { // Wrapping of pickers in overlay is done outside the picker code, // so this is fragile and will break if wrapped in some other widget. let picker = match compositor.find_id::>>(Self::ID) { @@ -808,6 +808,7 @@ impl Component for DynamicPicker { picker.options = new_options; picker.cursor = 0; picker.force_score(); + editor.reset_idle_timer(); })); anyhow::Ok(callback) }); From 2a60de74f9ccc935fa65031cfe30c62cf07bbbaf Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 8 Dec 2022 19:54:15 -0600 Subject: [PATCH 092/132] workspace symbols: Default to empty Vec on None A language server might send None as the response to workspace symbols. We should treat this as the empty Vec rather than the server sending an error status. This fixes the interaction with gopls which uses None to mean no matching symbols. --- helix-term/src/commands/lsp.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index 8052dcac..86b0c5fa 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -386,10 +386,7 @@ pub fn workspace_symbol_picker(cx: &mut Context) { cx.callback( future, move |_editor, compositor, response: Option>| { - let symbols = match response { - Some(s) => s, - None => return, - }; + let symbols = response.unwrap_or_default(); let picker = sym_picker(symbols, current_url, offset_encoding); let get_symbols = |query: String, editor: &mut Editor| { let doc = doc!(editor); @@ -420,9 +417,7 @@ pub fn workspace_symbol_picker(cx: &mut Context) { let response: Option> = serde_json::from_value(json)?; - response.ok_or_else(|| { - anyhow::anyhow!("No response for workspace symbols from language server") - }) + Ok(response.unwrap_or_default()) }; future.boxed() }; From 42ad1a9e043e2e0fb148924ff79b9abbe06907ae Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 15 Dec 2022 02:57:31 -0600 Subject: [PATCH 093/132] Select diagnostic range in goto_*_diag commands (#4713) This roughly matches the behavior of the diagnostic picker: when jumping to a diagnostic with `[d`/`]d`/`[D`/`]D`, the range of the diagnostic is selected instead of the start point. --- helix-term/src/commands.rs | 50 +++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 1310417e..0f04ecba 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2789,35 +2789,28 @@ fn exit_select_mode(cx: &mut Context) { } } -fn goto_pos(editor: &mut Editor, pos: usize) { - let (view, doc) = current!(editor); - - push_jump(view, doc); - doc.set_selection(view.id, Selection::point(pos)); - align_view(doc, view, Align::Center); -} - fn goto_first_diag(cx: &mut Context) { - let doc = doc!(cx.editor); - let pos = match doc.diagnostics().first() { - Some(diag) => diag.range.start, + let (view, doc) = current!(cx.editor); + let selection = match doc.diagnostics().first() { + Some(diag) => Selection::single(diag.range.start, diag.range.end), None => return, }; - goto_pos(cx.editor, pos); + doc.set_selection(view.id, selection); + align_view(doc, view, Align::Center); } fn goto_last_diag(cx: &mut Context) { - let doc = doc!(cx.editor); - let pos = match doc.diagnostics().last() { - Some(diag) => diag.range.start, + let (view, doc) = current!(cx.editor); + let selection = match doc.diagnostics().last() { + Some(diag) => Selection::single(diag.range.start, diag.range.end), None => return, }; - goto_pos(cx.editor, pos); + doc.set_selection(view.id, selection); + align_view(doc, view, Align::Center); } fn goto_next_diag(cx: &mut Context) { - let editor = &mut cx.editor; - let (view, doc) = current!(editor); + let (view, doc) = current!(cx.editor); let cursor_pos = doc .selection(view.id) @@ -2830,17 +2823,16 @@ fn goto_next_diag(cx: &mut Context) { .find(|diag| diag.range.start > cursor_pos) .or_else(|| doc.diagnostics().first()); - let pos = match diag { - Some(diag) => diag.range.start, + let selection = match diag { + Some(diag) => Selection::single(diag.range.start, diag.range.end), None => return, }; - - goto_pos(editor, pos); + doc.set_selection(view.id, selection); + align_view(doc, view, Align::Center); } fn goto_prev_diag(cx: &mut Context) { - let editor = &mut cx.editor; - let (view, doc) = current!(editor); + let (view, doc) = current!(cx.editor); let cursor_pos = doc .selection(view.id) @@ -2854,12 +2846,14 @@ fn goto_prev_diag(cx: &mut Context) { .find(|diag| diag.range.start < cursor_pos) .or_else(|| doc.diagnostics().last()); - let pos = match diag { - Some(diag) => diag.range.start, + let selection = match diag { + // NOTE: the selection is reversed because we're jumping to the + // previous diagnostic. + Some(diag) => Selection::single(diag.range.end, diag.range.start), None => return, }; - - goto_pos(editor, pos); + doc.set_selection(view.id, selection); + align_view(doc, view, Align::Center); } fn goto_first_change(cx: &mut Context) { From f916915b53fa6fedd3f9106bcf58163083cc052e Mon Sep 17 00:00:00 2001 From: Roberto Vidal Date: Thu, 15 Dec 2022 09:59:34 +0100 Subject: [PATCH 094/132] add redraw command (#4354) * add redraw command * update docs * Update helix-term/src/commands/typed.rs Co-authored-by: Michael Davis * update docs Co-authored-by: Michael Davis --- book/src/generated/typable-cmd.md | 1 + helix-term/src/commands/typed.rs | 29 +++++++++++++++++++++++++++++ helix-term/src/compositor.rs | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 66e6ac03..269d63e3 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -73,3 +73,4 @@ | `:pipe` | Pipe each selection to the shell command. | | `:pipe-to` | Pipe each selection to the shell command, ignoring output. | | `:run-shell-command`, `:sh` | Run a shell command | +| `:redraw` | Clear and re-render the whole UI | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index cb387fcb..90dde7e1 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1808,6 +1808,28 @@ fn run_shell_command( Ok(()) } +fn redraw( + cx: &mut compositor::Context, + _args: &[Cow], + event: PromptEvent, +) -> anyhow::Result<()> { + if event != PromptEvent::Validate { + return Ok(()); + } + + let callback = Box::pin(async move { + let call: job::Callback = Box::new(|_editor, compositor| { + compositor.clear().expect("unable to redraw"); + }); + + Ok(call) + }); + + cx.jobs.callback(callback); + + Ok(()) +} + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -2323,6 +2345,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: run_shell_command, completer: Some(completers::directory), }, + TypableCommand { + name: "redraw", + aliases: &[], + doc: "Clear and re-render the whole UI", + fun: redraw, + completer: None, + }, ]; pub static TYPABLE_COMMAND_MAP: Lazy> = diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 9dad3620..18620b7b 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -197,6 +197,10 @@ impl Compositor { .find(|component| component.id() == Some(id)) .and_then(|component| component.as_any_mut().downcast_mut()) } + + pub fn clear(&mut self) -> std::io::Result<()> { + self.terminal.clear() + } } // View casting, taken straight from Cursive From 5c4a9cba9a14ca10437e979c884d2ccba78ef1e7 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Thu, 15 Dec 2022 14:20:26 +0100 Subject: [PATCH 095/132] Restore deleted goto_pos function (#5164) --- helix-term/src/commands.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 0f04ecba..6cf49464 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2789,6 +2789,14 @@ fn exit_select_mode(cx: &mut Context) { } } +fn goto_pos(editor: &mut Editor, pos: usize) { + let (view, doc) = current!(editor); + + push_jump(view, doc); + doc.set_selection(view.id, Selection::point(pos)); + align_view(doc, view, Align::Center); +} + fn goto_first_diag(cx: &mut Context) { let (view, doc) = current!(cx.editor); let selection = match doc.diagnostics().first() { From ec9aa6690244bccefac24037c9f7a659816bffdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Thu, 15 Dec 2022 22:23:06 +0900 Subject: [PATCH 096/132] Remove redraw to fix build --- book/src/generated/typable-cmd.md | 1 - helix-term/src/commands/typed.rs | 29 ----------------------------- helix-term/src/compositor.rs | 4 ---- 3 files changed, 34 deletions(-) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 269d63e3..66e6ac03 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -73,4 +73,3 @@ | `:pipe` | Pipe each selection to the shell command. | | `:pipe-to` | Pipe each selection to the shell command, ignoring output. | | `:run-shell-command`, `:sh` | Run a shell command | -| `:redraw` | Clear and re-render the whole UI | diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 90dde7e1..cb387fcb 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1808,28 +1808,6 @@ fn run_shell_command( Ok(()) } -fn redraw( - cx: &mut compositor::Context, - _args: &[Cow], - event: PromptEvent, -) -> anyhow::Result<()> { - if event != PromptEvent::Validate { - return Ok(()); - } - - let callback = Box::pin(async move { - let call: job::Callback = Box::new(|_editor, compositor| { - compositor.clear().expect("unable to redraw"); - }); - - Ok(call) - }); - - cx.jobs.callback(callback); - - Ok(()) -} - pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -2345,13 +2323,6 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ fun: run_shell_command, completer: Some(completers::directory), }, - TypableCommand { - name: "redraw", - aliases: &[], - doc: "Clear and re-render the whole UI", - fun: redraw, - completer: None, - }, ]; pub static TYPABLE_COMMAND_MAP: Lazy> = diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 18620b7b..9dad3620 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -197,10 +197,6 @@ impl Compositor { .find(|component| component.id() == Some(id)) .and_then(|component| component.as_any_mut().downcast_mut()) } - - pub fn clear(&mut self) -> std::io::Result<()> { - self.terminal.clear() - } } // View casting, taken straight from Cursive From 3e6887648c386372839e29028a3459d4674ce68b Mon Sep 17 00:00:00 2001 From: alice Date: Fri, 16 Dec 2022 15:43:58 +0100 Subject: [PATCH 097/132] set 'c++' as a recognised extension for cpp (#5183) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index e28476d3..d03726e7 100644 --- a/languages.toml +++ b/languages.toml @@ -190,7 +190,7 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-c", rev = "7175a6dd name = "cpp" scope = "source.cpp" injection-regex = "cpp" -file-types = ["cc", "hh", "cpp", "hpp", "h", "ipp", "tpp", "cxx", "hxx", "ixx", "txx", "ino"] +file-types = ["cc", "hh", "c++", "cpp", "hpp", "h", "ipp", "tpp", "cxx", "hxx", "ixx", "txx", "ino"] roots = [] comment-token = "//" language-server = { command = "clangd" } From 9c9c775a27f23b2fa5c8c856af0b15671916efd6 Mon Sep 17 00:00:00 2001 From: Ifiok Jr Date: Sat, 17 Dec 2022 15:09:14 +0000 Subject: [PATCH 098/132] Fix a typo in the docs (#5191) --- book/src/keymap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 139e8fdd..15329400 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -317,7 +317,7 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire | `]c` | Go to next comment (**TS**) | `goto_next_comment` | | `[c` | Go to previous comment (**TS**) | `goto_prev_comment` | | `]T` | Go to next test (**TS**) | `goto_next_test` | -| `]T` | Go to previous test (**TS**) | `goto_prev_test` | +| `[T` | Go to previous test (**TS**) | `goto_prev_test` | | `]p` | Go to next paragraph | `goto_next_paragraph` | | `[p` | Go to previous paragraph | `goto_prev_paragraph` | | `]g` | Go to next change | `goto_next_change` | From b12c65678aacc577b070c70307ef6fce528e4d85 Mon Sep 17 00:00:00 2001 From: Eric Thorburn <60004386+hyderix@users.noreply.github.com> Date: Sat, 17 Dec 2022 20:03:18 +0100 Subject: [PATCH 099/132] Print the binary required by the debug adapter (#5195) This commit addresses issue 5193, where the author requested that the name of the binary needed is printed along with the rest of the health information. This commit adds a format! macro which formats in the name of the binary and then it will be printed along with the rest of the debug information. The value in cmd is referenced to the call to which, and then consumed upon the call to format! --- helix-term/src/health.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/health.rs b/helix-term/src/health.rs index e8fbb84d..6558fe19 100644 --- a/helix-term/src/health.rs +++ b/helix-term/src/health.rs @@ -281,9 +281,9 @@ fn probe_protocol(protocol_name: &str, server_cmd: Option) -> std::io::R writeln!(stdout, "Configured {}: {}", protocol_name, cmd_name)?; if let Some(cmd) = server_cmd { - let path = match which::which(cmd) { + let path = match which::which(&cmd) { Ok(path) => path.display().to_string().green(), - Err(_) => "Not found in $PATH".to_string().red(), + Err(_) => format!("'{}' not found in $PATH", cmd).red(), }; writeln!(stdout, "Binary for {}: {}", protocol_name, path)?; } From e6a2df8c798537a7dc5aff264eeccc773525aa6c Mon Sep 17 00:00:00 2001 From: Alex Kladov Date: Sat, 17 Dec 2022 19:30:43 +0000 Subject: [PATCH 100/132] Better sorting in picker in case of ties (#5169) --- helix-term/src/ui/mod.rs | 3 ++- helix-term/src/ui/picker.rs | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 5b5924bf..ade1d8cf 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -207,13 +207,14 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi // Cap the number of files if we aren't in a git project, preventing // hangs when using the picker in your home directory - let files: Vec<_> = if root.join(".git").exists() { + let mut files: Vec = if root.join(".git").exists() { files.collect() } else { // const MAX: usize = 8192; const MAX: usize = 100_000; files.take(MAX).collect() }; + files.sort(); log::debug!("file_picker init {:?}", Instant::now().duration_since(now)); diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 2d471aae..aad3f81c 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -12,7 +12,10 @@ use tui::{ use fuzzy_matcher::skim::SkimMatcherV2 as Matcher; use tui::widgets::Widget; -use std::{cmp::Ordering, time::Instant}; +use std::{ + cmp::{self, Ordering}, + time::Instant, +}; use std::{collections::HashMap, io::Read, path::PathBuf}; use crate::ui::{Prompt, PromptEvent}; @@ -344,11 +347,17 @@ impl Component for FilePicker { #[derive(PartialEq, Eq, Debug)] struct PickerMatch { - index: usize, score: i64, + index: usize, len: usize, } +impl PickerMatch { + fn key(&self) -> impl Ord { + (cmp::Reverse(self.score), self.len, self.index) + } +} + impl PartialOrd for PickerMatch { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) @@ -357,10 +366,7 @@ impl PartialOrd for PickerMatch { impl Ord for PickerMatch { fn cmp(&self, other: &Self) -> Ordering { - self.score - .cmp(&other.score) - .reverse() - .then_with(|| self.len.cmp(&other.len)) + self.key().cmp(&other.key()) } } @@ -502,6 +508,7 @@ impl Picker { }) }), ); + self.matches.sort_unstable(); } From aecb524e503363c2eed2a5a72d8fd881aae18e4b Mon Sep 17 00:00:00 2001 From: Jonas Everaert <62475953+Jomy10@users.noreply.github.com> Date: Sat, 17 Dec 2022 20:34:00 +0100 Subject: [PATCH 101/132] Crystal language support (#4993) --- book/src/generated/lang-support.md | 1 + languages.toml | 12 +++++ runtime/queries/crystal/highlights.scm | 66 ++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 runtime/queries/crystal/highlights.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 1400fa87..73e0bfcd 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -16,6 +16,7 @@ | common-lisp | ✓ | | | `cl-lsp` | | cpon | ✓ | | ✓ | | | cpp | ✓ | ✓ | ✓ | `clangd` | +| crystal | ✓ | | | | | css | ✓ | | | `vscode-css-language-server` | | cue | ✓ | | | `cuelsp` | | d | ✓ | ✓ | ✓ | `serve-d` | diff --git a/languages.toml b/languages.toml index d03726e7..42495e5c 100644 --- a/languages.toml +++ b/languages.toml @@ -223,6 +223,18 @@ args = { console = "internalConsole", attachCommands = [ "platform select remote name = "cpp" source = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev = "d5e90fba898f320db48d81ddedd78d52c67c1fed" } +[[language]] +name = "crystal" +scope = "source.cr" +file-types = ["cr"] +roots = ["shard.yml", "shard.lock"] +comment-token = "#" +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "crystal" +source = { git = "https://github.com/will/tree-sitter-crystal", rev = "15597b307b18028b04d288561f9c29794621562b" } + [[language]] name = "c-sharp" scope = "source.csharp" diff --git a/runtime/queries/crystal/highlights.scm b/runtime/queries/crystal/highlights.scm new file mode 100644 index 00000000..33a53e7f --- /dev/null +++ b/runtime/queries/crystal/highlights.scm @@ -0,0 +1,66 @@ +[ + "class" + "struct" + "module" + + "def" + "alias" + "do" + "end" + + "require" + "include" + "extend" +] @keyword + +[ + "[" "]" + "(" ")" + "{" "}" +] @punctuation.bracket + +(operator) @operator + +(comment) @comment + +; literals + +(nil) @constant.builtin +(bool) @constant.builtin.boolean + +(integer) @constant.numeric.integer +(float) @constant.numeric.float + +[ + (string) + (char) + (commandLiteral) +] @string + +(symbol) @string.special.symbol + +(regex) @string.special.regex + +; variables + +(local_variable) @variable + +[ + (instance_variable) + (class_variable) +] @variable.other.member + +(constant) @constant + +; type defintitions + +(type_identifier) @constructor + +; method definition/call +(identifier) @function.method + +; types +(generic_type) @type +(union_type) @type +(type_identifier) @type + From 042d03269ecbe68e0461548bcf6918324c967bbb Mon Sep 17 00:00:00 2001 From: g-s-k Date: Sat, 17 Dec 2022 20:44:08 +0100 Subject: [PATCH 102/132] Add support for MATLAB/Octave files (#5192) --- book/src/generated/lang-support.md | 1 + languages.toml | 13 ++++ runtime/queries/matlab/highlights.scm | 97 +++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 runtime/queries/matlab/highlights.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 73e0bfcd..1a3aed79 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -78,6 +78,7 @@ | make | ✓ | | | | | markdown | ✓ | | | `marksman` | | markdown.inline | ✓ | | | | +| matlab | ✓ | | | | | mermaid | ✓ | | | | | meson | ✓ | | ✓ | | | mint | | | | `mint` | diff --git a/languages.toml b/languages.toml index 42495e5c..8972a6e9 100644 --- a/languages.toml +++ b/languages.toml @@ -2068,3 +2068,16 @@ indent = { tab-width = 4, unit = " " } [[grammar]] name = "mermaid" source = { git = "https://github.com/monaqa/tree-sitter-mermaid", rev = "d787c66276e7e95899230539f556e8b83ee16f6d" } + +[[language]] +name = "matlab" +scope = "source.m" +file-types = ["m"] +comment-token = "%" +shebangs = ["octave-cli", "matlab"] +roots = [] +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "matlab" +source = { git = "https://github.com/mstanciu552/tree-sitter-matlab", rev = "2d5d3d5193718a86477d4335aba5b34e79147326" } diff --git a/runtime/queries/matlab/highlights.scm b/runtime/queries/matlab/highlights.scm new file mode 100644 index 00000000..c0e23e91 --- /dev/null +++ b/runtime/queries/matlab/highlights.scm @@ -0,0 +1,97 @@ + ; highlights.scm + +function_keyword: (function_keyword) @keyword.function + +(function_definition +function_name: (identifier) @function +(end) @function) + +(parameter_list (identifier) @variable.parameter) + +[ + "if" + "elseif" + "else" + "switch" + "case" + "otherwise" +] @keyword.control.conditional + +(if_statement (end) @keyword.control.conditional) +(switch_statement (end) @keyword.control.conditional) + +["for" "while"] @keyword.control.repeat +(for_statement (end) @keyword.control.repeat) +(while_statement (end) @keyword.control.repeat) + +["try" "catch"] @keyword.control.exception +(try_statement (end) @keyword.control.exception) + +(function_definition end: (end) @keyword) + +["return" "break" "continue"] @keyword.return + +( +(identifier) @constant.builtin +(#any-of? @constant.builtin "true" "false") +) + +( + (identifier) @constant.builtin + (#eq? @constant.builtin "end") +) + +;; Punctuations + +[";" ","] @punctuation.special +(argument_list "," @punctuation.delimiter) +(vector_definition ["," ";"] @punctuation.delimiter) +(cell_definition ["," ";"] @punctuation.delimiter) +":" @punctuation.delimiter +(parameter_list "," @punctuation.delimiter) +(return_value "," @punctuation.delimiter) + +; ;; Brackets + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +;; Operators +"=" @operator +(operation [ ">" + "<" + "==" + "<=" + ">=" + "=<" + "=>" + "~=" + "*" + ".*" + "/" + "\\" + "./" + "^" + ".^" + "+"] @operator) + +;; boolean operator +[ + "&&" + "||" +] @operator + +;; Number +(number) @constant.numeric + +;; String +(string) @string + +;; Comment +(comment) @comment From 24cd7f6adf7a46b8386583b17f01839eb592a2eb Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sat, 10 Dec 2022 09:56:12 +0000 Subject: [PATCH 103/132] Make prompt suggestions greyed out --- book/src/themes.md | 1 + helix-term/src/ui/prompt.rs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/book/src/themes.md b/book/src/themes.md index 322caea5..0f94828e 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -268,6 +268,7 @@ These scopes are used for theming the editor interface. | `ui.help` | Description box for commands | | `ui.text` | Command prompts, popup text, etc. | | `ui.text.focus` | | +| `ui.text.inactive` | Same as `ui.text` but when the text is inactive (e.g. suggestions) | | `ui.text.info` | The key: command text in `ui.popup.info` boxes | | `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section]) | | `ui.virtual.whitespace` | Visible whitespace characters | diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index b19b9a9f..5fb6745a 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -352,6 +352,7 @@ impl Prompt { let prompt_color = theme.get("ui.text"); let completion_color = theme.get("ui.menu"); let selected_color = theme.get("ui.menu.selected"); + let suggestion_color = theme.get("ui.text.inactive"); // completion let max_len = self @@ -450,21 +451,29 @@ impl Prompt { // render buffer text surface.set_string(area.x, area.y + line, &self.prompt, prompt_color); - let input: Cow = if self.line.is_empty() { + let (input, is_suggestion): (Cow, bool) = if self.line.is_empty() { // latest value in the register list - self.history_register + match self + .history_register .and_then(|reg| cx.editor.registers.last(reg)) .map(|entry| entry.into()) - .unwrap_or_else(|| Cow::from("")) + { + Some(value) => (value, true), + None => (Cow::from(""), false), + } } else { - self.line.as_str().into() + (self.line.as_str().into(), false) }; surface.set_string( area.x + self.prompt.len() as u16, area.y + line, &input, - prompt_color, + if is_suggestion { + suggestion_color + } else { + prompt_color + }, ); } } From ba3c24aa0268735ac57321442d458ab6a1ac662c Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sat, 10 Dec 2022 09:56:37 +0000 Subject: [PATCH 104/132] Set ui.text.inactive for official themes --- base16_theme.toml | 1 + theme.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/base16_theme.toml b/base16_theme.toml index 63fc2f79..268a38df 100644 --- a/base16_theme.toml +++ b/base16_theme.toml @@ -7,6 +7,7 @@ "ui.linenr.selected" = { fg = "white", bg = "black", modifiers = ["bold"] } "ui.selection" = { fg = "black", bg = "blue" } "ui.selection.primary" = { fg = "white", bg = "blue" } +"ui.text.inactive" = { fg = "gray" } "comment" = { fg = "gray" } "ui.statusline" = { fg = "black", bg = "white" } "ui.statusline.inactive" = { fg = "gray", bg = "white" } diff --git a/theme.toml b/theme.toml index 05409319..c7b5dc84 100644 --- a/theme.toml +++ b/theme.toml @@ -54,6 +54,7 @@ label = "honey" "ui.text" = { fg = "lavender" } "ui.text.focus" = { fg = "white" } +"ui.text.inactive" = "sirocco" "ui.virtual" = { fg = "comet" } "ui.virtual.indent-guide" = { fg = "comet" } From 99b346a9238b9e7c5b9b93abdf787213c4d67f92 Mon Sep 17 00:00:00 2001 From: Lukas Werling Date: Mon, 19 Dec 2022 18:00:47 +0100 Subject: [PATCH 105/132] tutor: Fix typos in 8.2 (#5213) --- runtime/tutor | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/tutor b/runtime/tutor index 418c4195..885ea0bf 100644 --- a/runtime/tutor +++ b/runtime/tutor @@ -848,13 +848,13 @@ lines. Ensure your cursor is on the '>' of the arrow. 2. Type Q to start recording. 3. Edit the line to look like the bottom one. - 4. Exit insert and Type Q again to stop recording. + 4. Exit insert and type Q again to stop recording. 5. Move to the line below and put your cursor on '>' again. 6. Type q to repeat the macro. - --> ... sentence doesn't have it's first and last ... . - --> ... sentence doesn't have it's first and last ... . - This sentence doesn't have it's first and last word. + --> ... sentence doesn't have its first and last ... . + --> ... sentence doesn't have its first and last ... . + This sentence doesn't have its first and last word. ================================================================= = CHAPTER 8 RECAP = From 45c58961424cca35bcab692b49949d45d917ef7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:16:26 -0600 Subject: [PATCH 106/132] build(deps): bump anyhow from 1.0.66 to 1.0.68 (#5222) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.66 to 1.0.68. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.66...1.0.68) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ae0a71f..52ed478f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "arc-swap" From bcb78c9382af059ccd89dd3c53a1846f2fff1d6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:21:30 -0600 Subject: [PATCH 107/132] build(deps): bump toml from 0.5.9 to 0.5.10 (#5224) Bumps [toml](https://github.com/toml-rs/toml) from 0.5.9 to 0.5.10. - [Release notes](https://github.com/toml-rs/toml/releases) - [Commits](https://github.com/toml-rs/toml/commits/toml-v0.5.10) --- updated-dependencies: - dependency-name: toml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52ed478f..3f4b081c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2142,9 +2142,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" dependencies = [ "serde", ] From 453c7b46993c7ecf2eb8c0549b93085907c6d6c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:21:51 -0600 Subject: [PATCH 108/132] build(deps): bump thiserror from 1.0.37 to 1.0.38 (#5223) Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.37 to 1.0.38. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.37...1.0.38) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f4b081c..7e98a0f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2018,18 +2018,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", From 38fd20c858d166ce9e5b421722b18dc9f7d8810f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:22:27 -0600 Subject: [PATCH 109/132] build(deps): bump indoc from 1.0.7 to 1.0.8 (#5226) Bumps [indoc](https://github.com/dtolnay/indoc) from 1.0.7 to 1.0.8. - [Release notes](https://github.com/dtolnay/indoc/releases) - [Commits](https://github.com/dtolnay/indoc/compare/1.0.7...1.0.8) --- updated-dependencies: - dependency-name: indoc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- helix-term/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e98a0f7..1b4572bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1386,9 +1386,9 @@ dependencies = [ [[package]] name = "indoc" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3" +checksum = "da2d6f23ffea9d7e76c53eee25dfb67bcd8fde7f1198b0855350698c9f07c780" [[package]] name = "instant" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 30bfc7ea..9f2e5188 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -78,5 +78,5 @@ helix-loader = { version = "0.6", path = "../helix-loader" } [dev-dependencies] smallvec = "1.10" -indoc = "1.0.6" +indoc = "1.0.8" tempfile = "3.3.0" From f7a9717088fd00f875f03ff89e7229e64eb7f5fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:24:26 -0600 Subject: [PATCH 110/132] build(deps): bump serde_json from 1.0.89 to 1.0.91 (#5225) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.89 to 1.0.91. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.89...v1.0.91) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b4572bb..e00e1f63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1825,9 +1825,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "itoa", "ryu", From 03baec8a2d83de59d7e8ada655022e4f81d1fa68 Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Tue, 20 Dec 2022 02:36:56 +0300 Subject: [PATCH 111/132] build(nix): update inputs (#5219) --- flake.lock | 70 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index f097519e..4cf1018c 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "crane": { "flake": false, "locked": { - "lastModified": 1661875961, - "narHash": "sha256-f1h/2c6Teeu1ofAHWzrS8TwBPcnN+EEu+z1sRVmMQTk=", + "lastModified": 1670900067, + "narHash": "sha256-VXVa+KBfukhmWizaiGiHRVX/fuk66P8dgSFfkVN4/MY=", "owner": "ipetkov", "repo": "crane", - "rev": "d9f394e4e20e97c2a60c3ad82c2b6ef99be19e24", + "rev": "59b31b41a589c0a65e4a1f86b0e5eac68081468b", "type": "github" }, "original": { @@ -45,6 +45,7 @@ "nci", "devshell" ], + "flake-parts": "flake-parts", "flake-utils-pre-commit": [ "nci" ], @@ -57,6 +58,9 @@ "mach-nix": [ "nci" ], + "nix-pypi-fetcher": [ + "nci" + ], "nixpkgs": [ "nci", "nixpkgs" @@ -69,11 +73,11 @@ ] }, "locked": { - "lastModified": 1668851003, - "narHash": "sha256-X7RCQQynbxStZR2m7HW38r/msMQwVl3afD6UXOCtvx4=", + "lastModified": 1671323629, + "narHash": "sha256-9KHTPjIDjfnzZ4NjpE3gGIVHVHopy6weRDYO/7Y3hF8=", "owner": "nix-community", "repo": "dream2nix", - "rev": "c77e8379d8fe01213ba072e40946cbfb7b58e628", + "rev": "2d7d68505c8619410df2c6b6463985f97cbcba6e", "type": "github" }, "original": { @@ -82,6 +86,24 @@ "type": "github" } }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1668450977, + "narHash": "sha256-cfLhMhnvXn6x1vPm+Jow3RiFAUSCw/l1utktCw5rVA4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "d591857e9d7dd9ddbfba0ea02b43b927c3c0f1fa", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "locked": { "lastModified": 1659877975, @@ -109,11 +131,11 @@ ] }, "locked": { - "lastModified": 1669011203, - "narHash": "sha256-Lymj4HktNEFmVXtwI0Os7srDXHZbZW0Nzw3/+5Hf8ko=", + "lastModified": 1671430291, + "narHash": "sha256-UIc7H8F3N8rK72J/Vj5YJdV72tvDvYjH+UPsOFvlcsE=", "owner": "yusdacra", "repo": "nix-cargo-integration", - "rev": "c5133b91fc1d549087c91228bd213f2518728a4b", + "rev": "b1b0d38b8c3b0d0e6a38638d5bbe10b0bc67522c", "type": "github" }, "original": { @@ -124,11 +146,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1668905981, - "narHash": "sha256-RBQa/+9Uk1eFTqIOXBSBezlEbA3v5OkgP+qptQs1OxY=", + "lastModified": 1671359686, + "narHash": "sha256-3MpC6yZo+Xn9cPordGz2/ii6IJpP2n8LE8e/ebUXLrs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "690ffff026b4e635b46f69002c0f4e81c65dfc2e", + "rev": "04f574a1c0fde90b51bf68198e2297ca4e7cccf4", "type": "github" }, "original": { @@ -138,6 +160,24 @@ "type": "github" } }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1665349835, + "narHash": "sha256-UK4urM3iN80UXQ7EaOappDzcisYIuEURFRoGQ/yPkug=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "34c5293a71ffdb2fe054eb5288adc1882c1eb0b1", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { "nci": "nci", @@ -153,11 +193,11 @@ ] }, "locked": { - "lastModified": 1668998422, - "narHash": "sha256-G/BklIplCHZEeDIabaaxqgITdIXtMolRGlwxn9jG2/Q=", + "lastModified": 1671416426, + "narHash": "sha256-kpSH1Jrxfk2qd0pRPJn1eQdIOseGv5JuE+YaOrqU9s4=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "68ab029c93f8f8eed4cf3ce9a89a9fd4504b2d6e", + "rev": "fbaaff24f375ac25ec64268b0a0d63f91e474b7d", "type": "github" }, "original": { From a7146f58f00b7d15f584c630ca6e123793a0a051 Mon Sep 17 00:00:00 2001 From: farwyler <1705805+farwyler@users.noreply.github.com> Date: Tue, 20 Dec 2022 00:40:08 +0100 Subject: [PATCH 112/132] Add missing comment injection for nix (#5208) --- runtime/queries/nix/injections.scm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/queries/nix/injections.scm b/runtime/queries/nix/injections.scm index 82d79cc7..a1a0ebb8 100644 --- a/runtime/queries/nix/injections.scm +++ b/runtime/queries/nix/injections.scm @@ -1,3 +1,6 @@ +((comment) @injection.content + (#set! injection.language "comment")) + ; mark arbitary languages with a comment ((((comment) @injection.language) . (indented_string_expression (string_fragment) @injection.content)) From bdeefbfb23077fcbbfe1e7df6c6ac88516244bbc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:49:23 -0600 Subject: [PATCH 113/132] build(deps): bump serde from 1.0.150 to 1.0.151 (#5221) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.150 to 1.0.151. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.150...v1.0.151) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e00e1f63..a6ca9495 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1805,18 +1805,18 @@ checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" [[package]] name = "serde" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", From 6ab8591715daf932d0dc45d0d5fb9e5a272f2fe1 Mon Sep 17 00:00:00 2001 From: Chirikumbrah <78883260+Chirikumbrah@users.noreply.github.com> Date: Wed, 21 Dec 2022 02:33:14 +0300 Subject: [PATCH 114/132] Better diagnostics highlighting for Dracula theme. (#5236) --- runtime/themes/dracula.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/themes/dracula.toml b/runtime/themes/dracula.toml index 90bdb446..0f459311 100644 --- a/runtime/themes/dracula.toml +++ b/runtime/themes/dracula.toml @@ -55,6 +55,9 @@ "markup.quote" = { fg = "yellow", modifiers = ["italic"] } "markup.raw" = { fg = "foreground" } +"diagnostic".underline = { color = "orange", style = "curl" } +"diagnostic.error".underline = { color = "red", style = "curl" } + [palette] background = "#282a36" background_dark = "#21222c" From d0a5e11c28a3ad2533b79e2922ca06aa7036516c Mon Sep 17 00:00:00 2001 From: LeoniePhiline <22329650+LeoniePhiline@users.noreply.github.com> Date: Thu, 22 Dec 2022 00:10:12 +0100 Subject: [PATCH 115/132] fix(theme): Replace invalid `cyan` by `blue` in line with original theme (#5250) --- runtime/themes/monokai_pro_spectrum.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/themes/monokai_pro_spectrum.toml b/runtime/themes/monokai_pro_spectrum.toml index 89575e3a..f5787ca8 100644 --- a/runtime/themes/monokai_pro_spectrum.toml +++ b/runtime/themes/monokai_pro_spectrum.toml @@ -53,7 +53,7 @@ "constructor" = "blue" "function" = "green" "function.macro" = { fg = "blue" } -"function.builtin" = { fg = "cyan" } +"function.builtin" = { fg = "blue" } # operator, tags, units, punctuations "operator" = "red" From c4263d6a56c6490b34a43c7d393fce321514b6ef Mon Sep 17 00:00:00 2001 From: Chickenkeeper Date: Wed, 21 Dec 2022 23:10:45 +0000 Subject: [PATCH 116/132] Fix & Tweak Rust's Syntax Highlighting (#5238) --- runtime/queries/rust/highlights.scm | 31 ++++++++--------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/runtime/queries/rust/highlights.scm b/runtime/queries/rust/highlights.scm index d3c29270..66058034 100644 --- a/runtime/queries/rust/highlights.scm +++ b/runtime/queries/rust/highlights.scm @@ -45,7 +45,8 @@ "'" @label (identifier) @label) (loop_label - (identifier) @type) + "'" @label + (identifier) @label) ; --- ; Punctuation @@ -102,8 +103,6 @@ (closure_parameters (identifier) @variable.parameter) - - ; ------- ; Keywords ; ------- @@ -129,9 +128,7 @@ [ "break" "continue" - "return" - "await" ] @keyword.control.return @@ -154,10 +151,7 @@ "trait" "for" - "unsafe" "default" - "macro_rules!" - "async" ] @keyword @@ -165,13 +159,13 @@ "struct" "enum" "union" - "type" ] @keyword.storage.type "let" @keyword.storage - "fn" @keyword.function +"unsafe" @keyword.special +"macro_rules!" @function.macro (mutable_specifier) @keyword.storage.modifier.mut @@ -202,11 +196,11 @@ (call_expression function: [ - ((identifier) @type.variant - (#match? @type.variant "^[A-Z]")) + ((identifier) @type.enum.variant + (#match? @type.enum.variant "^[A-Z]")) (scoped_identifier - name: ((identifier) @type.variant - (#match? @type.variant "^[A-Z]"))) + name: ((identifier) @type.enum.variant + (#match? @type.enum.variant "^[A-Z]"))) ]) ; --- @@ -237,8 +231,6 @@ ((identifier) @type (#match? @type "^[A-Z]")) - - (attribute (identifier) @_macro arguments: (token_tree (identifier) @constant.numeric.integer) @@ -246,7 +238,6 @@ ) @special - ; ------- ; Functions ; ------- @@ -303,8 +294,6 @@ (metavariable) @variable.parameter (fragment_specifier) @type - - ; ------- ; Operators ; ------- @@ -350,8 +339,6 @@ "'" ] @operator - - ; ------- ; Paths ; ------- @@ -382,8 +369,6 @@ (scoped_type_identifier path: (identifier) @namespace) - - ; ------- ; Remaining Identifiers ; ------- From 7905086b55eac2a817c16fe3a9ab987e718324c8 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 22 Dec 2022 19:21:02 -0600 Subject: [PATCH 117/132] Fix HTML injection within markdown (#5265) HTML nodes should be combined injections in the markdown block grammar. When nodes are together the highlighting works properly but when there is markdown content between HTML nodes like in a `
` tag, the highlighting of the closing tag breaks since tree-sitter-html looks for opening and closing tags. --- runtime/queries/markdown/injections.scm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runtime/queries/markdown/injections.scm b/runtime/queries/markdown/injections.scm index e184db15..e8839351 100644 --- a/runtime/queries/markdown/injections.scm +++ b/runtime/queries/markdown/injections.scm @@ -5,7 +5,10 @@ (language) @injection.language) (code_fence_content) @injection.content (#set! injection.include-unnamed-children)) -((html_block) @injection.content (#set! injection.language "html") (#set! injection.include-unnamed-children)) +((html_block) @injection.content + (#set! injection.language "html") + (#set! injection.include-unnamed-children) + (#set! injection.combined)) ((pipe_table_cell) @injection.content (#set! injection.language "markdown.inline") (#set! injection.include-unnamed-children)) From 7a1fa0c74fb2c3b7b1c9aea9aa77c5c612e0bd12 Mon Sep 17 00:00:00 2001 From: Gioele De Vitti Date: Fri, 23 Dec 2022 02:12:49 +0000 Subject: [PATCH 118/132] tutor: Add a content cycling section (#5161) --- runtime/tutor | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/runtime/tutor b/runtime/tutor index 885ea0bf..1fc5605e 100644 --- a/runtime/tutor +++ b/runtime/tutor @@ -985,11 +985,33 @@ lines. --> How much would would a wouldchuck chuck --> if a wouldchuck could chuck would? - Note: Additionally, Alt-( and Alt-) cycle the *contents* of the - selections as well. + + + +================================================================= += 10.2 CYCLING THE CONTENT OF SELECTIONS = +================================================================= + + Type Alt-) and Alt-( to cycle the content of the selections + forward and backward respectively. + + 1. Move the cursor to the line marked '-->' below. + 2. Select both lines with xx or 2x. + 3. Type s to select, type "through|water|know" and enter. + 4. Use Alt-( and Alt-) to cycle the content of the selections. + + --> Jumping through the water, + --> daring to know. + + + + + + + ================================================================= -= 10.2 CHANGING CASE = += 10.3 CHANGING CASE = ================================================================= Type ~ to switch the case of all selected letters. @@ -1011,7 +1033,7 @@ lines. --> THIS sentence should ALL BE IN uppercase! ================================================================= -= 10.3 SPLITTING SELECTIONS = += 10.4 SPLITTING SELECTIONS = ================================================================= Type S to split each selection on a regex pattern. @@ -1039,6 +1061,7 @@ letters! that is not good grammar. you can fix this. * Use ) and ( to cycle the primary selection back and forward through selections respectively. * Type Alt-, to remove the primary selection. + * Type Alt-) and Alt-( to cycle the content of the selections. * Type ~ to alternate case of selected letters. * Use ` and Alt-` to set the case of selected letters to @@ -1053,7 +1076,6 @@ letters! that is not good grammar. you can fix this. - ================================================================= = = ================================================================= From 1b89d3e5350f83b2ffb86a86326bd2714308ee53 Mon Sep 17 00:00:00 2001 From: Jack Allison Date: Thu, 22 Dec 2022 21:23:34 -0500 Subject: [PATCH 119/132] Add file picker dialogue when opening a directory with :o (#2707) --- helix-term/src/commands/typed.rs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index cb387fcb..c3a7c9fa 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -65,12 +65,28 @@ fn open(cx: &mut compositor::Context, args: &[Cow], event: PromptEvent) -> ensure!(!args.is_empty(), "wrong argument count"); for arg in args { let (path, pos) = args::parse_file(arg); - let _ = cx.editor.open(&path, Action::Replace)?; - let (view, doc) = current!(cx.editor); - let pos = Selection::point(pos_at_coords(doc.text().slice(..), pos, true)); - doc.set_selection(view.id, pos); - // does not affect opening a buffer without pos - align_view(doc, view, Align::Center); + // If the path is a directory, open a file picker on that directory and update the status + // message + if std::fs::canonicalize(&path)?.is_dir() { + let callback = async move { + let call: job::Callback = job::Callback::EditorCompositor(Box::new( + move |editor: &mut Editor, compositor: &mut Compositor| { + let picker = ui::file_picker(path, &editor.config()); + compositor.push(Box::new(overlayed(picker))); + }, + )); + Ok(call) + }; + cx.jobs.callback(callback); + } else { + // Otherwise, just open the file + let _ = cx.editor.open(&path, Action::Replace)?; + let (view, doc) = current!(cx.editor); + let pos = Selection::point(pos_at_coords(doc.text().slice(..), pos, true)); + doc.set_selection(view.id, pos); + // does not affect opening a buffer without pos + align_view(doc, view, Align::Center); + } } Ok(()) } From 1107296ca9bfd728258a4571be35eb7c811ff3b3 Mon Sep 17 00:00:00 2001 From: DylanBulfin <31492860+DylanBulfin@users.noreply.github.com> Date: Thu, 22 Dec 2022 21:27:20 -0500 Subject: [PATCH 120/132] Add command to merge consecutive ranges in selection (#5047) --- book/src/keymap.md | 1 + helix-core/src/selection.rs | 95 ++++++++++++++++++++++++++++---- helix-term/src/commands.rs | 7 +++ helix-term/src/keymap/default.rs | 1 + 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 15329400..272c758b 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -111,6 +111,7 @@ | `s` | Select all regex matches inside selections | `select_regex` | | `S` | Split selection into subselections on regex matches | `split_selection` | | `Alt-s` | Split selection on newlines | `split_selection_on_newline` | +| `Alt-_ ` | Merge consecutive selections | `merge_consecutive_selections` | | `&` | Align selection in columns | `align_selections` | | `_` | Trim whitespace from the selection | `trim_selections` | | `;` | Collapse selection onto a single cursor | `collapse_selection` | diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index 1f28ecef..ffba46ab 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -495,28 +495,53 @@ impl Selection { /// Normalizes a `Selection`. fn normalize(mut self) -> Self { - let primary = self.ranges[self.primary_index]; + let mut primary = self.ranges[self.primary_index]; self.ranges.sort_unstable_by_key(Range::from); + + self.ranges.dedup_by(|curr_range, prev_range| { + if prev_range.overlaps(curr_range) { + let new_range = curr_range.merge(*prev_range); + if prev_range == &primary || curr_range == &primary { + primary = new_range; + } + *prev_range = new_range; + true + } else { + false + } + }); + self.primary_index = self .ranges .iter() .position(|&range| range == primary) .unwrap(); - let mut prev_i = 0; - for i in 1..self.ranges.len() { - if self.ranges[prev_i].overlaps(&self.ranges[i]) { - self.ranges[prev_i] = self.ranges[prev_i].merge(self.ranges[i]); + self + } + + // Merges all ranges that are consecutive + pub fn merge_consecutive_ranges(mut self) -> Self { + let mut primary = self.ranges[self.primary_index]; + + self.ranges.dedup_by(|curr_range, prev_range| { + if prev_range.to() == curr_range.from() { + let new_range = curr_range.merge(*prev_range); + if prev_range == &primary || curr_range == &primary { + primary = new_range; + } + *prev_range = new_range; + true } else { - prev_i += 1; - self.ranges[prev_i] = self.ranges[i]; + false } - if i == self.primary_index { - self.primary_index = prev_i; - } - } + }); - self.ranges.truncate(prev_i + 1); + self.primary_index = self + .ranges + .iter() + .position(|&range| range == primary) + .unwrap(); self } @@ -1132,6 +1157,52 @@ mod test { &["", "abcd", "efg", "rs", "xyz"] ); } + + #[test] + fn test_merge_consecutive_ranges() { + let selection = Selection::new( + smallvec![ + Range::new(0, 1), + Range::new(1, 10), + Range::new(15, 20), + Range::new(25, 26), + Range::new(26, 30) + ], + 4, + ); + + let result = selection.merge_consecutive_ranges(); + + assert_eq!( + result.ranges(), + &[Range::new(0, 10), Range::new(15, 20), Range::new(25, 30)] + ); + assert_eq!(result.primary_index, 2); + + let selection = Selection::new(smallvec![Range::new(0, 1)], 0); + let result = selection.merge_consecutive_ranges(); + + assert_eq!(result.ranges(), &[Range::new(0, 1)]); + assert_eq!(result.primary_index, 0); + + let selection = Selection::new( + smallvec![ + Range::new(0, 1), + Range::new(1, 5), + Range::new(5, 8), + Range::new(8, 10), + Range::new(10, 15), + Range::new(18, 25) + ], + 3, + ); + + let result = selection.merge_consecutive_ranges(); + + assert_eq!(result.ranges(), &[Range::new(0, 15), Range::new(18, 25)]); + assert_eq!(result.primary_index, 0); + } + #[test] fn test_selection_contains() { fn contains(a: Vec<(usize, usize)>, b: Vec<(usize, usize)>) -> bool { diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 6cf49464..437e11b5 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -244,6 +244,7 @@ impl MappableCommand { select_regex, "Select all regex matches inside selections", split_selection, "Split selections on regex matches", split_selection_on_newline, "Split selection on newlines", + merge_consecutive_selections, "Merge consecutive selections", search, "Search for regex pattern", rsearch, "Reverse search for regex pattern", search_next, "Select next search match", @@ -1589,6 +1590,12 @@ fn split_selection_on_newline(cx: &mut Context) { doc.set_selection(view.id, selection); } +fn merge_consecutive_selections(cx: &mut Context) { + let (view, doc) = current!(cx.editor); + let selection = doc.selection(view.id).clone().merge_consecutive_ranges(); + doc.set_selection(view.id, selection); +} + #[allow(clippy::too_many_arguments)] fn search_impl( editor: &mut Editor, diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index ebcd125a..ef93dee0 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -76,6 +76,7 @@ pub fn default() -> HashMap { "s" => select_regex, "A-s" => split_selection_on_newline, + "A-_" => merge_consecutive_selections, "S" => split_selection, ";" => collapse_selection, "A-;" => flip_selections, From df1830ef28a7cb49abe31a18e4bd1bcfc7eb802a Mon Sep 17 00:00:00 2001 From: jliaoh <48660001+hunterliao29@users.noreply.github.com> Date: Thu, 22 Dec 2022 21:30:33 -0500 Subject: [PATCH 121/132] mouse operations respect scrolloff (#5255) --- helix-term/src/ui/editor.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index fc201853..35cf77ab 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1155,6 +1155,7 @@ impl EditorView { } editor.focus(view_id); + editor.ensure_cursor_in_view(view_id); return EventResult::Consumed(None); } @@ -1191,7 +1192,8 @@ impl EditorView { let primary = selection.primary_mut(); *primary = primary.put_cursor(doc.text().slice(..), pos, true); doc.set_selection(view.id, selection); - + let view_id = view.id; + cxt.editor.ensure_cursor_in_view(view_id); EventResult::Consumed(None) } @@ -1213,6 +1215,7 @@ impl EditorView { commands::scroll(cxt, offset, direction); cxt.editor.tree.focus = current_view; + cxt.editor.ensure_cursor_in_view(current_view); EventResult::Consumed(None) } From b1ca7ddf89c048a8da0d6cfe507ac3344e6f625f Mon Sep 17 00:00:00 2001 From: cor Date: Fri, 23 Dec 2022 15:03:54 +0100 Subject: [PATCH 122/132] Use curl underlines in the rose_pine theme (#5267) Also fixes the color "gold" being used for too many kinds of diagnostics, now there's a more conventional choice of diagnostics colors (redish = error, yellowish = warning, blueish = hint). --- runtime/themes/rose_pine.toml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/runtime/themes/rose_pine.toml b/runtime/themes/rose_pine.toml index 14e240dd..8558db3a 100644 --- a/runtime/themes/rose_pine.toml +++ b/runtime/themes/rose_pine.toml @@ -1,5 +1,6 @@ # Author: RayGervais # Author: ChrisHa +# Diagnostics patch author: cor "ui.background" = { bg = "base" } "ui.menu" = { fg = "text", bg = "overlay" } @@ -45,12 +46,18 @@ "diff.delta" = "rose" "diff.minus" = "love" -"info" = "gold" -"hint" = "gold" +"info" = "foam" +"hint" = "iris" "debug" = "rose" -"diagnostic" = "rose" +"warning" = "gold" "error" = "love" +"diagnostic" = { modifiers = ["underlined"] } +"diagnostic.error" = { underline = { style = "curl", color = "love" } } +"diagnostic.warning" = { underline = { style = "curl", color = "gold" } } +"diagnostic.info" = { underline = { style = "curl", color = "foam" } } +"diagnostic.hint" = { underline = { style = "curl", color = "iris" } } + "markup.heading.marker" = "subtle" "markup.heading.1" = { fg = "love", modifiers = ["bold"] } "markup.heading.2" = { fg = "gold", modifiers = ["bold"] } From 24c3b00d10858a02c6c1c351a7509e204c2bc647 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 23 Dec 2022 19:43:05 +0530 Subject: [PATCH 123/132] Avoid trailing `s` in message when only 1 file is opened (#5189) --- helix-term/src/application.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 7a50e007..5f013b9a 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -227,7 +227,11 @@ impl Application { doc.set_selection(view_id, pos); } } - editor.set_status(format!("Loaded {} files.", nr_of_files)); + editor.set_status(format!( + "Loaded {} file{}.", + nr_of_files, + if nr_of_files == 1 { "" } else { "s" } // avoid "Loaded 1 files." grammo + )); // align the view to center after all files are loaded, // does not affect views without pos since it is at the top let (view, doc) = current!(editor); From f0c6e6c9eeb1f2772571bcefe02bd344fa70d62f Mon Sep 17 00:00:00 2001 From: Erasin Date: Sat, 24 Dec 2022 19:30:44 +0800 Subject: [PATCH 124/132] fix comment token of godot resource file (#5276) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 8972a6e9..53f65be7 100644 --- a/languages.toml +++ b/languages.toml @@ -1460,7 +1460,7 @@ file-types = ["tscn","tres"] shebangs = [] roots = ["project.godot"] auto-format = false -comment-token = "#" +comment-token = ";" indent = { tab-width = 4, unit = "\t" } [[grammar]] From eb4ec3271005e9de7960a4dd08a9efbb648cb89f Mon Sep 17 00:00:00 2001 From: alois31 <36605164+alois31@users.noreply.github.com> Date: Sat, 24 Dec 2022 14:50:39 +0100 Subject: [PATCH 125/132] Fix opening new files (#5278) Commit 1b89d3e5350f83b2ffb86a86326bd2714308ee53 introduced a regression where opening a new file would no longer work, because attempting to canonicalize its path would lead to a "No such file or directory" error. Fall back to opening a new file when encountering an error to fix this case. --- helix-term/src/commands/typed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index c3a7c9fa..c2ca1a47 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -67,7 +67,7 @@ fn open(cx: &mut compositor::Context, args: &[Cow], event: PromptEvent) -> let (path, pos) = args::parse_file(arg); // If the path is a directory, open a file picker on that directory and update the status // message - if std::fs::canonicalize(&path)?.is_dir() { + if let Ok(true) = std::fs::canonicalize(&path).map(|p| p.is_dir()) { let callback = async move { let call: job::Callback = job::Callback::EditorCompositor(Box::new( move |editor: &mut Editor, compositor: &mut Compositor| { From 1af76b738dd5bdae14b025d07d3001c4ad23e071 Mon Sep 17 00:00:00 2001 From: Alex Kladov Date: Sat, 24 Dec 2022 21:55:16 +0000 Subject: [PATCH 126/132] Add eb word selection trick to the tutor (#5247) --- runtime/tutor | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/runtime/tutor b/runtime/tutor index 1fc5605e..baf32c27 100644 --- a/runtime/tutor +++ b/runtime/tutor @@ -241,7 +241,7 @@ _________________________________________________________________ ================================================================= -= 3.2 MORE ON MOTIONS = += 3.2 MORE MOTIONS = ================================================================= As you saw, typing w moves the cursor forward until the start @@ -253,6 +253,19 @@ _________________________________________________________________ e - Move forward to the end of the current word. b - Move backward to the beginning of the current word. + To select the word under cursor, combine e and b. + + 1. Move the cursor to the line marked '-->' below. + 2. Move to a 'd' letter. + 3. Type e to select a half of the word. + 4. Type b to select the rest. + +--> The Middle Kingdom. + +================================================================= += 3.3 WORDS AND words = +================================================================= + The w,e,b motions also have counterparts - W,E,B - which traverse WORDS instead of words. WORDS are only separated by whitespace, whereas words can be separated by other characters @@ -262,8 +275,17 @@ _________________________________________________________________ + + + + + + + + + ================================================================= -= 3.3 THE CHANGE COMMAND = += 3.4 THE CHANGE COMMAND = ================================================================= Type c to change the current selection. @@ -285,7 +307,7 @@ _________________________________________________________________ ================================================================= -= 3.4 COUNTS WITH MOTIONS = += 3.5 COUNTS WITH MOTIONS = ================================================================= Type a number before a motion to repeat it that many times. @@ -307,7 +329,7 @@ _________________________________________________________________ ================================================================= -= 3.5 SELECT / EXTEND MODE = += 3.6 SELECT / EXTEND MODE = ================================================================= Type v to enter Select mode. @@ -329,7 +351,7 @@ _________________________________________________________________ ================================================================= -= 3.6 SELECTING LINES = += 3.7 SELECTING LINES = ================================================================= Type x to select a whole line. Type x again to select the next. @@ -351,7 +373,7 @@ _________________________________________________________________ subsequent lines. X on an empty line does nothing. ================================================================= -= 3.7 COLLAPSING SELECTIONS = += 3.8 COLLAPSING SELECTIONS = ================================================================= Type ; to collapse selections to single cursors. From a637461677bed1468af5a5d86c57113de3345247 Mon Sep 17 00:00:00 2001 From: "Soc Virnyl S. Estela" Date: Tue, 27 Dec 2022 03:11:42 +0800 Subject: [PATCH 127/132] tutor: add chapter for commenting lines (#5211) --- runtime/tutor | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/runtime/tutor b/runtime/tutor index baf32c27..408f7451 100644 --- a/runtime/tutor +++ b/runtime/tutor @@ -1099,10 +1099,58 @@ letters! that is not good grammar. you can fix this. ================================================================= -= = += 11.1 COMMENTING A LINE = ================================================================= +Type Ctrl-c to comment the line under your cursor. +To uncomment the line, press Ctrl-c again. +1. Move your cursor to the line marked '-->' below. +2. Now comment the line marked with '-->'. +3. Now try uncommenting the line. + +--> Comment me please + + + + + + + + + + +================================================================= += 11.2 COMMENTING MULTIPLE LINES = +================================================================= + +Using the selections and multi-cursor functionality, you can +comment multiple lines as long as it is under the selection or +cursors. + +1. Move your cursor to the line marked with '-->' below. +2. Now try to select or add more cursors the other lines marked + with '-->'. +3. Comment those lines. + +--> How many are you going to comment? +--> Is this enough for a comment? +--> What are you doing?! +--> Stop commenting me! +--> AAAAaargh!!! + +Note: If there are already commented lines under selections or +multiple cursors, they won't be uncommented but commented again. + +================================================================= += CHAPTER 11 RECAP = +================================================================= + + * Use Ctrl-c to comment a line under your cursor. Type Ctrl-c + again to uncomment. + * To comment multiple lines, use the selections + and multi-cursors before typing Ctrl-c. + * Commented lines cannot be uncommented but commented again. From 792c2e3dbf1ae355f5cba829dff25d17d8b8c7d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Dec 2022 17:15:00 -0600 Subject: [PATCH 128/132] build(deps): bump git-repository from 0.29.0 to 0.30.2 (#5306) Bumps [git-repository](https://github.com/Byron/gitoxide) from 0.29.0 to 0.30.2. - [Release notes](https://github.com/Byron/gitoxide/releases) - [Changelog](https://github.com/Byron/gitoxide/blob/main/CHANGELOG.md) - [Commits](https://github.com/Byron/gitoxide/compare/git-repository-v0.29.0...git-repository-v0.30.2) --- updated-dependencies: - dependency-name: git-repository dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 207 +++++++++++++++++++++++-------------------- helix-vcs/Cargo.toml | 2 +- 2 files changed, 112 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6ca9495..1243bc51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] @@ -120,16 +120,6 @@ version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" -[[package]] -name = "byte-unit" -version = "4.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581ad4b3d627b0c09a0ccb2912148f839acaca0b93cf54cbe42b6c674e86079c" -dependencies = [ - "serde", - "utf8-width", -] - [[package]] name = "bytecount" version = "0.6.3" @@ -211,9 +201,9 @@ dependencies = [ [[package]] name = "clru" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "218d6bd3dde8e442a975fa1cd233c0e5fded7596bccfe39f58eca98d22421e0a" +checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" [[package]] name = "codespan-reporting" @@ -280,7 +270,7 @@ dependencies = [ "futures-core", "libc", "mio", - "parking_lot", + "parking_lot 0.12.1", "signal-hook", "signal-hook-mio", "winapi", @@ -349,7 +339,7 @@ dependencies = [ "hashbrown 0.12.3", "lock_api", "once_cell", - "parking_lot_core", + "parking_lot_core 0.9.4", ] [[package]] @@ -551,9 +541,9 @@ dependencies = [ [[package]] name = "git-actor" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9fb99c934ed45a62d9ae1e7b21949f2d869d1b82a07dcbf16ed61daa665870" +checksum = "7def29b46f25f95a2e196323cfb336eae9965e0a3c7c35ad9506f295c3a8e234" dependencies = [ "bstr 1.0.1", "btoi", @@ -565,9 +555,9 @@ dependencies = [ [[package]] name = "git-attributes" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e98446a2bf0eb5c8f29fa828d6529510a6fadeb59ce14ca98e58fa7e1e0199" +checksum = "f0affaed361598fdd06b2a184a566c823d0b5817b09f576018248fb267193a96" dependencies = [ "bstr 1.0.1", "compact_str", @@ -608,9 +598,9 @@ dependencies = [ [[package]] name = "git-config" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd1d13179bcf3dd68e83404f91a8d01c618f54eb97ef36c68ee5e6f30183a681" +checksum = "5ff189268cfb19d5151529ac30b6b708072ebfa1075643d785232675456ec320" dependencies = [ "bstr 1.0.1", "git-config-value", @@ -629,9 +619,9 @@ dependencies = [ [[package]] name = "git-config-value" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64561e9700f1fc737fa3c1c4ea55293be70dba98e45c54cf3715cb180f37a566" +checksum = "989a90c1c630513a153c685b4249b96fdf938afc75bf7ef2ae1ccbd3d799f5db" dependencies = [ "bitflags", "bstr 1.0.1", @@ -642,9 +632,9 @@ dependencies = [ [[package]] name = "git-credentials" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "621dd60288ae7b8f80bb0704f46d4d2b76fc1ec980a7804e48b02d94a927e331" +checksum = "28da3d029be10258007699d002321a3b1ebe45e67b0e140a4cf464ba3ee79b32" dependencies = [ "bstr 1.0.1", "git-command", @@ -658,9 +648,9 @@ dependencies = [ [[package]] name = "git-date" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33db9f4462b565a33507aee113f3383bf16b988d2c573f07691e34302b7aa0a" +checksum = "8a2874ce2f3a77cb144167901ea830969e5c991eac7bfee85e6e3f53ef9fcdf2" dependencies = [ "bstr 1.0.1", "itoa", @@ -670,9 +660,9 @@ dependencies = [ [[package]] name = "git-diff" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82f77407381267be95f1b26acfb32007258af342ee61729bb4271b1869bf5bb2" +checksum = "8f30011a43908645c492dfbea7b004e10528be6bd667bf5cdc12ff4297fe1e3c" dependencies = [ "git-hash", "git-object", @@ -682,9 +672,9 @@ dependencies = [ [[package]] name = "git-discover" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c2cfd1272824b126c6997ef479a71288d00fae14dc5144dfc48658f4dd24fbe" +checksum = "93c244b1cf7cf45501116e948506c25324e33ddc613f00557ff5bfded2132009" dependencies = [ "bstr 1.0.1", "git-hash", @@ -696,9 +686,9 @@ dependencies = [ [[package]] name = "git-features" -version = "0.24.1" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bdbe755d2129bc609437b6b18af1116f146128dda6070c15c0aa50201ac17c" +checksum = "0f98e6ede7b790dfba16bf3c62861ae75c3719485d675b522cf7d7e748a4011c" dependencies = [ "crc32fast", "flate2", @@ -713,9 +703,9 @@ dependencies = [ [[package]] name = "git-glob" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef858611602fce54b51e45671ca72f07fe6a3c0e24a0539c66b75dfd4d84bd77" +checksum = "3908404c9b76ac7b3f636a104142378d3eaa78623cbc6eb7c7f0651979d48e8a" dependencies = [ "bitflags", "bstr 1.0.1", @@ -731,11 +721,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "git-hashtable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c52b625ad8cc360a0b7f426266f21fb07bd49b8f4ccf1b3ca7bc89424db1dec4" +dependencies = [ + "git-hash", + "hashbrown 0.13.1", +] + [[package]] name = "git-index" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a87c32d2e012ee316d4037b2151e5893599379ff1fc2c6adb36d2d4d1c461e2c" +checksum = "20627f71f3a884b0ae50f9f3abb3a07d9b117d06e16110d25b85da4d71d478c0" dependencies = [ "atoi", "bitflags", @@ -766,9 +766,9 @@ dependencies = [ [[package]] name = "git-mailmap" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480eecdfaf1bfd05973678520d182dc07afa25b133db18c52575fb65b782b7ba" +checksum = "f90e3ee2eaeebda8a12d17f4d99dff5b19d81536476020bcebb99ee121820466" dependencies = [ "bstr 1.0.1", "git-actor", @@ -777,9 +777,9 @@ dependencies = [ [[package]] name = "git-object" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce0f14f9cd8f0782e843898a2fb7b0c2f5a6e37bd4cdff4409bb8ec698597dad" +checksum = "35b658f1e3e149d88cb3e0a2234be749bb0cab65887405975dbe6f3190cf6571" dependencies = [ "bstr 1.0.1", "btoi", @@ -796,9 +796,9 @@ dependencies = [ [[package]] name = "git-odb" -version = "0.37.0" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13493da6cf0326454215414d29f933a1e26bdba3b9b60ad8cdcbe06f0639584b" +checksum = "55333419bbb25aa6d39e29155f747ad8e1777fe385f70f447be9d680824d23dd" dependencies = [ "arc-swap", "git-features", @@ -807,16 +807,16 @@ dependencies = [ "git-pack", "git-path", "git-quote", - "parking_lot", + "parking_lot 0.12.1", "tempfile", "thiserror", ] [[package]] name = "git-pack" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8391cbf293f0f8ffbb5e324f25741f5e1e2d35fb87b89ab222a025661e0454" +checksum = "9ed3c9af66949553af9795b9eac9d450a5bdceee9959352cda468997ddce0d2f" dependencies = [ "bytesize", "clru", @@ -825,22 +825,22 @@ dependencies = [ "git-diff", "git-features", "git-hash", + "git-hashtable", "git-object", "git-path", "git-tempfile", "git-traverse", - "hash_hasher", "memmap2", - "parking_lot", + "parking_lot 0.12.1", "smallvec", "thiserror", ] [[package]] name = "git-path" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f60cbc13bc0fdd95df5f4b80437197e2853116792894b1bf38d1a6b4a64f8c9" +checksum = "e40e68481a06da243d3f4dfd86a4be39c24eefb535017a862e845140dcdb878a" dependencies = [ "bstr 1.0.1", "thiserror", @@ -848,14 +848,14 @@ dependencies = [ [[package]] name = "git-prompt" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21c6aaeb3f0f8de91f5e0eb950282c6508e05babcedef768db5a6f085d6e5242" +checksum = "3612a486e507dd431ef0f7108eeaafc8fd1ed7bd0f205a88554f6f91fe5dccbf" dependencies = [ "git-command", "git-config-value", "nix", - "parking_lot", + "parking_lot 0.12.1", "thiserror", ] @@ -872,9 +872,9 @@ dependencies = [ [[package]] name = "git-ref" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22484043921e699edc170415789f1b882c8f3546e1fbbc447a0043ef07e088c4" +checksum = "c97b7d719e4320179fb64d081016e7faca56fed4a8ee4cf84e4697faad9235a3" dependencies = [ "git-actor", "git-features", @@ -891,9 +891,9 @@ dependencies = [ [[package]] name = "git-refspec" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2e8f36e7d5d48903b60051dfb75aedfc4ea9ba66bdffa7a9081e8d276b0107" +checksum = "d478e9db0956d60cd386d3348b5ec093e3ae613105a7a75ff6084b886254eba8" dependencies = [ "bstr 1.0.1", "git-hash", @@ -905,12 +905,10 @@ dependencies = [ [[package]] name = "git-repository" -version = "0.29.0" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89cec253dd3fba44694f7468d907506a52d0055850ecd7d84f4bac07f00e73f" +checksum = "1925a65a9fea6587e969a7a85cb239c8e1e438cf6dc520406df1b4c9d0e83bdc" dependencies = [ - "byte-unit", - "clru", "git-actor", "git-attributes", "git-config", @@ -921,6 +919,7 @@ dependencies = [ "git-features", "git-glob", "git-hash", + "git-hashtable", "git-index", "git-lock", "git-mailmap", @@ -940,6 +939,7 @@ dependencies = [ "git-worktree", "log", "once_cell", + "prodash", "signal-hook", "smallvec", "thiserror", @@ -948,23 +948,23 @@ dependencies = [ [[package]] name = "git-revision" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629289b0d7f7f2f2e46248527f5cac838e6a7cb9507eab06fc8473082db6cb6" +checksum = "f7516b1db551756b4d3176c4b7d18ccc4b79d35dcc5e74f768c90f5bb11bb6c9" dependencies = [ "bstr 1.0.1", "git-date", "git-hash", + "git-hashtable", "git-object", - "hash_hasher", "thiserror", ] [[package]] name = "git-sec" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecb370efde58da72827909292284b5c5b885e0621a342515a36976b0b3bf660" +checksum = "9e1802e8252fa223b0ad89a393aed461132174ced1e6842a41f56dc92a3fc14f" dependencies = [ "bitflags", "dirs", @@ -989,21 +989,21 @@ dependencies = [ [[package]] name = "git-traverse" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2746935c92d252e24f9d345e0a981510596faceb7edae821b9e4c8c35c285b" +checksum = "5e5141dde56d0c4861193c760e01fb61c7e03a32d0840ba93a0ac1c597588d4d" dependencies = [ "git-hash", + "git-hashtable", "git-object", - "hash_hasher", "thiserror", ] [[package]] name = "git-url" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dbd91c55b1b03a833ff8278776fed272918cd61cd48efe9a97ad1fea7ef93ec" +checksum = "8651924c9692a778f09141ca44d1bf2dada229fe9b240f1ff1bdecd9621a1a93" dependencies = [ "bstr 1.0.1", "git-features", @@ -1015,9 +1015,9 @@ dependencies = [ [[package]] name = "git-validate" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf83bae632fc064ca938ebfb987364d9083b7f98b1476805f0a2d5eebb48686" +checksum = "0431cf9352c596dc7c8ec9066ee551ce54e63c86c3c767e5baf763f6019ff3c2" dependencies = [ "bstr 1.0.1", "thiserror", @@ -1025,9 +1025,9 @@ dependencies = [ [[package]] name = "git-worktree" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eae0e0b1050208e611d5fac0d8366b29ef3f83849767ff9c4bcf570f0d5dc2b" +checksum = "17d748c54c3d904c914b987654a1416c7abe7cf048fdc83eeae69e6ac3d76f20" dependencies = [ "bstr 1.0.1", "git-attributes", @@ -1093,12 +1093,6 @@ dependencies = [ "memmap2", ] -[[package]] -name = "hash_hasher" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74721d007512d0cb3338cd20f0654ac913920061a4c4d0d8708edb3f2a698c0c" - [[package]] name = "hashbrown" version = "0.12.3" @@ -1258,7 +1252,7 @@ dependencies = [ "helix-core", "imara-diff", "log", - "parking_lot", + "parking_lot 0.12.1", "tempfile", "tokio", ] @@ -1531,14 +1525,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +checksum = "46a58d1d356c6597d08cde02c2f09d785b09e28711837b1ed667dc652c08a694" dependencies = [ - "autocfg", "bitflags", "cfg-if", "libc", + "static_assertions", ] [[package]] @@ -1595,6 +1589,17 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1602,7 +1607,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.4", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", ] [[package]] @@ -1647,12 +1666,14 @@ dependencies = [ [[package]] name = "prodash" -version = "21.1.0" +version = "22.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e13d7bd38cdab08b3a8b780cedcc54238c84fdca4084eb188807b308bcf11e6" +checksum = "38e2b91fcc982d0d8ae5e9d477561c73e09c24c5c19bac4858e202f6f065a13e" dependencies = [ "bytesize", + "dashmap", "human_format", + "parking_lot 0.11.2", ] [[package]] @@ -2110,7 +2131,7 @@ dependencies = [ "memchr", "mio", "num_cpus", - "parking_lot", + "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", @@ -2235,12 +2256,6 @@ dependencies = [ "serde", ] -[[package]] -name = "utf8-width" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" - [[package]] name = "version_check" version = "0.9.4" diff --git a/helix-vcs/Cargo.toml b/helix-vcs/Cargo.toml index e54cf828..8e713638 100644 --- a/helix-vcs/Cargo.toml +++ b/helix-vcs/Cargo.toml @@ -16,7 +16,7 @@ helix-core = { version = "0.6", path = "../helix-core" } tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] } parking_lot = "0.12" -git-repository = { version = "0.29", default-features = false , optional = true } +git-repository = { version = "0.30", default-features = false , optional = true } imara-diff = "0.1.5" log = "0.4" From eed80ef1c231a27ea76e6cb1b8800b299f56d834 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Dec 2022 17:28:21 -0600 Subject: [PATCH 129/132] build(deps): bump serde from 1.0.151 to 1.0.152 (#5307) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.151 to 1.0.152. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.151...v1.0.152) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1243bc51..3592e621 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1826,18 +1826,18 @@ checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" [[package]] name = "serde" -version = "1.0.151" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.151" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", From ebaf01924dd0e6251535d88ec0a2a00e88680d6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Dec 2022 17:28:40 -0600 Subject: [PATCH 130/132] build(deps): bump cc from 1.0.77 to 1.0.78 (#5308) Bumps [cc](https://github.com/rust-lang/cc-rs) from 1.0.77 to 1.0.78. - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Commits](https://github.com/rust-lang/cc-rs/compare/1.0.77...1.0.78) --- updated-dependencies: - dependency-name: cc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3592e621..96c39fd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cfg-if" From 1f4d277013783c9c537444299ba4e558b9047fe2 Mon Sep 17 00:00:00 2001 From: farwyler <1705805+farwyler@users.noreply.github.com> Date: Tue, 27 Dec 2022 15:57:09 +0100 Subject: [PATCH 131/132] Allow custom preprocessors for 'vue' injections (#5268) --- runtime/queries/vue/injections.scm | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/runtime/queries/vue/injections.scm b/runtime/queries/vue/injections.scm index 73df868b..1b053e74 100644 --- a/runtime/queries/vue/injections.scm +++ b/runtime/queries/vue/injections.scm @@ -8,13 +8,37 @@ (raw_text) @injection.content) (#set! injection.language "javascript")) +;