diff options
| author | Ayose <ayosec@gmail.com> | 2025-07-23 00:00:00 +0000 |
|---|---|---|
| committer | Ayose <ayosec@gmail.com> | 2025-07-23 00:00:00 +0000 |
| commit | a247c96e9f59ee73908ace776dde3812557c8b83 (patch) | |
| tree | 41a8e4b4d0ae517443ff5f80c5227e37817986df | |
| parent | 814e8fefc60b4457ea155d11df9f27795de830ec (diff) | |
| parent | 376cdb370018b737d2d92f26bba0d5297b6eb0c0 (diff) | |
| download | r-alacritty-a247c96e9f59ee73908ace776dde3812557c8b83.tar.gz r-alacritty-a247c96e9f59ee73908ace776dde3812557c8b83.tar.bz2 r-alacritty-a247c96e9f59ee73908ace776dde3812557c8b83.zip | |
Merge remote-tracking branch 'vendor/master' into graphics
89 files changed, 1767 insertions, 980 deletions
diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index 5e5021c6..0546b948 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -24,7 +24,7 @@ tasks: cargo test - oldstable: | cd alacritty - oldstable=$(cat alacritty/Cargo.toml | grep "rust-version" | sed 's/.*"\(.*\)".*/\1/') + oldstable=$(cat Cargo.toml | grep "rust-version" | sed 's/.*"\(.*\)".*/\1/') rustup toolchain install --profile minimal $oldstable rustup default $oldstable cargo test diff --git a/.builds/linux.yml b/.builds/linux.yml index e036261b..7e19269d 100644 --- a/.builds/linux.yml +++ b/.builds/linux.yml @@ -34,7 +34,7 @@ tasks: cargo test - oldstable: | cd alacritty - oldstable=$(cat alacritty/Cargo.toml | grep "rust-version" | sed 's/.*"\(.*\)".*/\1/') + oldstable=$(cat Cargo.toml | grep "rust-version" | sed 's/.*"\(.*\)".*/\1/') rustup toolchain install --profile minimal $oldstable rustup default $oldstable cargo test diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c65e7f82..d7ae755d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: run: cargo test -p alacritty_terminal --no-default-features - name: Oldstable run: | - rustup default $(cat alacritty/Cargo.toml | grep "rust-version" | sed 's/.*"\(.*\)".*/\1/') + rustup default $(cat Cargo.toml | grep "rust-version" | sed 's/.*"\(.*\)".*/\1/') cargo test - name: Clippy run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index cf13eb7a..9daa45a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,18 @@ Notable changes to the `alacritty_terminal` crate are documented in its ## 0.16.0-dev +### Packaging + +- Minimum Rust version has been bumped to 1.85.0 + +### Added + +- Vi motions `*`, `#`, `{`, and `}` +- IPC config retrieval using `alacritty msg get-config` +- Multi-sequence touch zoom sequences +- Vi action `Y` keybind, yank to the end of line +- Add `/etc/alacritty/alacritty.toml` fallback for system wide configuration + ### Changed - Hide login message if `~/.hushlogin` is present @@ -17,6 +29,12 @@ Notable changes to the `alacritty_terminal` crate are documented in its ### Fixed - Crash when OpenGL context resets +- Modifier keys clearing selection with kitty keyboard protocol enabled +- `glyph_offset.y` not applied to strikeout +- `Enter`,`Tab`, `Backspace` not disambiguated with `shift` in kitty keyboard's disambiguate mode +- Hint bindings not respecting IPC overrides +- Search matching a wrapping fullwidth character in the last column +- Crash when `AppleFontSmoothing` option is not present on macOS ## 0.15.1 @@ -1,21 +1,21 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.3.3", "once_cell", "version_check", "zerocopy", @@ -38,7 +38,7 @@ dependencies = [ "alacritty_config", "alacritty_config_derive", "alacritty_terminal", - "bitflags 2.6.0", + "bitflags 2.9.1", "clap", "clap_complete", "copypasta", @@ -52,9 +52,9 @@ dependencies = [ "log", "memoffset", "notify", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.1", + "objc2-app-kit 0.3.1", + "objc2-foundation 0.3.1", "parking_lot", "png", "serde", @@ -63,9 +63,9 @@ dependencies = [ "smallvec", "tempfile", "toml", - "toml_edit", + "toml_edit 0.23.1", "unicode-width", - "windows-sys 0.52.0", + "windows-sys 0.59.0", "winit", "xdg", ] @@ -98,7 +98,7 @@ name = "alacritty_terminal" version = "0.25.1-dev" dependencies = [ "base64", - "bitflags 2.6.0", + "bitflags 2.9.1", "home", "libc", "log", @@ -107,6 +107,7 @@ dependencies = [ "piper", "polling", "regex-automata", + "rustix 1.0.7", "rustix-openpty", "serde", "serde_json", @@ -124,7 +125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.6.0", + "bitflags 2.9.1", "cc", "cesu8", "jni", @@ -135,7 +136,7 @@ dependencies = [ "ndk-context", "ndk-sys", "num_enum", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -146,9 +147,9 @@ checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -161,35 +162,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", + "once_cell_polyfill", "windows-sys 0.59.0", ] @@ -219,9 +221,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64" @@ -237,45 +239,39 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ "serde", ] [[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] name = "block2" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2", + "objc2 0.5.2", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.20.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "calloop" @@ -283,12 +279,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "log", "polling", - "rustix", + "rustix 0.38.44", "slab", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -298,16 +294,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", - "rustix", + "rustix 0.38.44", "wayland-backend", "wayland-client", ] [[package]] name = "cc" -version = "1.2.4" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" dependencies = [ "jobserver", "libc", @@ -322,9 +318,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cfg_aliases" @@ -343,9 +339,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.23" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" dependencies = [ "clap_builder", "clap_derive", @@ -353,9 +349,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" dependencies = [ "anstream", "anstyle", @@ -365,18 +361,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.38" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9647a559c112175f17cf724dc72d3645680a883c58481332779192b0d8e7a01" +checksum = "a5abde44486daf70c5be8b8f8f1b66c49f86236edf6fa2abadb4d961c4c6229a" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ "heck", "proc-macro2", @@ -386,55 +382,24 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "clipboard-win" -version = "3.1.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" dependencies = [ - "lazy-bytes-cast", - "winapi", -] - -[[package]] -name = "cocoa" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation", - "core-graphics", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation", - "core-graphics-types", - "libc", - "objc", + "error-code", ] [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -457,14 +422,14 @@ dependencies = [ [[package]] name = "copypasta" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb85422867ca93da58b7f95fb5c0c10f6183ed6e1ef8841568968a896d3a858" +checksum = "3e6811e17f81fe246ef2bc553f76b6ee6ab41a694845df1d37e52a92b7bbd38a" dependencies = [ "clipboard-win", - "objc", - "objc-foundation", - "objc_id", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "smithay-clipboard", "x11-clipboard", ] @@ -531,27 +496,17 @@ dependencies = [ ] [[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossfont" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44e28d120f3c9254800ea53349b09cbb45ac1f15f09215011a16241ae0289bc" +checksum = "a650099c323679b4d6fb6858c2c512660ff5118f6b0ffb1bfc6cadcd54002b14" dependencies = [ - "cocoa", "core-foundation", "core-foundation-sys", "core-graphics", @@ -561,7 +516,8 @@ dependencies = [ "freetype-rs", "libc", "log", - "objc", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "once_cell", "pkg-config", "winapi", @@ -580,32 +536,32 @@ dependencies = [ [[package]] name = "cursor-icon" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" dependencies = [ "serde", ] [[package]] name = "dirs" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] @@ -615,6 +571,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.1", +] + +[[package]] name = "dlib" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -631,18 +597,18 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" dependencies = [ "serde", ] [[package]] name = "dwrote" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70182709525a3632b2ba96b6569225467b18ecb4a77f46d255f713a6bebf05fd" +checksum = "bfe1f192fcce01590bd8d839aca53ce0d11d803bf291b2a6c4ad925a8f0024be" dependencies = [ "lazy_static", "libc", @@ -654,9 +620,9 @@ dependencies = [ [[package]] name = "embed-resource" -version = "2.5.1" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68b6f9f63a0b6a38bc447d4ce84e2b388f3ec95c99c641c8ff0dd3ef89a6379" +checksum = "4c6d81016d6c977deefb2ef8d8290da019e27cc26167e102185da528e6c0ab38" dependencies = [ "cc", "memchr", @@ -668,21 +634,27 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + +[[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -698,22 +670,10 @@ dependencies = [ ] [[package]] -name = "filetime" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" -dependencies = [ - "cfg-if", - "libc", - "libredox", - "windows-sys 0.59.0", -] - -[[package]] name = "flate2" -version = "1.0.35" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -752,7 +712,7 @@ version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5442dee36ca09604133580dc0553780e867936bb3cbef3275859e889026d2b17" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "freetype-sys", "libc", ] @@ -795,13 +755,25 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -817,22 +789,22 @@ dependencies = [ [[package]] name = "glutin" -version = "0.32.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03642b8b0cce622392deb0ee3e88511f75df2daac806102597905c3ea1974848" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cfg_aliases", "cgl", - "core-foundation", - "dispatch", + "dispatch2", "glutin_egl_sys", "glutin_glx_sys", "glutin_wgl_sys", "libloading", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.6.1", + "objc2-app-kit 0.3.1", + "objc2-core-foundation", + "objc2-foundation 0.3.1", "once_cell", "raw-window-handle", "wayland-sys", @@ -871,9 +843,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "heck" @@ -883,24 +855,24 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "indexmap" -version = "2.7.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", @@ -908,11 +880,11 @@ dependencies = [ [[package]] name = "inotify" -version = "0.9.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.1", "inotify-sys", "libc", ] @@ -934,9 +906,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jni" @@ -949,7 +921,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] @@ -962,18 +934,19 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -987,9 +960,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kqueue" -version = "1.0.8" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" dependencies = [ "kqueue-sys", "libc", @@ -1006,12 +979,6 @@ dependencies = [ ] [[package]] -name = "lazy-bytes-cast" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" - -[[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1019,42 +986,48 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.168" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.53.2", ] [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "libc", - "redox_syscall 0.5.8", + "redox_syscall 0.5.13", ] [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -1062,27 +1035,18 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" dependencies = [ "serde", ] [[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" @@ -1104,9 +1068,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", "simd-adler32", @@ -1114,14 +1078,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", - "wasi", - "windows-sys 0.48.0", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] @@ -1139,13 +1103,13 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "jni-sys", "log", "ndk-sys", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1165,37 +1129,43 @@ dependencies = [ [[package]] name = "notify" -version = "6.1.1" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +checksum = "3163f59cd3fa0e9ef8c32f242966a7b9994fd7378366099593e0e73077cd8c97" dependencies = [ - "bitflags 2.6.0", - "crossbeam-channel", - "filetime", + "bitflags 2.9.1", "fsevent-sys", "inotify", "kqueue", "libc", "log", "mio", + "notify-types", "walkdir", - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] +name = "notify-types" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" + +[[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1204,26 +1174,6 @@ dependencies = [ ] [[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] name = "objc-sys" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1240,32 +1190,53 @@ dependencies = [ ] [[package]] +name = "objc2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" +dependencies = [ + "objc2-encode", +] + +[[package]] name = "objc2-app-kit" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", "libc", - "objc2", + "objc2 0.5.2", "objc2-core-data", "objc2-core-image", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-quartz-core", ] [[package]] +name = "objc2-app-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.1", + "objc2-core-foundation", + "objc2-foundation 0.3.1", +] + +[[package]] name = "objc2-cloud-kit" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -1275,8 +1246,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -1285,10 +1256,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags 2.9.1", + "dispatch2", + "objc2 0.6.1", ] [[package]] @@ -1298,8 +1280,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -1310,16 +1292,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-contacts", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] name = "objc2-encode" -version = "4.0.3" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" [[package]] name = "objc2-foundation" @@ -1327,11 +1309,22 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", "dispatch", "libc", - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.1", + "objc2-core-foundation", ] [[package]] @@ -1341,9 +1334,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ "block2", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -1352,10 +1345,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -1364,10 +1357,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -1377,8 +1370,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -1387,14 +1380,14 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", "objc2-core-image", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-link-presentation", "objc2-quartz-core", "objc2-symbols", @@ -1409,8 +1402,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -1419,27 +1412,24 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] -name = "objc_id" -version = "0.1.1" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "once_cell" -version = "1.20.2" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "option-ext" @@ -1458,9 +1448,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -1468,13 +1458,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.8", + "redox_syscall 0.5.13", "smallvec", "windows-targets 0.52.6", ] @@ -1487,18 +1477,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", @@ -1507,9 +1497,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "piper" @@ -1524,15 +1514,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "png" -version = "0.17.15" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -1543,56 +1533,62 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.4" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +checksum = "b53a684391ad002dd6a596ceb6c74fd004fdce75f4be2e3f615068abbea5fd50" dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix", + "rustix 1.0.7", "tracing", "windows-sys 0.59.0", ] [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ - "toml_edit", + "toml_edit 0.22.27", ] [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quick-xml" -version = "0.36.2" +version = "0.37.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] name = "raw-window-handle" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1609,22 +1605,22 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", ] [[package]] name = "redox_users" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "getrandom", + "getrandom 0.2.16", "libredox", - "thiserror", + "thiserror 2.0.12", ] [[package]] @@ -1655,34 +1651,52 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.9.1", "errno", - "itoa", "libc", - "linux-raw-sys", + "linux-raw-sys 0.9.4", "windows-sys 0.59.0", ] [[package]] name = "rustix-openpty" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a25c3aad9fc1424eb82c88087789a7d938e1829724f3e4043163baf0d13cfc12" +checksum = "1de16c7c59892b870a6336f185dc10943517f1327447096bbb7bb32cd85e2393" dependencies = [ "errno", "libc", - "rustix", + "rustix 1.0.7", ] [[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -1719,24 +1733,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1745,9 +1759,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1757,9 +1771,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" dependencies = [ "serde", ] @@ -1785,9 +1799,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" dependencies = [ "libc", "signal-hook-registry", @@ -1795,9 +1809,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -1810,18 +1824,15 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" dependencies = [ "serde", ] @@ -1832,15 +1843,15 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "calloop", "calloop-wayland-source", "cursor-icon", "libc", "log", "memmap2", - "rustix", - "thiserror", + "rustix 0.38.44", + "thiserror 1.0.69", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -1885,9 +1896,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1896,14 +1907,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.14.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.3.3", "once_cell", - "rustix", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -1913,7 +1924,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -1928,6 +1948,17 @@ dependencies = [ ] [[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "tiny-skia" version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1954,39 +1985,74 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac" dependencies = [ + "indexmap", "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.7.0", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_datetime" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", - "serde", - "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "winnow", ] [[package]] +name = "toml_edit" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f23a5f4511b296579b6c83e437fe85fa7ece22e3ec44e45ddb975bcf57c3dd" +dependencies = [ + "indexmap", + "toml_datetime 0.7.0", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" + +[[package]] name = "tracing" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1998,15 +2064,15 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-segmentation" @@ -2016,9 +2082,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.14" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unsafe-libyaml" @@ -2050,9 +2116,9 @@ dependencies = [ [[package]] name = "vswhom-sys" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" dependencies = [ "cc", "libc", @@ -2065,7 +2131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a7d926313d94a0ef0d992fe9ab507451cdb4a7977e653155c8e4fa9b69c178f" dependencies = [ "arrayvec", - "bitflags 2.6.0", + "bitflags 2.9.1", "cursor-icon", "log", "memchr", @@ -2084,26 +2150,36 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", @@ -2115,9 +2191,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", @@ -2128,9 +2204,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2138,9 +2214,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -2151,19 +2227,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wayland-backend" -version = "0.3.7" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" dependencies = [ "cc", "downcast-rs", - "rustix", + "rustix 0.38.44", "scoped-tls", "smallvec", "wayland-sys", @@ -2171,12 +2250,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.7" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" dependencies = [ - "bitflags 2.6.0", - "rustix", + "bitflags 2.9.1", + "rustix 0.38.44", "wayland-backend", "wayland-scanner", ] @@ -2187,29 +2266,29 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "cursor-icon", "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.31.7" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" +checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182" dependencies = [ - "rustix", + "rustix 0.38.44", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.32.5" +version = "0.32.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "wayland-backend", "wayland-client", "wayland-scanner", @@ -2217,11 +2296,11 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" +checksum = "4fd38cdad69b56ace413c6bcc1fbf5acc5e2ef4af9d5f8f1f9570c0c83eae175" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2230,11 +2309,11 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2243,9 +2322,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.5" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" dependencies = [ "proc-macro2", "quick-xml", @@ -2254,9 +2333,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.5" +version = "0.31.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" dependencies = [ "dlib", "log", @@ -2266,9 +2345,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -2352,6 +2431,15 @@ dependencies = [ ] [[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + +[[package]] name = "windows-targets" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2390,7 +2478,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -2398,6 +2486,22 @@ dependencies = [ ] [[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2416,6 +2520,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2434,6 +2544,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2452,12 +2568,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2476,6 +2604,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2494,6 +2628,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2512,6 +2652,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2530,15 +2676,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] name = "winit" -version = "0.30.9" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0" +checksum = "a4409c10174df8779dc29a4788cac85ed84024ccbc1743b776b21a520ee1aaf4" dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.6.0", + "bitflags 2.9.1", "block2", "bytemuck", "calloop", @@ -2552,16 +2704,16 @@ dependencies = [ "libc", "memmap2", "ndk", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", "percent-encoding", "pin-project", "raw-window-handle", "redox_syscall 0.4.1", - "rustix", + "rustix 0.38.44", "sctk-adwaita", "serde", "smithay-client-toolkit", @@ -2584,21 +2736,21 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.52.0" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -2611,6 +2763,15 @@ dependencies = [ ] [[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] name = "x11-clipboard" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2642,7 +2803,7 @@ dependencies = [ "libc", "libloading", "once_cell", - "rustix", + "rustix 0.38.44", "x11rb-protocol", ] @@ -2654,15 +2815,15 @@ checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" [[package]] name = "xcursor" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" [[package]] name = "xdg" -version = "2.5.2" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" +checksum = "2fb433233f2df9344722454bc7e96465c9d03bff9d77c248f9e7523fe79585b5" [[package]] name = "xkbcommon-dl" @@ -2670,7 +2831,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.1", "dlib", "log", "once_cell", @@ -2685,9 +2846,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.24" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" [[package]] name = "yeslogic-fontconfig-sys" @@ -2703,18 +2864,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", @@ -7,7 +7,15 @@ members = [ ] resolver = "2" +[workspace.package] +edition = "2024" +rust-version = "1.85.0" + [profile.release] lto = "thin" debug = 1 incremental = false + +[workspace.dependencies] +toml = "0.9.2" +toml_edit = "0.23.1" @@ -84,7 +84,7 @@ to build Alacritty. Here's an apt command that should install all of them. If something is still found to be missing, please open an issue. ```sh -apt install cmake g++ pkg-config libfreetype6-dev libfontconfig1-dev libxcb-xfixes0-dev libxkbcommon-dev python3 +apt install cmake g++ pkg-config libfontconfig1-dev libxcb-xfixes0-dev libxkbcommon-dev python3 ``` #### Arch Linux @@ -136,7 +136,7 @@ a `zypper` command that should install all of them. If something is still found to be missing, please open an issue. ```sh -zypper install cmake freetype-devel fontconfig-devel libxcb-devel libxkbcommon-devel +zypper install cmake freetype-devel fontconfig-devel libxcb-devel libxkbcommon-devel gcc-c++ ``` #### Slackware @@ -68,6 +68,7 @@ following locations: 2. `$XDG_CONFIG_HOME/alacritty.toml` 3. `$HOME/.config/alacritty/alacritty.toml` 4. `$HOME/.alacritty.toml` +5. `/etc/alacritty/alacritty.toml` On Windows, the config file will be looked for in: diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index 19467e9d..59bbad8b 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -7,8 +7,8 @@ description = "A fast, cross-platform, OpenGL terminal emulator" readme = "README.md" homepage = "https://alacritty.org" repository = "https://github.com/alacritty/alacritty" -edition = "2021" -rust-version = "1.74.0" +edition.workspace = true +rust-version.workspace = true [dependencies.alacritty_terminal] path = "../alacritty_terminal" @@ -27,22 +27,22 @@ ahash = { version = "0.8.6", features = ["no-rng"] } bitflags = "2.2.1" clap = { version = "4.2.7", features = ["derive", "env"] } copypasta = { version = "0.10.1", default-features = false } -crossfont = "0.8.0" +crossfont = "0.8.1" glutin = { version = "0.32.2", default-features = false, features = ["egl", "wgl"] } home = "0.5.5" libc = "0.2" log = { version = "0.4", features = ["std", "serde"] } memoffset = "0.9.0" -notify = "6.1.1" +notify = "8.0.0" parking_lot = "0.12.0" serde_json = "1" serde = { version = "1", features = ["derive"] } serde_yaml = "0.9.25" smallvec = { version = "1.13.1", features = ["serde"] } tempfile = "3.12.0" -toml = "0.8.2" -toml_edit = "0.22.21" -unicode-width = "0.1" +toml.workspace = true +toml_edit.workspace = true +unicode-width = "0.2.0" winit = { version = "0.30.9", default-features = false, features = ["rwh_06", "serde"] } [build-dependencies] @@ -52,19 +52,19 @@ gl_generator = "0.14.0" clap_complete = "4.2.3" [target.'cfg(not(windows))'.dependencies] -xdg = "2.5.0" +xdg = "3.0.0" [target.'cfg(not(target_os = "macos"))'.dependencies] png = { version = "0.17.5", default-features = false, optional = true } [target.'cfg(target_os = "macos")'.dependencies] -objc2 = "0.5.2" -objc2-foundation = { version = "0.2.2", default-features = false, features = [ +objc2 = "0.6.1" +objc2-foundation = { version = "0.3.1", default-features = false, features = [ "std", "NSString", "NSLocale", ] } -objc2-app-kit = { version = "0.2.2", default-features = false, features = [ +objc2-app-kit = { version = "0.3.1", default-features = false, features = [ "std", "NSColorSpace", "NSResponder", @@ -73,8 +73,8 @@ objc2-app-kit = { version = "0.2.2", default-features = false, features = [ ] } [target.'cfg(windows)'.dependencies] -dirs = "5.0.1" -windows-sys = { version = "0.52", features = [ +dirs = "6.0.0" +windows-sys = { version = "0.59", features = [ "Win32_UI_WindowsAndMessaging", "Win32_System_Threading", "Win32_System_Console", @@ -82,7 +82,7 @@ windows-sys = { version = "0.52", features = [ ]} [target.'cfg(windows)'.build-dependencies] -embed-resource = "2.2.0" +embed-resource = "3.0.2" [features] default = ["wayland", "x11"] diff --git a/alacritty/build.rs b/alacritty/build.rs index 02f0fdaf..1ad3c4ed 100644 --- a/alacritty/build.rs +++ b/alacritty/build.rs @@ -25,7 +25,9 @@ fn main() { .unwrap(); #[cfg(windows)] - embed_resource::compile("./windows/alacritty.rc", embed_resource::NONE); + embed_resource::compile("./windows/alacritty.rc", embed_resource::NONE) + .manifest_required() + .unwrap(); } fn commit_hash() -> Option<String> { diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index feac41bd..041845cf 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -6,15 +6,15 @@ use std::rc::Rc; use alacritty_config::SerdeReplace; use clap::{ArgAction, Args, Parser, Subcommand, ValueHint}; -use log::{error, LevelFilter}; +use log::{LevelFilter, error}; use serde::{Deserialize, Serialize}; use toml::Value; use alacritty_terminal::tty::Options as PtyOptions; +use crate::config::UiConfig; use crate::config::ui_config::Program; use crate::config::window::{Class, Identity}; -use crate::config::UiConfig; use crate::logging::LOG_TARGET_IPC_CONFIG; /// CLI options for the main Alacritty executable. @@ -135,7 +135,7 @@ fn parse_class(input: &str) -> Result<Class, String> { let (general, instance) = match input.split_once(',') { // Warn the user if they've passed too many values. Some((_, instance)) if instance.contains(',') => { - return Err(String::from("Too many parameters")) + return Err(String::from("Too many parameters")); }, Some((general, instance)) => (general, instance), None => (input, input), @@ -181,7 +181,7 @@ impl TerminalOptions { if working_directory.is_dir() { pty_config.working_directory = Some(working_directory.to_owned()); } else { - error!("Invalid working directory: {:?}", working_directory); + error!("Invalid working directory: {working_directory:?}"); } } @@ -258,6 +258,9 @@ pub enum SocketMessage { /// Update the Alacritty configuration. Config(IpcConfig), + + /// Read runtime Alacritty configuration. + GetConfig(IpcGetConfig), } /// Migrate the configuration file. @@ -336,6 +339,17 @@ pub struct IpcConfig { pub reset: bool, } +/// Parameters to the `get-config` IPC subcommand. +#[cfg(unix)] +#[derive(Args, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)] +pub struct IpcGetConfig { + /// Window ID for the config request. + /// + /// Use `-1` to get the global config. + #[clap(short, long, allow_hyphen_values = true, env = "ALACRITTY_WINDOW_ID")] + pub window_id: Option<i128>, +} + /// Parsed CLI config overrides. #[derive(Debug, Default)] pub struct ParsedOptions { @@ -370,7 +384,7 @@ impl ParsedOptions { Err(err) => { error!( target: LOG_TARGET_IPC_CONFIG, - "Unable to override option '{}': {}", option, err + "Unable to override option '{option}': {err}" ); self.config_options.swap_remove(i); }, diff --git a/alacritty/src/clipboard.rs b/alacritty/src/clipboard.rs index 7853de47..4426269d 100644 --- a/alacritty/src/clipboard.rs +++ b/alacritty/src/clipboard.rs @@ -3,14 +3,14 @@ use winit::raw_window_handle::RawDisplayHandle; use alacritty_terminal::term::ClipboardType; +#[cfg(any(feature = "x11", target_os = "macos", windows))] +use copypasta::ClipboardContext; +use copypasta::ClipboardProvider; use copypasta::nop_clipboard::NopClipboardContext; #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] use copypasta::wayland_clipboard; #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] use copypasta::x11_clipboard::{Primary as X11SelectionClipboard, X11ClipboardContext}; -#[cfg(any(feature = "x11", target_os = "macos", windows))] -use copypasta::ClipboardContext; -use copypasta::ClipboardProvider; pub struct Clipboard { clipboard: Box<dyn ClipboardProvider>, @@ -22,8 +22,9 @@ impl Clipboard { match display { #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] RawDisplayHandle::Wayland(display) => { - let (selection, clipboard) = - wayland_clipboard::create_clipboards_from_external(display.display.as_ptr()); + let (selection, clipboard) = unsafe { + wayland_clipboard::create_clipboards_from_external(display.display.as_ptr()) + }; Self { clipboard: Box::new(clipboard), selection: Some(Box::new(selection)) } }, _ => Self::default(), @@ -62,7 +63,7 @@ impl Clipboard { }; clipboard.set_contents(text.into()).unwrap_or_else(|err| { - warn!("Unable to store text in clipboard: {}", err); + warn!("Unable to store text in clipboard: {err}"); }); } @@ -74,7 +75,7 @@ impl Clipboard { match clipboard.get_contents() { Err(err) => { - debug!("Unable to load text from clipboard: {}", err); + debug!("Unable to load text from clipboard: {err}"); String::new() }, Ok(text) => text, diff --git a/alacritty/src/config/bell.rs b/alacritty/src/config/bell.rs index 0d6874cb..83c6ce2f 100644 --- a/alacritty/src/config/bell.rs +++ b/alacritty/src/config/bell.rs @@ -1,11 +1,13 @@ use std::time::Duration; +use serde::Serialize; + use alacritty_config_derive::ConfigDeserialize; use crate::config::ui_config::Program; use crate::display::color::Rgb; -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct BellConfig { /// Visual bell animation function. pub animation: BellAnimation, @@ -39,7 +41,7 @@ impl BellConfig { /// `VisualBellAnimations` are modeled after a subset of CSS transitions and Robert /// Penner's Easing Functions. -#[derive(ConfigDeserialize, Default, Clone, Copy, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Copy, Debug, PartialEq, Eq)] pub enum BellAnimation { // CSS animation. Ease, diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index 931b0583..4e140dd7 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -328,6 +328,10 @@ pub enum ViAction { InlineSearchNext, /// Jump to the previous inline search match. InlineSearchPrevious, + /// Search forward for selection or word under the cursor. + SemanticSearchForward, + /// Search backward for selection or word under the cursor. + SemanticSearchBackward, } /// Search mode specific actions. @@ -396,21 +400,11 @@ macro_rules! bindings { } macro_rules! trigger { - (KeyBinding, $key:literal, $location:expr) => {{ - BindingKey::Keycode { key: Key::Character($key.into()), location: $location } - }}; - (KeyBinding, $key:literal,) => {{ - BindingKey::Keycode { key: Key::Character($key.into()), location: KeyLocation::Any } - }}; - (KeyBinding, $key:ident, $location:expr) => {{ - BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: $location } - }}; - (KeyBinding, $key:ident,) => {{ - BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: KeyLocation::Any } - }}; - (MouseBinding, $base:ident::$button:ident,) => {{ - $base::$button - }}; + (KeyBinding, $key:literal, $location:expr) => {{ BindingKey::Keycode { key: Key::Character($key.into()), location: $location } }}; + (KeyBinding, $key:literal,) => {{ BindingKey::Keycode { key: Key::Character($key.into()), location: KeyLocation::Any } }}; + (KeyBinding, $key:ident, $location:expr) => {{ BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: $location } }}; + (KeyBinding, $key:ident,) => {{ BindingKey::Keycode { key: Key::Named(NamedKey::$key), location: KeyLocation::Any } }}; + (MouseBinding, $base:ident::$button:ident,) => {{ $base::$button }}; } pub fn default_mouse_bindings() -> Vec<MouseBinding> { @@ -449,11 +443,11 @@ pub fn default_key_bindings() -> Vec<KeyBinding> { F2, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\x1bOQ".into()); F3, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\x1bOR".into()); F4, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\x1bOS".into()); - Tab, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x1b[Z".into()); - Tab, ModifiersState::SHIFT | ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x1b\x1b[Z".into()); + Tab, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\x1b[Z".into()); + Tab, ModifiersState::SHIFT | ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\x1b\x1b[Z".into()); Backspace, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x7f".into()); - Backspace, ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x1b\x7f".into()); - Backspace, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x7f".into()); + Backspace, ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\x1b\x7f".into()); + Backspace, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\x7f".into()); Enter => KeyLocation::Numpad, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\n".into()); // Vi mode. Space, ModifiersState::SHIFT | ModifiersState::CONTROL, ~BindingMode::SEARCH; Action::ToggleViMode; @@ -474,6 +468,10 @@ pub fn default_key_bindings() -> Vec<KeyBinding> { "y", +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; "/", +BindingMode::VI, ~BindingMode::SEARCH; Action::SearchForward; "?", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::SearchBackward; + "y", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleNormalSelection; + "y", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Last; + "y", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::Copy; + "y", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; "v", +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleNormalSelection; "v", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleLineSelection; "v", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleBlockSelection; @@ -488,6 +486,8 @@ pub fn default_key_bindings() -> Vec<KeyBinding> { "t", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::InlineSearchBackwardShort; ";", +BindingMode::VI, ~BindingMode::SEARCH; ViAction::InlineSearchNext; ",", +BindingMode::VI, ~BindingMode::SEARCH; ViAction::InlineSearchPrevious; + "*", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::SemanticSearchForward; + "#", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::SemanticSearchBackward; "k", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Up; "j", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Down; "h", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Left; @@ -511,6 +511,8 @@ pub fn default_key_bindings() -> Vec<KeyBinding> { "w", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::WordRight; "e", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::WordRightEnd; "%", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Bracket; + "{", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::ParagraphUp; + "}", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::ParagraphDown; Enter, +BindingMode::VI, +BindingMode::SEARCH; SearchAction::SearchConfirm; // Plain search. Escape, +BindingMode::SEARCH; SearchAction::SearchCancel; diff --git a/alacritty/src/config/color.rs b/alacritty/src/config/color.rs index 995d0499..ec6427f4 100644 --- a/alacritty/src/config/color.rs +++ b/alacritty/src/config/color.rs @@ -1,11 +1,11 @@ use serde::de::Error as SerdeError; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize}; use alacritty_config_derive::ConfigDeserialize; use crate::display::color::{CellRgb, Rgb}; -#[derive(ConfigDeserialize, Clone, Debug, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, Default, PartialEq, Eq)] pub struct Colors { pub primary: PrimaryColors, pub cursor: InvertedCellColors, @@ -33,19 +33,19 @@ impl Colors { } } -#[derive(ConfigDeserialize, Copy, Clone, Default, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Default, Debug, PartialEq, Eq)] pub struct LineIndicatorColors { pub foreground: Option<Rgb>, pub background: Option<Rgb>, } -#[derive(ConfigDeserialize, Default, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintColors { pub start: HintStartColors, pub end: HintEndColors, } -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintStartColors { pub foreground: CellRgb, pub background: CellRgb, @@ -60,7 +60,7 @@ impl Default for HintStartColors { } } -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintEndColors { pub foreground: CellRgb, pub background: CellRgb, @@ -75,7 +75,7 @@ impl Default for HintEndColors { } } -#[derive(Deserialize, Copy, Clone, Default, Debug, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Copy, Clone, Default, Debug, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct IndexedColor { pub color: Rgb, @@ -90,7 +90,7 @@ impl IndexedColor { } } -#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] +#[derive(Serialize, Copy, Clone, Default, Debug, PartialEq, Eq)] struct ColorIndex(u8); impl<'de> Deserialize<'de> for ColorIndex { @@ -111,7 +111,7 @@ impl<'de> Deserialize<'de> for ColorIndex { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct InvertedCellColors { #[config(alias = "text")] pub foreground: CellRgb, @@ -125,13 +125,13 @@ impl Default for InvertedCellColors { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, Default, PartialEq, Eq)] pub struct SearchColors { pub focused_match: FocusedMatchColors, pub matches: MatchColors, } -#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct FocusedMatchColors { pub foreground: CellRgb, pub background: CellRgb, @@ -146,7 +146,7 @@ impl Default for FocusedMatchColors { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct MatchColors { pub foreground: CellRgb, pub background: CellRgb, @@ -161,13 +161,13 @@ impl Default for MatchColors { } } -#[derive(ConfigDeserialize, Debug, Copy, Clone, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Copy, Clone, Default, PartialEq, Eq)] pub struct BarColors { foreground: Option<Rgb>, background: Option<Rgb>, } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct PrimaryColors { pub foreground: Rgb, pub background: Rgb, @@ -186,7 +186,7 @@ impl Default for PrimaryColors { } } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct NormalColors { pub black: Rgb, pub red: Rgb, @@ -213,7 +213,7 @@ impl Default for NormalColors { } } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct BrightColors { pub black: Rgb, pub red: Rgb, @@ -243,7 +243,7 @@ impl Default for BrightColors { } } -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct DimColors { pub black: Rgb, pub red: Rgb, diff --git a/alacritty/src/config/cursor.rs b/alacritty/src/config/cursor.rs index dc205b4b..660a05ab 100644 --- a/alacritty/src/config/cursor.rs +++ b/alacritty/src/config/cursor.rs @@ -1,7 +1,7 @@ use std::cmp; use std::time::Duration; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use alacritty_terminal::vte::ansi::{CursorShape as VteCursorShape, CursorStyle as VteCursorStyle}; @@ -14,7 +14,7 @@ const MIN_BLINK_INTERVAL: u64 = 10; /// The minimum number of blinks before pausing. const MIN_BLINK_CYCLES_BEFORE_PAUSE: u64 = 1; -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq)] pub struct Cursor { pub style: ConfigCursorStyle, pub vi_mode_style: Option<ConfigCursorStyle>, @@ -73,7 +73,7 @@ impl Cursor { } } -#[derive(SerdeReplace, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(SerdeReplace, Deserialize, Serialize, Debug, Copy, Clone, PartialEq, Eq)] #[serde(untagged, deny_unknown_fields)] pub enum ConfigCursorStyle { Shape(CursorShape), @@ -112,7 +112,7 @@ impl From<ConfigCursorStyle> for VteCursorStyle { } } -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum CursorBlinking { Never, #[default] @@ -137,7 +137,7 @@ impl From<CursorBlinking> for bool { } } -#[derive(ConfigDeserialize, Debug, Default, Eq, PartialEq, Copy, Clone, Hash)] +#[derive(ConfigDeserialize, Serialize, Debug, Default, Eq, PartialEq, Copy, Clone, Hash)] pub enum CursorShape { #[default] Block, diff --git a/alacritty/src/config/debug.rs b/alacritty/src/config/debug.rs index ffd396d5..7d520594 100644 --- a/alacritty/src/config/debug.rs +++ b/alacritty/src/config/debug.rs @@ -1,9 +1,10 @@ use log::LevelFilter; +use serde::Serialize; use alacritty_config_derive::ConfigDeserialize; /// Debugging options. -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Debug { pub log_level: LevelFilter, @@ -26,6 +27,7 @@ pub struct Debug { /// Record ref test. #[config(skip)] + #[serde(skip_serializing)] pub ref_test: bool, } @@ -45,7 +47,7 @@ impl Default for Debug { } /// The renderer configuration options. -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum RendererPreference { /// OpenGL 3.3 renderer. Glsl3, diff --git a/alacritty/src/config/font.rs b/alacritty/src/config/font.rs index 760c26d5..683dcd34 100644 --- a/alacritty/src/config/font.rs +++ b/alacritty/src/config/font.rs @@ -2,7 +2,7 @@ use std::fmt; use crossfont::Size as FontSize; use serde::de::{self, Visitor}; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; @@ -14,7 +14,7 @@ use crate::config::ui_config::Delta; /// field in this struct. It might be nice in the future to have defaults for /// each value independently. Alternatively, maybe erroring when the user /// doesn't provide complete config is Ok. -#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq, Eq)] pub struct Font { /// Extra spacing per character. pub offset: Delta<i8>, @@ -93,7 +93,7 @@ impl Default for Font { } /// Description of the normal font. -#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq, Eq)] pub struct FontDescription { pub family: String, pub style: Option<String>, @@ -114,7 +114,7 @@ impl Default for FontDescription { } /// Description of the italic and bold font. -#[derive(ConfigDeserialize, Debug, Default, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Default, Clone, PartialEq, Eq)] pub struct SecondaryFontDescription { family: Option<String>, style: Option<String>, @@ -163,3 +163,12 @@ impl<'de> Deserialize<'de> for Size { deserializer.deserialize_any(NumVisitor) } } + +impl Serialize for Size { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_f32(self.0.as_pt()) + } +} diff --git a/alacritty/src/config/general.rs b/alacritty/src/config/general.rs index ba559262..5468bfe3 100644 --- a/alacritty/src/config/general.rs +++ b/alacritty/src/config/general.rs @@ -2,13 +2,15 @@ use std::path::PathBuf; +use serde::Serialize; + use alacritty_config_derive::ConfigDeserialize; /// General config section. /// /// This section is for fields which can not be easily categorized, /// to avoid common TOML issues with root-level fields. -#[derive(ConfigDeserialize, Clone, PartialEq, Debug)] +#[derive(ConfigDeserialize, Serialize, Clone, PartialEq, Debug)] pub struct General { /// Configuration file imports. /// diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs index ba9d674d..5d35c2e0 100644 --- a/alacritty/src/config/mod.rs +++ b/alacritty/src/config/mod.rs @@ -31,7 +31,7 @@ use crate::cli::Options; #[cfg(test)] pub use crate::config::bindings::Binding; pub use crate::config::bindings::{ - Action, BindingKey, BindingMode, MouseAction, SearchAction, ViAction, + Action, BindingKey, BindingMode, KeyBinding, MouseAction, SearchAction, ViAction, }; pub use crate::config::ui_config::UiConfig; use crate::logging::LOG_TARGET_CONFIG; @@ -148,7 +148,7 @@ pub fn load(options: &mut Options) -> UiConfig { /// Attempt to reload the configuration file. pub fn reload(config_path: &Path, options: &mut Options) -> Result<UiConfig> { - debug!("Reloading configuration file: {:?}", config_path); + debug!("Reloading configuration file: {config_path:?}"); // Load config, propagating errors. let mut config = load_from(config_path)?; @@ -162,9 +162,6 @@ pub fn reload(config_path: &Path, options: &mut Options) -> Result<UiConfig> { fn after_loading(config: &mut UiConfig, options: &mut Options) { // Override config with CLI options. options.override_config(config); - - // Create key bindings for regex hints. - config.generate_hint_bindings(); } /// Load configuration file and log errors. @@ -172,11 +169,11 @@ fn load_from(path: &Path) -> Result<UiConfig> { match read_config(path) { Ok(config) => Ok(config), Err(Error::Io(io)) if io.kind() == io::ErrorKind::NotFound => { - error!(target: LOG_TARGET_CONFIG, "Unable to load config {:?}: File not found", path); + error!(target: LOG_TARGET_CONFIG, "Unable to load config {path:?}: File not found"); Err(Error::Io(io)) }, Err(err) => { - error!(target: LOG_TARGET_CONFIG, "Unable to load config {:?}: {}", path, err); + error!(target: LOG_TARGET_CONFIG, "Unable to load config {path:?}: {err}"); Err(err) }, } @@ -271,7 +268,7 @@ fn load_imports( continue; }, Err(err) => { - error!(target: LOG_TARGET_CONFIG, "Unable to import config {:?}: {}", path, err) + error!(target: LOG_TARGET_CONFIG, "Unable to import config {path:?}: {err}") }, } } @@ -371,19 +368,15 @@ fn prune_yaml_nulls(value: &mut serde_yaml::Value, warn_pruned: bool) { /// 2. $XDG_CONFIG_HOME/alacritty.toml /// 3. $HOME/.config/alacritty/alacritty.toml /// 4. $HOME/.alacritty.toml +/// 5. /etc/alacritty/alacritty.toml #[cfg(not(windows))] pub fn installed_config(suffix: &str) -> Option<PathBuf> { let file_name = format!("alacritty.{suffix}"); // Try using XDG location by default. xdg::BaseDirectories::with_prefix("alacritty") - .ok() - .and_then(|xdg| xdg.find_config_file(&file_name)) - .or_else(|| { - xdg::BaseDirectories::new() - .ok() - .and_then(|fallback| fallback.find_config_file(&file_name)) - }) + .find_config_file(&file_name) + .or_else(|| xdg::BaseDirectories::new().find_config_file(&file_name)) .or_else(|| { if let Ok(home) = env::var("HOME") { // Fallback path: $HOME/.config/alacritty/alacritty.toml. @@ -398,7 +391,9 @@ pub fn installed_config(suffix: &str) -> Option<PathBuf> { return Some(fallback); } } - None + + let fallback = PathBuf::from("/etc/alacritty").join(&file_name); + fallback.exists().then_some(fallback) }) } diff --git a/alacritty/src/config/monitor.rs b/alacritty/src/config/monitor.rs index 3f73f120..feda3f25 100644 --- a/alacritty/src/config/monitor.rs +++ b/alacritty/src/config/monitor.rs @@ -42,7 +42,7 @@ impl ConfigMonitor { // a regular file. paths.retain(|path| { // Call `metadata` to resolve symbolic links. - path.metadata().map_or(false, |metadata| metadata.file_type().is_file()) + path.metadata().is_ok_and(|metadata| metadata.file_type().is_file()) }); // Canonicalize paths, keeping the base paths for symlinks. @@ -63,7 +63,7 @@ impl ConfigMonitor { ) { Ok(watcher) => watcher, Err(err) => { - error!("Unable to watch config file: {}", err); + error!("Unable to watch config file: {err}"); return None; }, }; @@ -84,7 +84,7 @@ impl ConfigMonitor { // Watch all configuration file directories. for parent in &parents { if let Err(err) = watcher.watch(parent, RecursiveMode::NonRecursive) { - debug!("Unable to watch config directory {:?}: {}", parent, err); + debug!("Unable to watch config directory {parent:?}: {err}"); } } @@ -135,10 +135,10 @@ impl ConfigMonitor { } }, Ok(Err(err)) => { - debug!("Config watcher errors: {:?}", err); + debug!("Config watcher errors: {err:?}"); }, Err(err) => { - debug!("Config watcher channel dropped unexpectedly: {}", err); + debug!("Config watcher channel dropped unexpectedly: {err}"); break; }, }; @@ -166,7 +166,7 @@ impl ConfigMonitor { /// This checks the supplied list of files against the monitored files to determine if a /// restart is necessary. pub fn needs_restart(&self, files: &[PathBuf]) -> bool { - Self::hash_paths(files).map_or(true, |hash| Some(hash) == self.watched_hash) + Self::hash_paths(files).is_none_or(|hash| Some(hash) == self.watched_hash) } /// Generate the hash for a list of paths. diff --git a/alacritty/src/config/mouse.rs b/alacritty/src/config/mouse.rs index 4afd7446..1f39174a 100644 --- a/alacritty/src/config/mouse.rs +++ b/alacritty/src/config/mouse.rs @@ -1,13 +1,14 @@ -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use crate::config::bindings::{self, MouseBinding}; use crate::config::ui_config; -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq, Eq)] pub struct Mouse { pub hide_when_typing: bool, + #[serde(skip_serializing)] pub bindings: MouseBindings, } diff --git a/alacritty/src/config/scrolling.rs b/alacritty/src/config/scrolling.rs index 3b2b21f3..b1b84e73 100644 --- a/alacritty/src/config/scrolling.rs +++ b/alacritty/src/config/scrolling.rs @@ -1,5 +1,5 @@ use serde::de::Error as SerdeError; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; @@ -7,7 +7,7 @@ use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; pub const MAX_SCROLLBACK_LINES: u32 = 100_000; /// Struct for scrolling related settings. -#[derive(ConfigDeserialize, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub struct Scrolling { pub multiplier: u8, @@ -26,7 +26,7 @@ impl Scrolling { } } -#[derive(SerdeReplace, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(SerdeReplace, Serialize, Copy, Clone, Debug, PartialEq, Eq)] struct ScrollingHistory(u32); impl Default for ScrollingHistory { diff --git a/alacritty/src/config/selection.rs b/alacritty/src/config/selection.rs index bf90b48f..495c3b12 100644 --- a/alacritty/src/config/selection.rs +++ b/alacritty/src/config/selection.rs @@ -1,7 +1,9 @@ +use serde::Serialize; + use alacritty_config_derive::ConfigDeserialize; use alacritty_terminal::term::SEMANTIC_ESCAPE_CHARS; -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct Selection { pub semantic_escape_chars: String, pub save_to_clipboard: bool, diff --git a/alacritty/src/config/terminal.rs b/alacritty/src/config/terminal.rs index d0c0d9da..daf4a34e 100644 --- a/alacritty/src/config/terminal.rs +++ b/alacritty/src/config/terminal.rs @@ -1,4 +1,4 @@ -use serde::{de, Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, de}; use toml::Value; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; @@ -6,7 +6,7 @@ use alacritty_terminal::term::Osc52; use crate::config::ui_config::{Program, StringVisitor}; -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq)] pub struct Terminal { /// OSC52 support mode. pub osc52: SerdeOsc52, @@ -14,7 +14,7 @@ pub struct Terminal { pub shell: Option<Program>, } -#[derive(SerdeReplace, Default, Copy, Clone, Debug, PartialEq)] +#[derive(SerdeReplace, Serialize, Default, Copy, Clone, Debug, PartialEq)] pub struct SerdeOsc52(pub Osc52); impl<'de> Deserialize<'de> for SerdeOsc52 { diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index 960bdbbc..ddc9dbb7 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -1,22 +1,24 @@ -use std::cell::RefCell; +use std::cell::{OnceCell, RefCell}; use std::collections::HashMap; use std::error::Error; use std::fmt::{self, Formatter}; +use std::mem; use std::path::PathBuf; use std::rc::Rc; -use alacritty_config::SerdeReplace; -use alacritty_terminal::term::Config as TermConfig; -use alacritty_terminal::tty::{Options as PtyOptions, Shell}; use log::{error, warn}; use serde::de::{Error as SerdeError, MapAccess, Visitor}; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use unicode_width::UnicodeWidthChar; use winit::keyboard::{Key, ModifiersState}; +use alacritty_config::SerdeReplace; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; +use alacritty_terminal::term::Config as TermConfig; use alacritty_terminal::term::search::RegexSearch; +use alacritty_terminal::tty::{Options as PtyOptions, Shell}; +use crate::config::LOG_TARGET_CONFIG; use crate::config::bell::BellConfig; use crate::config::bindings::{ self, Action, Binding, BindingKey, KeyBinding, KeyLocation, ModeWrapper, ModsWrapper, @@ -32,14 +34,13 @@ use crate::config::scrolling::Scrolling; use crate::config::selection::Selection; use crate::config::terminal::Terminal; use crate::config::window::WindowConfig; -use crate::config::LOG_TARGET_CONFIG; /// Regex used for the default URL hint. #[rustfmt::skip] const URL_REGEX: &str = "(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)\ [^\u{0000}-\u{001F}\u{007F}-\u{009F}<>\"\\s{-}\\^⟨⟩`\\\\]+"; -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq)] pub struct UiConfig { /// Miscellaneous configuration options. pub general: General, @@ -76,6 +77,7 @@ pub struct UiConfig { /// Path where config was loaded from. #[config(skip)] + #[serde(skip_serializing)] pub config_paths: Vec<PathBuf>, /// Regex hints for interacting with terminal content. @@ -133,26 +135,6 @@ impl UiConfig { PtyOptions { working_directory, shell, drain_on_exit: false, env: HashMap::new() } } - /// Generate key bindings for all keyboard hints. - pub fn generate_hint_bindings(&mut self) { - for hint in &self.hints.enabled { - let binding = match &hint.binding { - Some(binding) => binding, - None => continue, - }; - - let binding = KeyBinding { - trigger: binding.key.clone(), - mods: binding.mods.0, - mode: binding.mode.mode, - notmode: binding.mode.not_mode, - action: Action::Hint(hint.clone()), - }; - - self.keyboard.bindings.0.push(binding); - } - } - #[inline] pub fn window_opacity(&self) -> f32 { self.window.opacity.as_f32() @@ -181,9 +163,10 @@ impl UiConfig { } /// Keyboard configuration. -#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Default, Clone, Debug, PartialEq)] struct Keyboard { /// Keybindings. + #[serde(skip_serializing)] bindings: KeyBindings, } @@ -222,7 +205,7 @@ where match Binding::<T>::deserialize(value) { Ok(binding) => bindings.push(binding), Err(err) => { - error!(target: LOG_TARGET_CONFIG, "Config error: {}; ignoring binding", err); + error!(target: LOG_TARGET_CONFIG, "Config error: {err}; ignoring binding"); }, } } @@ -238,7 +221,7 @@ where } /// A delta for a point in a 2 dimensional plane. -#[derive(ConfigDeserialize, Clone, Copy, Debug, Default, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct Delta<T: Default> { /// Horizontal change. pub x: T, @@ -247,7 +230,7 @@ pub struct Delta<T: Default> { } /// Regex terminal hints. -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct Hints { /// Characters for the hint labels. alphabet: HintsAlphabet, @@ -286,6 +269,7 @@ impl Default for Hints { location: KeyLocation::Standard, }, mods: ModsWrapper(ModifiersState::SHIFT | ModifiersState::CONTROL), + cache: Default::default(), mode: Default::default(), }), })], @@ -301,7 +285,7 @@ impl Hints { } } -#[derive(SerdeReplace, Clone, Debug, PartialEq, Eq)] +#[derive(SerdeReplace, Serialize, Clone, Debug, PartialEq, Eq)] struct HintsAlphabet(String); impl Default for HintsAlphabet { @@ -334,7 +318,7 @@ impl<'de> Deserialize<'de> for HintsAlphabet { } /// Built-in actions for hint mode. -#[derive(ConfigDeserialize, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub enum HintInternalAction { /// Copy the text to the clipboard. Copy, @@ -347,7 +331,7 @@ pub enum HintInternalAction { } /// Actions for hint bindings. -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub enum HintAction { /// Built-in hint action. #[serde(rename = "action")] @@ -359,7 +343,7 @@ pub enum HintAction { } /// Hint configuration. -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct Hint { /// Regex for finding matches. #[serde(flatten)] @@ -381,10 +365,11 @@ pub struct Hint { pub mouse: Option<HintMouse>, /// Binding required to search for this hint. - binding: Option<HintBinding>, + #[serde(skip_serializing)] + pub binding: Option<HintBinding>, } -#[derive(Default, Clone, Debug, PartialEq, Eq)] +#[derive(Serialize, Default, Clone, Debug, PartialEq, Eq)] pub struct HintContent { /// Regex for finding matches. pub regex: Option<LazyRegex>, @@ -425,7 +410,7 @@ impl<'de> Deserialize<'de> for HintContent { Err(err) => { error!( target: LOG_TARGET_CONFIG, - "Config error: hint's regex: {}", err + "Config error: hint's regex: {err}" ); }, }, @@ -434,7 +419,7 @@ impl<'de> Deserialize<'de> for HintContent { Err(err) => { error!( target: LOG_TARGET_CONFIG, - "Config error: hint's hyperlinks: {}", err + "Config error: hint's hyperlinks: {err}" ); }, }, @@ -460,7 +445,7 @@ impl<'de> Deserialize<'de> for HintContent { } /// Binding for triggering a keyboard hint. -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Clone, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct HintBinding { pub key: BindingKey, @@ -468,15 +453,43 @@ pub struct HintBinding { pub mods: ModsWrapper, #[serde(default)] pub mode: ModeWrapper, + + /// Cache for on-demand [`HintBinding`] to [`KeyBinding`] conversion. + #[serde(skip)] + cache: OnceCell<KeyBinding>, +} + +impl HintBinding { + /// Get the key binding for a hint. + pub fn key_binding(&self, hint: &Rc<Hint>) -> &KeyBinding { + self.cache.get_or_init(|| KeyBinding { + trigger: self.key.clone(), + mods: self.mods.0, + mode: self.mode.mode, + notmode: self.mode.not_mode, + action: Action::Hint(hint.clone()), + }) + } +} + +impl fmt::Debug for HintBinding { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("HintBinding") + .field("key", &self.key) + .field("mods", &self.mods) + .field("mode", &self.mode) + .finish_non_exhaustive() + } } /// Hint mouse highlighting. -#[derive(ConfigDeserialize, Default, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Copy, Clone, Debug, PartialEq, Eq)] pub struct HintMouse { /// Hint mouse highlighting availability. pub enabled: bool, /// Required mouse modifiers for hint highlighting. + #[serde(skip_serializing)] pub mods: ModsWrapper, } @@ -504,12 +517,27 @@ impl<'de> Deserialize<'de> for LazyRegex { } } +impl Serialize for LazyRegex { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let variant = self.0.borrow(); + let regex = match &*variant { + LazyRegexVariant::Compiled(regex, _) => regex, + LazyRegexVariant::Uncompilable(regex) => regex, + LazyRegexVariant::Pattern(regex) => regex, + }; + serializer.serialize_str(regex) + } +} + /// Regex which is compiled on demand, to avoid expensive computations at startup. #[derive(Clone, Debug)] pub enum LazyRegexVariant { - Compiled(Box<RegexSearch>), + Compiled(String, Box<RegexSearch>), Pattern(String), - Uncompilable, + Uncompilable(String), } impl LazyRegexVariant { @@ -520,25 +548,25 @@ impl LazyRegexVariant { fn compiled(&mut self) -> Option<&mut RegexSearch> { // Check if the regex has already been compiled. let regex = match self { - Self::Compiled(regex_search) => return Some(regex_search), - Self::Uncompilable => return None, - Self::Pattern(regex) => regex, + Self::Compiled(_, regex_search) => return Some(regex_search), + Self::Uncompilable(_) => return None, + Self::Pattern(regex) => mem::take(regex), }; // Compile the regex. - let regex_search = match RegexSearch::new(regex) { + let regex_search = match RegexSearch::new(®ex) { Ok(regex_search) => regex_search, Err(err) => { error!("could not compile hint regex: {err}"); - *self = Self::Uncompilable; + *self = Self::Uncompilable(regex); return None; }, }; - *self = Self::Compiled(Box::new(regex_search)); + *self = Self::Compiled(regex, Box::new(regex_search)); // Return a reference to the compiled DFAs. match self { - Self::Compiled(dfas) => Some(dfas), + Self::Compiled(_, dfas) => Some(dfas), _ => unreachable!(), } } @@ -555,7 +583,7 @@ impl PartialEq for LazyRegexVariant { impl Eq for LazyRegexVariant {} /// Wrapper around f32 that represents a percentage value between 0.0 and 1.0. -#[derive(SerdeReplace, Deserialize, Clone, Copy, Debug, PartialEq)] +#[derive(SerdeReplace, Serialize, Clone, Copy, Debug, PartialEq)] pub struct Percentage(f32); impl Default for Percentage { @@ -574,7 +602,16 @@ impl Percentage { } } -#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +impl<'de> Deserialize<'de> for Percentage { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + Ok(Percentage::new(f32::deserialize(deserializer)?)) + } +} + +#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] #[serde(untagged, deny_unknown_fields)] pub enum Program { Just(String), diff --git a/alacritty/src/config/window.rs b/alacritty/src/config/window.rs index 358bb76d..6eacb251 100644 --- a/alacritty/src/config/window.rs +++ b/alacritty/src/config/window.rs @@ -10,13 +10,13 @@ use winit::window::{Fullscreen, Theme as WinitTheme, WindowLevel as WinitWindowL use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; -use crate::config::ui_config::{Delta, Percentage}; use crate::config::LOG_TARGET_CONFIG; +use crate::config::ui_config::{Delta, Percentage}; /// Default Alacritty name, used for window title and class. pub const DEFAULT_NAME: &str = "Alacritty"; -#[derive(ConfigDeserialize, Debug, Clone, PartialEq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq)] pub struct WindowConfig { /// Initial position. pub position: Option<Delta<i32>>, @@ -29,6 +29,7 @@ pub struct WindowConfig { /// XEmbed parent. #[config(skip)] + #[serde(skip_serializing)] pub embed: Option<u32>, /// Spread out additional padding evenly. @@ -109,10 +110,7 @@ impl WindowConfig { warn!( target: LOG_TARGET_CONFIG, "Both `lines` and `columns` must be non-zero for `window.dimensions` to take \ - effect. Configured value of `{}` is 0 while that of `{}` is {}", - zero_key, - non_zero_key, - non_zero_value, + effect. Configured value of `{zero_key}` is 0 while that of `{non_zero_key}` is {non_zero_value}", ); None @@ -157,7 +155,7 @@ impl WindowConfig { } } -#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, PartialEq, Eq)] pub struct Identity { /// Window title. pub title: String, @@ -172,7 +170,7 @@ impl Default for Identity { } } -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum StartupMode { #[default] Windowed, @@ -181,7 +179,7 @@ pub enum StartupMode { SimpleFullscreen, } -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub enum Decorations { #[default] Full, @@ -193,7 +191,7 @@ pub enum Decorations { /// Window Dimensions. /// /// Newtype to avoid passing values incorrectly. -#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub struct Dimensions { /// Window width in character columns. pub columns: usize, @@ -254,7 +252,7 @@ impl<'de> Deserialize<'de> for Class { Err(err) => { error!( target: LOG_TARGET_CONFIG, - "Config error: class.instance: {}", err + "Config error: class.instance: {err}" ); }, }, @@ -263,7 +261,7 @@ impl<'de> Deserialize<'de> for Class { Err(err) => { error!( target: LOG_TARGET_CONFIG, - "Config error: class.instance: {}", err + "Config error: class.instance: {err}" ); }, }, @@ -279,7 +277,7 @@ impl<'de> Deserialize<'de> for Class { } } -#[derive(ConfigDeserialize, Default, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Clone, Copy, PartialEq, Eq)] pub enum OptionAsAlt { /// The left `Option` key is treated as `Alt`. OnlyLeft, @@ -296,7 +294,7 @@ pub enum OptionAsAlt { } /// System decorations theme variant. -#[derive(ConfigDeserialize, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)] pub enum Theme { Light, Dark, @@ -311,7 +309,7 @@ impl From<Theme> for WinitTheme { } } -#[derive(ConfigDeserialize, Default, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(ConfigDeserialize, Serialize, Default, Debug, Clone, Copy, PartialEq, Eq)] pub enum WindowLevel { #[default] Normal, diff --git a/alacritty/src/display/color.rs b/alacritty/src/display/color.rs index 2e854a3f..a825aff8 100644 --- a/alacritty/src/display/color.rs +++ b/alacritty/src/display/color.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use log::trace; use serde::de::{Error as SerdeError, Visitor}; -use serde::{Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use alacritty_config_derive::SerdeReplace; use alacritty_terminal::term::color::COUNT; @@ -216,10 +216,7 @@ impl Add<Rgb> for Rgb { } } -/// Deserialize an Rgb from a hex string. -/// -/// This is *not* the deserialize impl for Rgb since we want a symmetric -/// serialize/deserialize impl for ref tests. +/// Deserialize Rgb color from a hex string. impl<'de> Deserialize<'de> for Rgb { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where @@ -267,6 +264,16 @@ impl<'de> Deserialize<'de> for Rgb { } } +/// Serialize Rgb color to a hex string. +impl Serialize for Rgb { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + impl Display for Rgb { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b) @@ -300,10 +307,11 @@ impl FromStr for Rgb { } /// RGB color optionally referencing the cell's foreground or background. -#[derive(SerdeReplace, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(SerdeReplace, Serialize, Copy, Clone, Debug, PartialEq, Eq)] pub enum CellRgb { CellForeground, CellBackground, + #[serde(untagged)] Rgb(Rgb), } diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs index 9a7de3fe..58804534 100644 --- a/alacritty/src/display/content.rs +++ b/alacritty/src/display/content.rs @@ -14,7 +14,7 @@ use alacritty_terminal::term::{self, RenderableContent as TerminalContent, Term, use alacritty_terminal::vte::ansi::{Color, CursorShape, NamedColor}; use crate::config::UiConfig; -use crate::display::color::{CellRgb, List, Rgb, DIM_FACTOR}; +use crate::display::color::{CellRgb, DIM_FACTOR, List, Rgb}; use crate::display::hint::{self, HintState}; use crate::display::{Display, SizeInfo}; use crate::event::SearchState; @@ -235,7 +235,7 @@ impl RenderableCell { Self::compute_bg_alpha(content.config, cell.bg) }; - let is_selected = content.terminal_content.selection.map_or(false, |selection| { + let is_selected = content.terminal_content.selection.is_some_and(|selection| { selection.contains_cell( &cell, content.terminal_content.cursor.point, @@ -279,8 +279,8 @@ impl RenderableCell { bg = content.color(NamedColor::Foreground as usize); bg_alpha = 1.0; } - } else if content.search.as_mut().map_or(false, |search| search.advance(cell.point)) { - let focused = content.focused_match.map_or(false, |fm| fm.contains(&cell.point)); + } else if content.search.as_mut().is_some_and(|search| search.advance(cell.point)) { + let focused = content.focused_match.is_some_and(|fm| fm.contains(&cell.point)); let (config_fg, config_bg) = if focused { (colors.search.focused_match.foreground, colors.search.focused_match.background) } else { diff --git a/alacritty/src/display/cursor.rs b/alacritty/src/display/cursor.rs index b0e2d6c3..17e910c0 100644 --- a/alacritty/src/display/cursor.rs +++ b/alacritty/src/display/cursor.rs @@ -2,9 +2,9 @@ use alacritty_terminal::vte::ansi::CursorShape; +use crate::display::SizeInfo; use crate::display::color::Rgb; use crate::display::content::RenderableCursor; -use crate::display::SizeInfo; use crate::renderer::rects::RenderRect; /// Trait for conversion into the iterator. diff --git a/alacritty/src/display/damage.rs b/alacritty/src/display/damage.rs index b0736375..303eef9c 100644 --- a/alacritty/src/display/damage.rs +++ b/alacritty/src/display/damage.rs @@ -238,12 +238,12 @@ impl<'a> RenderDamageIterator<'a> { fn overdamage(size_info: &SizeInfo<u32>, mut rect: Rect) -> Rect { rect.x = (rect.x - size_info.cell_width() as i32).max(0); rect.width = cmp::min( - size_info.width() as i32 - rect.x, + (size_info.width() as i32 - rect.x).max(0), rect.width + 2 * size_info.cell_width() as i32, ); rect.y = (rect.y - size_info.cell_height() as i32 / 2).max(0); rect.height = cmp::min( - size_info.height() as i32 - rect.y, + (size_info.height() as i32 - rect.y).max(0), rect.height + size_info.cell_height() as i32, ); @@ -344,6 +344,11 @@ mod tests { ), rect ); + + // Test out of bounds coord clamping. + let rect = Rect::new(bound * 2, bound * 2, rect_side, rect_side); + let rect = RenderDamageIterator::overdamage(&size_info, rect); + assert_eq!(Rect::new(bound * 2 - cell_size, bound * 2 - cell_size / 2, 0, 0), rect); } #[test] diff --git a/alacritty/src/display/hint.rs b/alacritty/src/display/hint.rs index 3f10b4e5..7083dce3 100644 --- a/alacritty/src/display/hint.rs +++ b/alacritty/src/display/hint.rs @@ -13,8 +13,8 @@ use alacritty_terminal::term::cell::Hyperlink; use alacritty_terminal::term::search::{Match, RegexIter, RegexSearch}; use alacritty_terminal::term::{Term, TermMode}; -use crate::config::ui_config::{Hint, HintAction}; use crate::config::UiConfig; +use crate::config::ui_config::{Hint, HintAction}; /// Maximum number of linewraps followed outside of the viewport during search highlighting. pub const MAX_SEARCH_LINES: usize = 100; @@ -396,7 +396,7 @@ pub fn highlighted_at<T>( config.hints.enabled.iter().find_map(|hint| { // Check if all required modifiers are pressed. - let highlight = hint.mouse.map_or(false, |mouse| { + let highlight = hint.mouse.is_some_and(|mouse| { mouse.enabled && mouse_mods.contains(mouse.mods.0) && (!mouse_mode || mouse_mods.contains(ModifiersState::SHIFT)) @@ -432,7 +432,7 @@ fn hyperlink_at<T>(term: &Term<T>, point: Point) -> Option<(Hyperlink, Match)> { let mut match_end = point; for cell in grid.iter_from(point) { - if cell.hyperlink().map_or(false, |link| link == hyperlink) { + if cell.hyperlink().is_some_and(|link| link == hyperlink) { match_end = cell.point; } else { break; @@ -442,7 +442,7 @@ fn hyperlink_at<T>(term: &Term<T>, point: Point) -> Option<(Hyperlink, Match)> { let mut match_start = point; let mut iter = grid.iter_from(point); while let Some(cell) = iter.prev() { - if cell.hyperlink().map_or(false, |link| link == hyperlink) { + if cell.hyperlink().is_some_and(|link| link == hyperlink) { match_start = cell.point; } else { break; @@ -548,11 +548,7 @@ impl<'a, T> HintPostProcessor<'a, T> { } } - if start > iter.point() { - None - } else { - Some(start..=iter.point()) - } + if start > iter.point() { None } else { Some(start..=iter.point()) } } /// Loop over submatches until a non-empty post-processed match is found. diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 6ff8b1e3..cce7a53f 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -32,28 +32,28 @@ use alacritty_terminal::index::{Column, Direction, Line, Point}; use alacritty_terminal::selection::Selection; use alacritty_terminal::term::cell::Flags; use alacritty_terminal::term::{ - self, LineDamageBounds, Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES, + self, LineDamageBounds, MIN_COLUMNS, MIN_SCREEN_LINES, Term, TermDamage, TermMode, }; use alacritty_terminal::vte::ansi::{CursorShape, NamedColor}; +use crate::config::UiConfig; use crate::config::debug::RendererPreference; use crate::config::font::Font; use crate::config::window::Dimensions; #[cfg(not(windows))] use crate::config::window::StartupMode; -use crate::config::UiConfig; use crate::display::bell::VisualBell; use crate::display::color::{List, Rgb}; use crate::display::content::{RenderableContent, RenderableCursor}; use crate::display::cursor::IntoRects; -use crate::display::damage::{damage_y_to_viewport_y, DamageTracker}; +use crate::display::damage::{DamageTracker, damage_y_to_viewport_y}; use crate::display::hint::{HintMatch, HintState}; use crate::display::meter::Meter; use crate::display::window::Window; use crate::event::{Event, EventType, Mouse, SearchState}; use crate::message_bar::{MessageBuffer, MessageType}; use crate::renderer::rects::{RenderLine, RenderLines, RenderRect}; -use crate::renderer::{self, platform, GlyphCache, Renderer}; +use crate::renderer::{self, GlyphCache, Renderer, platform}; use crate::scheduler::{Scheduler, TimerId, Topic}; use crate::string::{ShortenDirection, StrShortener}; @@ -468,7 +468,7 @@ impl Display { config.window.dynamic_padding && config.window.dimensions().is_none(), ); - info!("Cell size: {} x {}", cell_width, cell_height); + info!("Cell size: {cell_width} x {cell_height}"); info!("Padding: {} x {}", size_info.padding_x(), size_info.padding_y()); info!("Width: {}, Height: {}", size_info.width(), size_info.height()); @@ -521,7 +521,7 @@ impl Display { // Disable vsync. if let Err(err) = surface.set_swap_interval(&context, SwapInterval::DontWait) { - info!("Failed to disable vsync: {}", err); + info!("Failed to disable vsync: {err}"); } Ok(Self { @@ -628,7 +628,7 @@ impl Display { (surface, context) => surface.swap_buffers(context), }; if let Err(err) = res { - debug!("error calling swap_buffers: {}", err); + debug!("error calling swap_buffers: {err}"); } } @@ -684,7 +684,7 @@ impl Display { cell_width = cell_dimensions.0; cell_height = cell_dimensions.1; - info!("Cell size: {} x {}", cell_width, cell_height); + info!("Cell size: {cell_width} x {cell_height}"); // Mark entire terminal as damaged since glyph size could change without cell size // changes. @@ -881,7 +881,7 @@ impl Display { let hyperlink = cell.extra.as_ref().and_then(|extra| extra.hyperlink.as_ref()); let should_highlight = |hint: &Option<HintMatch>| { - hint.as_ref().map_or(false, |hint| hint.should_highlight(point, hyperlink)) + hint.as_ref().is_some_and(|hint| hint.should_highlight(point, hyperlink)) }; if should_highlight(highlighted_hint) || should_highlight(vi_highlighted_hint) { show_hint = true; @@ -1106,7 +1106,7 @@ impl Display { } // Abort if mouse highlighting conditions are not met. - if !mouse.inside_text_area || !term.selection.as_ref().map_or(true, Selection::is_empty) { + if !mouse.inside_text_area || !term.selection.as_ref().is_none_or(Selection::is_empty) { if self.highlighted_hint.take().is_some() { self.damage_tracker.frame().mark_fully_damaged(); dirty = true; @@ -1122,7 +1122,7 @@ impl Display { if highlighted_hint.is_some() { // If mouse changed the line, we should update the hyperlink preview, since the // highlighted hint could be disrupted by the old preview. - dirty = self.hint_mouse_point.map_or(false, |p| p.line != point.line); + dirty = self.hint_mouse_point.is_some_and(|p| p.line != point.line); self.hint_mouse_point = Some(point); self.window.set_mouse_cursor(CursorIcon::Pointer); } else if self.highlighted_hint.is_some() { @@ -1392,7 +1392,7 @@ impl Display { let bg = colors.line_indicator.background.unwrap_or(colors.primary.foreground); // Do not render anything if it would obscure the vi mode cursor. - if obstructed_column.map_or(true, |obstructed_column| obstructed_column < column) { + if obstructed_column.is_none_or(|obstructed_column| obstructed_column < column) { let glyph_cache = &mut self.glyph_cache; self.renderer.draw_string(point, fg, bg, text.chars(), &self.size_info, glyph_cache); } diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index f9fb9272..a91df304 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -22,8 +22,8 @@ use std::fmt::{self, Display, Formatter}; #[cfg(target_os = "macos")] use { + objc2::MainThreadMarker, objc2_app_kit::{NSColorSpace, NSView}, - objc2_foundation::is_main_thread, winit::platform::macos::{OptionAsAlt, WindowAttributesExtMacOS, WindowExtMacOS}, }; @@ -41,8 +41,8 @@ use winit::window::{ use alacritty_terminal::index::Point; use crate::cli::WindowOptions; -use crate::config::window::{Decorations, Identity, WindowConfig}; use crate::config::UiConfig; +use crate::config::window::{Decorations, Identity, WindowConfig}; use crate::display::SizeInfo; /// Window icon for `_NET_WM_ICON` property. @@ -198,7 +198,7 @@ impl Window { use_srgb_color_space(&window); let scale_factor = window.scale_factor(); - log::info!("Window scale factor: {}", scale_factor); + log::info!("Window scale factor: {scale_factor}"); let is_x11 = matches!(window.window_handle().unwrap().as_raw(), RawWindowHandle::Xlib(_)); Ok(Self { @@ -463,7 +463,7 @@ impl Window { pub fn set_has_shadow(&self, has_shadows: bool) { let view = match self.raw_window_handle() { RawWindowHandle::AppKit(handle) => { - assert!(is_main_thread()); + assert!(MainThreadMarker::new().is_some()); unsafe { handle.ns_view.cast::<NSView>().as_ref() } }, _ => return, @@ -506,7 +506,7 @@ impl Window { fn use_srgb_color_space(window: &WinitWindow) { let view = match window.window_handle().unwrap().as_raw() { RawWindowHandle::AppKit(handle) => { - assert!(is_main_thread()); + assert!(MainThreadMarker::new().is_some()); unsafe { handle.ns_view.cast::<NSView>().as_ref() } }, _ => return, diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index c761f5ae..e604ae81 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -11,8 +11,12 @@ use std::ffi::OsStr; use std::fmt::Debug; #[cfg(not(windows))] use std::os::unix::io::RawFd; +#[cfg(unix)] +use std::os::unix::net::UnixStream; use std::path::PathBuf; use std::rc::Rc; +#[cfg(unix)] +use std::sync::Arc; use std::time::{Duration, Instant}; use std::{env, f32, mem}; @@ -35,6 +39,7 @@ use alacritty_terminal::event_loop::Notifier; use alacritty_terminal::grid::{BidirectionalIterator, Dimensions, Scroll}; use alacritty_terminal::index::{Boundary, Column, Direction, Line, Point, Side}; use alacritty_terminal::selection::{Selection, SelectionType}; +use alacritty_terminal::term::cell::Flags; use alacritty_terminal::term::search::{Match, RegexSearch}; use alacritty_terminal::term::{self, ClipboardType, Term, TermMode}; use alacritty_terminal::vte::ansi::NamedColor; @@ -53,6 +58,8 @@ use crate::display::hint::HintMatch; use crate::display::window::Window; use crate::display::{Display, Preedit, SizeInfo}; use crate::input::{self, ActionContext as _, FONT_SIZE_STEP}; +#[cfg(unix)] +use crate::ipc::{self, SocketReply}; use crate::logging::{LOG_TARGET_CONFIG, LOG_TARGET_WINIT}; use crate::message_bar::{Message, MessageBuffer}; use crate::scheduler::{Scheduler, TimerId, Topic}; @@ -189,10 +196,9 @@ impl Processor { /// The result is exit code generate from the loop. pub fn run(&mut self, event_loop: EventLoop<Event>) -> Result<(), Box<dyn Error>> { let result = event_loop.run_app(self); - if let Some(initial_window_error) = self.initial_window_error.take() { - Err(initial_window_error) - } else { - result.map_err(Into::into) + match self.initial_window_error.take() { + Some(initial_window_error) => Err(initial_window_error), + _ => result.map_err(Into::into), } } @@ -308,6 +314,29 @@ impl ApplicationHandler<Event> for Processor { } } }, + // Process IPC config requests. + #[cfg(unix)] + (EventType::IpcGetConfig(stream), window_id) => { + // Get the config for the requested window ID. + let config = match self.windows.iter().find(|(id, _)| window_id == Some(*id)) { + Some((_, window_context)) => window_context.config(), + None => &self.global_ipc_options.override_config_rc(self.config.clone()), + }; + + // Convert config to JSON format. + let config_json = match serde_json::to_string(&config) { + Ok(config_json) => config_json, + Err(err) => { + error!("Failed config serialization: {err}"); + return; + }, + }; + + // Send JSON config to the socket. + if let Ok(mut stream) = stream.try_clone() { + ipc::send_reply(&mut stream, SocketReply::GetConfig(config_json)); + } + }, (EventType::ConfigReload(path), _) => { // Clear config logs from message bar for all terminals. for window_context in self.windows.values_mut() { @@ -354,7 +383,7 @@ impl ApplicationHandler<Event> for Processor { event_loop.exit(); } } else if let Err(err) = self.create_window(event_loop, options) { - error!("Could not open window: {:?}", err); + error!("Could not open window: {err:?}"); } }, // Process events affecting all windows. @@ -477,7 +506,7 @@ impl ApplicationHandler<Event> for Processor { // SAFETY: The clipboard must be dropped before the event loop, so use the nop clipboard // as a safe placeholder. - mem::swap(&mut self.clipboard, &mut Clipboard::new_nop()); + self.clipboard = Clipboard::new_nop(); } } @@ -513,6 +542,8 @@ pub enum EventType { CreateWindow(WindowOptions), #[cfg(unix)] IpcConfig(IpcConfig), + #[cfg(unix)] + IpcGetConfig(Arc<UnixStream>), BlinkCursor, BlinkCursorTimeout, SearchNext, @@ -680,7 +711,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon let vi_mode = self.terminal.mode().contains(TermMode::VI); // Update selection. - if vi_mode && self.terminal.selection.as_ref().map_or(false, |s| !s.is_empty()) { + if vi_mode && self.terminal.selection.as_ref().is_some_and(|s| !s.is_empty()) { self.update_selection(self.terminal.vi_mode_cursor.point, Side::Right); } else if self.mouse.left_button_state == ElementState::Pressed || self.mouse.right_button_state == ElementState::Pressed @@ -714,14 +745,14 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon } fn selection_is_empty(&self) -> bool { - self.terminal.selection.as_ref().map_or(true, Selection::is_empty) + self.terminal.selection.as_ref().is_none_or(Selection::is_empty) } fn clear_selection(&mut self) { // Clear the selection on the terminal. let selection = self.terminal.selection.take(); // Mark the terminal as dirty when selection wasn't empty. - *self.dirty |= selection.map_or(false, |s| !s.is_empty()); + *self.dirty |= selection.is_some_and(|s| !s.is_empty()); } fn update_selection(&mut self, mut point: Point, side: Side) { @@ -873,7 +904,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon let result = spawn_daemon(program, args); match result { - Ok(_) => debug!("Launched {} with args {:?}", program, args), + Ok(_) => debug!("Launched {program} with args {args:?}"), Err(err) => warn!("Unable to launch {program} with args {args:?}: {err}"), } } @@ -905,7 +936,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon #[inline] fn start_search(&mut self, direction: Direction) { // Only create new history entry if the previous regex wasn't empty. - if self.search_state.history.front().map_or(true, |regex| !regex.is_empty()) { + if self.search_state.history.front().is_none_or(|regex| !regex.is_empty()) { self.search_state.history.push_front(String::new()); self.search_state.history.truncate(MAX_SEARCH_HISTORY_SIZE); } @@ -941,6 +972,52 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon } #[inline] + fn start_seeded_search(&mut self, direction: Direction, text: String) { + let origin = self.terminal.vi_mode_cursor.point; + + // Start new search. + self.clear_selection(); + self.start_search(direction); + + // Enter initial selection text. + for c in text.chars() { + if let '$' | '('..='+' | '?' | '['..='^' | '{'..='}' = c { + self.search_input('\\'); + } + self.search_input(c); + } + + // Leave search mode. + self.confirm_search(); + + if !self.terminal.mode().contains(TermMode::VI) { + return; + } + + // Find the target vi cursor point by going to the next match to the right of the origin, + // then jump to the next search match in the target direction. + let target = self.search_next(origin, Direction::Right, Side::Right).and_then(|rm| { + let regex_match = match direction { + Direction::Right => { + let origin = rm.end().add(self.terminal, Boundary::None, 1); + self.search_next(origin, Direction::Right, Side::Left)? + }, + Direction::Left => { + let origin = rm.start().sub(self.terminal, Boundary::None, 1); + self.search_next(origin, Direction::Left, Side::Left)? + }, + }; + Some(*regex_match.start()) + }); + + // Move the vi cursor to the target position. + if let Some(target) = target { + self.terminal_mut().vi_goto_point(target); + self.mark_dirty(); + } + } + + #[inline] fn confirm_search(&mut self) { // Just cancel search when not in vi mode. if !self.terminal.mode().contains(TermMode::VI) { @@ -1217,6 +1294,55 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon } } + /// Get the semantic word at the specified point. + fn semantic_word(&self, point: Point) -> String { + let terminal = self.terminal(); + let grid = terminal.grid(); + + // Find the next semantic word boundary to the right. + let mut end = terminal.semantic_search_right(point); + + // Get point at which skipping over semantic characters has led us back to the + // original character. + let start_cell = &grid[point]; + let search_end = if start_cell.flags.intersects(Flags::LEADING_WIDE_CHAR_SPACER) { + point.add(terminal, Boundary::None, 2) + } else if start_cell.flags.intersects(Flags::WIDE_CHAR) { + point.add(terminal, Boundary::None, 1) + } else { + point + }; + + // Keep moving until we're not on top of a semantic escape character. + let semantic_chars = terminal.semantic_escape_chars(); + loop { + let cell = &grid[end]; + + // Get cell's character, taking wide characters into account. + let c = if cell.flags.contains(Flags::WIDE_CHAR_SPACER) { + grid[end.sub(terminal, Boundary::None, 1)].c + } else { + cell.c + }; + + if !semantic_chars.contains(c) { + break; + } + + end = terminal.semantic_search_right(end.add(terminal, Boundary::None, 1)); + + // Stop if the entire grid is only semantic escape characters. + if end == search_end { + return String::new(); + } + } + + // Find the beginning of the semantic word. + let start = terminal.semantic_search_left(end); + + terminal.bounds_to_string(start, end) + } + /// Handle beginning of terminal text input. fn on_terminal_input_start(&mut self) { self.on_typing_start(); @@ -1575,6 +1701,7 @@ pub enum TouchPurpose { Select(TouchEvent), Scroll(TouchEvent), Zoom(TouchZoom), + ZoomPendingSlot(TouchEvent), Tap(TouchEvent), Invalid(HashSet<u64, RandomState>), } @@ -1617,11 +1744,8 @@ impl TouchZoom { } /// Get active touch slots. - pub fn slots(&self) -> HashSet<u64, RandomState> { - let mut set = HashSet::default(); - set.insert(self.slots.0.id); - set.insert(self.slots.1.id); - set + pub fn slots(&self) -> (TouchEvent, TouchEvent) { + self.slots } /// Calculate distance between slots. @@ -1790,7 +1914,7 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { TerminalEvent::Exit | TerminalEvent::ChildExit(_) | TerminalEvent::Wakeup => (), }, #[cfg(unix)] - EventType::IpcConfig(_) => (), + EventType::IpcConfig(_) | EventType::IpcGetConfig(..) => (), EventType::Message(_) | EventType::ConfigReload(_) | EventType::CreateWindow(_) @@ -1916,7 +2040,7 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { | WindowEvent::Moved(_) => (), } }, - WinitEvent::Suspended { .. } + WinitEvent::Suspended | WinitEvent::NewEvents { .. } | WinitEvent::DeviceEvent { .. } | WinitEvent::LoopExiting diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs index 417f599b..7b0aa09b 100644 --- a/alacritty/src/input/keyboard.rs +++ b/alacritty/src/input/keyboard.rs @@ -11,7 +11,7 @@ use alacritty_terminal::event::EventListener; use alacritty_terminal::term::TermMode; use winit::platform::modifier_supplement::KeyEventExtModifierSupplement; -use crate::config::{Action, BindingKey, BindingMode}; +use crate::config::{Action, BindingKey, BindingMode, KeyBinding}; use crate::event::TYPING_SEARCH_DELAY; use crate::input::{ActionContext, Execute, Processor}; use crate::scheduler::{TimerId, Topic}; @@ -77,6 +77,7 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { let mods = if self.alt_send_esc(&key, text) { mods } else { mods & !ModifiersState::ALT }; let build_key_sequence = Self::should_build_sequence(&key, text, mode, mods); + let is_modifier_key = Self::is_modifier_key(&key); let bytes = if build_key_sequence { build_sequence(key, mods, mode) @@ -92,7 +93,10 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { // Write only if we have something to write. if !bytes.is_empty() { - self.ctx.on_terminal_input_start(); + // Don't clear selection/scroll down when writing escaped modifier keys. + if !is_modifier_key { + self.ctx.on_terminal_input_start(); + } self.ctx.write_to_pty(bytes); } } @@ -125,6 +129,16 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { } } + fn is_modifier_key(key: &KeyEvent) -> bool { + matches!( + key.logical_key.as_ref(), + Key::Named(NamedKey::Shift) + | Key::Named(NamedKey::Control) + | Key::Named(NamedKey::Alt) + | Key::Named(NamedKey::Super) + ) + } + /// Check whether we should try to build escape sequence for the [`KeyEvent`]. fn should_build_sequence( key: &KeyEvent, @@ -138,8 +152,15 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { let disambiguate = mode.contains(TermMode::DISAMBIGUATE_ESC_CODES) && (key.logical_key == Key::Named(NamedKey::Escape) - || (!mods.is_empty() && mods != ModifiersState::SHIFT) - || key.location == KeyLocation::Numpad); + || key.location == KeyLocation::Numpad + || (!mods.is_empty() + && (mods != ModifiersState::SHIFT + || matches!( + key.logical_key, + Key::Named(NamedKey::Tab) + | Key::Named(NamedKey::Enter) + | Key::Named(NamedKey::Backspace) + )))); match key.logical_key { _ if disambiguate => true, @@ -182,9 +203,8 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { key.logical_key.clone() }; - for i in 0..self.ctx.config().key_bindings().len() { - let binding = &self.ctx.config().key_bindings()[i]; - + // Get the action of a key binding. + let mut binding_action = |binding: &KeyBinding| { let key = match (&binding.trigger, &logical_key) { (BindingKey::Scancode(_), _) => BindingKey::Scancode(key.physical_key), (_, code) => { @@ -197,7 +217,30 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { *suppress_chars.get_or_insert(true) &= binding.action != Action::ReceiveChar; // Binding was triggered; run the action. - binding.action.clone().execute(&mut self.ctx); + Some(binding.action.clone()) + } else { + None + } + }; + + // Trigger matching key bindings. + for i in 0..self.ctx.config().key_bindings().len() { + let binding = &self.ctx.config().key_bindings()[i]; + if let Some(action) = binding_action(binding) { + action.execute(&mut self.ctx); + } + } + + // Trigger key bindings for hints. + for i in 0..self.ctx.config().hints.enabled.len() { + let hint = &self.ctx.config().hints.enabled[i]; + let binding = match hint.binding.as_ref() { + Some(binding) => binding.key_binding(hint), + None => continue, + }; + + if let Some(action) = binding_action(binding) { + action.execute(&mut self.ctx); } } @@ -224,7 +267,7 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { | Key::Named(NamedKey::Backspace) if !mode.contains(TermMode::REPORT_ALL_KEYS_AS_ESC) => { - return + return; }, _ => build_sequence(key, mods, mode), }; diff --git a/alacritty/src/input/mod.rs b/alacritty/src/input/mod.rs index 3f85512f..8466ce84 100644 --- a/alacritty/src/input/mod.rs +++ b/alacritty/src/input/mod.rs @@ -6,7 +6,7 @@ //! determine what to do when a non-modifier key is pressed. use std::borrow::Cow; -use std::cmp::{max, min, Ordering}; +use std::cmp::{Ordering, max, min}; use std::collections::HashSet; use std::ffi::OsStr; use std::fmt::Debug; @@ -112,6 +112,7 @@ pub trait ActionContext<T: EventListener> { fn clipboard_mut(&mut self) -> &mut Clipboard; fn scheduler_mut(&mut self) -> &mut Scheduler; fn start_search(&mut self, _direction: Direction) {} + fn start_seeded_search(&mut self, _direction: Direction, _text: String) {} fn confirm_search(&mut self) {} fn cancel_search(&mut self) {} fn search_input(&mut self, _c: char) {} @@ -132,6 +133,7 @@ pub trait ActionContext<T: EventListener> { fn hint_input(&mut self, _character: char) {} fn trigger_hint(&mut self, _hint: &HintMatch) {} fn expand_selection(&mut self) {} + fn semantic_word(&self, point: Point) -> String; fn on_terminal_input_start(&mut self) {} fn paste(&mut self, _text: &str, _bracketed: bool) {} fn spawn_daemon<I, S>(&self, _program: &str, _args: I) @@ -278,6 +280,21 @@ impl<T: EventListener> Execute<T> for Action { }, Action::Vi(ViAction::InlineSearchNext) => ctx.inline_search_next(), Action::Vi(ViAction::InlineSearchPrevious) => ctx.inline_search_previous(), + Action::Vi(ViAction::SemanticSearchForward | ViAction::SemanticSearchBackward) => { + let seed_text = match ctx.terminal().selection_to_string() { + Some(selection) if !selection.is_empty() => selection, + // Get semantic word at the vi cursor position. + _ => ctx.semantic_word(ctx.terminal().vi_mode_cursor.point), + }; + + if !seed_text.is_empty() { + let direction = match self { + Action::Vi(ViAction::SemanticSearchForward) => Direction::Right, + _ => Direction::Left, + }; + ctx.start_seeded_search(direction, seed_text); + } + }, action @ Action::Search(_) if !ctx.search_active() => { debug!("Ignoring {action:?}: Search mode inactive"); }, @@ -834,7 +851,16 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { *touch_purpose = match mem::take(touch_purpose) { TouchPurpose::None => TouchPurpose::Tap(touch), TouchPurpose::Tap(start) => TouchPurpose::Zoom(TouchZoom::new((start, touch))), - TouchPurpose::Zoom(zoom) => TouchPurpose::Invalid(zoom.slots()), + TouchPurpose::ZoomPendingSlot(slot) => { + TouchPurpose::Zoom(TouchZoom::new((slot, touch))) + }, + TouchPurpose::Zoom(zoom) => { + let slots = zoom.slots(); + let mut set = HashSet::default(); + set.insert(slots.0.id); + set.insert(slots.1.id); + TouchPurpose::Invalid(set) + }, TouchPurpose::Scroll(event) | TouchPurpose::Select(event) => { let mut set = HashSet::default(); set.insert(event.id); @@ -888,7 +914,7 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { self.scroll_terminal(0., delta_y, 1.0); }, TouchPurpose::Select(_) => self.mouse_moved(touch.location), - TouchPurpose::Invalid(_) => (), + TouchPurpose::ZoomPendingSlot(_) | TouchPurpose::Invalid(_) => (), } } @@ -908,12 +934,13 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { self.mouse_input(ElementState::Pressed, MouseButton::Left); self.mouse_input(ElementState::Released, MouseButton::Left); }, - // Invalidate zoom once a finger was released. + // Transition zoom to pending state once a finger was released. TouchPurpose::Zoom(zoom) => { - let mut slots = zoom.slots(); - slots.remove(&touch.id); - *touch_purpose = TouchPurpose::Invalid(slots); + let slots = zoom.slots(); + let remaining = if slots.0.id == touch.id { slots.1 } else { slots.0 }; + *touch_purpose = TouchPurpose::ZoomPendingSlot(remaining); }, + TouchPurpose::ZoomPendingSlot(_) => *touch_purpose = Default::default(), // Reset touch state once all slots were released. TouchPurpose::Invalid(slots) => { slots.remove(&touch.id); @@ -1066,7 +1093,7 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { if let Some(mouse_state) = self.message_bar_cursor_state() { mouse_state - } else if self.ctx.display().highlighted_hint.as_ref().map_or(false, hint_highlighted) { + } else if self.ctx.display().highlighted_hint.as_ref().is_some_and(hint_highlighted) { CursorIcon::Pointer } else if !self.ctx.modifiers().state().shift_key() && self.ctx.mouse_mode() { CursorIcon::Default @@ -1237,6 +1264,10 @@ mod tests { fn scheduler_mut(&mut self) -> &mut Scheduler { unimplemented!(); } + + fn semantic_word(&self, _point: Point) -> String { + unimplemented!(); + } } macro_rules! test_clickstate { diff --git a/alacritty/src/ipc.rs b/alacritty/src/ipc.rs index 919035a6..64d96f91 100644 --- a/alacritty/src/ipc.rs +++ b/alacritty/src/ipc.rs @@ -1,12 +1,16 @@ //! Alacritty socket IPC. +use serde::{Deserialize, Serialize}; use std::ffi::OsStr; use std::io::{BufRead, BufReader, Error as IoError, ErrorKind, Result as IoResult, Write}; +use std::net::Shutdown; use std::os::unix::net::{UnixListener, UnixStream}; use std::path::PathBuf; +use std::sync::Arc; use std::{env, fs, process}; -use log::warn; +use log::{error, warn}; +use std::result::Result; use winit::event_loop::EventLoopProxy; use winit::window::WindowId; @@ -33,7 +37,7 @@ pub fn spawn_ipc_socket( let listener = UnixListener::bind(&socket_path)?; - env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str()); + unsafe { env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str()) }; if options.daemon { println!("ALACRITTY_SOCKET={}; export ALACRITTY_SOCKET", socket_path.display()); } @@ -43,9 +47,9 @@ pub fn spawn_ipc_socket( let mut data = String::new(); for stream in listener.incoming().filter_map(Result::ok) { data.clear(); - let mut stream = BufReader::new(stream); + let mut reader = BufReader::new(&stream); - match stream.read_line(&mut data) { + match reader.read_line(&mut data) { Ok(0) | Err(_) => continue, Ok(_) => (), }; @@ -54,7 +58,7 @@ pub fn spawn_ipc_socket( let message: SocketMessage = match serde_json::from_str(&data) { Ok(message) => message, Err(err) => { - warn!("Failed to convert data from socket: {}", err); + warn!("Failed to convert data from socket: {err}"); continue; }, }; @@ -73,6 +77,12 @@ pub fn spawn_ipc_socket( let event = Event::new(EventType::IpcConfig(ipc_config), window_id); let _ = event_proxy.send_event(event); }, + SocketMessage::GetConfig(config) => { + let window_id = + config.window_id.and_then(|id| u64::try_from(id).ok()).map(WindowId::from); + let event = Event::new(EventType::IpcGetConfig(Arc::new(stream)), window_id); + let _ = event_proxy.send_event(event); + }, } } }); @@ -84,10 +94,57 @@ pub fn spawn_ipc_socket( pub fn send_message(socket: Option<PathBuf>, message: SocketMessage) -> IoResult<()> { let mut socket = find_socket(socket)?; - let message = serde_json::to_string(&message)?; - socket.write_all(message[..].as_bytes())?; + // Write message to socket. + let message_json = serde_json::to_string(&message)?; + socket.write_all(message_json.as_bytes())?; let _ = socket.flush(); + // Shutdown write end, to allow reading. + socket.shutdown(Shutdown::Write)?; + + // Get matching IPC reply. + handle_reply(&socket, &message)?; + + Ok(()) +} + +/// Process IPC responses. +fn handle_reply(stream: &UnixStream, message: &SocketMessage) -> IoResult<()> { + // Read reply, returning early if there is none. + let mut buffer = String::new(); + let mut reader = BufReader::new(stream); + if let Ok(0) | Err(_) = reader.read_line(&mut buffer) { + return Ok(()); + } + + // Parse IPC reply. + let reply: SocketReply = serde_json::from_str(&buffer) + .map_err(|err| IoError::other(format!("Invalid IPC format: {err}")))?; + + // Ensure reply matches request. + match (message, &reply) { + // Write requested config to STDOUT. + (SocketMessage::GetConfig(..), SocketReply::GetConfig(config)) => { + println!("{config}"); + Ok(()) + }, + // Ignore requests without reply. + _ => Ok(()), + } +} + +/// Send IPC message reply. +pub fn send_reply(stream: &mut UnixStream, message: SocketReply) { + if let Err(err) = send_reply_fallible(stream, message) { + error!("Failed to send IPC reply: {err}"); + } +} + +/// Send IPC message reply, returning possible errors. +fn send_reply_fallible(stream: &mut UnixStream, message: SocketReply) -> IoResult<()> { + let json = serde_json::to_string(&message).map_err(IoError::other)?; + stream.write_all(json.as_bytes())?; + stream.flush()?; Ok(()) } @@ -95,8 +152,9 @@ pub fn send_message(socket: Option<PathBuf>, message: SocketMessage) -> IoResult #[cfg(not(target_os = "macos"))] fn socket_dir() -> PathBuf { xdg::BaseDirectories::with_prefix("alacritty") + .get_runtime_directory() + .map(ToOwned::to_owned) .ok() - .and_then(|xdg| xdg.get_runtime_directory().map(ToOwned::to_owned).ok()) .and_then(|path| fs::create_dir_all(&path).map(|_| path).ok()) .unwrap_or_else(env::temp_dir) } @@ -171,3 +229,9 @@ fn socket_prefix() -> String { fn socket_prefix() -> String { String::from("Alacritty") } + +/// IPC socket replies. +#[derive(Serialize, Deserialize, Debug)] +pub enum SocketReply { + GetConfig(String), +} diff --git a/alacritty/src/logging.rs b/alacritty/src/logging.rs index 67cad63e..386fe5b2 100644 --- a/alacritty/src/logging.rs +++ b/alacritty/src/logging.rs @@ -87,11 +87,8 @@ impl Logger { } fn file_path(&self) -> Option<PathBuf> { - if let Ok(logfile) = self.logfile.lock() { - Some(logfile.path().clone()) - } else { - None - } + let logfile_lock = self.logfile.lock().ok()?; + Some(logfile_lock.path().clone()) } /// Log a record to the message bar. @@ -204,7 +201,7 @@ impl OnDemandLogFile { path.push(format!("Alacritty-{}.log", process::id())); // Set log path as an environment variable. - env::set_var(ALACRITTY_LOG_ENV, path.as_os_str()); + unsafe { env::set_var(ALACRITTY_LOG_ENV, path.as_os_str()) }; OnDemandLogFile { path, file: None, created: Arc::new(AtomicBool::new(false)) } } diff --git a/alacritty/src/macos/locale.rs b/alacritty/src/macos/locale.rs index 46996515..93dfd8dc 100644 --- a/alacritty/src/macos/locale.rs +++ b/alacritty/src/macos/locale.rs @@ -3,7 +3,7 @@ use std::ffi::{CStr, CString}; use std::{env, str}; -use libc::{setlocale, LC_ALL, LC_CTYPE}; +use libc::{LC_ALL, LC_CTYPE, setlocale}; use log::debug; use objc2::sel; use objc2_foundation::{NSLocale, NSObjectProtocol}; @@ -37,12 +37,12 @@ pub fn set_locale_environment() { let fallback_locale_c = CString::new(FALLBACK_LOCALE).unwrap(); unsafe { setlocale(LC_CTYPE, fallback_locale_c.as_ptr()) }; - env::set_var("LC_CTYPE", FALLBACK_LOCALE); + unsafe { env::set_var("LC_CTYPE", FALLBACK_LOCALE) }; } else { // Use system locale. debug!("Using system locale: {}", system_locale); - env::set_var("LC_ALL", system_locale); + unsafe { env::set_var("LC_ALL", system_locale) }; } } diff --git a/alacritty/src/macos/proc.rs b/alacritty/src/macos/proc.rs index eaa879d9..93dd928b 100644 --- a/alacritty/src/macos/proc.rs +++ b/alacritty/src/macos/proc.rs @@ -135,7 +135,7 @@ mod sys { pub pvi_rdir: vnode_info_path, } - extern "C" { + unsafe extern "C" { pub fn proc_pidinfo( pid: c_int, flavor: c_int, diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index 9260bfa4..eff1a0a2 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -20,7 +20,7 @@ use std::{env, fs}; use log::info; #[cfg(windows)] -use windows_sys::Win32::System::Console::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS}; +use windows_sys::Win32::System::Console::{ATTACH_PARENT_PROCESS, AttachConsole, FreeConsole}; use winit::event_loop::EventLoop; #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] use winit::raw_window_handle::{HasDisplayHandle, RawDisplayHandle}; @@ -49,7 +49,7 @@ mod string; mod window_context; mod gl { - #![allow(clippy::all)] + #![allow(clippy::all, unsafe_op_in_unsafe_fn)] include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs")); } @@ -58,8 +58,8 @@ use crate::cli::MessageOptions; #[cfg(not(any(target_os = "macos", windows)))] use crate::cli::SocketMessage; use crate::cli::{Options, Subcommands}; -use crate::config::monitor::ConfigMonitor; use crate::config::UiConfig; +use crate::config::monitor::ConfigMonitor; use crate::event::{Event, Processor}; #[cfg(target_os = "macos")] use crate::macos::locale; @@ -169,7 +169,7 @@ fn alacritty(mut options: Options) -> Result<(), Box<dyn Error>> { // Set env vars from config. for (key, value) in config.env.iter() { - env::set_var(key, value); + unsafe { env::set_var(key, value) }; } // Switch to home directory. @@ -187,7 +187,7 @@ fn alacritty(mut options: Options) -> Result<(), Box<dyn Error>> { Ok(path) => Some(path), Err(err) if options.daemon => return Err(err.into()), Err(err) => { - log::warn!("Unable to create socket: {:?}", err); + log::warn!("Unable to create socket: {err:?}"); None }, } diff --git a/alacritty/src/panic.rs b/alacritty/src/panic.rs index 2637f8d6..60cf455c 100644 --- a/alacritty/src/panic.rs +++ b/alacritty/src/panic.rs @@ -1,8 +1,8 @@ use std::io::Write; -use std::{io, panic}; +use std::{io, panic, ptr}; use windows_sys::Win32::UI::WindowsAndMessaging::{ - MessageBoxW, MB_ICONERROR, MB_OK, MB_SETFOREGROUND, MB_TASKMODAL, + MB_ICONERROR, MB_OK, MB_SETFOREGROUND, MB_TASKMODAL, MessageBoxW, }; use alacritty_terminal::tty::windows::win32_string; @@ -15,7 +15,7 @@ pub fn attach_handler() { let msg = format!("{}\n\nPress Ctrl-C to Copy", panic_info); unsafe { MessageBoxW( - 0isize, + ptr::null_mut(), win32_string(&msg).as_ptr(), win32_string("Alacritty: Runtime Error").as_ptr(), MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TASKMODAL, diff --git a/alacritty/src/renderer/graphics/draw.rs b/alacritty/src/renderer/graphics/draw.rs index eb1cbad3..4bc66aa4 100644 --- a/alacritty/src/renderer/graphics/draw.rs +++ b/alacritty/src/renderer/graphics/draw.rs @@ -8,11 +8,11 @@ use std::collections::BTreeMap; use std::mem::{self, MaybeUninit}; -use crate::display::content::RenderableCell; use crate::display::SizeInfo; +use crate::display::content::RenderableCell; use crate::gl::types::*; use crate::gl::{self}; -use crate::renderer::graphics::{shader, GraphicsRenderer}; +use crate::renderer::graphics::{GraphicsRenderer, shader}; use crate::renderer::{RenderRect, Rgb}; use alacritty_terminal::graphics::GraphicId; diff --git a/alacritty/src/renderer/graphics/mod.rs b/alacritty/src/renderer/graphics/mod.rs index a6b601b2..37de2969 100644 --- a/alacritty/src/renderer/graphics/mod.rs +++ b/alacritty/src/renderer/graphics/mod.rs @@ -137,7 +137,7 @@ impl GraphicsRenderer { unsafe { gl::GenTextures(1, &mut texture); - trace!("Texture generated: {}", texture); + trace!("Texture generated: {texture}"); gl::BindTexture(gl::TEXTURE_2D, texture); gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAX_LEVEL, 0); @@ -285,7 +285,7 @@ fn check_opengl_extensions(extensions: &[&str]) -> bool { for index in 0..num_exts as GLuint { let pointer = unsafe { gl::GetStringi(gl::EXTENSIONS, index) }; if pointer.is_null() { - log::warn!("Can't get OpenGL extension name at index {} of {}", index, num_exts); + log::warn!("Can't get OpenGL extension name at index {index} of {num_exts}"); return false; } @@ -297,6 +297,6 @@ fn check_opengl_extensions(extensions: &[&str]) -> bool { } } - log::debug!("Missing OpenGL extensions: {:?}", needed); + log::debug!("Missing OpenGL extensions: {needed:?}"); false } diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index ce6b0914..99d4ccae 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -1,15 +1,15 @@ use std::borrow::Cow; use std::collections::HashSet; use std::ffi::{CStr, CString}; -use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::OnceLock; +use std::sync::atomic::{AtomicBool, Ordering}; use std::{fmt, ptr}; use ahash::RandomState; use crossfont::Metrics; use glutin::context::{ContextApi, GlContext, PossiblyCurrentContext}; use glutin::display::{GetGlDisplay, GlDisplay}; -use log::{debug, info, LevelFilter}; +use log::{LevelFilter, debug, info}; use unicode_width::UnicodeWidthChar; use alacritty_terminal::graphics::UpdateQueues; @@ -17,9 +17,9 @@ use alacritty_terminal::index::Point; use alacritty_terminal::term::cell::Flags; use crate::config::debug::RendererPreference; +use crate::display::SizeInfo; use crate::display::color::Rgb; use crate::display::content::RenderableCell; -use crate::display::SizeInfo; use crate::gl; use crate::renderer::graphics::GraphicsRenderer; use crate::renderer::rects::{RectRenderer, RenderRect}; @@ -36,14 +36,6 @@ pub use text::{GlyphCache, LoaderApi}; use shader::ShaderVersion; use text::{Gles2Renderer, Glsl3Renderer, TextRenderer}; -macro_rules! cstr { - ($s:literal) => { - // This can be optimized into an no-op with pre-allocated NUL-terminated bytes. - unsafe { std::ffi::CStr::from_ptr(concat!($s, "\0").as_ptr().cast()) } - }; -} -pub(crate) use cstr; - /// Whether the OpenGL functions have been loaded. pub static GL_FUNS_LOADED: AtomicBool = AtomicBool::new(false); @@ -309,7 +301,7 @@ impl Renderer { _ => "invalid", }; - info!("GPU reset ({})", reason); + info!("GPU reset ({reason})"); true } @@ -442,5 +434,5 @@ extern "system" fn gl_debug_log( _: *mut std::os::raw::c_void, ) { let msg = unsafe { CStr::from_ptr(msg).to_string_lossy() }; - debug!("[gl_render] {}", msg); + debug!("[gl_render] {msg}"); } diff --git a/alacritty/src/renderer/platform.rs b/alacritty/src/renderer/platform.rs index 3b2e2fce..99778ea0 100644 --- a/alacritty/src/renderer/platform.rs +++ b/alacritty/src/renderer/platform.rs @@ -10,7 +10,7 @@ use glutin::display::{Display, DisplayApiPreference, DisplayFeatures, GetGlDispl use glutin::error::Result as GlutinResult; use glutin::prelude::*; use glutin::surface::{Surface, SurfaceAttributesBuilder, WindowSurface}; -use log::{debug, LevelFilter}; +use log::{LevelFilter, debug}; use winit::dpi::PhysicalSize; #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] diff --git a/alacritty/src/renderer/rects.rs b/alacritty/src/renderer/rects.rs index d394073b..16862b76 100644 --- a/alacritty/src/renderer/rects.rs +++ b/alacritty/src/renderer/rects.rs @@ -9,13 +9,12 @@ use alacritty_terminal::grid::Dimensions; use alacritty_terminal::index::{Column, Point}; use alacritty_terminal::term::cell::Flags; +use crate::display::SizeInfo; use crate::display::color::Rgb; use crate::display::content::RenderableCell; -use crate::display::SizeInfo; -use crate::gl; use crate::gl::types::*; use crate::renderer::shader::{ShaderError, ShaderProgram, ShaderVersion}; -use crate::renderer::{self, cstr}; +use crate::{gl, renderer}; #[derive(Debug, Copy, Clone)] pub struct RenderRect { @@ -451,13 +450,13 @@ impl RectShaderProgram { let program = ShaderProgram::new(shader_version, header, RECT_SHADER_V, RECT_SHADER_F)?; Ok(Self { - u_cell_width: program.get_uniform_location(cstr!("cellWidth")).ok(), - u_cell_height: program.get_uniform_location(cstr!("cellHeight")).ok(), - u_padding_x: program.get_uniform_location(cstr!("paddingX")).ok(), - u_padding_y: program.get_uniform_location(cstr!("paddingY")).ok(), - u_underline_position: program.get_uniform_location(cstr!("underlinePosition")).ok(), - u_underline_thickness: program.get_uniform_location(cstr!("underlineThickness")).ok(), - u_undercurl_position: program.get_uniform_location(cstr!("undercurlPosition")).ok(), + u_cell_width: program.get_uniform_location(c"cellWidth").ok(), + u_cell_height: program.get_uniform_location(c"cellHeight").ok(), + u_padding_x: program.get_uniform_location(c"paddingX").ok(), + u_padding_y: program.get_uniform_location(c"paddingY").ok(), + u_underline_position: program.get_uniform_location(c"underlinePosition").ok(), + u_underline_thickness: program.get_uniform_location(c"underlineThickness").ok(), + u_undercurl_position: program.get_uniform_location(c"undercurlPosition").ok(), program, }) } diff --git a/alacritty/src/renderer/text/builtin_font.rs b/alacritty/src/renderer/text/builtin_font.rs index ece7eb86..1d7664f9 100644 --- a/alacritty/src/renderer/text/builtin_font.rs +++ b/alacritty/src/renderer/text/builtin_font.rs @@ -73,7 +73,7 @@ fn box_drawing(character: char, metrics: &Metrics, offset: &Delta<i8>) -> Raster y_end += y_offset; let k = y_end / x_end; - let f_x = |x: f32, h: f32| -> f32 { -1. * k * x + h + y_offset }; + let f_x = |x: f32, h: f32| -> f32 { -k * x + h + y_offset }; let g_x = |x: f32, h: f32| -> f32 { k * x + h + y_offset }; let from_x = 0.; @@ -660,7 +660,7 @@ fn powerline_drawing( }) } -#[repr(packed)] +#[repr(C, packed)] #[derive(Clone, Copy, Debug, Default)] struct Pixel { _r: u8, diff --git a/alacritty/src/renderer/text/gles2.rs b/alacritty/src/renderer/text/gles2.rs index 5268341d..1aa913b6 100644 --- a/alacritty/src/renderer/text/gles2.rs +++ b/alacritty/src/renderer/text/gles2.rs @@ -6,17 +6,17 @@ use log::info; use alacritty_terminal::term::cell::Flags; -use crate::display::content::RenderableCell; use crate::display::SizeInfo; +use crate::display::content::RenderableCell; use crate::gl; use crate::gl::types::*; use crate::renderer::shader::{ShaderProgram, ShaderVersion}; -use crate::renderer::{cstr, Error, GlExtensions}; +use crate::renderer::{Error, GlExtensions}; -use super::atlas::{Atlas, ATLAS_SIZE}; +use super::atlas::{ATLAS_SIZE, Atlas}; use super::{ - glsl3, Glyph, LoadGlyph, LoaderApi, RenderingGlyphFlags, RenderingPass, TextRenderApi, - TextRenderBatch, TextRenderer, TextShader, + Glyph, LoadGlyph, LoaderApi, RenderingGlyphFlags, RenderingPass, TextRenderApi, + TextRenderBatch, TextRenderer, TextShader, glsl3, }; // Shader source. @@ -486,8 +486,8 @@ impl TextShaderProgram { let program = ShaderProgram::new(shader_version, None, TEXT_SHADER_V, fragment_shader)?; Ok(Self { - u_projection: program.get_uniform_location(cstr!("projection"))?, - u_rendering_pass: program.get_uniform_location(cstr!("renderingPass"))?, + u_projection: program.get_uniform_location(c"projection")?, + u_rendering_pass: program.get_uniform_location(c"renderingPass")?, program, }) } diff --git a/alacritty/src/renderer/text/glsl3.rs b/alacritty/src/renderer/text/glsl3.rs index 07fcdff0..b59c8bf2 100644 --- a/alacritty/src/renderer/text/glsl3.rs +++ b/alacritty/src/renderer/text/glsl3.rs @@ -6,14 +6,14 @@ use log::info; use alacritty_terminal::term::cell::Flags; -use crate::display::content::RenderableCell; use crate::display::SizeInfo; +use crate::display::content::RenderableCell; use crate::gl; use crate::gl::types::*; +use crate::renderer::Error; use crate::renderer::shader::{ShaderProgram, ShaderVersion}; -use crate::renderer::{cstr, Error}; -use super::atlas::{Atlas, ATLAS_SIZE}; +use super::atlas::{ATLAS_SIZE, Atlas}; use super::{ Glyph, LoadGlyph, LoaderApi, RenderingGlyphFlags, RenderingPass, TextRenderApi, TextRenderBatch, TextRenderer, TextShader, @@ -430,9 +430,9 @@ impl TextShaderProgram { pub fn new(shader_version: ShaderVersion) -> Result<TextShaderProgram, Error> { let program = ShaderProgram::new(shader_version, None, TEXT_SHADER_V, TEXT_SHADER_F)?; Ok(Self { - u_projection: program.get_uniform_location(cstr!("projection"))?, - u_cell_dim: program.get_uniform_location(cstr!("cellDim"))?, - u_rendering_pass: program.get_uniform_location(cstr!("renderingPass"))?, + u_projection: program.get_uniform_location(c"projection")?, + u_cell_dim: program.get_uniform_location(c"cellDim")?, + u_rendering_pass: program.get_uniform_location(c"renderingPass")?, program, }) } diff --git a/alacritty/src/renderer/text/glyph_cache.rs b/alacritty/src/renderer/text/glyph_cache.rs index 6acc3189..bba1c417 100644 --- a/alacritty/src/renderer/text/glyph_cache.rs +++ b/alacritty/src/renderer/text/glyph_cache.rs @@ -82,13 +82,7 @@ impl GlyphCache { pub fn new(mut rasterizer: Rasterizer, font: &Font) -> Result<GlyphCache, crossfont::Error> { let (regular, bold, italic, bold_italic) = Self::compute_font_keys(font, &mut rasterizer)?; - // Need to load at least one glyph for the face before calling metrics. - // The glyph requested here ('m' at the time of writing) has no special - // meaning. - rasterizer.get_glyph(GlyphKey { font_key: regular, character: 'm', size: font.size() })?; - - let metrics = rasterizer.metrics(regular, font.size())?; - + let metrics = GlyphCache::load_font_metrics(&mut rasterizer, font, regular)?; Ok(Self { cache: Default::default(), rasterizer, @@ -104,6 +98,22 @@ impl GlyphCache { }) } + // Load font metrics and adjust for glyph offset. + fn load_font_metrics( + rasterizer: &mut Rasterizer, + font: &Font, + key: FontKey, + ) -> Result<Metrics, crossfont::Error> { + // Need to load at least one glyph for the face before calling metrics. + // The glyph requested here ('m' at the time of writing) has no special + // meaning. + rasterizer.get_glyph(GlyphKey { font_key: key, character: 'm', size: font.size() })?; + + let mut metrics = rasterizer.metrics(key, font.size())?; + metrics.strikeout_position += font.glyph_offset.y as f32; + Ok(metrics) + } + fn load_glyphs_for_font<L: LoadGlyph>(&mut self, font: FontKey, loader: &mut L) { let size = self.font_size; @@ -160,7 +170,7 @@ impl GlyphCache { match rasterizer.load_font(description, size) { Ok(font) => Ok(font), Err(err) => { - error!("{}", err); + error!("{err}"); let fallback_desc = Self::make_desc(Font::default().normal(), Slant::Normal, Weight::Normal); @@ -279,12 +289,7 @@ impl GlyphCache { let (regular, bold, italic, bold_italic) = Self::compute_font_keys(font, &mut self.rasterizer)?; - self.rasterizer.get_glyph(GlyphKey { - font_key: regular, - character: 'm', - size: font.size(), - })?; - let metrics = self.rasterizer.metrics(regular, font.size())?; + let metrics = GlyphCache::load_font_metrics(&mut self.rasterizer, font, regular)?; info!("Font size changed to {:?} px", font.size().as_px()); diff --git a/alacritty/src/renderer/text/mod.rs b/alacritty/src/renderer/text/mod.rs index 2742704d..c0776b8a 100644 --- a/alacritty/src/renderer/text/mod.rs +++ b/alacritty/src/renderer/text/mod.rs @@ -3,8 +3,8 @@ use crossfont::{GlyphKey, RasterizedGlyph}; use alacritty_terminal::term::cell::Flags; -use crate::display::content::RenderableCell; use crate::display::SizeInfo; +use crate::display::content::RenderableCell; use crate::gl; use crate::gl::types::*; diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index a0e66cc0..5bfeef83 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -32,8 +32,8 @@ use alacritty_terminal::tty; use crate::cli::{ParsedOptions, WindowOptions}; use crate::clipboard::Clipboard; use crate::config::UiConfig; -use crate::display::window::Window; use crate::display::Display; +use crate::display::window::Window; use crate::event::{ ActionContext, Event, EventProxy, InlineSearchState, Mouse, SearchState, TouchPurpose, }; @@ -328,6 +328,12 @@ impl WindowContext { self.dirty = true; } + /// Get reference to the window's configuration. + #[cfg(unix)] + pub fn config(&self) -> &UiConfig { + &self.config + } + /// Clear the window config overrides. #[cfg(unix)] pub fn reset_window_config(&mut self, config: Rc<UiConfig>) { diff --git a/alacritty_config/Cargo.toml b/alacritty_config/Cargo.toml index a6d651bc..0dd78829 100644 --- a/alacritty_config/Cargo.toml +++ b/alacritty_config/Cargo.toml @@ -6,13 +6,13 @@ license = "MIT OR Apache-2.0" description = "Alacritty configuration abstractions" homepage = "https://alacritty.org" repository = "https://github.com/alacritty/alacritty" -edition = "2021" -rust-version = "1.74.0" +edition.workspace = true +rust-version.workspace = true [dependencies] log = { version = "0.4.17", features = ["serde"] } serde = "1.0.163" -toml = "0.8.2" +toml.workspace = true [dev-dependencies] alacritty_config_derive = { version = "0.2.5-dev", path = "../alacritty_config_derive" } diff --git a/alacritty_config_derive/Cargo.toml b/alacritty_config_derive/Cargo.toml index 7d04eacc..14648c60 100644 --- a/alacritty_config_derive/Cargo.toml +++ b/alacritty_config_derive/Cargo.toml @@ -6,8 +6,8 @@ license = "MIT OR Apache-2.0" description = "Failure resistant deserialization derive" homepage = "https://alacritty.org" repository = "https://github.com/alacritty/alacritty" -edition = "2021" -rust-version = "1.74.0" +edition.workspace = true +rust-version.workspace = true [lib] proc-macro = true @@ -24,4 +24,4 @@ version = "0.2.3-dev" [dev-dependencies] log = "0.4.11" serde = { version = "1.0.117", features = ["derive"] } -toml = "0.8.2" +toml.workspace = true diff --git a/alacritty_config_derive/src/config_deserialize/de_enum.rs b/alacritty_config_derive/src/config_deserialize/de_enum.rs index f94977ae..0d181e11 100644 --- a/alacritty_config_derive/src/config_deserialize/de_enum.rs +++ b/alacritty_config_derive/src/config_deserialize/de_enum.rs @@ -16,11 +16,7 @@ pub fn derive_deserialize(ident: Ident, generics: Generics, data_enum: DataEnum) // Skip deserialization for `#[config(skip)]` fields. variant.attrs.iter().all(|attr| { let is_skip = |meta: ParseNestedMeta| { - if meta.path.is_ident("skip") { - Ok(()) - } else { - Err(meta.error("not skip")) - } + if meta.path.is_ident("skip") { Ok(()) } else { Err(meta.error("not skip")) } }; !attr.path().is_ident("config") || attr.parse_nested_meta(is_skip).is_err() }) diff --git a/alacritty_config_derive/src/config_deserialize/de_struct.rs b/alacritty_config_derive/src/config_deserialize/de_struct.rs index ad38863e..31bf8907 100644 --- a/alacritty_config_derive/src/config_deserialize/de_struct.rs +++ b/alacritty_config_derive/src/config_deserialize/de_struct.rs @@ -5,7 +5,7 @@ use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::{Error, Field, Generics, Ident, Type}; -use crate::{serde_replace, Attr, GenericsStreams, MULTIPLE_FLATTEN_ERROR}; +use crate::{Attr, GenericsStreams, MULTIPLE_FLATTEN_ERROR, serde_replace}; /// Use this crate's name as log target. const LOG_TARGET: &str = env!("CARGO_PKG_NAME"); @@ -174,9 +174,9 @@ fn field_deserializer(field_streams: &mut FieldStreams, field: &Field) -> Result // Create token stream for deserializing "none" string into `Option<T>`. if let Type::Path(type_path) = &field.ty { - if type_path.path.segments.iter().last().map_or(false, |s| s.ident == "Option") { + if type_path.path.segments.iter().next_back().is_some_and(|s| s.ident == "Option") { match_assignment_stream = quote! { - if value.as_str().map_or(false, |s| s.eq_ignore_ascii_case("none")) { + if value.as_str().is_some_and(|s| s.eq_ignore_ascii_case("none")) { config.#ident = None; continue; } diff --git a/alacritty_config_derive/src/config_deserialize/mod.rs b/alacritty_config_derive/src/config_deserialize/mod.rs index b1923377..58e60e6b 100644 --- a/alacritty_config_derive/src/config_deserialize/mod.rs +++ b/alacritty_config_derive/src/config_deserialize/mod.rs @@ -1,5 +1,5 @@ use proc_macro::TokenStream; -use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Error, Fields}; +use syn::{Data, DataStruct, DeriveInput, Error, Fields, parse_macro_input}; /// Error if the derive was used on an unsupported type. const UNSUPPORTED_ERROR: &str = "ConfigDeserialize must be used on an enum or struct with fields"; diff --git a/alacritty_config_derive/src/serde_replace.rs b/alacritty_config_derive/src/serde_replace.rs index cd56b3bc..a00cb847 100644 --- a/alacritty_config_derive/src/serde_replace.rs +++ b/alacritty_config_derive/src/serde_replace.rs @@ -3,7 +3,7 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::punctuated::Punctuated; use syn::{ - parse_macro_input, Data, DataStruct, DeriveInput, Error, Field, Fields, Generics, Ident, + Data, DataStruct, DeriveInput, Error, Field, Fields, Generics, Ident, parse_macro_input, }; use crate::{Attr, GenericsStreams, MULTIPLE_FLATTEN_ERROR}; diff --git a/alacritty_config_derive/tests/config.rs b/alacritty_config_derive/tests/config.rs index be140cbe..37d2fc60 100644 --- a/alacritty_config_derive/tests/config.rs +++ b/alacritty_config_derive/tests/config.rs @@ -124,18 +124,20 @@ fn config_deserialize() { assert_eq!(test.flatten.flatty, 123); // Verify all log messages are correct. - let error_logs = logger.error_logs.lock().unwrap(); + let mut error_logs = logger.error_logs.lock().unwrap(); + error_logs.sort_unstable(); assert_eq!(error_logs.as_slice(), [ "Config error: enom_error: unknown variant `HugaBuga`, expected one of `One`, `Two`, \ `Three`", "Config error: field1: invalid type: string \"testing\", expected usize", ]); - let warn_logs = logger.warn_logs.lock().unwrap(); + let mut warn_logs = logger.warn_logs.lock().unwrap(); + warn_logs.sort_unstable(); assert_eq!(warn_logs.as_slice(), [ - "Config warning: field1 has been deprecated; use field2 instead\nUse `alacritty migrate` \ - to automatically resolve it", "Config warning: enom_error has been deprecated\nUse `alacritty migrate` to automatically \ resolve it", + "Config warning: field1 has been deprecated; use field2 instead\nUse `alacritty migrate` \ + to automatically resolve it", "Config warning: gone has been removed; it's gone\nUse `alacritty migrate` to \ automatically resolve it", "Unused config key: field3", diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 04547103..7ac4df9e 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -7,8 +7,8 @@ description = "Library for writing terminal emulators" readme = "../README.md" homepage = "https://alacritty.org" repository = "https://github.com/alacritty/alacritty" -edition = "2021" -rust-version = "1.74.0" +edition.workspace = true +rust-version.workspace = true [features] default = ["serde"] @@ -21,15 +21,16 @@ home = "0.5.5" libc = "0.2" log = "0.4" parking_lot = "0.12.0" -polling = "3.0.0" +polling = "3.8.0" regex-automata = "0.4.3" -unicode-width = "0.1" +unicode-width = "0.2.0" vte = { version = "0.15.0", package = "vte-graphics", default-features = false, features = ["std", "ansi"] } serde = { version = "1", features = ["derive", "rc"], optional = true } smallvec = { version = "1.13.1", features = ["serde"] } [target.'cfg(unix)'.dependencies] -rustix-openpty = "0.1.1" +rustix-openpty = "0.2.0" +rustix = { version = "1.0.0", default-features = false, features = ["std"] } signal-hook = "0.3.10" [target.'cfg(windows)'.dependencies] diff --git a/alacritty_terminal/src/event_loop.rs b/alacritty_terminal/src/event_loop.rs index 1bef1d4f..eec692e4 100644 --- a/alacritty_terminal/src/event_loop.rs +++ b/alacritty_terminal/src/event_loop.rs @@ -6,8 +6,8 @@ use std::fmt::{self, Display, Formatter}; use std::fs::File; use std::io::{self, ErrorKind, Read, Write}; use std::num::NonZeroUsize; -use std::sync::mpsc::{self, Receiver, Sender, TryRecvError}; use std::sync::Arc; +use std::sync::mpsc::{self, Receiver, Sender, TryRecvError}; use std::thread::JoinHandle; use std::time::Instant; @@ -212,7 +212,7 @@ where // Register TTY through EventedRW interface. if let Err(err) = unsafe { self.pty.register(&self.poll, interest, poll_opts) } { - error!("Event loop registration error: {}", err); + error!("Event loop registration error: {err}"); return (self, state); } @@ -235,7 +235,7 @@ where match err.kind() { ErrorKind::Interrupted => continue, _ => { - error!("Event loop polling error: {}", err); + error!("Event loop polling error: {err}"); break 'event_loop; }, } @@ -289,14 +289,14 @@ where continue; } - error!("Error reading from PTY in event loop: {}", err); + error!("Error reading from PTY in event loop: {err}"); break 'event_loop; } } if event.writable { if let Err(err) = self.pty_write(&mut state) { - error!("Error writing to PTY in event loop: {}", err); + error!("Error writing to PTY in event loop: {err}"); break 'event_loop; } } @@ -338,7 +338,7 @@ impl event::Notify for Notifier { { let bytes = bytes.into(); // Terminal hangs if we send 0 bytes through. - if bytes.len() == 0 { + if bytes.is_empty() { return; } diff --git a/alacritty_terminal/src/graphics/mod.rs b/alacritty_terminal/src/graphics/mod.rs index 5ecdf29c..cb9f1461 100644 --- a/alacritty_terminal/src/graphics/mod.rs +++ b/alacritty_terminal/src/graphics/mod.rs @@ -18,8 +18,8 @@ use crate::event::{Event, EventListener}; use crate::grid::Dimensions; use crate::index::{Column, Line}; use crate::term::{Term, TermMode}; -use crate::vte::ansi::{Handler, Rgb}; use crate::vte::Params; +use crate::vte::ansi::{Handler, Rgb}; /// Max allowed dimensions (width, height) for the graphic, in pixels. pub const MAX_GRAPHIC_DIMENSIONS: [usize; 2] = [4096, 4096]; @@ -337,11 +337,7 @@ impl Graphics { pub fn take_queues(&mut self) -> Option<UpdateQueues> { let texture_operations = { let mut queue = self.texture_operations.lock(); - if queue.is_empty() { - Vec::new() - } else { - mem::take(&mut *queue) - } + if queue.is_empty() { Vec::new() } else { mem::take(&mut *queue) } }; if texture_operations.is_empty() && self.pending.is_empty() { @@ -398,9 +394,9 @@ impl Graphics { // On success, Pv represents the value read or set. fn generate_response(pi: u16, ps: u16, pv: &[usize]) -> String { - let mut text = format!("\x1b[?{};{}", pi, ps); + let mut text = format!("\x1b[?{pi};{ps}"); for item in pv { - let _ = write!(&mut text, ";{}", item); + let _ = write!(&mut text, ";{item}"); } text.push('S'); text @@ -464,7 +460,7 @@ impl Graphics { pub fn parse_sixel<L: EventListener>(term: &mut Term<L>, parser: sixel::Parser) { match parser.finish() { Ok((graphic, palette)) => insert_graphic(term, graphic, Some(palette)), - Err(err) => log::warn!("Failed to parse Sixel data: {}", err), + Err(err) => log::warn!("Failed to parse Sixel data: {err}"), } } diff --git a/alacritty_terminal/src/graphics/sixel.rs b/alacritty_terminal/src/graphics/sixel.rs index 3f908915..96618146 100644 --- a/alacritty_terminal/src/graphics/sixel.rs +++ b/alacritty_terminal/src/graphics/sixel.rs @@ -56,18 +56,17 @@ impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::TooBigImage { width, height } => { - write!(fmt, "The image dimensions are too big ({}, {})", width, height) + write!(fmt, "The image dimensions are too big ({width}, {height})") }, Error::InvalidColorComponent { register, component_value } => { - write!(fmt, "Invalid color component {} for register {}", component_value, register) + write!(fmt, "Invalid color component {component_value} for register {register}") }, Error::InvalidColorCoordinateSystem { register, coordinate_system } => { write!( fmt, - "Invalid color coordinate system {} for register {}", - coordinate_system, register + "Invalid color coordinate system {coordinate_system} for register {register}" ) }, } @@ -201,7 +200,7 @@ impl CommandParser { return Err(Error::InvalidColorCoordinateSystem { register: register.0, coordinate_system: x, - }) + }); }, }; @@ -547,11 +546,7 @@ fn hls_to_rgb(hue: u16, lum: u16, sat: u16) -> Rgb { fn clamp(x: f64) -> u8 { let x = f64::round(x * 255. / 100.) % 256.; - if x < 0. { - 0 - } else { - x as u8 - } + if x < 0. { 0 } else { x as u8 } } Rgb { r: clamp(r), g: clamp(g), b: clamp(b) } @@ -645,11 +640,7 @@ mod tests { // Reimplement abs_diff to be compatible with rustc before 1.60. fn abs_diff(x: u8, y: u8) -> u8 { - if x > y { - x - y - } else { - y - x - } + if x > y { x - y } else { y - x } } macro_rules! assert_color { diff --git a/alacritty_terminal/src/grid/mod.rs b/alacritty_terminal/src/grid/mod.rs index a1b4d67b..0faed56c 100644 --- a/alacritty_terminal/src/grid/mod.rs +++ b/alacritty_terminal/src/grid/mod.rs @@ -611,7 +611,7 @@ impl<'a, T> Iterator for GridIterator<'a, T> { } match self.point { - Point { column, .. } if column == self.grid.last_column() => { + Point { column, .. } if column >= self.grid.last_column() => { self.point.column = Column(0); self.point.line += 1; }, @@ -620,6 +620,24 @@ impl<'a, T> Iterator for GridIterator<'a, T> { Some(Indexed { cell: &self.grid[self.point], point: self.point }) } + + fn size_hint(&self) -> (usize, Option<usize>) { + if self.point >= self.end { + return (0, Some(0)); + } + + let size = if self.point.line == self.end.line { + (self.end.column - self.point.column).0 + } else { + let cols_on_first_line = self.grid.columns.saturating_sub(self.point.column.0 + 1); + let middle_lines = (self.end.line - self.point.line).0 as usize - 1; + let cols_on_last_line = self.end.column + 1; + + cols_on_first_line + middle_lines * self.grid.columns + cols_on_last_line.0 + }; + + (size, Some(size)) + } } /// Bidirectional iterator. @@ -633,7 +651,7 @@ impl<T> BidirectionalIterator for GridIterator<'_, T> { let last_column = self.grid.last_column(); // Stop once we've reached the end of the grid. - if self.point == Point::new(topmost_line, Column(0)) { + if self.point <= Point::new(topmost_line, Column(0)) { return None; } diff --git a/alacritty_terminal/src/grid/resize.rs b/alacritty_terminal/src/grid/resize.rs index 751abae1..37f93691 100644 --- a/alacritty_terminal/src/grid/resize.rs +++ b/alacritty_terminal/src/grid/resize.rs @@ -1,6 +1,6 @@ //! Grid resize and reflow. -use std::cmp::{max, min, Ordering}; +use std::cmp::{Ordering, max, min}; use std::mem; use crate::index::{Boundary, Column, Line}; diff --git a/alacritty_terminal/src/grid/storage.rs b/alacritty_terminal/src/grid/storage.rs index abf57103..6d7984d4 100644 --- a/alacritty_terminal/src/grid/storage.rs +++ b/alacritty_terminal/src/grid/storage.rs @@ -230,11 +230,7 @@ impl<T> Storage<T> { // // Requires `zeroed` to be smaller than `self.inner.len() * 2`, // but both `self.zero` and `requested` are always smaller than `self.inner.len()`. - if zeroed >= self.inner.len() { - zeroed - self.inner.len() - } else { - zeroed - } + if zeroed >= self.inner.len() { zeroed - self.inner.len() } else { zeroed } } /// Rotate the ringbuffer to reset `self.zero` back to index `0`. @@ -269,9 +265,9 @@ impl<T> IndexMut<Line> for Storage<T> { #[cfg(test)] mod tests { - use crate::grid::row::Row; - use crate::grid::storage::{Storage, MAX_CACHE_SIZE}; use crate::grid::GridCell; + use crate::grid::row::Row; + use crate::grid::storage::{MAX_CACHE_SIZE, Storage}; use crate::index::{Column, Line}; use crate::term::cell::Flags; diff --git a/alacritty_terminal/src/grid/tests.rs b/alacritty_terminal/src/grid/tests.rs index 49cf1a76..f052c75a 100644 --- a/alacritty_terminal/src/grid/tests.rs +++ b/alacritty_terminal/src/grid/tests.rs @@ -348,6 +348,33 @@ fn shrink_reflow_disabled() { assert_eq!(grid[Line(0)][Column(1)], cell('2')); } +#[test] +fn accurate_size_hint() { + let grid = Grid::<Cell>::new(5, 5, 2); + + size_hint_matches_count(grid.iter_from(Point::new(Line(0), Column(0)))); + size_hint_matches_count(grid.iter_from(Point::new(Line(2), Column(3)))); + size_hint_matches_count(grid.iter_from(Point::new(Line(4), Column(4)))); + size_hint_matches_count(grid.iter_from(Point::new(Line(4), Column(2)))); + size_hint_matches_count(grid.iter_from(Point::new(Line(10), Column(10)))); + size_hint_matches_count(grid.iter_from(Point::new(Line(2), Column(10)))); + + let mut iterator = grid.iter_from(Point::new(Line(3), Column(1))); + iterator.next(); + iterator.next(); + size_hint_matches_count(iterator); + + size_hint_matches_count(grid.display_iter()); +} + +fn size_hint_matches_count<T>(iter: impl Iterator<Item = T>) { + let iterator = iter.into_iter(); + let (lower, upper) = iterator.size_hint(); + let count = iterator.count(); + assert_eq!(lower, count); + assert_eq!(upper, Some(count)); +} + // https://github.com/rust-lang/rust-clippy/pull/6375 #[allow(clippy::all)] fn cell(c: char) -> Cell { diff --git a/alacritty_terminal/src/index.rs b/alacritty_terminal/src/index.rs index dd7faa7b..8b394842 100644 --- a/alacritty_terminal/src/index.rs +++ b/alacritty_terminal/src/index.rs @@ -1,7 +1,7 @@ //! Line and Column newtypes for strongly typed tty/grid/terminal APIs. /// Indexing types and implementations for Grid and Line. -use std::cmp::{max, min, Ord, Ordering}; +use std::cmp::{Ord, Ordering, max, min}; use std::fmt; use std::ops::{Add, AddAssign, Deref, Sub, SubAssign}; diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs index 34bbdaed..61088f4e 100644 --- a/alacritty_terminal/src/selection.rs +++ b/alacritty_terminal/src/selection.rs @@ -11,8 +11,8 @@ use std::ops::{Bound, Range, RangeBounds}; use crate::grid::{Dimensions, GridCell, Indexed}; use crate::index::{Boundary, Column, Line, Point, Side}; -use crate::term::cell::{Cell, Flags}; use crate::term::Term; +use crate::term::cell::{Cell, Flags}; use crate::vte::ansi::CursorShape; /// A Point and side within that point. diff --git a/alacritty_terminal/src/term/cell.rs b/alacritty_terminal/src/term/cell.rs index c91ef2f1..d05f794d 100644 --- a/alacritty_terminal/src/term/cell.rs +++ b/alacritty_terminal/src/term/cell.rs @@ -1,5 +1,5 @@ -use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicU32, Ordering}; use bitflags::bitflags; #[cfg(feature = "serde")] @@ -215,7 +215,7 @@ impl Cell { && self .extra .as_ref() - .map_or(true, |extra| extra.zerowidth.is_empty() && extra.hyperlink.is_none()) + .is_none_or(|extra| extra.zerowidth.is_empty() && extra.hyperlink.is_none()) { self.extra = None; } else { @@ -233,9 +233,10 @@ impl Cell { /// Set hyperlink. pub fn set_hyperlink(&mut self, hyperlink: Option<Hyperlink>) { let should_drop = hyperlink.is_none() - && self.extra.as_ref().map_or(true, |extra| { - extra.zerowidth.is_empty() && extra.underline_color.is_none() - }); + && self + .extra + .as_ref() + .is_none_or(|extra| extra.zerowidth.is_empty() && extra.underline_color.is_none()); if should_drop { self.extra = None; diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 486799cd..51b3d544 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -7,8 +7,8 @@ use std::{cmp, mem, ptr, slice, str}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use base64::engine::general_purpose::STANDARD as Base64; use base64::Engine; +use base64::engine::general_purpose::STANDARD as Base64; use bitflags::bitflags; use log::{debug, trace}; use unicode_width::UnicodeWidthChar; @@ -20,12 +20,12 @@ use crate::selection::{Selection, SelectionRange, SelectionType}; use crate::term::cell::{Cell, Flags, LineLength}; use crate::term::color::Colors; use crate::vi_mode::{ViModeCursor, ViMotion}; +use crate::vte::Params; use crate::vte::ansi::{ self, Attr, CharsetIndex, Color, CursorShape, CursorStyle, Handler, Hyperlink, KeyboardModes, KeyboardModesApplyBehavior, NamedColor, NamedMode, NamedPrivateMode, PrivateMode, Rgb, StandardCharset, }; -use crate::vte::Params; use crate::graphics::{Graphics, UpdateQueues}; @@ -687,7 +687,7 @@ impl<T> Term<T> { return; } - debug!("New num_cols is {} and num_lines is {}", num_cols, num_lines); + debug!("New num_cols is {num_cols} and num_lines is {num_lines}"); // Move vi mode cursor with the content. let history_size = self.history_size(); @@ -766,7 +766,7 @@ impl<T> Term<T> { /// Expects origin to be in scroll range. #[inline] fn scroll_down_relative(&mut self, origin: Line, mut lines: usize) { - trace!("Scrolling down relative: origin={}, lines={}", origin, lines); + trace!("Scrolling down relative: origin={origin}, lines={lines}"); lines = cmp::min(lines, (self.scroll_region.end - self.scroll_region.start).0 as usize); lines = cmp::min(lines, (self.scroll_region.end - origin).0 as usize); @@ -794,7 +794,7 @@ impl<T> Term<T> { /// Expects origin to be in scroll range. #[inline] fn scroll_up_relative(&mut self, origin: Line, mut lines: usize) { - trace!("Scrolling up relative: origin={}, lines={}", origin, lines); + trace!("Scrolling up relative: origin={origin}, lines={lines}"); lines = cmp::min(lines, (self.scroll_region.end - self.scroll_region.start).0 as usize); @@ -1183,7 +1183,7 @@ impl<T: EventListener> Handler for Term<T> { let line = Line(line); let col = Column(col); - trace!("Going to: line={}, col={}", line, col); + trace!("Going to: line={line}, col={col}"); let (y_offset, max_y) = if self.mode.contains(TermMode::ORIGIN) { (self.scroll_region.start, self.scroll_region.end - 1) } else { @@ -1199,13 +1199,13 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn goto_line(&mut self, line: i32) { - trace!("Going to line: {}", line); + trace!("Going to line: {line}"); self.goto(line, self.grid.cursor.point.column.0) } #[inline] fn goto_col(&mut self, col: usize) { - trace!("Going to column: {}", col); + trace!("Going to column: {col}"); self.goto(self.grid.cursor.point.line.0, col) } @@ -1239,7 +1239,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn move_up(&mut self, lines: usize) { - trace!("Moving up: {}", lines); + trace!("Moving up: {lines}"); let line = self.grid.cursor.point.line - lines; let column = self.grid.cursor.point.column; @@ -1248,7 +1248,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn move_down(&mut self, lines: usize) { - trace!("Moving down: {}", lines); + trace!("Moving down: {lines}"); let line = self.grid.cursor.point.line + lines; let column = self.grid.cursor.point.column; @@ -1257,7 +1257,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn move_forward(&mut self, cols: usize) { - trace!("Moving forward: {}", cols); + trace!("Moving forward: {cols}"); let last_column = cmp::min(self.grid.cursor.point.column + cols, self.last_column()); let cursor_line = self.grid.cursor.point.line.0 as usize; @@ -1269,7 +1269,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn move_backward(&mut self, cols: usize) { - trace!("Moving backward: {}", cols); + trace!("Moving backward: {cols}"); let column = self.grid.cursor.point.column.saturating_sub(cols); let cursor_line = self.grid.cursor.point.line.0 as usize; @@ -1321,8 +1321,8 @@ impl<T: EventListener> Handler for Term<T> { if self.keyboard_mode_stack.len() >= KEYBOARD_MODE_STACK_MAX_DEPTH { let removed = self.title_stack.remove(0); trace!( - "Removing '{:?}' from bottom of keyboard mode stack that exceeds its maximum depth", - removed + "Removing '{removed:?}' from bottom of keyboard mode stack that exceeds its \ + maximum depth" ); } @@ -1356,7 +1356,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn device_status(&mut self, arg: usize) { - trace!("Reporting device status: {}", arg); + trace!("Reporting device status: {arg}"); match arg { 5 => { let text = String::from("\x1b[0n"); @@ -1367,13 +1367,13 @@ impl<T: EventListener> Handler for Term<T> { let text = format!("\x1b[{};{}R", pos.line + 1, pos.column + 1); self.event_proxy.send_event(Event::PtyWrite(text)); }, - _ => debug!("unknown device status query: {}", arg), + _ => debug!("unknown device status query: {arg}"), }; } #[inline] fn move_down_and_cr(&mut self, lines: usize) { - trace!("Moving down and cr: {}", lines); + trace!("Moving down and cr: {lines}"); let line = self.grid.cursor.point.line + lines; self.goto(line.0, 0) @@ -1381,7 +1381,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn move_up_and_cr(&mut self, lines: usize) { - trace!("Moving up and cr: {}", lines); + trace!("Moving up and cr: {lines}"); let line = self.grid.cursor.point.line - lines; self.goto(line.0, 0) @@ -1521,7 +1521,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn insert_blank_lines(&mut self, lines: usize) { - trace!("Inserting blank {} lines", lines); + trace!("Inserting blank {lines} lines"); let origin = self.grid.cursor.point.line; if self.scroll_region.contains(&origin) { @@ -1534,7 +1534,7 @@ impl<T: EventListener> Handler for Term<T> { let origin = self.grid.cursor.point.line; let lines = cmp::min(self.screen_lines() - origin.0 as usize, lines); - trace!("Deleting {} lines", lines); + trace!("Deleting {lines} lines"); if lines > 0 && self.scroll_region.contains(&origin) { self.scroll_up_relative(origin, lines); @@ -1591,7 +1591,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn move_backward_tabs(&mut self, count: u16) { - trace!("Moving backward {} tabs", count); + trace!("Moving backward {count} tabs"); let old_col = self.grid.cursor.point.column.0; for _ in 0..count { @@ -1616,7 +1616,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn move_forward_tabs(&mut self, count: u16) { - trace!("Moving forward {} tabs", count); + trace!("Moving forward {count} tabs"); let num_cols = self.columns(); let old_col = self.grid.cursor.point.column.0; @@ -1659,7 +1659,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn clear_line(&mut self, mode: ansi::LineClearMode) { - trace!("Clearing line: {:?}", mode); + trace!("Clearing line: {mode:?}"); let cursor = &self.grid.cursor; let bg = cursor.template.bg; @@ -1686,7 +1686,7 @@ impl<T: EventListener> Handler for Term<T> { /// Set the indexed color value. #[inline] fn set_color(&mut self, index: usize, color: Rgb) { - trace!("Setting color[{}] = {:?}", index, color); + trace!("Setting color[{index}] = {color:?}"); // Damage terminal if the color changed and it's not the cursor. if index != NamedColor::Cursor as usize && self.colors[index] != Some(color) { @@ -1699,7 +1699,7 @@ impl<T: EventListener> Handler for Term<T> { /// Respond to a color query escape sequence. #[inline] fn dynamic_color_sequence(&mut self, prefix: String, index: usize, terminator: &str) { - trace!("Requested write of escape sequence for color code {}: color[{}]", prefix, index); + trace!("Requested write of escape sequence for color code {prefix}: color[{index}]"); let terminator = terminator.to_owned(); self.event_proxy.send_event(Event::ColorRequest( @@ -1716,7 +1716,7 @@ impl<T: EventListener> Handler for Term<T> { /// Reset the indexed color to original value. #[inline] fn reset_color(&mut self, index: usize) { - trace!("Resetting color[{}]", index); + trace!("Resetting color[{index}]"); // Damage terminal if the color changed and it's not the cursor. if index != NamedColor::Cursor as usize && self.colors[index].is_some() { @@ -1774,7 +1774,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn clear_screen(&mut self, mode: ansi::ClearMode) { - trace!("Clearing screen: {:?}", mode); + trace!("Clearing screen: {mode:?}"); let bg = self.grid.cursor.template.bg; let screen_lines = self.screen_lines(); @@ -1845,7 +1845,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn clear_tabs(&mut self, mode: ansi::TabulationClearMode) { - trace!("Clearing tabs: {:?}", mode); + trace!("Clearing tabs: {mode:?}"); match mode { ansi::TabulationClearMode::Current => { self.tabs[self.grid.cursor.point.column] = false; @@ -1898,14 +1898,14 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn set_hyperlink(&mut self, hyperlink: Option<Hyperlink>) { - trace!("Setting hyperlink: {:?}", hyperlink); + trace!("Setting hyperlink: {hyperlink:?}"); self.grid.cursor.template.set_hyperlink(hyperlink.map(|e| e.into())); } /// Set a terminal attribute. #[inline] fn terminal_attribute(&mut self, attr: Attr) { - trace!("Setting attribute: {:?}", attr); + trace!("Setting attribute: {attr:?}"); let cursor = &mut self.grid.cursor; match attr { Attr::Foreground(color) => cursor.template.fg = color, @@ -1951,7 +1951,7 @@ impl<T: EventListener> Handler for Term<T> { Attr::Strike => cursor.template.flags.insert(Flags::STRIKEOUT), Attr::CancelStrike => cursor.template.flags.remove(Flags::STRIKEOUT), _ => { - debug!("Term got unhandled attr: {:?}", attr); + debug!("Term got unhandled attr: {attr:?}"); }, } } @@ -1980,12 +1980,12 @@ impl<T: EventListener> Handler for Term<T> { }, PrivateMode::Unknown(mode) => { - debug!("Ignoring unknown mode {} in set_private_mode", mode); + debug!("Ignoring unknown mode {mode} in set_private_mode"); return; }, }; - trace!("Setting private mode: {:?}", mode); + trace!("Setting private mode: {mode:?}"); match mode { NamedPrivateMode::UrgencyHints => self.mode.insert(TermMode::URGENCY_HINTS), NamedPrivateMode::SwapScreenAndSetRestoreCursor => { @@ -2060,12 +2060,12 @@ impl<T: EventListener> Handler for Term<T> { }, PrivateMode::Unknown(mode) => { - debug!("Ignoring unknown mode {} in unset_private_mode", mode); + debug!("Ignoring unknown mode {mode} in unset_private_mode"); return; }, }; - trace!("Unsetting private mode: {:?}", mode); + trace!("Unsetting private mode: {mode:?}"); match mode { NamedPrivateMode::UrgencyHints => self.mode.remove(TermMode::URGENCY_HINTS), NamedPrivateMode::SwapScreenAndSetRestoreCursor => { @@ -2161,12 +2161,12 @@ impl<T: EventListener> Handler for Term<T> { let mode = match mode { ansi::Mode::Named(mode) => mode, ansi::Mode::Unknown(mode) => { - debug!("Ignoring unknown mode {} in set_mode", mode); + debug!("Ignoring unknown mode {mode} in set_mode"); return; }, }; - trace!("Setting public mode: {:?}", mode); + trace!("Setting public mode: {mode:?}"); match mode { NamedMode::Insert => self.mode.insert(TermMode::INSERT), NamedMode::LineFeedNewLine => self.mode.insert(TermMode::LINE_FEED_NEW_LINE), @@ -2178,12 +2178,12 @@ impl<T: EventListener> Handler for Term<T> { let mode = match mode { ansi::Mode::Named(mode) => mode, ansi::Mode::Unknown(mode) => { - debug!("Ignoring unknown mode {} in unset_mode", mode); + debug!("Ignoring unknown mode {mode} in unset_mode"); return; }, }; - trace!("Setting public mode: {:?}", mode); + trace!("Setting public mode: {mode:?}"); match mode { NamedMode::Insert => { self.mode.remove(TermMode::INSERT); @@ -2219,7 +2219,7 @@ impl<T: EventListener> Handler for Term<T> { let bottom = bottom.unwrap_or_else(|| self.screen_lines()); if top >= bottom { - debug!("Invalid scrolling region: ({};{})", top, bottom); + debug!("Invalid scrolling region: ({top};{bottom})"); return; } @@ -2230,7 +2230,7 @@ impl<T: EventListener> Handler for Term<T> { let start = Line(top as i32 - 1); let end = Line(bottom as i32); - trace!("Setting scrolling region: ({};{})", start, end); + trace!("Setting scrolling region: ({start};{end})"); let screen_lines = Line(self.screen_lines() as i32); self.scroll_region.start = cmp::min(start, screen_lines); @@ -2252,19 +2252,19 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn configure_charset(&mut self, index: CharsetIndex, charset: StandardCharset) { - trace!("Configuring charset {:?} as {:?}", index, charset); + trace!("Configuring charset {index:?} as {charset:?}"); self.grid.cursor.charsets[index] = charset; } #[inline] fn set_active_charset(&mut self, index: CharsetIndex) { - trace!("Setting active charset {:?}", index); + trace!("Setting active charset {index:?}"); self.active_charset = index; } #[inline] fn set_cursor_style(&mut self, style: Option<CursorStyle>) { - trace!("Setting cursor style {:?}", style); + trace!("Setting cursor style {style:?}"); self.cursor_style = style; // Notify UI about blinking changes. @@ -2273,7 +2273,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn set_cursor_shape(&mut self, shape: CursorShape) { - trace!("Setting cursor shape {:?}", shape); + trace!("Setting cursor shape {shape:?}"); let style = self.cursor_style.get_or_insert(self.config.default_cursor_style); style.shape = shape; @@ -2281,7 +2281,7 @@ impl<T: EventListener> Handler for Term<T> { #[inline] fn set_title(&mut self, title: Option<String>) { - trace!("Setting title to '{:?}'", title); + trace!("Setting title to '{title:?}'"); self.title.clone_from(&title); @@ -2300,8 +2300,7 @@ impl<T: EventListener> Handler for Term<T> { if self.title_stack.len() >= TITLE_STACK_MAX_DEPTH { let removed = self.title_stack.remove(0); trace!( - "Removing '{:?}' from bottom of title stack that exceeds its maximum depth", - removed + "Removing '{removed:?}' from bottom of title stack that exceeds its maximum depth" ); } @@ -2313,7 +2312,7 @@ impl<T: EventListener> Handler for Term<T> { trace!("Attempting to pop title from stack..."); if let Some(popped) = self.title_stack.pop() { - trace!("Title '{:?}' popped from stack", popped); + trace!("Title '{popped:?}' popped from stack"); self.set_title(popped); } } @@ -2345,8 +2344,7 @@ impl<T: EventListener> Handler for Term<T> { self.graphics.start_sixel_graphic(params); }, _ => debug!( - "[unhandled hook] params={:?}, ints: {:?}, ignore: {:?}, action: {:?}", - params, intermediates, ignore, action + "[unhandled hook] params={params:?}, ints: {intermediates:?}, ignore: {ignore:?}, action: {action:?}" ), } } @@ -2355,11 +2353,11 @@ impl<T: EventListener> Handler for Term<T> { fn dcs_put(&mut self, byte: u8) { if let Some(parser) = &mut self.graphics.sixel_parser { if let Err(err) = parser.put(byte) { - log::warn!("Failed to parse Sixel data: {}", err); + log::warn!("Failed to parse Sixel data: {err}"); self.graphics.sixel_parser = None; } } else { - debug!("[unhandled put] byte={:?}", byte); + debug!("[unhandled put] byte={byte:?}"); } } @@ -2368,7 +2366,7 @@ impl<T: EventListener> Handler for Term<T> { if let Some(parser) = self.graphics.sixel_parser.take() { crate::graphics::parse_sixel(self, *parser); } else { - dbg!("[unhandled dcs_unhook]"); + debug!("[unhandled dcs_unhook]"); } } } @@ -2387,11 +2385,7 @@ enum ModeState { impl From<bool> for ModeState { fn from(value: bool) -> Self { - if value { - Self::Set - } else { - Self::Reset - } + if value { Self::Set } else { Self::Reset } } } diff --git a/alacritty_terminal/src/term/search.rs b/alacritty_terminal/src/term/search.rs index 20a427b7..1bdc659c 100644 --- a/alacritty_terminal/src/term/search.rs +++ b/alacritty_terminal/src/term/search.rs @@ -4,16 +4,16 @@ use std::mem; use std::ops::RangeInclusive; use log::{debug, warn}; -use regex_automata::hybrid::dfa::{Builder, Cache, Config, DFA}; pub use regex_automata::hybrid::BuildError; +use regex_automata::hybrid::dfa::{Builder, Cache, Config, DFA}; use regex_automata::nfa::thompson::Config as ThompsonConfig; use regex_automata::util::syntax::Config as SyntaxConfig; use regex_automata::{Anchored, Input, MatchKind}; use crate::grid::{BidirectionalIterator, Dimensions, GridIterator, Indexed}; use crate::index::{Boundary, Column, Direction, Point, Side}; -use crate::term::cell::{Cell, Flags}; use crate::term::Term; +use crate::term::cell::{Cell, Flags}; /// Used to match equal brackets, when performing a bracket-pair selection. const BRACKET_PAIRS: [(char, char); 4] = [('(', ')'), ('[', ']'), ('{', '}'), ('<', '>')]; @@ -298,8 +298,8 @@ impl<T> Term<T> { let mut cell = iter.cell(); self.skip_fullwidth(&mut iter, &mut cell, regex.direction); - let mut last_wrapped = cell.flags.contains(Flags::WRAPLINE); let mut c = cell.c; + let mut last_wrapped = iter.cell().flags.contains(Flags::WRAPLINE); let mut point = iter.point(); let mut last_point = point; @@ -401,8 +401,8 @@ impl<T> Term<T> { self.skip_fullwidth(&mut iter, &mut cell, regex.direction); - let wrapped = cell.flags.contains(Flags::WRAPLINE); c = cell.c; + let wrapped = iter.cell().flags.contains(Flags::WRAPLINE); last_point = mem::replace(&mut point, iter.point()); @@ -689,8 +689,8 @@ mod tests { use super::*; use crate::index::{Column, Line}; - use crate::term::test::{mock_term, TermSize}; use crate::term::Config; + use crate::term::test::{TermSize, mock_term}; #[test] fn regex_right() { @@ -1190,4 +1190,62 @@ mod tests { assert_eq!(start, Point::new(Line(0), Column(6))); assert_eq!(end, Point::new(Line(0), Column(6))); } + + #[test] + fn fullwidth_across_lines() { + let term = mock_term("a🦇\n🦇b"); + + let mut regex = RegexSearch::new("🦇🦇").unwrap(); + let start = Point::new(Line(0), Column(0)); + let end = Point::new(Line(1), Column(2)); + let match_start = Point::new(Line(0), Column(1)); + let match_end = Point::new(Line(1), Column(1)); + assert_eq!(term.regex_search_right(&mut regex, start, end), Some(match_start..=match_end)); + + let mut regex = RegexSearch::new("🦇🦇").unwrap(); + let start = Point::new(Line(1), Column(2)); + let end = Point::new(Line(0), Column(0)); + let match_start = Point::new(Line(1), Column(1)); + let match_end = Point::new(Line(0), Column(1)); + assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_end..=match_start)); + } + + #[test] + fn fullwidth_into_halfwidth_across_lines() { + let term = mock_term("a🦇\nxab"); + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(0), Column(0)); + let end = Point::new(Line(1), Column(2)); + let match_start = Point::new(Line(0), Column(1)); + let match_end = Point::new(Line(1), Column(0)); + assert_eq!(term.regex_search_right(&mut regex, start, end), Some(match_start..=match_end)); + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(1), Column(2)); + let end = Point::new(Line(0), Column(0)); + let match_start = Point::new(Line(1), Column(0)); + let match_end = Point::new(Line(0), Column(1)); + assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_end..=match_start)); + } + + #[test] + fn no_spacer_fullwidth_linewrap() { + let mut term = mock_term("abY\nxab"); + term.grid_mut()[Line(0)][Column(2)].c = '🦇'; + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(0), Column(0)); + let end = Point::new(Line(1), Column(2)); + let match_start = Point::new(Line(0), Column(2)); + let match_end = Point::new(Line(1), Column(0)); + assert_eq!(term.regex_search_right(&mut regex, start, end), Some(match_start..=match_end)); + + let mut regex = RegexSearch::new("🦇x").unwrap(); + let start = Point::new(Line(1), Column(2)); + let end = Point::new(Line(0), Column(0)); + let match_start = Point::new(Line(1), Column(0)); + let match_end = Point::new(Line(0), Column(2)); + assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_end..=match_start)); + } } diff --git a/alacritty_terminal/src/tty/mod.rs b/alacritty_terminal/src/tty/mod.rs index 208547ba..1df59377 100644 --- a/alacritty_terminal/src/tty/mod.rs +++ b/alacritty_terminal/src/tty/mod.rs @@ -94,10 +94,10 @@ pub fn setup_env() { // default to 'xterm-256color'. May be overridden by user's config // below. let terminfo = if terminfo_exists("alacritty") { "alacritty" } else { "xterm-256color" }; - env::set_var("TERM", terminfo); + unsafe { env::set_var("TERM", terminfo) }; // Advertise 24-bit color support. - env::set_var("COLORTERM", "truecolor"); + unsafe { env::set_var("COLORTERM", "truecolor") }; } /// Check if a terminfo entry exists on the system. diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index 884cb5c1..0807f3ee 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -14,7 +14,7 @@ use std::process::{Child, Command}; use std::sync::Arc; use std::{env, ptr}; -use libc::{c_int, TIOCSCTTY}; +use libc::{F_GETFL, F_SETFL, O_NONBLOCK, TIOCSCTTY, c_int, fcntl}; use log::error; use polling::{Event, PollMode, Poller}; use rustix_openpty::openpty; @@ -22,7 +22,7 @@ use rustix_openpty::rustix::termios::Winsize; #[cfg(any(target_os = "linux", target_os = "macos"))] use rustix_openpty::rustix::termios::{self, InputModes, OptionalActions}; use signal_hook::low_level::{pipe as signal_pipe, unregister as unregister_signal}; -use signal_hook::{consts as sigconsts, SigId}; +use signal_hook::{SigId, consts as sigconsts}; use crate::event::{OnResize, WindowSize}; use crate::tty::{ChildEvent, EventedPty, EventedReadWrite, Options}; @@ -37,7 +37,7 @@ macro_rules! die { ($($arg:tt)*) => {{ error!($($arg)*); std::process::exit(1); - }} + }}; } /// Really only needed on BSD, but should be fine elsewhere. @@ -82,11 +82,11 @@ fn get_pw_entry(buf: &mut [i8; 1024]) -> Result<Passwd<'_>> { let entry = unsafe { entry.assume_init() }; if status < 0 { - return Err(Error::new(ErrorKind::Other, "getpwuid_r failed")); + return Err(Error::other("getpwuid_r failed")); } if res.is_null() { - return Err(Error::new(ErrorKind::Other, "pw not found")); + return Err(Error::other("pw not found")); } // Sanity check. @@ -247,7 +247,7 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd // Create a new process group. let err = libc::setsid(); if err == -1 { - return Err(Error::new(ErrorKind::Other, "Failed to set session id")); + return Err(Error::other("Failed to set session id")); } // Set working directory, ignoring invalid paths. @@ -383,7 +383,7 @@ impl EventedPty for Pty { let mut buf = [0u8; 1]; if let Err(err) = self.signals.read(&mut buf) { if err.kind() != ErrorKind::WouldBlock { - error!("Error reading from signal pipe: {}", err); + error!("Error reading from signal pipe: {err}"); } return None; } @@ -391,7 +391,7 @@ impl EventedPty for Pty { // Match on the child process. match self.child.try_wait() { Err(err) => { - error!("Error checking child process termination: {}", err); + error!("Error checking child process termination: {err}"); None }, Ok(None) => None, @@ -434,9 +434,7 @@ impl ToWinsize for WindowSize { } unsafe fn set_nonblocking(fd: c_int) { - use libc::{fcntl, F_GETFL, F_SETFL, O_NONBLOCK}; - - let res = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + let res = unsafe { fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) }; assert_eq!(res, 0); } diff --git a/alacritty_terminal/src/tty/windows/blocking.rs b/alacritty_terminal/src/tty/windows/blocking.rs index 3c74be4a..a1b3c96f 100644 --- a/alacritty_terminal/src/tty/windows/blocking.rs +++ b/alacritty_terminal/src/tty/windows/blocking.rs @@ -6,7 +6,7 @@ use std::sync::{Arc, Mutex}; use std::task::{Context, Poll, Wake, Waker}; use std::{io, thread}; -use piper::{pipe, Reader, Writer}; +use piper::{Reader, Writer, pipe}; use polling::os::iocp::{CompletionPacket, PollerIocpExt}; use polling::{Event, PollMode, Poller}; diff --git a/alacritty_terminal/src/tty/windows/child.rs b/alacritty_terminal/src/tty/windows/child.rs index 573eb475..31d753b4 100644 --- a/alacritty_terminal/src/tty/windows/child.rs +++ b/alacritty_terminal/src/tty/windows/child.rs @@ -3,14 +3,14 @@ use std::io::Error; use std::num::NonZeroU32; use std::ptr; use std::sync::atomic::{AtomicPtr, Ordering}; -use std::sync::{mpsc, Arc, Mutex}; +use std::sync::{Arc, Mutex, mpsc}; use polling::os::iocp::{CompletionPacket, PollerIocpExt}; use polling::{Event, Poller}; use windows_sys::Win32::Foundation::{BOOLEAN, FALSE, HANDLE}; use windows_sys::Win32::System::Threading::{ - GetExitCodeProcess, GetProcessId, RegisterWaitForSingleObject, UnregisterWait, INFINITE, + GetExitCodeProcess, GetProcessId, INFINITE, RegisterWaitForSingleObject, UnregisterWait, WT_EXECUTEINWAITTHREAD, WT_EXECUTEONLYONCE, }; diff --git a/alacritty_terminal/src/tty/windows/conpty.rs b/alacritty_terminal/src/tty/windows/conpty.rs index bcbc1f0e..5d6359ef 100644 --- a/alacritty_terminal/src/tty/windows/conpty.rs +++ b/alacritty_terminal/src/tty/windows/conpty.rs @@ -6,25 +6,25 @@ use std::os::windows::ffi::OsStrExt; use std::os::windows::io::IntoRawHandle; use std::{mem, ptr}; -use windows_sys::core::{HRESULT, PWSTR}; use windows_sys::Win32::Foundation::{HANDLE, S_OK}; use windows_sys::Win32::System::Console::{ - ClosePseudoConsole, CreatePseudoConsole, ResizePseudoConsole, COORD, HPCON, + COORD, ClosePseudoConsole, CreatePseudoConsole, HPCON, ResizePseudoConsole, }; use windows_sys::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryW}; +use windows_sys::core::{HRESULT, PWSTR}; use windows_sys::{s, w}; use windows_sys::Win32::System::Threading::{ - CreateProcessW, InitializeProcThreadAttributeList, UpdateProcThreadAttribute, - CREATE_UNICODE_ENVIRONMENT, EXTENDED_STARTUPINFO_PRESENT, PROCESS_INFORMATION, - PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, STARTF_USESTDHANDLES, STARTUPINFOEXW, STARTUPINFOW, + CREATE_UNICODE_ENVIRONMENT, CreateProcessW, EXTENDED_STARTUPINFO_PRESENT, + InitializeProcThreadAttributeList, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, PROCESS_INFORMATION, + STARTF_USESTDHANDLES, STARTUPINFOEXW, STARTUPINFOW, UpdateProcThreadAttribute, }; use crate::event::{OnResize, WindowSize}; +use crate::tty::Options; use crate::tty::windows::blocking::{UnblockedReader, UnblockedWriter}; use crate::tty::windows::child::ChildExitWatcher; -use crate::tty::windows::{cmdline, win32_string, Pty}; -use crate::tty::Options; +use crate::tty::windows::{Pty, cmdline, win32_string}; const PIPE_CAPACITY: usize = crate::event_loop::READ_BUFFER_SIZE; diff --git a/alacritty_terminal/src/tty/windows/mod.rs b/alacritty_terminal/src/tty/windows/mod.rs index 32e24677..83b747c8 100644 --- a/alacritty_terminal/src/tty/windows/mod.rs +++ b/alacritty_terminal/src/tty/windows/mod.rs @@ -2,8 +2,8 @@ use std::ffi::OsStr; use std::io::{self, Result}; use std::iter::once; use std::os::windows::ffi::OsStrExt; -use std::sync::mpsc::TryRecvError; use std::sync::Arc; +use std::sync::mpsc::TryRecvError; use crate::event::{OnResize, WindowSize}; use crate::tty::windows::child::ChildExitWatcher; diff --git a/alacritty_terminal/src/vi_mode.rs b/alacritty_terminal/src/vi_mode.rs index e23e9b80..f3655b30 100644 --- a/alacritty_terminal/src/vi_mode.rs +++ b/alacritty_terminal/src/vi_mode.rs @@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize}; use crate::event::EventListener; use crate::grid::{Dimensions, GridCell}; use crate::index::{Boundary, Column, Direction, Line, Point, Side}; -use crate::term::cell::Flags; use crate::term::Term; +use crate::term::cell::Flags; /// Possible vi mode motion movements. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -52,6 +52,10 @@ pub enum ViMotion { WordRightEnd, /// Move to opposing bracket. Bracket, + /// Move above the current paragraph. + ParagraphUp, + /// Move below the current paragraph. + ParagraphDown, } /// Cursor tracking vi mode position. @@ -153,6 +157,27 @@ impl ViModeCursor { self.point = word(term, self.point, Direction::Right, Side::Right); }, ViMotion::Bracket => self.point = term.bracket_search(self.point).unwrap_or(self.point), + ViMotion::ParagraphUp => { + // Skip empty lines until we find the next paragraph, + // then skip over the paragraph until we reach the next empty line. + let topmost_line = term.topmost_line(); + self.point.line = (*topmost_line..*self.point.line) + .rev() + .skip_while(|line| term.grid()[Line(*line)].is_clear()) + .find(|line| term.grid()[Line(*line)].is_clear()) + .map_or(topmost_line, Line); + self.point.column = Column(0); + }, + ViMotion::ParagraphDown => { + // Skip empty lines until we find the next paragraph, + // then skip over the paragraph until we reach the next empty line. + let bottommost_line = term.bottommost_line(); + self.point.line = (*self.point.line..*bottommost_line) + .skip_while(|line| term.grid()[Line(*line)].is_clear()) + .find(|line| term.grid()[Line(*line)].is_clear()) + .map_or(bottommost_line, Line); + self.point.column = Column(0); + }, } term.scroll_to_point(self.point); @@ -226,17 +251,19 @@ fn first_occupied<T>(term: &Term<T>, mut point: Point) -> Point { // Fallback to the next non-empty cell. let mut line = point.line; - occupied.unwrap_or_else(|| loop { - if let Some(occupied) = first_occupied_in_line(term, line) { - break occupied; - } + occupied.unwrap_or_else(|| { + loop { + if let Some(occupied) = first_occupied_in_line(term, line) { + break occupied; + } - let last_cell = Point::new(line, last_column); - if !is_wrap(term, last_cell) { - break last_cell; - } + let last_cell = Point::new(line, last_column); + if !is_wrap(term, last_cell) { + break last_cell; + } - line += 1; + line += 1; + } }) } else { occupied diff --git a/alacritty_terminal/tests/ref.rs b/alacritty_terminal/tests/ref.rs index 454f2e5d..5596d5b0 100644 --- a/alacritty_terminal/tests/ref.rs +++ b/alacritty_terminal/tests/ref.rs @@ -24,7 +24,7 @@ macro_rules! ref_tests { ref_test(&test_path); } )* - } + }; } ref_tests! { diff --git a/extra/completions/_alacritty b/extra/completions/_alacritty index a0ac0e3b..971d93ce 100644 --- a/extra/completions/_alacritty +++ b/extra/completions/_alacritty @@ -87,6 +87,14 @@ _arguments "${_arguments_options[@]}" : \ '*::options -- Configuration file options \[example\: '\''cursor.style="Beam"'\''\]:_default' \ && ret=0 ;; +(get-config) +_arguments "${_arguments_options[@]}" : \ +'-w+[Window ID for the config request]:WINDOW_ID:_default' \ +'--window-id=[Window ID for the config request]:WINDOW_ID:_default' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ ":: :_alacritty__msg__help_commands" \ @@ -107,6 +115,10 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(get-config) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; (help) _arguments "${_arguments_options[@]}" : \ && ret=0 @@ -166,6 +178,10 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ && ret=0 ;; +(get-config) +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; esac ;; esac @@ -220,6 +236,7 @@ _alacritty__help__msg_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ +'get-config:Read runtime Alacritty configuration' \ ) _describe -t commands 'alacritty help msg commands' commands "$@" } @@ -233,6 +250,11 @@ _alacritty__help__msg__create-window_commands() { local commands; commands=() _describe -t commands 'alacritty help msg create-window commands' commands "$@" } +(( $+functions[_alacritty__help__msg__get-config_commands] )) || +_alacritty__help__msg__get-config_commands() { + local commands; commands=() + _describe -t commands 'alacritty help msg get-config commands' commands "$@" +} (( $+functions[_alacritty__migrate_commands] )) || _alacritty__migrate_commands() { local commands; commands=() @@ -243,6 +265,7 @@ _alacritty__msg_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ +'get-config:Read runtime Alacritty configuration' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'alacritty msg commands' commands "$@" @@ -257,11 +280,17 @@ _alacritty__msg__create-window_commands() { local commands; commands=() _describe -t commands 'alacritty msg create-window commands' commands "$@" } +(( $+functions[_alacritty__msg__get-config_commands] )) || +_alacritty__msg__get-config_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg get-config commands' commands "$@" +} (( $+functions[_alacritty__msg__help_commands] )) || _alacritty__msg__help_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ +'get-config:Read runtime Alacritty configuration' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'alacritty msg help commands' commands "$@" @@ -276,6 +305,11 @@ _alacritty__msg__help__create-window_commands() { local commands; commands=() _describe -t commands 'alacritty msg help create-window commands' commands "$@" } +(( $+functions[_alacritty__msg__help__get-config_commands] )) || +_alacritty__msg__help__get-config_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg help get-config commands' commands "$@" +} (( $+functions[_alacritty__msg__help__help_commands] )) || _alacritty__msg__help__help_commands() { local commands; commands=() diff --git a/extra/completions/alacritty.bash b/extra/completions/alacritty.bash index e2213b75..a52f5075 100644 --- a/extra/completions/alacritty.bash +++ b/extra/completions/alacritty.bash @@ -1,12 +1,16 @@ _alacritty() { local i cur prev opts cmd COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + cur="$2" + else + cur="${COMP_WORDS[COMP_CWORD]}" + fi + prev="$3" cmd="" opts="" - for i in ${COMP_WORDS[@]} + for i in "${COMP_WORDS[@]:0:COMP_CWORD}" do case "${cmd},${i}" in ",$1") @@ -36,12 +40,18 @@ _alacritty() { alacritty__help__msg,create-window) cmd="alacritty__help__msg__create__window" ;; + alacritty__help__msg,get-config) + cmd="alacritty__help__msg__get__config" + ;; alacritty__msg,config) cmd="alacritty__msg__config" ;; alacritty__msg,create-window) cmd="alacritty__msg__create__window" ;; + alacritty__msg,get-config) + cmd="alacritty__msg__get__config" + ;; alacritty__msg,help) cmd="alacritty__msg__help" ;; @@ -51,6 +61,9 @@ _alacritty() { alacritty__msg__help,create-window) cmd="alacritty__msg__help__create__window" ;; + alacritty__msg__help,get-config) + cmd="alacritty__msg__help__get__config" + ;; alacritty__msg__help,help) cmd="alacritty__msg__help__help" ;; @@ -194,7 +207,7 @@ _alacritty() { return 0 ;; alacritty__help__msg) - opts="create-window config" + opts="create-window config get-config" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -235,6 +248,20 @@ _alacritty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + alacritty__help__msg__get__config) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; alacritty__migrate) opts="-c -d -i -s -h --config-file --dry-run --skip-imports --skip-renames --silent --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -280,7 +307,7 @@ _alacritty() { return 0 ;; alacritty__msg) - opts="-s -h --socket --help create-window config help" + opts="-s -h --socket --help create-window config get-config help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -402,8 +429,30 @@ _alacritty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + alacritty__msg__get__config) + opts="-w -h --window-id --help" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --window-id) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -w) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; alacritty__msg__help) - opts="create-window config help" + opts="create-window config get-config help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -444,6 +493,20 @@ _alacritty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + alacritty__msg__help__get__config) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; alacritty__msg__help__help) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 4 ]] ; then diff --git a/extra/completions/alacritty.fish b/extra/completions/alacritty.fish index 7cfc3337..5f58ce4c 100644 --- a/extra/completions/alacritty.fish +++ b/extra/completions/alacritty.fish @@ -43,11 +43,12 @@ complete -c alacritty -n "__fish_alacritty_needs_command" -s V -l version -d 'Pr complete -c alacritty -n "__fish_alacritty_needs_command" -f -a "msg" -d 'Send a message to the Alacritty socket' complete -c alacritty -n "__fish_alacritty_needs_command" -f -a "migrate" -d 'Migrate the configuration file' complete -c alacritty -n "__fish_alacritty_needs_command" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -s s -l socket -d 'IPC socket connection path override' -r -F -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -s h -l help -d 'Print help' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -f -a "config" -d 'Update the Alacritty configuration' -complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -s s -l socket -d 'IPC socket connection path override' -r -F +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -s h -l help -d 'Print help' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "config" -d 'Update the Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "get-config" -d 'Read runtime Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and not __fish_seen_subcommand_from create-window config get-config help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -l working-directory -d 'Start the shell in the specified working directory' -r -F complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -s e -l command -d 'Command and args to execute (must be last argument)' -r complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -s T -l title -d 'Defines the window title [default: Alacritty]' -r @@ -58,8 +59,11 @@ complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from config" -s w -l window-id -d 'Window ID for the new config' -r complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from config" -s r -l reset -d 'Clear all runtime configuration changes' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from config" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from get-config" -s w -l window-id -d 'Window ID for the config request' -r +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from get-config" -s h -l help -d 'Print help (see more with \'--help\')' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "config" -d 'Update the Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "get-config" -d 'Read runtime Alacritty configuration' complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -s c -l config-file -d 'Path to the configuration file' -r -F complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -s d -l dry-run -d 'Only output TOML config to STDOUT' @@ -72,3 +76,4 @@ complete -c alacritty -n "__fish_alacritty_using_subcommand help; and not __fish complete -c alacritty -n "__fish_alacritty_using_subcommand help; and not __fish_seen_subcommand_from msg migrate help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' complete -c alacritty -n "__fish_alacritty_using_subcommand help; and __fish_seen_subcommand_from msg" -f -a "create-window" -d 'Create a new window in the same Alacritty process' complete -c alacritty -n "__fish_alacritty_using_subcommand help; and __fish_seen_subcommand_from msg" -f -a "config" -d 'Update the Alacritty configuration' +complete -c alacritty -n "__fish_alacritty_using_subcommand help; and __fish_seen_subcommand_from msg" -f -a "get-config" -d 'Read runtime Alacritty configuration' diff --git a/extra/man/alacritty-bindings.5.scd b/extra/man/alacritty-bindings.5.scd index 7f0bdf34..a4269e52 100644 --- a/extra/man/alacritty-bindings.5.scd +++ b/extra/man/alacritty-bindings.5.scd @@ -141,6 +141,22 @@ configuration. See *alacritty*(5) for full configuration format documentation. :[ : _"Vi|~Search"_ : _"ClearSelection"_ +| _"Y"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"ToggleNormalSelection"_ +| _"Y"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"Last"_ +| _"Y"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"Copy"_ +| _"Y"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"ClearSelection"_ | _"V"_ :[ : _"Vi|~Search"_ @@ -189,6 +205,14 @@ configuration. See *alacritty*(5) for full configuration format documentation. :[ : _"Vi|~Search"_ : _"InlineSearchPrevious"_ +| _"\*"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"SemanticSearchForward"_ +| _"#"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"SemanticSearchBackward"_ | _"K"_ :[ : _"Vi|~Search"_ @@ -281,6 +305,14 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Shift"_ : _"Vi|~Search"_ : _"Bracket"_ +| _"{"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"ParagraphUp"_ +| _"}"_ +: _"Shift"_ +: _"Vi|~Search"_ +: _"ParagraphDown"_ | _"/"_ :[ : _"Vi|~Search"_ diff --git a/extra/man/alacritty-msg.1.scd b/extra/man/alacritty-msg.1.scd index 7a14dd1d..5a054040 100644 --- a/extra/man/alacritty-msg.1.scd +++ b/extra/man/alacritty-msg.1.scd @@ -78,6 +78,19 @@ making it possible to control Alacritty without directly accessing it. Default: _$ALACRITTY_WINDOW_ID_ +*get-config* + + Read runtime Alacritty configuration. + + *OPTIONS* + *-w, --window-id* _<WINDOW_ID>_ + + Window ID for the config request. + + Use _-1_ to get the global config. + + Default: _$ALACRITTY_WINDOW_ID_ + # SEE ALSO *alacritty*(1), *alacritty*(5), *alacritty-bindings*(5) diff --git a/extra/man/alacritty.1.scd b/extra/man/alacritty.1.scd index 86630a65..96745033 100644 --- a/extra/man/alacritty.1.scd +++ b/extra/man/alacritty.1.scd @@ -72,6 +72,7 @@ set of features with high performance. . _$XDG_CONFIG_HOME/alacritty.toml_ . _$HOME/.config/alacritty/alacritty.toml_ . _$HOME/.alacritty.toml_ + . _/etc/alacritty/alacritty.toml_ On Windows, the config file will be looked for in: diff --git a/extra/man/alacritty.5.scd b/extra/man/alacritty.5.scd index e2f5b252..af4a79fa 100644 --- a/extra/man/alacritty.5.scd +++ b/extra/man/alacritty.5.scd @@ -18,6 +18,7 @@ following locations on UNIX systems: . _$XDG_CONFIG_HOME/alacritty.toml_ . _$HOME/.config/alacritty/alacritty.toml_ . _$HOME/.alacritty.toml_ +. _/etc/alacritty/alacritty.toml_ On Windows, the config file will be looked for in: @@ -894,6 +895,10 @@ _https://docs.rs/winit/latest/winit/keyboard/enum.Key.html#variant.Dead_ Move to end of whitespace separated word. *Bracket* Move to opposing bracket. + *ParagraphUp* + Move above the current paragraph. + *ParagraphDown* + Move below the current paragraph. *ToggleNormalSelection* Toggle normal vi selection. *ToggleLineSelection* @@ -926,6 +931,10 @@ _https://docs.rs/winit/latest/winit/keyboard/enum.Key.html#variant.Dead_ Jump to the next inline search match. *InlineSearchPrevious* Jump to the previous inline search match. + *SemanticSearchForward* + Search forward for selection or word under the cursor. + *SemanticSearchBackward* + Search backward for selection or word under the cursor. _Search actions:_ |