Merge branch 'master' into force_move

pull/11093/head
5-pebbles 3 months ago
commit 84ff01ed48

280
Cargo.lock generated

@ -136,9 +136,12 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.1.7" version = "1.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6"
dependencies = [
"shlex",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -271,6 +274,7 @@ dependencies = [
"crossterm_winapi", "crossterm_winapi",
"filedescriptor", "filedescriptor",
"futures-core", "futures-core",
"libc",
"mio", "mio",
"parking_lot", "parking_lot",
"rustix", "rustix",
@ -345,15 +349,6 @@ dependencies = [
"parking_lot_core", "parking_lot_core",
] ]
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
]
[[package]] [[package]]
name = "dunce" name = "dunce"
version = "1.0.5" version = "1.0.5"
@ -541,9 +536,9 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
[[package]] [[package]]
name = "gix" name = "gix"
version = "0.64.0" version = "0.66.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78414d29fcc82329080166077e0f7689f4016551fdb334d787c3d040fe2634f" checksum = "9048b8d1ae2104f045cb37e5c450fc49d5d8af22609386bfc739c11ba88995eb"
dependencies = [ dependencies = [
"gix-actor", "gix-actor",
"gix-attributes", "gix-attributes",
@ -563,7 +558,6 @@ dependencies = [
"gix-ignore", "gix-ignore",
"gix-index", "gix-index",
"gix-lock", "gix-lock",
"gix-macros",
"gix-object", "gix-object",
"gix-odb", "gix-odb",
"gix-pack", "gix-pack",
@ -590,9 +584,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-actor" name = "gix-actor"
version = "0.31.5" version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0e454357e34b833cc3a00b6efbbd3dd4d18b24b9fb0c023876ec2645e8aa3f2" checksum = "fc19e312cd45c4a66cd003f909163dc2f8e1623e30a0c0c6df3776e89b308665"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-date", "gix-date",
@ -604,9 +598,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-attributes" name = "gix-attributes"
version = "0.22.3" version = "0.22.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e37ce99c7e81288c28b703641b6d5d119aacc45c1a6b247156e6249afa486257" checksum = "ebccbf25aa4a973dd352564a9000af69edca90623e8a16dad9cbc03713131311"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-glob", "gix-glob",
@ -639,9 +633,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-command" name = "gix-command"
version = "0.3.8" version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d76867867da891cbe32021ad454e8cae90242f6afb06762e4dd0d357afd1d7b" checksum = "dff2e692b36bbcf09286c70803006ca3fd56551a311de450be317a0ab8ea92e7"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-path", "gix-path",
@ -665,9 +659,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-config" name = "gix-config"
version = "0.38.0" version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28f53fd03d1bf09ebcc2c8654f08969439c4556e644ca925f27cf033bc43e658" checksum = "78e797487e6ca3552491de1131b4f72202f282fb33f198b1c34406d765b42bb0"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-config-value", "gix-config-value",
@ -686,9 +680,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-config-value" name = "gix-config-value"
version = "0.14.7" version = "0.14.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b328997d74dd15dc71b2773b162cb4af9a25c424105e4876e6d0686ab41c383e" checksum = "03f76169faa0dec598eac60f83d7fcdd739ec16596eca8fb144c88973dbe6f8c"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"bstr", "bstr",
@ -699,21 +693,21 @@ dependencies = [
[[package]] [[package]]
name = "gix-date" name = "gix-date"
version = "0.8.7" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9eed6931f21491ee0aeb922751bd7ec97b4b2fe8fbfedcb678e2a2dce5f3b8c0" checksum = "35c84b7af01e68daf7a6bb8bb909c1ff5edb3ce4326f1f43063a5a96d3c3c8a5"
dependencies = [ dependencies = [
"bstr", "bstr",
"itoa", "itoa",
"jiff",
"thiserror", "thiserror",
"time",
] ]
[[package]] [[package]]
name = "gix-diff" name = "gix-diff"
version = "0.44.1" version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1996d5c8a305b59709467d80617c9fde48d9d75fd1f4179ea970912630886c9d" checksum = "92c9afd80fff00f8b38b1c1928442feb4cd6d2232a6ed806b6b193151a3d336c"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-command", "gix-command",
@ -731,9 +725,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-dir" name = "gix-dir"
version = "0.6.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c975679aa00dd2d757bfd3ddb232e8a188c0094c3306400575a0813858b1365" checksum = "0ed3a9076661359a1c5a27c12ad6c3ebe2dd96b8b3c0af6488ab7c128b7bdd98"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-discover", "gix-discover",
@ -751,9 +745,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-discover" name = "gix-discover"
version = "0.33.0" version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67662731cec3cb31ba3ed2463809493f76d8e5d6c6d245de8b0560438c13450e" checksum = "0577366b9567376bc26e815fd74451ebd0e6218814e242f8e5b7072c58d956d2"
dependencies = [ dependencies = [
"bstr", "bstr",
"dunce", "dunce",
@ -786,9 +780,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-filter" name = "gix-filter"
version = "0.11.3" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6547738da28275f4dff4e9f3a0f28509f53f94dd6bd822733c91cb306bca61a" checksum = "4121790ae140066e5b953becc72e7496278138d19239be2e63b5067b0843119e"
dependencies = [ dependencies = [
"bstr", "bstr",
"encoding_rs", "encoding_rs",
@ -807,9 +801,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-fs" name = "gix-fs"
version = "0.11.2" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6adf99c27cdf17b1c4d77680c917e0d94d8783d4e1c73d3be0d1d63107163d7a" checksum = "f2bfe6249cfea6d0c0e0990d5226a4cb36f030444ba9e35e0639275db8f98575"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"gix-features", "gix-features",
@ -818,9 +812,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-glob" name = "gix-glob"
version = "0.16.4" version = "0.16.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7df15afa265cc8abe92813cd354d522f1ac06b29ec6dfa163ad320575cb447" checksum = "74908b4bbc0a0a40852737e5d7889f676f081e340d5451a16e5b4c50d592f111"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"bstr", "bstr",
@ -851,9 +845,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-ignore" name = "gix-ignore"
version = "0.11.3" version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6afb8f98e314d4e1adc822449389ada863c174b5707cedd327d67b84dba527" checksum = "e447cd96598460f5906a0f6c75e950a39f98c2705fc755ad2f2020c9e937fab7"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-glob", "gix-glob",
@ -864,9 +858,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-index" name = "gix-index"
version = "0.33.1" version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a9a44eb55bd84bb48f8a44980e951968ced21e171b22d115d1cdcef82a7d73f" checksum = "0cd4203244444017682176e65fd0180be9298e58ed90bd4a8489a357795ed22d"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"bstr", "bstr",
@ -901,22 +895,11 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "gix-macros"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "999ce923619f88194171a67fb3e6d613653b8d4d6078b529b15a765da0edcc17"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]] [[package]]
name = "gix-object" name = "gix-object"
version = "0.42.3" version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25da2f46b4e7c2fa7b413ce4dffb87f69eaf89c2057e386491f4c55cadbfe386" checksum = "2f5b801834f1de7640731820c2df6ba88d95480dc4ab166a5882f8ff12b88efa"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-actor", "gix-actor",
@ -933,9 +916,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-odb" name = "gix-odb"
version = "0.61.1" version = "0.63.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20d384fe541d93d8a3bb7d5d5ef210780d6df4f50c4e684ccba32665a5e3bc9b" checksum = "a3158068701c17df54f0ab2adda527f5a6aca38fd5fd80ceb7e3c0a2717ec747"
dependencies = [ dependencies = [
"arc-swap", "arc-swap",
"gix-date", "gix-date",
@ -953,9 +936,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-pack" name = "gix-pack"
version = "0.51.1" version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0594491fffe55df94ba1c111a6566b7f56b3f8d2e1efc750e77d572f5f5229" checksum = "3223aa342eee21e1e0e403cad8ae9caf9edca55ef84c347738d10681676fd954"
dependencies = [ dependencies = [
"clru", "clru",
"gix-chunk", "gix-chunk",
@ -971,9 +954,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-packetline-blocking" name = "gix-packetline-blocking"
version = "0.17.4" version = "0.17.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31d42378a3d284732e4d589979930d0d253360eccf7ec7a80332e5ccb77e14a" checksum = "b9802304baa798dd6f5ff8008a2b6516d54b74a69ca2d3a2b9e2d6c3b5556b40"
dependencies = [ dependencies = [
"bstr", "bstr",
"faster-hex", "faster-hex",
@ -983,9 +966,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-path" name = "gix-path"
version = "0.10.9" version = "0.10.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9" checksum = "38d5b8722112fa2fa87135298780bc833b0e9f6c56cc82795d209804b3a03484"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-trace", "gix-trace",
@ -996,9 +979,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-pathspec" name = "gix-pathspec"
version = "0.7.6" version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d307d1b8f84dc8386c4aa20ce0cf09242033840e15469a3ecba92f10cfb5c046" checksum = "5d23bf239532b4414d0e63b8ab3a65481881f7237ed9647bb10c1e3cc54c5ceb"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"bstr", "bstr",
@ -1022,9 +1005,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-ref" name = "gix-ref"
version = "0.45.0" version = "0.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "636e96a0a5562715153fee098c217110c33a6f8218f08f4687ff99afde159bb5" checksum = "ae0d8406ebf9aaa91f55a57f053c5a1ad1a39f60fdf0303142b7be7ea44311e5"
dependencies = [ dependencies = [
"gix-actor", "gix-actor",
"gix-features", "gix-features",
@ -1043,9 +1026,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-refspec" name = "gix-refspec"
version = "0.23.1" version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6868f8cd2e62555d1f7c78b784bece43ace40dd2a462daf3b588d5416e603f37" checksum = "ebb005f82341ba67615ffdd9f7742c87787544441c88090878393d0682869ca6"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-hash", "gix-hash",
@ -1057,9 +1040,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-revision" name = "gix-revision"
version = "0.27.2" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01b13e43c2118c4b0537ddac7d0821ae0dfa90b7b8dbf20c711e153fb749adce" checksum = "ba4621b219ac0cdb9256883030c3d56a6c64a6deaa829a92da73b9a576825e1e"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-date", "gix-date",
@ -1071,9 +1054,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-revwalk" name = "gix-revwalk"
version = "0.13.2" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b030ccaab71af141f537e0225f19b9e74f25fefdba0372246b844491cab43e0" checksum = "b41e72544b93084ee682ef3d5b31b1ba4d8fa27a017482900e5e044d5b1b3984"
dependencies = [ dependencies = [
"gix-commitgraph", "gix-commitgraph",
"gix-date", "gix-date",
@ -1086,9 +1069,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-sec" name = "gix-sec"
version = "0.10.7" version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1547d26fa5693a7f34f05b4a3b59a90890972922172653bcb891ab3f09f436df" checksum = "0fe4d52f30a737bbece5276fab5d3a8b276dc2650df963e293d0673be34e7a5f"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"gix-path", "gix-path",
@ -1098,9 +1081,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-status" name = "gix-status"
version = "0.11.0" version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83f7b084cb65c3d007ce6bb479755ca13d602ca3cd91c4f08d7e59904de33736" checksum = "f70d35ba639f0c16a6e4cca81aa374a05f07b23fa36ee8beb72c100d98b4ffea"
dependencies = [ dependencies = [
"bstr", "bstr",
"filetime", "filetime",
@ -1121,9 +1104,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-submodule" name = "gix-submodule"
version = "0.12.0" version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f2e0f69aa00805e39d39ec80472a7e9da20ed5d73318b27925a2cc198e854fd" checksum = "529d0af78cc2f372b3218f15eb1e3d1635a21c8937c12e2dd0b6fc80c2ca874b"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-config", "gix-config",
@ -1156,9 +1139,9 @@ checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e"
[[package]] [[package]]
name = "gix-traverse" name = "gix-traverse"
version = "0.39.2" version = "0.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e499a18c511e71cf4a20413b743b9f5bcf64b3d9e81e9c3c6cd399eae55a8840" checksum = "030da39af94e4df35472e9318228f36530989327906f38e27807df305fccb780"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"gix-commitgraph", "gix-commitgraph",
@ -1173,9 +1156,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-url" name = "gix-url"
version = "0.27.4" version = "0.27.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2eb9b35bba92ea8f0b5ab406fad3cf6b87f7929aa677ff10aa042c6da621156" checksum = "fd280c5e84fb22e128ed2a053a0daeacb6379469be6a85e3d518a0636e160c89"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-features", "gix-features",
@ -1198,9 +1181,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-validate" name = "gix-validate"
version = "0.8.5" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82c27dd34a49b1addf193c92070bcbf3beaf6e10f16a78544de6372e146a0acf" checksum = "81f2badbb64e57b404593ee26b752c26991910fd0d81fe6f9a71c1a8309b6c86"
dependencies = [ dependencies = [
"bstr", "bstr",
"thiserror", "thiserror",
@ -1208,9 +1191,9 @@ dependencies = [
[[package]] [[package]]
name = "gix-worktree" name = "gix-worktree"
version = "0.34.1" version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26f7326ebe0b9172220694ea69d344c536009a9b98fb0f9de092c440f3efe7a6" checksum = "c312ad76a3f2ba8e865b360d5cb3aa04660971d16dec6dd0ce717938d903149a"
dependencies = [ dependencies = [
"bstr", "bstr",
"gix-attributes", "gix-attributes",
@ -1668,6 +1651,31 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "jiff"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ef8bc400f8312944a9f879db116fed372c4f0859af672eba2a80f79c767dd19"
dependencies = [
"jiff-tzdb-platform",
"windows-sys 0.59.0",
]
[[package]]
name = "jiff-tzdb"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05fac328b3df1c0f18a3c2ab6cb7e06e4e549f366017d796e3e66b6d6889abe6"
[[package]]
name = "jiff-tzdb-platform"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8da387d5feaf355954c2c122c194d6df9c57d865125a67984bb453db5336940"
dependencies = [
"jiff-tzdb",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.61" version = "0.3.61"
@ -1688,9 +1696,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.155" version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -1699,7 +1707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"windows-targets 0.48.0", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@ -1800,12 +1808,6 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.15" version = "0.2.15"
@ -1825,15 +1827,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.31.1" version = "0.31.1"
@ -1913,12 +1906,6 @@ version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.76" version = "1.0.76"
@ -1936,9 +1923,9 @@ checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79"
[[package]] [[package]]
name = "pulldown-cmark" name = "pulldown-cmark"
version = "0.11.0" version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0" checksum = "4d31cbfcd94884c3a67ec210c83efb06cb43674043458b0ad59f6947f8462c23"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"memchr", "memchr",
@ -2121,18 +2108,18 @@ checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.204" version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.204" version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2141,9 +2128,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.122" version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@ -2183,6 +2170,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]] [[package]]
name = "signal-hook" name = "signal-hook"
version = "0.3.17" version = "0.3.17"
@ -2312,15 +2305,15 @@ dependencies = [
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.11.0" version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@ -2381,39 +2374,6 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "time"
version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
"libc",
"num-conv",
"num_threads",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -2431,9 +2391,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.39.2" version = "1.39.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
@ -2663,9 +2623,9 @@ checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
[[package]] [[package]]
name = "which" name = "which"
version = "6.0.2" version = "6.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d9c5ed668ee1f17edb3b627225343d210006a90bb1e3745ce1f30b1fb115075" checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f"
dependencies = [ dependencies = [
"either", "either",
"home", "home",

@ -1,6 +1,6 @@
| Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP | | Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| ada | ✓ | ✓ | | `ada_language_server`, `ada_language_server` | | ada | ✓ | ✓ | | `ada_language_server` |
| adl | ✓ | ✓ | ✓ | | | adl | ✓ | ✓ | ✓ | |
| agda | ✓ | | | | | agda | ✓ | | | |
| astro | ✓ | | | | | astro | ✓ | | | |
@ -34,8 +34,8 @@
| devicetree | ✓ | | | | | devicetree | ✓ | | | |
| dhall | ✓ | ✓ | | `dhall-lsp-server` | | dhall | ✓ | ✓ | | `dhall-lsp-server` |
| diff | ✓ | | | | | diff | ✓ | | | |
| docker-compose | ✓ | | ✓ | `docker-compose-langserver`, `yaml-language-server` | | docker-compose | ✓ | | ✓ | `docker-compose-langserver`, `yaml-language-server` |
| dockerfile | ✓ | | | `docker-langserver` | | dockerfile | ✓ | | | `docker-langserver` |
| dot | ✓ | | | `dot-language-server` | | dot | ✓ | | | `dot-language-server` |
| dtd | ✓ | | | | | dtd | ✓ | | | |
| earthfile | ✓ | ✓ | ✓ | `earthlyls` | | earthfile | ✓ | ✓ | ✓ | `earthlyls` |
@ -46,7 +46,7 @@
| elixir | ✓ | ✓ | ✓ | `elixir-ls` | | elixir | ✓ | ✓ | ✓ | `elixir-ls` |
| elm | ✓ | ✓ | | `elm-language-server` | | elm | ✓ | ✓ | | `elm-language-server` |
| elvish | ✓ | | | `elvish` | | elvish | ✓ | | | `elvish` |
| env | ✓ | | | | | env | ✓ | | | |
| erb | ✓ | | | | | erb | ✓ | | | |
| erlang | ✓ | ✓ | | `erlang_ls` | | erlang | ✓ | ✓ | | `erlang_ls` |
| esdl | ✓ | | | | | esdl | ✓ | | | |
@ -58,9 +58,10 @@
| gas | ✓ | ✓ | | | | gas | ✓ | ✓ | | |
| gdscript | ✓ | ✓ | ✓ | | | gdscript | ✓ | ✓ | ✓ | |
| gemini | ✓ | | | | | gemini | ✓ | | | |
| gherkin | ✓ | | | |
| git-attributes | ✓ | | | | | git-attributes | ✓ | | | |
| git-commit | ✓ | ✓ | | | | git-commit | ✓ | ✓ | | |
| git-config | ✓ | | | | | git-config | ✓ | | | |
| git-ignore | ✓ | | | | | git-ignore | ✓ | | | |
| git-rebase | ✓ | | | | | git-rebase | ✓ | | | |
| gjs | ✓ | ✓ | ✓ | `typescript-language-server`, `vscode-eslint-language-server`, `ember-language-server` | | gjs | ✓ | ✓ | ✓ | `typescript-language-server`, `vscode-eslint-language-server`, `ember-language-server` |
@ -82,7 +83,7 @@
| hcl | ✓ | ✓ | ✓ | `terraform-ls` | | hcl | ✓ | ✓ | ✓ | `terraform-ls` |
| heex | ✓ | ✓ | | `elixir-ls` | | heex | ✓ | ✓ | | `elixir-ls` |
| helm | ✓ | | | `helm_ls` | | helm | ✓ | | | `helm_ls` |
| hocon | ✓ | | ✓ | | | hocon | ✓ | | ✓ | |
| hoon | ✓ | | | | | hoon | ✓ | | | |
| hosts | ✓ | | | | | hosts | ✓ | | | |
| html | ✓ | | | `vscode-html-language-server` | | html | ✓ | | | `vscode-html-language-server` |
@ -97,6 +98,7 @@
| javascript | ✓ | ✓ | ✓ | `typescript-language-server` | | javascript | ✓ | ✓ | ✓ | `typescript-language-server` |
| jinja | ✓ | | | | | jinja | ✓ | | | |
| jjdescription | ✓ | | | | | jjdescription | ✓ | | | |
| jq | ✓ | ✓ | | `jq-lsp` |
| jsdoc | ✓ | | | | | jsdoc | ✓ | | | |
| json | ✓ | ✓ | ✓ | `vscode-json-language-server` | | json | ✓ | ✓ | ✓ | `vscode-json-language-server` |
| json5 | ✓ | | | | | json5 | ✓ | | | |
@ -125,7 +127,7 @@
| markdown.inline | ✓ | | | | | markdown.inline | ✓ | | | |
| matlab | ✓ | ✓ | ✓ | | | matlab | ✓ | ✓ | ✓ | |
| mermaid | ✓ | | | | | mermaid | ✓ | | | |
| meson | ✓ | | ✓ | | | meson | ✓ | | ✓ | `mesonlsp` |
| mint | | | | `mint` | | mint | | | | `mint` |
| mojo | ✓ | ✓ | ✓ | `mojo-lsp-server` | | mojo | ✓ | ✓ | ✓ | `mojo-lsp-server` |
| move | ✓ | | | | | move | ✓ | | | |
@ -133,7 +135,7 @@
| nasm | ✓ | ✓ | | | | nasm | ✓ | ✓ | | |
| nickel | ✓ | | ✓ | `nls` | | nickel | ✓ | | ✓ | `nls` |
| nim | ✓ | ✓ | ✓ | `nimlangserver` | | nim | ✓ | ✓ | ✓ | `nimlangserver` |
| nix | ✓ | ✓ | | `nil` | | nix | ✓ | ✓ | | `nil`, `nixd` |
| nu | ✓ | | | `nu` | | nu | ✓ | | | `nu` |
| nunjucks | ✓ | | | | | nunjucks | ✓ | | | |
| ocaml | ✓ | | ✓ | `ocamllsp` | | ocaml | ✓ | | ✓ | `ocamllsp` |
@ -156,7 +158,7 @@
| pod | ✓ | | | | | pod | ✓ | | | |
| ponylang | ✓ | ✓ | ✓ | | | ponylang | ✓ | ✓ | ✓ | |
| powershell | ✓ | | | | | powershell | ✓ | | | |
| prisma | ✓ | | | `prisma-language-server` | | prisma | ✓ | | | `prisma-language-server` |
| prolog | | | | `swipl` | | prolog | | | | `swipl` |
| protobuf | ✓ | ✓ | ✓ | `bufls`, `pb` | | protobuf | ✓ | ✓ | ✓ | `bufls`, `pb` |
| prql | ✓ | | | | | prql | ✓ | | | |
@ -184,7 +186,7 @@
| sml | ✓ | | | | | sml | ✓ | | | |
| solidity | ✓ | ✓ | | `solc` | | solidity | ✓ | ✓ | | `solc` |
| spicedb | ✓ | | | | | spicedb | ✓ | | | |
| sql | ✓ | | | | | sql | ✓ | | | |
| sshclientconfig | ✓ | | | | | sshclientconfig | ✓ | | | |
| starlark | ✓ | ✓ | | | | starlark | ✓ | ✓ | | |
| strace | ✓ | | | | | strace | ✓ | | | |
@ -199,12 +201,14 @@
| tcl | ✓ | | ✓ | | | tcl | ✓ | | ✓ | |
| templ | ✓ | | | `templ` | | templ | ✓ | | | `templ` |
| tfvars | ✓ | | ✓ | `terraform-ls` | | tfvars | ✓ | | ✓ | `terraform-ls` |
| thrift | ✓ | | | |
| todotxt | ✓ | | | | | todotxt | ✓ | | | |
| toml | ✓ | ✓ | | `taplo` | | toml | ✓ | ✓ | | `taplo` |
| tsq | ✓ | | | | | tsq | ✓ | | | |
| tsx | ✓ | ✓ | ✓ | `typescript-language-server` | | tsx | ✓ | ✓ | ✓ | `typescript-language-server` |
| twig | ✓ | | | | | twig | ✓ | | | |
| typescript | ✓ | ✓ | ✓ | `typescript-language-server` | | typescript | ✓ | ✓ | ✓ | `typescript-language-server` |
| typespec | ✓ | ✓ | ✓ | `tsp-server` |
| typst | ✓ | | | `tinymist`, `typst-lsp` | | typst | ✓ | | | `tinymist`, `typst-lsp` |
| ungrammar | ✓ | | | | | ungrammar | ✓ | | | |
| unison | ✓ | | ✓ | | | unison | ✓ | | ✓ | |
@ -224,6 +228,6 @@
| xit | ✓ | | | | | xit | ✓ | | | |
| xml | ✓ | | ✓ | | | xml | ✓ | | ✓ | |
| xtc | ✓ | | | | | xtc | ✓ | | | |
| yaml | ✓ | | ✓ | `yaml-language-server`, `ansible-language-server` | | yaml | ✓ | | ✓ | `yaml-language-server`, `ansible-language-server` |
| yuck | ✓ | | | | | yuck | ✓ | | | |
| zig | ✓ | ✓ | ✓ | `zls` | | zig | ✓ | ✓ | ✓ | `zls` |

@ -14,6 +14,10 @@ Note that:
## Pre-built binaries ## Pre-built binaries
Download pre-built binaries from the [GitHub Releases page](https://github.com/helix-editor/helix/releases). Download pre-built binaries from the [GitHub Releases page](https://github.com/helix-editor/helix/releases).
Add the `hx` binary to your system's `$PATH` to use it from the command line, and copy the `runtime` directory into the config directory (for example `~/.config/helix/runtime` on Linux/macOS). The tarball contents include an `hx` binary and a `runtime` directory.
The runtime location can be overriden via the HELIX_RUNTIME environment variable. To set up Helix:
1. Add the `hx` binary to your system's `$PATH` to allow it to be used from the command line.
2. Copy the `runtime` directory to a location that `hx` searches for runtime files. A typical location on Linux/macOS is `~/.config/helix/runtime`.
To see the runtime directories that `hx` searches, run `hx --health`. If necessary, you can override the default runtime location by setting the `HELIX_RUNTIME` environment variable.

@ -324,6 +324,10 @@ Displays documentation for the selected completion item. Remapping currently not
| ---- | ----------- | | ---- | ----------- |
| `Shift-Tab`, `Ctrl-p`, `Up` | Previous entry | | `Shift-Tab`, `Ctrl-p`, `Up` | Previous entry |
| `Tab`, `Ctrl-n`, `Down` | Next entry | | `Tab`, `Ctrl-n`, `Down` | Next entry |
| `Enter` | Close menu and accept completion |
| `Ctrl-c` | Close menu and reject completion |
Any other keypresses result in the completion being accepted.
##### Signature-help Popup ##### Signature-help Popup

@ -75,5 +75,20 @@ Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes
Keys can be disabled by binding them to the `no_op` command. Keys can be disabled by binding them to the `no_op` command.
A list of commands is available in the [Keymap](https://docs.helix-editor.com/keymap.html) documentation ## Commands
and in the source code at [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs) at the invocation of `static_commands!` macro and the `TypableCommandList`.
There are three kinds of commands that can be used in keymaps:
* Static commands: commands like `move_char_right` which are usually bound to
keys and used for movement and editing. A list of static commands is
available in the [Keymap](./keymap.html) documentation and in the source code
in [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs)
at the invocation of `static_commands!` macro and the `TypableCommandList`.
* Typable commands: commands that can be executed from command mode (`:`), for
example `:write!`. See the [Commands](./commands.html) documentation for a
list of available typeable commands.
* Macros: sequences of keys that are executed in order. These keybindings
start with `@` and then list any number of keys to be executed. For example
`@miw` can be used to select the surrounding word. For now, macro keybindings
are not allowed in keybinding sequences due to limitations in the way that
command sequences are executed.

@ -126,6 +126,7 @@
# disable fetching and building of tree-sitter grammars in the helix-term build.rs # disable fetching and building of tree-sitter grammars in the helix-term build.rs
HELIX_DISABLE_AUTO_GRAMMAR_BUILD = "1"; HELIX_DISABLE_AUTO_GRAMMAR_BUILD = "1";
buildInputs = [stdenv.cc.cc.lib]; buildInputs = [stdenv.cc.cc.lib];
nativeBuildInputs = [pkgs.installShellFiles];
# disable tests # disable tests
doCheck = false; doCheck = false;
meta.mainProgram = "hx"; meta.mainProgram = "hx";
@ -141,6 +142,7 @@
cp contrib/Helix.desktop $out/share/applications cp contrib/Helix.desktop $out/share/applications
cp logo.svg $out/share/icons/hicolor/scalable/apps/helix.svg cp logo.svg $out/share/icons/hicolor/scalable/apps/helix.svg
cp contrib/helix.png $out/share/icons/hicolor/256x256/apps cp contrib/helix.png $out/share/icons/hicolor/256x256/apps
installShellCompletion contrib/completion/hx.{bash,fish,zsh}
''; '';
}); });
helix = makeOverridableHelix self.packages.${system}.helix-unwrapped {}; helix = makeOverridableHelix self.packages.${system}.helix-unwrapped {};

@ -197,13 +197,31 @@ pub fn move_prev_long_word_end(slice: RopeSlice, range: Range, count: usize) ->
word_move(slice, range, count, WordMotionTarget::PrevLongWordEnd) word_move(slice, range, count, WordMotionTarget::PrevLongWordEnd)
} }
pub fn move_next_sub_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {
word_move(slice, range, count, WordMotionTarget::NextSubWordStart)
}
pub fn move_next_sub_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {
word_move(slice, range, count, WordMotionTarget::NextSubWordEnd)
}
pub fn move_prev_sub_word_start(slice: RopeSlice, range: Range, count: usize) -> Range {
word_move(slice, range, count, WordMotionTarget::PrevSubWordStart)
}
pub fn move_prev_sub_word_end(slice: RopeSlice, range: Range, count: usize) -> Range {
word_move(slice, range, count, WordMotionTarget::PrevSubWordEnd)
}
fn word_move(slice: RopeSlice, range: Range, count: usize, target: WordMotionTarget) -> Range { fn word_move(slice: RopeSlice, range: Range, count: usize, target: WordMotionTarget) -> Range {
let is_prev = matches!( let is_prev = matches!(
target, target,
WordMotionTarget::PrevWordStart WordMotionTarget::PrevWordStart
| WordMotionTarget::PrevLongWordStart | WordMotionTarget::PrevLongWordStart
| WordMotionTarget::PrevSubWordStart
| WordMotionTarget::PrevWordEnd | WordMotionTarget::PrevWordEnd
| WordMotionTarget::PrevLongWordEnd | WordMotionTarget::PrevLongWordEnd
| WordMotionTarget::PrevSubWordEnd
); );
// Special-case early-out. // Special-case early-out.
@ -383,6 +401,12 @@ pub enum WordMotionTarget {
NextLongWordEnd, NextLongWordEnd,
PrevLongWordStart, PrevLongWordStart,
PrevLongWordEnd, PrevLongWordEnd,
// A sub word is similar to a regular word, except it is also delimited by
// underscores and transitions from lowercase to uppercase.
NextSubWordStart,
NextSubWordEnd,
PrevSubWordStart,
PrevSubWordEnd,
} }
pub trait CharHelpers { pub trait CharHelpers {
@ -398,8 +422,10 @@ impl CharHelpers for Chars<'_> {
target, target,
WordMotionTarget::PrevWordStart WordMotionTarget::PrevWordStart
| WordMotionTarget::PrevLongWordStart | WordMotionTarget::PrevLongWordStart
| WordMotionTarget::PrevSubWordStart
| WordMotionTarget::PrevWordEnd | WordMotionTarget::PrevWordEnd
| WordMotionTarget::PrevLongWordEnd | WordMotionTarget::PrevLongWordEnd
| WordMotionTarget::PrevSubWordEnd
); );
// Reverse the iterator if needed for the motion direction. // Reverse the iterator if needed for the motion direction.
@ -476,6 +502,25 @@ fn is_long_word_boundary(a: char, b: char) -> bool {
} }
} }
fn is_sub_word_boundary(a: char, b: char, dir: Direction) -> bool {
match (categorize_char(a), categorize_char(b)) {
(CharCategory::Word, CharCategory::Word) => {
if (a == '_') != (b == '_') {
return true;
}
// Subword boundaries are directional: in 'fooBar', there is a
// boundary between 'o' and 'B', but not between 'B' and 'a'.
match dir {
Direction::Forward => a.is_lowercase() && b.is_uppercase(),
Direction::Backward => a.is_uppercase() && b.is_lowercase(),
}
}
(a, b) if a != b => true,
_ => false,
}
}
fn reached_target(target: WordMotionTarget, prev_ch: char, next_ch: char) -> bool { fn reached_target(target: WordMotionTarget, prev_ch: char, next_ch: char) -> bool {
match target { match target {
WordMotionTarget::NextWordStart | WordMotionTarget::PrevWordEnd => { WordMotionTarget::NextWordStart | WordMotionTarget::PrevWordEnd => {
@ -494,6 +539,22 @@ fn reached_target(target: WordMotionTarget, prev_ch: char, next_ch: char) -> boo
is_long_word_boundary(prev_ch, next_ch) is_long_word_boundary(prev_ch, next_ch)
&& (!prev_ch.is_whitespace() || char_is_line_ending(next_ch)) && (!prev_ch.is_whitespace() || char_is_line_ending(next_ch))
} }
WordMotionTarget::NextSubWordStart => {
is_sub_word_boundary(prev_ch, next_ch, Direction::Forward)
&& (char_is_line_ending(next_ch) || !(next_ch.is_whitespace() || next_ch == '_'))
}
WordMotionTarget::PrevSubWordEnd => {
is_sub_word_boundary(prev_ch, next_ch, Direction::Backward)
&& (char_is_line_ending(next_ch) || !(next_ch.is_whitespace() || next_ch == '_'))
}
WordMotionTarget::NextSubWordEnd => {
is_sub_word_boundary(prev_ch, next_ch, Direction::Forward)
&& (!(prev_ch.is_whitespace() || prev_ch == '_') || char_is_line_ending(next_ch))
}
WordMotionTarget::PrevSubWordStart => {
is_sub_word_boundary(prev_ch, next_ch, Direction::Backward)
&& (!(prev_ch.is_whitespace() || prev_ch == '_') || char_is_line_ending(next_ch))
}
} }
} }
@ -1012,6 +1073,178 @@ mod test {
} }
} }
#[test]
fn test_behaviour_when_moving_to_start_of_next_sub_words() {
let tests = [
(
"NextSubwordStart",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 11)),
],
),
(
"next_subword_start",
vec![
(1, Range::new(0, 0), Range::new(0, 5)),
(1, Range::new(4, 4), Range::new(5, 13)),
],
),
(
"Next_Subword_Start",
vec![
(1, Range::new(0, 0), Range::new(0, 5)),
(1, Range::new(4, 4), Range::new(5, 13)),
],
),
(
"NEXT_SUBWORD_START",
vec![
(1, Range::new(0, 0), Range::new(0, 5)),
(1, Range::new(4, 4), Range::new(5, 13)),
],
),
(
"next subword start",
vec![
(1, Range::new(0, 0), Range::new(0, 5)),
(1, Range::new(4, 4), Range::new(5, 13)),
],
),
(
"Next Subword Start",
vec![
(1, Range::new(0, 0), Range::new(0, 5)),
(1, Range::new(4, 4), Range::new(5, 13)),
],
),
(
"NEXT SUBWORD START",
vec![
(1, Range::new(0, 0), Range::new(0, 5)),
(1, Range::new(4, 4), Range::new(5, 13)),
],
),
(
"next__subword__start",
vec![
(1, Range::new(0, 0), Range::new(0, 6)),
(1, Range::new(4, 4), Range::new(4, 6)),
(1, Range::new(5, 5), Range::new(6, 15)),
],
),
(
"Next__Subword__Start",
vec![
(1, Range::new(0, 0), Range::new(0, 6)),
(1, Range::new(4, 4), Range::new(4, 6)),
(1, Range::new(5, 5), Range::new(6, 15)),
],
),
(
"NEXT__SUBWORD__START",
vec![
(1, Range::new(0, 0), Range::new(0, 6)),
(1, Range::new(4, 4), Range::new(4, 6)),
(1, Range::new(5, 5), Range::new(6, 15)),
],
),
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
let range = move_next_sub_word_start(Rope::from(sample).slice(..), begin, count);
assert_eq!(range, expected_end, "Case failed: [{}]", sample);
}
}
}
#[test]
fn test_behaviour_when_moving_to_end_of_next_sub_words() {
let tests = [
(
"NextSubwordEnd",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 11)),
],
),
(
"next subword end",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 12)),
],
),
(
"Next Subword End",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 12)),
],
),
(
"NEXT SUBWORD END",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 12)),
],
),
(
"next_subword_end",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 12)),
],
),
(
"Next_Subword_End",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 12)),
],
),
(
"NEXT_SUBWORD_END",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 12)),
],
),
(
"next__subword__end",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 13)),
(1, Range::new(5, 5), Range::new(5, 13)),
],
),
(
"Next__Subword__End",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 13)),
(1, Range::new(5, 5), Range::new(5, 13)),
],
),
(
"NEXT__SUBWORD__END",
vec![
(1, Range::new(0, 0), Range::new(0, 4)),
(1, Range::new(4, 4), Range::new(4, 13)),
(1, Range::new(5, 5), Range::new(5, 13)),
],
),
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
let range = move_next_sub_word_end(Rope::from(sample).slice(..), begin, count);
assert_eq!(range, expected_end, "Case failed: [{}]", sample);
}
}
}
#[test] #[test]
fn test_behaviour_when_moving_to_start_of_next_long_words() { fn test_behaviour_when_moving_to_start_of_next_long_words() {
let tests = [ let tests = [
@ -1181,6 +1414,92 @@ mod test {
} }
} }
#[test]
fn test_behaviour_when_moving_to_start_of_previous_sub_words() {
let tests = [
(
"PrevSubwordEnd",
vec![
(1, Range::new(13, 13), Range::new(14, 11)),
(1, Range::new(11, 11), Range::new(11, 4)),
],
),
(
"prev subword end",
vec![
(1, Range::new(15, 15), Range::new(16, 13)),
(1, Range::new(12, 12), Range::new(13, 5)),
],
),
(
"Prev Subword End",
vec![
(1, Range::new(15, 15), Range::new(16, 13)),
(1, Range::new(12, 12), Range::new(13, 5)),
],
),
(
"PREV SUBWORD END",
vec![
(1, Range::new(15, 15), Range::new(16, 13)),
(1, Range::new(12, 12), Range::new(13, 5)),
],
),
(
"prev_subword_end",
vec![
(1, Range::new(15, 15), Range::new(16, 13)),
(1, Range::new(12, 12), Range::new(13, 5)),
],
),
(
"Prev_Subword_End",
vec![
(1, Range::new(15, 15), Range::new(16, 13)),
(1, Range::new(12, 12), Range::new(13, 5)),
],
),
(
"PREV_SUBWORD_END",
vec![
(1, Range::new(15, 15), Range::new(16, 13)),
(1, Range::new(12, 12), Range::new(13, 5)),
],
),
(
"prev__subword__end",
vec![
(1, Range::new(17, 17), Range::new(18, 15)),
(1, Range::new(13, 13), Range::new(14, 6)),
(1, Range::new(14, 14), Range::new(15, 6)),
],
),
(
"Prev__Subword__End",
vec![
(1, Range::new(17, 17), Range::new(18, 15)),
(1, Range::new(13, 13), Range::new(14, 6)),
(1, Range::new(14, 14), Range::new(15, 6)),
],
),
(
"PREV__SUBWORD__END",
vec![
(1, Range::new(17, 17), Range::new(18, 15)),
(1, Range::new(13, 13), Range::new(14, 6)),
(1, Range::new(14, 14), Range::new(15, 6)),
],
),
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
let range = move_prev_sub_word_start(Rope::from(sample).slice(..), begin, count);
assert_eq!(range, expected_end, "Case failed: [{}]", sample);
}
}
}
#[test] #[test]
fn test_behaviour_when_moving_to_start_of_previous_long_words() { fn test_behaviour_when_moving_to_start_of_previous_long_words() {
let tests = [ let tests = [
@ -1444,6 +1763,92 @@ mod test {
} }
} }
#[test]
fn test_behaviour_when_moving_to_end_of_previous_sub_words() {
let tests = [
(
"PrevSubwordEnd",
vec![
(1, Range::new(13, 13), Range::new(14, 11)),
(1, Range::new(11, 11), Range::new(11, 4)),
],
),
(
"prev subword end",
vec![
(1, Range::new(15, 15), Range::new(16, 12)),
(1, Range::new(12, 12), Range::new(12, 4)),
],
),
(
"Prev Subword End",
vec![
(1, Range::new(15, 15), Range::new(16, 12)),
(1, Range::new(12, 12), Range::new(12, 4)),
],
),
(
"PREV SUBWORD END",
vec![
(1, Range::new(15, 15), Range::new(16, 12)),
(1, Range::new(12, 12), Range::new(12, 4)),
],
),
(
"prev_subword_end",
vec![
(1, Range::new(15, 15), Range::new(16, 12)),
(1, Range::new(12, 12), Range::new(12, 4)),
],
),
(
"Prev_Subword_End",
vec![
(1, Range::new(15, 15), Range::new(16, 12)),
(1, Range::new(12, 12), Range::new(12, 4)),
],
),
(
"PREV_SUBWORD_END",
vec![
(1, Range::new(15, 15), Range::new(16, 12)),
(1, Range::new(12, 12), Range::new(12, 4)),
],
),
(
"prev__subword__end",
vec![
(1, Range::new(17, 17), Range::new(18, 13)),
(1, Range::new(13, 13), Range::new(13, 4)),
(1, Range::new(14, 14), Range::new(15, 13)),
],
),
(
"Prev__Subword__End",
vec![
(1, Range::new(17, 17), Range::new(18, 13)),
(1, Range::new(13, 13), Range::new(13, 4)),
(1, Range::new(14, 14), Range::new(15, 13)),
],
),
(
"PREV__SUBWORD__END",
vec![
(1, Range::new(17, 17), Range::new(18, 13)),
(1, Range::new(13, 13), Range::new(13, 4)),
(1, Range::new(14, 14), Range::new(15, 13)),
],
),
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
let range = move_prev_sub_word_end(Rope::from(sample).slice(..), begin, count);
assert_eq!(range, expected_end, "Case failed: [{}]", sample);
}
}
}
#[test] #[test]
fn test_behaviour_when_moving_to_end_of_next_long_words() { fn test_behaviour_when_moving_to_end_of_next_long_words() {
let tests = [ let tests = [

@ -184,16 +184,16 @@ impl Range {
let positions_to_map = match self.anchor.cmp(&self.head) { let positions_to_map = match self.anchor.cmp(&self.head) {
Ordering::Equal => [ Ordering::Equal => [
(&mut self.anchor, Assoc::After), (&mut self.anchor, Assoc::AfterSticky),
(&mut self.head, Assoc::After), (&mut self.head, Assoc::AfterSticky),
], ],
Ordering::Less => [ Ordering::Less => [
(&mut self.anchor, Assoc::After), (&mut self.anchor, Assoc::AfterSticky),
(&mut self.head, Assoc::Before), (&mut self.head, Assoc::BeforeSticky),
], ],
Ordering::Greater => [ Ordering::Greater => [
(&mut self.head, Assoc::After), (&mut self.head, Assoc::AfterSticky),
(&mut self.anchor, Assoc::Before), (&mut self.anchor, Assoc::BeforeSticky),
], ],
}; };
changes.update_positions(positions_to_map.into_iter()); changes.update_positions(positions_to_map.into_iter());
@ -482,16 +482,16 @@ impl Selection {
range.old_visual_position = None; range.old_visual_position = None;
match range.anchor.cmp(&range.head) { match range.anchor.cmp(&range.head) {
Ordering::Equal => [ Ordering::Equal => [
(&mut range.anchor, Assoc::After), (&mut range.anchor, Assoc::AfterSticky),
(&mut range.head, Assoc::After), (&mut range.head, Assoc::AfterSticky),
], ],
Ordering::Less => [ Ordering::Less => [
(&mut range.anchor, Assoc::After), (&mut range.anchor, Assoc::AfterSticky),
(&mut range.head, Assoc::Before), (&mut range.head, Assoc::BeforeSticky),
], ],
Ordering::Greater => [ Ordering::Greater => [
(&mut range.head, Assoc::After), (&mut range.head, Assoc::AfterSticky),
(&mut range.anchor, Assoc::Before), (&mut range.anchor, Assoc::BeforeSticky),
], ],
} }
}); });

@ -29,6 +29,12 @@ pub enum Assoc {
/// Acts like `Before` if a word character is inserted /// Acts like `Before` if a word character is inserted
/// before the position, otherwise acts like `After` /// before the position, otherwise acts like `After`
BeforeWord, BeforeWord,
/// Acts like `Before` but if the position is within an exact replacement
/// (exact size) the offset to the start of the replacement is kept
BeforeSticky,
/// Acts like `After` but if the position is within an exact replacement
/// (exact size) the offset to the start of the replacement is kept
AfterSticky,
} }
impl Assoc { impl Assoc {
@ -40,13 +46,17 @@ impl Assoc {
fn insert_offset(self, s: &str) -> usize { fn insert_offset(self, s: &str) -> usize {
let chars = s.chars().count(); let chars = s.chars().count();
match self { match self {
Assoc::After => chars, Assoc::After | Assoc::AfterSticky => chars,
Assoc::AfterWord => s.chars().take_while(|&c| char_is_word(c)).count(), Assoc::AfterWord => s.chars().take_while(|&c| char_is_word(c)).count(),
// return position before inserted text // return position before inserted text
Assoc::Before => 0, Assoc::Before | Assoc::BeforeSticky => 0,
Assoc::BeforeWord => chars - s.chars().rev().take_while(|&c| char_is_word(c)).count(), Assoc::BeforeWord => chars - s.chars().rev().take_while(|&c| char_is_word(c)).count(),
} }
} }
pub fn sticky(self) -> bool {
matches!(self, Assoc::BeforeSticky | Assoc::AfterSticky)
}
} }
#[derive(Debug, Default, Clone, PartialEq, Eq)] #[derive(Debug, Default, Clone, PartialEq, Eq)]
@ -456,9 +466,15 @@ impl ChangeSet {
if pos == old_pos && assoc.stay_at_gaps() { if pos == old_pos && assoc.stay_at_gaps() {
new_pos new_pos
} else { } else {
// place to end of insert let ins = assoc.insert_offset(s);
// if the deleted and inserted text have the exact same size
// keep the relative offset into the new text
if *len == ins && assoc.sticky() {
new_pos + (pos - old_pos)
} else {
new_pos + assoc.insert_offset(s) new_pos + assoc.insert_offset(s)
} }
}
}), }),
i i
); );

