From 10c3502a89d51e2d074d0d2ca62f85241d6e8c0f Mon Sep 17 00:00:00 2001 From: Elizabeth <88293801+lizclipse@users.noreply.github.com> Date: Mon, 11 Nov 2024 03:30:55 +0000 Subject: [PATCH 01/62] fix: removed explict default config file from swift-format (#12052) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index d55948ad5..f24c70d81 100644 --- a/languages.toml +++ b/languages.toml @@ -1966,7 +1966,7 @@ file-types = ["swift", "swiftinterface"] roots = [ "Package.swift" ] comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } -formatter = { command = "swift-format", args = [ "--configuration", ".swift-format"] } +formatter = { command = "swift-format" } auto-format = true language-servers = [ "sourcekit-lsp" ] From b5d56e57a621ccb4e3674cf8645dbc57c7b64fa2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 23:54:14 +0000 Subject: [PATCH 02/62] build(deps): bump the rust-dependencies group across 1 directory with 11 updates Bumps the rust-dependencies group with 10 updates in the / directory: | Package | From | To | | --- | --- | --- | | [regex](https://github.com/rust-lang/regex) | `1.11.0` | `1.11.1` | | [url](https://github.com/servo/rust-url) | `2.5.2` | `2.5.3` | | [serde](https://github.com/serde-rs/serde) | `1.0.210` | `1.0.215` | | [encoding_rs](https://github.com/hsivonen/encoding_rs) | `0.8.34` | `0.8.35` | | [anyhow](https://github.com/dtolnay/anyhow) | `1.0.90` | `1.0.93` | | [tempfile](https://github.com/Stebalien/tempfile) | `3.13.0` | `3.14.0` | | [tokio](https://github.com/tokio-rs/tokio) | `1.40.0` | `1.41.1` | | [libc](https://github.com/rust-lang/libc) | `0.2.161` | `0.2.162` | | [cc](https://github.com/rust-lang/cc-rs) | `1.1.31` | `1.1.37` | | [gix](https://github.com/GitoxideLabs/gitoxide) | `0.66.0` | `0.67.0` | Updates `regex` from 1.11.0 to 1.11.1 - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.11.0...1.11.1) Updates `url` from 2.5.2 to 2.5.3 - [Release notes](https://github.com/servo/rust-url/releases) - [Commits](https://github.com/servo/rust-url/compare/v2.5.2...v2.5.3) Updates `serde` from 1.0.210 to 1.0.215 - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.210...v1.0.215) Updates `encoding_rs` from 0.8.34 to 0.8.35 - [Commits](https://github.com/hsivonen/encoding_rs/compare/v0.8.34...v0.8.35) Updates `anyhow` from 1.0.90 to 1.0.93 - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.90...1.0.93) Updates `tempfile` from 3.13.0 to 3.14.0 - [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md) - [Commits](https://github.com/Stebalien/tempfile/compare/v3.13.0...v3.14.0) Updates `tokio` from 1.40.0 to 1.41.1 - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.40.0...tokio-1.41.1) Updates `libc` from 0.2.161 to 0.2.162 - [Release notes](https://github.com/rust-lang/libc/releases) - [Changelog](https://github.com/rust-lang/libc/blob/0.2.162/CHANGELOG.md) - [Commits](https://github.com/rust-lang/libc/compare/0.2.161...0.2.162) Updates `rustix` from 0.38.37 to 0.38.40 - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Changelog](https://github.com/bytecodealliance/rustix/blob/main/CHANGELOG.md) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.37...v0.38.40) Updates `cc` from 1.1.31 to 1.1.37 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.31...cc-v1.1.37) Updates `gix` from 0.66.0 to 0.67.0 - [Release notes](https://github.com/GitoxideLabs/gitoxide/releases) - [Changelog](https://github.com/GitoxideLabs/gitoxide/blob/main/CHANGELOG.md) - [Commits](https://github.com/GitoxideLabs/gitoxide/compare/gix-v0.66.0...gix-v0.67.0) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: url dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: encoding_rs dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: tempfile dependency-type: direct:production update-type: version-update:semver-minor dependency-group: rust-dependencies - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor dependency-group: rust-dependencies - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: rustix dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: cc dependency-type: direct:production update-type: version-update:semver-patch dependency-group: rust-dependencies - dependency-name: gix dependency-type: direct:production update-type: version-update:semver-minor dependency-group: rust-dependencies ... Signed-off-by: dependabot[bot] --- Cargo.lock | 514 ++++++++++++++++++++++++++++--------- helix-core/Cargo.toml | 2 +- helix-loader/Cargo.toml | 2 +- helix-lsp-types/Cargo.toml | 4 +- helix-lsp/Cargo.toml | 2 +- helix-stdx/Cargo.toml | 2 +- helix-term/Cargo.toml | 6 +- helix-vcs/Cargo.toml | 4 +- helix-view/Cargo.toml | 4 +- 9 files changed, 404 insertions(+), 136 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8662c41e..86dace16c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.90" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arc-swap" @@ -136,9 +136,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.1.31" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ "shlex", ] @@ -278,6 +278,17 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dunce" version = "1.0.5" @@ -292,9 +303,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -346,6 +357,9 @@ name = "faster-hex" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" +dependencies = [ + "serde", +] [[package]] name = "fastrand" @@ -465,9 +479,9 @@ checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "gix" -version = "0.66.0" +version = "0.67.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9048b8d1ae2104f045cb37e5c450fc49d5d8af22609386bfc739c11ba88995eb" +checksum = "c7d3e78ddac368d3e3bfbc2862bc2aafa3d89f1b15fed898d9761e1ec6f3f17f" dependencies = [ "gix-actor", "gix-attributes", @@ -513,9 +527,9 @@ dependencies = [ [[package]] name = "gix-actor" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc19e312cd45c4a66cd003f909163dc2f8e1623e30a0c0c6df3776e89b308665" +checksum = "59226ef06661c756e664b46b1d3b2c198f6adc5407a484c086d0171108a70027" dependencies = [ "bstr", "gix-date", @@ -527,9 +541,9 @@ dependencies = [ [[package]] name = "gix-attributes" -version = "0.22.5" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebccbf25aa4a973dd352564a9000af69edca90623e8a16dad9cbc03713131311" +checksum = "31a102d201ef0e5a848458a82292581e7641e52f0f52e693b6cbdd05a652c029" dependencies = [ "bstr", "gix-glob", @@ -544,27 +558,27 @@ dependencies = [ [[package]] name = "gix-bitmap" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae" +checksum = "10f78312288bd02052be5dbc2ecbc342c9f4eb791986d86c0a5c06b92dc72efa" dependencies = [ "thiserror", ] [[package]] name = "gix-chunk" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c8751169961ba7640b513c3b24af61aa962c967aaf04116734975cd5af0c52" +checksum = "6c28b58ba04f0c004722344390af9dbc85888fbb84be1981afb934da4114d4cf" dependencies = [ "thiserror", ] [[package]] name = "gix-command" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff2e692b36bbcf09286c70803006ca3fd56551a311de450be317a0ab8ea92e7" +checksum = "c201d2b9e9cce2365a6638fd0a966f751ed92d74be5c0727ac331e6a29ef5846" dependencies = [ "bstr", "gix-path", @@ -574,9 +588,9 @@ dependencies = [ [[package]] name = "gix-commitgraph" -version = "0.24.3" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133b06f67f565836ec0c473e2116a60fb74f80b6435e21d88013ac0e3c60fc78" +checksum = "41db900b189e62dc61575f06fdf1a3b6901d264a99be9d32b286af6b2e3984e1" dependencies = [ "bstr", "gix-chunk", @@ -588,9 +602,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78e797487e6ca3552491de1131b4f72202f282fb33f198b1c34406d765b42bb0" +checksum = "0bedd1bf1c7b994be9d57207e8e0de79016c05e2e8701d3015da906e65ac445e" dependencies = [ "bstr", "gix-config-value", @@ -609,9 +623,9 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.14.8" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f76169faa0dec598eac60f83d7fcdd739ec16596eca8fb144c88973dbe6f8c" +checksum = "f3de3fdca9c75fa4b83a76583d265fa49b1de6b088ebcd210749c24ceeb74660" dependencies = [ "bitflags", "bstr", @@ -622,9 +636,9 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c84b7af01e68daf7a6bb8bb909c1ff5edb3ce4326f1f43063a5a96d3c3c8a5" +checksum = "d10d543ac13c97292a15e8e8b7889cd006faf739777437ed95362504b8fe81a0" dependencies = [ "bstr", "itoa", @@ -634,9 +648,9 @@ dependencies = [ [[package]] name = "gix-diff" -version = "0.46.0" +version = "0.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c9afd80fff00f8b38b1c1928442feb4cd6d2232a6ed806b6b193151a3d336c" +checksum = "c9850fd0c15af113db6f9e130d13091ba0d3754e570a2afdff9e2f3043da260e" dependencies = [ "bstr", "gix-command", @@ -647,6 +661,7 @@ dependencies = [ "gix-path", "gix-tempfile", "gix-trace", + "gix-traverse", "gix-worktree", "imara-diff", "thiserror", @@ -654,9 +669,9 @@ dependencies = [ [[package]] name = "gix-dir" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed3a9076661359a1c5a27c12ad6c3ebe2dd96b8b3c0af6488ab7c128b7bdd98" +checksum = "bbf6c29bf17baf3996d4925fad5e10c1a12eac9b3a0d8475d89292e0e5ba34a3" dependencies = [ "bstr", "gix-discover", @@ -674,9 +689,9 @@ dependencies = [ [[package]] name = "gix-discover" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0577366b9567376bc26e815fd74451ebd0e6218814e242f8e5b7072c58d956d2" +checksum = "c522e31f458f50af09dfb014e10873c5378f702f8049c96f508989aad59671f6" dependencies = [ "bstr", "dunce", @@ -690,9 +705,9 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.38.2" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" +checksum = "8e0eb9efdf96c35c0bed7596d1bef2d4ce6360a1d09738001f9d3e402aa7ba3e" dependencies = [ "crc32fast", "flate2", @@ -709,9 +724,9 @@ dependencies = [ [[package]] name = "gix-filter" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4121790ae140066e5b953becc72e7496278138d19239be2e63b5067b0843119e" +checksum = "6b37f82359a4485770ed8993ae715ced1bf674f2a63e45f5a0786d38310665ea" dependencies = [ "bstr", "encoding_rs", @@ -730,9 +745,9 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.11.3" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bfe6249cfea6d0c0e0990d5226a4cb36f030444ba9e35e0639275db8f98575" +checksum = "34740384d8d763975858fa2c176b68652a6fcc09f616e24e3ce967b0d370e4d8" dependencies = [ "fastrand", "gix-features", @@ -741,9 +756,9 @@ dependencies = [ [[package]] name = "gix-glob" -version = "0.16.5" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74908b4bbc0a0a40852737e5d7889f676f081e340d5451a16e5b4c50d592f111" +checksum = "254b5101cf7facc00d9b5ff564cf46302ca76695cca23d33bc958a707b6fc857" dependencies = [ "bitflags", "bstr", @@ -753,9 +768,9 @@ dependencies = [ [[package]] name = "gix-hash" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" +checksum = "952c3a29f1bc1007cc901abce7479943abfa42016db089de33d0a4fa3c85bfe8" dependencies = [ "faster-hex", "thiserror", @@ -763,9 +778,9 @@ dependencies = [ [[package]] name = "gix-hashtable" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddf80e16f3c19ac06ce415a38b8591993d3f73aede049cb561becb5b3a8e242" +checksum = "0ef65b256631078ef733bc5530c4e6b1c2e7d5c2830b75d4e9034ab3997d18fe" dependencies = [ "gix-hash", "hashbrown", @@ -774,9 +789,9 @@ dependencies = [ [[package]] name = "gix-ignore" -version = "0.11.4" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e447cd96598460f5906a0f6c75e950a39f98c2705fc755ad2f2020c9e937fab7" +checksum = "ba55a9b582dc26a639875497615959a8127ac5c37b2426dc50f037fada33a4b7" dependencies = [ "bstr", "gix-glob", @@ -787,9 +802,9 @@ dependencies = [ [[package]] name = "gix-index" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cd4203244444017682176e65fd0180be9298e58ed90bd4a8489a357795ed22d" +checksum = "27619009ca1ea33fd885041273f5fa5a09163a5c1d22a913b28d7b985e66fe29" dependencies = [ "bitflags", "bstr", @@ -815,9 +830,9 @@ dependencies = [ [[package]] name = "gix-lock" -version = "14.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bc7fe297f1f4614774989c00ec8b1add59571dc9b024b4c00acb7dedd4e19d" +checksum = "5102acdf4acae2644e38dbbd18cdfba9597a218f7d85f810fe5430207e03c2de" dependencies = [ "gix-tempfile", "gix-utils", @@ -826,15 +841,16 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.44.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5b801834f1de7640731820c2df6ba88d95480dc4ab166a5882f8ff12b88efa" +checksum = "2a77b6e7753d298553d9ae8b1744924481e7a49170983938bb578dccfbc6fc1a" dependencies = [ "bstr", "gix-actor", "gix-date", "gix-features", "gix-hash", + "gix-hashtable", "gix-utils", "gix-validate", "itoa", @@ -845,15 +861,16 @@ dependencies = [ [[package]] name = "gix-odb" -version = "0.63.0" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3158068701c17df54f0ab2adda527f5a6aca38fd5fd80ceb7e3c0a2717ec747" +checksum = "0bb86aadf7f1b2f980601b4fc94309706f9700f8008f935dc512d556c9e60f61" dependencies = [ "arc-swap", "gix-date", "gix-features", "gix-fs", "gix-hash", + "gix-hashtable", "gix-object", "gix-pack", "gix-path", @@ -865,9 +882,9 @@ dependencies = [ [[package]] name = "gix-pack" -version = "0.53.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3223aa342eee21e1e0e403cad8ae9caf9edca55ef84c347738d10681676fd954" +checksum = "363e6e59a855ba243672408139db68e2478126cdcfeabb420777df4a1f20026b" dependencies = [ "clru", "gix-chunk", @@ -883,9 +900,9 @@ dependencies = [ [[package]] name = "gix-packetline-blocking" -version = "0.17.5" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9802304baa798dd6f5ff8008a2b6516d54b74a69ca2d3a2b9e2d6c3b5556b40" +checksum = "decace940e8ba8e29d29b73b843a6cbae67503887f3e5fb7e688d0f4f6ee0757" dependencies = [ "bstr", "faster-hex", @@ -895,9 +912,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.11" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebfc4febd088abdcbc9f1246896e57e37b7a34f6909840045a1767c6dafac7af" +checksum = "c04e5a94fdb56b1e91eb7df2658ad16832428b8eeda24ff1a0f0288de2bce554" dependencies = [ "bstr", "gix-trace", @@ -908,9 +925,9 @@ dependencies = [ [[package]] name = "gix-pathspec" -version = "0.7.7" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d23bf239532b4414d0e63b8ab3a65481881f7237ed9647bb10c1e3cc54c5ceb" +checksum = "70f02bf7625dbf15bf9fedbeace2ac1ce1c5177806bdbc24c441d664c75c00e4" dependencies = [ "bitflags", "bstr", @@ -923,9 +940,9 @@ dependencies = [ [[package]] name = "gix-quote" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbff4f9b9ea3fa7a25a70ee62f545143abef624ac6aa5884344e70c8b0a1d9ff" +checksum = "f89f9a1525dcfd9639e282ea939f5ab0d09d93cf2b90c1fc6104f1b9582a8e49" dependencies = [ "bstr", "gix-utils", @@ -934,9 +951,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.47.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae0d8406ebf9aaa91f55a57f053c5a1ad1a39f60fdf0303142b7be7ea44311e5" +checksum = "a47385e71fa2d9da8c35e642ef4648808ddf0a52bc93425879088c706dfeaea2" dependencies = [ "gix-actor", "gix-features", @@ -955,9 +972,9 @@ dependencies = [ [[package]] name = "gix-refspec" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb005f82341ba67615ffdd9f7742c87787544441c88090878393d0682869ca6" +checksum = "0022038a09d80d9abf773be8efcbb502868d97f6972b8633bfb52ab6edaac442" dependencies = [ "bstr", "gix-hash", @@ -969,11 +986,12 @@ dependencies = [ [[package]] name = "gix-revision" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4621b219ac0cdb9256883030c3d56a6c64a6deaa829a92da73b9a576825e1e" +checksum = "4ee8eb4088fece3562af4a5d751e069f90e93345524ad730512185234c4b55f1" dependencies = [ "bstr", + "gix-commitgraph", "gix-date", "gix-hash", "gix-object", @@ -983,9 +1001,9 @@ dependencies = [ [[package]] name = "gix-revwalk" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41e72544b93084ee682ef3d5b31b1ba4d8fa27a017482900e5e044d5b1b3984" +checksum = "e6c9a9496da98d36ff19063a8576bf09a87425583b709a56dc5594fffa9d39b2" dependencies = [ "gix-commitgraph", "gix-date", @@ -998,9 +1016,9 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe4d52f30a737bbece5276fab5d3a8b276dc2650df963e293d0673be34e7a5f" +checksum = "a2007538eda296445c07949cf04f4a767307d887184d6b3e83e2d636533ddc6e" dependencies = [ "bitflags", "gix-path", @@ -1010,9 +1028,9 @@ dependencies = [ [[package]] name = "gix-status" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f70d35ba639f0c16a6e4cca81aa374a05f07b23fa36ee8beb72c100d98b4ffea" +checksum = "57414886e750161b4c86d8bca6b2d15bcc87f37ddc46684bb05cebbd29390543" dependencies = [ "bstr", "filetime", @@ -1033,9 +1051,9 @@ dependencies = [ [[package]] name = "gix-submodule" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529d0af78cc2f372b3218f15eb1e3d1635a21c8937c12e2dd0b6fc80c2ca874b" +checksum = "3ed099621873cd36c580fc822176a32a7e50fef15a5c2ed81aaa087296f0497a" dependencies = [ "bstr", "gix-config", @@ -1048,9 +1066,9 @@ dependencies = [ [[package]] name = "gix-tempfile" -version = "14.0.2" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046b4927969fa816a150a0cda2e62c80016fe11fb3c3184e4dddf4e542f108aa" +checksum = "2feb86ef094cc77a4a9a5afbfe5de626897351bbbd0de3cb9314baf3049adb82" dependencies = [ "dashmap", "gix-fs", @@ -1062,15 +1080,15 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cae0e8661c3ff92688ce1c8b8058b3efb312aba9492bbe93661a21705ab431b" +checksum = "04bdde120c29f1fc23a24d3e115aeeea3d60d8e65bab92cc5f9d90d9302eb952" [[package]] name = "gix-traverse" -version = "0.41.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030da39af94e4df35472e9318228f36530989327906f38e27807df305fccb780" +checksum = "f20f1b13cc4fa6ba92b24e6aa0c2fb6a34beb4458ef88c6300212db504e818df" dependencies = [ "bitflags", "gix-commitgraph", @@ -1085,23 +1103,22 @@ dependencies = [ [[package]] name = "gix-url" -version = "0.27.5" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd280c5e84fb22e128ed2a053a0daeacb6379469be6a85e3d518a0636e160c89" +checksum = "33e7c297c3265015c133a2c02199610b6e1373a09dc4be057d0c1b5285737f06" dependencies = [ "bstr", "gix-features", "gix-path", - "home", "thiserror", "url", ] [[package]] name = "gix-utils" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc" +checksum = "ba427e3e9599508ed98a6ddf8ed05493db114564e338e41f6a996d2e4790335f" dependencies = [ "bstr", "fastrand", @@ -1110,9 +1127,9 @@ dependencies = [ [[package]] name = "gix-validate" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f2badbb64e57b404593ee26b752c26991910fd0d81fe6f9a71c1a8309b6c86" +checksum = "e187b263461bc36cea17650141567753bc6207d036cedd1de6e81a52f277ff68" dependencies = [ "bstr", "thiserror", @@ -1120,9 +1137,9 @@ dependencies = [ [[package]] name = "gix-worktree" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c312ad76a3f2ba8e865b360d5cb3aa04660971d16dec6dd0ce717938d903149a" +checksum = "0d345e5b523550fe4fa0e912bf957de752011ccfc87451968fda1b624318f29c" dependencies = [ "bstr", "gix-attributes", @@ -1487,14 +1504,143 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -1609,9 +1755,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libloading" @@ -1640,6 +1786,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -1832,9 +1984,13 @@ dependencies = [ [[package]] name = "prodash" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" +checksum = "a266d8d6020c61a437be704c5e618037588e1985c7dbb7bf8d265db84cffe325" +dependencies = [ + "log", + "parking_lot", +] [[package]] name = "pulldown-cmark" @@ -1914,9 +2070,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1972,9 +2128,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags", "errno", @@ -2006,18 +2162,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -2167,6 +2323,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -2181,20 +2343,31 @@ checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -2252,6 +2425,16 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -2269,9 +2452,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -2360,12 +2543,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-bom" version = "2.0.3" @@ -2413,9 +2590,9 @@ checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", "idna", @@ -2423,6 +2600,18 @@ dependencies = [ "serde", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "version_check" version = "0.9.5" @@ -2715,6 +2904,18 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xtask" version = "24.7.0" @@ -2726,6 +2927,30 @@ dependencies = [ "toml", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -2745,3 +2970,46 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 4cd516268..db06f0081 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -39,7 +39,7 @@ bitflags = "2.6" ahash = "0.8.11" hashbrown = { version = "0.14.5", features = ["raw"] } dunce = "1.0" -url = "2.5.0" +url = "2.5.3" log = "0.4" serde = { version = "1.0", features = ["derive"] } diff --git a/helix-loader/Cargo.toml b/helix-loader/Cargo.toml index 26ab3f264..b87a9184a 100644 --- a/helix-loader/Cargo.toml +++ b/helix-loader/Cargo.toml @@ -30,7 +30,7 @@ log = "0.4" # cloning/compiling tree-sitter grammars cc = { version = "1" } threadpool = { version = "1.0" } -tempfile = "3.13.0" +tempfile = "3.14.0" dunce = "1.0.5" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/helix-lsp-types/Cargo.toml b/helix-lsp-types/Cargo.toml index bf2aeae12..b44e4c93a 100644 --- a/helix-lsp-types/Cargo.toml +++ b/helix-lsp-types/Cargo.toml @@ -22,10 +22,10 @@ license = "MIT" [dependencies] bitflags = "2.6.0" -serde = { version = "1.0.209", features = ["derive"] } +serde = { version = "1.0.215", features = ["derive"] } serde_json = "1.0.132" serde_repr = "0.1" -url = {version = "2.0.0", features = ["serde"]} +url = {version = "2.5.3", features = ["serde"]} [features] default = [] diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 1522ca340..5f22ede7b 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -26,7 +26,7 @@ globset = "0.4.15" log = "0.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.40", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } +tokio = { version = "1.41", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } tokio-stream = "0.1.15" parking_lot = "0.12.3" arc-swap = "1" diff --git a/helix-stdx/Cargo.toml b/helix-stdx/Cargo.toml index 25c0a164d..c4fbe5e78 100644 --- a/helix-stdx/Cargo.toml +++ b/helix-stdx/Cargo.toml @@ -26,4 +26,4 @@ windows-sys = { version = "0.59", features = ["Win32_Foundation", "Win32_Securit rustix = { version = "0.38", features = ["fs"] } [dev-dependencies] -tempfile = "3.13" +tempfile = "3.14" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index dc0e20b68..cd2cfe034 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -60,7 +60,7 @@ thiserror = "1.0" # opening URLs open = "5.3.0" -url = "2.5.2" +url = "2.5.3" # config toml = "0.8" @@ -74,7 +74,7 @@ grep-searcher = "0.1.14" [target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } -libc = "0.2.161" +libc = "0.2.162" [target.'cfg(target_os = "macos")'.dependencies] crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty", "libc"] } @@ -85,5 +85,5 @@ helix-loader = { path = "../helix-loader" } [dev-dependencies] smallvec = "1.13" indoc = "2.0.5" -tempfile = "3.13.0" +tempfile = "3.14.0" same-file = "1.0.1" diff --git a/helix-vcs/Cargo.toml b/helix-vcs/Cargo.toml index 43d5d619b..919df04ac 100644 --- a/helix-vcs/Cargo.toml +++ b/helix-vcs/Cargo.toml @@ -19,7 +19,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "p parking_lot = "0.12" arc-swap = { version = "1.7.1" } -gix = { version = "0.66.0", features = ["attributes", "status"], default-features = false, optional = true } +gix = { version = "0.67.0", features = ["attributes", "status"], default-features = false, optional = true } imara-diff = "0.1.7" anyhow = "1" @@ -29,4 +29,4 @@ log = "0.4" git = ["gix"] [dev-dependencies] -tempfile = "3.13" +tempfile = "3.14" diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 725a77547..6bbe15868 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -28,11 +28,11 @@ bitflags = "2.6" anyhow = "1" crossterm = { version = "0.28", optional = true } -tempfile = "3.13" +tempfile = "3.14" # Conversion traits once_cell = "1.20" -url = "2.5.2" +url = "2.5.3" arc-swap = { version = "1.7.1" } From 9806ca08b1adfd1a15426d90083f378f0a4bb270 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 30 Oct 2024 14:31:52 -0400 Subject: [PATCH 03/62] Fix breaking change in gix Tree::loop_entry_by_path --- helix-vcs/src/git.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-vcs/src/git.rs b/helix-vcs/src/git.rs index 48220f4df..189f6e22b 100644 --- a/helix-vcs/src/git.rs +++ b/helix-vcs/src/git.rs @@ -198,7 +198,7 @@ fn find_file_in_commit(repo: &Repository, commit: &Commit, file: &Path) -> Resul let rel_path = file.strip_prefix(repo_dir)?; let tree = commit.tree()?; let tree_entry = tree - .lookup_entry_by_path(rel_path, &mut Vec::new())? + .lookup_entry_by_path(rel_path)? .context("file is untracked")?; match tree_entry.mode().kind() { // not a file, everything is new, do not show diff From 6cca98264fe308bd6a4f7f85be2d821b58f60b4a Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Tue, 12 Nov 2024 09:28:55 -0500 Subject: [PATCH 04/62] Re-vendor encoding_rs test data This fixes a test (`helix_view::document::gb18030_decode`) since encoding_rs updated its gb18030 encoding to match GB18030-2022 (was GB18030-2005). The newly vendored files update the license line and I've included the referenced license in the `encoding/` directory. --- helix-view/tests/encoding/LICENSE-WHATWG | 26 +++++++++++++ helix-view/tests/encoding/big5_in.txt | 3 +- helix-view/tests/encoding/big5_in_ref.txt | 3 +- helix-view/tests/encoding/big5_out.txt | 3 +- helix-view/tests/encoding/big5_out_ref.txt | 3 +- helix-view/tests/encoding/euc_kr_in.txt | 3 +- helix-view/tests/encoding/euc_kr_in_ref.txt | 3 +- helix-view/tests/encoding/euc_kr_out.txt | 3 +- helix-view/tests/encoding/euc_kr_out_ref.txt | 3 +- helix-view/tests/encoding/gb18030_in.txt | 3 +- helix-view/tests/encoding/gb18030_in_ref.txt | 39 +++++++++---------- helix-view/tests/encoding/gb18030_out.txt | 39 +++++++++---------- helix-view/tests/encoding/gb18030_out_ref.txt | 3 +- helix-view/tests/encoding/iso_2022_jp_in.txt | 3 +- .../tests/encoding/iso_2022_jp_in_ref.txt | 3 +- helix-view/tests/encoding/iso_2022_jp_out.txt | 3 +- .../tests/encoding/iso_2022_jp_out_ref.txt | 3 +- helix-view/tests/encoding/jis0208_in.txt | 3 +- helix-view/tests/encoding/jis0208_in_ref.txt | 3 +- helix-view/tests/encoding/jis0208_out.txt | 3 +- helix-view/tests/encoding/jis0208_out_ref.txt | 3 +- helix-view/tests/encoding/jis0212_in.txt | 3 +- helix-view/tests/encoding/jis0212_in_ref.txt | 3 +- helix-view/tests/encoding/shift_jis_in.txt | 3 +- .../tests/encoding/shift_jis_in_ref.txt | 3 +- helix-view/tests/encoding/shift_jis_out.txt | 3 +- .../tests/encoding/shift_jis_out_ref.txt | 3 +- 27 files changed, 88 insertions(+), 88 deletions(-) create mode 100644 helix-view/tests/encoding/LICENSE-WHATWG diff --git a/helix-view/tests/encoding/LICENSE-WHATWG b/helix-view/tests/encoding/LICENSE-WHATWG new file mode 100644 index 000000000..f690e7196 --- /dev/null +++ b/helix-view/tests/encoding/LICENSE-WHATWG @@ -0,0 +1,26 @@ +Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/helix-view/tests/encoding/big5_in.txt b/helix-view/tests/encoding/big5_in.txt index 564f9f6a4..d5e1f9bc3 100644 --- a/helix-view/tests/encoding/big5_in.txt +++ b/helix-view/tests/encoding/big5_in.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/big5_in_ref.txt b/helix-view/tests/encoding/big5_in_ref.txt index 06eac7313..30f080b76 100644 --- a/helix-view/tests/encoding/big5_in_ref.txt +++ b/helix-view/tests/encoding/big5_in_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/big5_out.txt b/helix-view/tests/encoding/big5_out.txt index 142b833ce..403a07c11 100644 --- a/helix-view/tests/encoding/big5_out.txt +++ b/helix-view/tests/encoding/big5_out.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/big5_out_ref.txt b/helix-view/tests/encoding/big5_out_ref.txt index bf741afbb..ee853f21b 100644 --- a/helix-view/tests/encoding/big5_out_ref.txt +++ b/helix-view/tests/encoding/big5_out_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/euc_kr_in.txt b/helix-view/tests/encoding/euc_kr_in.txt index 88cb355a7..0f429e7b1 100644 --- a/helix-view/tests/encoding/euc_kr_in.txt +++ b/helix-view/tests/encoding/euc_kr_in.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/euc_kr_in_ref.txt b/helix-view/tests/encoding/euc_kr_in_ref.txt index 24867df2f..116e8593f 100644 --- a/helix-view/tests/encoding/euc_kr_in_ref.txt +++ b/helix-view/tests/encoding/euc_kr_in_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/euc_kr_out.txt b/helix-view/tests/encoding/euc_kr_out.txt index 9f30be6ed..3b023126a 100644 --- a/helix-view/tests/encoding/euc_kr_out.txt +++ b/helix-view/tests/encoding/euc_kr_out.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/euc_kr_out_ref.txt b/helix-view/tests/encoding/euc_kr_out_ref.txt index bd886e0df..a11cb3239 100644 --- a/helix-view/tests/encoding/euc_kr_out_ref.txt +++ b/helix-view/tests/encoding/euc_kr_out_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/gb18030_in.txt b/helix-view/tests/encoding/gb18030_in.txt index a5293a98e..2fb7d00e9 100644 --- a/helix-view/tests/encoding/gb18030_in.txt +++ b/helix-view/tests/encoding/gb18030_in.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/gb18030_in_ref.txt b/helix-view/tests/encoding/gb18030_in_ref.txt index bf9188dd0..30e684546 100644 --- a/helix-view/tests/encoding/gb18030_in_ref.txt +++ b/helix-view/tests/encoding/gb18030_in_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py @@ -7185,13 +7184,13 @@ Instead, please regenerate using generate-encoding-data.py χ ψ ω - - - - - - - +︐ +︒ +︑ +︓ +︔ +︕ +︖ ︵ ︶ ︹ @@ -7204,14 +7203,14 @@ Instead, please regenerate using generate-encoding-data.py ﹂ ﹃ ﹄ - - +︗ +︘ ︻ ︼ ︷ ︸ ︱ - +︙ ︳ ︴  @@ -23778,7 +23777,7 @@ Instead, please regenerate using generate-encoding-data.py 㑇 ⺈ ⺋ - +龴 㖞 㘚 㘎 @@ -23786,19 +23785,19 @@ Instead, please regenerate using generate-encoding-data.py ⺗ 㥮 㤘 - +龵 㧏 㧟 㩳 㧐 - - +龶 +龷 㭎 㱮 㳠 ⺧  - +龸 ⺪ 䁖 䅟 @@ -23815,7 +23814,7 @@ Instead, please regenerate using generate-encoding-data.py 䓖 䙡 䙌 - +龹 䜣 䜩 䝼 @@ -23832,7 +23831,7 @@ Instead, please regenerate using generate-encoding-data.py 䦛 䦷 䦶 - +龺  䲣 䲟 @@ -23848,7 +23847,7 @@ Instead, please regenerate using generate-encoding-data.py 䴘 䴙 䶮 - +龻    diff --git a/helix-view/tests/encoding/gb18030_out.txt b/helix-view/tests/encoding/gb18030_out.txt index 72d5e48e7..68264ca1b 100644 --- a/helix-view/tests/encoding/gb18030_out.txt +++ b/helix-view/tests/encoding/gb18030_out.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py @@ -7184,13 +7183,13 @@ Instead, please regenerate using generate-encoding-data.py χ ψ ω - - - - - - - +︐ +︒ +︑ +︓ +︔ +︕ +︖ ︵ ︶ ︹ @@ -7203,14 +7202,14 @@ Instead, please regenerate using generate-encoding-data.py ﹂ ﹃ ﹄ - - +︗ +︘ ︻ ︼ ︷ ︸ ︱ - +︙ ︳ ︴  @@ -23777,7 +23776,7 @@ Instead, please regenerate using generate-encoding-data.py 㑇 ⺈ ⺋ - +龴 㖞 㘚 㘎 @@ -23785,19 +23784,19 @@ Instead, please regenerate using generate-encoding-data.py ⺗ 㥮 㤘 - +龵 㧏 㧟 㩳 㧐 - - +龶 +龷 㭎 㱮 㳠 ⺧  - +龸 ⺪ 䁖 䅟 @@ -23814,7 +23813,7 @@ Instead, please regenerate using generate-encoding-data.py 䓖 䙡 䙌 - +龹 䜣 䜩 䝼 @@ -23831,7 +23830,7 @@ Instead, please regenerate using generate-encoding-data.py 䦛 䦷 䦶 - +龺  䲣 䲟 @@ -23847,7 +23846,7 @@ Instead, please regenerate using generate-encoding-data.py 䴘 䴙 䶮 - +龻    diff --git a/helix-view/tests/encoding/gb18030_out_ref.txt b/helix-view/tests/encoding/gb18030_out_ref.txt index eab1cf0fe..820e7cd94 100644 --- a/helix-view/tests/encoding/gb18030_out_ref.txt +++ b/helix-view/tests/encoding/gb18030_out_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/iso_2022_jp_in.txt b/helix-view/tests/encoding/iso_2022_jp_in.txt index 78d0beffa..58d3e52be 100644 --- a/helix-view/tests/encoding/iso_2022_jp_in.txt +++ b/helix-view/tests/encoding/iso_2022_jp_in.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/iso_2022_jp_in_ref.txt b/helix-view/tests/encoding/iso_2022_jp_in_ref.txt index ef1f74079..51cc69008 100644 --- a/helix-view/tests/encoding/iso_2022_jp_in_ref.txt +++ b/helix-view/tests/encoding/iso_2022_jp_in_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/iso_2022_jp_out.txt b/helix-view/tests/encoding/iso_2022_jp_out.txt index 577dc4d2b..73f9b6ff7 100644 --- a/helix-view/tests/encoding/iso_2022_jp_out.txt +++ b/helix-view/tests/encoding/iso_2022_jp_out.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/iso_2022_jp_out_ref.txt b/helix-view/tests/encoding/iso_2022_jp_out_ref.txt index e0685529f..fc6753b65 100644 --- a/helix-view/tests/encoding/iso_2022_jp_out_ref.txt +++ b/helix-view/tests/encoding/iso_2022_jp_out_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/jis0208_in.txt b/helix-view/tests/encoding/jis0208_in.txt index a38f7a4c1..c39b0503b 100644 --- a/helix-view/tests/encoding/jis0208_in.txt +++ b/helix-view/tests/encoding/jis0208_in.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/jis0208_in_ref.txt b/helix-view/tests/encoding/jis0208_in_ref.txt index ef1f74079..51cc69008 100644 --- a/helix-view/tests/encoding/jis0208_in_ref.txt +++ b/helix-view/tests/encoding/jis0208_in_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/jis0208_out.txt b/helix-view/tests/encoding/jis0208_out.txt index 76e346474..87727fc8c 100644 --- a/helix-view/tests/encoding/jis0208_out.txt +++ b/helix-view/tests/encoding/jis0208_out.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/jis0208_out_ref.txt b/helix-view/tests/encoding/jis0208_out_ref.txt index 42d167a8c..86ec39ce6 100644 --- a/helix-view/tests/encoding/jis0208_out_ref.txt +++ b/helix-view/tests/encoding/jis0208_out_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/jis0212_in.txt b/helix-view/tests/encoding/jis0212_in.txt index b144707b5..8ee54fc1e 100644 --- a/helix-view/tests/encoding/jis0212_in.txt +++ b/helix-view/tests/encoding/jis0212_in.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/jis0212_in_ref.txt b/helix-view/tests/encoding/jis0212_in_ref.txt index 09a72e28b..afbbf0901 100644 --- a/helix-view/tests/encoding/jis0212_in_ref.txt +++ b/helix-view/tests/encoding/jis0212_in_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/shift_jis_in.txt b/helix-view/tests/encoding/shift_jis_in.txt index cee6bb570..3b9d7c366 100644 --- a/helix-view/tests/encoding/shift_jis_in.txt +++ b/helix-view/tests/encoding/shift_jis_in.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/shift_jis_in_ref.txt b/helix-view/tests/encoding/shift_jis_in_ref.txt index 19ae14cb6..19570a3b7 100644 --- a/helix-view/tests/encoding/shift_jis_in_ref.txt +++ b/helix-view/tests/encoding/shift_jis_in_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/shift_jis_out.txt b/helix-view/tests/encoding/shift_jis_out.txt index 383584b0d..fd13adcab 100644 --- a/helix-view/tests/encoding/shift_jis_out.txt +++ b/helix-view/tests/encoding/shift_jis_out.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py diff --git a/helix-view/tests/encoding/shift_jis_out_ref.txt b/helix-view/tests/encoding/shift_jis_out_ref.txt index 25bce72ee..33c12d21b 100644 --- a/helix-view/tests/encoding/shift_jis_out_ref.txt +++ b/helix-view/tests/encoding/shift_jis_out_ref.txt @@ -1,5 +1,4 @@ -Any copyright to the test code below this comment is dedicated to the -Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ +Generated from WHATWG indexes.json; see LICENSE-WHATWG. This is a generated file. Please do not edit. Instead, please regenerate using generate-encoding-data.py From 35802cb025b7a833387ce5187c7977e535f7000d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:40:00 -0600 Subject: [PATCH 05/62] build(deps): bump which from 6.0.3 to 7.0.0 (#12090) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- helix-stdx/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86dace16c..4950fa43f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2691,9 +2691,9 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "which" -version = "6.0.3" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" +checksum = "c9cad3279ade7346b96e38731a641d7343dd6a53d55083dd54eadfa5a1b38c6b" dependencies = [ "either", "home", diff --git a/helix-stdx/Cargo.toml b/helix-stdx/Cargo.toml index c4fbe5e78..4e85adb5b 100644 --- a/helix-stdx/Cargo.toml +++ b/helix-stdx/Cargo.toml @@ -15,7 +15,7 @@ homepage.workspace = true dunce = "1.0" etcetera = "0.8" ropey = { version = "1.6.1", default-features = false } -which = "6.0" +which = "7.0" regex-cursor = "0.1.4" bitflags = "2.6" From f621423e7d7b81118cd23b907b69114451eb21eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:42:54 +0000 Subject: [PATCH 06/62] build(deps): bump thiserror from 1.0.64 to 2.0.3 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.64 to 2.0.3. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.64...2.0.3) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- Cargo.lock | 106 +++++++++++++++++++++++++----------------- Cargo.toml | 2 +- helix-term/Cargo.toml | 2 +- 3 files changed, 65 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4950fa43f..e175df776 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,7 +383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.69", "winapi", ] @@ -522,7 +522,7 @@ dependencies = [ "gix-worktree", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -535,7 +535,7 @@ dependencies = [ "gix-date", "gix-utils", "itoa", - "thiserror", + "thiserror 1.0.69", "winnow", ] @@ -552,7 +552,7 @@ dependencies = [ "gix-trace", "kstring", "smallvec", - "thiserror", + "thiserror 1.0.69", "unicode-bom", ] @@ -562,7 +562,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10f78312288bd02052be5dbc2ecbc342c9f4eb791986d86c0a5c06b92dc72efa" dependencies = [ - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -571,7 +571,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c28b58ba04f0c004722344390af9dbc85888fbb84be1981afb934da4114d4cf" dependencies = [ - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -597,7 +597,7 @@ dependencies = [ "gix-features", "gix-hash", "memmap2", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -616,7 +616,7 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.69", "unicode-bom", "winnow", ] @@ -631,7 +631,7 @@ dependencies = [ "bstr", "gix-path", "libc", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -643,7 +643,7 @@ dependencies = [ "bstr", "itoa", "jiff", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -664,7 +664,7 @@ dependencies = [ "gix-traverse", "gix-worktree", "imara-diff", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -684,7 +684,7 @@ dependencies = [ "gix-trace", "gix-utils", "gix-worktree", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -700,7 +700,7 @@ dependencies = [ "gix-path", "gix-ref", "gix-sec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -718,7 +718,7 @@ dependencies = [ "once_cell", "prodash", "sha1_smol", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -740,7 +740,7 @@ dependencies = [ "gix-trace", "gix-utils", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -773,7 +773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "952c3a29f1bc1007cc901abce7479943abfa42016db089de33d0a4fa3c85bfe8" dependencies = [ "faster-hex", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -825,7 +825,7 @@ dependencies = [ "memmap2", "rustix", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -836,7 +836,7 @@ checksum = "5102acdf4acae2644e38dbbd18cdfba9597a218f7d85f810fe5430207e03c2de" dependencies = [ "gix-tempfile", "gix-utils", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -855,7 +855,7 @@ dependencies = [ "gix-validate", "itoa", "smallvec", - "thiserror", + "thiserror 1.0.69", "winnow", ] @@ -877,7 +877,7 @@ dependencies = [ "gix-quote", "parking_lot", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -895,7 +895,7 @@ dependencies = [ "gix-path", "memmap2", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -907,7 +907,7 @@ dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -920,7 +920,7 @@ dependencies = [ "gix-trace", "home", "once_cell", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -935,7 +935,7 @@ dependencies = [ "gix-config-value", "gix-glob", "gix-path", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -946,7 +946,7 @@ checksum = "f89f9a1525dcfd9639e282ea939f5ab0d09d93cf2b90c1fc6104f1b9582a8e49" dependencies = [ "bstr", "gix-utils", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -966,7 +966,7 @@ dependencies = [ "gix-utils", "gix-validate", "memmap2", - "thiserror", + "thiserror 1.0.69", "winnow", ] @@ -981,7 +981,7 @@ dependencies = [ "gix-revision", "gix-validate", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -996,7 +996,7 @@ dependencies = [ "gix-hash", "gix-object", "gix-revwalk", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1011,7 +1011,7 @@ dependencies = [ "gix-hashtable", "gix-object", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1046,7 +1046,7 @@ dependencies = [ "gix-pathspec", "gix-worktree", "portable-atomic", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1061,7 +1061,7 @@ dependencies = [ "gix-pathspec", "gix-refspec", "gix-url", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1098,7 +1098,7 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1110,7 +1110,7 @@ dependencies = [ "bstr", "gix-features", "gix-path", - "thiserror", + "thiserror 1.0.69", "url", ] @@ -1132,7 +1132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e187b263461bc36cea17650141567753bc6207d036cedd1de6e81a52f277ff68" dependencies = [ "bstr", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1263,7 +1263,7 @@ dependencies = [ "log", "serde", "serde_json", - "thiserror", + "thiserror 2.0.3", "tokio", ] @@ -1319,7 +1319,7 @@ dependencies = [ "serde", "serde_json", "slotmap", - "thiserror", + "thiserror 2.0.3", "tokio", "tokio-stream", ] @@ -1392,7 +1392,7 @@ dependencies = [ "smallvec", "tempfile", "termini", - "thiserror", + "thiserror 2.0.3", "tokio", "tokio-stream", "toml", @@ -1459,7 +1459,7 @@ dependencies = [ "serde_json", "slotmap", "tempfile", - "thiserror", + "thiserror 2.0.3", "tokio", "tokio-stream", "toml", @@ -2398,18 +2398,38 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 763992480..b690267d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ package.helix-term.opt-level = 2 tree-sitter = { version = "0.22" } nucleo = "0.5.0" slotmap = "1.0.7" -thiserror = "1.0" +thiserror = "2.0" [workspace.package] version = "24.7.0" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index cd2cfe034..194e0811c 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -56,7 +56,7 @@ ignore = "0.4" pulldown-cmark = { version = "0.12", default-features = false } # file type detection content_inspector = "0.2.4" -thiserror = "1.0" +thiserror = "2.0" # opening URLs open = "5.3.0" From d489c03c4f9e5b6e7d72f8305245200ff8785191 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Mon, 18 Nov 2024 19:02:30 -0500 Subject: [PATCH 07/62] helix-term: Use workspace thiserror dep --- helix-term/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 194e0811c..db3bb644d 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -56,7 +56,7 @@ ignore = "0.4" pulldown-cmark = { version = "0.12", default-features = false } # file type detection content_inspector = "0.2.4" -thiserror = "2.0" +thiserror.workspace = true # opening URLs open = "5.3.0" From a219d5aabbdf214033f7992ed88233b016161fa8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:41:07 -0600 Subject: [PATCH 08/62] build(deps): bump unicode-general-category from 0.6.0 to 1.0.0 (#12089) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- helix-core/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e175df776..c4e05ff92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2571,9 +2571,9 @@ checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" [[package]] name = "unicode-general-category" -version = "0.6.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7" +checksum = "24adfe8311434967077a6adff125729161e6e4934d76f6b7c55318ac5c9246d3" [[package]] name = "unicode-ident" diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index db06f0081..d7f9d7206 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -29,7 +29,7 @@ unicode-segmentation = "1.12" # For now lets lock the version to avoid rendering glitches # when installing without `--locked` unicode-width = "=0.1.12" -unicode-general-category = "0.6" +unicode-general-category = "1.0" slotmap.workspace = true tree-sitter.workspace = true once_cell = "1.20" From f06f481ad9b61c6657d1512268bbaab6c8a2839c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:56:56 -0600 Subject: [PATCH 09/62] build(deps): bump the rust-dependencies group with 5 updates (#12088) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 20 ++++++++++---------- helix-lsp-types/Cargo.toml | 2 +- helix-term/Cargo.toml | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c4e05ff92..f4f03c797 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,9 +136,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.1.37" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "shlex", ] @@ -1755,9 +1755,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.162" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libloading" @@ -1911,9 +1911,9 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "open" -version = "5.3.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3" +checksum = "3ecd52f0b8d15c40ce4820aa251ed5de032e5d91fab27f7db2f40d42a8bdf69c" dependencies = [ "is-wsl", "libc", @@ -2128,9 +2128,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags", "errno", @@ -2182,9 +2182,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", diff --git a/helix-lsp-types/Cargo.toml b/helix-lsp-types/Cargo.toml index b44e4c93a..cb6b94307 100644 --- a/helix-lsp-types/Cargo.toml +++ b/helix-lsp-types/Cargo.toml @@ -23,7 +23,7 @@ license = "MIT" [dependencies] bitflags = "2.6.0" serde = { version = "1.0.215", features = ["derive"] } -serde_json = "1.0.132" +serde_json = "1.0.133" serde_repr = "0.1" url = {version = "2.5.3", features = ["serde"]} diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index db3bb644d..1c399a47c 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -59,7 +59,7 @@ content_inspector = "0.2.4" thiserror.workspace = true # opening URLs -open = "5.3.0" +open = "5.3.1" url = "2.5.3" # config @@ -74,7 +74,7 @@ grep-searcher = "0.1.14" [target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } -libc = "0.2.162" +libc = "0.2.164" [target.'cfg(target_os = "macos")'.dependencies] crossterm = { version = "0.28", features = ["event-stream", "use-dev-tty", "libc"] } From 6373027c9e97ba4b271e3f1f6ecd5733ff8ebd27 Mon Sep 17 00:00:00 2001 From: Oren Mittman Date: Wed, 20 Nov 2024 16:57:15 -0500 Subject: [PATCH 10/62] chore: add "ui.virtual.jump-label" to serika-dark theme (#11911) --- runtime/themes/serika-dark.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/themes/serika-dark.toml b/runtime/themes/serika-dark.toml index eb8d6c839..10ceacd15 100644 --- a/runtime/themes/serika-dark.toml +++ b/runtime/themes/serika-dark.toml @@ -53,6 +53,7 @@ "ui.virtual.whitespace" = "bg2" "ui.virtual.ruler" = { bg = "grey2" } "ui.virtual.inlay-hint" = { fg = "grey2", modifiers = ["italic"] } +"ui.virtual.jump-label" = { fg = "nasty-red", modifiers = ["bold"] } "hint" = "blue" "info" = "aqua" From 3fd7ca334eb53c2f452717c632ea36ce95191390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20D=C3=B6rner?= Date: Wed, 20 Nov 2024 22:57:30 +0100 Subject: [PATCH 11/62] Add support for textproto language. (#11874) --- book/src/generated/lang-support.md | 1 + languages.toml | 13 +++++++++++++ runtime/queries/textproto/highlights.scm | 22 ++++++++++++++++++++++ runtime/queries/textproto/indents.scm | 11 +++++++++++ runtime/queries/textproto/textobjects.scm | 12 ++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 runtime/queries/textproto/highlights.scm create mode 100644 runtime/queries/textproto/indents.scm create mode 100644 runtime/queries/textproto/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 09f15b374..9308bec88 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -204,6 +204,7 @@ | task | ✓ | | | | | tcl | ✓ | | ✓ | | | templ | ✓ | | | `templ` | +| textproto | ✓ | ✓ | ✓ | | | tfvars | ✓ | | ✓ | `terraform-ls` | | thrift | ✓ | | | | | todotxt | ✓ | | | | diff --git a/languages.toml b/languages.toml index f24c70d81..5ad48c0c8 100644 --- a/languages.toml +++ b/languages.toml @@ -344,6 +344,19 @@ indent = { tab-width = 2, unit = " " } name = "protobuf" source = { git = "https://github.com/yusdacra/tree-sitter-protobuf", rev = "19c211a01434d9f03efff99f85e19f967591b175"} +[[language]] +name = "textproto" +file-types = ["txtpb", "textpb", "textproto"] +comment-token = "#" +scope = "source.textproto" +indent = { tab-width = 2, unit = " " } +formatter = { command = "txtpbfmt" } +auto-format = true + +[[grammar]] +name = "textproto" +source = { git = "https://github.com/PorterAtGoogle/tree-sitter-textproto", rev = "568471b80fd8793d37ed01865d8c2208a9fefd1b"} + [[language]] name = "elixir" scope = "source.elixir" diff --git a/runtime/queries/textproto/highlights.scm b/runtime/queries/textproto/highlights.scm new file mode 100644 index 000000000..766897f44 --- /dev/null +++ b/runtime/queries/textproto/highlights.scm @@ -0,0 +1,22 @@ +(string) @string + +(field_name) @variable.other.member + +(comment) @comment + +(number) @constant.numeric +; covers e.g. booleans and "inf" +(scalar_value (identifier)) @constant +; Covers "-inf" +(scalar_value (signed_identifier)) @constant.numeric + +[ + (open_squiggly) + (close_squiggly) + (open_square) + (close_square) + (open_arrow) + (close_arrow) +] @punctuation.bracket + +"," @punctuation.delimiter diff --git a/runtime/queries/textproto/indents.scm b/runtime/queries/textproto/indents.scm new file mode 100644 index 000000000..ebea3ff39 --- /dev/null +++ b/runtime/queries/textproto/indents.scm @@ -0,0 +1,11 @@ +[ + (message_value) + (message_list) + (scalar_list) +] @indent + +[ + (close_arrow) + (close_square) + (close_squiggly) +] @outdent diff --git a/runtime/queries/textproto/textobjects.scm b/runtime/queries/textproto/textobjects.scm new file mode 100644 index 000000000..9cc428c6a --- /dev/null +++ b/runtime/queries/textproto/textobjects.scm @@ -0,0 +1,12 @@ +(message_field + (_) @entry.inside) @entry.around + +(scalar_field + (_) @entry.inside) @entry.around + +(message_list + (_) @entry.around) + +(scalar_list + (_) @entry.around) + From bc18dc2c0c0808db15dab059bbe50fa48b6227f7 Mon Sep 17 00:00:00 2001 From: stefanvi <60365750+stefanvi@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:57:42 +0100 Subject: [PATCH 12/62] Pluralize 'parenthesis' in the tutorial (#12015) --- runtime/tutor | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/tutor b/runtime/tutor index d24f83d5e..194a01f0d 100644 --- a/runtime/tutor +++ b/runtime/tutor @@ -1223,7 +1223,7 @@ letters! that is not good grammar. you can fix this. to the matching ). You can do the same on the line below: for example move to ], and press mm to jump to [ . - --> you can (jump between matching parenthesis) + --> you can (jump between matching parentheses) --> or between matching [ square brackets ] --> now { you know the drill: this works with brackets too } @@ -1238,19 +1238,19 @@ letters! that is not good grammar. you can fix this. pair of brackets or other delimiters. In the lines below: - move to the --> line, put your cursor in normal mode at any - location between the parenthesis, for example at 'x', and press - mi( or mi) to select the whole content inside the parenthesis - (parenthesis excluded). As usual, you can then do anything you want + location between the parentheses, for example at 'x', and press + mi( or mi) to select the whole content inside the parentheses + (parentheses excluded). As usual, you can then do anything you want with the selection (for example, press c to change it) - --> outside and (inside x parenthesis) - and outside again + --> outside and (inside x parentheses) - and outside again Test below that you can do the same with [], or {}, or with nested combinations of these (this will act on the immediately surrounding matching pair). This also works with "" and similar --> test [ with square brackets ] ! - --> try ( with nested [ pairs of ( parenthesis) and "brackets" ]) + --> try ( with nested [ pairs of ( parentheses) and "brackets" ]) ================================================================= = 12.3 USING MATCH MODE SELECT AROUND = @@ -1284,7 +1284,7 @@ letters! that is not good grammar. you can fix this. move in normal mode the cursor to the start of select, then enter selection mode with v , then select the 4 next words with 4e ), * ii) press ms( or ms) to surround the selection with a pair of - parenthesis. + parentheses. --> so, select all of this, and surround it with () @@ -1304,9 +1304,9 @@ letters! that is not good grammar. you can fix this. command. On the line below, move the cursor anywhere within the pair of (), for example to the 'x', then from there, in normal mode, press md( or md) to delete the surrounding - pair of parenthesis. + pair of parentheses. - --> delete (the x pair of parenthesis) from within! + --> delete (the x pair of parentheses) from within! You can naturally delete other kinds of surroundings: From 287e4127804f44ec087b07d49692a5e2876b25af Mon Sep 17 00:00:00 2001 From: Sam Kagan Date: Wed, 20 Nov 2024 14:58:00 -0700 Subject: [PATCH 13/62] docs(keymap): add select_all_children (#11972) Co-authored-by: Sam Kagan --- book/src/keymap.md | 73 +++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 71ae5e31f..eb4cc1356 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -112,42 +112,43 @@ Normal mode is the default mode when you launch helix. You can return to it from ### Selection manipulation -| Key | Description | Command | -| ----- | ----------- | ------- | -| `s` | Select all regex matches inside selections | `select_regex` | -| `S` | Split selection into sub selections on regex matches | `split_selection` | -| `Alt-s` | Split selection on newlines | `split_selection_on_newline` | -| `Alt-minus` | Merge selections | `merge_selections` | -| `Alt-_` | Merge consecutive selections | `merge_consecutive_selections` | -| `&` | Align selection in columns | `align_selections` | -| `_` | Trim whitespace from the selection | `trim_selections` | -| `;` | Collapse selection onto a single cursor | `collapse_selection` | -| `Alt-;` | Flip selection cursor and anchor | `flip_selections` | -| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` | -| `,` | Keep only the primary selection | `keep_primary_selection` | -| `Alt-,` | Remove the primary selection | `remove_primary_selection` | -| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` | -| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` | -| `(` | Rotate main selection backward | `rotate_selections_backward` | -| `)` | Rotate main selection forward | `rotate_selections_forward` | -| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` | -| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` | -| `%` | Select entire file | `select_all` | -| `x` | Select current line, if already selected, extend to next line | `extend_line_below` | -| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | -| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` | -| `J` | Join lines inside selection | `join_selections` | -| `Alt-J` | Join lines inside selection and select the inserted space | `join_selections_space` | -| `K` | Keep selections matching the regex | `keep_selections` | -| `Alt-K` | Remove selections matching the regex | `remove_selections` | -| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | -| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` | -| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` | -| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` | -| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` | -| `Alt-a` | Select all sibling nodes in syntax tree (**TS**) | `select_all_siblings` | -| `Alt-e` | Move to end of parent node in syntax tree (**TS**) | `move_parent_node_end` | -| `Alt-b` | Move to start of parent node in syntax tree (**TS**) | `move_parent_node_start` | +| Key | Description | Command | +| ----- | ----------- | ------- | +| `s` | Select all regex matches inside selections | `select_regex` | +| `S` | Split selection into sub selections on regex matches | `split_selection` | +| `Alt-s` | Split selection on newlines | `split_selection_on_newline` | +| `Alt-minus` | Merge selections | `merge_selections` | +| `Alt-_` | Merge consecutive selections | `merge_consecutive_selections` | +| `&` | Align selection in columns | `align_selections` | +| `_` | Trim whitespace from the selection | `trim_selections` | +| `;` | Collapse selection onto a single cursor | `collapse_selection` | +| `Alt-;` | Flip selection cursor and anchor | `flip_selections` | +| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` | +| `,` | Keep only the primary selection | `keep_primary_selection` | +| `Alt-,` | Remove the primary selection | `remove_primary_selection` | +| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` | +| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` | +| `(` | Rotate main selection backward | `rotate_selections_backward` | +| `)` | Rotate main selection forward | `rotate_selections_forward` | +| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` | +| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` | +| `%` | Select entire file | `select_all` | +| `x` | Select current line, if already selected, extend to next line | `extend_line_below` | +| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | +| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` | +| `J` | Join lines inside selection | `join_selections` | +| `Alt-J` | Join lines inside selection and select the inserted space | `join_selections_space` | +| `K` | Keep selections matching the regex | `keep_selections` | +| `Alt-K` | Remove selections matching the regex | `remove_selections` | +| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | +| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` | +| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` | +| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` | +| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` | +| `Alt-a` | Select all sibling nodes in syntax tree (**TS**) | `select_all_siblings` | +| `Alt-I`, `Alt-Shift-down`| Select all children nodes in syntax tree (**TS**) | `select_all_children` | +| `Alt-e` | Move to end of parent node in syntax tree (**TS**) | `move_parent_node_end` | +| `Alt-b` | Move to start of parent node in syntax tree (**TS**) | `move_parent_node_start` | ### Search From 23600e3ecb457cd85062a48a0d23961421ea764a Mon Sep 17 00:00:00 2001 From: Eduardo Rittner Coelho <116819854+eduardorittner@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:58:24 -0400 Subject: [PATCH 14/62] Add correct source file for TypableCommandList (#11839) Co-authored-by: Michael Davis --- book/src/remapping.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/book/src/remapping.md b/book/src/remapping.md index e3efdf16f..e794e1c27 100644 --- a/book/src/remapping.md +++ b/book/src/remapping.md @@ -83,10 +83,11 @@ There are three kinds of commands that can be used in keymaps: 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`. + at the invocation of `static_commands!` macro. * 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. + list of available typeable commands or the `TypableCommandList` declaration in + the source code at [`helix-term/src/commands/typed.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands/typed.rs). * 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 From 239262e094b4ab0ef3ee70a13154dce994aa191c Mon Sep 17 00:00:00 2001 From: Mark Stosberg Date: Wed, 20 Nov 2024 16:58:50 -0500 Subject: [PATCH 15/62] docs: Document what directory file_picker opens from (#10816) --- book/src/keymap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index eb4cc1356..28113ea0b 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -282,7 +282,7 @@ This layer is a kludge of mappings, mostly pickers. | Key | Description | Command | | ----- | ----------- | ------- | -| `f` | Open file picker | `file_picker` | +| `f` | Open file picker at LSP workspace root | `file_picker` | | `F` | Open file picker at current working directory | `file_picker_in_current_directory` | | `b` | Open buffer picker | `buffer_picker` | | `j` | Open jumplist picker | `jumplist_picker` | From 59b020ec91592f94647a8bab8a583c2418480d96 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 20 Nov 2024 16:02:10 -0600 Subject: [PATCH 16/62] Save an undo checkpoint before paste in insert mode (#8121) --- helix-term/src/commands.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ee2949fa0..073413989 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -4339,6 +4339,10 @@ fn paste_impl( return; } + if mode == Mode::Insert { + doc.append_changes_to_history(view); + } + let repeat = std::iter::repeat( // `values` is asserted to have at least one entry above. values From 48e15f77f7c3e5c48d754966784afabdb211c2ac Mon Sep 17 00:00:00 2001 From: Jaakko Paju Date: Thu, 21 Nov 2024 00:03:46 +0200 Subject: [PATCH 17/62] Add package.json and (and tsconfig.json) for TS/JS language config roots (#10652) * Add package.json and tsconfig.json for TS/JS language config roots * Add root to Javascript --- languages.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/languages.toml b/languages.toml index 5ad48c0c8..0661d9c3e 100644 --- a/languages.toml +++ b/languages.toml @@ -742,6 +742,7 @@ injection-regex = "(js|javascript)" language-id = "javascript" file-types = ["js", "mjs", "cjs", "rules", "es6", "pac", { glob = ".node_repl_history" }, { glob = "jakefile" }] shebangs = ["node"] +roots = [ "package.json" ] comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } language-servers = [ "typescript-language-server" ] @@ -769,6 +770,7 @@ scope = "source.jsx" injection-regex = "jsx" language-id = "javascriptreact" file-types = ["jsx"] +roots = [ "package.json" ] comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } language-servers = [ "typescript-language-server" ] @@ -782,6 +784,7 @@ injection-regex = "(ts|typescript)" language-id = "typescript" file-types = ["ts", "mts", "cts"] shebangs = ["deno", "bun", "ts-node"] +roots = [ "package.json", "tsconfig.json" ] comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } language-servers = [ "typescript-language-server" ] @@ -814,6 +817,7 @@ scope = "source.tsx" injection-regex = "(tsx)" # |typescript language-id = "typescriptreact" file-types = ["tsx"] +roots = [ "package.json", "tsconfig.json" ] comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } language-servers = [ "typescript-language-server" ] From b6e555a2ed383e88c0a6164c4015fbfed2cedec7 Mon Sep 17 00:00:00 2001 From: RoloEdits Date: Wed, 20 Nov 2024 14:04:43 -0800 Subject: [PATCH 18/62] feat(highlights): add `INVARIANT` to error tag (#12094) --- runtime/queries/comment/highlights.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/queries/comment/highlights.scm b/runtime/queries/comment/highlights.scm index e0916cece..8d1232453 100644 --- a/runtime/queries/comment/highlights.scm +++ b/runtime/queries/comment/highlights.scm @@ -21,10 +21,10 @@ ; Error level tags ((tag (name) @error) - (#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG)$")) + (#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG|INVARIANT)$")) ("text" @error - (#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG)$")) + (#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG|INVARIANT)$")) (tag (name) @ui.text From 68ee87695b371cf14a191c57684d687afe38eb4a Mon Sep 17 00:00:00 2001 From: Alfie Richards Date: Wed, 20 Nov 2024 22:06:23 +0000 Subject: [PATCH 19/62] Add clipboard provider configuration (#10839) --- book/src/editor.md | 24 + helix-term/src/commands/typed.rs | 2 +- helix-term/src/health.rs | 19 +- helix-view/src/clipboard.rs | 754 +++++++++++++++++-------------- helix-view/src/editor.rs | 9 +- helix-view/src/register.rs | 39 +- 6 files changed, 488 insertions(+), 359 deletions(-) diff --git a/book/src/editor.md b/book/src/editor.md index 82d5f8461..3edc38fc9 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -52,6 +52,30 @@ | `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid` | `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"` | `end-of-line-diagnostics` | Minimum severity of diagnostics to render at the end of the line. Set to `disable` to disable entirely. Refer to the setting about `inline-diagnostics` for more details | "disable" +| `clipboard-provider` | Which API to use for clipboard interaction. One of `pasteboard` (MacOS), `wayland`, `x-clip`, `x-sel`, `win-32-yank`, `termux`, `tmux`, `windows`, `termcode`, `none`, or a custom command set. | Platform and environment specific. | + +### `[editor.clipboard-provider]` Section + +Helix can be configured wither to use a builtin clipboard configuration or to use +a provided command. + +For instance, setting it to use OSC 52 termcodes, the configuration would be: +```toml +[editor] +clipboard-provider = "termcode" +``` + +Alternatively, Helix can be configured to use arbitary commands for clipboard integration: + +```toml +[editor.clipboard-provider.custom] +yank = { command = "cat", args = ["test.txt"] } +paste = { command = "tee", args = ["test.txt"] } +primary-yank = { command = "cat", args = ["test-primary.txt"] } # optional +primary-paste = { command = "tee", args = ["test-primary.txt"] } # optional +``` + +For custom commands the contents of the yank/paste is communicated over stdin/stdout. ### `[editor.statusline]` Section diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 68ba9bab5..7402a06f3 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1074,7 +1074,7 @@ fn show_clipboard_provider( } cx.editor - .set_status(cx.editor.registers.clipboard_provider_name().to_string()); + .set_status(cx.editor.registers.clipboard_provider_name()); Ok(()) } diff --git a/helix-term/src/health.rs b/helix-term/src/health.rs index 0bbb5735c..e59fd74dc 100644 --- a/helix-term/src/health.rs +++ b/helix-term/src/health.rs @@ -1,10 +1,10 @@ +use crate::config::{Config, ConfigLoadError}; use crossterm::{ style::{Color, Print, Stylize}, tty::IsTty, }; use helix_core::config::{default_lang_config, user_lang_config}; use helix_loader::grammar::load_runtime_file; -use helix_view::clipboard::get_clipboard_provider; use std::io::Write; #[derive(Copy, Clone)] @@ -53,7 +53,6 @@ pub fn general() -> std::io::Result<()> { let lang_file = helix_loader::lang_config_file(); let log_file = helix_loader::log_file(); let rt_dirs = helix_loader::runtime_dirs(); - let clipboard_provider = get_clipboard_provider(); if config_file.exists() { writeln!(stdout, "Config file: {}", config_file.display())?; @@ -92,7 +91,6 @@ pub fn general() -> std::io::Result<()> { writeln!(stdout, "{}", msg.yellow())?; } } - writeln!(stdout, "Clipboard provider: {}", clipboard_provider.name())?; Ok(()) } @@ -101,8 +99,19 @@ pub fn clipboard() -> std::io::Result<()> { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); - let board = get_clipboard_provider(); - match board.name().as_ref() { + let config = match Config::load_default() { + Ok(config) => config, + Err(ConfigLoadError::Error(err)) if err.kind() == std::io::ErrorKind::NotFound => { + Config::default() + } + Err(err) => { + writeln!(stdout, "{}", "Configuration file malformed".red())?; + writeln!(stdout, "{}", err)?; + return Ok(()); + } + }; + + match config.editor.clipboard_provider.name().as_ref() { "none" => { writeln!( stdout, diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index 379accc7e..234b91fe3 100644 --- a/helix-view/src/clipboard.rs +++ b/helix-view/src/clipboard.rs @@ -1,356 +1,224 @@ // Implementation reference: https://github.com/neovim/neovim/blob/f2906a4669a2eef6d7bf86a29648793d63c98949/runtime/autoload/provider/clipboard.vim#L68-L152 -use anyhow::Result; +use serde::{Deserialize, Serialize}; use std::borrow::Cow; +use thiserror::Error; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy)] pub enum ClipboardType { Clipboard, Selection, } -pub trait ClipboardProvider: std::fmt::Debug { - fn name(&self) -> Cow; - fn get_contents(&self, clipboard_type: ClipboardType) -> Result; - fn set_contents(&mut self, contents: String, clipboard_type: ClipboardType) -> Result<()>; +#[derive(Debug, Error)] +pub enum ClipboardError { + #[error(transparent)] + IoError(#[from] std::io::Error), + #[error("could not convert terminal output to UTF-8: {0}")] + FromUtf8Error(#[from] std::string::FromUtf8Error), + #[cfg(windows)] + #[error("Windows API error: {0}")] + WinAPI(#[from] clipboard_win::ErrorCode), + #[error("clipboard provider command failed")] + CommandFailed, + #[error("failed to write to clipboard provider's stdin")] + StdinWriteFailed, + #[error("clipboard provider did not return any contents")] + MissingStdout, + #[error("This clipboard provider does not support reading")] + ReadingNotSupported, } -#[cfg(not(windows))] -macro_rules! command_provider { - (paste => $get_prg:literal $( , $get_arg:literal )* ; copy => $set_prg:literal $( , $set_arg:literal )* ; ) => {{ - log::debug!( - "Using {} to interact with the system clipboard", - if $set_prg != $get_prg { format!("{}+{}", $set_prg, $get_prg)} else { $set_prg.to_string() } - ); - Box::new(provider::command::Provider { - get_cmd: provider::command::Config { - prg: $get_prg, - args: &[ $( $get_arg ),* ], - }, - set_cmd: provider::command::Config { - prg: $set_prg, - args: &[ $( $set_arg ),* ], - }, - get_primary_cmd: None, - set_primary_cmd: None, - }) - }}; - - (paste => $get_prg:literal $( , $get_arg:literal )* ; - copy => $set_prg:literal $( , $set_arg:literal )* ; - primary_paste => $pr_get_prg:literal $( , $pr_get_arg:literal )* ; - primary_copy => $pr_set_prg:literal $( , $pr_set_arg:literal )* ; - ) => {{ - log::debug!( - "Using {} to interact with the system and selection (primary) clipboard", - if $set_prg != $get_prg { format!("{}+{}", $set_prg, $get_prg)} else { $set_prg.to_string() } - ); - Box::new(provider::command::Provider { - get_cmd: provider::command::Config { - prg: $get_prg, - args: &[ $( $get_arg ),* ], - }, - set_cmd: provider::command::Config { - prg: $set_prg, - args: &[ $( $set_arg ),* ], - }, - get_primary_cmd: Some(provider::command::Config { - prg: $pr_get_prg, - args: &[ $( $pr_get_arg ),* ], - }), - set_primary_cmd: Some(provider::command::Config { - prg: $pr_set_prg, - args: &[ $( $pr_set_arg ),* ], - }), - }) - }}; -} - -#[cfg(windows)] -pub fn get_clipboard_provider() -> Box { - Box::::default() -} - -#[cfg(target_os = "macos")] -pub fn get_clipboard_provider() -> Box { - use helix_stdx::env::{binary_exists, env_var_is_set}; - - if env_var_is_set("TMUX") && binary_exists("tmux") { - command_provider! { - paste => "tmux", "save-buffer", "-"; - copy => "tmux", "load-buffer", "-w", "-"; - } - } else if binary_exists("pbcopy") && binary_exists("pbpaste") { - command_provider! { - paste => "pbpaste"; - copy => "pbcopy"; - } - } else { - Box::new(provider::FallbackProvider::new()) - } -} +type Result = std::result::Result; +#[cfg(not(target_arch = "wasm32"))] +pub use external::ClipboardProvider; #[cfg(target_arch = "wasm32")] -pub fn get_clipboard_provider() -> Box { - // TODO: - Box::new(provider::FallbackProvider::new()) -} +pub use noop::ClipboardProvider; -#[cfg(not(any(windows, target_arch = "wasm32", target_os = "macos")))] -pub fn get_clipboard_provider() -> Box { - use helix_stdx::env::{binary_exists, env_var_is_set}; - use provider::command::is_exit_success; - // TODO: support for user-defined provider, probably when we have plugin support by setting a - // variable? - - if env_var_is_set("WAYLAND_DISPLAY") && binary_exists("wl-copy") && binary_exists("wl-paste") { - command_provider! { - paste => "wl-paste", "--no-newline"; - copy => "wl-copy", "--type", "text/plain"; - primary_paste => "wl-paste", "-p", "--no-newline"; - primary_copy => "wl-copy", "-p", "--type", "text/plain"; - } - } else if env_var_is_set("DISPLAY") && binary_exists("xclip") { - command_provider! { - paste => "xclip", "-o", "-selection", "clipboard"; - copy => "xclip", "-i", "-selection", "clipboard"; - primary_paste => "xclip", "-o"; - primary_copy => "xclip", "-i"; - } - } else if env_var_is_set("DISPLAY") - && binary_exists("xsel") - && is_exit_success("xsel", &["-o", "-b"]) - { - // FIXME: check performance of is_exit_success - command_provider! { - paste => "xsel", "-o", "-b"; - copy => "xsel", "-i", "-b"; - primary_paste => "xsel", "-o"; - primary_copy => "xsel", "-i"; - } - } else if binary_exists("win32yank.exe") { - command_provider! { - paste => "win32yank.exe", "-o", "--lf"; - copy => "win32yank.exe", "-i", "--crlf"; - } - } else if binary_exists("termux-clipboard-set") && binary_exists("termux-clipboard-get") { - command_provider! { - paste => "termux-clipboard-get"; - copy => "termux-clipboard-set"; - } - } else if env_var_is_set("TMUX") && binary_exists("tmux") { - command_provider! { - paste => "tmux", "save-buffer", "-"; - copy => "tmux", "load-buffer", "-w", "-"; - } - } else { - Box::new(provider::FallbackProvider::new()) - } -} +// Clipboard not supported for wasm +#[cfg(target_arch = "wasm32")] +mod noop { + use super::*; -#[cfg(not(target_os = "windows"))] -pub mod provider { - use super::{ClipboardProvider, ClipboardType}; - use anyhow::Result; - use std::borrow::Cow; + #[derive(Debug, Clone)] + pub enum ClipboardProvider {} - #[cfg(feature = "term")] - mod osc52 { - use {super::ClipboardType, crate::base64}; + impl ClipboardProvider { + pub fn detect() -> Self { + Self + } - #[derive(Debug)] - pub struct SetClipboardCommand { - encoded_content: String, - clipboard_type: ClipboardType, + pub fn name(&self) -> Cow { + "none".into() } - impl SetClipboardCommand { - pub fn new(content: &str, clipboard_type: ClipboardType) -> Self { - Self { - encoded_content: base64::encode(content.as_bytes()), - clipboard_type, - } - } + pub fn get_contents(&self, _clipboard_type: ClipboardType) -> Result { + Err(ClipboardError::ReadingNotSupported) } - impl crossterm::Command for SetClipboardCommand { - fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result { - let kind = match &self.clipboard_type { - ClipboardType::Clipboard => "c", - ClipboardType::Selection => "p", - }; - // Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/ - write!(f, "\x1b]52;{};{}\x1b\\", kind, &self.encoded_content) - } + pub fn set_contents(&self, _content: &str, _clipboard_type: ClipboardType) -> Result<()> { + Ok(()) } } +} - #[derive(Debug)] - pub struct FallbackProvider { - buf: String, - primary_buf: String, - } +#[cfg(not(target_arch = "wasm32"))] +mod external { + use super::*; - impl FallbackProvider { - pub fn new() -> Self { - #[cfg(feature = "term")] - log::debug!( - "No native clipboard provider found. Yanking by OSC 52 and pasting will be internal to Helix" - ); - #[cfg(not(feature = "term"))] - log::warn!( - "No native clipboard provider found! Yanking and pasting will be internal to Helix" - ); - Self { - buf: String::new(), - primary_buf: String::new(), - } - } + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] + pub struct Command { + command: Cow<'static, str>, + #[serde(default)] + args: Cow<'static, [Cow<'static, str>]>, } - impl Default for FallbackProvider { - fn default() -> Self { - Self::new() - } + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] + #[serde(rename_all = "kebab-case")] + pub struct CommandProvider { + yank: Command, + paste: Command, + yank_primary: Option, + paste_primary: Option, } - impl ClipboardProvider for FallbackProvider { + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] + #[serde(rename_all = "kebab-case")] + #[allow(clippy::large_enum_variant)] + pub enum ClipboardProvider { + Pasteboard, + Wayland, + XClip, + XSel, + Win32Yank, + Tmux, + #[cfg(windows)] + Windows, + Termux, #[cfg(feature = "term")] - fn name(&self) -> Cow { - Cow::Borrowed("termcode") - } - - #[cfg(not(feature = "term"))] - fn name(&self) -> Cow { - Cow::Borrowed("none") - } + Termcode, + Custom(CommandProvider), + None, + } - fn get_contents(&self, clipboard_type: ClipboardType) -> Result { - // This is the same noop if term is enabled or not. - // We don't use the get side of OSC 52 as it isn't often enabled, it's a security hole, - // and it would require this to be async to listen for the response - let value = match clipboard_type { - ClipboardType::Clipboard => self.buf.clone(), - ClipboardType::Selection => self.primary_buf.clone(), - }; + impl Default for ClipboardProvider { + #[cfg(windows)] + fn default() -> Self { + use helix_stdx::env::binary_exists; - Ok(value) + if binary_exists("win32yank.exe") { + Self::Win32Yank + } else { + Self::Windows + } } - fn set_contents(&mut self, content: String, clipboard_type: ClipboardType) -> Result<()> { - #[cfg(feature = "term")] - crossterm::execute!( - std::io::stdout(), - osc52::SetClipboardCommand::new(&content, clipboard_type) - )?; - // Set our internal variables to use in get_content regardless of using OSC 52 - match clipboard_type { - ClipboardType::Clipboard => self.buf = content, - ClipboardType::Selection => self.primary_buf = content, + #[cfg(target_os = "macos")] + fn default() -> Self { + use helix_stdx::env::{binary_exists, env_var_is_set}; + + if env_var_is_set("TMUX") && binary_exists("tmux") { + Self::Tmux + } else if binary_exists("pbcopy") && binary_exists("pbpaste") { + Self::Pasteboard + } else if cfg!(feature = "term") { + Self::Termcode + } else { + Self::None } - Ok(()) } - } - - #[cfg(not(target_arch = "wasm32"))] - pub mod command { - use super::*; - use anyhow::{bail, Context as _}; #[cfg(not(any(windows, target_os = "macos")))] - pub fn is_exit_success(program: &str, args: &[&str]) -> bool { - std::process::Command::new(program) - .args(args) - .output() - .ok() - .and_then(|out| out.status.success().then_some(())) - .is_some() - } + fn default() -> Self { + use helix_stdx::env::{binary_exists, env_var_is_set}; + + fn is_exit_success(program: &str, args: &[&str]) -> bool { + std::process::Command::new(program) + .args(args) + .output() + .ok() + .and_then(|out| out.status.success().then_some(())) + .is_some() + } - #[derive(Debug)] - pub struct Config { - pub prg: &'static str, - pub args: &'static [&'static str], + if env_var_is_set("WAYLAND_DISPLAY") + && binary_exists("wl-copy") + && binary_exists("wl-paste") + { + Self::Wayland + } else if env_var_is_set("DISPLAY") && binary_exists("xclip") { + Self::XClip + } else if env_var_is_set("DISPLAY") + && binary_exists("xsel") + // FIXME: check performance of is_exit_success + && is_exit_success("xsel", &["-o", "-b"]) + { + Self::XSel + } else if binary_exists("termux-clipboard-set") && binary_exists("termux-clipboard-get") + { + Self::Termux + } else if env_var_is_set("TMUX") && binary_exists("tmux") { + Self::Tmux + } else if binary_exists("win32yank.exe") { + Self::Win32Yank + } else if cfg!(feature = "term") { + Self::Termcode + } else { + Self::None + } } + } - impl Config { - fn execute(&self, input: Option<&str>, pipe_output: bool) -> Result> { - use std::io::Write; - use std::process::{Command, Stdio}; - - let stdin = input.map(|_| Stdio::piped()).unwrap_or_else(Stdio::null); - let stdout = pipe_output.then(Stdio::piped).unwrap_or_else(Stdio::null); - - let mut command: Command = Command::new(self.prg); - - let mut command_mut: &mut Command = command - .args(self.args) - .stdin(stdin) - .stdout(stdout) - .stderr(Stdio::null()); - - // Fix for https://github.com/helix-editor/helix/issues/5424 - if cfg!(unix) { - use std::os::unix::process::CommandExt; - - unsafe { - command_mut = command_mut.pre_exec(|| match libc::setsid() { - -1 => Err(std::io::Error::last_os_error()), - _ => Ok(()), - }); - } - } - - let mut child = command_mut.spawn()?; - - if let Some(input) = input { - let mut stdin = child.stdin.take().context("stdin is missing")?; - stdin - .write_all(input.as_bytes()) - .context("couldn't write in stdin")?; - } - - // TODO: add timer? - let output = child.wait_with_output()?; - - if !output.status.success() { - bail!("clipboard provider {} failed", self.prg); - } - - if pipe_output { - Ok(Some(String::from_utf8(output.stdout)?)) + impl ClipboardProvider { + pub fn name(&self) -> Cow<'_, str> { + fn builtin_name<'a>( + name: &'static str, + provider: &'static CommandProvider, + ) -> Cow<'a, str> { + if provider.yank.command != provider.paste.command { + Cow::Owned(format!( + "{} ({}+{})", + name, provider.yank.command, provider.paste.command + )) } else { - Ok(None) + Cow::Owned(format!("{} ({})", name, provider.yank.command)) } } - } - - #[derive(Debug)] - pub struct Provider { - pub get_cmd: Config, - pub set_cmd: Config, - pub get_primary_cmd: Option, - pub set_primary_cmd: Option, - } - impl ClipboardProvider for Provider { - fn name(&self) -> Cow { - if self.get_cmd.prg != self.set_cmd.prg { - Cow::Owned(format!("{}+{}", self.get_cmd.prg, self.set_cmd.prg)) - } else { - Cow::Borrowed(self.get_cmd.prg) - } + match self { + // These names should match the config option names from Serde + Self::Pasteboard => builtin_name("pasteboard", &PASTEBOARD), + Self::Wayland => builtin_name("wayland", &WL_CLIPBOARD), + Self::XClip => builtin_name("x-clip", &WL_CLIPBOARD), + Self::XSel => builtin_name("x-sel", &WL_CLIPBOARD), + Self::Win32Yank => builtin_name("win-32-yank", &WL_CLIPBOARD), + Self::Tmux => builtin_name("tmux", &TMUX), + Self::Termux => builtin_name("termux", &TERMUX), + #[cfg(windows)] + Self::Windows => "windows".into(), + #[cfg(feature = "term")] + Self::Termcode => "termcode".into(), + Self::Custom(command_provider) => Cow::Owned(format!( + "custom ({}+{})", + command_provider.yank.command, command_provider.paste.command + )), + Self::None => "none".into(), } + } - fn get_contents(&self, clipboard_type: ClipboardType) -> Result { + pub fn get_contents(&self, clipboard_type: &ClipboardType) -> Result { + fn yank_from_builtin( + provider: CommandProvider, + clipboard_type: &ClipboardType, + ) -> Result { match clipboard_type { - ClipboardType::Clipboard => Ok(self - .get_cmd - .execute(None, true)? - .context("output is missing")?), + ClipboardType::Clipboard => execute_command(&provider.yank, None, true)? + .ok_or(ClipboardError::MissingStdout), ClipboardType::Selection => { - if let Some(cmd) = &self.get_primary_cmd { - return cmd.execute(None, true)?.context("output is missing"); + if let Some(cmd) = provider.yank_primary.as_ref() { + return execute_command(cmd, None, true)? + .ok_or(ClipboardError::MissingStdout); } Ok(String::new()) @@ -358,56 +226,274 @@ pub mod provider { } } - fn set_contents(&mut self, value: String, clipboard_type: ClipboardType) -> Result<()> { + match self { + Self::Pasteboard => yank_from_builtin(PASTEBOARD, clipboard_type), + Self::Wayland => yank_from_builtin(WL_CLIPBOARD, clipboard_type), + Self::XClip => yank_from_builtin(XCLIP, clipboard_type), + Self::XSel => yank_from_builtin(XSEL, clipboard_type), + Self::Win32Yank => yank_from_builtin(WIN32, clipboard_type), + Self::Tmux => yank_from_builtin(TMUX, clipboard_type), + Self::Termux => yank_from_builtin(TERMUX, clipboard_type), + #[cfg(target_os = "windows")] + Self::Windows => match clipboard_type { + ClipboardType::Clipboard => { + let contents = + clipboard_win::get_clipboard(clipboard_win::formats::Unicode)?; + Ok(contents) + } + ClipboardType::Selection => Ok(String::new()), + }, + #[cfg(feature = "term")] + Self::Termcode => Err(ClipboardError::ReadingNotSupported), + Self::Custom(command_provider) => { + execute_command(&command_provider.yank, None, true)? + .ok_or(ClipboardError::MissingStdout) + } + Self::None => Err(ClipboardError::ReadingNotSupported), + } + } + + pub fn set_contents(&self, content: &str, clipboard_type: ClipboardType) -> Result<()> { + fn paste_to_builtin( + provider: CommandProvider, + content: &str, + clipboard_type: ClipboardType, + ) -> Result<()> { let cmd = match clipboard_type { - ClipboardType::Clipboard => &self.set_cmd, + ClipboardType::Clipboard => &provider.paste, ClipboardType::Selection => { - if let Some(cmd) = &self.set_primary_cmd { + if let Some(cmd) = provider.paste_primary.as_ref() { cmd } else { return Ok(()); } } }; - cmd.execute(Some(&value), false).map(|_| ()) + + execute_command(cmd, Some(content), false).map(|_| ()) + } + + match self { + Self::Pasteboard => paste_to_builtin(PASTEBOARD, content, clipboard_type), + Self::Wayland => paste_to_builtin(WL_CLIPBOARD, content, clipboard_type), + Self::XClip => paste_to_builtin(XCLIP, content, clipboard_type), + Self::XSel => paste_to_builtin(XSEL, content, clipboard_type), + Self::Win32Yank => paste_to_builtin(WIN32, content, clipboard_type), + Self::Tmux => paste_to_builtin(TMUX, content, clipboard_type), + Self::Termux => paste_to_builtin(TERMUX, content, clipboard_type), + #[cfg(target_os = "windows")] + Self::Windows => match clipboard_type { + ClipboardType::Clipboard => { + clipboard_win::set_clipboard(clipboard_win::formats::Unicode, content)?; + Ok(()) + } + ClipboardType::Selection => Ok(()), + }, + #[cfg(feature = "term")] + Self::Termcode => { + crossterm::queue!( + std::io::stdout(), + osc52::SetClipboardCommand::new(content, clipboard_type) + )?; + Ok(()) + } + Self::Custom(command_provider) => match clipboard_type { + ClipboardType::Clipboard => { + execute_command(&command_provider.paste, Some(content), false).map(|_| ()) + } + ClipboardType::Selection => { + if let Some(cmd) = &command_provider.paste_primary { + execute_command(cmd, Some(content), false).map(|_| ()) + } else { + Ok(()) + } + } + }, + Self::None => Ok(()), } } } -} -#[cfg(target_os = "windows")] -mod provider { - use super::{ClipboardProvider, ClipboardType}; - use anyhow::Result; - use std::borrow::Cow; + macro_rules! command_provider { + ($name:ident, + yank => $yank_cmd:literal $( , $yank_arg:literal )* ; + paste => $paste_cmd:literal $( , $paste_arg:literal )* ; ) => { + const $name: CommandProvider = CommandProvider { + yank: Command { + command: Cow::Borrowed($yank_cmd), + args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_arg) ),* ]) + }, + paste: Command { + command: Cow::Borrowed($paste_cmd), + args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_arg) ),* ]) + }, + yank_primary: None, + paste_primary: None, + }; + }; + ($name:ident, + yank => $yank_cmd:literal $( , $yank_arg:literal )* ; + paste => $paste_cmd:literal $( , $paste_arg:literal )* ; + yank_primary => $yank_primary_cmd:literal $( , $yank_primary_arg:literal )* ; + paste_primary => $paste_primary_cmd:literal $( , $paste_primary_arg:literal )* ; ) => { + const $name: CommandProvider = CommandProvider { + yank: Command { + command: Cow::Borrowed($yank_cmd), + args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_arg) ),* ]) + }, + paste: Command { + command: Cow::Borrowed($paste_cmd), + args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_arg) ),* ]) + }, + yank_primary: Some(Command { + command: Cow::Borrowed($yank_primary_cmd), + args: Cow::Borrowed(&[ $( Cow::Borrowed($yank_primary_arg) ),* ]) + }), + paste_primary: Some(Command { + command: Cow::Borrowed($paste_primary_cmd), + args: Cow::Borrowed(&[ $( Cow::Borrowed($paste_primary_arg) ),* ]) + }), + }; + }; + } - #[derive(Default, Debug)] - pub struct WindowsProvider; + command_provider! { + TMUX, + yank => "tmux", "load-buffer", "-w", "-"; + paste => "tmux", "save-buffer", "-"; + } + command_provider! { + PASTEBOARD, + yank => "pbcopy"; + paste => "pbpaste"; + } + command_provider! { + WL_CLIPBOARD, + yank => "wl-copy", "--type", "text/plain"; + paste => "wl-paste", "--no-newline"; + yank_primary => "wl-copy", "-p", "--type", "text/plain"; + paste_primary => "wl-paste", "-p", "--no-newline"; + } + command_provider! { + XCLIP, + yank => "xclip", "-i", "-selection", "clipboard"; + paste => "xclip", "-o", "-selection", "clipboard"; + yank_primary => "xclip", "-i"; + paste_primary => "xclip", "-o"; + } + command_provider! { + XSEL, + yank => "xsel", "-i", "-b"; + paste => "xsel", "-o", "-b"; + yank_primary => "xsel", "-i"; + paste_primary => "xsel", "-o"; + } + command_provider! { + WIN32, + yank => "win32yank.exe", "-i", "--crlf"; + paste => "win32yank.exe", "-o", "--lf"; + } + command_provider! { + TERMUX, + yank => "termux-clipboard-set"; + paste => "termux-clipboard-get"; + } - impl ClipboardProvider for WindowsProvider { - fn name(&self) -> Cow { - log::debug!("Using clipboard-win to interact with the system clipboard"); - Cow::Borrowed("clipboard-win") + #[cfg(feature = "term")] + mod osc52 { + use {super::ClipboardType, crate::base64}; + + pub struct SetClipboardCommand { + encoded_content: String, + clipboard_type: ClipboardType, } - fn get_contents(&self, clipboard_type: ClipboardType) -> Result { - match clipboard_type { - ClipboardType::Clipboard => { - let contents = clipboard_win::get_clipboard(clipboard_win::formats::Unicode)?; - Ok(contents) + impl SetClipboardCommand { + pub fn new(content: &str, clipboard_type: ClipboardType) -> Self { + Self { + encoded_content: base64::encode(content.as_bytes()), + clipboard_type, } - ClipboardType::Selection => Ok(String::new()), } } - fn set_contents(&mut self, contents: String, clipboard_type: ClipboardType) -> Result<()> { - match clipboard_type { - ClipboardType::Clipboard => { - clipboard_win::set_clipboard(clipboard_win::formats::Unicode, contents)?; - } - ClipboardType::Selection => {} - }; - Ok(()) + impl crossterm::Command for SetClipboardCommand { + fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result { + let kind = match &self.clipboard_type { + ClipboardType::Clipboard => "c", + ClipboardType::Selection => "p", + }; + // Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/ + write!(f, "\x1b]52;{};{}\x1b\\", kind, &self.encoded_content) + } + #[cfg(windows)] + fn execute_winapi(&self) -> std::result::Result<(), std::io::Error> { + Err(std::io::Error::new( + std::io::ErrorKind::Other, + "OSC clipboard codes not supported by winapi.", + )) + } + } + } + + fn execute_command( + cmd: &Command, + input: Option<&str>, + pipe_output: bool, + ) -> Result> { + use std::io::Write; + use std::process::{Command, Stdio}; + + let stdin = input.map(|_| Stdio::piped()).unwrap_or_else(Stdio::null); + let stdout = pipe_output.then(Stdio::piped).unwrap_or_else(Stdio::null); + + let mut command: Command = Command::new(cmd.command.as_ref()); + + #[allow(unused_mut)] + let mut command_mut: &mut Command = command + .args(cmd.args.iter().map(AsRef::as_ref)) + .stdin(stdin) + .stdout(stdout) + .stderr(Stdio::null()); + + // Fix for https://github.com/helix-editor/helix/issues/5424 + #[cfg(unix)] + { + use std::os::unix::process::CommandExt; + + unsafe { + command_mut = command_mut.pre_exec(|| match libc::setsid() { + -1 => Err(std::io::Error::last_os_error()), + _ => Ok(()), + }); + } + } + + let mut child = command_mut.spawn()?; + + if let Some(input) = input { + let mut stdin = child.stdin.take().ok_or(ClipboardError::StdinWriteFailed)?; + stdin + .write_all(input.as_bytes()) + .map_err(|_| ClipboardError::StdinWriteFailed)?; + } + + // TODO: add timer? + let output = child.wait_with_output()?; + + if !output.status.success() { + log::error!( + "clipboard provider {} failed with stderr: \"{}\"", + cmd.command, + String::from_utf8_lossy(&output.stderr) + ); + return Err(ClipboardError::CommandFailed); + } + + if pipe_output { + Ok(Some(String::from_utf8(output.stdout)?)) + } else { + Ok(None) } } } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 26dea3a21..48d3bc365 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1,5 +1,6 @@ use crate::{ annotations::diagnostics::{DiagnosticFilter, InlineDiagnosticsConfig}, + clipboard::ClipboardProvider, document::{ DocumentOpenError, DocumentSavedEventFuture, DocumentSavedEventResult, Mode, SavePoint, }, @@ -345,6 +346,8 @@ pub struct Config { /// Display diagnostic below the line they occur. pub inline_diagnostics: InlineDiagnosticsConfig, pub end_of_line_diagnostics: DiagnosticFilter, + // Set to override the default clipboard provider + pub clipboard_provider: ClipboardProvider, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)] @@ -982,6 +985,7 @@ impl Default for Config { jump_label_alphabet: ('a'..='z').collect(), inline_diagnostics: InlineDiagnosticsConfig::default(), end_of_line_diagnostics: DiagnosticFilter::Disable, + clipboard_provider: ClipboardProvider::default(), } } } @@ -1183,7 +1187,10 @@ impl Editor { theme_loader, last_theme: None, last_selection: None, - registers: Registers::default(), + registers: Registers::new(Box::new(arc_swap::access::Map::new( + Arc::clone(&config), + |config: &Config| &config.clipboard_provider, + ))), status_msg: None, autoinfo: None, idle_timer: Box::pin(sleep(conf.idle_timeout)), diff --git a/helix-view/src/register.rs b/helix-view/src/register.rs index 3a2e1b7cc..3f7844cd6 100644 --- a/helix-view/src/register.rs +++ b/helix-view/src/register.rs @@ -1,10 +1,11 @@ use std::{borrow::Cow, collections::HashMap, iter}; use anyhow::Result; +use arc_swap::access::DynAccess; use helix_core::NATIVE_LINE_ENDING; use crate::{ - clipboard::{get_clipboard_provider, ClipboardProvider, ClipboardType}, + clipboard::{ClipboardProvider, ClipboardType}, Editor, }; @@ -20,28 +21,25 @@ use crate::{ /// * Document path (`%`): filename of the current buffer /// * System clipboard (`*`) /// * Primary clipboard (`+`) -#[derive(Debug)] pub struct Registers { /// The mapping of register to values. /// Values are stored in reverse order when inserted with `Registers::write`. /// The order is reversed again in `Registers::read`. This allows us to /// efficiently prepend new values in `Registers::push`. inner: HashMap>, - clipboard_provider: Box, + clipboard_provider: Box>, pub last_search_register: char, } -impl Default for Registers { - fn default() -> Self { +impl Registers { + pub fn new(clipboard_provider: Box>) -> Self { Self { inner: Default::default(), - clipboard_provider: get_clipboard_provider(), + clipboard_provider, last_search_register: '/', } } -} -impl Registers { pub fn read<'a>(&'a self, name: char, editor: &'a Editor) -> Option> { match name { '_' => Some(RegisterValues::new(iter::empty())), @@ -64,7 +62,7 @@ impl Registers { Some(RegisterValues::new(iter::once(path))) } '*' | '+' => Some(read_from_clipboard( - self.clipboard_provider.as_ref(), + &self.clipboard_provider.load(), self.inner.get(&name), match name { '+' => ClipboardType::Clipboard, @@ -84,8 +82,8 @@ impl Registers { '_' => Ok(()), '#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support writing")), '*' | '+' => { - self.clipboard_provider.set_contents( - values.join(NATIVE_LINE_ENDING.as_str()), + self.clipboard_provider.load().set_contents( + &values.join(NATIVE_LINE_ENDING.as_str()), match name { '+' => ClipboardType::Clipboard, '*' => ClipboardType::Selection, @@ -114,7 +112,10 @@ impl Registers { '*' => ClipboardType::Selection, _ => unreachable!(), }; - let contents = self.clipboard_provider.get_contents(clipboard_type)?; + let contents = self + .clipboard_provider + .load() + .get_contents(&clipboard_type)?; let saved_values = self.inner.entry(name).or_default(); if !contents_are_saved(saved_values, &contents) { @@ -127,7 +128,8 @@ impl Registers { } value.push_str(&contents); self.clipboard_provider - .set_contents(value, clipboard_type)?; + .load() + .set_contents(&value, clipboard_type)?; Ok(()) } @@ -198,7 +200,8 @@ impl Registers { fn clear_clipboard(&mut self, clipboard_type: ClipboardType) { if let Err(err) = self .clipboard_provider - .set_contents("".into(), clipboard_type) + .load() + .set_contents("", clipboard_type) { log::error!( "Failed to clear {} clipboard: {err}", @@ -210,17 +213,17 @@ impl Registers { } } - pub fn clipboard_provider_name(&self) -> Cow { - self.clipboard_provider.name() + pub fn clipboard_provider_name(&self) -> String { + self.clipboard_provider.load().name().into_owned() } } fn read_from_clipboard<'a>( - provider: &dyn ClipboardProvider, + provider: &ClipboardProvider, saved_values: Option<&'a Vec>, clipboard_type: ClipboardType, ) -> RegisterValues<'a> { - match provider.get_contents(clipboard_type) { + match provider.get_contents(&clipboard_type) { Ok(contents) => { // If we're pasting the same values that we just yanked, re-use // the saved values. This allows pasting multiple selections From 0fca0d057e8c4b6505c2b565365538df5e2c38b7 Mon Sep 17 00:00:00 2001 From: AbrA-K <127196460+AbrA-K@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:07:31 +0100 Subject: [PATCH 20/62] Theme: add adwaita-light theme (#10869) Co-authored-by: Michael Davis Co-authored-by: abra --- runtime/themes/adwaita-light.toml | 110 ++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 runtime/themes/adwaita-light.toml diff --git a/runtime/themes/adwaita-light.toml b/runtime/themes/adwaita-light.toml new file mode 100644 index 000000000..5bbbaf68d --- /dev/null +++ b/runtime/themes/adwaita-light.toml @@ -0,0 +1,110 @@ +inherits="adwaita-dark" +"attribute" = "orange_5" + +"type" = "teal_4" +"type.builtin" = "teal_4" + +"constructor" = "blue_4" + +"constant" = "violet_4" +"constant.builtin" = { fg = "violet_4", modifiers = ["bold"] } +"constant.character" = "teal_5" +"constant.numeric" = { fg = "teal_5", modifiers = ["bold"] } +"constant.character.escape" = "violet_4" + +"string" = "teal_3" +"string.regexp" = "purple_4" +"string.special" = "blue_4" + +"comment" = "light_6" + +"variable" = "dark_5" +"variable.parameter" = "orange_4" +"variable.builtin" = "orange_4" +"variable.other" = "teal_4" +"variable.other.member" = "teal_5" + +"label" = "purple_4" + +"punctuation" = "dark_4" +"punctuation.delimiter" = "dark_4" +"punctuation.bracket" = "dark_4" +"punctuation.special" = "red_5" + +"keyword" = { fg = "orange_4", modifiers = ["bold"] } +"keyword.control" = { fg = "orange_4", modifiers = ["bold"] } +"keyword.operator" = "purple_4" +"keyword.directive" = { fg = "orange_4", modifiers = ["bold"] } +"keyword.function" = "orange_4" +"keyword.storage" = { fg = "orange_4", modifiers = ["bold"] } + +"operator" = "purple_4" + +"function" = "blue_4" +"function.builtin" = "blue_4" +"function.macro" = { fg = "blue_4", modifiers = ["bold"] } +"function.special" = { fg = "blue_4", modifiers = ["bold"] } + +"tag" = "teal_4" + +"namespace" = "orange_4" + +"markup" = "dark_4" +"markup.heading" = { fg = "teal_4", modifiers = ["bold"] } +"markup.list" = { fg = "orange_4", modifiers = ["bold"] } +"markup.bold" = { fg = "dark_4", modifiers = ["bold"] } +"markup.italic" = { fg = "dark_4", modifiers = ["italic"] } +"markup.link" = { fg = "blue_5", modifiers = ["underlined"] } +"markup.quote" = { fg = "dark_3", modifiers = ["italic"] } +"diff.plus" = "teal_5" +"diff.minus" = "red_3" +"diff.delta" = "orange_5" +"diff.delta.moved" = "orange_4" + +"ui.background" = { fg = "dark_4", bg = "light_1" } +"ui.background.separator" = { fg = "split_and_borders", bg = "light_2" } +"ui.cursor" = { fg = "light_2", bg = "dark_5" } +"ui.cursor.insert" = { fg = "light_2", bg = "dark_4" } +"ui.cursor.primary.insert" = { fg = "light_2", bg = "yellow_5" } +"ui.cursor.select" = { fg = "light_2", bg = "dark_5" } +"ui.cursor.match" = { fg = "light_2", bg = "blue_1" } +"ui.cursor.primary" = { fg = "light_2", bg = "dark_6" } +"ui.linenr" = "light_5" +"ui.linenr.selected" = { fg = "dark_2", bg = "light_3", modifiers = [ + "bold", +] } +"ui.statusline" = { fg = "dark_4", bg = "light_4" } +"ui.statusline.inactive" = { fg = "dark_3", bg = "light_3" } +"ui.statusline.insert" = { fg = "light_5", bg = "teal_3" } +"ui.statusline.select" = { fg = "light_4", bg = "blue_3" } +"ui.popup" = { bg = "light_3" } +"ui.window" = "split_and_borders" +"ui.help" = { bg = "light_3" } +"ui.text" = "dark_4" +"ui.virtual" = "light_1" +"ui.virtual.ruler" = { bg = "light_5"} +"ui.menu" = { fg = "dark_4", bg = "light_3" } +"ui.menu.selected" = { fg = "dark_4", bg = "blue_1" } +"ui.menu.scroll" = { fg = "dark_6", bg = "light_3" } +"ui.selection" = { bg = "blue_0" } +"ui.selection.primary" = { bg = "blue_0" } +"ui.cursorline.primary" = { bg = "light_3" } +"ui.virtual.whitespace" = "light_7" + +"warning" = "yellow_4" +"error" = "red_5" +"info" = "purple_3" +"hint" = "blue_3" + +"diagnostic.hint" = { fg = "blue_4", modifiers = ["dim"] } +"diagnostic.info" = { fg = "purple_4", modifiers = ["dim"] } +"diagnostic.error" = { fg = "red_5", modifiers = ["underlined"] } +"diagnostic.warning" = { fg = "yellow_4", modifiers = ["underlined"] } +"diagnostic.unnecessary" = { modifiers = ["dim"] } +"diagnostic.deprecated" = { modifiers = ["crossed_out"] } + +"ui.bufferline" = { fg = "light_7", bg = "light_2" } +"ui.bufferline.active" = { fg = "dark_4", bg = "light_4", modifiers = ["bold"]} + +[palette] +blue_0 = "#d3e4f9" From 4e2faa0be9faef50c7f86b8f8fdaf8c1ca85e79e Mon Sep 17 00:00:00 2001 From: Raghu Saxena Date: Thu, 21 Nov 2024 06:08:06 +0800 Subject: [PATCH 21/62] Add `:config-reload` to configuration docs (#11086) Co-authored-by: Michael Davis --- book/src/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/configuration.md b/book/src/configuration.md index 0cd12568b..317007efc 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -27,8 +27,8 @@ hidden = false You can use a custom configuration file by specifying it with the `-c` or `--config` command line argument, for example `hx -c path/to/custom-config.toml`. -Additionally, you can reload the configuration file by sending the USR1 -signal to the Helix process on Unix operating systems, such as by using the command `pkill -USR1 hx`. +You can reload the config file by issuing the `:config-reload` command. Alternatively, on Unix operating systems, you can reload it by sending the USR1 +signal to the Helix process, such as by using the command `pkill -USR1 hx`. Finally, you can have a `config.toml` local to a project by putting it under a `.helix` directory in your repository. Its settings will be merged with the configuration directory `config.toml` and the built-in configuration. From 07968880e6a5a8287d316cd7c864f83769ab814d Mon Sep 17 00:00:00 2001 From: Freddie Gilbraith <75043775+FreddieGilbraith@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:08:38 +0000 Subject: [PATCH 22/62] update to newest rescript treesitter library and queries (#11165) Co-authored-by: Michael Davis Co-authored-by: Freddie Ridell --- languages.toml | 2 +- runtime/queries/rescript/highlights.scm | 31 ++++++++++++---------- runtime/queries/rescript/injections.scm | 33 +++++++++++++++++++----- runtime/queries/rescript/locals.scm | 6 ++--- runtime/queries/rescript/textobjects.scm | 2 +- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/languages.toml b/languages.toml index 0661d9c3e..93ea3bd04 100644 --- a/languages.toml +++ b/languages.toml @@ -1825,7 +1825,7 @@ indent = { tab-width = 2, unit = " " } [[grammar]] name = "rescript" -source = { git = "https://github.com/jaredramirez/tree-sitter-rescript", rev = "467dcf99f68c47823d7b378779a6b282d7ef9782" } +source = { git = "https://github.com/rescript-lang/tree-sitter-rescript", rev = "5e2a44a9d886b0a509f5bfd0437d33b4871fbac5" } [[language]] name = "erlang" diff --git a/runtime/queries/rescript/highlights.scm b/runtime/queries/rescript/highlights.scm index ed41322b4..51d37b87c 100644 --- a/runtime/queries/rescript/highlights.scm +++ b/runtime/queries/rescript/highlights.scm @@ -10,11 +10,10 @@ [ (type_identifier) (unit_type) + (list) + (list_pattern) ] @type -(list ["list{" "}"] @type) -(list_pattern ["list{" "}"] @type) - [ (variant_identifier) (polyvar_identifier) @@ -72,14 +71,16 @@ ; single parameter with no parens (function parameter: (value_identifier) @variable.parameter) +; first-level descructuring (required for nvim-tree-sitter as it only matches direct +; children and the above patterns do not match destructuring patterns in NeoVim) +(parameter (tuple_pattern (tuple_item_pattern (value_identifier) @variable.parameter))) +(parameter (array_pattern (value_identifier) @variable.parameter)) +(parameter (record_pattern (value_identifier) @variable.parameter)) + ; Meta ;----- -[ - "@" - "@@" - (decorator_identifier) -] @keyword.directive +(decorator_identifier) @keyword.directive (extension_identifier) @keyword ("%") @keyword @@ -87,7 +88,7 @@ ; Misc ;----- -; (subscript_expression index: (string) @attribute) +(subscript_expression index: (string) @attribute) (polyvar_type_pattern "#" @constant) [ @@ -101,18 +102,21 @@ "external" "let" "module" + "mutable" "private" "rec" "type" "and" "assert" - "async" "await" "with" - "unpack" -] @keyword.storage.type + "lazy" + "constraint" +] @keyword + +((function "async" @keyword.storage)) -"mutable" @keyword.storage.modifier +(module_unpack "unpack" @keyword) [ "if" @@ -169,6 +173,7 @@ "->" "|>" ":>" + "+=" (uncurry) ] @operator diff --git a/runtime/queries/rescript/injections.scm b/runtime/queries/rescript/injections.scm index 03e29b008..67f530d3b 100644 --- a/runtime/queries/rescript/injections.scm +++ b/runtime/queries/rescript/injections.scm @@ -1,8 +1,29 @@ -((comment) @injection.content - (#set! injection.language "comment")) +((comment) @injection.content (#set! injection.language "comment")) -((raw_js) @injection.content - (#set! injection.language "javascript")) +; %re +(extension_expression + (extension_identifier) @_name + (#eq? @_name "re") + (expression_statement (_) @injection.content (#set! injection.language "regex"))) + +; %raw +(extension_expression + (extension_identifier) @_name + (#eq? @_name "raw") + (expression_statement + (_ (_) @injection.content (#set! injection.language "javascript")))) + +; %graphql +(extension_expression + (extension_identifier) @_name + (#eq? @_name "graphql") + (expression_statement + (_ (_) @injection.content (#set! injection.language "graphql")))) + +; %relay +(extension_expression + (extension_identifier) @_name + (#eq? @_name "relay") + (expression_statement + (_ (_) @injection.content (#set! injection.language "graphql") ))) -((raw_gql) @injection.content - (#set! injection.language "graphql")) \ No newline at end of file diff --git a/runtime/queries/rescript/locals.scm b/runtime/queries/rescript/locals.scm index 1240ed160..4de73890e 100644 --- a/runtime/queries/rescript/locals.scm +++ b/runtime/queries/rescript/locals.scm @@ -1,7 +1,7 @@ (switch_expression) @local.scope -(if_expression) @local.scope ; Definitions ;------------ -(type_declaration) @local.defintion -(let_binding) @local.defintion +(type_declaration) @local.definition +(let_binding) @local.definition +(module_declaration) @local.definition diff --git a/runtime/queries/rescript/textobjects.scm b/runtime/queries/rescript/textobjects.scm index 4f1d8c53a..32c77b8f9 100644 --- a/runtime/queries/rescript/textobjects.scm +++ b/runtime/queries/rescript/textobjects.scm @@ -1,7 +1,7 @@ ; Classes (modules) ;------------------ -(module_declaration definition: ((_) @class.inside)) @class.around +(module_binding definition: ((_) @class.inside)) @class.around ; Blocks ;------- From aa10b1fd11c9c664edbf627af3ff3e8d498c8c7c Mon Sep 17 00:00:00 2001 From: eh Date: Wed, 20 Nov 2024 17:10:46 -0500 Subject: [PATCH 23/62] Theme: Seoul256 dark & light (#11466) --- runtime/themes/seoul256-dark-hard.toml | 16 +++ runtime/themes/seoul256-dark-soft.toml | 15 +++ runtime/themes/seoul256-dark.toml | 161 ++++++++++++++++++++++++ runtime/themes/seoul256-light-hard.toml | 16 +++ runtime/themes/seoul256-light-soft.toml | 16 +++ runtime/themes/seoul256-light.toml | 51 ++++++++ 6 files changed, 275 insertions(+) create mode 100644 runtime/themes/seoul256-dark-hard.toml create mode 100644 runtime/themes/seoul256-dark-soft.toml create mode 100644 runtime/themes/seoul256-dark.toml create mode 100644 runtime/themes/seoul256-light-hard.toml create mode 100644 runtime/themes/seoul256-light-soft.toml create mode 100644 runtime/themes/seoul256-light.toml diff --git a/runtime/themes/seoul256-dark-hard.toml b/runtime/themes/seoul256-dark-hard.toml new file mode 100644 index 000000000..fa918d29a --- /dev/null +++ b/runtime/themes/seoul256-dark-hard.toml @@ -0,0 +1,16 @@ +# Seoul256 Dark Hard +# Author : EricHenry +# Original Creator: https://github.com/junegunn/seoul256.vim + +inherits = "seoul256-dark" + +"ui.background" = { bg = "gray1" } +"ui.gutter" = { bg = "gray2" } +"ui.cursorline.primary" = { bg = "gray" } +"ui.gutter.selected" = { bg = "gray" } +"ui.linenr.selected" = { bg = "gray", fg = "magenta", modifiers = ["bold"] } +"ui.virtual.inlay-hint" = { fg = "gray4", modifiers = ["bold"] } + +"ui.help" = { bg = "gray" } +"ui.popup" = { bg = "gray" } +"ui.menu" = { bg = "gray" } diff --git a/runtime/themes/seoul256-dark-soft.toml b/runtime/themes/seoul256-dark-soft.toml new file mode 100644 index 000000000..548d0c182 --- /dev/null +++ b/runtime/themes/seoul256-dark-soft.toml @@ -0,0 +1,15 @@ +# Seoul256 Dark Soft +# Author : EricHenry +# Original Creator: https://github.com/junegunn/seoul256.vim + +inherits = "seoul256-dark" + +"ui.background" = { bg = "gray8" } +"ui.gutter" = { bg = "gray6" } +"ui.cursorline.primary" = { bg = "gray5" } +"ui.gutter.selected" = { bg = "gray5" } +"ui.linenr.selected" = { bg = "gray5", fg = "magenta", modifiers = ["bold"] } + +"ui.help" = { bg = "gray5" } +"ui.popup" = { bg = "gray5" } +"ui.menu" = { bg = "gray5" } diff --git a/runtime/themes/seoul256-dark.toml b/runtime/themes/seoul256-dark.toml new file mode 100644 index 000000000..df9d43df0 --- /dev/null +++ b/runtime/themes/seoul256-dark.toml @@ -0,0 +1,161 @@ +# Seoul256 Dark +# Author : EricHenry +# Original Creator: https://github.com/junegunn/seoul256.vim + +# Syntax highlighting configuration +"attribute" = { fg = "yellow" } +"comment" = { fg = "green1" } +"constant" = { fg = "blue5" } +"constant.numeric" = { fg = "yellow1" } +"constant.builtin.boolean" = { fg = "purple" } +"constant.character.escape" = { fg = "salmon" } +"constructor" = { fg = "yellow" } +"function" = { fg = "yellow2" } +"function.builtin" = { fg = "blue1" } +"function.method" = { fg = "salmon" } +"function.macro" = { fg = "yellow2" } +"keyword" = { fg = "mauve" } +"label" = { fg = "magenta" } +"namespace" = { fg = "cyan" } +"operator" = { fg = "yellow3" } +"punctuation" = { fg = "brown" } +"special" = { fg = "yellow2" } +"string" = { fg = "blue" } +"type" = { fg = "yellow" } +"type.builtin" = { fg = "salmon" } +"variable" = { fg = "white" } +"variable.builtin" = { fg = "salmon" } +"variable.parameter" = { fg = "white" } +"variable.other.member" = { fg = "white" } + +"markup.heading" = { fg = "salmon2", modifiers = ["bold"] } +"markup.raw.inline" = { fg = "green" } +"markup.bold" = { fg = "yellow1", modifiers = ["bold"] } +"markup.italic" = { fg = "magenta1", modifiers = ["italic"] } +"markup.strikethrough" = { modifiers = ["crossed_out"] } +"markup.list" = { fg = "salmon" } +"markup.quote" = { fg = "yellow" } +"markup.link.url" = { fg = "cyan", modifiers = ["underlined"] } +"markup.link.text" = { fg = "salmon2" } + +"diff.plus" = { fg = "green3" } +"diff.delta" = { fg = "blue1" } +"diff.minus" = { fg = "magenta3" } + +"diagnostic.info".underline = { color = "cyan", style = "curl" } +"diagnostic.hint".underline = { color = "green1", style = "curl" } +"diagnostic.warning".underline = { color = "yellow1", style = "curl" } +"diagnostic.error".underline = { color = "red", style = "curl" } +"diagnostic.unnecessary" = { modifiers = ["dim"] } +"diagnostic.deprecated" = { modifiers = ["crossed_out"] } +"info" = { fg = "blue2", modifiers = ["bold"] } +"hint" = { fg = "blue3", modifiers = ["bold"] } +"warning" = { fg = "yellow", modifiers = ["bold"] } +"error" = { fg = "red", modifiers = ["bold"] } + +"ui.background" = { bg = "gray4" } +"ui.gutter" = { bg = "gray5" } +"ui.gutter.selected" = { bg = "gray3" } +"ui.virtual" = { fg = "gray6" } +"ui.virtual.indent-guide" = { fg = "gray6" } +"ui.virtual.whitespace" = { fg = "gray6" } +"ui.virtual.ruler" = { bg = "gray5" } +"ui.virtual.inlay-hint" = { fg = "gray9", modifiers = ["bold"] } +"ui.virtual.jump-label" = { fg = "red", modifiers = ["bold"] } + +"ui.cursor" = { fg = "white", modifiers = ["reversed"] } +"ui.cursor.primary" = { fg = "white", modifiers = ["reversed"] } +"ui.cursor.match" = { bg = "gray4", modifiers = ["underlined"] } +"ui.cursor.insert" = { fg = "blue1" } + +"ui.selection" = { bg = "magenta2" } +"ui.selection.primary" = { bg = "blue4" } +"ui.cursorline.primary" = { bg = "gray3" } + +"ui.highlight" = { bg = "gray5" } +"ui.highlight.frameline" = { bg = "red" } + +"ui.linenr" = { fg = "yellow4" } +"ui.linenr.selected" = { bg = "gray3", fg = "magenta", modifiers = ["bold"] } + +"ui.statusline" = { fg = "magenta2", bg = "yellow2" } +"ui.statusline.inactive" = { fg = "gray6", bg = "black" } +"ui.statusline.normal" = { fg = "black", bg = "blue2" } +"ui.statusline.insert" = { fg = "black", bg = "green2" } +"ui.statusline.select" = { fg = "black", bg = "magenta" } + +"ui.text" = { fg = "white" } +"ui.text.focus" = { fg = "white", bg = "magenta2", modifiers = ["bold"] } + +"ui.help" = { fg = "white", bg = "gray3" } +"ui.popup" = { fg = "white", bg = "gray3" } +"ui.window" = { fg = "white" } +"ui.menu" = { fg = "white", bg = "gray3" } +"ui.menu.selected" = { fg = "white", bg = "magenta2" } +"ui.menu.scroll" = { fg = "gray7", bg = "gray6" } + +"ui.debug" = { fg = "red" } + +# Colors (Seoul256) +[palette] +black = '#000000' # Black +black1 = '#14161B' +red = '#d70000' # Red +green = '#afd75f' # Greenish Yellow +green1 = '#5f875f' # Greenish Gray +green2 = '#5f8700' # Green +green3 = '#87af87' +green4 = '#5f5f00' +yellow = '#d8af5f' # Yellow +yellow1 = '#ffd787' # Bright Yellow +yellow2 = '#d7d7af' # Yellowish +yellow3 = '#d7d787' # Yellow Dim +yellow4 = '#87875f' # Olive +yellow5 = '#6B5300' +blue = '#87afaf' # Light Blue +blue1 = '#5f87d7' # Bright Blue +blue2 = '#5f5f87' # Blue +blue3 = '#a6dbff' # Lightest Blue +blue4 = '#005f5f' # Blue Green +blue5 = '#5fafaf' # Dark Blue +blue6 = '#008787' +magenta = '#af5f5f' # Magenta +magenta1 = '#af5f87' # Soft Magenta +magenta2 = '#875f5f' # Dark Magenta +magenta3 = '#d7005f' # Darker Magenta +cyan = '#87d7d7' # Bright Cyan +cyan1 = '#afd7d7' +white = '#d0d0d0' # White +white1 = '#dadada' # White +purple = '#8787af' # Purple +brown = '#af875f' # Brownish +brown1 = '#875f00' # Brownish +orange = '#ff5f00' # Orange +salmon = '#ffaf87' # Salmon +salmon1 = '#d78787' # Salmon Bright +salmon2 = '#d7afaf' # Salmon Light +salmon3 = '#d7875f' # Yellowish +mauve = '#d75f87' # Mauve + +gray = '#121212' # Very Dark Gray +gray1 = '#1c1c1c' # Darker Gray +gray2 = '#262626' # Dark Gray +gray3 = '#303030' # Dark Medium Gray +gray4 = '#3a3a3a' # Medium Gray +gray5 = '#444444' # Lighter Medium Gray +gray6 = '#585858' # Light Gray +gray7 = '#626262' # Lighter Gray +gray8 = '#4e4e4e' # Even Lighter Gray +gray9 = '#5f5f5f' +gray10 = '#c6c6c6' +gray11 = '#eeeeee' +gray12 = '#e4e4e4' +gray13 = '#bcbcbc' + +# 233 = '#121212' +# 234 = '#1c1c1c' +# 235 = '#262626' +# 236 = '#303030' +# 237 = '#3a3a3a' # Default +# 238 = '#444444' +# 239 = '#4e4e4e' diff --git a/runtime/themes/seoul256-light-hard.toml b/runtime/themes/seoul256-light-hard.toml new file mode 100644 index 000000000..c1f92fac1 --- /dev/null +++ b/runtime/themes/seoul256-light-hard.toml @@ -0,0 +1,16 @@ +# Seoul256 Light Hard +# Author : EricHenry +# Original Creator: https://github.com/junegunn/seoul256.vim + +inherits = "seoul256-light" + +"ui.background" = { bg = "gray11" } +"ui.cursor.match" = { bg = "gray10", modifiers = ["underlined"] } +"ui.gutter" = { bg = "white1" } +"ui.cursorline.primary" = { bg = "gray12" } +"ui.gutter.selected" = { bg = "gray12" } +"ui.linenr.selected" = { bg = "gray12", fg = "magenta", modifiers = ["bold"] } + +"ui.help" = { fg = "black1", bg = "gray12" } +"ui.popup" = { fg = "black1", bg = "gray12" } +"ui.menu" = { fg = "black1", bg = "gray12" } diff --git a/runtime/themes/seoul256-light-soft.toml b/runtime/themes/seoul256-light-soft.toml new file mode 100644 index 000000000..0a25bb696 --- /dev/null +++ b/runtime/themes/seoul256-light-soft.toml @@ -0,0 +1,16 @@ +# Seoul256 Light Soft +# Author : EricHenry +# Original Creator: https://github.com/junegunn/seoul256.vim + +inherits = "seoul256-light" + +"ui.background" = { bg = "white" } +"ui.cursor.match" = { bg = "gray13", modifiers = ["underlined"] } +"ui.gutter" = { bg = "gray13" } +"ui.cursorline.primary" = { bg = "gray10" } +"ui.gutter.selected" = { bg = "gray10" } +"ui.linenr.selected" = { bg = "gray10", fg = "magenta", modifiers = ["bold"] } + +"ui.help" = { fg = "black1", bg = "gray10" } +"ui.popup" = { fg = "black1", bg = "gray10" } +"ui.menu" = { fg = "black1", bg = "gray10" } diff --git a/runtime/themes/seoul256-light.toml b/runtime/themes/seoul256-light.toml new file mode 100644 index 000000000..4f45a9d02 --- /dev/null +++ b/runtime/themes/seoul256-light.toml @@ -0,0 +1,51 @@ +# Seoul256 Light +# Author : EricHenry +# Original Creator: https://github.com/junegunn/seoul256.vim + +inherits = "seoul256-dark" + +"constructor" = { fg = "brown1" } +"constant.numeric" = { fg = "magenta2" } +"constant.builtin.boolean" = { fg = "mauve" } +"constant.character.escape" = { fg = "salmon3" } +"function" = { fg = "green4" } +"function.builtin" = { fg = "blue1" } +"function.method" = { fg = "salmon" } +"function.macro" = { fg = "green4" } +"namespace" = { fg = "blue4" } +"operator" = { fg = "brown1" } +"punctuation" = { fg = "brown1" } +"special" = { fg = "green4" } +"string" = { fg = "blue6" } +"type" = { fg = "brown1" } +"type.builtin" = { fg = "salmon3" } +"variable" = { fg = "black1" } +"variable.builtin" = { fg = "salmon3" } +"variable.parameter" = { fg = "black1" } +"variable.other.member" = { fg = "black1" } + +"diagnostic.info".underline = { color = "green1", style = "curl" } +"info" = { fg = "green1", modifiers = ["bold"] } +"hint" = { fg = "blue", modifiers = ["bold"] } +"warning" = { fg = "yellow5", modifiers = ["bold"] } + +"ui.background" = { bg = "white1" } +"ui.cursor" = { fg = "gray4", modifiers = ["reversed"] } +"ui.cursor.primary" = { fg = "gray4", modifiers = ["reversed"] } +"ui.cursor.match" = { bg = "gray13", modifiers = ["underlined"] } +"ui.cursor.insert" = { fg = "blue1" } +"ui.cursorline.primary" = { bg = "white" } +"ui.gutter" = { bg = "gray10" } +"ui.gutter.selected" = { bg = "white" } +"ui.linenr.selected" = { bg = "white", fg = "magenta", modifiers = ["bold"] } +"ui.virtual.inlay-hint" = { fg = "gray6", modifiers = ["bold"] } + +"ui.selection" = { bg = "yellow2" } +"ui.selection.primary" = { bg = "cyan1" } + +"ui.text" = { fg = "black1" } + +"ui.help" = { fg = "black1", bg = "white" } +"ui.popup" = { fg = "black1", bg = "white" } +"ui.menu" = { fg = "black1", bg = "white" } + From 2dbecd3c8027e9135a613e12339faa5ee2976675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grenier=20C=C3=A9lestin?= <43825779+naclsn@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:13:27 +0100 Subject: [PATCH 24/62] Bump tree-sitter-nasm (#11795) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 93ea3bd04..4e63b2d46 100644 --- a/languages.toml +++ b/languages.toml @@ -3000,7 +3000,7 @@ indent = { tab-width = 8, unit = " " } [[grammar]] name = "nasm" -source = { git = "https://github.com/naclsn/tree-sitter-nasm", rev = "a0db15db6fcfb1bf2cc8702500e55e558825c48b" } +source = { git = "https://github.com/naclsn/tree-sitter-nasm", rev = "570f3d7be01fffc751237f4cfcf52d04e20532d1" } [[language]] name = "gas" From f9ac1f1ff110c02abf99c4c4dc4715aed95be725 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Wed, 20 Nov 2024 23:14:15 +0100 Subject: [PATCH 25/62] Bump tree-sitter llvm grammars (#11851) --- languages.toml | 6 +++--- runtime/queries/llvm-mir/highlights.scm | 12 +++++++++++- runtime/queries/llvm/highlights.scm | 2 ++ runtime/queries/tablegen/highlights.scm | 2 ++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/languages.toml b/languages.toml index 4e63b2d46..d572bee90 100644 --- a/languages.toml +++ b/languages.toml @@ -1559,7 +1559,7 @@ injection-regex = "llvm" [[grammar]] name = "llvm" -source = { git = "https://github.com/benwilliamgraham/tree-sitter-llvm", rev = "e9948edc41e9e5869af99dddb2b5ff5cc5581af6" } +source = { git = "https://github.com/benwilliamgraham/tree-sitter-llvm", rev = "c14cb839003348692158b845db9edda201374548" } [[language]] name = "llvm-mir" @@ -1571,7 +1571,7 @@ injection-regex = "mir" [[grammar]] name = "llvm-mir" -source = { git = "https://github.com/Flakebi/tree-sitter-llvm-mir", rev = "06fabca19454b2dc00c1b211a7cb7ad0bc2585f1" } +source = { git = "https://github.com/Flakebi/tree-sitter-llvm-mir", rev = "d166ff8c5950f80b0a476956e7a0ad2f27c12505" } [[language]] name = "llvm-mir-yaml" @@ -1594,7 +1594,7 @@ injection-regex = "tablegen" [[grammar]] name = "tablegen" -source = { git = "https://github.com/Flakebi/tree-sitter-tablegen", rev = "568dd8a937347175fd58db83d4c4cdaeb6069bd2" } +source = { git = "https://github.com/Flakebi/tree-sitter-tablegen", rev = "3e9c4822ab5cdcccf4f8aa9dcd42117f736d51d9" } [[language]] name = "markdown" diff --git a/runtime/queries/llvm-mir/highlights.scm b/runtime/queries/llvm-mir/highlights.scm index 792346122..743b9690b 100644 --- a/runtime/queries/llvm-mir/highlights.scm +++ b/runtime/queries/llvm-mir/highlights.scm @@ -75,11 +75,16 @@ "pre-instr-symbol" "post-instr-symbol" "heap-alloc-marker" + "pcsections" + "mmra" + "cfi-type" "debug-instr-number" "debug-location" + "dbg-instr-ref" "mcsymbol" "tied-def" "target-flags" + "vscale" "CustomRegMask" "same_value" "def_cfa_register" @@ -118,11 +123,16 @@ "got" "jump-table" "syncscope" - "address-taken" + "machine-block-address-taken" + "ir-block-address-taken" "landing-pad" "inlineasm-br-indirect-target" "ehfunclet-entry" + "bb_id" + "call-frame-size" "bbsections" + "Exception" + "Cold" (intpred) (floatpred) diff --git a/runtime/queries/llvm/highlights.scm b/runtime/queries/llvm/highlights.scm index cb705197e..4de2a1655 100644 --- a/runtime/queries/llvm/highlights.scm +++ b/runtime/queries/llvm/highlights.scm @@ -17,9 +17,11 @@ [ "to" + "nneg" "nuw" "nsw" "exact" + "disjoint" "unwind" "from" "cleanup" diff --git a/runtime/queries/tablegen/highlights.scm b/runtime/queries/tablegen/highlights.scm index 8ade5ba9a..188fa2ef0 100644 --- a/runtime/queries/tablegen/highlights.scm +++ b/runtime/queries/tablegen/highlights.scm @@ -68,7 +68,9 @@ "def" "defset" "defvar" + "deftype" "assert" + "dump" ] @keyword [ From 4d3612125b5feaeadee838cd57f60140816e2c6e Mon Sep 17 00:00:00 2001 From: Veesh Goldman Date: Thu, 21 Nov 2024 00:14:39 +0200 Subject: [PATCH 26/62] chore: update perl + pod parsers (#11848) --- languages.toml | 4 ++-- runtime/queries/perl/highlights.scm | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/languages.toml b/languages.toml index d572bee90..1551d76b9 100644 --- a/languages.toml +++ b/languages.toml @@ -1487,7 +1487,7 @@ indent = { tab-width = 2, unit = " " } [[grammar]] name = "perl" -source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "e99bb5283805db4cb86c964722d709df21b0ac16" } +source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "72a08a496a23212f23802490ef6f4700d68cfd0e" } [[language]] name = "pod" @@ -1497,7 +1497,7 @@ file-types = ["pod"] [[grammar]] name = "pod" -source = { git = "https://github.com/tree-sitter-perl/tree-sitter-pod", rev = "39da859947b94abdee43e431368e1ae975c0a424" } +source = { git = "https://github.com/tree-sitter-perl/tree-sitter-pod", rev = "0bf8387987c21bf2f8ed41d2575a8f22b139687f" } [[language]] name = "racket" diff --git a/runtime/queries/perl/highlights.scm b/runtime/queries/perl/highlights.scm index c2496f9fb..bf5918b95 100644 --- a/runtime/queries/perl/highlights.scm +++ b/runtime/queries/perl/highlights.scm @@ -1,9 +1,9 @@ [ - "use" "no" "require" "package" + "use" "no" "require" "package" "class" "role" ] @keyword.control.import [ - "sub" + "sub" "method" "async" "extended" ] @keyword.function [ @@ -17,7 +17,7 @@ ] @keyword.control.repeat [ - "my" "our" "local" + "my" "our" "local" "state" ] @keyword.storage.modifier [ @@ -29,9 +29,10 @@ ] @constant.builtin (phaser_statement phase: _ @keyword.directive) +(class_phaser_statement phase: _ @keyword.directive) [ - "or" "and" + "or" "xor" "and" "eq" "ne" "cmp" "lt" "le" "ge" "gt" "isa" ] @keyword.operator @@ -55,7 +56,7 @@ [(quoted_regexp) (match_regexp)] @string.regexp -(autoquoted_bareword _?) @string.special +(autoquoted_bareword) @string.special [(scalar) (arraylen)] @variable (scalar_deref_expression ["->" "$" "*"] @variable) From 6ec510d58fddd907324e06b7475c81b21d0782f4 Mon Sep 17 00:00:00 2001 From: pacien Date: Wed, 20 Nov 2024 23:14:56 +0100 Subject: [PATCH 27/62] queries/nix: add injections for nim writers (#11837) --- runtime/queries/nix/injections.scm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime/queries/nix/injections.scm b/runtime/queries/nix/injections.scm index 9804b75be..2fb8918a7 100644 --- a/runtime/queries/nix/injections.scm +++ b/runtime/queries/nix/injections.scm @@ -127,6 +127,16 @@ (#set! injection.language "haskell") (#set! injection.combined)) +; pkgs.writers.writeNim[Bin] name attrs content +(apply_expression + (apply_expression + function: (apply_expression + function: ((_) @_func))) + argument: (indented_string_expression (string_fragment) @injection.content) + (#match? @_func "(^|\\.)writeNim(Bin)?$") + (#set! injection.language "nim") + (#set! injection.combined)) + ; pkgs.writers.writeJS[Bin] name attrs content (apply_expression (apply_expression From 07262f51704eae45865cf0373f97c9347e22f153 Mon Sep 17 00:00:00 2001 From: Michael McClintock Date: Thu, 21 Nov 2024 08:15:13 +1000 Subject: [PATCH 28/62] Add yo themes (#11703) --- runtime/themes/yo.toml | 125 +++++++++++++++++++++++++++++++++++ runtime/themes/yo_berry.toml | 31 +++++++++ runtime/themes/yo_light.toml | 34 ++++++++++ 3 files changed, 190 insertions(+) create mode 100644 runtime/themes/yo.toml create mode 100644 runtime/themes/yo_berry.toml create mode 100644 runtime/themes/yo_light.toml diff --git a/runtime/themes/yo.toml b/runtime/themes/yo.toml new file mode 100644 index 000000000..55c805204 --- /dev/null +++ b/runtime/themes/yo.toml @@ -0,0 +1,125 @@ +# Author: Michael McClintock +# License: MIT + +# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors. +# https://github.com/mrmcc3/yo-theme-helix + +# background/text +"ui.background" = { fg = "p11", bg = "p2" } +"ui.background.separator" = { fg = "p7" } +"ui.text" = { fg = "p11" } +"ui.text.focus" = { fg = "p12", modifiers = ["bold"] } + +# popups/menus +"ui.window" = { fg = "p7" } +"ui.popup" = { fg = "p12", bg = "p4" } +"ui.popup.info" = { fg = "p12", bg = "p2" } +"ui.text.info" = { fg = "p12", bg = "p2" } +"ui.help" = { fg = "p12", bg = "p2" } +"ui.menu" = { fg = "p11", bg = "p4" } +"ui.menu.selected" = { fg = "p12", modifiers = ["bold"] } +"ui.menu.scroll" = { fg = "p8", bg = "p4" } +"ui.picker.header.column" = { underline.style = "line" } + +# cursor/selection +"ui.cursor" = { fg = "p2", bg = "p11" } +"ui.cursor.insert" = { fg = "p2", bg = "keyword" } +"ui.cursor.select" = { fg = "p2", bg = "p12" } +"ui.cursor.match" = { fg = "p12", modifiers = ["bold"] } +"ui.cursor.primary" = { fg = "p2", bg = "p11", modifiers = ["bold"] } +"ui.cursor.primary.insert" = { fg = "p2", bg = "keyword", modifiers = ["bold"] } +"ui.cursor.primary.select" = { fg = "p2", bg = "p12", modifiers = ["bold"] } +"ui.selection" = { bg = "p4" } +"ui.selection.primary" = { bg = "p5" } +"ui.cursorline.primary" = { bg = "p3" } +"ui.cursorcolumn.primary" = { bg = "p3" } + +# line numbers / diff +"ui.linenr" = { fg = "p7" } +"ui.linenr.selected" = { fg = "p11" } +diff = { fg = "p8" } + +# bufferline/statusline +"ui.bufferline" = { fg = "p11", bg = "p4" } +"ui.bufferline.active" = { fg = "p2", bg = "p11" } +"ui.statusline" = { fg = "p11", bg = "p4" } +"ui.statusline.inactive" = { fg = "p11", bg = "p2" } +"ui.statusline.normal" = { fg = "p2", bg = "p11" } +"ui.statusline.insert" = { fg = "p2", bg = "keyword" } +"ui.statusline.select" = { fg = "p2", bg = "p12" } +"ui.statusline.separator" = { fg = "p7" } + +# virtual +"ui.virtual" = { fg = "p6" } +"ui.virtual.ruler" = { bg = "p3" } +"ui.virtual.inlay-hint" = { fg = "p7", underline.style = "dotted" } +"ui.virtual.jump-label" = { fg = "p12", modifiers = [ + "bold", +], underline = { style = "curl", color = "info" } } + +# diagnostics +error = { fg = "error", modifiers = ["bold"] } +warning = { fg = "warning", modifiers = ["bold"] } +info = { fg = "info", modifiers = ["bold"] } +hint = { fg = "info", modifiers = ["bold"] } +"diagnostic.error" = { fg = "error", modifiers = ["bold"] } +"diagnostic.warning" = { fg = "warning", modifiers = ["bold"] } +"diagnostic.info" = { fg = "info", modifiers = ["bold"] } +"diagnostic.hint" = { fg = "info", modifiers = ["bold"] } +# "diagnostic.unnecessary" = {} +# "diagnostic.deprecated" = {} + +# code +comment = { fg = "info" } +keyword = { fg = "keyword" } +operator = { fg = "keyword" } +string = { fg = "string" } +constant = { fg = "constant" } +"string.special.symbol" = { fg = "constant" } +variable = { fg = "p10" } +namespace = { fg = "p10" } +punctuation = { fg = "p9" } +"punctuation.delimiter" = { fg = "p8" } +function = { fg = "p11" } +attribute = { fg = "p10" } +tag = { fg = "keyword" } +label = { fg = "p12" } +constructor = { fg = "p12" } +type = { fg = "p12" } + +# markup +"markup.bold" = { modifiers = ["bold"] } +"markup.italic" = { modifiers = ["italic"] } +"markup.strikethrough" = { modifiers = ["crossed_out"] } +"markup.heading" = { fg = "p12", modifiers = ["bold"] } +"markup.heading.marker" = { fg = "p8" } +"markup.list" = { fg = "p8" } +"markup.link.url" = { underline.style = "line" } +"markup.link.label" = { underline.style = "dotted" } +# "markup.link.text" = {} +"markup.quote" = { fg = "p10" } +# "markup.raw" = {} + +[palette] # https://www.radix-ui.com/colors + +# grayDark +p1 = "#111111" +p2 = "#191919" +p3 = "#222222" +p4 = "#2a2a2a" +p5 = "#313131" +p6 = "#3a3a3a" +p7 = "#484848" +p8 = "#606060" +p9 = "#6e6e6e" +p10 = "#7b7b7b" +p11 = "#b4b4b4" +p12 = "#eeeeee" + +error = "#ec5d5e" # redDark-10 +warning = "#ff801f" # orangeDark-10 +info = "#3b9eff" # blueDark-10 + +string = "#33b074" # greenDark-10 +constant = "#9a5cd0" # purpleDark-10 +keyword = "#ae8c7e" # bronzeDark-10 diff --git a/runtime/themes/yo_berry.toml b/runtime/themes/yo_berry.toml new file mode 100644 index 000000000..1aaac1a92 --- /dev/null +++ b/runtime/themes/yo_berry.toml @@ -0,0 +1,31 @@ +# Author: Michael McClintock +# License: MIT + +# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors. +# https://github.com/mrmcc3/yo-theme-helix + +inherits = "yo" + +[palette] + +# mauveDark +p1 = "#121113" +p2 = "#1a191b" +p3 = "#232225" +p4 = "#2b292d" +p5 = "#323035" +p6 = "#3c393f" +p7 = "#49474e" +p8 = "#625f69" +p9 = "#6f6d78" +p10 = "#7c7a85" +p11 = "#b5b2bc" +p12 = "#eeeef0" + +error = "#ee518a" # crimsonDark-10 +warning = "#ffff57" # yellowDark-10 +info = "#3b9eff" # blueDark-10 + +string = "#0eb39e" # teal-10 +constant = "#b658c4" # plum-10 +keyword = "#9eb1ff" # indigo-11 diff --git a/runtime/themes/yo_light.toml b/runtime/themes/yo_light.toml new file mode 100644 index 000000000..15c149184 --- /dev/null +++ b/runtime/themes/yo_light.toml @@ -0,0 +1,34 @@ +# Author: Michael McClintock +# License: MIT + +# Yo - Themes for Helix inspired by Zenbones & Alabaster with Radix Colors. +# https://github.com/mrmcc3/yo-theme-helix + +inherits = "yo" + +"ui.virtual.inlay-hint" = { fg = "p8", underline.style = "dotted" } +"markup.quote" = { fg = "p9" } + +[palette] + +# gray +p1 = "#fcfcfc" +p2 = "#f9f9f9" +p3 = "#f0f0f0" +p4 = "#e8e8e8" +p5 = "#e0e0e0" +p6 = "#d9d9d9" +p7 = "#cecece" +p8 = "#bbbbbb" +p9 = "#8d8d8d" +p10 = "#838383" +p11 = "#646464" +p12 = "#202020" + +error = "#dc3e42" # red-10 +warning = "#ef5f00" # orange-10 +info = "#0588f0" # blue-10 + +string = "#2b9a66" # green-10 +constant = "#8347b9" # purple-10 +keyword = "#957468" # bronze-10 From 5b3e0b64f0acd02631fbef7a88d97b246b8a9efe Mon Sep 17 00:00:00 2001 From: mesmere <95945959+mesmere@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:15:38 -0500 Subject: [PATCH 29/62] Add new "Eiffel" theme (#11679) --- runtime/themes/eiffel.toml | 180 +++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 runtime/themes/eiffel.toml diff --git a/runtime/themes/eiffel.toml b/runtime/themes/eiffel.toml new file mode 100644 index 000000000..ba0f5c60d --- /dev/null +++ b/runtime/themes/eiffel.toml @@ -0,0 +1,180 @@ +## Author: mesmere <95945959+mesmere@users.noreply.github.com> +## Original design by Ian Joyner + +"attribute" = { fg = "markup", modifiers = ["italic"] } +"comment" = "comments" +"comment.block" = "comments" +"comment.block.documentation" = "comments" +"comment.line" = "comments" +#"constant" = "" +"constant.builtin" = { fg = "builtins", modifiers = ["italic"] } +"constant.character" = "strings" +"constant.character.escape" = "symbols" +"constant.numeric" = { fg = "constants_numeric", modifiers = ["italic"] } +"constructor" = { modifiers = ["italic"] } +"function" = { fg = "members" } +"function.builtin" = "builtins" +"function.macro" = "preprocessor" +"function.method" = { fg = "members", modifiers = ["italic"] } +#"function.method.private" = "" +"function.special" = "preprocessor" +"keyword" = { fg = "ui_text" } +"keyword.control" = { fg = "keywords", modifiers = ["bold"] } +"keyword.directive" = { fg = "preprocessor", modifiers = ["bold"] } +#"keyword.function" = "" +"keyword.operator" = { fg = "operators", modifiers = ["italic"] } +#"keyword.storage" = "" +#"label" = "" +#"namespace" = "" +"operator" = { fg = "operators", modifiers = ["bold"] } +#"punctuation" = "" +#"punctuation.bracket" = "" +#"punctuation.delimiter" = "" +"punctuation.special" = "strings" +#"special" = "" +"string" = "strings" +"string.regexp" = "symbols" +"string.special" = "symbols" +"tag" = "markup" +"type" = { modifiers = ["italic"] } +#"type.builtin" = "" +#"type.enum" = "" +#"type.parameter" = "" +#"variable" = "" +"variable.builtin" = "builtins" +"variable.other.member" = { fg = "members", modifiers = ["italic"] } +#"variable.other.member.private" = "" +#"variable.parameter" = "" +"markup" = "markup" +"markup.heading" = { fg = "markup_headings", modifiers = ["bold"] } +#"markup.heading.marker" = "" +"markup.list" = "markup_lists" +"markup.bold" = { modifiers = ["bold"] } +"markup.italic" = { modifiers = ["italic"] } +"markup.strikethrough" = { modifiers = ["crossed_out"] } +"markup.link.url" = { fg = "strings", underline.style = "line" } # Match HTML href/src attributes. +#"markup.link.label" = "" +"markup.link.text" = "ui_text" +"markup.quote" = { fg = "black", modifiers = ["italic"] } +"markup.raw" = "strings" +#"markup.raw.inline" = "" +#"markup.raw.block" = "" + +"diff.delta" = "diff_delta" +"diff.minus" = "diff_minus" +"diff.plus" = "diff_plus" + +"ui.background" = { bg = "ui_background" } +#"ui.background.separator" = "" +"ui.bufferline" = { fg = "ui_text_dim", bg = "ui_background_accent" } +"ui.bufferline.active" = { fg = "ui_text", bg = "ui_background_accent" } +"ui.bufferline.background" = { bg = "ui_background_accent" } +#"ui.cursor" = { modifiers = ['reversed'] } +"ui.cursor.insert" = { bg = "ui_mode_insert_accent" } +"ui.cursor.match" = { modifiers = ['reversed'] } +"ui.cursor.normal" = { bg = "ui_mode_normal_accent" } +"ui.cursor.select" = { bg = "ui_mode_select_accent" } +#"ui.cursor.primary" = "" +"ui.cursor.primary.insert" = { bg = "ui_mode_insert" } +#"ui.cursor.primary.match" = "" +"ui.cursor.primary.normal" = { bg = "ui_mode_normal" } +"ui.cursor.primary.select" = { bg = "ui_mode_select" } +"ui.cursorcolumn.primary" = { bg = "ui_background_accent" } +#"ui.cursorcolumn.secondary" = "" +"ui.cursorline.primary" = { bg = "ui_background_accent" } +#"ui.cursorline.secondary" = "" +"ui.debug.active" = { fg = "ui_debug_breakpoint" } +"ui.debug.breakpoint" = { fg = "ui_debug_breakpoint" } +"ui.gutter" = { bg = "ui_background" } +"ui.gutter.selected" = { bg = "ui_background_accent" } +"ui.help" = { fg = "ui_text", bg = "ui_menu" } +"ui.highlight" = { fg = "ui_highlight_line_text", bg = "ui_highlight_line" } # fg is not respected https://github.com/helix-editor/helix/issues/11141 +"ui.highlight.frameline" = { fg = "ui_highlight_line_text", bg = "ui_highlight_line" } +"ui.linenr" = "ui_text_dim" +"ui.linenr.selected" = { fg = "ui_text_dim", bg = "ui_background_accent" } +"ui.menu" = { fg = "ui_menu_text", bg = "ui_menu" } +"ui.menu.scroll" = { fg = "ui_menu_handle", bg = "ui_menu_selected" } +"ui.menu.selected" = { fg = "ui_text", bg = "ui_menu_selected" } +#"ui.picker" = { fg = "ui_text", bg = "ui_menu" } # Styling the picker is currently unsupported. +"ui.picker.header" = { bg = "ui_background_accent" } +"ui.picker.header.column" = "ui_text" +"ui.picker.header.column.active" = { fg = "ui_text", modifiers = ["bold"], underline = { style = "line" } } +"ui.popup" = { fg = "ui_text", bg = "ui_background_accent" } +"ui.popup.info" = { fg = "ui_text", bg = "ui_menu" } +"ui.selection" = { bg = "ui_selection" } +#"ui.selection.primary" = { bg = "ui_selection", underline.style = "line" } +"ui.statusline" = { fg = "ui_text", bg = "ui_background_accent" } +#"ui.statusline.inactive" = { fg = "", bg = "" } +"ui.statusline.insert" = { fg = "ui_mode_insert_text", bg = "ui_mode_insert", modifiers = ["bold"] } +"ui.statusline.normal" = { fg = "ui_mode_normal_text", bg = "ui_mode_normal", modifiers = ["bold"] } +"ui.statusline.select" = { fg = "ui_mode_select_text", bg = "ui_mode_select", modifiers = ["bold"] } +"ui.text" = "ui_text" +"ui.text.focus" = { fg = "ui_text", modifiers = ["bold"] } +"ui.text.inactive" = "ui_text_dim" +#"ui.text.info" = "" +"ui.virtual.indent-guide" = "ui_text_dim" +"ui.virtual.inlay-hint" = "ui_text_dim" +#"ui.virtual.inlay-hint.parameter" = "" +#"ui.virtual.inlay-hint.type" = "" +"ui.virtual.jump-label" = { fg = "white", bg = "ui_jumplabel", modifiers = ["bold"] } +"ui.virtual.ruler" = { bg = "ui_background_accent" } +"ui.virtual.whitespace" = "ui_text_dim" +"ui.virtual.wrap" = "ui_text_dim" +"ui.window" = "ui_split_line" + +info = { fg = 'ui_diagnostic_info' } +hint = { fg = 'ui_diagnostic_hint', modifiers = ['bold'] } +warning = { fg = 'ui_diagnostic_warning', modifiers = ['bold'] } +error = { fg = 'ui_diagnostic_error', modifiers = ['bold'] } + +"diagnostic.info" = { fg = "ui_diagnostic_info", underline = { style = "curl", color = "ui_diagnostic_info" } } +"diagnostic.hint" = { fg = "ui_diagnostic_hint", underline = { style = "curl", color = "ui_diagnostic_hint" } } +"diagnostic.warning" = { fg = "ui_diagnostic_warning", underline = { style = "curl", color = "ui_diagnostic_warning" } } +"diagnostic.error" = { fg = "ui_diagnostic_error", underline = { style = "curl", color = "ui_diagnostic_error" } } +"diagnostic.unnecessary" = { modifiers = ["dim"] } +"diagnostic.deprecated" = { modifiers = ["crossed_out"] } + +[palette] +builtins = "#585cf6" +comments = "#00b418" +constants_numeric = "#cd0000" +diff_delta = "#0000a2" +diff_minus = "#990000" +diff_plus = "#00b418" +keywords = "#0100b6" +markup = "#1c02ff" +markup_headings = "#0c07ff" +markup_lists = "#b90690" +members = "#0206ff" +operators = "#0100b6" +preprocessor = "#0c450d" +strings = "#d80800" +symbols = "#26b31a" +ui_background = "#ffffff" +ui_background_accent = "#ededed" +ui_highlight_line = "#0100b6" +ui_highlight_line_text = "#ffffff" +ui_debug_breakpoint = "#990000" +ui_diagnostic_error = "#990000" +ui_diagnostic_hint = "#06960e" +ui_diagnostic_info = "#808080" +ui_diagnostic_warning = "#fafa28" +ui_jumplabel = "#990000" +ui_menu = "#c3dcff" +ui_menu_selected = "#a3bcdf" +ui_menu_handle = "#839cbf" +ui_menu_text = "#000000" +ui_mode_insert = "#009608" +ui_mode_insert_accent = "#73e678" +ui_mode_insert_text = "#ffffff" +ui_mode_normal = "#444444" +ui_mode_normal_accent = "#cccccc" +ui_mode_normal_text = "#ffffff" +ui_mode_select = "#000096" +ui_mode_select_accent = "#7373e6" +ui_mode_select_text = "#ffffff" +ui_selection = "#c3dcff" +ui_split_line = "#000000" +ui_statusline = "#000000" +ui_text = "#000000" +ui_text_dim = "#808080" From e2d79c189184f4c367d6c67a8ae2ae094a961662 Mon Sep 17 00:00:00 2001 From: Eamon Caton Date: Wed, 20 Nov 2024 22:16:05 +0000 Subject: [PATCH 30/62] Add Carbonfox theme (#11558) --- runtime/themes/carbonfox.toml | 50 +++++++++++++++++++++++ runtime/themes/licenses/carbonfox.license | 21 ++++++++++ 2 files changed, 71 insertions(+) create mode 100644 runtime/themes/carbonfox.toml create mode 100644 runtime/themes/licenses/carbonfox.license diff --git a/runtime/themes/carbonfox.toml b/runtime/themes/carbonfox.toml new file mode 100644 index 000000000..12e812955 --- /dev/null +++ b/runtime/themes/carbonfox.toml @@ -0,0 +1,50 @@ +# Author: github.com/ETCaton +# License: MIT License +# Carbonfox +# +# Based on Helix's Nightfox port with changes to align it to Nightfox's Carbonfox theme +# Any 'custom' colors are replicating the result of the linear color blending done in the original +# Neovim theme. +# https://github.com/EdenEast/nightfox.nvim/blob/d3e8b1acc095baf57af81bb5e89fe7c4359eb619/lua/nightfox/lib/color.lua#L236-L247 + +inherits = 'nightfox' + +# DIAGNOSTICS +# For brevity: All blends here are a blend between bg1 and the fg value with factor of 0.15 +"warning" = { fg = "magenta", bg = "#2f2939" } +"error.bg" = "#361f29" +"info.bg" = "#252c39" +"hint" = { fg = "orange", bg = "#1c3433" } + +[palette] +black = "#282828" +red = "#ee5396" +red-dim = "#ca4780" +green = "#25be6a" +green-dim = "#1fa25a" +yellow = "#08bdba" +yellow-bright = "#2dc7c4" +blue = "#78a9ff" +blue-bright = "#8cb6ff" +blue-dim = "#6690d9" +magenta = "#be95ff" +magenta-bright = "#c8a5ff" +cyan = "#33b1ff" +cyan-bright = "#52bdff" +cyan-dim = "#2b96d9" +orange = "#3ddbd9" +orange-bright = "#5ae0df" +pink = "#ff7eb6" +pink-bright = "#ff91c1" +# spec +bg0 = "#0c0c0c" +bg1 = "#161616" +bg2 = "#252525" +bg3 = "#353535" +bg4 = "#535353" +fg0 = "#f9fbff" +fg1 = "#f2f4f8" +fg2 = "#b6b8bb" +fg3 = "#7b7c7e" +sel0 = "#2a2a2a" +sel1 = "#525253" diff --git a/runtime/themes/licenses/carbonfox.license b/runtime/themes/licenses/carbonfox.license new file mode 100644 index 000000000..4f446e776 --- /dev/null +++ b/runtime/themes/licenses/carbonfox.license @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 James Simpson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 06d5b88dee124650d899369651addcec670bb830 Mon Sep 17 00:00:00 2001 From: Aidan Gauland Date: Thu, 21 Nov 2024 11:17:40 +1300 Subject: [PATCH 31/62] feat(languages): add .livemd Markdown extension (#12034) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 1551d76b9..27047aea3 100644 --- a/languages.toml +++ b/languages.toml @@ -1600,7 +1600,7 @@ source = { git = "https://github.com/Flakebi/tree-sitter-tablegen", rev = "3e9c4 name = "markdown" scope = "source.md" injection-regex = "md|markdown" -file-types = ["md", "markdown", "mdx", "mkd", "mkdn", "mdwn", "mdown", "markdn", "mdtxt", "mdtext", "workbook", { glob = "PULLREQ_EDITMSG" }] +file-types = ["md", "livemd", "markdown", "mdx", "mkd", "mkdn", "mdwn", "mdown", "markdn", "mdtxt", "mdtext", "workbook", { glob = "PULLREQ_EDITMSG" }] roots = [".marksman.toml"] language-servers = [ "marksman", "markdown-oxide" ] indent = { tab-width = 2, unit = " " } From 56bb366f7e417c700a1fd00c6f92910392219621 Mon Sep 17 00:00:00 2001 From: zetashift Date: Wed, 20 Nov 2024 23:18:18 +0100 Subject: [PATCH 32/62] Update Unison grammar and queries (#12039) --- book/src/generated/lang-support.md | 2 +- languages.toml | 2 +- runtime/queries/unison/highlights.scm | 81 ++++++++++++++++++-------- runtime/queries/unison/indents.scm | 5 -- runtime/queries/unison/textobjects.scm | 15 +++++ 5 files changed, 74 insertions(+), 31 deletions(-) create mode 100644 runtime/queries/unison/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 9308bec88..2a01ec376 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -216,7 +216,7 @@ | typespec | ✓ | ✓ | ✓ | `tsp-server` | | typst | ✓ | | | `tinymist`, `typst-lsp` | | ungrammar | ✓ | | | | -| unison | ✓ | | ✓ | | +| unison | ✓ | ✓ | ✓ | | | uxntal | ✓ | | | | | v | ✓ | ✓ | ✓ | `v-analyzer` | | vala | ✓ | ✓ | | `vala-language-server` | diff --git a/languages.toml b/languages.toml index 27047aea3..025ccfa00 100644 --- a/languages.toml +++ b/languages.toml @@ -3333,7 +3333,7 @@ indent = { tab-width = 4, unit = " " } [[grammar]] name = "unison" -source = { git = "https://github.com/kylegoetz/tree-sitter-unison", rev = "1f505e2447fa876a87aee47ff3d70b9e141c744f" } +source = { git = "https://github.com/kylegoetz/tree-sitter-unison", rev = "3c97db76d3cdbd002dfba493620c2d5df2fd6fa9" } [[language]] name = "todotxt" diff --git a/runtime/queries/unison/highlights.scm b/runtime/queries/unison/highlights.scm index 711779295..4c8f0c234 100644 --- a/runtime/queries/unison/highlights.scm +++ b/runtime/queries/unison/highlights.scm @@ -9,32 +9,25 @@ ;; Keywords [ (kw_forall) - (type_kw) (kw_equals) (do) + (kw_let) (ability) (where) ] @keyword (kw_let) @keyword.function -(type_kw) @keyword.storage.type -(unique) @keyword.storage.modifier +(type_kw) @keyword.storage.modifier (structural) @keyword.storage.modifier ("use") @keyword.control.import - - -[ - (type_constructor) -] @constructor +(unique) @keyword.storage.modifier [ (operator) (pipe) (arrow_symbol) - (">") (or) (and) - (bang) ] @operator [ @@ -48,24 +41,62 @@ (blank_pattern) @variable.builtin +(pattern) @variable + +(use_clause) @keyword.import + ;; Types -(record_field name: (wordy_id) @variable.other.member type: (_) @type) -(type_constructor (type_name (wordy_id) @constructor)) -(ability_declaration type_name: (wordy_id) @type type_arg: (wordy_id) @variable.parameter) -(effect (wordy_id) @special) ;; NOTE: an effect is just like a type, but in signature we special case it +(record_field + (field_name) @variable.other.member + type: (regular_identifier) @type) + +(type_name) @type + +(type_declaration + (regular_identifier) @type.enum.variant) + +(ability_name + (path)? @namespace + (regular_identifier) @type) -;; Namespaces -(path) @namespace -(namespace) @namespace +(ability_declaration + (ability_name) @type + (type_argument) @variable.parameter) -;; Terms -(type_signature term_name: (path)? @variable term_name: (wordy_id) @variable) -(type_signature (wordy_id) @type) -(type_signature (term_type(delayed(wordy_id))) @type) +(type_constructor) @constructor -(term_definition param: (wordy_id) @variable.parameter) +(constructor + (constructor_name) @constructor) -(function_application function_name: (path)? function_name: (wordy_id) @function) +(constructor + type: (regular_identifier) @type) + +(effect + (regular_identifier) @special) ; NOTE: an effect is a special type + +; Namespaces +(path) @module + +(namespace) @module + +; Terms +(type_signature + term_name: (path) @module + term_name: (regular_identifier) @variable) + +(type_signature + term_name: (regular_identifier) @variable) + +(term_type) @type + +(term_definition + name: (path) @namespace) + +(term_definition + name: (regular_identifier) @variable) + +(term_definition + param: (regular_identifier) @variable.parameter) ;; Punctuation [ @@ -82,4 +113,6 @@ "]" ] @punctuation.bracket -(test_watch_expression (wordy_id) @keyword.directive) +(watch_expression) @keyword.directive + +(test_watch_expression) @keyword.directive diff --git a/runtime/queries/unison/indents.scm b/runtime/queries/unison/indents.scm index 6cb15517c..9ebe26ced 100644 --- a/runtime/queries/unison/indents.scm +++ b/runtime/queries/unison/indents.scm @@ -1,11 +1,6 @@ [ (term_definition) - (type_declaration) (pattern) - (tuple_or_parenthesized) - (literal_list) - (tuple_pattern) - (function_application) (exp_if) (constructor) (delay_block) diff --git a/runtime/queries/unison/textobjects.scm b/runtime/queries/unison/textobjects.scm new file mode 100644 index 000000000..02a908368 --- /dev/null +++ b/runtime/queries/unison/textobjects.scm @@ -0,0 +1,15 @@ +(term_declaration) @function.around + +(type_declaration) @class.inside +(record) @class.inside + +(comment) @comment.inside +(comment)+ @comment.around + +(doc_block) @comment.around + +(literal_list) @entry.around + +(parenthesized_or_tuple_pattern) @entry.around + +(pattern) @entry.around From d95b21ddd33675e0678774eb2b20b837b3750e60 Mon Sep 17 00:00:00 2001 From: Elizabeth Date: Fri, 15 Nov 2024 14:16:17 +0000 Subject: [PATCH 33/62] fix(swift): disabled auto-format & added .swift-format highlighting --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 025ccfa00..07fc5bb59 100644 --- a/languages.toml +++ b/languages.toml @@ -464,6 +464,7 @@ file-types = [ "avsc", "ldtk", "ldtkl", + { glob = ".swift-format" }, ] language-servers = [ "vscode-json-language-server" ] auto-format = true @@ -1984,7 +1985,6 @@ roots = [ "Package.swift" ] comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } formatter = { command = "swift-format" } -auto-format = true language-servers = [ "sourcekit-lsp" ] [[grammar]] From eeb5b7bbddfbde1e73c3ef45629b2d1f91b796ae Mon Sep 17 00:00:00 2001 From: Elizabeth Date: Fri, 15 Nov 2024 14:20:40 +0000 Subject: [PATCH 34/62] fix: added .DS_Store to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6a6fc782a..64a837dfd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ target helix-term/rustfmt.toml result runtime/grammars +.DS_Store From 8ed8d52e9d37ee37599f415398d750a12601bf79 Mon Sep 17 00:00:00 2001 From: blt-r <63462729+blt-r@users.noreply.github.com> Date: Thu, 21 Nov 2024 02:19:06 +0400 Subject: [PATCH 35/62] Treat .clangd and .clang-format as YAML (#12032) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 07fc5bb59..cfa151803 100644 --- a/languages.toml +++ b/languages.toml @@ -1323,7 +1323,7 @@ source = { git = "https://github.com/ikatyang/tree-sitter-vue", rev = "91fe27547 [[language]] name = "yaml" scope = "source.yaml" -file-types = ["yml", "yaml", { glob = ".prettierrc" }] +file-types = ["yml", "yaml", { glob = ".prettierrc" }, { glob = ".clangd" }, { glob = ".clang-format" }] comment-token = "#" indent = { tab-width = 2, unit = " " } language-servers = [ "yaml-language-server", "ansible-language-server" ] From 548fd574891a92104472bbd437a6762db55ac920 Mon Sep 17 00:00:00 2001 From: Yuki Kobayashi <137767097+aster-void@users.noreply.github.com> Date: Thu, 21 Nov 2024 07:19:23 +0900 Subject: [PATCH 36/62] fix(languages): treat tsconfig.json as jsonc (#12031) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index cfa151803..3f9f224c6 100644 --- a/languages.toml +++ b/languages.toml @@ -478,7 +478,7 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "73076 name = "jsonc" scope = "source.json" injection-regex = "jsonc" -file-types = ["jsonc"] +file-types = ["jsonc", { glob = "tsconfig.json" }] grammar = "json" language-servers = [ "vscode-json-language-server" ] auto-format = true From 4d0b7e57b146f3d386da989f60e58cbbf65a430e Mon Sep 17 00:00:00 2001 From: Javier Goday Date: Wed, 20 Nov 2024 23:19:58 +0100 Subject: [PATCH 37/62] Set tags color in monokai theme (#11917) --- runtime/themes/monokai.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/themes/monokai.toml b/runtime/themes/monokai.toml index 22e6d0639..dfa7040ce 100644 --- a/runtime/themes/monokai.toml +++ b/runtime/themes/monokai.toml @@ -1,5 +1,7 @@ # Author: Shafkath Shuhan +"tag" = { fg = "tag" } + "namespace" = { fg = "type" } "module" = { fg = "type" } @@ -116,3 +118,4 @@ cursor = "#a6a6a6" inactive_cursor = "#878b91" widget = "#1e1f1c" selection = "#414339" +tag = "#F92672" From 4dc46f9472526b9a14b7d2d69c258db1e787ec17 Mon Sep 17 00:00:00 2001 From: Keir Lawson Date: Wed, 20 Nov 2024 22:20:21 +0000 Subject: [PATCH 38/62] Make Spacebones theme picker selection more legible (#12064) --- runtime/themes/spacebones_light.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/themes/spacebones_light.toml b/runtime/themes/spacebones_light.toml index 7870f67ca..1d744019b 100644 --- a/runtime/themes/spacebones_light.toml +++ b/runtime/themes/spacebones_light.toml @@ -63,7 +63,7 @@ "ui.window" = { bg = "bg1" } "ui.help" = { bg = "bg1", fg = "fg1" } "ui.text" = { fg = "fg1" } -"ui.text.focus" = { fg = "fg1" } +"ui.text.focus" = { fg = "fg1", modifiers = ["bold"] } "ui.selection" = { bg = "hl2" } "ui.selection.primary" = { bg = "hl1" } "ui.cursor.primary" = { modifiers = ["reversed"] } From 83f1b98e806082242629f03f0202ee0453272e5e Mon Sep 17 00:00:00 2001 From: Robert Edmonds Date: Wed, 20 Nov 2024 17:20:59 -0500 Subject: [PATCH 39/62] languages: Add `ssh_config.d/*.conf` as a glob for sshclientconfig (#11947) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 3f9f224c6..c92b78932 100644 --- a/languages.toml +++ b/languages.toml @@ -2219,7 +2219,7 @@ source = { git = "https://github.com/staysail/tree-sitter-meson", rev = "32a83e8 [[language]] name = "sshclientconfig" scope = "source.sshclientconfig" -file-types = [{ glob = ".ssh/config" }, { glob = "/etc/ssh/ssh_config" }] +file-types = [{ glob = ".ssh/config" }, { glob = "/etc/ssh/ssh_config" }, { glob = "ssh_config.d/*.conf" } ] comment-token = "#" [[grammar]] From 188f701f5019cb9775bc2b44129971f7ae2ab395 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 20 Nov 2024 17:25:39 -0500 Subject: [PATCH 40/62] docs: Remove invalid '--path helix-term' from build instructions Fixes https://github.com/helix-editor/helix/issues/11557 --- book/src/building-from-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/building-from-source.md b/book/src/building-from-source.md index 42ed57a27..539e9cf86 100644 --- a/book/src/building-from-source.md +++ b/book/src/building-from-source.md @@ -117,7 +117,7 @@ to package the runtime into `/usr/lib/helix/runtime`. The rough steps a build script could follow are: 1. `export HELIX_DEFAULT_RUNTIME=/usr/lib/helix/runtime` -1. `cargo build --profile opt --locked --path helix-term` +1. `cargo build --profile opt --locked` 1. `cp -r runtime $BUILD_DIR/usr/lib/helix/` 1. `cp target/opt/hx $BUILD_DIR/usr/bin/hx` From d8e2aab2017a5ffdcbcb982d713ae5991e846744 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Wed, 20 Nov 2024 16:26:46 -0600 Subject: [PATCH 41/62] Document how to use modifier keys in macro remaps (#11930) --- book/src/remapping.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/book/src/remapping.md b/book/src/remapping.md index e794e1c27..ea63f292c 100644 --- a/book/src/remapping.md +++ b/book/src/remapping.md @@ -92,4 +92,5 @@ There are three kinds of commands that can be used in keymaps: 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. + command sequences are executed. Modifier keys (e.g. Alt+o) can be used + like `""`, e.g. `"@miw"` From b97c7456315f6f870fcd5eca6bca64d80d9172e9 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 20 Nov 2024 17:28:13 -0500 Subject: [PATCH 42/62] docs: Improve display of inline-diagnostics config sample Closes https://github.com/helix-editor/helix/issues/11591 --- book/src/editor.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/book/src/editor.md b/book/src/editor.md index 3edc38fc9..b5a5608af 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -452,7 +452,8 @@ fn main() { The new diagnostic rendering is not yet enabled by default. As soon as end of line or inline diagnostics are enabled the old diagnostics rendering is automatically disabled. The recommended default setting are: -``` +```toml +[editor] end-of-line-diagnostics = "hint" [editor.inline-diagnostics] cursor-line = "warning" # show warnings and errors on the cursorline inline From 8c6ca3c0fcf7a306c5f4b3061846b05d0c7e5c06 Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Wed, 20 Nov 2024 23:30:35 +0100 Subject: [PATCH 43/62] Update modus themes to 4.6.0 (#11949) --- runtime/themes/modus_operandi.toml | 2 +- runtime/themes/modus_operandi_deuteranopia.toml | 2 +- runtime/themes/modus_operandi_tinted.toml | 2 +- runtime/themes/modus_operandi_tritanopia.toml | 2 +- runtime/themes/modus_vivendi.toml | 4 ++-- runtime/themes/modus_vivendi_deuteranopia.toml | 4 ++-- runtime/themes/modus_vivendi_tinted.toml | 4 ++-- runtime/themes/modus_vivendi_tritanopia.toml | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime/themes/modus_operandi.toml b/runtime/themes/modus_operandi.toml index 362f97778..5d84741bc 100644 --- a/runtime/themes/modus_operandi.toml +++ b/runtime/themes/modus_operandi.toml @@ -1,6 +1,6 @@ # Author: Alexis Mousset # Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou -# Version 4.4.0 +# Version 4.6.0 # # Syntax highlighting diff --git a/runtime/themes/modus_operandi_deuteranopia.toml b/runtime/themes/modus_operandi_deuteranopia.toml index 27f19a7ad..24d460f6d 100644 --- a/runtime/themes/modus_operandi_deuteranopia.toml +++ b/runtime/themes/modus_operandi_deuteranopia.toml @@ -2,7 +2,7 @@ # modus_operandi.toml variant # # This variant is optimized for users with red-green color deficiency (deuteranopia) -# Version 4.4.0 +# Version 4.6.0 inherits = "modus_operandi" diff --git a/runtime/themes/modus_operandi_tinted.toml b/runtime/themes/modus_operandi_tinted.toml index 1f285361b..63c74f2a1 100644 --- a/runtime/themes/modus_operandi_tinted.toml +++ b/runtime/themes/modus_operandi_tinted.toml @@ -1,6 +1,6 @@ # Author: Alexis Mousset # modus_operandi.toml variant -# Version 4.4.0 +# Version 4.6.0 inherits = "modus_operandi" diff --git a/runtime/themes/modus_operandi_tritanopia.toml b/runtime/themes/modus_operandi_tritanopia.toml index 49d40e931..90fa59f6c 100644 --- a/runtime/themes/modus_operandi_tritanopia.toml +++ b/runtime/themes/modus_operandi_tritanopia.toml @@ -2,7 +2,7 @@ # modus_operandi.toml variant # # This variant is optimized for users with blue-yellow color deficiency (tritanopia) -# Version 4.4.0 +# Version 4.6.0 inherits = "modus_operandi" diff --git a/runtime/themes/modus_vivendi.toml b/runtime/themes/modus_vivendi.toml index 952683ee7..00c55e3b0 100644 --- a/runtime/themes/modus_vivendi.toml +++ b/runtime/themes/modus_vivendi.toml @@ -1,7 +1,7 @@ # Author: Matous Dzivjak # Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou # Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-theme.el -# Version 4.4.0 +# Version 4.6.0 # Syntax highlighting # ------------------- @@ -124,7 +124,7 @@ bg-inactive = "#303030" # Common accent foregrounds red = "#ff5f59" red-warmer = "#ff6b55" -red-cooler = "#ff7f9f" +red-cooler = "#ff7f86" red-faint = "#ff9580" red-intense = "#ff5f5f" green = "#44bc44" diff --git a/runtime/themes/modus_vivendi_deuteranopia.toml b/runtime/themes/modus_vivendi_deuteranopia.toml index 294196f31..a787359e0 100644 --- a/runtime/themes/modus_vivendi_deuteranopia.toml +++ b/runtime/themes/modus_vivendi_deuteranopia.toml @@ -1,7 +1,7 @@ # Author: Matous Dzivjak # Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou # Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-deuteranopia-theme.el -# Version 4.3.0 +# Version 4.6.0 inherits = "modus_vivendi" @@ -37,7 +37,7 @@ border = "#646464" # Common accent foregrounds red = "#ff5f59" red-warmer = "#ff6b55" -red-cooler = "#ff7f9f" +red-cooler = "#ff7f86" red-faint = "#ff9580" red-intense = "#ff5f5f" green = "#44bc44" diff --git a/runtime/themes/modus_vivendi_tinted.toml b/runtime/themes/modus_vivendi_tinted.toml index 2f9e2bb19..c7f9f76f3 100644 --- a/runtime/themes/modus_vivendi_tinted.toml +++ b/runtime/themes/modus_vivendi_tinted.toml @@ -1,7 +1,7 @@ # Author: Matous Dzivjak # Adapted from: https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou # Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tinted-theme.el -# Version 4.4.0 +# Version 4.6.0 inherits = "modus_vivendi" @@ -23,7 +23,7 @@ border = "#61647a" # Common accent foregrounds red = "#ff5f59" red-warmer = "#ff6b55" -red-cooler = "#ff7f9f" +red-cooler = "#ff7f86" red-faint = "#ff9f80" red-intense = "#ff5f5f" green = "#44bc44" diff --git a/runtime/themes/modus_vivendi_tritanopia.toml b/runtime/themes/modus_vivendi_tritanopia.toml index 7d8569d23..89cbee75e 100644 --- a/runtime/themes/modus_vivendi_tritanopia.toml +++ b/runtime/themes/modus_vivendi_tritanopia.toml @@ -1,7 +1,7 @@ # Author: Matous Dzivjak # Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou # Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tritanopia-theme.el -# Version 4.3.0 +# Version 4.6.0 inherits = "modus_vivendi" @@ -51,7 +51,7 @@ border = "#646464" # Common accent foregrounds red = "#ff5f59" red-warmer = "#ff6740" -red-cooler = "#ff6f9f" +red-cooler = "#ff7f86" red-faint = "#ff9070" red-intense = "#ff5f5f" green = "#44bc44" From 2f6a113fbea528845283161fac6ce697cb4b6996 Mon Sep 17 00:00:00 2001 From: Thomas Aarholt Date: Wed, 20 Nov 2024 23:35:06 +0100 Subject: [PATCH 44/62] Docs Key-Remapping: Move Commands to top as introduction (#11953) --- book/src/remapping.md | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/book/src/remapping.md b/book/src/remapping.md index ea63f292c..41e20f84b 100644 --- a/book/src/remapping.md +++ b/book/src/remapping.md @@ -4,10 +4,31 @@ Helix currently supports one-way key remapping through a simple TOML configurati file. (More powerful solutions such as rebinding via commands will be available in the future). +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. +* 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 or the `TypableCommandList` declaration in + the source code at [`helix-term/src/commands/typed.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands/typed.rs). +* 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. Modifier keys (e.g. Alt+o) can be used + like `""`, e.g. `"@miw"` + To remap keys, create a `config.toml` file in your `helix` configuration directory (default `~/.config/helix` on Linux systems) with a structure like this: +> 💡 To set a modifier + key as a keymap, type `A-X = ...` or `C-X = ...` for Alt + X or Ctrl + X. Combine with Shift using a dash, e.g. `C-S-esc`. +> Within macros, wrap them in `<>`, e.g. `` and `` to distinguish from the `A` or `C` keys. + ```toml # At most one section each of 'keys.normal', 'keys.insert' and 'keys.select' [keys.normal] @@ -18,6 +39,7 @@ w = "move_line_up" # Maps the 'w' key move_line_up "C-S-esc" = "extend_line" # Maps Ctrl-Shift-Escape to extend_line g = { a = "code_action" } # Maps `ga` to show possible code actions "ret" = ["open_below", "normal_mode"] # Maps the enter key to open_below then re-enter normal mode +"A-x" = "@x" # Maps Alt-x to a macro selecting the whole line and deleting it without yanking it [keys.insert] "A-x" = "normal_mode" # Maps Alt-X to enter normal mode @@ -74,23 +96,3 @@ Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes | Escape | `"esc"` | Keys can be disabled by binding them to the `no_op` command. - -## Commands - -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. -* 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 or the `TypableCommandList` declaration in - the source code at [`helix-term/src/commands/typed.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands/typed.rs). -* 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. Modifier keys (e.g. Alt+o) can be used - like `""`, e.g. `"@miw"` From 310bc04f23ff4fb9fa056aea9d5373890cac8103 Mon Sep 17 00:00:00 2001 From: Frans Skarman Date: Wed, 20 Nov 2024 23:35:49 +0100 Subject: [PATCH 45/62] Add spade support (#11448) Co-authored-by: Michael Davis --- book/src/generated/lang-support.md | 1 + languages.toml | 26 ++++++ pr.md | 24 +++++ runtime/queries/spade/highlights.scm | 130 +++++++++++++++++++++++++++ runtime/queries/spade/indents.scm | 27 ++++++ 5 files changed, 208 insertions(+) create mode 100644 pr.md create mode 100644 runtime/queries/spade/highlights.scm create mode 100644 runtime/queries/spade/indents.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 2a01ec376..18570695c 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -189,6 +189,7 @@ | sml | ✓ | | | | | snakemake | ✓ | | ✓ | `pylsp` | | solidity | ✓ | ✓ | | `solc` | +| spade | ✓ | | ✓ | `spade-language-server` | | spicedb | ✓ | | | | | sql | ✓ | ✓ | | | | sshclientconfig | ✓ | | | | diff --git a/languages.toml b/languages.toml index c92b78932..3c96d49fe 100644 --- a/languages.toml +++ b/languages.toml @@ -94,6 +94,7 @@ slint-lsp = { command = "slint-lsp", args = [] } solargraph = { command = "solargraph", args = ["stdio"] } solc = { command = "solc", args = ["--lsp"] } sourcekit-lsp = { command = "sourcekit-lsp" } +spade-language-server = {command = "spade-language-server"} svlangserver = { command = "svlangserver", args = [] } swipl = { command = "swipl", args = [ "-g", "use_module(library(lsp_server))", "-g", "lsp_server:main", "-t", "halt", "--", "stdio" ] } superhtml = { command = "superhtml", args = ["lsp"]} @@ -3876,3 +3877,28 @@ indent = { tab-width = 4, unit = " " } [[grammar]] name = "cylc" source = { git = "https://github.com/elliotfontaine/tree-sitter-cylc", rev = "30dd40d9bf23912e4aefa93eeb4c7090bda3d0f6" } + +[[language]] +name = "spade" +scope = "source.spade" +roots = ["swim.toml"] +file-types = ['spade'] +injection-regex = "spade" +comment-tokens = ["//", "///"] +block-comment-tokens = [ + { start = "/*", end = "*/" }, + { start = "/**", end = "*/" }, +] +language-servers = [ "spade-language-server" ] +indent = { tab-width = 4, unit = " " } + +[language.auto-pairs] +'(' = ')' +'{' = '}' +'[' = ']' +'"' = '"' +'<' = '>' + +[[grammar]] +name = "spade" +source = { git = "https://gitlab.com/spade-lang/tree-sitter-spade/", rev = "4d5b141017c61fe7e168e0a5c5721ee62b0d9572" } diff --git a/pr.md b/pr.md new file mode 100644 index 000000000..0ea65a5ad --- /dev/null +++ b/pr.md @@ -0,0 +1,24 @@ +Syntax symbol pickers +== + +This adds two new symbol picker commands that use tree-sitter rather than LSP. We run a new `symbols.scm` query across the file and extract tagged things like function definitions, types, classes, etc. For languages with unambiguous syntax this behaves roughly the same as the LSP symbol picker (`s`). It's less precise though since we don't have semantic info about the language. For example it can easily produce false positives for C/C++ because of preprocessor magic. + +The hope is to start introducing LSP-like features for navigation that can work without installing or running a language server. I made these two pickers in particular because I don't like LSP equivalents in ErlangLS - the document symbol picker can take a long time to show up during boot and the workspace symbol picker only searches for module names. The other motivation is to have some navigation features in cases when running a language server is too cumbersome - either to set up or because of resource constraints. For example `clangd` needs a fair amount of setup (`compile_commands.json`) that you might not want to do when quickly reading through a codebase. + +GitHub already uses tree-sitter like this to provide [imprecise code navigation](https://docs.github.com/en/repositories/working-with-files/using-files/navigating-code-on-github#about-navigating-code-on-github). It should be possible to find definitions and references as well like `gd` and `gr` - this is left as a follow-up. + +This PR also adds commands that either open the LSP symbol picker or the syntax one if a language server is not available. This way you can customize a language to not use the LSP symbol pickers, for example: + +```toml +[[language]] +name = "erlang" +language-servers = [{ name = "erlang-ls", except-features = ["document-symbols", "workspace-symbols"] }] +``` + +and `s` will use the syntax symbol picker, while `s` on a Rust file will still prefer the language server. + +--- + +Outstanding question - how closely should we try to match LSP symbol kind? Not at all? Should we have markup specific symbol kinds? (For example see markdown's `symbols.scm`). + +Also this PR needs docs on writing `symbols.scm` queries. diff --git a/runtime/queries/spade/highlights.scm b/runtime/queries/spade/highlights.scm new file mode 100644 index 000000000..08511b859 --- /dev/null +++ b/runtime/queries/spade/highlights.scm @@ -0,0 +1,130 @@ +(self) @variable.builtin + +(unit_definition (identifier) @function) + +(parameter (identifier) @variable.parameter) + +((pipeline_reg_marker) @keyword) + +(scoped_identifier + path: (identifier) @namespace) +(scoped_identifier + (scoped_identifier + name: (identifier) @namespace)) + +((builtin_type) @type.builtin) + +((identifier) @type.builtin + (#any-of? + @type.builtin + "uint" + "Option" + "Memory")) + +((identifier) @type.enum.variant.builtin + (#any-of? @type.enum.variant.builtin "Some" "None")) + +((pipeline_stage_name) @label) + +((stage_reference + stage: (identifier) @label)) + +[ + "pipeline" + "let" + "set" + "entity" + "fn" + "reg" + "reset" + "initial" + "inst" + "assert" + "struct" + "enum" + "stage" + "impl" + "port" + "decl" + "mod" + "where" + "trait" +] @keyword + +[ + "use" +] @keyword.import + +[ + "$if" + "$else" + "$config" +] @keyword.directive + +((comptime_if ["{" "}"] @keyword.directive)) +((comptime_else ["{" "}"] @keyword.directive)) + +((attribute) ["#" "[" "]"] @punctuation.delimiter) + +[ + "else" + "if" + "match" +] @keyword.control.conditional + +(bool_literal) @constant.builtin.boolean +(int_literal) @constant.numeric.integer + +[ + "&" + "inv" + "-" + "=>" + ">" + "<" + "::<" + "::$<" + "=" + "->" + "~" + "!" +] @operator + + +((op_add) @operator) +((op_sub) @operator) +((op_mul) @operator) +((op_equals) @operator) +((op_lt) @operator) +((op_gt) @operator) +((op_le) @operator) +((op_ge) @operator) +((op_lshift) @operator) +((op_rshift) @operator) +((op_bitwise_and) @operator) +((op_bitwise_xor) @operator) +((op_bitwise_or) @operator) +((op_logical_and) @operator) +((op_logical_or) @operator) + + +[ + (line_comment) + (block_comment) +] @comment + +[ + (doc_comment) +] @comment.block.documentation + + +((identifier) @type + (#match? @type "[A-Z]")) + +((scoped_identifier + name: (identifier) @type) + (#match? @type "^[A-Z]")) + +((identifier) @constant + (#match? @constant "^[A-Z][A-Z\\d_]*$")) + diff --git a/runtime/queries/spade/indents.scm b/runtime/queries/spade/indents.scm new file mode 100644 index 000000000..dc30bdc3e --- /dev/null +++ b/runtime/queries/spade/indents.scm @@ -0,0 +1,27 @@ + +[ + (unit_definition) + (struct_definition) + (enum_definition) + (enum_member) + (impl) + (mod) + (argument_list) + (let_binding) + (block) + (tuple_literal) + (array_literal) + (paren_expression) + (turbofish) + (generic_parameters) + (named_unpack) + (positional_unpack) + (tuple_pattern) +] @indent + +[ + "}" + "]" + ")" +] @outdent + From b501a300e9ffa97a5d4bfa669f63661701bc6ddc Mon Sep 17 00:00:00 2001 From: Krishan <54745129+krish-r@users.noreply.github.com> Date: Thu, 21 Nov 2024 04:06:28 +0530 Subject: [PATCH 46/62] Update Zig's comment tokens (#12049) --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 3c96d49fe..500273d87 100644 --- a/languages.toml +++ b/languages.toml @@ -1384,7 +1384,7 @@ injection-regex = "zig" file-types = ["zig", "zon"] roots = ["build.zig"] auto-format = true -comment-token = "//" +comment-tokens = ["//", "///", "//!"] language-servers = [ "zls" ] indent = { tab-width = 4, unit = " " } formatter = { command = "zig" , args = ["fmt", "--stdin"] } From ed7e5bd8dc5c25b50118f3ea588f6ac25d5a00c7 Mon Sep 17 00:00:00 2001 From: Travis Harmon Date: Wed, 20 Nov 2024 16:36:59 -0600 Subject: [PATCH 47/62] Use bold statusline for mode indicator in onedarker theme (#11958) --- runtime/themes/onedarker.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/themes/onedarker.toml b/runtime/themes/onedarker.toml index ffa3ae2dc..221b394b0 100644 --- a/runtime/themes/onedarker.toml +++ b/runtime/themes/onedarker.toml @@ -74,9 +74,9 @@ "ui.statusline" = { fg = "white", bg = "light-black" } "ui.statusline.inactive" = { fg = "light-gray", bg = "light-black" } -"ui.statusline.normal" = { fg = "light-black", bg = "purple" } -"ui.statusline.insert" = { fg = "light-black", bg = "green" } -"ui.statusline.select" = { fg = "light-black", bg = "cyan" } +"ui.statusline.normal" = { fg = "light-black", bg = "purple", modifiers = ["bold"] } +"ui.statusline.insert" = { fg = "light-black", bg = "green", modifiers = ["bold"] } +"ui.statusline.select" = { fg = "light-black", bg = "cyan", modifiers = ["bold"] } "ui.bufferline" = { fg = "light-gray", bg = "light-black" } "ui.bufferline.active" = { fg = "light-black", bg = "blue", underline = { color = "light-black", style = "line" } } From 843c058f0bdd9d821cb2d51114389ab2727c7c6f Mon Sep 17 00:00:00 2001 From: Heath Stewart Date: Wed, 20 Nov 2024 14:38:15 -0800 Subject: [PATCH 48/62] Use latest tree-sitter-bicep, support bicepparams (#11525) Co-authored-by: Michael Davis --- languages.toml | 4 +- runtime/queries/bicep/highlights.scm | 255 ++++++++++++++++++++++----- 2 files changed, 209 insertions(+), 50 deletions(-) diff --git a/languages.toml b/languages.toml index 500273d87..5bb3d298d 100644 --- a/languages.toml +++ b/languages.toml @@ -2811,7 +2811,7 @@ source = { git = "https://github.com/inko-lang/tree-sitter-inko", rev = "7860637 [[language]] name = "bicep" scope = "source.bicep" -file-types = ["bicep"] +file-types = ["bicep","bicepparam"] auto-format = true comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } @@ -2820,7 +2820,7 @@ language-servers = [ "bicep-langserver" ] [[grammar]] name = "bicep" -source = { git = "https://github.com/the-mikedavis/tree-sitter-bicep", rev = "d8e097fcfa143854861ef737161163a09cc2916b" } +source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-bicep", rev = "0092c7d1bd6bb22ce0a6f78497d50ea2b87f19c0" } [[language]] name = "qml" diff --git a/runtime/queries/bicep/highlights.scm b/runtime/queries/bicep/highlights.scm index b6f928726..b80de7fd7 100644 --- a/runtime/queries/bicep/highlights.scm +++ b/runtime/queries/bicep/highlights.scm @@ -1,73 +1,232 @@ -; Keywords +; Includes +[ + "import" + "provider" + "with" + "as" + "from" +] @keyword.control.import + +; Namespaces +(module_declaration + (identifier) @namespace) + +; Builtins +(primitive_type) @type.builtin + +((member_expression + object: (identifier) @type.builtin) + (#eq? @type.builtin "sys")) + +; Functions +(call_expression + function: (identifier) @function) + +(user_defined_function + name: (identifier) @function) + +; Properties +(object_property + (identifier) @function.method + ":" @punctuation.delimiter + (_)) + +(object_property + (compatible_identifier) @function.method + ":" @punctuation.delimiter + (_)) + +(property_identifier) @function.method + +; Attributes +(decorator + "@" @attribute) + +(decorator + (call_expression + (identifier) @attribute)) + +(decorator + (call_expression + (member_expression + object: (identifier) @attribute + property: (property_identifier) @attribute))) + +; Types +(type_declaration + (identifier) @type) +(type_declaration + (identifier) + "=" + (identifier) @type) + +(type + (identifier) @type) + +(resource_declaration + (identifier) @type) + +(resource_expression + (identifier) @type) + +; Parameters +(parameter_declaration + (identifier) @variable.parameter + (_)) + +(call_expression + function: (_) + (arguments + (identifier) @variable.parameter)) + +(call_expression + function: (_) + (arguments + (member_expression + object: (identifier) @variable.parameter))) + +(parameter + . + (identifier) @variable.parameter) + +; Variables +(variable_declaration + (identifier) @variable + (_)) + +(metadata_declaration + (identifier) @variable + (_)) + +(output_declaration + (identifier) @variable + (_)) + +(object_property + (_) + ":" + (identifier) @variable) + +(for_statement + "for" + (for_loop_parameters + (loop_variable) @variable + (loop_enumerator) @variable)) + +; Conditionals +"if" @keyword.conditional + +(ternary_expression + "?" @keyword.control.conditional + ":" @keyword.control.conditional) + +; Loops +(for_statement + "for" @keyword.control.repeat + "in" + ":" @punctuation.delimiter) + +; Keywords [ "module" - "var" + "metadata" + "output" "param" - "import" "resource" "existing" - "if" "targetScope" - "output" + "type" + "var" + "using" + "test" ] @keyword -; Functions +"func" @keyword.function -(decorator) @function.builtin +"assert" @keyword.control.exception -(functionCall) @function +; Operators +[ + "+" + "-" + "*" + "/" + "%" + "||" + "&&" + "|" + "==" + "!=" + "=~" + "!~" + ">" + ">=" + "<=" + "<" + "??" + "=" + "!" + ".?" +] @operator -(functionCall - (functionArgument - (variableAccess) @variable)) +(subscript_expression + "?" @operator) -; Literals/Types +(nullable_type + "?" @operator) -[ - "(" - ")" - "[" - "]" - "{" - "}" -] @punctuation.bracket +"in" @keyword.operator -(resourceDeclaration - (string - (stringLiteral) @string.special)) +; Literals +(string) @string -(moduleDeclaration - (string - (stringLiteral) @string.special)) +(escape_sequence) @constant.character -[ - (string) - (stringLiteral) -] @string +(number) @constant.number -(nullLiteral) @keyword -(booleanLiteral) @constant.builtin.boolean -(integerLiteral) @constant.numeric.integer -(comment) @comment +(boolean) @constant.builtin.boolean -(string - (variableAccess - (identifier) @variable)) +(null) @constant.builtin -(type) @type +; Misc +(compatible_identifier + "?" @punctuation.special) -; Variables +(nullable_return_type) @punctuation.special + +[ + "{" + "}" +] @punctuation.bracket -(localVariable) @variable +[ + "[" + "]" +] @punctuation.bracket -; Statements +[ + "(" + ")" +] @punctuation.bracket -(object - (objectProperty - (identifier) @identifier)) +[ + "." + ":" + "::" + "=>" +] @punctuation.delimiter -(propertyAccess - (identifier) @identifier) - -(ifCondition) @keyword.control.conditional +; Interpolation +(interpolation + "${" @punctuation.special + "}" @punctuation.special) + +(interpolation + (identifier) @variable) + +; Comments +[ + (comment) + (diagnostic_comment) +] @comment From 7ee66c06582ffc971754e485002b64d853683776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Fern=C3=A1ndez=20Serrata?= <76864299+Rudxain@users.noreply.github.com> Date: Wed, 20 Nov 2024 18:39:06 -0400 Subject: [PATCH 49/62] suggest `*.desktop` for AppImage (#10823) Co-authored-by: Michael Davis --- book/src/package-managers.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/book/src/package-managers.md b/book/src/package-managers.md index 441de45e0..a08baccd1 100644 --- a/book/src/package-managers.md +++ b/book/src/package-managers.md @@ -101,7 +101,15 @@ Download the official Helix AppImage from the [latest releases](https://github.c chmod +x helix-*.AppImage # change permission for executable mode ./helix-*.AppImage # run helix ``` - + +You can optionally [add the `.desktop` file](./building-from-source.md#configure-the-desktop-shortcut). Helix must be installed in `PATH` with the name `hx`. For example: +```sh +mkdir -p "$HOME/.local/bin" +mv helix-*.AppImage "$HOME/.local/bin/hx" +``` + +and make sure `~/.local/bin` is in your `PATH`. + ## macOS ### Homebrew Core From 887bbbc37508c68d6e65bc52d7e58b20fa9a850c Mon Sep 17 00:00:00 2001 From: Yerlan Date: Wed, 20 Nov 2024 23:39:34 +0100 Subject: [PATCH 50/62] Adding NestedText language support (#11987) Co-authored-by: Yerlan Sergaziyev --- book/src/generated/lang-support.md | 1 + languages.toml | 9 +++++++++ runtime/queries/nestedtext/highlights.scm | 1 + runtime/queries/nestedtext/indents.scm | 1 + runtime/queries/nestedtext/injections.scm | 1 + runtime/queries/nestedtext/textobjects.scm | 1 + 6 files changed, 14 insertions(+) create mode 100644 runtime/queries/nestedtext/highlights.scm create mode 100644 runtime/queries/nestedtext/indents.scm create mode 100644 runtime/queries/nestedtext/injections.scm create mode 100644 runtime/queries/nestedtext/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 18570695c..6c250ec4f 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -136,6 +136,7 @@ | move | ✓ | | | | | msbuild | ✓ | | ✓ | | | nasm | ✓ | ✓ | | | +| nestedtext | ✓ | ✓ | ✓ | | | nickel | ✓ | | ✓ | `nls` | | nim | ✓ | ✓ | ✓ | `nimlangserver` | | nix | ✓ | ✓ | | `nil`, `nixd` | diff --git a/languages.toml b/languages.toml index 5bb3d298d..026c8bcd3 100644 --- a/languages.toml +++ b/languages.toml @@ -1334,6 +1334,15 @@ injection-regex = "yml|yaml" name = "yaml" source = { git = "https://github.com/ikatyang/tree-sitter-yaml", rev = "0e36bed171768908f331ff7dff9d956bae016efb" } +[[language]] +name = "nestedtext" +scope = "text.nested" +injection-regex = "nestedtext" +file-types = ["nt"] +comment-token = "#" +indent = { tab-width = 4, unit = " " } +grammar = "yaml" + [[language]] name = "haskell" scope = "source.haskell" diff --git a/runtime/queries/nestedtext/highlights.scm b/runtime/queries/nestedtext/highlights.scm new file mode 100644 index 000000000..4ba254e82 --- /dev/null +++ b/runtime/queries/nestedtext/highlights.scm @@ -0,0 +1 @@ +; inherits: yaml diff --git a/runtime/queries/nestedtext/indents.scm b/runtime/queries/nestedtext/indents.scm new file mode 100644 index 000000000..4ba254e82 --- /dev/null +++ b/runtime/queries/nestedtext/indents.scm @@ -0,0 +1 @@ +; inherits: yaml diff --git a/runtime/queries/nestedtext/injections.scm b/runtime/queries/nestedtext/injections.scm new file mode 100644 index 000000000..4ba254e82 --- /dev/null +++ b/runtime/queries/nestedtext/injections.scm @@ -0,0 +1 @@ +; inherits: yaml diff --git a/runtime/queries/nestedtext/textobjects.scm b/runtime/queries/nestedtext/textobjects.scm new file mode 100644 index 000000000..4ba254e82 --- /dev/null +++ b/runtime/queries/nestedtext/textobjects.scm @@ -0,0 +1 @@ +; inherits: yaml From 6101b3a7a3dfd18039e117e0c38682e77f15a889 Mon Sep 17 00:00:00 2001 From: spx01 <42381535+spx01@users.noreply.github.com> Date: Thu, 21 Nov 2024 00:40:43 +0200 Subject: [PATCH 51/62] fix: simplify text reflowing strategy to improve language compatibility (#12048) --- helix-core/src/wrap.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helix-core/src/wrap.rs b/helix-core/src/wrap.rs index f32d6f4bc..337b389ae 100644 --- a/helix-core/src/wrap.rs +++ b/helix-core/src/wrap.rs @@ -4,6 +4,8 @@ use textwrap::{Options, WordSplitter::NoHyphenation}; /// Given a slice of text, return the text re-wrapped to fit it /// within the given width. pub fn reflow_hard_wrap(text: &str, text_width: usize) -> SmartString { - let options = Options::new(text_width).word_splitter(NoHyphenation); + let options = Options::new(text_width) + .word_splitter(NoHyphenation) + .word_separator(textwrap::WordSeparator::AsciiSpace); textwrap::refill(text, options).into() } From b855cd0cdab8bdb1e7adb24b41a09c9b4ce8c2a6 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 20 Nov 2024 17:57:57 -0500 Subject: [PATCH 52/62] clipboard: Fix builtin_names for x-clip, x-sel, win-32-yank Copy/paste error from #10839 --- helix-view/src/clipboard.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index 234b91fe3..cd8a4eeb5 100644 --- a/helix-view/src/clipboard.rs +++ b/helix-view/src/clipboard.rs @@ -190,9 +190,9 @@ mod external { // These names should match the config option names from Serde Self::Pasteboard => builtin_name("pasteboard", &PASTEBOARD), Self::Wayland => builtin_name("wayland", &WL_CLIPBOARD), - Self::XClip => builtin_name("x-clip", &WL_CLIPBOARD), - Self::XSel => builtin_name("x-sel", &WL_CLIPBOARD), - Self::Win32Yank => builtin_name("win-32-yank", &WL_CLIPBOARD), + Self::XClip => builtin_name("x-clip", &XCLIP), + Self::XSel => builtin_name("x-sel", &XSEL), + Self::Win32Yank => builtin_name("win-32-yank", &WIN32), Self::Tmux => builtin_name("tmux", &TMUX), Self::Termux => builtin_name("termux", &TERMUX), #[cfg(windows)] From 467fad51b1a604515f0add44e0675105ae393f79 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 20 Nov 2024 18:09:01 -0500 Subject: [PATCH 53/62] clipboard: Sway builtin provider yank and paste commands The configuration here is not super intuitive - in order to yank from a clipboard provider we want it to paste the clipboard and in order to paste to the clipboard we want it to yank the contents we pass. This swaps the programs for yank and paste to align with that. Ref #10839 --- helix-view/src/clipboard.rs | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index cd8a4eeb5..5e16461e0 100644 --- a/helix-view/src/clipboard.rs +++ b/helix-view/src/clipboard.rs @@ -359,44 +359,44 @@ mod external { command_provider! { TMUX, - yank => "tmux", "load-buffer", "-w", "-"; - paste => "tmux", "save-buffer", "-"; + yank => "tmux", "save-buffer", "-"; + paste => "tmux", "load-buffer", "-w", "-"; } command_provider! { PASTEBOARD, - yank => "pbcopy"; - paste => "pbpaste"; + yank => "pbpaste"; + paste => "pbcopy"; } command_provider! { WL_CLIPBOARD, - yank => "wl-copy", "--type", "text/plain"; - paste => "wl-paste", "--no-newline"; - yank_primary => "wl-copy", "-p", "--type", "text/plain"; - paste_primary => "wl-paste", "-p", "--no-newline"; + yank => "wl-paste", "--no-newline"; + paste => "wl-copy", "--type", "text/plain"; + yank_primary => "wl-paste", "-p", "--no-newline"; + paste_primary => "wl-copy", "-p", "--type", "text/plain"; } command_provider! { XCLIP, - yank => "xclip", "-i", "-selection", "clipboard"; - paste => "xclip", "-o", "-selection", "clipboard"; - yank_primary => "xclip", "-i"; - paste_primary => "xclip", "-o"; + yank => "xclip", "-o", "-selection", "clipboard"; + paste => "xclip", "-i", "-selection", "clipboard"; + yank_primary => "xclip", "-o"; + paste_primary => "xclip", "-i"; } command_provider! { XSEL, - yank => "xsel", "-i", "-b"; - paste => "xsel", "-o", "-b"; - yank_primary => "xsel", "-i"; - paste_primary => "xsel", "-o"; + yank => "xsel", "-o", "-b"; + paste => "xsel", "-i", "-b"; + yank_primary => "xsel", "-o"; + paste_primary => "xsel", "-i"; } command_provider! { WIN32, - yank => "win32yank.exe", "-i", "--crlf"; - paste => "win32yank.exe", "-o", "--lf"; + yank => "win32yank.exe", "-o", "--lf"; + paste => "win32yank.exe", "-i", "--crlf"; } command_provider! { TERMUX, - yank => "termux-clipboard-set"; - paste => "termux-clipboard-get"; + yank => "termux-clipboard-get"; + paste => "termux-clipboard-set"; } #[cfg(feature = "term")] From 15b478d433049a77737c2bf80e38951e9de565c2 Mon Sep 17 00:00:00 2001 From: Arthur <150680976+arthsmn@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:16:49 +0000 Subject: [PATCH 54/62] hyprlang: add hyprls language server (#11056) Co-authored-by: Michael Davis --- book/src/generated/lang-support.md | 2 +- languages.toml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 6c250ec4f..20f861a5d 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -91,7 +91,7 @@ | hosts | ✓ | | | | | html | ✓ | | | `vscode-html-language-server`, `superhtml` | | hurl | ✓ | ✓ | ✓ | | -| hyprlang | ✓ | | ✓ | | +| hyprlang | ✓ | | ✓ | `hyprls` | | idris | | | | `idris2-lsp` | | iex | ✓ | | | | | ini | ✓ | | | | diff --git a/languages.toml b/languages.toml index 026c8bcd3..00df4bf45 100644 --- a/languages.toml +++ b/languages.toml @@ -44,6 +44,7 @@ gleam = { command = "gleam", args = ["lsp"] } glsl_analyzer = { command = "glsl_analyzer" } graphql-language-service = { command = "graphql-lsp", args = ["server", "-m", "stream"] } haskell-language-server = { command = "haskell-language-server-wrapper", args = ["--lsp"] } +hyprls = { command = "hyprls" } idris2-lsp = { command = "idris2-lsp" } intelephense = { command = "intelephense", args = ["--stdio"] } jdtls = { command = "jdtls" } @@ -3577,6 +3578,7 @@ roots = ["hyprland.conf"] file-types = [ { glob = "hyprland.conf" }, { glob = "hyprpaper.conf" }, { glob = "hypridle.conf" }, { glob = "hyprlock.conf" } ] comment-token = "#" grammar = "hyprlang" +language-servers = ["hyprls"] [[grammar]] name = "hyprlang" From 8807dbfc4051af95c76d5ef591476aadb5a60eb4 Mon Sep 17 00:00:00 2001 From: PORTALSURFER <41680373+PORTALSURFER@users.noreply.github.com> Date: Thu, 21 Nov 2024 00:20:04 +0100 Subject: [PATCH 55/62] Update current hex themes, add a new hex theme (#10849) --- runtime/themes/hex_lavender.toml | 18 +++++++--- runtime/themes/hex_poison.toml | 41 +++++++++++++++++++++ runtime/themes/hex_steel.toml | 61 ++++++++++++++++++-------------- runtime/themes/hex_toxic.toml | 15 ++++++-- 4 files changed, 103 insertions(+), 32 deletions(-) create mode 100644 runtime/themes/hex_poison.toml diff --git a/runtime/themes/hex_lavender.toml b/runtime/themes/hex_lavender.toml index d7c54be69..b14f3cafd 100644 --- a/runtime/themes/hex_lavender.toml +++ b/runtime/themes/hex_lavender.toml @@ -1,13 +1,15 @@ +# Author : portalsurfer + inherits = "hex_steel" [palette] t1 = "#0e0e0d" -t2 = "#121311" +t2 = "#181a17" t3 = "#2b3444" t4 = "#61586f" t5 = "#686e73" t6 = "#878480" -t7 = "#897dca" +t7 = "#8e80de" t8 = "#7b89a3" t9 = "#bcb6ba" t10 = "#9db2b8" @@ -20,12 +22,20 @@ highlight_three = "#29bbff" black = "#000000" selection = "#290019" +selection_fg = "#958e9a" -comment = "#9aacfe" +comment = "#404768" comment_doc = "#0affa9" error = "#ff0900" warning = "#ffbf00" display = "#57ff89" info = "#dad7d5" -# + +hints = "#44273f" +ruler = "#1c1f1b" + +diff_minus = "#ff4000" +diff_delta = "#0078bd" +diff_plus = "#c9d400" +diff_delta_moved = "#0048bd" \ No newline at end of file diff --git a/runtime/themes/hex_poison.toml b/runtime/themes/hex_poison.toml new file mode 100644 index 000000000..0d6e13eee --- /dev/null +++ b/runtime/themes/hex_poison.toml @@ -0,0 +1,41 @@ +# Author : portalsurfer + +inherits = "hex_steel" + +[palette] +t1 = "#121211" +t2 = "#1e1f1b" +t3 = "#4c513a" +t4 = "#5a6052" +t5 = "#6f6d6f" +t8 = "#7e808a" +t7 = "#b1b354" +t10 = "#6fa197" +t9 = "#3f4a4e" +t6 = "#98acaa" +t11 = "#6fd7a8" + +highlight = "#ff2e5f" +highlight_two = "#0affa9" +highlight_three = "#d7ff52" + +black = "#000000" + +selection = "#290019" +selection_fg = "#c8e732" + +comment = "#396884" +comment_doc = "#234048" + +error = "#c73500" +warning = "#dcbb00" +display = "#57ff89" +info = "#dad7d5" + +hints = "#313d3c" +ruler = "#21221e" + +diff_minus = "#ff4000" +diff_delta = "#16a7c7" +diff_plus = "#c9d400" +diff_delta_moved = "#0048bd" \ No newline at end of file diff --git a/runtime/themes/hex_steel.toml b/runtime/themes/hex_steel.toml index fb4fc1fd8..d133cf7f3 100644 --- a/runtime/themes/hex_steel.toml +++ b/runtime/themes/hex_steel.toml @@ -1,14 +1,16 @@ +# Author : portalsurfer + "comment" = { fg = "comment" } "comment.block.documentation" = { bg = "comment_doc", modifiers = ["italic"] } "constant" = { fg = "t11" } "function" = { fg = "t10" } -"function.method" = { fg = "t10" } +"function.method" = { fg = "t7" } "function.macro" = { fg = "t7" } "keyword.storage.modifier" = { fg = "t7" } "keyword.control.import" = { fg = "t8" } "keyword.control" = { fg = "t8" } -"keyword.function" = { fg = "t7" } +"keyword.function" = { fg = "t11" } "keyword" = { fg = "t6" } "operator" = { fg = "t8" } "punctuation" = { fg = "t9" } @@ -18,6 +20,8 @@ "type" = { fg = "t8", modifiers = ["bold"] } "namespace" = { fg = "t6", modifiers = ["bold"] } "variable" = { fg = "t4" } +"variable.parameter" = { fg = "t6" } +"variable.other.member" = { fg = "t3" } "label" = { fg = "t4" } "diff.plus" = { fg = "diff_plus" } @@ -25,10 +29,12 @@ "diff.delta.moved" = { fg = "diff_delta_moved" } "diff.minus" = { fg = "diff_minus" } -"ui.cursor.insert" = { fg = "t2", bg = "highlight" } -"ui.cursor.select" = { fg = "t2", bg = "highlight_two" } -"ui.cursor" = { fg = "t1", bg = "highlight_three" } -"ui.cursor.match" = { fg = "highlight", bg = "selection", modifiers = ["bold"] } +"ui.cursor.primary.insert" = { fg = "t2", bg = "highlight" } +"ui.cursor.primary.select" = { fg = "t2", bg = "highlight_two" } +"ui.cursor.primary" = { fg = "t1", bg = "highlight_three" } +"ui.cursor.match" = { fg = "highlight", bg = "t1", modifiers = ["bold"] } +"ui.cursorline.primary" = { bg = "ruler" } +"ui.cursorline.secondary" = { bg = "ruler" } "ui.linenr" = { fg = "t3", bg = "t2" } "ui.linenr.selected" = { fg = "highlight_three", bg = "t2" } @@ -42,10 +48,7 @@ "ui.popup" = { fg = "t4", bg = "t1" } "ui.window" = { fg = "t4" } -"ui.selection.primary" = { bg = "selection" } -"ui.selection" = { bg = "selection" } - -"ui.cursorline.primary" = { bg = "t1" } +"ui.selection" = { fg = "selection_fg", bg = "selection" } "ui.statusline" = { fg = "t4", bg = "t1" } "ui.statusline.inactive" = { fg = "t4", bg = "t1" } @@ -55,17 +58,20 @@ "ui.text" = { fg = "t4" } "ui.text.focus" = { fg = "highlight_three", modifiers = ["bold"] } -# -"ui.virtual.ruler" = { bg = "t1" } + +"ui.virtual.ruler" = { bg = "ruler" } "ui.virtual.indent-guide" = { fg = "t3" } "ui.virtual.whitespace" = { fg = "t3" } +"ui.virtual.jump-label" = { fg = "t11", modifiers = ["bold"] } +"ui.virtual.inlay-hint" = { fg = "hints", modifiers = ["bold"] } + +"ui.bufferline" = { fg = "t3", bg = "t1" } +"ui.bufferline.active" = { fg = "t7", bg = "t2" } "diagnostic.error" = { underline = { color = "error", style = "curl" } } "diagnostic.warning" = { underline = { color = "warning", style = "curl" } } "diagnostic.info" = { underline = { color = "info", style = "curl" } } "diagnostic.hint" = { underline = { color = "display", style = "curl" } } -"diagnostic.unnecessary" = { modifiers = ["dim"] } -"diagnostic.deprecated" = { modifiers = ["crossed_out"] } "error" = { fg = "error", modifiers = ["bold"] } "warning" = { fg = "warning", modifiers = ["bold"] } @@ -73,14 +79,14 @@ "hint" = { fg = "display", modifiers = ["bold"] } "special" = { fg = "t7", modifiers = ["bold"] } -"markup.heading" = { fg = "t4" } -"markup.list" = { fg = "t4" } +"markup.heading" = { fg = "t7" } +"markup.list" = { fg = "t7" } "markup.bold" = { fg = "t4" } "markup.italic" = { fg = "t4" } "markup.strikethrough" = { fg = "t4", modifiers = ["crossed_out"] } -"markup.link.url" = { fg = "t4", modifiers = ["underlined"] } -"markup.link.text" = { fg = "t4" } -"markup.quote" = { fg = "t4" } +"markup.link.url" = { fg = "t11", modifiers = ["underlined"] } +"markup.link.text" = { fg = "t11" } +"markup.quote" = { fg = "t5" } "markup.raw" = { fg = "t4" } [palette] @@ -93,25 +99,28 @@ t6 = "#6e8789" t7 = "#d85c60" t8 = "#9bc1bb" t9 = "#b5c5c5" -t10 = "#c0d0ce" +t10 = "#c3c3bd" t11 = "#f78c5e" -highlight = "#3f36f2" +highlight = "#f23672" highlight_two = "#f69c3c" highlight_three = "#d4d987" -selection = "#032d4a" +selection = "#4a9aa6" +selection_fg = "#080a0b" black = "#000000" -comment = "#d4d987" +comment = "#654642" comment_doc = "#234048" +hints = "#31353c" +ruler = "#222320" -error = "#ff0900" +error = "#ff4000" warning = "#ffbf00" display = "#42baff" info = "#dad7d5" -diff_minus = "#ff0900" +diff_minus = "#ff4000" diff_delta = "#0078bd" -diff_plus = "#87a800" +diff_plus = "#c9d400" diff_delta_moved = "#0048bd" diff --git a/runtime/themes/hex_toxic.toml b/runtime/themes/hex_toxic.toml index 33bfa6e5f..33f51185b 100644 --- a/runtime/themes/hex_toxic.toml +++ b/runtime/themes/hex_toxic.toml @@ -1,3 +1,5 @@ +# Author : portalsurfer + inherits = "hex_steel" [palette] @@ -19,12 +21,21 @@ highlight_three = "#f8ed8b" black = "#000000" -selection = "#382e1e" +selection = "#b10656" +selection_fg = "#101719" -comment = "#61bdd1" +comment = "#417e8c" comment_doc = "#234048" error = "#ff0900" warning = "#ffbf00" display = "#57ff89" info = "#dad7d5" + +hints = "#39515c" +ruler = "#1e3039" + +diff_minus = "#ff4000" +diff_delta = "#0078bd" +diff_plus = "#c9d400" +diff_delta_moved = "#0048bd" \ No newline at end of file From b92e8abfb3629970e8df97ae87f92c3989af66e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teemu=20S=C3=A4ilynoja?= <33978952+TeemuSailynoja@users.noreply.github.com> Date: Thu, 21 Nov 2024 01:20:51 +0200 Subject: [PATCH 56/62] Update Snakemake language config (#11936) --- languages.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 00df4bf45..84171af3f 100644 --- a/languages.toml +++ b/languages.toml @@ -3868,11 +3868,15 @@ source = { git = "https://github.com/Decurity/tree-sitter-circom", rev = "021505 name = "snakemake" scope = "source.snakemake" roots = ["Snakefile", "config.yaml", "environment.yaml", "workflow/"] -file-types = ["smk", "Snakefile"] +file-types = ["smk", { glob = "Snakefile" } ] comment-tokens = ["#", "##"] indent = { tab-width = 2, unit = " " } language-servers = ["pylsp" ] +[language.formatter] +command = "snakefmt" +args = ["-"] + [[grammar]] name = "snakemake" source = { git = "https://github.com/osthomas/tree-sitter-snakemake", rev = "e909815acdbe37e69440261ebb1091ed52e1dec6" } From 9e171e7d1d644654010b54c775a1d688b6d56fb2 Mon Sep 17 00:00:00 2001 From: yehor <64604791+oworope@users.noreply.github.com> Date: Thu, 21 Nov 2024 02:24:55 +0300 Subject: [PATCH 57/62] Add default-yank-register option (#11430) Co-authored-by: Michael Davis --- book/src/editor.md | 1 + helix-term/src/commands.rs | 33 ++++++++++++++++++++++++++------- helix-view/src/editor.rs | 3 +++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/book/src/editor.md b/book/src/editor.md index b5a5608af..fa5aef47e 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -24,6 +24,7 @@ |--|--|---------| | `scrolloff` | Number of lines of padding around the edge of the screen when scrolling | `5` | | `mouse` | Enable mouse mode | `true` | +| `default-yank-register` | Default register used for yank/paste | `"` | | `middle-click-paste` | Middle click paste support | `true` | | `scroll-lines` | Number of lines to scroll per scroll wheel step | `3` | | `shell` | Shell to use when running external commands | Unix: `["sh", "-c"]`
Windows: `["cmd", "/C"]` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 073413989..61855d356 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2735,7 +2735,9 @@ fn delete_selection_impl(cx: &mut Context, op: Operation, yank: YankAction) { // yank the selection let text = doc.text().slice(..); let values: Vec = selection.fragments(text).map(Cow::into_owned).collect(); - let reg_name = cx.register.unwrap_or('"'); + let reg_name = cx + .register + .unwrap_or_else(|| cx.editor.config.load().default_yank_register); if let Err(err) = cx.editor.registers.write(reg_name, values) { cx.editor.set_error(err.to_string()); return; @@ -4221,7 +4223,11 @@ fn commit_undo_checkpoint(cx: &mut Context) { // Yank / Paste fn yank(cx: &mut Context) { - yank_impl(cx.editor, cx.register.unwrap_or('"')); + yank_impl( + cx.editor, + cx.register + .unwrap_or(cx.editor.config().default_yank_register), + ); exit_select_mode(cx); } @@ -4282,7 +4288,12 @@ fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) { fn yank_joined(cx: &mut Context) { let separator = doc!(cx.editor).line_ending.as_str(); - yank_joined_impl(cx.editor, separator, cx.register.unwrap_or('"')); + yank_joined_impl( + cx.editor, + separator, + cx.register + .unwrap_or(cx.editor.config().default_yank_register), + ); exit_select_mode(cx); } @@ -4442,7 +4453,12 @@ fn paste_primary_clipboard_before(cx: &mut Context) { } fn replace_with_yanked(cx: &mut Context) { - replace_with_yanked_impl(cx.editor, cx.register.unwrap_or('"'), cx.count()); + replace_with_yanked_impl( + cx.editor, + cx.register + .unwrap_or(cx.editor.config().default_yank_register), + cx.count(), + ); exit_select_mode(cx); } @@ -4505,7 +4521,8 @@ fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize) { fn paste_after(cx: &mut Context) { paste( cx.editor, - cx.register.unwrap_or('"'), + cx.register + .unwrap_or(cx.editor.config().default_yank_register), Paste::After, cx.count(), ); @@ -4515,7 +4532,8 @@ fn paste_after(cx: &mut Context) { fn paste_before(cx: &mut Context) { paste( cx.editor, - cx.register.unwrap_or('"'), + cx.register + .unwrap_or(cx.editor.config().default_yank_register), Paste::Before, cx.count(), ); @@ -5369,7 +5387,8 @@ fn insert_register(cx: &mut Context) { cx.register = Some(ch); paste( cx.editor, - cx.register.unwrap_or('"'), + cx.register + .unwrap_or(cx.editor.config().default_yank_register), Paste::Cursor, cx.count(), ); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 48d3bc365..9e1bee8e1 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -270,6 +270,8 @@ pub struct Config { pub auto_completion: bool, /// Automatic formatting on save. Defaults to true. pub auto_format: bool, + /// Default register used for yank/paste. Defaults to '"' + pub default_yank_register: char, /// Automatic save on focus lost and/or after delay. /// Time delay in milliseconds since last edit after which auto save timer triggers. /// Time delay defaults to false with 3000ms delay. Focus lost defaults to false. @@ -951,6 +953,7 @@ impl Default for Config { auto_pairs: AutoPairConfig::default(), auto_completion: true, auto_format: true, + default_yank_register: '"', auto_save: AutoSave::default(), idle_timeout: Duration::from_millis(250), completion_timeout: Duration::from_millis(250), From 32ff0fce4acc9cabc2fed1ebb21a9206d8243bea Mon Sep 17 00:00:00 2001 From: Egor Afanasin <69684823+pithecantrope@users.noreply.github.com> Date: Thu, 21 Nov 2024 02:26:44 +0300 Subject: [PATCH 58/62] Add Sunset theme (#12093) --- runtime/themes/sunset.toml | 159 +++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 runtime/themes/sunset.toml diff --git a/runtime/themes/sunset.toml b/runtime/themes/sunset.toml new file mode 100644 index 000000000..2683f0a8b --- /dev/null +++ b/runtime/themes/sunset.toml @@ -0,0 +1,159 @@ +# Sunset +# Author : Egor Afanasin +# Repo: https://github.com/pithecantrope/sunset + +# Syntax highlighting +# ---------------------------------------------------------------- +attribute = "rose" + +type = "rose" +"type.builtin" = { fg = "rose", modifiers = ["italic"] } + +constructor = "wood" + +constant = "fire" +"constant.builtin" = { fg = "fire", modifiers = ["italic"] } +"constant.character" = "wood" +"constant.character.escape" = "pink" +"constant.numeric" = "wood" + +string = "grass" +"string.regexp" = "pink" +"string.special" = "rose" +"string.special.symbol" = "fire" + +comment = { fg = "cmnt", modifiers = ["italic"] } +"comment.block.documentation" = "grass" + +variable = "text" +"variable.builtin" = { fg = "sky", modifiers = ["italic"] } +# TODO: variable.parameter +"variable.other.member" = "mud" + +label = "sky" + +punctuation = "cmnt" +"punctuation.special" = "wine" + +keyword = "sun" +"keyword.control.return" = { fg = "sun", modifiers = ["italic"] } +"keyword.control.exception" = { fg = "sun", modifiers = ["italic"] } +"keyword.directive" = "sky" + +operator = "wine" + +function = "peach" +"function.builtin" = { fg = "peach", modifiers = ["italic"] } +"function.macro" = "pink" + +tag = "peach" + +namespace = { fg = "pink", modifiers = ["italic"] } + +special = "sky" + +# Editor interface +# ---------------------------------------------------------------- +"markup.heading.marker" = "sun" +"markup.heading.1" = "attn" +"markup.heading.2" = "fire" +"markup.heading.3" = "rose" +"markup.heading.4" = "peach" +"markup.heading.5" = "wine" +"markup.heading.6" = "grass" + +"markup.list" = "wood" + +"markup.bold" = { modifiers = ["bold"] } +"markup.italic" = { modifiers = ["italic"] } +"markup.strikethrough" = { modifiers = ["crossed_out"] } + +"markup.link.url" = { fg = "sky", underline.style = "line" } +"markup.link.label" = { fg = "sky", modifiers = ["italic"] } +"markup.link.text" = "mud" + +"markup.quote" = "grass" + +"markup.raw" = "pink" + +"diff.plus" = "grass" +"diff.minus" = "attn" +"diff.delta" = "sky" + +# User interface +# ---------------------------------------------------------------- +"ui.background" = { fg = "text", bg = "base" } + +"ui.cursor" = { modifiers = ["reversed"] } +"ui.cursor.match" = { fg = "attn", modifiers = ["bold"] } + +# TODO: ui.debug + +"ui.linenr" = "block" +"ui.linenr.selected" = "cmnt" + +"ui.statusline" = { bg = "block" } +"ui.statusline.inactive" = { fg = "cmnt" } +"ui.statusline.normal" = { fg = "block", bg = "sun", modifiers = ["bold"] } +"ui.statusline.insert" = { fg = "block", bg = "grass", modifiers = ["bold"] } +"ui.statusline.select" = { fg = "block", bg = "wine", modifiers = ["bold"] } + +"ui.bufferline" = { fg = "cmnt", bg = "block" } +"ui.bufferline.active" = "sun" + +"ui.popup" = { fg = "text", bg = "base" } +"ui.popup.info" = { fg = "text", bg = "block" } + +"ui.window" = { fg = "block", modifiers = ["bold"] } + +"ui.help" = { fg = "text", bg = "block" } + +"ui.text" = { fg = "text", bg = "base" } +"ui.text.focus" = "sun" +"ui.text.inactive" = { fg = "cmnt", modifiers = ["italic"] } +"ui.text.info" = { bg = "block" } + +"ui.virtual" = { fg = "block" } +"ui.virtual.ruler" = { bg = "block" } +"ui.virtual.indent-guide" = "sel" +"ui.virtual.jump-label" = { fg = "attn", modifiers = ["bold"] } + +"ui.menu" = { fg = "text", bg = "base" } +"ui.menu.selected" = { bg = "sel" } +"ui.menu.scroll" = "sel" + +"ui.selection" = { bg = "sel" } + +"ui.highlight" = { bg = "sel" } + +error = "attn" +warning = "fire" +info = "pink" +hint = "sky" + +diagnostic = { underline.style = "line" } + +[palette] +# Reddish +fire = "#EE7711" +rose = "#EE7777" +peach = "#EEBB77" +pink = "#EEAAAA" +wood = "#997755" + +# Greenish +grass = "#66CC33" +mud = "#BBCC77" +sun = "#EEEE11" + +# Bluish +sky = "#77AAAA" +wine = "#775599" + +# Ui +base = "#111111" +block = "#222222" +sel = "#333333" +cmnt = "#777777" +text = "#EEEEEE" +attn = "#EE1111" From b8313da5a87a375e444796c1daaf5019cf6ff0b2 Mon Sep 17 00:00:00 2001 From: Niklas Gruhn Date: Thu, 21 Nov 2024 00:56:24 +0100 Subject: [PATCH 59/62] Add language support for Quint (#11898) Co-authored-by: Michael Davis --- book/src/generated/lang-support.md | 1 + languages.toml | 14 +++++ runtime/queries/quint/highlights.scm | 94 ++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 runtime/queries/quint/highlights.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 20f861a5d..28f25ba3f 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -169,6 +169,7 @@ | purescript | ✓ | ✓ | | `purescript-language-server` | | python | ✓ | ✓ | ✓ | `ruff`, `jedi-language-server`, `pylsp` | | qml | ✓ | | ✓ | `qmlls` | +| quint | ✓ | | | `quint-language-server` | | r | ✓ | | | `R` | | racket | ✓ | | ✓ | `racket` | | regex | ✓ | | | | diff --git a/languages.toml b/languages.toml index 84171af3f..ea6e6893f 100644 --- a/languages.toml +++ b/languages.toml @@ -84,6 +84,7 @@ pyright = { command = "pyright-langserver", args = ["--stdio"], config = {} } basedpyright = { command = "basedpyright-langserver", args = ["--stdio"], config = {} } pylyzer = { command = "pylyzer", args = ["--server"] } qmlls = { command = "qmlls" } +quint-language-server = { command = "quint-language-server", args = ["--stdio"] } r = { command = "R", args = ["--no-echo", "-e", "languageserver::run()"] } racket = { command = "racket", args = ["-l", "racket-langserver"] } regols = { command = "regols" } @@ -3893,6 +3894,19 @@ indent = { tab-width = 4, unit = " " } name = "cylc" source = { git = "https://github.com/elliotfontaine/tree-sitter-cylc", rev = "30dd40d9bf23912e4aefa93eeb4c7090bda3d0f6" } +[[language]] +name = "quint" +scope = "source.quint" +file-types = ["qnt"] +language-servers = ["quint-language-server"] +comment-token = "//" +block-comment-tokens = { start = "/*", end = "*/" } +indent = { tab-width = 2, unit = " " } + +[[grammar]] +name = "quint" +source = { git = "https://github.com/gruhn/tree-sitter-quint", rev = "eebbd01edfeff6404778c92efe5554e42e506a18" } + [[language]] name = "spade" scope = "source.spade" diff --git a/runtime/queries/quint/highlights.scm b/runtime/queries/quint/highlights.scm new file mode 100644 index 000000000..edb56fbad --- /dev/null +++ b/runtime/queries/quint/highlights.scm @@ -0,0 +1,94 @@ +[ + "module" + "type" + "assume" + "const" + "var" + "val" + "nondet" + "def" + "pure" + "action" + "temporal" + "run" +] @keyword + +(match_expr "match" @keyword.control.conditional) + +(if_else_condition + "if" @keyword.control.conditional + "else" @keyword.control.conditional) + +(import "import" @keyword.control.import) +(import "as" @keyword.control.import) +(import "from" @keyword.control.import) +(export "export" @keyword.control.import) +(export "as" @keyword.control.import) + +[ + "true" + "false" + "Int" + "Nat" + "Bool" +] @constant.builtin + +[ + ";" + "." + "," +] @punctuation.delimiter + +[ + "-" + "+" + "*" + "/" + "%" + "<" + "<=" + "=" + "==" + "!=" + "=>" + ">" + ">=" + "^" + "->" +] @operator + +(infix_and "and" @operator) +(infix_or "or" @operator) +(infix_iff "iff" @operator) +(infix_implies "implies" @operator) + +(braced_and "and" @keyword) +(braced_or "or" @keyword) +(braced_all "all" @keyword) +(braced_any "any" @keyword) + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +(polymorphic_type + (type) @type.parameter) + +(variant_constructor) @type.enum.variant + +(type) @type +(int_literal) @constant.numeric.integer +(comment) @comment +(string) @string + +(operator_application + operator: (qualified_identifier) @function) + +(operator_definition + name: (qualified_identifier) @function + arguments: (typed_argument_list)) From 9e0d2d0a19c16640cc5ece4f1dc45d1eb7276823 Mon Sep 17 00:00:00 2001 From: "Valentin B." <703631+beeb@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:58:14 +0100 Subject: [PATCH 60/62] chore(solidity): add highlight queries (#12102) Add highlights for `hex` and `unicode` string prefixes and YUL booleans --- runtime/queries/solidity/highlights.scm | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/runtime/queries/solidity/highlights.scm b/runtime/queries/solidity/highlights.scm index 73f354a25..8b5dae420 100644 --- a/runtime/queries/solidity/highlights.scm +++ b/runtime/queries/solidity/highlights.scm @@ -12,6 +12,8 @@ (unicode_string_literal) (yul_string_literal) ] @string +(hex_string_literal "hex" @string.special.symbol) +(unicode_string_literal "unicode" @string.special.symbol) [ (number_literal) (yul_decimal_number) @@ -20,6 +22,7 @@ [ (true) (false) + (yul_boolean) ] @constant.builtin.boolean (comment) @comment @@ -44,18 +47,18 @@ (type_name "(" @punctuation.bracket "=>" @punctuation.delimiter ")" @punctuation.bracket) ; Definitions -(struct_declaration +(struct_declaration name: (identifier) @type) -(enum_declaration +(enum_declaration name: (identifier) @type) (contract_declaration - name: (identifier) @type) + name: (identifier) @type) (library_declaration - name: (identifier) @type) + name: (identifier) @type) (interface_declaration name: (identifier) @type) -(event_definition - name: (identifier) @type) +(event_definition + name: (identifier) @type) (function_definition name: (identifier) @function) From f305c7299d8471957eaa66bb83a4c9a70cfc57a9 Mon Sep 17 00:00:00 2001 From: Lens0021 / Leslie Date: Fri, 22 Nov 2024 01:09:42 +0900 Subject: [PATCH 61/62] Add support for Amber-lang (#12021) Co-authored-by: Phoenix Himself Co-authored-by: Michael Davis --- book/src/generated/lang-support.md | 1 + languages.toml | 11 +++++ runtime/queries/amber/highlights.scm | 60 ++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 runtime/queries/amber/highlights.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 28f25ba3f..d85cebf06 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -3,6 +3,7 @@ | ada | ✓ | ✓ | | `ada_language_server` | | adl | ✓ | ✓ | ✓ | | | agda | ✓ | | | | +| amber | ✓ | | | | | astro | ✓ | | | | | awk | ✓ | ✓ | | `awk-language-server` | | bash | ✓ | ✓ | ✓ | `bash-language-server` | diff --git a/languages.toml b/languages.toml index ea6e6893f..54283ea8d 100644 --- a/languages.toml +++ b/languages.toml @@ -3931,3 +3931,14 @@ indent = { tab-width = 4, unit = " " } [[grammar]] name = "spade" source = { git = "https://gitlab.com/spade-lang/tree-sitter-spade/", rev = "4d5b141017c61fe7e168e0a5c5721ee62b0d9572" } + +[[language]] +name = "amber" +scope = "source.ab" +file-types = ["ab"] +comment-token = "//" +indent = { tab-width = 4, unit = " " } + +[[grammar]] +name = "amber" +source = { git = "https://github.com/amber-lang/tree-sitter-amber", rev = "c6df3ec2ec243ed76550c525e7ac3d9a10c6c814" } diff --git a/runtime/queries/amber/highlights.scm b/runtime/queries/amber/highlights.scm new file mode 100644 index 000000000..39f965b58 --- /dev/null +++ b/runtime/queries/amber/highlights.scm @@ -0,0 +1,60 @@ +(comment) @comment + +[ + "if" + "loop" + "for" + "return" + "fun" + "else" + "then" + "break" + "continue" + "and" + "or" + "not" + "let" + "pub" + "main" + "echo" + "exit" + "fun" + "import" + "from" + "as" + "in" + "fail" + "failed" + "silent" + "nameof" + "is" + "unsafe" + "trust" +] @keyword + +; Literals +(boolean) @constant.builtin.boolean +(number) @constant.numeric +(null) @constant.numeric +(string) @string +(status) @keyword +(command) @string +(handler) @keyword +(block) @punctuation.delimiter +(variable_init) @keyword +(variable_assignment) @punctuation.delimiter +(variable) @variable +(escape_sequence) @constant.character.escape +(type_name_symbol) @type +(interpolation) @punctuation.delimiter +(reference) @keyword +(preprocessor_directive) @comment +(shebang) @comment +(function_definition + name: (variable) @function.method) +(function_call + name: (variable) @function.method) +(import_statement + "pub" @keyword + "import" @keyword + "from" @keyword) From dc941d6d24cd4876f75e68487047542239b8316a Mon Sep 17 00:00:00 2001 From: Philipp Mildenberger Date: Fri, 22 Nov 2024 04:12:36 +0100 Subject: [PATCH 62/62] Add support for path completion (#2608) Co-authored-by: Michael Davis Co-authored-by: Pascal Kuthe --- Cargo.lock | 2 + book/src/editor.md | 1 + book/src/languages.md | 1 + helix-core/src/completion.rs | 12 + helix-core/src/lib.rs | 2 + helix-core/src/syntax.rs | 3 + helix-event/src/cancel.rs | 282 +++++++++++++++++- helix-event/src/lib.rs | 2 +- helix-stdx/Cargo.toml | 2 + helix-stdx/src/env.rs | 126 +++++++- helix-stdx/src/path.rs | 224 +++++++++++++- helix-term/src/commands.rs | 68 ++--- helix-term/src/handlers/completion.rs | 83 ++++-- helix-term/src/handlers/completion/item.rs | 41 +++ helix-term/src/handlers/completion/path.rs | 189 ++++++++++++ helix-term/src/handlers/completion/resolve.rs | 36 ++- helix-term/src/handlers/signature_help.rs | 25 +- helix-term/src/ui/completion.rs | 218 ++++++++------ helix-term/src/ui/editor.rs | 3 +- helix-term/src/ui/menu.rs | 2 +- helix-term/src/ui/mod.rs | 2 +- helix-view/src/document.rs | 6 + helix-view/src/editor.rs | 6 + 23 files changed, 1124 insertions(+), 212 deletions(-) create mode 100644 helix-core/src/completion.rs create mode 100644 helix-term/src/handlers/completion/item.rs create mode 100644 helix-term/src/handlers/completion/path.rs diff --git a/Cargo.lock b/Cargo.lock index f4f03c797..6cc73ebf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1346,6 +1346,8 @@ dependencies = [ "bitflags", "dunce", "etcetera", + "once_cell", + "regex-automata", "regex-cursor", "ropey", "rustix", diff --git a/book/src/editor.md b/book/src/editor.md index fa5aef47e..06f8800c2 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -33,6 +33,7 @@ | `cursorcolumn` | Highlight all columns with a cursor | `false` | | `gutters` | Gutters to display: Available are `diagnostics` and `diff` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "spacer", "line-numbers", "spacer", "diff"]` | | `auto-completion` | Enable automatic pop up of auto-completion | `true` | +| `path-completion` | Enable filepath completion. Show files and directories if an existing path at the cursor was recognized, either absolute or relative to the current opened document or current working directory (if the buffer is not yet saved). Defaults to true. | `true` | | `auto-format` | Enable automatic formatting on save | `true` | | `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. | `250` | | `completion-timeout` | Time in milliseconds after typing a word character before completions are shown, set to 5 for instant. | `250` | diff --git a/book/src/languages.md b/book/src/languages.md index fe105cced..2a1c6d652 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -69,6 +69,7 @@ These configuration keys are available: | `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout | | `soft-wrap` | [editor.softwrap](./configuration.md#editorsoft-wrap-section) | `text-width` | Maximum line length. Used for the `:reflow` command and soft-wrapping if `soft-wrap.wrap-at-text-width` is set, defaults to `editor.text-width` | +| `path-completion` | Overrides the `editor.path-completion` config key for the language. | | `workspace-lsp-roots` | Directories relative to the workspace root that are treated as LSP roots. Should only be set in `.helix/config.toml`. Overwrites the setting of the same name in `config.toml` if set. | | `persistent-diagnostic-sources` | An array of LSP diagnostic sources assumed unchanged when the language server resends the same set of diagnostics. Helix can track the position for these diagnostics internally instead. Useful for diagnostics that are recomputed on save. diff --git a/helix-core/src/completion.rs b/helix-core/src/completion.rs new file mode 100644 index 000000000..0bd111eb4 --- /dev/null +++ b/helix-core/src/completion.rs @@ -0,0 +1,12 @@ +use std::borrow::Cow; + +use crate::Transaction; + +#[derive(Debug, PartialEq, Clone)] +pub struct CompletionItem { + pub transaction: Transaction, + pub label: Cow<'static, str>, + pub kind: Cow<'static, str>, + /// Containing Markdown + pub documentation: String, +} diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 9165560d0..413c2da77 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -3,6 +3,7 @@ pub use encoding_rs as encoding; pub mod auto_pairs; pub mod chars; pub mod comment; +pub mod completion; pub mod config; pub mod diagnostic; pub mod diff; @@ -63,6 +64,7 @@ pub use selection::{Range, Selection}; pub use smallvec::{smallvec, SmallVec}; pub use syntax::Syntax; +pub use completion::CompletionItem; pub use diagnostic::Diagnostic; pub use line_ending::{LineEnding, NATIVE_LINE_ENDING}; diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 7de6ddf44..cd9230f35 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -125,6 +125,9 @@ pub struct LanguageConfiguration { #[serde(skip_serializing_if = "Option::is_none")] pub formatter: Option, + /// If set, overrides `editor.path-completion`. + pub path_completion: Option, + #[serde(default)] pub diagnostic_severity: Severity, diff --git a/helix-event/src/cancel.rs b/helix-event/src/cancel.rs index f027be80e..2029c9456 100644 --- a/helix-event/src/cancel.rs +++ b/helix-event/src/cancel.rs @@ -1,15 +1,18 @@ +use std::borrow::Borrow; use std::future::Future; +use std::sync::atomic::AtomicU64; +use std::sync::atomic::Ordering::Relaxed; +use std::sync::Arc; -pub use oneshot::channel as cancelation; -use tokio::sync::oneshot; +use tokio::sync::Notify; -pub type CancelTx = oneshot::Sender<()>; -pub type CancelRx = oneshot::Receiver<()>; - -pub async fn cancelable_future(future: impl Future, cancel: CancelRx) -> Option { +pub async fn cancelable_future( + future: impl Future, + cancel: impl Borrow, +) -> Option { tokio::select! { biased; - _ = cancel => { + _ = cancel.borrow().canceled() => { None } res = future => { @@ -17,3 +20,268 @@ pub async fn cancelable_future(future: impl Future, cancel: Cance } } } + +#[derive(Default, Debug)] +struct Shared { + state: AtomicU64, + // `Notify` has some features that we don't really need here because it + // supports waking single tasks (`notify_one`) and does its own (more + // complicated) state tracking, we could reimplement the waiter linked list + // with modest effort and reduce memory consumption by one word/8 bytes and + // reduce code complexity/number of atomic operations. + // + // I don't think that's worth the complexity (unsafe code). + // + // if we only cared about async code then we could also only use a notify + // (without the generation count), this would be equivalent (or maybe more + // correct if we want to allow cloning the TX) but it would be extremly slow + // to frequently check for cancelation from sync code + notify: Notify, +} + +impl Shared { + fn generation(&self) -> u32 { + self.state.load(Relaxed) as u32 + } + + fn num_running(&self) -> u32 { + (self.state.load(Relaxed) >> 32) as u32 + } + + /// Increments the generation count and sets `num_running` + /// to the provided value, this operation is not with + /// regard to the generation counter (doesn't use `fetch_add`) + /// so the calling code must ensure it cannot execute concurrently + /// to maintain correctness (but not safety) + fn inc_generation(&self, num_running: u32) -> (u32, u32) { + let state = self.state.load(Relaxed); + let generation = state as u32; + let prev_running = (state >> 32) as u32; + // no need to create a new generation if the refcount is zero (fastpath) + if prev_running == 0 && num_running == 0 { + return (generation, 0); + } + let new_generation = generation.saturating_add(1); + self.state.store( + new_generation as u64 | ((num_running as u64) << 32), + Relaxed, + ); + self.notify.notify_waiters(); + (new_generation, prev_running) + } + + fn inc_running(&self, generation: u32) { + let mut state = self.state.load(Relaxed); + loop { + let current_generation = state as u32; + if current_generation != generation { + break; + } + let off = 1 << 32; + let res = self.state.compare_exchange_weak( + state, + state.saturating_add(off), + Relaxed, + Relaxed, + ); + match res { + Ok(_) => break, + Err(new_state) => state = new_state, + } + } + } + + fn dec_running(&self, generation: u32) { + let mut state = self.state.load(Relaxed); + loop { + let current_generation = state as u32; + if current_generation != generation { + break; + } + let num_running = (state >> 32) as u32; + // running can't be zero here, that would mean we miscounted somewhere + assert_ne!(num_running, 0); + let off = 1 << 32; + let res = self + .state + .compare_exchange_weak(state, state - off, Relaxed, Relaxed); + match res { + Ok(_) => break, + Err(new_state) => state = new_state, + } + } + } +} + +// This intentionally doesn't implement `Clone` and requires a mutable reference +// for cancelation to avoid races (in inc_generation). + +/// A task controller allows managing a single subtask enabling the controller +/// to cancel the subtask and to check whether it is still running. +/// +/// For efficiency reasons the controller can be reused/restarted, +/// in that case the previous task is automatically canceled. +/// +/// If the controller is dropped, the subtasks are automatically canceled. +#[derive(Default, Debug)] +pub struct TaskController { + shared: Arc, +} + +impl TaskController { + pub fn new() -> Self { + TaskController::default() + } + /// Cancels the active task (handle). + /// + /// Returns whether any tasks were still running before the cancelation. + pub fn cancel(&mut self) -> bool { + self.shared.inc_generation(0).1 != 0 + } + + /// Checks whether there are any task handles + /// that haven't been dropped (or canceled) yet. + pub fn is_running(&self) -> bool { + self.shared.num_running() != 0 + } + + /// Starts a new task and cancels the previous task (handles). + pub fn restart(&mut self) -> TaskHandle { + TaskHandle { + generation: self.shared.inc_generation(1).0, + shared: self.shared.clone(), + } + } +} + +impl Drop for TaskController { + fn drop(&mut self) { + self.cancel(); + } +} + +/// A handle that is used to link a task with a task controller. +/// +/// It can be used to cancel async futures very efficiently but can also be checked for +/// cancelation very quickly (single atomic read) in blocking code. +/// The handle can be cheaply cloned (reference counted). +/// +/// The TaskController can check whether a task is "running" by inspecting the +/// refcount of the (current) tasks handles. Therefore, if that information +/// is important, ensure that the handle is not dropped until the task fully +/// completes. +pub struct TaskHandle { + shared: Arc, + generation: u32, +} + +impl Clone for TaskHandle { + fn clone(&self) -> Self { + self.shared.inc_running(self.generation); + TaskHandle { + shared: self.shared.clone(), + generation: self.generation, + } + } +} + +impl Drop for TaskHandle { + fn drop(&mut self) { + self.shared.dec_running(self.generation); + } +} + +impl TaskHandle { + /// Waits until [`TaskController::cancel`] is called for the corresponding + /// [`TaskController`]. Immediately returns if `cancel` was already called since + pub async fn canceled(&self) { + let notified = self.shared.notify.notified(); + if !self.is_canceled() { + notified.await + } + } + + pub fn is_canceled(&self) -> bool { + self.generation != self.shared.generation() + } +} + +#[cfg(test)] +mod tests { + use std::future::poll_fn; + + use futures_executor::block_on; + use tokio::task::yield_now; + + use crate::{cancelable_future, TaskController}; + + #[test] + fn immediate_cancel() { + let mut controller = TaskController::new(); + let handle = controller.restart(); + controller.cancel(); + assert!(handle.is_canceled()); + controller.restart(); + assert!(handle.is_canceled()); + + let res = block_on(cancelable_future( + poll_fn(|_cx| std::task::Poll::Ready(())), + handle, + )); + assert!(res.is_none()); + } + + #[test] + fn running_count() { + let mut controller = TaskController::new(); + let handle = controller.restart(); + assert!(controller.is_running()); + assert!(!handle.is_canceled()); + drop(handle); + assert!(!controller.is_running()); + assert!(!controller.cancel()); + let handle = controller.restart(); + assert!(!handle.is_canceled()); + assert!(controller.is_running()); + let handle2 = handle.clone(); + assert!(!handle.is_canceled()); + assert!(controller.is_running()); + drop(handle2); + assert!(!handle.is_canceled()); + assert!(controller.is_running()); + assert!(controller.cancel()); + assert!(handle.is_canceled()); + assert!(!controller.is_running()); + } + + #[test] + fn no_cancel() { + let mut controller = TaskController::new(); + let handle = controller.restart(); + assert!(!handle.is_canceled()); + + let res = block_on(cancelable_future( + poll_fn(|_cx| std::task::Poll::Ready(())), + handle, + )); + assert!(res.is_some()); + } + + #[test] + fn delayed_cancel() { + let mut controller = TaskController::new(); + let handle = controller.restart(); + + let mut hit = false; + let res = block_on(cancelable_future( + async { + controller.cancel(); + hit = true; + yield_now().await; + }, + handle, + )); + assert!(res.is_none()); + assert!(hit); + } +} diff --git a/helix-event/src/lib.rs b/helix-event/src/lib.rs index de018a79d..8aa6b52fa 100644 --- a/helix-event/src/lib.rs +++ b/helix-event/src/lib.rs @@ -32,7 +32,7 @@ //! to helix-view in the future if we manage to detach the compositor from its rendering backend. use anyhow::Result; -pub use cancel::{cancelable_future, cancelation, CancelRx, CancelTx}; +pub use cancel::{cancelable_future, TaskController, TaskHandle}; pub use debounce::{send_blocking, AsyncHook}; pub use redraw::{ lock_frame, redraw_requested, request_redraw, start_frame, RenderLockGuard, RequestRedrawOnDrop, diff --git a/helix-stdx/Cargo.toml b/helix-stdx/Cargo.toml index 4e85adb5b..d18740efa 100644 --- a/helix-stdx/Cargo.toml +++ b/helix-stdx/Cargo.toml @@ -18,6 +18,8 @@ ropey = { version = "1.6.1", default-features = false } which = "7.0" regex-cursor = "0.1.4" bitflags = "2.6" +once_cell = "1.19" +regex-automata = "0.4.8" [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.59", features = ["Win32_Foundation", "Win32_Security", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Threading"] } diff --git a/helix-stdx/src/env.rs b/helix-stdx/src/env.rs index 51450d225..d29a98fde 100644 --- a/helix-stdx/src/env.rs +++ b/helix-stdx/src/env.rs @@ -1,9 +1,12 @@ use std::{ - ffi::OsStr, + borrow::Cow, + ffi::{OsStr, OsString}, path::{Path, PathBuf}, sync::RwLock, }; +use once_cell::sync::Lazy; + static CWD: RwLock> = RwLock::new(None); // Get the current working directory. @@ -59,6 +62,93 @@ pub fn which>( }) } +fn find_brace_end(src: &[u8]) -> Option { + use regex_automata::meta::Regex; + + static REGEX: Lazy = Lazy::new(|| Regex::builder().build("[{}]").unwrap()); + let mut depth = 0; + for mat in REGEX.find_iter(src) { + let pos = mat.start(); + match src[pos] { + b'{' => depth += 1, + b'}' if depth == 0 => return Some(pos), + b'}' => depth -= 1, + _ => unreachable!(), + } + } + None +} + +fn expand_impl(src: &OsStr, mut resolve: impl FnMut(&OsStr) -> Option) -> Cow { + use regex_automata::meta::Regex; + + static REGEX: Lazy = Lazy::new(|| { + Regex::builder() + .build_many(&[ + r"\$\{([^\}:]+):-", + r"\$\{([^\}:]+):=", + r"\$\{([^\}-]+)-", + r"\$\{([^\}=]+)=", + r"\$\{([^\}]+)", + r"\$(\w+)", + ]) + .unwrap() + }); + + let bytes = src.as_encoded_bytes(); + let mut res = Vec::with_capacity(bytes.len()); + let mut pos = 0; + for captures in REGEX.captures_iter(bytes) { + let mat = captures.get_match().unwrap(); + let pattern_id = mat.pattern().as_usize(); + let mut range = mat.range(); + let var = &bytes[captures.get_group(1).unwrap().range()]; + let default = if pattern_id != 5 { + let Some(bracket_pos) = find_brace_end(&bytes[range.end..]) else { + break; + }; + let default = &bytes[range.end..range.end + bracket_pos]; + range.end += bracket_pos + 1; + default + } else { + &[] + }; + // safety: this is a codepoint aligned substring of an osstr (always valid) + let var = unsafe { OsStr::from_encoded_bytes_unchecked(var) }; + let expansion = resolve(var); + let expansion = match &expansion { + Some(val) => { + if val.is_empty() && pattern_id < 2 { + default + } else { + val.as_encoded_bytes() + } + } + None => default, + }; + res.extend_from_slice(&bytes[pos..range.start]); + pos = range.end; + res.extend_from_slice(expansion); + } + if pos == 0 { + src.into() + } else { + res.extend_from_slice(&bytes[pos..]); + // safety: this is a composition of valid osstr (and codepoint aligned slices which are also valid) + unsafe { OsString::from_encoded_bytes_unchecked(res) }.into() + } +} + +/// performs substitution of enviorment variables. Supports the following (POSIX) syntax: +/// +/// * `$`, `${}` +/// * `${:-}`, `${-}` +/// * `${:=}`, `${=default}` +/// +pub fn expand + ?Sized>(src: &S) -> Cow { + expand_impl(src.as_ref(), |var| std::env::var_os(var)) +} + #[derive(Debug)] pub struct ExecutableNotFoundError { command: String, @@ -75,7 +165,9 @@ impl std::error::Error for ExecutableNotFoundError {} #[cfg(test)] mod tests { - use super::{current_working_dir, set_current_working_dir}; + use std::ffi::{OsStr, OsString}; + + use super::{current_working_dir, expand_impl, set_current_working_dir}; #[test] fn current_dir_is_set() { @@ -88,4 +180,34 @@ mod tests { let cwd = current_working_dir(); assert_eq!(cwd, new_path); } + + macro_rules! assert_env_expand { + ($env: expr, $lhs: expr, $rhs: expr) => { + assert_eq!(&*expand_impl($lhs.as_ref(), $env), OsStr::new($rhs)); + }; + } + + /// paths that should work on all platforms + #[test] + fn test_env_expand() { + let env = |var: &OsStr| -> Option { + match var.to_str().unwrap() { + "FOO" => Some("foo".into()), + "EMPTY" => Some("".into()), + _ => None, + } + }; + assert_env_expand!(env, "pass_trough", "pass_trough"); + assert_env_expand!(env, "$FOO", "foo"); + assert_env_expand!(env, "bar/$FOO/baz", "bar/foo/baz"); + assert_env_expand!(env, "bar/${FOO}/baz", "bar/foo/baz"); + assert_env_expand!(env, "baz/${BAR:-bar}/foo", "baz/bar/foo"); + assert_env_expand!(env, "baz/${BAR:=bar}/foo", "baz/bar/foo"); + assert_env_expand!(env, "baz/${BAR-bar}/foo", "baz/bar/foo"); + assert_env_expand!(env, "baz/${BAR=bar}/foo", "baz/bar/foo"); + assert_env_expand!(env, "baz/${EMPTY:-bar}/foo", "baz/bar/foo"); + assert_env_expand!(env, "baz/${EMPTY:=bar}/foo", "baz/bar/foo"); + assert_env_expand!(env, "baz/${EMPTY-bar}/foo", "baz//foo"); + assert_env_expand!(env, "baz/${EMPTY=bar}/foo", "baz//foo"); + } } diff --git a/helix-stdx/src/path.rs b/helix-stdx/src/path.rs index 968596a70..72b233cca 100644 --- a/helix-stdx/src/path.rs +++ b/helix-stdx/src/path.rs @@ -1,8 +1,12 @@ pub use etcetera::home_dir; +use once_cell::sync::Lazy; +use regex_cursor::{engines::meta::Regex, Input}; +use ropey::RopeSlice; use std::{ borrow::Cow, ffi::OsString, + ops::Range, path::{Component, Path, PathBuf, MAIN_SEPARATOR_STR}, }; @@ -51,7 +55,7 @@ where /// Normalize a path without resolving symlinks. // Strategy: start from the first component and move up. Cannonicalize previous path, -// join component, cannonicalize new path, strip prefix and join to the final result. +// join component, canonicalize new path, strip prefix and join to the final result. pub fn normalize(path: impl AsRef) -> PathBuf { let mut components = path.as_ref().components().peekable(); let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { @@ -201,6 +205,96 @@ pub fn get_truncated_path(path: impl AsRef) -> PathBuf { ret } +fn path_component_regex(windows: bool) -> String { + // TODO: support backslash path escape on windows (when using git bash for example) + let space_escape = if windows { r"[\^`]\s" } else { r"[\\]\s" }; + // partially baesd on what's allowed in an url but with some care to avoid + // false positivies (like any kind of brackets or quotes) + r"[\w@.\-+#$%?!,;~&]|".to_owned() + space_escape +} + +/// Regex for delimited environment captures like `${HOME}`. +fn braced_env_regex(windows: bool) -> String { + r"\$\{(?:".to_owned() + &path_component_regex(windows) + r"|[/:=])+\}" +} + +fn compile_path_regex( + prefix: &str, + postfix: &str, + match_single_file: bool, + windows: bool, +) -> Regex { + let first_component = format!( + "(?:{}|(?:{}))", + braced_env_regex(windows), + path_component_regex(windows) + ); + // For all components except the first we allow an equals so that `foo=/ + // bar/baz` does not include foo. This is primarily intended for url queries + // (where an equals is never in the first component) + let component = format!("(?:{first_component}|=)"); + let sep = if windows { r"[/\\]" } else { "/" }; + let url_prefix = r"[\w+\-.]+://??"; + let path_prefix = if windows { + // single slash handles most windows prefixes (like\\server\...) but `\ + // \?\C:\..` (and C:\) needs special handling, since we don't allow : in path + // components (so that colon separated paths and : work) + r"\\\\\?\\\w:|\w:|\\|" + } else { + "" + }; + let path_start = format!("(?:{first_component}+|~|{path_prefix}{url_prefix})"); + let optional = if match_single_file { + format!("|{path_start}") + } else { + String::new() + }; + let path_regex = format!( + "{prefix}(?:{path_start}?(?:(?:{sep}{component}+)+{sep}?|{sep}){optional}){postfix}" + ); + Regex::new(&path_regex).unwrap() +} + +/// If `src` ends with a path then this function returns the part of the slice. +pub fn get_path_suffix(src: RopeSlice<'_>, match_single_file: bool) -> Option> { + let regex = if match_single_file { + static REGEX: Lazy = Lazy::new(|| compile_path_regex("", "$", true, cfg!(windows))); + &*REGEX + } else { + static REGEX: Lazy = Lazy::new(|| compile_path_regex("", "$", false, cfg!(windows))); + &*REGEX + }; + + regex + .find(Input::new(src)) + .map(|mat| src.byte_slice(mat.range())) +} + +/// Returns an iterator of the **byte** ranges in src that contain a path. +pub fn find_paths( + src: RopeSlice<'_>, + match_single_file: bool, +) -> impl Iterator> + '_ { + let regex = if match_single_file { + static REGEX: Lazy = Lazy::new(|| compile_path_regex("", "", true, cfg!(windows))); + &*REGEX + } else { + static REGEX: Lazy = Lazy::new(|| compile_path_regex("", "", false, cfg!(windows))); + &*REGEX + }; + regex.find_iter(Input::new(src)).map(|mat| mat.range()) +} + +/// Performs substitution of `~` and environment variables, see [`env::expand`](crate::env::expand) and [`expand_tilde`] +pub fn expand + ?Sized>(path: &T) -> Cow<'_, Path> { + let path = path.as_ref(); + let path = expand_tilde(path); + match crate::env::expand(&*path) { + Cow::Borrowed(_) => path, + Cow::Owned(path) => PathBuf::from(path).into(), + } +} + #[cfg(test)] mod tests { use std::{ @@ -208,7 +302,10 @@ mod tests { path::{Component, Path}, }; - use crate::path; + use regex_cursor::Input; + use ropey::RopeSlice; + + use crate::path::{self, compile_path_regex}; #[test] fn expand_tilde() { @@ -228,4 +325,127 @@ mod tests { assert_ne!(component_count, 0); } } + + macro_rules! assert_match { + ($regex: expr, $haystack: expr) => { + let haystack = Input::new(RopeSlice::from($haystack)); + assert!( + $regex.is_match(haystack), + "regex should match {}", + $haystack + ); + }; + } + macro_rules! assert_no_match { + ($regex: expr, $haystack: expr) => { + let haystack = Input::new(RopeSlice::from($haystack)); + assert!( + !$regex.is_match(haystack), + "regex should not match {}", + $haystack + ); + }; + } + + macro_rules! assert_matches { + ($regex: expr, $haystack: expr, [$($matches: expr),*]) => { + let src = $haystack; + let matches: Vec<_> = $regex + .find_iter(Input::new(RopeSlice::from(src))) + .map(|it| &src[it.range()]) + .collect(); + assert_eq!(matches, vec![$($matches),*]); + }; + } + + /// Linux-only path + #[test] + fn path_regex_unix() { + // due to ambiguity with the `\` path separator we can't support space escapes `\ ` on windows + let regex = compile_path_regex("^", "$", false, false); + assert_match!(regex, "${FOO}/hello\\ world"); + assert_match!(regex, "${FOO}/\\ "); + } + + /// Windows-only paths + #[test] + fn path_regex_windows() { + let regex = compile_path_regex("^", "$", false, true); + assert_match!(regex, "${FOO}/hello^ world"); + assert_match!(regex, "${FOO}/hello` world"); + assert_match!(regex, "${FOO}/^ "); + assert_match!(regex, "${FOO}/` "); + assert_match!(regex, r"foo\bar"); + assert_match!(regex, r"foo\bar"); + assert_match!(regex, r"..\bar"); + assert_match!(regex, r"..\"); + assert_match!(regex, r"C:\"); + assert_match!(regex, r"\\?\C:\foo"); + assert_match!(regex, r"\\server\foo"); + } + + /// Paths that should work on all platforms + #[test] + fn path_regex() { + for windows in [false, true] { + let regex = compile_path_regex("^", "$", false, windows); + assert_no_match!(regex, "foo"); + assert_no_match!(regex, ""); + assert_match!(regex, "https://github.com/notifications/query=foo"); + assert_match!(regex, "file:///foo/bar"); + assert_match!(regex, "foo/bar"); + assert_match!(regex, "$HOME/foo"); + assert_match!(regex, "${FOO:-bar}/baz"); + assert_match!(regex, "foo/bar_"); + assert_match!(regex, "/home/bar"); + assert_match!(regex, "foo/"); + assert_match!(regex, "./"); + assert_match!(regex, "../"); + assert_match!(regex, "../.."); + assert_match!(regex, "./foo"); + assert_match!(regex, "./foo.rs"); + assert_match!(regex, "/"); + assert_match!(regex, "~/"); + assert_match!(regex, "~/foo"); + assert_match!(regex, "~/foo"); + assert_match!(regex, "~/foo/../baz"); + assert_match!(regex, "${HOME}/foo"); + assert_match!(regex, "$HOME/foo"); + assert_match!(regex, "/$FOO"); + assert_match!(regex, "/${FOO}"); + assert_match!(regex, "/${FOO}/${BAR}"); + assert_match!(regex, "/${FOO}/${BAR}/foo"); + assert_match!(regex, "/${FOO}/${BAR}"); + assert_match!(regex, "${FOO}/hello_$WORLD"); + assert_match!(regex, "${FOO}/hello_${WORLD}"); + let regex = compile_path_regex("", "", false, windows); + assert_no_match!(regex, ""); + assert_matches!( + regex, + r#"${FOO}/hello_${WORLD} ${FOO}/hello_${WORLD} foo("./bar", "/home/foo")""#, + [ + "${FOO}/hello_${WORLD}", + "${FOO}/hello_${WORLD}", + "./bar", + "/home/foo" + ] + ); + assert_matches!( + regex, + r#"--> helix-stdx/src/path.rs:427:13"#, + ["helix-stdx/src/path.rs"] + ); + assert_matches!( + regex, + r#"PATH=/foo/bar:/bar/baz:${foo:-/foo}/bar:${PATH}"#, + ["/foo/bar", "/bar/baz", "${foo:-/foo}/bar"] + ); + let regex = compile_path_regex("^", "$", true, windows); + assert_no_match!(regex, ""); + assert_match!(regex, "foo"); + assert_match!(regex, "foo/"); + assert_match!(regex, "$FOO"); + assert_match!(regex, "${BAR}"); + } + } } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 61855d356..628f6fd27 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -6,7 +6,7 @@ pub use dap::*; use futures_util::FutureExt; use helix_event::status; use helix_stdx::{ - path::expand_tilde, + path::{self, find_paths}, rope::{self, RopeSliceExt}, }; use helix_vcs::{FileChange, Hunk}; @@ -1272,53 +1272,31 @@ fn goto_file_impl(cx: &mut Context, action: Action) { .unwrap_or_default(); let paths: Vec<_> = if selections.len() == 1 && primary.len() == 1 { - // Secial case: if there is only one one-width selection, try to detect the - // path under the cursor. - let is_valid_path_char = |c: &char| { - #[cfg(target_os = "windows")] - let valid_chars = &[ - '@', '/', '\\', '.', '-', '_', '+', '#', '$', '%', '{', '}', '[', ']', ':', '!', - '~', '=', - ]; - #[cfg(not(target_os = "windows"))] - let valid_chars = &['@', '/', '.', '-', '_', '+', '#', '$', '%', '~', '=', ':']; - - valid_chars.contains(c) || c.is_alphabetic() || c.is_numeric() - }; - - let cursor_pos = primary.cursor(text.slice(..)); - let pre_cursor_pos = cursor_pos.saturating_sub(1); - let post_cursor_pos = cursor_pos + 1; - let start_pos = if is_valid_path_char(&text.char(cursor_pos)) { - cursor_pos - } else if is_valid_path_char(&text.char(pre_cursor_pos)) { - pre_cursor_pos - } else { - post_cursor_pos - }; - - let prefix_len = text - .chars_at(start_pos) - .reversed() - .take_while(is_valid_path_char) - .count(); - - let postfix_len = text - .chars_at(start_pos) - .take_while(is_valid_path_char) - .count(); - - let path: String = text - .slice((start_pos - prefix_len)..(start_pos + postfix_len)) - .into(); - log::debug!("goto_file auto-detected path: {}", path); - - vec![path] + let mut pos = primary.cursor(text.slice(..)); + pos = text.char_to_byte(pos); + let search_start = text + .line_to_byte(text.byte_to_line(pos)) + .max(pos.saturating_sub(1000)); + let search_end = text + .line_to_byte(text.byte_to_line(pos) + 1) + .min(pos + 1000); + let search_range = text.slice(search_start..search_end); + // we also allow paths that are next to the cursor (can be ambigous but + // rarely so in practice) so that gf on quoted/braced path works (not sure about this + // but apparently that is how gf has worked historically in helix) + let path = find_paths(search_range, true) + .inspect(|mat| println!("{mat:?} {:?}", pos - search_start)) + .take_while(|range| search_start + range.start <= pos + 1) + .find(|range| pos <= search_start + range.end) + .map(|range| Cow::from(search_range.byte_slice(range))); + log::debug!("goto_file auto-detected path: {path:?}"); + let path = path.unwrap_or_else(|| primary.fragment(text.slice(..))); + vec![path.into_owned()] } else { // Otherwise use each selection, trimmed. selections .fragments(text.slice(..)) - .map(|sel| sel.trim().to_string()) + .map(|sel| sel.trim().to_owned()) .filter(|sel| !sel.is_empty()) .collect() }; @@ -1329,7 +1307,7 @@ fn goto_file_impl(cx: &mut Context, action: Action) { continue; } - let path = expand_tilde(Cow::from(PathBuf::from(sel))); + let path = path::expand(&sel); let path = &rel_path.join(path); if path.is_dir() { let picker = ui::file_picker(path.into(), &cx.editor.config()); diff --git a/helix-term/src/handlers/completion.rs b/helix-term/src/handlers/completion.rs index 68956c85f..f3223487c 100644 --- a/helix-term/src/handlers/completion.rs +++ b/helix-term/src/handlers/completion.rs @@ -4,20 +4,20 @@ use std::time::Duration; use arc_swap::ArcSwap; use futures_util::stream::FuturesUnordered; +use futures_util::FutureExt; use helix_core::chars::char_is_word; use helix_core::syntax::LanguageServerFeature; -use helix_event::{ - cancelable_future, cancelation, register_hook, send_blocking, CancelRx, CancelTx, -}; +use helix_event::{cancelable_future, register_hook, send_blocking, TaskController, TaskHandle}; use helix_lsp::lsp; use helix_lsp::util::pos_to_lsp_pos; use helix_stdx::rope::RopeSliceExt; use helix_view::document::{Mode, SavePoint}; use helix_view::handlers::lsp::CompletionEvent; use helix_view::{DocumentId, Editor, ViewId}; +use path::path_completion; use tokio::sync::mpsc::Sender; use tokio::time::Instant; -use tokio_stream::StreamExt; +use tokio_stream::StreamExt as _; use crate::commands; use crate::compositor::Compositor; @@ -27,10 +27,13 @@ use crate::job::{dispatch, dispatch_blocking}; use crate::keymap::MappableCommand; use crate::ui::editor::InsertEvent; use crate::ui::lsp::SignatureHelp; -use crate::ui::{self, CompletionItem, Popup}; +use crate::ui::{self, Popup}; use super::Handlers; +pub use item::{CompletionItem, LspCompletionItem}; pub use resolve::ResolveHandler; +mod item; +mod path; mod resolve; #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -53,12 +56,8 @@ pub(super) struct CompletionHandler { /// currently active trigger which will cause a /// completion request after the timeout trigger: Option, - /// A handle for currently active completion request. - /// This can be used to determine whether the current - /// request is still active (and new triggers should be - /// ignored) and can also be used to abort the current - /// request (by dropping the handle) - request: Option, + in_flight: Option, + task_controller: TaskController, config: Arc>, } @@ -66,8 +65,9 @@ impl CompletionHandler { pub fn new(config: Arc>) -> CompletionHandler { Self { config, - request: None, + task_controller: TaskController::new(), trigger: None, + in_flight: None, } } } @@ -80,6 +80,9 @@ impl helix_event::AsyncHook for CompletionHandler { event: Self::Event, _old_timeout: Option, ) -> Option { + if self.in_flight.is_some() && !self.task_controller.is_running() { + self.in_flight = None; + } match event { CompletionEvent::AutoTrigger { cursor: trigger_pos, @@ -90,7 +93,7 @@ impl helix_event::AsyncHook for CompletionHandler { // but people may create weird keymaps/use the mouse so lets be extra careful if self .trigger - .as_ref() + .or(self.in_flight) .map_or(true, |trigger| trigger.doc != doc || trigger.view != view) { self.trigger = Some(Trigger { @@ -103,7 +106,7 @@ impl helix_event::AsyncHook for CompletionHandler { } CompletionEvent::TriggerChar { cursor, doc, view } => { // immediately request completions and drop all auto completion requests - self.request = None; + self.task_controller.cancel(); self.trigger = Some(Trigger { pos: cursor, view, @@ -113,7 +116,6 @@ impl helix_event::AsyncHook for CompletionHandler { } CompletionEvent::ManualTrigger { cursor, doc, view } => { // immediately request completions and drop all auto completion requests - self.request = None; self.trigger = Some(Trigger { pos: cursor, view, @@ -126,21 +128,21 @@ impl helix_event::AsyncHook for CompletionHandler { } CompletionEvent::Cancel => { self.trigger = None; - self.request = None; + self.task_controller.cancel(); } CompletionEvent::DeleteText { cursor } => { // if we deleted the original trigger, abort the completion - if matches!(self.trigger, Some(Trigger{ pos, .. }) if cursor < pos) { + if matches!(self.trigger.or(self.in_flight), Some(Trigger{ pos, .. }) if cursor < pos) + { self.trigger = None; - self.request = None; + self.task_controller.cancel(); } } } self.trigger.map(|trigger| { // if the current request was closed forget about it // otherwise immediately restart the completion request - let cancel = self.request.take().map_or(false, |req| !req.is_closed()); - let timeout = if trigger.kind == TriggerKind::Auto && !cancel { + let timeout = if trigger.kind == TriggerKind::Auto { self.config.load().editor.completion_timeout } else { // we want almost instant completions for trigger chars @@ -155,17 +157,17 @@ impl helix_event::AsyncHook for CompletionHandler { fn finish_debounce(&mut self) { let trigger = self.trigger.take().expect("debounce always has a trigger"); - let (tx, rx) = cancelation(); - self.request = Some(tx); + self.in_flight = Some(trigger); + let handle = self.task_controller.restart(); dispatch_blocking(move |editor, compositor| { - request_completion(trigger, rx, editor, compositor) + request_completion(trigger, handle, editor, compositor) }); } } fn request_completion( mut trigger: Trigger, - cancel: CancelRx, + handle: TaskHandle, editor: &mut Editor, compositor: &mut Compositor, ) { @@ -251,15 +253,19 @@ fn request_completion( None => Vec::new(), } .into_iter() - .map(|item| CompletionItem { - item, - provider: language_server_id, - resolved: false, + .map(|item| { + CompletionItem::Lsp(LspCompletionItem { + item, + provider: language_server_id, + resolved: false, + }) }) .collect(); anyhow::Ok(items) } + .boxed() }) + .chain(path_completion(cursor, text.clone(), doc, handle.clone())) .collect(); let future = async move { @@ -280,12 +286,13 @@ fn request_completion( let ui = compositor.find::().unwrap(); ui.last_insert.1.push(InsertEvent::RequestCompletion); tokio::spawn(async move { - let items = cancelable_future(future, cancel).await.unwrap_or_default(); - if items.is_empty() { + let items = cancelable_future(future, &handle).await; + let Some(items) = items.filter(|items| !items.is_empty()) else { return; - } + }; dispatch(move |editor, compositor| { - show_completion(editor, compositor, items, trigger, savepoint) + show_completion(editor, compositor, items, trigger, savepoint); + drop(handle) }) .await }); @@ -346,7 +353,17 @@ pub fn trigger_auto_completion( .. }) if triggers.iter().any(|trigger| text.ends_with(trigger))) }); - if is_trigger_char { + + let cursor_char = text + .get_bytes_at(text.len_bytes()) + .and_then(|t| t.reversed().next()); + + #[cfg(windows)] + let is_path_completion_trigger = matches!(cursor_char, Some(b'/' | b'\\')); + #[cfg(not(windows))] + let is_path_completion_trigger = matches!(cursor_char, Some(b'/')); + + if is_trigger_char || (is_path_completion_trigger && doc.path_completion_enabled()) { send_blocking( tx, CompletionEvent::TriggerChar { diff --git a/helix-term/src/handlers/completion/item.rs b/helix-term/src/handlers/completion/item.rs new file mode 100644 index 000000000..bcd35cd54 --- /dev/null +++ b/helix-term/src/handlers/completion/item.rs @@ -0,0 +1,41 @@ +use helix_lsp::{lsp, LanguageServerId}; + +#[derive(Debug, PartialEq, Clone)] +pub struct LspCompletionItem { + pub item: lsp::CompletionItem, + pub provider: LanguageServerId, + pub resolved: bool, +} + +#[derive(Debug, PartialEq, Clone)] +pub enum CompletionItem { + Lsp(LspCompletionItem), + Other(helix_core::CompletionItem), +} + +impl PartialEq for LspCompletionItem { + fn eq(&self, other: &CompletionItem) -> bool { + match other { + CompletionItem::Lsp(other) => self == other, + _ => false, + } + } +} + +impl PartialEq for helix_core::CompletionItem { + fn eq(&self, other: &CompletionItem) -> bool { + match other { + CompletionItem::Other(other) => self == other, + _ => false, + } + } +} + +impl CompletionItem { + pub fn preselect(&self) -> bool { + match self { + CompletionItem::Lsp(LspCompletionItem { item, .. }) => item.preselect.unwrap_or(false), + CompletionItem::Other(_) => false, + } + } +} diff --git a/helix-term/src/handlers/completion/path.rs b/helix-term/src/handlers/completion/path.rs new file mode 100644 index 000000000..b7b605073 --- /dev/null +++ b/helix-term/src/handlers/completion/path.rs @@ -0,0 +1,189 @@ +use std::{ + borrow::Cow, + fs, + path::{Path, PathBuf}, + str::FromStr as _, +}; + +use futures_util::{future::BoxFuture, FutureExt as _}; +use helix_core as core; +use helix_core::Transaction; +use helix_event::TaskHandle; +use helix_stdx::path::{self, canonicalize, fold_home_dir, get_path_suffix}; +use helix_view::Document; +use url::Url; + +use super::item::CompletionItem; + +pub(crate) fn path_completion( + cursor: usize, + text: core::Rope, + doc: &Document, + handle: TaskHandle, +) -> Option>>> { + if !doc.path_completion_enabled() { + return None; + } + + let cur_line = text.char_to_line(cursor); + let start = text.line_to_char(cur_line).max(cursor.saturating_sub(1000)); + let line_until_cursor = text.slice(start..cursor); + + let (dir_path, typed_file_name) = + get_path_suffix(line_until_cursor, false).and_then(|matched_path| { + let matched_path = Cow::from(matched_path); + let path: Cow<_> = if matched_path.starts_with("file://") { + Url::from_str(&matched_path) + .ok() + .and_then(|url| url.to_file_path().ok())? + .into() + } else { + Path::new(&*matched_path).into() + }; + let path = path::expand(&path); + let parent_dir = doc.path().and_then(|dp| dp.parent()); + let path = match parent_dir { + Some(parent_dir) if path.is_relative() => parent_dir.join(&path), + _ => path.into_owned(), + }; + #[cfg(windows)] + let ends_with_slash = matches!(matched_path.as_bytes().last(), Some(b'/' | b'\\')); + #[cfg(not(windows))] + let ends_with_slash = matches!(matched_path.as_bytes().last(), Some(b'/')); + + if ends_with_slash { + Some((PathBuf::from(path.as_path()), None)) + } else { + path.parent().map(|parent_path| { + ( + PathBuf::from(parent_path), + path.file_name().and_then(|f| f.to_str().map(String::from)), + ) + }) + } + })?; + + if handle.is_canceled() { + return None; + } + + let future = tokio::task::spawn_blocking(move || { + let Ok(read_dir) = std::fs::read_dir(&dir_path) else { + return Vec::new(); + }; + + read_dir + .filter_map(Result::ok) + .filter_map(|dir_entry| { + dir_entry + .metadata() + .ok() + .and_then(|md| Some((dir_entry.file_name().into_string().ok()?, md))) + }) + .map_while(|(file_name, md)| { + if handle.is_canceled() { + return None; + } + + let kind = path_kind(&md); + let documentation = path_documentation(&md, &dir_path.join(&file_name), kind); + + let edit_diff = typed_file_name + .as_ref() + .map(|f| f.len()) + .unwrap_or_default(); + + let transaction = Transaction::change( + &text, + std::iter::once((cursor - edit_diff, cursor, Some((&file_name).into()))), + ); + + Some(CompletionItem::Other(core::CompletionItem { + kind: Cow::Borrowed(kind), + label: file_name.into(), + transaction, + documentation, + })) + }) + .collect::>() + }); + + Some(async move { Ok(future.await?) }.boxed()) +} + +#[cfg(unix)] +fn path_documentation(md: &fs::Metadata, full_path: &Path, kind: &str) -> String { + let full_path = fold_home_dir(canonicalize(full_path)); + let full_path_name = full_path.to_string_lossy(); + + use std::os::unix::prelude::PermissionsExt; + let mode = md.permissions().mode(); + + let perms = [ + (libc::S_IRUSR, 'r'), + (libc::S_IWUSR, 'w'), + (libc::S_IXUSR, 'x'), + (libc::S_IRGRP, 'r'), + (libc::S_IWGRP, 'w'), + (libc::S_IXGRP, 'x'), + (libc::S_IROTH, 'r'), + (libc::S_IWOTH, 'w'), + (libc::S_IXOTH, 'x'), + ] + .into_iter() + .fold(String::with_capacity(9), |mut acc, (p, s)| { + // This cast is necessary on some platforms such as macos as `mode_t` is u16 there + #[allow(clippy::unnecessary_cast)] + acc.push(if mode & (p as u32) > 0 { s } else { '-' }); + acc + }); + + // TODO it would be great to be able to individually color the documentation, + // but this will likely require a custom doc implementation (i.e. not `lsp::Documentation`) + // and/or different rendering in completion.rs + format!( + "type: `{kind}`\n\ + permissions: `[{perms}]`\n\ + full path: `{full_path_name}`", + ) +} + +#[cfg(not(unix))] +fn path_documentation(md: &fs::Metadata, full_path: &Path, kind: &str) -> String { + let full_path = fold_home_dir(canonicalize(full_path)); + let full_path_name = full_path.to_string_lossy(); + format!("type: `{kind}`\nfull path: `{full_path_name}`",) +} + +#[cfg(unix)] +fn path_kind(md: &fs::Metadata) -> &'static str { + if md.is_symlink() { + "link" + } else if md.is_dir() { + "folder" + } else { + use std::os::unix::fs::FileTypeExt; + if md.file_type().is_block_device() { + "block" + } else if md.file_type().is_socket() { + "socket" + } else if md.file_type().is_char_device() { + "char_device" + } else if md.file_type().is_fifo() { + "fifo" + } else { + "file" + } + } +} + +#[cfg(not(unix))] +fn path_kind(md: &fs::Metadata) -> &'static str { + if md.is_symlink() { + "link" + } else if md.is_dir() { + "folder" + } else { + "file" + } +} diff --git a/helix-term/src/handlers/completion/resolve.rs b/helix-term/src/handlers/completion/resolve.rs index 0b2c90672..802d6f51d 100644 --- a/helix-term/src/handlers/completion/resolve.rs +++ b/helix-term/src/handlers/completion/resolve.rs @@ -4,9 +4,10 @@ use helix_lsp::lsp; use tokio::sync::mpsc::Sender; use tokio::time::{Duration, Instant}; -use helix_event::{send_blocking, AsyncHook, CancelRx}; +use helix_event::{send_blocking, AsyncHook, TaskController, TaskHandle}; use helix_view::Editor; +use super::LspCompletionItem; use crate::handlers::completion::CompletionItem; use crate::job; @@ -22,7 +23,7 @@ use crate::job; /// > 'completionItem/resolve' request is sent with the selected completion item as a parameter. /// > The returned completion item should have the documentation property filled in. pub struct ResolveHandler { - last_request: Option>, + last_request: Option>, resolver: Sender, } @@ -30,15 +31,11 @@ impl ResolveHandler { pub fn new() -> ResolveHandler { ResolveHandler { last_request: None, - resolver: ResolveTimeout { - next_request: None, - in_flight: None, - } - .spawn(), + resolver: ResolveTimeout::default().spawn(), } } - pub fn ensure_item_resolved(&mut self, editor: &mut Editor, item: &mut CompletionItem) { + pub fn ensure_item_resolved(&mut self, editor: &mut Editor, item: &mut LspCompletionItem) { if item.resolved { return; } @@ -93,14 +90,15 @@ impl ResolveHandler { } struct ResolveRequest { - item: Arc, + item: Arc, ls: Arc, } #[derive(Default)] struct ResolveTimeout { next_request: Option, - in_flight: Option<(helix_event::CancelTx, Arc)>, + in_flight: Option>, + task_controller: TaskController, } impl AsyncHook for ResolveTimeout { @@ -120,7 +118,7 @@ impl AsyncHook for ResolveTimeout { } else if self .in_flight .as_ref() - .is_some_and(|(_, old_request)| old_request.item == request.item.item) + .is_some_and(|old_request| old_request.item == request.item.item) { self.next_request = None; None @@ -134,14 +132,14 @@ impl AsyncHook for ResolveTimeout { let Some(request) = self.next_request.take() else { return; }; - let (tx, rx) = helix_event::cancelation(); - self.in_flight = Some((tx, request.item.clone())); - tokio::spawn(request.execute(rx)); + let token = self.task_controller.restart(); + self.in_flight = Some(request.item.clone()); + tokio::spawn(request.execute(token)); } } impl ResolveRequest { - async fn execute(self, cancel: CancelRx) { + async fn execute(self, cancel: TaskHandle) { let future = self.ls.resolve_completion_item(&self.item.item); let Some(resolved_item) = helix_event::cancelable_future(future, cancel).await else { return; @@ -152,8 +150,8 @@ impl ResolveRequest { .unwrap() .completion { - let resolved_item = match resolved_item { - Ok(item) => CompletionItem { + let resolved_item = CompletionItem::Lsp(match resolved_item { + Ok(item) => LspCompletionItem { item, resolved: true, ..*self.item @@ -166,8 +164,8 @@ impl ResolveRequest { item.resolved = true; item } - }; - completion.replace_item(&self.item, resolved_item); + }); + completion.replace_item(&*self.item, resolved_item); }; }) .await diff --git a/helix-term/src/handlers/signature_help.rs b/helix-term/src/handlers/signature_help.rs index aaa97b9a0..e4f7e935a 100644 --- a/helix-term/src/handlers/signature_help.rs +++ b/helix-term/src/handlers/signature_help.rs @@ -2,9 +2,7 @@ use std::sync::Arc; use std::time::Duration; use helix_core::syntax::LanguageServerFeature; -use helix_event::{ - cancelable_future, cancelation, register_hook, send_blocking, CancelRx, CancelTx, -}; +use helix_event::{cancelable_future, register_hook, send_blocking, TaskController, TaskHandle}; use helix_lsp::lsp::{self, SignatureInformation}; use helix_stdx::rope::RopeSliceExt; use helix_view::document::Mode; @@ -22,11 +20,11 @@ use crate::ui::lsp::{Signature, SignatureHelp}; use crate::ui::Popup; use crate::{job, ui}; -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] enum State { Open, Closed, - Pending { request: CancelTx }, + Pending, } /// debounce timeout in ms, value taken from VSCode @@ -37,6 +35,7 @@ const TIMEOUT: u64 = 120; pub(super) struct SignatureHelpHandler { trigger: Option, state: State, + task_controller: TaskController, } impl SignatureHelpHandler { @@ -44,6 +43,7 @@ impl SignatureHelpHandler { SignatureHelpHandler { trigger: None, state: State::Closed, + task_controller: TaskController::new(), } } } @@ -76,12 +76,11 @@ impl helix_event::AsyncHook for SignatureHelpHandler { } SignatureHelpEvent::RequestComplete { open } => { // don't cancel rerequest that was already triggered - if let State::Pending { request } = &self.state { - if !request.is_closed() { - return timeout; - } + if self.state == State::Pending && self.task_controller.is_running() { + return timeout; } self.state = if open { State::Open } else { State::Closed }; + self.task_controller.cancel(); return timeout; } @@ -94,16 +93,16 @@ impl helix_event::AsyncHook for SignatureHelpHandler { fn finish_debounce(&mut self) { let invocation = self.trigger.take().unwrap(); - let (tx, rx) = cancelation(); - self.state = State::Pending { request: tx }; - job::dispatch_blocking(move |editor, _| request_signature_help(editor, invocation, rx)) + self.state = State::Pending; + let handle = self.task_controller.restart(); + job::dispatch_blocking(move |editor, _| request_signature_help(editor, invocation, handle)) } } pub fn request_signature_help( editor: &mut Editor, invoked: SignatureHelpInvoked, - cancel: CancelRx, + cancel: TaskHandle, ) { let (view, doc) = current!(editor); diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index 14397bb5c..cb0af6fc6 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -1,6 +1,9 @@ use crate::{ compositor::{Component, Context, Event, EventResult}, - handlers::{completion::ResolveHandler, trigger_auto_completion}, + handlers::{ + completion::{CompletionItem, LspCompletionItem, ResolveHandler}, + trigger_auto_completion, + }, }; use helix_view::{ document::SavePoint, @@ -13,12 +16,12 @@ use tui::{buffer::Buffer as Surface, text::Span}; use std::{borrow::Cow, sync::Arc}; -use helix_core::{chars, Change, Transaction}; +use helix_core::{self as core, chars, Change, Transaction}; use helix_view::{graphics::Rect, Document, Editor}; use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent}; -use helix_lsp::{lsp, util, LanguageServerId, OffsetEncoding}; +use helix_lsp::{lsp, util, OffsetEncoding}; impl menu::Item for CompletionItem { type Data = (); @@ -28,30 +31,35 @@ impl menu::Item for CompletionItem { #[inline] fn filter_text(&self, _data: &Self::Data) -> Cow { - self.item - .filter_text - .as_ref() - .unwrap_or(&self.item.label) - .as_str() - .into() + match self { + CompletionItem::Lsp(LspCompletionItem { item, .. }) => item + .filter_text + .as_ref() + .unwrap_or(&item.label) + .as_str() + .into(), + CompletionItem::Other(core::CompletionItem { label, .. }) => label.clone(), + } } fn format(&self, _data: &Self::Data) -> menu::Row { - let deprecated = self.item.deprecated.unwrap_or_default() - || self.item.tags.as_ref().map_or(false, |tags| { - tags.contains(&lsp::CompletionItemTag::DEPRECATED) - }); + let deprecated = match self { + CompletionItem::Lsp(LspCompletionItem { item, .. }) => { + item.deprecated.unwrap_or_default() + || item.tags.as_ref().map_or(false, |tags| { + tags.contains(&lsp::CompletionItemTag::DEPRECATED) + }) + } + CompletionItem::Other(_) => false, + }; - menu::Row::new(vec![ - menu::Cell::from(Span::styled( - self.item.label.as_str(), - if deprecated { - Style::default().add_modifier(Modifier::CROSSED_OUT) - } else { - Style::default() - }, - )), - menu::Cell::from(match self.item.kind { + let label = match self { + CompletionItem::Lsp(LspCompletionItem { item, .. }) => item.label.as_str(), + CompletionItem::Other(core::CompletionItem { label, .. }) => label, + }; + + let kind = match self { + CompletionItem::Lsp(LspCompletionItem { item, .. }) => match item.kind { Some(lsp::CompletionItemKind::TEXT) => "text", Some(lsp::CompletionItemKind::METHOD) => "method", Some(lsp::CompletionItemKind::FUNCTION) => "function", @@ -82,18 +90,24 @@ impl menu::Item for CompletionItem { "" } None => "", - }), + }, + CompletionItem::Other(core::CompletionItem { kind, .. }) => kind, + }; + + menu::Row::new([ + menu::Cell::from(Span::styled( + label, + if deprecated { + Style::default().add_modifier(Modifier::CROSSED_OUT) + } else { + Style::default() + }, + )), + menu::Cell::from(kind), ]) } } -#[derive(Debug, PartialEq, Default, Clone)] -pub struct CompletionItem { - pub item: lsp::CompletionItem, - pub provider: LanguageServerId, - pub resolved: bool, -} - /// Wraps a Menu. pub struct Completion { popup: Popup>, @@ -115,11 +129,11 @@ impl Completion { let preview_completion_insert = editor.config().preview_completion_insert; let replace_mode = editor.config().completion_replace; // Sort completion items according to their preselect status (given by the LSP server) - items.sort_by_key(|item| !item.item.preselect.unwrap_or(false)); + items.sort_by_key(|item| !item.preselect()); // Then create the menu let menu = Menu::new(items, (), move |editor: &mut Editor, item, event| { - fn item_to_transaction( + fn lsp_item_to_transaction( doc: &Document, view_id: ViewId, item: &lsp::CompletionItem, @@ -257,16 +271,23 @@ impl Completion { // always present here let item = item.unwrap(); - let transaction = item_to_transaction( - doc, - view.id, - &item.item, - language_server!(item).offset_encoding(), - trigger_offset, - true, - replace_mode, - ); - doc.apply_temporary(&transaction, view.id); + match item { + CompletionItem::Lsp(item) => doc.apply_temporary( + &lsp_item_to_transaction( + doc, + view.id, + &item.item, + language_server!(item).offset_encoding(), + trigger_offset, + true, + replace_mode, + ), + view.id, + ), + CompletionItem::Other(core::CompletionItem { transaction, .. }) => { + doc.apply_temporary(transaction, view.id) + } + }; } PromptEvent::Update => {} PromptEvent::Validate => { @@ -275,32 +296,46 @@ impl Completion { { doc.restore(view, &savepoint, false); } - // always present here - let mut item = item.unwrap().clone(); - - let language_server = language_server!(item); - let offset_encoding = language_server.offset_encoding(); - if !item.resolved { - if let Some(resolved) = - Self::resolve_completion_item(language_server, item.item.clone()) - { - item.item = resolved; - } - }; // if more text was entered, remove it doc.restore(view, &savepoint, true); // save an undo checkpoint before the completion doc.append_changes_to_history(view); - let transaction = item_to_transaction( - doc, - view.id, - &item.item, - offset_encoding, - trigger_offset, - false, - replace_mode, - ); + + // item always present here + let (transaction, additional_edits) = match item.unwrap().clone() { + CompletionItem::Lsp(mut item) => { + let language_server = language_server!(item); + + // resolve item if not yet resolved + if !item.resolved { + if let Some(resolved_item) = Self::resolve_completion_item( + language_server, + item.item.clone(), + ) { + item.item = resolved_item; + } + }; + + let encoding = language_server.offset_encoding(); + let transaction = lsp_item_to_transaction( + doc, + view.id, + &item.item, + encoding, + trigger_offset, + false, + replace_mode, + ); + let add_edits = item.item.additional_text_edits; + + (transaction, add_edits.map(|edits| (edits, encoding))) + } + CompletionItem::Other(core::CompletionItem { transaction, .. }) => { + (transaction, None) + } + }; + doc.apply(&transaction, view.id); editor.last_completion = Some(CompleteAction::Applied { @@ -309,7 +344,7 @@ impl Completion { }); // TODO: add additional _edits to completion_changes? - if let Some(additional_edits) = item.item.additional_text_edits { + if let Some((additional_edits, offset_encoding)) = additional_edits { if !additional_edits.is_empty() { let transaction = util::generate_transaction_from_edits( doc.text(), @@ -414,7 +449,11 @@ impl Completion { self.popup.contents().is_empty() } - pub fn replace_item(&mut self, old_item: &CompletionItem, new_item: CompletionItem) { + pub fn replace_item( + &mut self, + old_item: &impl PartialEq, + new_item: CompletionItem, + ) { self.popup.contents_mut().replace_option(old_item, new_item); } @@ -440,7 +479,7 @@ impl Component for Completion { Some(option) => option, None => return, }; - if !option.resolved { + if let CompletionItem::Lsp(option) = option { self.resolve_handler.ensure_item_resolved(cx.editor, option); } // need to render: @@ -465,27 +504,32 @@ impl Component for Completion { Markdown::new(md, cx.editor.syn_loader.clone()) }; - let mut markdown_doc = match &option.item.documentation { - Some(lsp::Documentation::String(contents)) - | Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { - kind: lsp::MarkupKind::PlainText, - value: contents, - })) => { - // TODO: convert to wrapped text - markdowned(language, option.item.detail.as_deref(), Some(contents)) - } - Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { - kind: lsp::MarkupKind::Markdown, - value: contents, - })) => { - // TODO: set language based on doc scope - markdowned(language, option.item.detail.as_deref(), Some(contents)) - } - None if option.item.detail.is_some() => { - // TODO: set language based on doc scope - markdowned(language, option.item.detail.as_deref(), None) + let mut markdown_doc = match option { + CompletionItem::Lsp(option) => match &option.item.documentation { + Some(lsp::Documentation::String(contents)) + | Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { + kind: lsp::MarkupKind::PlainText, + value: contents, + })) => { + // TODO: convert to wrapped text + markdowned(language, option.item.detail.as_deref(), Some(contents)) + } + Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { + kind: lsp::MarkupKind::Markdown, + value: contents, + })) => { + // TODO: set language based on doc scope + markdowned(language, option.item.detail.as_deref(), Some(contents)) + } + None if option.item.detail.is_some() => { + // TODO: set language based on doc scope + markdowned(language, option.item.detail.as_deref(), None) + } + None => return, + }, + CompletionItem::Other(option) => { + markdowned(language, None, Some(&option.documentation)) } - None => return, }; let popup_area = self.popup.area(area, cx.editor); diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index f7541fe25..5179be4f4 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -2,13 +2,14 @@ use crate::{ commands::{self, OnKeyCallback}, compositor::{Component, Context, Event, EventResult}, events::{OnModeSwitch, PostCommand}, + handlers::completion::CompletionItem, key, keymap::{KeymapResult, Keymaps}, ui::{ document::{render_document, LinePos, TextRenderer}, statusline, text_decorations::{self, Decoration, DecorationManager, InlineDiagnostics}, - Completion, CompletionItem, ProgressSpinners, + Completion, ProgressSpinners, }, }; diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index c120d0b25..ffe3ebb3c 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -228,7 +228,7 @@ impl Menu { } impl Menu { - pub fn replace_option(&mut self, old_option: &T, new_option: T) { + pub fn replace_option(&mut self, old_option: &impl PartialEq, new_option: T) { for option in &mut self.options { if old_option == option { *option = new_option; diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 6a3e198c1..ab9b5392b 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -17,7 +17,7 @@ mod text_decorations; use crate::compositor::Compositor; use crate::filter_picker_entry; use crate::job::{self, Callback}; -pub use completion::{Completion, CompletionItem}; +pub use completion::Completion; pub use editor::EditorView; use helix_stdx::rope; pub use markdown::Markdown; diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 91ec27874..fa089cdaf 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -1713,6 +1713,12 @@ impl Document { self.version } + pub fn path_completion_enabled(&self) -> bool { + self.language_config() + .and_then(|lang_config| lang_config.path_completion) + .unwrap_or_else(|| self.config.load().path_completion) + } + /// maintains the order as configured in the language_servers TOML array pub fn language_servers(&self) -> impl Iterator { self.language_config().into_iter().flat_map(move |config| { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 9e1bee8e1..174190e5d 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -268,6 +268,11 @@ pub struct Config { pub auto_pairs: AutoPairConfig, /// Automatic auto-completion, automatically pop up without user trigger. Defaults to true. pub auto_completion: bool, + /// Enable filepath completion. + /// Show files and directories if an existing path at the cursor was recognized, + /// either absolute or relative to the current opened document or current working directory (if the buffer is not yet saved). + /// Defaults to true. + pub path_completion: bool, /// Automatic formatting on save. Defaults to true. pub auto_format: bool, /// Default register used for yank/paste. Defaults to '"' @@ -952,6 +957,7 @@ impl Default for Config { middle_click_paste: true, auto_pairs: AutoPairConfig::default(), auto_completion: true, + path_completion: true, auto_format: true, default_yank_register: '"', auto_save: AutoSave::default(),