@ -30,7 +30,7 @@ log = "0.4"
# cloning/compiling tree-sitter grammars # cloning/compiling tree-sitter grammars
cc = { version = "1" } cc = { version = "1" }
threadpool = { version = "1.0" } threadpool = { version = "1.0" }
tempfile = "3.11.0" tempfile = "3.12.0"
dunce = "1.0.5" dunce = "1.0.5"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]

@ -225,13 +225,16 @@ pub fn merge_toml_values(left: toml::Value, right: toml::Value, merge_depth: usi
/// Used as a ceiling dir for LSP root resolution, the filepicker and potentially as a future filewatching root /// Used as a ceiling dir for LSP root resolution, the filepicker and potentially as a future filewatching root
/// ///
/// This function starts searching the FS upward from the CWD /// This function starts searching the FS upward from the CWD
/// and returns the first directory that contains either `.git` or `.helix`. /// and returns the first directory that contains either `.git`, `.svn` or `.helix`.
/// If no workspace was found returns (CWD, true). /// If no workspace was found returns (CWD, true).
/// Otherwise (workspace, false) is returned /// Otherwise (workspace, false) is returned
pub fn find_workspace() -> (PathBuf, bool) { pub fn find_workspace() -> (PathBuf, bool) {
let current_dir = current_working_dir(); let current_dir = current_working_dir();
for ancestor in current_dir.ancestors() { for ancestor in current_dir.ancestors() {
if ancestor.join(".git").exists() || ancestor.join(".helix").exists() { if ancestor.join(".git").exists()
|| ancestor.join(".svn").exists()
|| ancestor.join(".helix").exists()
{
return (ancestor.to_owned(), false); return (ancestor.to_owned(), false);
} }
} }

@ -22,8 +22,8 @@ license = "MIT"
[dependencies] [dependencies]
bitflags = "2.6.0" bitflags = "2.6.0"
serde = { version = "1.0.34", features = ["derive"] } serde = { version = "1.0.209", features = ["derive"] }
serde_json = "1.0.122" serde_json = "1.0.127"
serde_repr = "0.1" serde_repr = "0.1"
url = {version = "2.0.0", features = ["serde"]} url = {version = "2.0.0", features = ["serde"]}

@ -20,10 +20,10 @@ regex-cursor = "0.1.4"
bitflags = "2.6" bitflags = "2.6"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.59", features = ["Win32_Security", "Win32_Security_Authorization", "Win32_System_Threading"] } windows-sys = { version = "0.59", features = ["Win32_Foundation", "Win32_Security", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Threading"] }
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
rustix = { version = "0.38", features = ["fs"] } rustix = { version = "0.38", features = ["fs"] }
[dev-dependencies] [dev-dependencies]
tempfile = "3.11" tempfile = "3.12"

@ -85,7 +85,7 @@ mod imp {
#[cfg(windows)] #[cfg(windows)]
mod imp { mod imp {
use windows_sys::Win32::Foundation::{CloseHandle, LocalFree, ERROR_SUCCESS, HANDLE, PSID}; use windows_sys::Win32::Foundation::{CloseHandle, LocalFree, ERROR_SUCCESS, HANDLE};
use windows_sys::Win32::Security::Authorization::{ use windows_sys::Win32::Security::Authorization::{
GetNamedSecurityInfoW, SetNamedSecurityInfoW, SE_FILE_OBJECT, GetNamedSecurityInfoW, SetNamedSecurityInfoW, SE_FILE_OBJECT,
}; };
@ -95,7 +95,7 @@ mod imp {
SecurityImpersonation, ACCESS_ALLOWED_CALLBACK_ACE, ACL, ACL_SIZE_INFORMATION, SecurityImpersonation, ACCESS_ALLOWED_CALLBACK_ACE, ACL, ACL_SIZE_INFORMATION,
DACL_SECURITY_INFORMATION, GENERIC_MAPPING, GROUP_SECURITY_INFORMATION, INHERITED_ACE, DACL_SECURITY_INFORMATION, GENERIC_MAPPING, GROUP_SECURITY_INFORMATION, INHERITED_ACE,
LABEL_SECURITY_INFORMATION, OBJECT_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION, LABEL_SECURITY_INFORMATION, OBJECT_SECURITY_INFORMATION, OWNER_SECURITY_INFORMATION,
PRIVILEGE_SET, PROTECTED_DACL_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PRIVILEGE_SET, PROTECTED_DACL_SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PSID,
SID_IDENTIFIER_AUTHORITY, TOKEN_DUPLICATE, TOKEN_QUERY, SID_IDENTIFIER_AUTHORITY, TOKEN_DUPLICATE, TOKEN_QUERY,
}; };
use windows_sys::Win32::Storage::FileSystem::{ use windows_sys::Win32::Storage::FileSystem::{
@ -419,7 +419,7 @@ mod imp {
pub fn hardlink_count(p: &Path) -> std::io::Result<u64> { pub fn hardlink_count(p: &Path) -> std::io::Result<u64> {
let file = std::fs::File::open(p)?; let file = std::fs::File::open(p)?;
let handle = file.as_raw_handle() as isize; let handle = file.as_raw_handle();
let mut info: BY_HANDLE_FILE_INFORMATION = unsafe { std::mem::zeroed() }; let mut info: BY_HANDLE_FILE_INFORMATION = unsafe { std::mem::zeroed() };
if unsafe { GetFileInformationByHandle(handle, &mut info) } == 0 { if unsafe { GetFileInformationByHandle(handle, &mut info) } == 0 {

@ -53,7 +53,7 @@ log = "0.4"
nucleo.workspace = true nucleo.workspace = true
ignore = "0.4" ignore = "0.4"
# markdown doc rendering # markdown doc rendering
pulldown-cmark = { version = "0.11", default-features = false } pulldown-cmark = { version = "0.12", default-features = false }
# file type detection # file type detection
content_inspector = "0.2.4" content_inspector = "0.2.4"
thiserror = "1.0" thiserror = "1.0"
@ -74,10 +74,10 @@ grep-searcher = "0.1.13"
[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 [target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
libc = "0.2.155" libc = "0.2.158"
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty"] } crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty", "libc"] }
[build-dependencies] [build-dependencies]
helix-loader = { path = "../helix-loader" } helix-loader = { path = "../helix-loader" }
@ -85,5 +85,5 @@ helix-loader = { path = "../helix-loader" }
[dev-dependencies] [dev-dependencies]
smallvec = "1.13" smallvec = "1.13"
indoc = "2.0.5" indoc = "2.0.5"
tempfile = "3.11.0" tempfile = "3.12.0"
same-file = "1.0.1" same-file = "1.0.1"

@ -176,9 +176,16 @@ where
use helix_view::{align_view, Align}; use helix_view::{align_view, Align};
/// A MappableCommand is either a static command like "jump_view_up" or a Typable command like /// MappableCommands are commands that can be bound to keys, executable in
/// :format. It causes a side-effect on the state (usually by creating and applying a transaction). /// normal, insert or select mode.
/// Both of these types of commands can be mapped with keybindings in the config.toml. ///
/// There are three kinds:
///
/// * Static: commands usually bound to keys and used for editing, movement,
/// etc., for example `move_char_left`.
/// * Typable: commands executable from command mode, prefixed with a `:`,
/// for example `:write!`.
/// * Macro: a sequence of keys to execute, for example `@miw`.
#[derive(Clone)] #[derive(Clone)]
pub enum MappableCommand { pub enum MappableCommand {
Typable { Typable {
@ -191,6 +198,10 @@ pub enum MappableCommand {
fun: fn(cx: &mut Context), fun: fn(cx: &mut Context),
doc: &'static str, doc: &'static str,
}, },
Macro {
name: String,
keys: Vec<KeyEvent>,
},
} }
macro_rules! static_commands { macro_rules! static_commands {
@ -227,6 +238,23 @@ impl MappableCommand {
} }
} }
Self::Static { fun, .. } => (fun)(cx), Self::Static { fun, .. } => (fun)(cx),
Self::Macro { keys, .. } => {
// Protect against recursive macros.
if cx.editor.macro_replaying.contains(&'@') {
cx.editor.set_error(
"Cannot execute macro because the [@] register is already playing a macro",
);
return;
}
cx.editor.macro_replaying.push('@');
let keys = keys.clone();
cx.callback.push(Box::new(move |compositor, cx| {
for key in keys.into_iter() {
compositor.handle_event(&compositor::Event::Key(key), cx);
}
cx.editor.macro_replaying.pop();
}));
}
} }
} }
@ -234,6 +262,7 @@ impl MappableCommand {
match &self { match &self {
Self::Typable { name, .. } => name, Self::Typable { name, .. } => name,
Self::Static { name, .. } => name, Self::Static { name, .. } => name,
Self::Macro { name, .. } => name,
} }
} }
@ -241,6 +270,7 @@ impl MappableCommand {
match &self { match &self {
Self::Typable { doc, .. } => doc, Self::Typable { doc, .. } => doc,
Self::Static { doc, .. } => doc, Self::Static { doc, .. } => doc,
Self::Macro { name, .. } => name,
} }
} }
@ -269,6 +299,10 @@ impl MappableCommand {
move_prev_long_word_start, "Move to start of previous long word", move_prev_long_word_start, "Move to start of previous long word",
move_next_long_word_end, "Move to end of next long word", move_next_long_word_end, "Move to end of next long word",
move_prev_long_word_end, "Move to end of previous long word", move_prev_long_word_end, "Move to end of previous long word",
move_next_sub_word_start, "Move to start of next sub word",
move_prev_sub_word_start, "Move to start of previous sub word",
move_next_sub_word_end, "Move to end of next sub word",
move_prev_sub_word_end, "Move to end of previous sub word",
move_parent_node_end, "Move to end of the parent node", move_parent_node_end, "Move to end of the parent node",
move_parent_node_start, "Move to beginning of the parent node", move_parent_node_start, "Move to beginning of the parent node",
extend_next_word_start, "Extend to start of next word", extend_next_word_start, "Extend to start of next word",
@ -279,6 +313,10 @@ impl MappableCommand {
extend_prev_long_word_start, "Extend to start of previous long word", extend_prev_long_word_start, "Extend to start of previous long word",
extend_next_long_word_end, "Extend to end of next long word", extend_next_long_word_end, "Extend to end of next long word",
extend_prev_long_word_end, "Extend to end of prev long word", extend_prev_long_word_end, "Extend to end of prev long word",
extend_next_sub_word_start, "Extend to start of next sub word",
extend_prev_sub_word_start, "Extend to start of previous sub word",
extend_next_sub_word_end, "Extend to end of next sub word",
extend_prev_sub_word_end, "Extend to end of prev sub word",
extend_parent_node_end, "Extend to end of the parent node", extend_parent_node_end, "Extend to end of the parent node",
extend_parent_node_start, "Extend to beginning of the parent node", extend_parent_node_start, "Extend to beginning of the parent node",
find_till_char, "Move till next occurrence of char", find_till_char, "Move till next occurrence of char",
@ -543,6 +581,11 @@ impl fmt::Debug for MappableCommand {
.field(name) .field(name)
.field(args) .field(args)
.finish(), .finish(),
MappableCommand::Macro { name, keys, .. } => f
.debug_tuple("MappableCommand")
.field(name)
.field(keys)
.finish(),
} }
} }
} }
@ -573,6 +616,11 @@ impl std::str::FromStr for MappableCommand {
args, args,
}) })
.ok_or_else(|| anyhow!("No TypableCommand named '{}'", s)) .ok_or_else(|| anyhow!("No TypableCommand named '{}'", s))
} else if let Some(suffix) = s.strip_prefix('@') {
helix_view::input::parse_macro(suffix).map(|keys| Self::Macro {
name: s.to_string(),
keys,
})
} else { } else {
MappableCommand::STATIC_COMMAND_LIST MappableCommand::STATIC_COMMAND_LIST
.iter() .iter()
@ -1126,6 +1174,22 @@ fn move_next_long_word_end(cx: &mut Context) {
move_word_impl(cx, movement::move_next_long_word_end) move_word_impl(cx, movement::move_next_long_word_end)
} }
fn move_next_sub_word_start(cx: &mut Context) {
move_word_impl(cx, movement::move_next_sub_word_start)
}
fn move_prev_sub_word_start(cx: &mut Context) {
move_word_impl(cx, movement::move_prev_sub_word_start)
}
fn move_prev_sub_word_end(cx: &mut Context) {
move_word_impl(cx, movement::move_prev_sub_word_end)
}
fn move_next_sub_word_end(cx: &mut Context) {
move_word_impl(cx, movement::move_next_sub_word_end)
}
fn goto_para_impl<F>(cx: &mut Context, move_fn: F) fn goto_para_impl<F>(cx: &mut Context, move_fn: F)
where where
F: Fn(RopeSlice, Range, usize, Movement) -> Range + 'static, F: Fn(RopeSlice, Range, usize, Movement) -> Range + 'static,
@ -1362,6 +1426,22 @@ fn extend_next_long_word_end(cx: &mut Context) {
extend_word_impl(cx, movement::move_next_long_word_end) extend_word_impl(cx, movement::move_next_long_word_end)
} }
fn extend_next_sub_word_start(cx: &mut Context) {
extend_word_impl(cx, movement::move_next_sub_word_start)
}
fn extend_prev_sub_word_start(cx: &mut Context) {
extend_word_impl(cx, movement::move_prev_sub_word_start)
}
fn extend_prev_sub_word_end(cx: &mut Context) {
extend_word_impl(cx, movement::move_prev_sub_word_end)
}
fn extend_next_sub_word_end(cx: &mut Context) {
extend_word_impl(cx, movement::move_next_sub_word_end)
}
/// Separate branch to find_char designed only for `<ret>` char. /// Separate branch to find_char designed only for `<ret>` char.
// //
// This is necessary because the one document can have different line endings inside. And we // This is necessary because the one document can have different line endings inside. And we
@ -3145,6 +3225,9 @@ pub fn command_palette(cx: &mut Context) {
ui::PickerColumn::new("name", |item, _| match item { ui::PickerColumn::new("name", |item, _| match item {
MappableCommand::Typable { name, .. } => format!(":{name}").into(), MappableCommand::Typable { name, .. } => format!(":{name}").into(),
MappableCommand::Static { name, .. } => (*name).into(), MappableCommand::Static { name, .. } => (*name).into(),
MappableCommand::Macro { .. } => {
unreachable!("macros aren't included in the command palette")
}
}), }),
ui::PickerColumn::new( ui::PickerColumn::new(
"bindings", "bindings",
@ -5055,6 +5138,8 @@ fn jump_forward(cx: &mut Context) {
} }
doc.set_selection(view.id, selection); doc.set_selection(view.id, selection);
// Document we switch to might not have been opened in the view before
doc.ensure_view_init(view.id);
view.ensure_cursor_in_view_center(doc, config.scrolloff); view.ensure_cursor_in_view_center(doc, config.scrolloff);
}; };
} }
@ -5075,6 +5160,8 @@ fn jump_backward(cx: &mut Context) {
} }
doc.set_selection(view.id, selection); doc.set_selection(view.id, selection);
// Document we switch to might not have been opened in the view before
doc.ensure_view_init(view.id);
view.ensure_cursor_in_view_center(doc, config.scrolloff); view.ensure_cursor_in_view_center(doc, config.scrolloff);
}; };
} }

@ -2300,7 +2300,7 @@ fn run_shell_command(
move |editor: &mut Editor, compositor: &mut Compositor| { move |editor: &mut Editor, compositor: &mut Compositor| {
if !output.is_empty() { if !output.is_empty() {
let contents = ui::Markdown::new( let contents = ui::Markdown::new(
format!("```sh\n{}\n```", output), format!("```sh\n{}\n```", output.trim_end()),
editor.syn_loader.clone(), editor.syn_loader.clone(),
); );
let popup = Popup::new("shell", contents).position(Some( let popup = Popup::new("shell", contents).position(Some(

@ -177,6 +177,19 @@ impl<'de> serde::de::Visitor<'de> for KeyTrieVisitor {
.map_err(serde::de::Error::custom)?, .map_err(serde::de::Error::custom)?,
) )
} }
// Prevent macro keybindings from being used in command sequences.
// This is meant to be a temporary restriction pending a larger
// refactor of how command sequences are executed.
if commands
.iter()
.any(|cmd| matches!(cmd, MappableCommand::Macro { .. }))
{
return Err(serde::de::Error::custom(
"macro keybindings may not be used in command sequences",
));
}
Ok(KeyTrie::Sequence(commands)) Ok(KeyTrie::Sequence(commands))
} }
@ -199,6 +212,7 @@ impl KeyTrie {
// recursively visit all nodes in keymap // recursively visit all nodes in keymap
fn map_node(cmd_map: &mut ReverseKeymap, node: &KeyTrie, keys: &mut Vec<KeyEvent>) { fn map_node(cmd_map: &mut ReverseKeymap, node: &KeyTrie, keys: &mut Vec<KeyEvent>) {
match node { match node {
KeyTrie::MappableCommand(MappableCommand::Macro { .. }) => {}
KeyTrie::MappableCommand(cmd) => { KeyTrie::MappableCommand(cmd) => {
let name = cmd.name(); let name = cmd.name();
if name != "no_op" { if name != "no_op" {

@ -58,11 +58,16 @@ impl PickerQuery {
() => { () => {
let key = field.take().unwrap_or(primary_field); let key = field.take().unwrap_or(primary_field);
// Trims one space from the end, enabling leading and trailing
// spaces in search patterns, while also retaining spaces as separators
// between column filters.
let pat = text.strip_suffix(' ').unwrap_or(&text);
if let Some(pattern) = fields.get_mut(key) { if let Some(pattern) = fields.get_mut(key) {
pattern.push(' '); pattern.push(' ');
pattern.push_str(text.trim()); pattern.push_str(pat);
} else { } else {
fields.insert(key.clone(), text.trim().to_string()); fields.insert(key.clone(), pat.to_string());
} }
text.clear(); text.clear();
}; };

@ -19,7 +19,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "p
parking_lot = "0.12" parking_lot = "0.12"
arc-swap = { version = "1.7.1" } arc-swap = { version = "1.7.1" }
gix = { version = "0.64.0", features = ["attributes", "status"], default-features = false, optional = true } gix = { version = "0.66.0", features = ["attributes", "status"], default-features = false, optional = true }
imara-diff = "0.1.7" imara-diff = "0.1.7"
anyhow = "1" anyhow = "1"
@ -29,4 +29,4 @@ log = "0.4"
git = ["gix"] git = ["gix"]
[dev-dependencies] [dev-dependencies]
tempfile = "3.11" tempfile = "3.12"

@ -5,7 +5,7 @@ use std::sync::Arc;
use helix_core::Rope; use helix_core::Rope;
use helix_event::RenderLockGuard; use helix_event::RenderLockGuard;
use imara_diff::Algorithm; use imara_diff::Algorithm;
use parking_lot::{Mutex, MutexGuard}; use parking_lot::{RwLock, RwLockReadGuard};
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender}; use tokio::sync::mpsc::{unbounded_channel, UnboundedSender};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tokio::time::Instant; use tokio::time::Instant;
@ -37,7 +37,7 @@ struct DiffInner {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct DiffHandle { pub struct DiffHandle {
channel: UnboundedSender<Event>, channel: UnboundedSender<Event>,
diff: Arc<Mutex<DiffInner>>, diff: Arc<RwLock<DiffInner>>,
inverted: bool, inverted: bool,
} }
@ -48,7 +48,7 @@ impl DiffHandle {
fn new_with_handle(diff_base: Rope, doc: Rope) -> (DiffHandle, JoinHandle<()>) { fn new_with_handle(diff_base: Rope, doc: Rope) -> (DiffHandle, JoinHandle<()>) {
let (sender, receiver) = unbounded_channel(); let (sender, receiver) = unbounded_channel();
let diff: Arc<Mutex<DiffInner>> = Arc::default(); let diff: Arc<RwLock<DiffInner>> = Arc::default();
let worker = DiffWorker { let worker = DiffWorker {
channel: receiver, channel: receiver,
diff: diff.clone(), diff: diff.clone(),
@ -70,7 +70,7 @@ impl DiffHandle {
pub fn load(&self) -> Diff { pub fn load(&self) -> Diff {
Diff { Diff {
diff: self.diff.lock(), diff: self.diff.read(),
inverted: self.inverted, inverted: self.inverted,
} }
} }
@ -164,7 +164,7 @@ impl Hunk {
/// non-overlapping order /// non-overlapping order
#[derive(Debug)] #[derive(Debug)]
pub struct Diff<'a> { pub struct Diff<'a> {
diff: MutexGuard<'a, DiffInner>, diff: RwLockReadGuard<'a, DiffInner>,
inverted: bool, inverted: bool,
} }

@ -4,7 +4,7 @@ use std::sync::Arc;
use helix_core::{Rope, RopeSlice}; use helix_core::{Rope, RopeSlice};
use imara_diff::intern::InternedInput; use imara_diff::intern::InternedInput;
use parking_lot::Mutex; use parking_lot::RwLock;
use tokio::sync::mpsc::UnboundedReceiver; use tokio::sync::mpsc::UnboundedReceiver;
use tokio::sync::Notify; use tokio::sync::Notify;
use tokio::time::{timeout, timeout_at, Duration}; use tokio::time::{timeout, timeout_at, Duration};
@ -21,7 +21,7 @@ mod test;
pub(super) struct DiffWorker { pub(super) struct DiffWorker {
pub channel: UnboundedReceiver<Event>, pub channel: UnboundedReceiver<Event>,
pub diff: Arc<Mutex<DiffInner>>, pub diff: Arc<RwLock<DiffInner>>,
pub new_hunks: Vec<Hunk>, pub new_hunks: Vec<Hunk>,
pub diff_finished_notify: Arc<Notify>, pub diff_finished_notify: Arc<Notify>,
} }
@ -73,7 +73,7 @@ impl DiffWorker {
/// `self.new_hunks` is always empty after this function runs. /// `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` /// 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, diff_base: Rope, doc: Rope) { fn apply_hunks(&mut self, diff_base: Rope, doc: Rope) {
let mut diff = self.diff.lock(); let mut diff = self.diff.write();
diff.diff_base = diff_base; diff.diff_base = diff_base;
diff.doc = doc; diff.doc = doc;
swap(&mut diff.hunks, &mut self.new_hunks); swap(&mut diff.hunks, &mut self.new_hunks);

@ -12,7 +12,7 @@ impl DiffHandle {
// dropping the channel terminates the task // dropping the channel terminates the task
drop(self.channel); drop(self.channel);
handle.await.unwrap(); handle.await.unwrap();
let diff = diff.lock(); let diff = diff.read();
Vec::clone(&diff.hunks) Vec::clone(&diff.hunks)
} }
} }

@ -28,7 +28,7 @@ bitflags = "2.6"
anyhow = "1" anyhow = "1"
crossterm = { version = "0.28", optional = true } crossterm = { version = "0.28", optional = true }
tempfile = "3.11" tempfile = "3.12"
# Conversion traits # Conversion traits
once_cell = "1.19" once_cell = "1.19"

@ -1920,12 +1920,15 @@ impl Document {
return None; return None;
}; };
let severity = diagnostic.severity.map(|severity| match severity { let severity = diagnostic.severity.and_then(|severity| match severity {
lsp::DiagnosticSeverity::ERROR => Error, lsp::DiagnosticSeverity::ERROR => Some(Error),
lsp::DiagnosticSeverity::WARNING => Warning, lsp::DiagnosticSeverity::WARNING => Some(Warning),
lsp::DiagnosticSeverity::INFORMATION => Info, lsp::DiagnosticSeverity::INFORMATION => Some(Info),
lsp::DiagnosticSeverity::HINT => Hint, lsp::DiagnosticSeverity::HINT => Some(Hint),
severity => unreachable!("unrecognized diagnostic severity: {:?}", severity), severity => {
log::error!("unrecognized diagnostic severity: {:?}", severity);
None
}
}); });
if let Some(lang_conf) = language_config { if let Some(lang_conf) = language_config {

@ -44,6 +44,7 @@ haskell-language-server = { command = "haskell-language-server-wrapper", args =
idris2-lsp = { command = "idris2-lsp" } idris2-lsp = { command = "idris2-lsp" }
intelephense = { command = "intelephense", args = ["--stdio"] } intelephense = { command = "intelephense", args = ["--stdio"] }
jdtls = { command = "jdtls" } jdtls = { command = "jdtls" }
jq-lsp = { command = "jq-lsp" }
jsonnet-language-server = { command = "jsonnet-language-server", args= ["-t", "--lint"] } jsonnet-language-server = { command = "jsonnet-language-server", args= ["-t", "--lint"] }
julia = { command = "julia", timeout = 60, args = [ "--startup-file=no", "--history-file=no", "--quiet", "-e", "using LanguageServer; runserver()", ] } julia = { command = "julia", timeout = 60, args = [ "--startup-file=no", "--history-file=no", "--quiet", "-e", "using LanguageServer; runserver()", ] }
koka = { command = "koka", args = ["--language-server", "--lsstdio"] } koka = { command = "koka", args = ["--language-server", "--lsstdio"] }
@ -54,11 +55,13 @@ markdoc-ls = { command = "markdoc-ls", args = ["--stdio"] }
markdown-oxide = { command = "markdown-oxide" } markdown-oxide = { command = "markdown-oxide" }
marksman = { command = "marksman", args = ["server"] } marksman = { command = "marksman", args = ["server"] }
metals = { command = "metals", config = { "isHttpEnabled" = true, metals = { inlayHints = { typeParameters = {enable = true} , hintsInPatternMatch = {enable = true} } } } } metals = { command = "metals", config = { "isHttpEnabled" = true, metals = { inlayHints = { typeParameters = {enable = true} , hintsInPatternMatch = {enable = true} } } } }
mesonlsp = { command = "mesonlsp", args = ["--lsp"] }
mint = { command = "mint", args = ["ls"] } mint = { command = "mint", args = ["ls"] }
mojo-lsp = { command = "mojo-lsp-server" } mojo-lsp = { command = "mojo-lsp-server" }
nil = { command = "nil" } nil = { command = "nil" }
nimlangserver = { command = "nimlangserver" } nimlangserver = { command = "nimlangserver" }
nimlsp = { command = "nimlsp" } nimlsp = { command = "nimlsp" }
nixd = { command = "nixd" }
nls = { command = "nls" } nls = { command = "nls" }
nu-lsp = { command = "nu", args = [ "--lsp" ] } nu-lsp = { command = "nu", args = [ "--lsp" ] }
ocamllsp = { command = "ocamllsp" } ocamllsp = { command = "ocamllsp" }
@ -93,6 +96,7 @@ taplo = { command = "taplo", args = ["lsp", "stdio"] }
templ = { command = "templ", args = ["lsp"] } templ = { command = "templ", args = ["lsp"] }
terraform-ls = { command = "terraform-ls", args = ["serve"] } terraform-ls = { command = "terraform-ls", args = ["serve"] }
texlab = { command = "texlab" } texlab = { command = "texlab" }
typespec = { command = "tsp-server", args = ["--stdio"] }
vala-language-server = { command = "vala-language-server" } vala-language-server = { command = "vala-language-server" }
vhdl_ls = { command = "vhdl_ls", args = [] } vhdl_ls = { command = "vhdl_ls", args = [] }
vlang-language-server = { command = "v-analyzer" } vlang-language-server = { command = "v-analyzer" }
@ -766,6 +770,23 @@ indent = { tab-width = 2, unit = " " }
name = "typescript" name = "typescript"
source = { git = "https://github.com/tree-sitter/tree-sitter-typescript", rev = "b1bf4825d9eaa0f3bdeb1e52f099533328acfbdf", subpath = "typescript" } source = { git = "https://github.com/tree-sitter/tree-sitter-typescript", rev = "b1bf4825d9eaa0f3bdeb1e52f099533328acfbdf", subpath = "typescript" }
[[language]]
name = "typespec"
scope = "source.typespec"
injection-regex = "(tsp|typespec)"
language-id = "typespec"
file-types = ["tsp"]
roots = ["tspconfig.yaml"]
auto-format = true
comment-token = "//"
block-comment-tokens = { start = "/*", end = "*/" }
language-servers = ["typespec"]
indent = { tab-width = 2, unit = " " }
[[grammar]]
name = "typespec"
source = { git = "https://github.com/happenslol/tree-sitter-typespec", rev = "0ee05546d73d8eb64635ed8125de6f35c77759fe" }
[[language]] [[language]]
name = "tsx" name = "tsx"
scope = "source.tsx" scope = "source.tsx"
@ -813,7 +834,7 @@ source = { git = "https://github.com/serenadeai/tree-sitter-scss", rev = "c478c6
name = "html" name = "html"
scope = "text.html.basic" scope = "text.html.basic"
injection-regex = "html" injection-regex = "html"
file-types = ["html", "htm", "shtml", "xhtml", "xht", "jsp", "asp", "aspx", "jshtm", "volt", "rhtml"] file-types = ["html", "htm", "shtml", "xhtml", "xht", "jsp", "asp", "aspx", "jshtm", "volt", "rhtml", "cshtml"]
block-comment-tokens = { start = "<!--", end = "-->" } block-comment-tokens = { start = "<!--", end = "-->" }
language-servers = [ "vscode-html-language-server" ] language-servers = [ "vscode-html-language-server" ]
auto-format = true auto-format = true
@ -866,7 +887,7 @@ injection-regex = "nix"
file-types = ["nix"] file-types = ["nix"]
shebangs = [] shebangs = []
comment-token = "#" comment-token = "#"
language-servers = [ "nil" ] language-servers = [ "nil", "nixd" ]
indent = { tab-width = 2, unit = " " } indent = { tab-width = 2, unit = " " }
[[grammar]] [[grammar]]
@ -948,6 +969,8 @@ file-types = [
"tcshrc", "tcshrc",
"bashrc_Apple_Terminal", "bashrc_Apple_Terminal",
"zshrc_Apple_Terminal", "zshrc_Apple_Terminal",
{ glob = "i3/config" },
{ glob = "sway/config" },
{ glob = "tmux.conf" }, { glob = "tmux.conf" },
{ glob = ".bash_history" }, { glob = ".bash_history" },
{ glob = ".bash_login" }, { glob = ".bash_login" },
@ -2143,6 +2166,7 @@ injection-regex = "meson"
file-types = [{ glob = "meson.build" }, { glob = "meson.options" }, { glob = "meson_options.txt" }] file-types = [{ glob = "meson.build" }, { glob = "meson.options" }, { glob = "meson_options.txt" }]
comment-token = "#" comment-token = "#"
indent = { tab-width = 2, unit = " " } indent = { tab-width = 2, unit = " " }
language-servers = ["mesonlsp"]
[[grammar]] [[grammar]]
name = "meson" name = "meson"
@ -3082,7 +3106,7 @@ indent = { tab-width = 4, unit = " " }
[[grammar]] [[grammar]]
name = "just" name = "just"
source = { git = "https://github.com/IndianBoy42/tree-sitter-just", rev = "379fbe36d1e441bc9414ea050ad0c85c9d6935ea" } source = { git = "https://github.com/poliorcetics/tree-sitter-just", rev = "f58a8fd869035ac4653081401e6c2030251240ab" }
[[language]] [[language]]
name = "gn" name = "gn"
@ -3139,7 +3163,7 @@ language-servers = ["fsharp-ls"]
[[grammar]] [[grammar]]
name = "fsharp" name = "fsharp"
source = { git = "https://github.com/kaashyapan/tree-sitter-fsharp", rev = "18da392fd9bd5e79f357abcce13f61f3a15e3951" } source = { git = "https://github.com/ionide/tree-sitter-fsharp", rev = "996ea9982bd4e490029f84682016b6793940113b" }
[[language]] [[language]]
name = "t32" name = "t32"
@ -3216,6 +3240,19 @@ text-width = 72
name = "jjdescription" name = "jjdescription"
source = { git = "https://github.com/kareigu/tree-sitter-jjdescription", rev = "2ddec6cad07b366aee276a608e1daa2c29d3caf2" } source = { git = "https://github.com/kareigu/tree-sitter-jjdescription", rev = "2ddec6cad07b366aee276a608e1daa2c29d3caf2" }
[[language]]
name = "jq"
scope = "source.jq"
injection-regex = "jq"
file-types = ["jq"]
comment-token = "#"
language-servers = ["jq-lsp"]
indent = { tab-width = 2, unit = " " }
[[grammar]]
name = "jq"
source = { git = "https://github.com/flurie/tree-sitter-jq", rev = "13990f530e8e6709b7978503da9bc8701d366791" }
[[grammar]] [[grammar]]
name = "wren" name = "wren"
source = { git = "https://git.sr.ht/~jummit/tree-sitter-wren", rev = "6748694be32f11e7ec6b5faeb1b48ca6156d4e06" } source = { git = "https://git.sr.ht/~jummit/tree-sitter-wren", rev = "6748694be32f11e7ec6b5faeb1b48ca6156d4e06" }
@ -3726,3 +3763,26 @@ grammar = "typescript"
"{" = "}" "{" = "}"
"(" = ")" "(" = ")"
'"' = '"' '"' = '"'
[[language]]
name = "gherkin"
scope = "source.feature"
file-types = ["feature"]
comment-token = "#"
indent = { tab-width = 2, unit = " " }
[[grammar]]
name = "gherkin"
source = { git = "https://github.com/SamyAB/tree-sitter-gherkin", rev = "43873ee8de16476635b48d52c46f5b6407cb5c09" }
[[language]]
name = "thrift"
scope = "source.thrift"
file-types = ["thrift"]
comment-token = "//"
block-comment-tokens = { start = "/*", end = "*/" }
indent = { tab-width = 2, unit = " " }
[[grammar]]
name = "thrift"
source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-thrift" , rev = "68fd0d80943a828d9e6f49c58a74be1e9ca142cf" }

@ -0,0 +1,4 @@
(comment) @comment.inside
(comment)+ @comment.around

@ -0,0 +1,6 @@
(comment) @comment.inside
(comment)+ @comment.around
(variable_assignment
(_) @entry.inside) @entry.around

@ -1,16 +1,176 @@
;; ---------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------
;; Literals and comments ;; Literals and comments
[ (line_comment) @comment.line
(line_comment)
(block_comment) (block_comment) @comment.block
(block_comment_content)
] @comment (xml_doc) @comment.block.documentation
(const
[
(_) @constant
(unit) @constant.builtin
])
(primary_constr_args (_) @variable.parameter)
((identifier_pattern (long_identifier (identifier) @special))
(#match? @special "^\_.*"))
((long_identifier
(identifier)+
.
(identifier) @variable.other.member))
;; ---------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------
;; Punctuation ;; Punctuation
(wildcard_pattern) @string.special
(type_name type_name: (_) @type)
[
(type)
(atomic_type)
] @type
(member_signature
.
(identifier) @function.method
(curried_spec
(arguments_spec
"*"* @operator
(argument_spec
(argument_name_spec
"?"? @special
name: (_) @variable.parameter)))))
(union_type_case) @constant
(rules
(rule
pattern: (_) @constant
block: (_)))
(identifier_pattern
.
(_) @constant
.
(_) @variable)
(fsi_directive_decl . (string) @namespace)
(import_decl . (_) @namespace)
(named_module
name: (_) @namespace)
(namespace
name: (_) @namespace)
(module_defn
.
(_) @namespace)
(ce_expression
.
(_) @function.macro)
(field_initializer
field: (_) @variable.other.member)
(record_fields
(record_field
.
(identifier) @variable.other.member))
(dot_expression
base: (_) @namespace
field: (_) @variable.other.member)
(value_declaration_left . (_) @variable)
(function_declaration_left
. (_) @function
[
(argument_patterns)
(argument_patterns (long_identifier (identifier)))
] @variable.parameter)
(member_defn
(method_or_prop_defn
[
(property_or_ident) @function
(property_or_ident
instance: (identifier) @variable.builtin
method: (identifier) @function.method)
]
args: (_)* @variable.parameter))
(application_expression
.
[
(long_identifier_or_op [
(long_identifier (identifier)* (identifier) @function)
(identifier) @function
])
(typed_expression . (long_identifier_or_op (long_identifier (identifier)* . (identifier) @function.call)))
(dot_expression base: (_) @variable.other.member field: (_) @function)
] @function)
((infix_expression
.
(_)
.
(infix_op) @operator
.
(_) @function
)
(#eq? @operator "|>")
)
((infix_expression
.
(_) @function
.
(infix_op) @operator
.
(_)
)
(#eq? @operator "<|")
)
[
(xint)
(int)
(int16)
(uint16)
(int32)
(uint32)
(int64)
(uint64)
(nativeint)
(unativeint)
] @constant.numeric.integer
[
(ieee32)
(ieee64)
(float)
(decimal)
] @constant.numeric.float
(bool) @constant.builtin.boolean
([
(string)
(triple_quoted_string)
(verbatim_string)
(char)
] @string)
(compiler_directive_decl) @keyword.directive
(attribute) @attribute
[ [
"(" "("
")" ")"
@ -20,10 +180,18 @@
"]" "]"
"[|" "[|"
"|]" "|]"
"{|"
"|}"
"[<" "[<"
">]" ">]"
] @punctuation.bracket ] @punctuation.bracket
(format_string_eval
[
"{"
"}"
] @punctuation.special)
[ [
"," ","
";" ";"
@ -36,15 +204,16 @@
"<" "<"
"-" "-"
"~" "~"
"->"
"<-"
"&&"
"||"
":>"
":?>"
(infix_op) (infix_op)
(prefix_op) (prefix_op)
(symbolic_op)
] @operator ] @operator
(attribute) @attribute
[ [
"if" "if"
"then" "then"
@ -53,22 +222,29 @@
"when" "when"
"match" "match"
"match!" "match!"
] @keyword.control.conditional
[
"and" "and"
"or" "or"
"&&" "not"
"||" "upcast"
"then" "downcast"
] @keyword.control.conditional ] @keyword.operator
[ [
"return" "return"
"return!" "return!"
"yield"
"yield!"
] @keyword.control.return ] @keyword.control.return
[ [
"for" "for"
"while" "while"
] @keyword.control.return "downto"
"to"
] @keyword.control.repeat
[ [
@ -82,115 +258,93 @@
"delegate" "delegate"
"static" "static"
"inline" "inline"
"internal"
"mutable" "mutable"
"override" "override"
"private"
"public"
"rec" "rec"
"global"
(access_modifier)
] @keyword.storage.modifier ] @keyword.storage.modifier
[ [
"enum"
"let" "let"
"let!" "let!"
"use"
"use!"
"member" "member"
"module" ] @keyword.function
"namespace"
[
"enum"
"type" "type"
] @keyword.storage "inherit"
"interface"
] @keyword.storage.type
(try_expression
[
"try"
"with"
"finally"
] @keyword.control.exception)
((identifier) @keyword.control.exception
(#any-of? @keyword.control.exception "failwith" "failwithf" "raise" "reraise"))
[ [
"as" "as"
"assert" "assert"
"begin" "begin"
"end"
"done"
"default" "default"
"in"
"do" "do"
"do!" "do!"
"done"
"downcast"
"downto"
"end"
"event" "event"
"field" "field"
"finally"
"fun" "fun"
"function" "function"
"get" "get"
"global" "set"
"inherit"
"interface"
"lazy" "lazy"
"new" "new"
"not"
"null"
"of" "of"
"param" "param"
"property" "property"
"set"
"struct" "struct"
"try"
"upcast"
"use"
"use!"
"val" "val"
"module"
"namespace"
"with" "with"
"yield"
"yield!"
] @keyword ] @keyword
[ [
"true" "null"
"false" ] @constant.builtin
"unit"
] @constant.builtin
[
(type)
(const)
] @constant
[
(union_type_case)
(rules (rule (identifier_pattern)))
] @type.enum
(fsi_directive_decl (string) @namespace)
[
(import_decl (long_identifier))
(named_module (long_identifier))
(namespace (long_identifier))
(named_module
name: (long_identifier) )
(namespace
name: (long_identifier) )
] @namespace
(match_expression "with" @keyword.control.conditional)
(dot_expression ((type
base: (long_identifier_or_op) @variable.other.member (long_identifier (identifier) @type.builtin))
field: (long_identifier_or_op) @function) (#any-of? @type.builtin "bool" "byte" "sbyte" "int16" "uint16" "int" "uint" "int64" "uint64" "nativeint" "unativeint" "decimal" "float" "double" "float32" "single" "char" "string" "unit"))
[ (preproc_if
;;(value_declaration_left (identifier_pattern) ) [
(function_declaration_left (identifier) ) "#if" @keyword.directive
(call_expression (long_identifier_or_op (long_identifier))) "#endif" @keyword.directive
;;(application_expression (long_identifier_or_op (long_identifier))) ]
] @function condition: (_)? @keyword.directive)
[ (preproc_else
(string) "#else" @keyword.directive)
(triple_quoted_string)
] @string
[ ((long_identifier
(int) (identifier)+ @namespace
(int16) .
(int32) (identifier)))
(int64)
(float)
(decimal)
] @constant.numeric
(long_identifier_or_op
(op_identifier) @operator)
((identifier) @namespace
(#any-of? @namespace "Array" "Async" "Directory" "File" "List" "Option" "Path" "Map" "Set" "Lazy" "Seq" "Task" "String" "Result" ))

@ -0,0 +1,8 @@
([
(line_comment)
(block_comment_content)
] @injection.content
(#set! injection.language "comment"))
((xml_doc (xml_doc_content) @injection.content)
(#set! injection.language "xml"))

@ -1,25 +1,32 @@
; Scopes (identifier) @local.reference
;-------
[ [
(ce_expression) (namespace)
(module_defn) (named_module)
(for_expression) (function_or_value_defn)
(do_expression)
(fun_expression)
(function_expression)
(try_expression)
(match_expression)
(elif_expression)
(if_expression)
] @local.scope ] @local.scope
; Definitions (value_declaration_left
;------------ .
[
(function_or_value_defn) @local.definition (_ (identifier) @local.definition)
(_ (_ (identifier) @local.definition))
(_ (_ (_ (identifier) @local.definition)))
(_ (_ (_ (_ (identifier) @local.definition))))
(_ (_ (_ (_ (_ (identifier) @local.definition)))))
(_ (_ (_ (_ (_ (_ (identifier) @local.definition))))))
])
; References (function_declaration_left
;----------- .
((_) @local.definition)
(identifier) @local.reference ((argument_patterns
[
(_ (identifier) @local.definition)
(_ (_ (identifier) @local.definition))
(_ (_ (_ (identifier) @local.definition)))
(_ (_ (_ (_ (identifier) @local.definition))))
(_ (_ (_ (_ (_ (identifier) @local.definition)))))
(_ (_ (_ (_ (_ (_ (identifier) @local.definition))))))
])
))

@ -0,0 +1,17 @@
[
(feature_keyword)
(rule_keyword)
(background_keyword)
(scenario_keyword)
(given_keyword)
(when_keyword)
(then_keyword)
(and_keyword)
(but_keyword)
(asterisk_keyword)
] @keyword
(tag) @function
(doc_string) @string
(data_table) @special
(comment) @comment

@ -0,0 +1,6 @@
(comment) @comment.inside
(comment)+ @comment.around
(variable
(_) @entry.inside) @entry.around

@ -4,3 +4,8 @@
(function_arguments (function_arguments
((_) @parameter.inside . ","? @parameter.around) @parameter.around) ((_) @parameter.inside . ","? @parameter.around) @parameter.around)
(attribute
(_) @entry.inside) @entry.around
(tuple
(_) @entry.around)

@ -0,0 +1,10 @@
(comment) @comment.inside
(comment)+ @comment.around
(pair
(_) @entry.inside) @entry.around
(array
(_) @entry.around)

@ -1,13 +1,39 @@
(tag_name) @tag (tag_name) @tag
(erroneous_end_tag_name) @tag.error (erroneous_end_tag_name) @error
(doctype) @constant (doctype) @constant
(attribute_name) @attribute (attribute_name) @attribute
(comment) @comment (comment) @comment
[ ((attribute
"\"" (attribute_name) @_attr
(attribute_value) (quoted_attribute_value (attribute_value) @markup.link.url))
] @string (#any-of? @_attr "href" "src"))
((element
(start_tag
(tag_name) @_tag)
(text) @markup.link.label)
(#eq? @_tag "a"))
(attribute [(attribute_value) (quoted_attribute_value)] @string)
((element
(start_tag
(tag_name) @_tag)
(text) @markup.bold)
(#any-of? @_tag "strong" "b"))
((element
(start_tag
(tag_name) @_tag)
(text) @markup.italic)
(#any-of? @_tag "em" "i"))
((element
(start_tag
(tag_name) @_tag)
(text) @markup.strikethrough)
(#any-of? @_tag "s" "del"))
[ [
"<" "<"

@ -0,0 +1,160 @@
;; From nvim-treesitter, contributed by @ObserverOfTime et al.
; Variables
(variable) @variable
((variable) @constant.builtin
(#eq? @constant.builtin "$ENV"))
((variable) @constant.builtin
(#eq? @constant.builtin "$__loc__"))
; Properties
(index
(identifier) @variable.other.member)
; Labels
(query
label: (variable) @label)
(query
break_statement: (variable) @label)
; Literals
(number) @constant.numeric
(string) @string
[
"true"
"false"
] @constant.builtin.boolean
"null" @type.builtin
; Interpolation
[
"\\("
")"
] @special
; Format
(format) @attribute
; Functions
(funcdef
(identifier) @function)
(funcdefargs
(identifier) @variable.parameter)
[
"reduce"
"foreach"
] @function.builtin
((funcname) @function
.
"(")
; jq -n 'builtins | map(split("/")[0]) | unique | .[]'
((funcname) @function.builtin
(#any-of? @function.builtin
"IN" "INDEX" "JOIN" "abs" "acos" "acosh" "add" "all" "any" "arrays" "ascii_downcase"
"ascii_upcase" "asin" "asinh" "atan" "atan2" "atanh" "booleans" "bsearch" "builtins" "capture"
"cbrt" "ceil" "combinations" "contains" "copysign" "cos" "cosh" "debug" "del" "delpaths" "drem"
"empty" "endswith" "env" "erf" "erfc" "error" "exp" "exp10" "exp2" "explode" "expm1" "fabs"
"fdim" "finites" "first" "flatten" "floor" "fma" "fmax" "fmin" "fmod" "format" "frexp"
"from_entries" "fromdate" "fromdateiso8601" "fromjson" "fromstream" "gamma" "get_jq_origin"
"get_prog_origin" "get_search_list" "getpath" "gmtime" "group_by" "gsub" "halt" "halt_error"
"has" "hypot" "implode" "in" "index" "indices" "infinite" "input" "input_filename"
"input_line_number" "inputs" "inside" "isempty" "isfinite" "isinfinite" "isnan" "isnormal"
"iterables" "j0" "j1" "jn" "join" "keys" "keys_unsorted" "last" "ldexp" "length" "lgamma"
"lgamma_r" "limit" "localtime" "log" "log10" "log1p" "log2" "logb" "ltrimstr" "map" "map_values"
"match" "max" "max_by" "min" "min_by" "mktime" "modf" "modulemeta" "nan" "nearbyint" "nextafter"
"nexttoward" "normals" "not" "now" "nth" "nulls" "numbers" "objects" "path" "paths" "pick" "pow"
"pow10" "range" "recurse" "remainder" "repeat" "reverse" "rindex" "rint" "round" "rtrimstr"
"scalars" "scalb" "scalbln" "scan" "select" "setpath" "significand" "sin" "sinh" "sort"
"sort_by" "split" "splits" "sqrt" "startswith" "stderr" "strflocaltime" "strftime" "strings"
"strptime" "sub" "tan" "tanh" "test" "tgamma" "to_entries" "todate" "todateiso8601" "tojson"
"tonumber" "tostream" "tostring" "transpose" "trunc" "truncate_stream" "type" "unique"
"unique_by" "until" "utf8bytelength" "values" "walk" "while" "with_entries" "y0" "y1" "yn"))
; Keywords
[
"def"
"as"
"label"
"module"
"break"
] @keyword
[
"import"
"include"
] @keyword.control.import
[
"if"
"then"
"elif"
"else"
"end"
] @keyword.control.conditional
[
"try"
"catch"
] @keyword.control.exception
[
"or"
"and"
] @keyword.operator
; Operators
[
"."
"=="
"!="
">"
">="
"<="
"<"
"="
"+"
"-"
"*"
"/"
"%"
"+="
"-="
"*="
"/="
"%="
"//="
"|"
"?"
"//"
"?//"
(recurse) ; ".."
] @operator
; Punctuation
[
";"
","
":"
] @punctuation.delimiter
[
"["
"]"
"{"
"}"
"("
")"
] @punctuation.bracket
; Comments
(comment) @comment.line

@ -0,0 +1,25 @@
;; From nvim-treesitter, contributed by @ObserverOfTime et al.
((comment) @injection.content
(#set! injection.language "comment"))
; test(val)
(query
((funcname) @_function
(#any-of? @_function "test" "match" "capture" "scan" "split" "splits" "sub" "gsub"))
(args
.
(query
(string) @injection.content
(#set! injection.language "regex"))))
; test(regex; flags)
(query
((funcname) @_function
(#any-of? @_function "test" "match" "capture" "scan" "split" "splits" "sub" "gsub"))
(args
.
(args
(query
(string) @injection.content
(#set! injection.language "regex")))))

@ -0,0 +1,12 @@
;; From nvim-treesitter, contributed by @ObserverOfTime et al.
(funcdef
(identifier) @local.definition)
(funcdefargs
(identifier) @local.definition)
(funcname) @local.reference
(index
(identifier) @local.reference)

@ -0,0 +1,8 @@
(comment) @comment.inside
(comment)+ @comment.around
(funcdef
(query) @function.inside) @function.around
(objectkeyval
(_) @entry.inside) @entry.around

@ -1,5 +1,3 @@
; From <https://github.com/IndianBoy42/tree-sitter-just/blob/6c2f018ab1d90946c0ce029bb2f7d57f56895dff/queries-flavored/helix/folds.scm>
; Define collapse points ; Define collapse points
([ ([

@ -1,5 +1,3 @@
; From <https://github.com/IndianBoy42/tree-sitter-just/blob/6c2f018ab1d90946c0ce029bb2f7d57f56895dff/queries-flavored/helix/highlights.scm>
; This file specifies how matched syntax patterns should be highlighted ; This file specifies how matched syntax patterns should be highlighted
[ [
@ -26,35 +24,57 @@
(identifier) @variable) (identifier) @variable)
(alias (alias
left: (identifier) @variable) name: (identifier) @variable)
(assignment (assignment
left: (identifier) @variable) name: (identifier) @variable)
; Functions (shell_variable_name) @variable
(recipe_header ; Functions
name: (identifier) @function)
(dependency (recipe
name: (identifier) @function) name: (identifier) @function)
(dependency_expression (recipe_dependency
name: (identifier) @function) name: (identifier) @function.call)
(function_call (function_call
name: (identifier) @function) name: (identifier) @function.builtin)
; Parameters ; Parameters
(parameter (recipe_parameter
name: (identifier) @variable.parameter) name: (identifier) @variable.parameter)
; Namespaces ; Namespaces
(module (mod
name: (identifier) @namespace) name: (identifier) @namespace)
; Paths
(mod
(path) @string.special.path)
(import
(path) @string.special.path)
; Shebangs
(shebang_line) @keyword.directive
(shebang_line
(shebang_shell) @string.special)
(shell_expanded_string
[
(expansion_short_start)
(expansion_long_start)
(expansion_long_middle)
(expansion_long_end)
] @punctuation.special)
; Operators ; Operators
[ [
@ -95,55 +115,31 @@
; Literals ; Literals
(boolean) @constant.builtin.boolean ; Booleans are not allowed anywhere except in settings
(setting
(boolean) @constant.builtin.boolean)
[ [
(string) (string)
(external_command) (external_command)
] @string ] @string
(escape_sequence) @constant.character.escape [
(escape_sequence)
(escape_variable_end)
] @constant.character.escape
; Comments ; Comments
(comment) @comment.line (comment) @comment.line
(shebang) @keyword.directive ; highlight known settings
; highlight known settings (filtering does not always work)
(setting (setting
left: (identifier) @keyword name: (_) @keyword.function)
(#any-of? @keyword
"allow-duplicate-recipes"
"dotenv-filename"
"dotenv-load"
"dotenv-path"
"export"
"fallback"
"ignore-comments"
"positional-arguments"
"shell"
"tempdi"
"windows-powershell"
"windows-shell"))
; highlight known attributes (filtering does not always work) ; highlight known attributes
(attribute (attribute
(identifier) @attribute name: (identifier) @attribute)
(#any-of? @attribute
"private"
"allow-duplicate-recipes"
"dotenv-filename"
"dotenv-load"
"dotenv-path"
"export"
"fallback"
"ignore-comments"
"positional-arguments"
"shell"
"tempdi"
"windows-powershell"
"windows-shell"))
; Numbers are part of the syntax tree, even if disallowed ; Numbers are part of the syntax tree, even if disallowed
(numeric_error) @error (numeric_error) @error

@ -1,5 +1,3 @@
; From <https://github.com/IndianBoy42/tree-sitter-just/blob/6c2f018ab1d90946c0ce029bb2f7d57f56895dff/queries-flavored/helix/indents.scm>
;
; This query specifies how to auto-indent logical blocks. ; This query specifies how to auto-indent logical blocks.
; ;
; Better documentation with diagrams is in https://docs.helix-editor.com/guides/indent.html ; Better documentation with diagrams is in https://docs.helix-editor.com/guides/indent.html

@ -1,5 +1,3 @@
; From <https://github.com/IndianBoy42/tree-sitter-just/blob/6c2f018ab1d90946c0ce029bb2f7d57f56895dff/queries-flavored/helix/injections.scm>
;
; Specify nested languages that live within a `justfile` ; Specify nested languages that live within a `justfile`
; ================ Always applicable ================ ; ================ Always applicable ================
@ -8,7 +6,7 @@
(#set! injection.language "comment")) (#set! injection.language "comment"))
; Highlight the RHS of `=~` as regex ; Highlight the RHS of `=~` as regex
((regex_literal ((regex
(_) @injection.content) (_) @injection.content)
(#set! injection.language "regex")) (#set! injection.language "regex"))
@ -21,7 +19,7 @@
(#set! injection.include-children)) @injection.content (#set! injection.include-children)) @injection.content
(external_command (external_command
(command_body) @injection.content (content) @injection.content
(#set! injection.language "bash")) (#set! injection.language "bash"))
; ================ Global language specified ================ ; ================ Global language specified ================
@ -43,7 +41,7 @@
; they default to bash. Limitations... ; they default to bash. Limitations...
; See https://github.com/tree-sitter/tree-sitter/issues/880 for more on that. ; See https://github.com/tree-sitter/tree-sitter/issues/880 for more on that.
(source_file (file
(setting "shell" ":=" "[" (string) @_langstr (setting "shell" ":=" "[" (string) @_langstr
(#match? @_langstr ".*(powershell|pwsh|cmd).*") (#match? @_langstr ".*(powershell|pwsh|cmd).*")
(#set! injection.language "powershell")) (#set! injection.language "powershell"))
@ -57,10 +55,10 @@
(expression (expression
(value (value
(external_command (external_command
(command_body) @injection.content)))) (content) @injection.content))))
]) ])
(source_file (file
(setting "shell" ":=" "[" (string) @injection.language (setting "shell" ":=" "[" (string) @injection.language
(#not-match? @injection.language ".*(powershell|pwsh|cmd).*")) (#not-match? @injection.language ".*(powershell|pwsh|cmd).*"))
[ [
@ -73,12 +71,12 @@
(expression (expression
(value (value
(external_command (external_command
(command_body) @injection.content)))) (content) @injection.content))))
]) ])
; ================ Recipe language specified - Helix only ================ ; ================ Recipe language specified - Helix only ================
; Set highlighting for recipes that specify a language using builtin shebang matching ; Set highlighting for recipes that specify a language using builtin shebang matching
(recipe_body (recipe_body
(shebang) @injection.shebang (shebang_line) @injection.shebang
(#set! injection.include-children)) @injection.content (#set! injection.include-children)) @injection.content

@ -1,5 +1,3 @@
; From <https://github.com/IndianBoy42/tree-sitter-just/blob/6c2f018ab1d90946c0ce029bb2f7d57f56895dff/queries-flavored/helix/locals.scm>
;
; This file tells us about the scope of variables so e.g. local ; This file tells us about the scope of variables so e.g. local
; variables override global functions with the same name ; variables override global functions with the same name
@ -10,32 +8,29 @@
; Definitions ; Definitions
(alias (alias
left: (identifier) @local.definition) name: (identifier) @local.definition)
(assignment (assignment
left: (identifier) @local.definition) name: (identifier) @local.definition)
(module (mod
name: (identifier) @local.definition) name: (identifier) @local.definition)
(parameter (recipe_parameter
name: (identifier) @local.definition) name: (identifier) @local.definition)
(recipe_header (recipe
name: (identifier) @local.definition) name: (identifier) @local.definition)
; References ; References
(alias (alias
right: (identifier) @local.reference)
(function_call
name: (identifier) @local.reference) name: (identifier) @local.reference)
(dependency (function_call
name: (identifier) @local.reference) name: (identifier) @local.reference)
(dependency_expression (recipe_dependency
name: (identifier) @local.reference) name: (identifier) @local.reference)
(value (value

@ -1,18 +1,19 @@
; From <https://github.com/IndianBoy42/tree-sitter-just/blob/6c2f018ab1d90946c0ce029bb2f7d57f56895dff/queries-flavored/helix/textobjects.scm>
;
; Specify how to navigate around logical blocks in code ; Specify how to navigate around logical blocks in code
(assert_parameters
((_) @parameter.inside . ","? @parameter.around)) @parameter.around
(recipe (recipe
(recipe_body) @function.inside) @function.around (recipe_body) @function.inside) @function.around
(parameters (recipe_parameters
((_) @parameter.inside . ","? @parameter.around)) @parameter.around ((_) @parameter.inside . ","? @parameter.around)) @parameter.around
(dependency_expression (recipe_dependency
(_) @parameter.inside) @parameter.around (_) @parameter.inside) @parameter.around
(function_call (function_call
arguments: (sequence (function_parameters
(expression) @parameter.inside) @parameter.around) @function.around ((_) @parameter.inside . ","? @parameter.around)) @parameter.around) @function.around
(comment) @comment.around (comment) @comment.around

@ -7,3 +7,6 @@
(function_expression (function_expression
body: (_) @function.inside) @function.around body: (_) @function.inside) @function.around
(binding
(_) @entry.inside) @entry.around

@ -0,0 +1,17 @@
(model_declaration
((statement_block) @class.inside)) @class.around
(call_expression
(arguments (_) @parameter.inside . ","? @parameter.around) @parameter.around)
(column_declaration) @entry.around
(array (_) @entry.around)
(assignment_expression
(_) @entry.inside) @entry.around
(developer_comment) @comment.inside
(developer_comment)+ @comment.around

@ -55,6 +55,55 @@
"'" @label "'" @label
(identifier) @label) (identifier) @label)
; ---
; Prelude
; ---
((identifier) @type.enum.variant.builtin
(#any-of? @type.enum.variant.builtin "Some" "None" "Ok" "Err"))
((type_identifier) @type.builtin
(#any-of?
@type.builtin
"Send"
"Sized"
"Sync"
"Unpin"
"Drop"
"Fn"
"FnMut"
"FnOnce"
"AsMut"
"AsRef"
"From"
"Into"
"DoubleEndedIterator"
"ExactSizeIterator"
"Extend"
"IntoIterator"
"Iterator"
"Option"
"Result"
"Clone"
"Copy"
"Debug"
"Default"
"Eq"
"Hash"
"Ord"
"PartialEq"
"PartialOrd"
"ToOwned"
"Box"
"String"
"ToString"
"Vec"
"FromIterator"
"TryFrom"
"TryInto"))
; --- ; ---
; Punctuation ; Punctuation
; --- ; ---

@ -0,0 +1,4 @@
(comment) @comment.inside
(comment)+ @comment.around

@ -0,0 +1,12 @@
[
(annotation_definition)
(enum_definition)
(exception_definition)
(function_definition)
(senum_definition)
(service_definition)
(struct_definition)
(union_definition)
(comment)
] @fold

@ -0,0 +1,211 @@
; Variables
((identifier) @variable)
; Includes
[
"include"
"cpp_include"
] @keyword
; Function
(function_definition
(identifier) @function)
; Fields
(field (identifier) @variable.other.member)
; Parameters
(function_definition
(parameters
(parameter (identifier) @variable.parameter)))
(throws
(parameters
(parameter (identifier) @keyword.control.exception)))
; Types
(typedef_identifier) @type
(struct_definition
"struct" (identifier) @type)
(union_definition
"union" (identifier) @type)
(exception_definition
"exception" (identifier) @type)
(service_definition
"service" (identifier) @type)
(interaction_definition
"interaction" (identifier) @type)
(type
type: (identifier) @type)
(definition_type
type: (identifier) @type)
; Constants
(const_definition (identifier) @constant)
(enum_definition "enum"
. (identifier) @type
"{" (identifier) @constant "}")
; Builtin Types
(primitive) @type.builtin
[
"list"
"map"
"set"
"sink"
"stream"
"void"
] @type.builtin
; Namespace
(namespace_declaration
(namespace_scope) @tag
[(namespace) @namespace (_ (identifier) @namespace)])
; Attributes
(annotation_definition
(annotation_identifier (identifier) @attribute))
(fb_annotation_definition
"@" @attribute (annotation_identifier (identifier) @attribute)
(identifier)? @attribute)
(namespace_uri (string) @attribute)
; Operators
[
"="
"&"
] @operator
; Exceptions
[
"throws"
] @keyword.control.exception
; Keywords
[
"enum"
"exception"
"extends"
"interaction"
"namespace"
"senum"
"service"
"struct"
"typedef"
"union"
"uri"
] @keyword
; Deprecated Keywords
[
"cocoa_prefix"
"cpp_namespace"
"csharp_namespace"
"delphi_namespace"
"java_package"
"perl_package"
"php_namespace"
"py_module"
"ruby_namespace"
"smalltalk_category"
"smalltalk_prefix"
"xsd_all"
"xsd_attrs"
"xsd_namespace"
"xsd_nillable"
"xsd_optional"
] @keyword
; Extended Kewords
[
"package"
"performs"
] @keyword
[
"async"
"oneway"
] @keyword
; Qualifiers
[
"client"
"const"
"idempotent"
"optional"
"permanent"
"readonly"
"required"
"safe"
"server"
"stateful"
"transient"
] @type.directive
; Literals
(string) @string
(escape_sequence) @constant.character.escape
(namespace_uri
(string) @string.special)
(number) @constant.numeric.integer
(double) @constant.numeric.float
(boolean) @constant.builtin.boolean
; Typedefs
(typedef_identifier) @type.definition
; Punctuation
[
"*"
] @punctuation.special
["{" "}"] @punctuation.bracket
["(" ")"] @punctuation.bracket
["[" "]"] @punctuation.bracket
["<" ">"] @punctuation.bracket
[
"."
","
";"
":"
] @punctuation.delimiter
; Comments
(comment) @comment

@ -0,0 +1,2 @@
((comment) @injection.content
(#set! injection.language "comment"))

@ -0,0 +1,51 @@
; Scopes
[
(document)
(definition)
] @local.scope
; References
(identifier) @local.reference
; Definitions
(annotation_identifier) @local.definition
; (const_definition (identifier) @definition.constant)
; (enum_definition "enum"
; . (identifier) @definition.enum
; "{" (identifier) @definition.constant "}")
; (senum_definition "senum"
; . (identifier) @definition.enum)
; (field (identifier) @definition.field)
; (function_definition (identifier) @definition.function)
; (namespace_declaration
; "namespace" (namespace_scope)
; . (_) @definition.namespace
; (namespace_uri)?)
; (parameter (identifier) @definition.parameter)
; (struct_definition
; "struct" . (identifier) @definition.type)
; (union_definition
; "union" . (identifier) @definition.type)
; (exception_definition
; "exception" . (identifier) @definition.type)
; (service_definition
; "service" . (identifier) @definition.type)
; (interaction_definition
; "interaction" . (identifier) @definition.type)
; (typedef_identifier) @definition.type

@ -0,0 +1,177 @@
; Keywords
[
"is"
"extends"
"valueof"
] @keyword.operator
[
"namespace"
"scalar"
"interface"
"alias"
] @keyword
[
"model"
"enum"
"union"
] @keyword.storage.type
[
"op"
"fn"
"dec"
] @keyword.function
"extern" @keyword.storage.modifier
[
"import"
"using"
] @keyword.control.import
[
"("
")"
"{"
"}"
"<"
">"
"["
"]"
] @punctuation.bracket
[
","
";"
"."
":"
] @punctuation.delimiter
[
"|"
"&"
"="
"..."
] @operator
"?" @punctuation.special
; Imports
(import_statement
(quoted_string_literal) @string.special.path)
; Namespaces
(using_statement
module: (identifier_or_member_expression) @namespace)
(namespace_statement
name: (identifier_or_member_expression) @namespace)
; Comments
[
(single_line_comment)
] @comment.line
[
(multi_line_comment)
] @comment.block
; Decorators
(decorator
"@" @attribute
name: (identifier_or_member_expression) @attribute)
(augment_decorator_statement
name: (identifier_or_member_expression) @attribute)
(decorator
(decorator_arguments) @variable.parameter)
; Scalars
(scalar_statement
name: (identifier) @type)
; Models
(model_statement
name: (identifier) @type)
(model_property
name: (identifier) @variable.other.member)
; Operations
(operation_statement
name: (identifier) @function.method)
(operation_arguments
(model_property
name: (identifier) @variable.parameter))
(template_parameter
name: (identifier) @type.parameter)
(function_parameter
name: (identifier) @variable.parameter)
; Interfaces
(interface_statement
name: (identifier) @type)
(interface_statement
(interface_body
(interface_member
(identifier) @function.method)))
; Enums
(enum_statement
name: (identifier) @type.enum)
(enum_member
name: (identifier) @constant)
; Unions
(union_statement
name: (identifier) @type)
(union_variant
name: (identifier) @type.enum.variant)
; Aliases
(alias_statement
name: (identifier) @type)
; Built-in types
[
(quoted_string_literal)
(triple_quoted_string_literal)
] @string
(escape_sequence) @constant.character.escape
(boolean_literal) @constant.builtin.boolean
[
(decimal_literal)
(hex_integer_literal)
(binary_integer_literal)
] @constant.numeric.integer
(builtin_type) @type.builtin
; Identifiers
(identifier_or_member_expression) @type

@ -0,0 +1,18 @@
[
(model_expression)
(tuple_expression)
(namespace_body)
(interface_body)
(union_body)
(enum_body)
(template_arguments)
(template_parameters)
(operation_arguments)
] @indent.begin
[
"}"
")"
">"
"]"
] @indent.end

@ -0,0 +1,5 @@
([
(single_line_comment)
(multi_line_comment)
] @injection.content
(#set! injection.language "comment"))

@ -0,0 +1,51 @@
; Classes
(enum_statement
(enum_body) @class.inside) @class.around
(model_statement
(model_expression) @class.inside) @class.around
(union_statement
(union_body) @class.inside) @class.around
; Interfaces
(interface_statement
(interface_body
(interface_member) @function.around) @class.inside) @class.around
; Comments
[
(single_line_comment)
(multi_line_comment)
] @comment.inside
[
(single_line_comment)
(multi_line_comment)
]+ @comment.around
; Functions
[
(decorator)
(decorator_declaration_statement)
(function_declaration_statement)
(operation_statement)
] @function.around
(function_parameter_list
(function_parameter)? @parameter.inside)* @function.inside
(decorator_arguments
(expression_list
(_) @parameter.inside)*) @function.inside
(operation_arguments
(model_property)? @parameter.inside)* @function.inside
(template_parameters
(template_parameter_list
(template_parameter) @parameter.inside)) @function.inside

@ -4,3 +4,7 @@
(function_identifier (function_identifier
(function_identifier (function_identifier
(simple_identifier) @function.inside)))) @function.around (simple_identifier) @function.inside)))) @function.around
(comment) @comment.inside
(comment)+ @comment.around

@ -0,0 +1,7 @@
(comment) @comment.inside
(comment)+ @comment.around
(block_mapping_pair
(_) @entry.inside) @entry.around

@ -1,7 +1,7 @@
# Author: David Else <12832280+David-Else@users.noreply.github.com> # Author: David Else <12832280+David-Else@users.noreply.github.com>
# SYNTAX # SYNTAX
"attribute" = "fn_declaration" "attribute" = "variable"
"comment" = "dark_green" "comment" = "dark_green"
"constant" = "constant" "constant" = "constant"
"constant.builtin" = "blue2" "constant.builtin" = "blue2"
@ -39,10 +39,10 @@
# MARKUP # MARKUP
"markup.heading" = { fg = "blue2", modifiers = ["bold"] } "markup.heading" = { fg = "blue2", modifiers = ["bold"] }
"markup.list" = "blue3" "markup.list" = "blue3"
"markup.bold" = { fg = "blue2", modifiers = ["bold"] } "markup.bold" = { modifiers = ["bold"] }
"markup.italic" = { modifiers = ["italic"] } "markup.italic" = { modifiers = ["italic"] }
"markup.strikethrough" = { modifiers = ["crossed_out"] } "markup.strikethrough" = { modifiers = ["crossed_out"] }
"markup.link.url" = { modifiers = ["underlined"] } "markup.link.url" = { underline.style= "line" }
"markup.link.text" = "orange" "markup.link.text" = "orange"
"markup.quote" = "dark_green" "markup.quote" = "dark_green"
"markup.raw" = "orange" "markup.raw" = "orange"
@ -57,7 +57,7 @@
# TODO: Alternate bg colour for `ui.cursor.match` and `ui.selection`. # TODO: Alternate bg colour for `ui.cursor.match` and `ui.selection`.
"ui.cursor" = { fg = "cursor", modifiers = ["reversed"] } "ui.cursor" = { fg = "cursor", modifiers = ["reversed"] }
"ui.cursor.primary" = { fg = "cursor", modifiers = ["reversed"] } "ui.cursor.primary" = { fg = "cursor", modifiers = ["reversed"] }
"ui.cursor.match" = { bg = "#3a3d41", modifiers = ["underlined"] } "ui.cursor.match" = { bg = "#3a3d41", underline.style = "line" }
"ui.selection" = { bg = "#3a3d41" } "ui.selection" = { bg = "#3a3d41" }
"ui.selection.primary" = { bg = "dark_blue" } "ui.selection.primary" = { bg = "dark_blue" }
"ui.linenr" = { fg = "dark_gray" } "ui.linenr" = { fg = "dark_gray" }
@ -80,6 +80,8 @@
"ui.highlight.frameline" = { bg = "#4b4b18" } "ui.highlight.frameline" = { bg = "#4b4b18" }
"ui.debug.active" = { fg = "#ffcc00" } "ui.debug.active" = { fg = "#ffcc00" }
"ui.debug.breakpoint" = { fg = "#e51400" } "ui.debug.breakpoint" = { fg = "#e51400" }
"ui.picker.header.column" = { underline.style = "line" }
"ui.picker.header.column.active" = { fg ="white", underline.style = "line" }
"warning" = { fg = "gold2" } "warning" = { fg = "gold2" }
"error" = { fg = "red" } "error" = { fg = "red" }
"info" = { fg = "light_blue" } "info" = { fg = "light_blue" }

@ -65,7 +65,7 @@
"diff.minus" = "red" "diff.minus" = "red"
"ui.background" = { bg = "bg0" } "ui.background" = { bg = "bg0" }
"ui.background.separator" = "bg_visual" "ui.background.separator" = "grey0"
"ui.cursor" = { fg = "bg1", bg = "grey2" } "ui.cursor" = { fg = "bg1", bg = "grey2" }
"ui.cursor.insert" = { fg = "bg0", bg = "grey1" } "ui.cursor.insert" = { fg = "bg0", bg = "grey1" }
"ui.cursor.select" = { fg = "bg0", bg = "blue" } "ui.cursor.select" = { fg = "bg0", bg = "blue" }
@ -90,6 +90,7 @@
"bold", "bold",
] } ] }
"ui.popup" = { fg = "grey2", bg = "bg2" } "ui.popup" = { fg = "grey2", bg = "bg2" }
"ui.picker.header" = { modifiers = ["bold", "underlined"] }
"ui.window" = { fg = "bg4", bg = "bg_dim" } "ui.window" = { fg = "bg4", bg = "bg_dim" }
"ui.help" = { fg = "fg", bg = "bg2" } "ui.help" = { fg = "fg", bg = "bg2" }
"ui.text" = "fg" "ui.text" = "fg"

@ -64,7 +64,7 @@
"diff.minus" = "red" "diff.minus" = "red"
"ui.background" = { bg = "bg0" } "ui.background" = { bg = "bg0" }
"ui.background.separator" = "bg_visual" "ui.background.separator" = "grey0"
"ui.cursor" = { fg = "bg1", bg = "grey2" } "ui.cursor" = { fg = "bg1", bg = "grey2" }
"ui.cursor.insert" = { fg = "bg0", bg = "grey1" } "ui.cursor.insert" = { fg = "bg0", bg = "grey1" }
"ui.cursor.select" = { fg = "bg0", bg = "blue" } "ui.cursor.select" = { fg = "bg0", bg = "blue" }
@ -89,6 +89,7 @@
"bold", "bold",
] } ] }
"ui.popup" = { fg = "grey2", bg = "bg2" } "ui.popup" = { fg = "grey2", bg = "bg2" }
"ui.picker.header" = { modifiers = ["bold", "underlined"] }
"ui.window" = { fg = "bg4", bg = "bg_dim" } "ui.window" = { fg = "bg4", bg = "bg_dim" }
"ui.help" = { fg = "fg", bg = "bg2" } "ui.help" = { fg = "fg", bg = "bg2" }
"ui.text" = "fg" "ui.text" = "fg"

@ -94,6 +94,8 @@
"ui.menu" = { fg = "fg1", bg = "bg2" } "ui.menu" = { fg = "fg1", bg = "bg2" }
"ui.menu.selected" = { fg = "bg2", bg = "blue1", modifiers = ["bold"] } "ui.menu.selected" = { fg = "bg2", bg = "blue1", modifiers = ["bold"] }
"ui.popup" = { bg = "bg1" } "ui.popup" = { bg = "bg1" }
"ui.picker.header.column" = { underline.style = "line" }
"ui.picker.header.column.active" = { modifiers = ["bold"], underline.style = "line" }
"ui.selection" = { bg = "bg2" } "ui.selection" = { bg = "bg2" }
"ui.selection.primary" = { bg = "bg3" } "ui.selection.primary" = { bg = "bg3" }

@ -0,0 +1,128 @@
# Author : Chromo-residuum-opec <development.0extl@simplelogin.com>
"attribute" = { fg = "green" }
"boolean" = { fg = "purple" }
"character" = { fg = "purple" }
"comment" = { fg = "comment_fg" }
"conditional" = { fg = "blue" }
"constant" = { fg = "purple" }
"constructor" = { fg = "blue" }
"diagnostic.deprecated" = { modifiers = ["crossed_out"] }
"diagnostic.error" = { underline = { style = "curl", color = "red" } }
"diagnostic.hint" = { underline = { style = "curl", color = "comment_fg" } }
"diagnostic.info" = { underline = { style = "curl", color = "cyan" } }
"diagnostic.unnecessary" = { modifiers = ["dim"] }
"diagnostic.warning" = { underline = { style = "curl", color = "orange" } }
"diff.delta" = { fg = "blue" }
"diff.delta.gutter" = { fg = "cyan", bg = "linenr_bg" }
"diff.minus" = { fg = "red" }
"diff.minus.gutter" = { fg = "red", bg = "linenr_bg" }
"diff.plus" = { fg = "green" }
"diff.plus.gutter" = { fg = "green", bg = "linenr_bg" }
"error" = { fg = "red" }
"exception" = { fg = "blue" }
"field" = { fg = "background_fg" }
"float" = { fg = "purple" }
"function" = { fg = "pale" }
"function.macro" = { fg = "green" }
"hint" = { fg = "comment_fg" }
"identifier" = { fg = "blue" }
"info" = { fg = "cyan" }
"keyword" = { fg = "blue" }
"keyword.directive" = { fg = "green" }
"keyword.import" = { fg = "pale" }
"label" = { fg = "green" }
"markup.bold" = { modifiers = ["bold"] }
"markup.heading" = { fg = "blue", modifiers = ["bold"] }
"markup.italic" = { modifiers = ["italic"] }
"markup.link" = { fg = "blue", underline = { style = "line" } }
"markup.link.label" = { fg = "cyan" }
"markup.link.text" = { fg = "cyan" }
"markup.link.url" = { underline = { style = "line" } }
"markup.list" = { fg = "orange", modifiers = ["bold"] }
"markup.raw" = { fg = "cyan" }
"markup.raw.inline" = { bg = "black", fg = "blue" }
"markup.strikethrough" = { modifiers = ["crossed_out"] }
"method" = { fg = "pale" }
"namespace" = { fg = "blue" }
"number" = { fg = "purple" }
"operator" = { fg = "blue" }
"parameter" = { fg = "background_fg" }
"property" = { fg = "background_fg" }
"punctuation.bracket" = { fg = "background_fg" }
"punctuation.delimiter" = { fg = "background_fg" }
"punctuation.special" = { fg = "green" }
"repeat" = { fg = "blue" }
"special" = { fg = "green" }
"string" = { fg = "cyan" }
"string.escape" = { fg = "green" }
"string.special" = { fg = "green" }
"tag" = { fg = "blue" }
"tag.attribute" = { fg = "purple" }
"text" = { fg = "background_fg" }
"type" = { fg = "blue" }
"ui.background" = { fg = "background_fg", bg = "background_bg" }
"ui.background.separator" = { fg = "comment_fg" }
"ui.bufferline.active" = { fg = "pale" }
"ui.cursor.match" = { fg = "background_fg", bg = "matchparen_bg" }
"ui.cursor.normal" = { bg = "gray" }
"ui.cursor.primary" = { modifiers = ["reversed"] }
"ui.cursor.select" = { bg = "gray" }
"ui.gutter" = { fg = "linenr_fg", bg = "linenr_bg" }
"ui.help" = { fg = "background_fg", bg = "cursorlinenr_bg" }
"ui.linenr" = { fg = "linenr_fg", bg = "linenr_bg" }
"ui.menu" = { fg = "background_fg", bg = "cursorlinenr_bg" }
"ui.menu.border" = { fg = "comment_fg" }
"ui.menu.selected" = { fg = "menusel_fg", bg = "menusel_bg" }
"ui.popup" = { fg = "background_fg", bg = "cursorlinenr_bg" }
"ui.popup.info" = { fg = "blue" }
"ui.selection" = { bg = "sel_bg" }
"ui.statusline" = { bg = "statusline_bg", fg = "statusline_fg" }
"ui.statusline.insert" = { fg = "black", bg = "blue" }
"ui.statusline.select" = { fg = "black", bg = "green" }
"ui.text.focus" = { fg = "orange" }
"ui.virtual" = { fg = "linenr_fg" }
"ui.virtual.indent-guide" = { fg = "linenr_fg" }
"ui.virtual.jump-label" = { fg = "orange", modifiers = ["bold"] }
"ui.virtual.ruler" = { bg = "linenr_bg" }
"ui.virtual.whitespace" = { fg = "sel_bg" }
"ui.window" = { fg = "comment_fg", modifiers = ["bold"] }
"variable" = { fg = "background_fg" }
"variable.builtin" = { fg = "blue" }
"warning" = { fg = "orange" }
[palette]
orange = "#e2a578"
pale = "#a4aecc"
purple = "#a093c8"
black = "#1e2132"
gray = "#6b7089"
red = "#e27878"
light-red = "#e98989"
green = "#b5bf82"
light-green = "#c0ca8e"
yellow = "#e2a478"
light-yellow = "#e9b189"
blue = "#85a0c7"
light-blue = "#91acd1"
magenta = "#a093c7"
light-magenta = "#ada0d3"
cyan = "#89b9c2"
light-cyan = "#95c4ce"
white = "#c6c8d1"
light-gray = "#d2d4de"
background_bg = "#161822"
background_fg = "#c7c9d1"
comment_fg = "#6c7189"
cursorlinenr_bg = "#3d425c"
linenr_bg = "#1f2233"
linenr_fg = "#454d73"
matchparen_bg = "#3f455f"
menusel_bg = "#5c638a"
menusel_fg = "#f0f1f5"
sel_bg = "#282d43"
statusline_bg = "#0f1117"
statusline_fg = "#828597"

@ -0,0 +1,39 @@
# Author : Chromo-residuum-opec <development.0extl@simplelogin.com>
inherits = "iceberg-dark"
"ui.menu.selected" = { fg = "background_fg", bg = "menusel_bg" }
[palette]
orange = "#c67439"
pale = "#505695"
purple = "#785ab5"
black = "#dcdfe7"
gray = "#8389a3"
red = "#cd517a"
light-red = "#cc3768"
green = "#668f3d"
light-green = "#598030"
yellow = "#c57339"
light-yellow = "#b6662d"
blue = "#2e539e"
light-blue = "#22478e"
magenta = "#7759b4"
light-magenta = "#6845ad"
cyan = "#3f84a6"
light-cyan = "#327698"
white = "#33374c"
light-gray = "#262a3f"
background_bg = "#e9e9ed"
background_fg = "#33374d"
comment_fg = "#8489a4"
cursorlinenr_bg = "#cccfe0"
linenr_bg = "#dddfe9"
linenr_fg = "#a0a5c0"
matchparen_bg = "#bec0ca"
menusel_bg = "#a9afd1"
sel_bg = "#cacdd8"
statusline_bg = "#cad0de"
statusline_fg = "#757da3"

@ -1044,8 +1044,8 @@ lines.
1. Move the cursor to the line marked '-->' below. 1. Move the cursor to the line marked '-->' below.
2. Select both lines with xx or 2x. 2. Select both lines with xx or 2x.
3. Type s to select, type "would" and enter. 3. Type s to select, type "would" and enter.
4. Use ( and ) to cycle the primary selection and remove the 4. Use ( and ) to cycle the primary selection and deselect
very second "would" with Alt-, . the second "would" with Alt-, .
5. Type c "wood" to change the remaining "would"s to "wood". 5. Type c "wood" to change the remaining "would"s to "wood".
--> How much would would a wouldchuck chuck --> How much would would a wouldchuck chuck

@ -1,9 +1,9 @@
use crate::helpers; use crate::helpers;
use crate::path; use crate::path;
use crate::DynError; use crate::DynError;
use helix_term::commands::TYPABLE_COMMAND_LIST; use helix_term::commands::TYPABLE_COMMAND_LIST;
use helix_term::health::TsFeature; use helix_term::health::TsFeature;
use std::collections::HashSet;
use std::fs; use std::fs;
pub const TYPABLE_COMMANDS_MD_OUTPUT: &str = "typable-cmd.md"; pub const TYPABLE_COMMANDS_MD_OUTPUT: &str = "typable-cmd.md";
@ -95,14 +95,25 @@ pub fn lang_features() -> Result<String, DynError> {
.to_owned(), .to_owned(),
); );
} }
row.push( let mut seen_commands = HashSet::new();
lc.language_servers let mut commands = String::new();
for ls_config in lc
.language_servers
.iter() .iter()
.filter_map(|ls| config.language_server.get(&ls.name)) .filter_map(|ls| config.language_server.get(&ls.name))
.map(|s| md_mono(&s.command.clone())) {
.collect::<Vec<_>>() let command = &ls_config.command;
.join(", "), if !seen_commands.insert(command) {
); continue;
}
if !commands.is_empty() {
commands.push_str(", ");
}
commands.push_str(&md_mono(command));
}
row.push(commands);
md.push_str(&md_table_row(&row)); md.push_str(&md_table_row(&row));
row.clear(); row.clear();

Loading…
Cancel
Save