diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2fe8dd2cd0b..c65e7f82ee9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Stable run: cargo test - name: Stable (no default features) @@ -30,7 +30,7 @@ jobs: check-macos-x86_64: runs-on: macos-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install target run: rustup update && rustup target add x86_64-apple-darwin - name: Build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8c5d756ea44..6efa44221ad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,9 @@ on: push: tags: ["v[0-9]+.[0-9]+.[0-9]+*"] +permissions: + contents: write + env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CARGO_TERM_COLOR: always @@ -98,7 +101,7 @@ jobs: shell: bash steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Test run: cargo test --release - name: Build @@ -124,13 +127,15 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install dependencies run: | sudo apt-get install cmake pkg-config libfreetype6-dev libfontconfig1-dev \ libxcb-xfixes0-dev libxkbcommon-dev python3 scdoc - name: Test run: cargo test --release + - name: Build + run: cargo build --release - name: Generate manpages run: | scdoc < extra/man/alacritty.1.scd | gzip -c > "./alacritty.1.gz" @@ -139,7 +144,12 @@ jobs: scdoc < extra/man/alacritty-bindings.5.scd | gzip -c > "./alacritty-bindings.5.gz" - name: Upload Assets run: | + binpath="alacritty-linux-$(uname -m).gz" + gzip -9 --stdout target/release/alacritty > "$binpath" + mv ./extra/logo/alacritty-term.svg ./Alacritty.svg + + ./.github/workflows/upload_asset.sh "$binpath" $GITHUB_TOKEN ./.github/workflows/upload_asset.sh ./Alacritty.svg $GITHUB_TOKEN ./.github/workflows/upload_asset.sh ./alacritty.1.gz $GITHUB_TOKEN ./.github/workflows/upload_asset.sh ./alacritty-msg.1.gz $GITHUB_TOKEN diff --git a/.github/workflows/upload_asset.sh b/.github/workflows/upload_asset.sh index 5f57d934f7d..1503cb161ca 100755 --- a/.github/workflows/upload_asset.sh +++ b/.github/workflows/upload_asset.sh @@ -8,89 +8,12 @@ fi repo="xxxbrian/alacritty" file_path=$1 -bearer=$2 -echo "Starting asset upload from $file_path to $repo." +tag=$(git describe --tags --abbrev=0) -# Get the release for this tag. -tag="$(git describe --tags --abbrev=0)" - -# Make sure the git tag could be determined. -if [ -z "$tag" ]; then - printf "\e[31mError: Unable to find git tag\e[0m\n" - exit 1 -fi - -echo "Git tag: $tag" - -# Get the upload URL for the current tag. -# -# Since this might be a draft release, we can't just use the /releases/tags/:tag -# endpoint which only shows published releases. -echo "Checking for existing release..." -upload_url=$(\ - curl \ - --http1.1 \ - -H "Authorization: Bearer $bearer" \ - "https://api.github.com/repos/$repo/releases" \ - 2> /dev/null \ - | grep -E "(upload_url|tag_name)" \ - | paste - - \ - | grep -e "tag_name\": \"$tag\"" \ - | head -n 1 \ - | sed 's/.*\(https.*assets\).*/\1/' \ -) - -# Create a new release if we didn't find one for this tag. -if [ -z "$upload_url" ]; then - echo "No release found." - echo "Creating new release..." - - # Create new release. - response=$( - curl -f \ - --http1.1 \ - -X POST \ - -H "Authorization: Bearer $bearer" \ - -d "{\"tag_name\":\"$tag\",\"draft\":true}" \ - "https://api.github.com/repos/$repo/releases" \ - 2> /dev/null\ - ) - - # Abort if the release could not be created. - if [ $? -ne 0 ]; then - printf "\e[31mError: Unable to create new release.\e[0m\n" - exit 1; - fi - - # Extract upload URL from new release. - upload_url=$(\ - echo "$response" \ - | grep "upload_url" \ - | sed 's/.*: "\(.*\){.*/\1/' \ - ) +if ! gh release view "$tag" +then + gh release create --draft "$tag" fi -# Propagate error if no URL for asset upload could be found. -if [ -z "$upload_url" ]; then - printf "\e[31mError: Unable to find release upload url.\e[0m\n" - exit 2 -fi - -# Upload the file to the tag's release. -file_name=${file_path##*/} -echo "Uploading asset $file_name to $upload_url..." -curl -f \ - --http1.1 \ - -X POST \ - -H "Authorization: Bearer $bearer" \ - -H "Content-Type: application/octet-stream" \ - --data-binary @"$file_path" \ - "$upload_url?name=$file_name" \ - &> /dev/null \ -|| { \ - printf "\e[31mError: Unable to upload asset.\e[0m\n" \ - && exit 3; \ -} - -printf "\e[32mSuccess\e[0m\n" +gh release upload "$tag" "$file_path" diff --git a/CHANGELOG.md b/CHANGELOG.md index 8442355ae5c..2b3d2b46b97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,17 +8,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Notable changes to the `alacritty_terminal` crate are documented in its [CHANGELOG](./alacritty_terminal/CHANGELOG.md). -## 0.14.0-dev +## 0.14.0 + +### Packaging + +- Minimum Rust version has been bumped to 1.74.0 ### Added - Support relative path imports from config files +- `alacritty migrate` support for TOML configuration changes +- Headless mode using `alacritty --daemon` ### Changed - Pressing `Alt` with unicode input will now add `ESC` like for ASCII input - Decorations use opaque style and system window background on macOS - No longer source `~/.zshenv` on macOS +- Moved config options `import`, `working_directory`, `live_config_reload`, and `ipc_socket` + to the new `general` section +- Moved config option `shell` to `terminal.shell` +- `ctrl+shift+u` binding to open links to `ctrl+shift+o` to avoid collisions with IMEs +- Use `Beam` cursor for single char cursor inside the IME preview ### Fixed @@ -32,6 +43,14 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Config emitting errors for nonexistent import paths - Kitty keyboard protocol reporting shifted key codes - Broken search with words broken across line boundary on the first character +- Config import changes not being live reloaded +- Cursor color requests with default cursor colors +- Fullwidth semantic escape characters +- Windows app icon now displays properly in old alt+tab on Windows +- Alacritty not being properly activated with startup notify +- Invalid URL highlights after terminal scrolling +- Hollow block cursor not spanning multiple chars being edited inside the IME preview +- Vi inline search only working for direct key input without modifiers ## 0.13.2 diff --git a/Cargo.lock b/Cargo.lock index 91e64d06f85..4c79f0e7761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,22 +23,22 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "alacritty" -version = "0.14.0-dev" +version = "0.14.0" dependencies = [ "ahash", "alacritty_config", "alacritty_config_derive", "alacritty_terminal", - "bitflags 2.5.0", + "bitflags 2.6.0", "clap", "clap_complete", "cocoa", @@ -60,7 +60,9 @@ dependencies = [ "serde_json", "serde_yaml", "smallvec", + "tempfile", "toml", + "toml_edit 0.22.21", "unicode-width", "windows-sys 0.52.0", "winit", @@ -69,7 +71,7 @@ dependencies = [ [[package]] name = "alacritty_config" -version = "0.2.1-dev" +version = "0.2.2" dependencies = [ "alacritty_config_derive", "log", @@ -79,7 +81,7 @@ dependencies = [ [[package]] name = "alacritty_config_derive" -version = "0.2.3-dev" +version = "0.2.4" dependencies = [ "alacritty_config", "log", @@ -92,10 +94,10 @@ dependencies = [ [[package]] name = "alacritty_terminal" -version = "0.24.1-dev" +version = "0.24.1" dependencies = [ "base64", - "bitflags 2.5.0", + "bitflags 2.6.0", "home", "libc", "log", @@ -121,7 +123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.5.0", + "bitflags 2.6.0", "cc", "cesu8", "jni", @@ -143,50 +145,51 @@ checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -215,15 +218,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "base64" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" @@ -233,9 +236,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -257,29 +260,29 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.15.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "calloop" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "log", "polling", "rustix", @@ -289,9 +292,9 @@ dependencies = [ [[package]] name = "calloop-wayland-source" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ "calloop", "rustix", @@ -301,9 +304,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" dependencies = [ "jobserver", "libc", @@ -338,9 +341,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -348,9 +351,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -360,18 +363,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" +checksum = "5b4be9c4c4b1f30b78d8a750e0822b6a6102d97e62061c583a6c1dea2dfb33ae" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck", "proc-macro2", @@ -381,9 +384,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "clipboard-win" @@ -427,15 +430,15 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -443,9 +446,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -482,9 +485,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -518,27 +521,27 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossfont" @@ -620,9 +623,9 @@ dependencies = [ [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" @@ -669,19 +672,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fdeflate" @@ -694,21 +697,21 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -747,7 +750,7 @@ version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5442dee36ca09604133580dc0553780e867936bb3cbef3275859e889026d2b17" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "freetype-sys", "libc", ] @@ -790,9 +793,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -816,7 +819,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2491aa3090f682ddd920b184491844440fdd14379c7eef8f5bc10ef7fb3242fd" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg_aliases", "cgl", "core-foundation", @@ -866,30 +869,36 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "indexmap" -version = "2.2.5" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", @@ -915,11 +924,17 @@ dependencies = [ "libc", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni" @@ -945,9 +960,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -995,59 +1010,58 @@ checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] name = "libredox" -version = "0.0.1" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", "redox_syscall 0.4.1", ] [[package]] name = "libredox" -version = "0.0.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", - "redox_syscall 0.4.1", ] [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1055,9 +1069,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" dependencies = [ "serde", ] @@ -1073,9 +1087,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -1097,9 +1111,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", "simd-adler32", @@ -1132,7 +1146,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "jni-sys", "log", "ndk-sys", @@ -1162,7 +1176,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossbeam-channel", "filetime", "fsevent-sys", @@ -1238,7 +1252,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "libc", "objc2", @@ -1254,7 +1268,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "objc2", "objc2-core-location", @@ -1278,7 +1292,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "objc2", "objc2-foundation", @@ -1320,7 +1334,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "dispatch", "libc", @@ -1345,7 +1359,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "objc2", "objc2-foundation", @@ -1357,7 +1371,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "objc2", "objc2-foundation", @@ -1380,7 +1394,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "objc2", "objc2-cloud-kit", @@ -1412,7 +1426,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "objc2", "objc2-core-location", @@ -1451,9 +1465,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1461,15 +1475,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -1500,15 +1514,15 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", "fastrand", @@ -1536,16 +1550,17 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53b6af1f60f36f8c2ac2aad5459d75a5a9b4be1e8cdd40264f315d78193e531" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi", "pin-project-lite", "rustix", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1559,27 +1574,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1592,38 +1607,38 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", - "libredox 0.0.1", + "libredox 0.1.3", "thiserror", ] [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -1632,9 +1647,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rustc_version" @@ -1647,16 +1662,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.25" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "itoa", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1672,9 +1687,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -1699,9 +1714,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sctk-adwaita" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de61fa7334ee8ee1f5c3c58dcc414fb9361e7e8f5bff9d45f4d69eeb89a7169" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" dependencies = [ "crossfont", "log", @@ -1711,24 +1726,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", @@ -1737,9 +1752,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -1748,18 +1763,18 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] [[package]] name = "serde_yaml" -version = "0.9.33" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0623d197252096520c6f2a5e1171ee436e5af99a5d7caa2891e55e61950e6d9" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap", "itoa", @@ -1780,9 +1795,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -1804,20 +1819,20 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" dependencies = [ "serde", ] [[package]] name = "smithay-client-toolkit" -version = "0.18.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -1838,9 +1853,9 @@ dependencies = [ [[package]] name = "smithay-clipboard" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c091e7354ea8059d6ad99eace06dd13ddeedbb0ac72d40a9a6e7ff790525882d" +checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" dependencies = [ "libc", "smithay-client-toolkit", @@ -1849,9 +1864,9 @@ dependencies = [ [[package]] name = "smol_str" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" dependencies = [ "serde", ] @@ -1864,35 +1879,48 @@ checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.53" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" dependencies = [ "proc-macro2", "quote", @@ -1926,21 +1954,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.11" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.7", + "toml_edit 0.22.21", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -1958,15 +1986,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.7" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow 0.6.18", ] [[package]] @@ -1999,9 +2027,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unsafe-libyaml" @@ -2011,9 +2039,9 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" @@ -2047,7 +2075,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2864755f49461b8296184ac43e06516a4bc47dab4d4d06396b8c852f3e7c1593" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cursor-icon", "log", "serde", @@ -2057,9 +2085,9 @@ dependencies = [ [[package]] name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" dependencies = [ "proc-macro2", "quote", @@ -2149,9 +2177,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wayland-backend" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" dependencies = [ "cc", "downcast-rs", @@ -2163,11 +2191,11 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.2" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "rustix", "wayland-backend", "wayland-scanner", @@ -2179,16 +2207,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cursor-icon", "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.31.1" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" +checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" dependencies = [ "rustix", "wayland-client", @@ -2197,11 +2225,11 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.31.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -2209,11 +2237,11 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2222,11 +2250,11 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2235,9 +2263,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" dependencies = [ "proc-macro2", "quick-xml", @@ -2246,9 +2274,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" dependencies = [ "dlib", "log", @@ -2294,11 +2322,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2331,7 +2359,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -2366,18 +2403,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2394,9 +2431,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2412,9 +2449,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2430,15 +2467,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2454,9 +2491,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2472,9 +2509,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2490,9 +2527,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2508,20 +2545,20 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.30.3" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f45a7b7e2de6af35448d7718dab6d95acec466eb3bb7a56f4d31d1af754004" +checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33" dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.5.0", + "bitflags 2.6.0", "block2", "bytemuck", "calloop", @@ -2576,9 +2613,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -2604,9 +2641,9 @@ dependencies = [ [[package]] name = "x11-clipboard" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98785a09322d7446e28a13203d2cae1059a0dd3dfb32cb06d0a225f023d8286" +checksum = "662d74b3d77e396b8e5beb00b9cad6a9eccf40b2ef68cc858784b14c41d535a3" dependencies = [ "libc", "x11rb", @@ -2625,9 +2662,9 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "as-raw-xcb-connection", "gethostname", @@ -2640,9 +2677,9 @@ dependencies = [ [[package]] name = "x11rb-protocol" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" [[package]] name = "xcursor" @@ -2662,7 +2699,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "dlib", "log", "once_cell", @@ -2671,15 +2708,15 @@ dependencies = [ [[package]] name = "xkeysym" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" [[package]] name = "yeslogic-fontconfig-sys" @@ -2695,18 +2732,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index 062a443d85d..453ac70c7ce 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alacritty" -version = "0.14.0-dev" +version = "0.14.0" authors = ["Christian Duerr ", "Joe Wilm "] license = "Apache-2.0" description = "A fast, cross-platform, OpenGL terminal emulator" @@ -8,19 +8,19 @@ readme = "README.md" homepage = "https://alacritty.org" repository = "https://github.com/alacritty/alacritty" edition = "2021" -rust-version = "1.70.0" +rust-version = "1.74.0" [dependencies.alacritty_terminal] path = "../alacritty_terminal" -version = "0.24.1-dev" +version = "0.24.1" [dependencies.alacritty_config_derive] path = "../alacritty_config_derive" -version = "0.2.3-dev" +version = "0.2.4" [dependencies.alacritty_config] path = "../alacritty_config" -version = "0.2.1-dev" +version = "0.2.2" [dependencies] ahash = { version = "0.8.6", features = ["no-rng"] } @@ -35,13 +35,15 @@ log = { version = "0.4", features = ["std", "serde"] } memoffset = "0.9.0" notify = "6.1.1" parking_lot = "0.12.0" -serde = { version = "1", features = ["derive"] } 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" -winit = { version = "0.30.3", default-features = false, features = ["rwh_06", "serde"] } +winit = { version = "0.30.4", default-features = false, features = ["rwh_06", "serde"] } [build-dependencies] gl_generator = "0.14.0" diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index e7f2d3efd7e..bb0a24f4bd7 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -26,7 +26,7 @@ pub struct Options { pub print_events: bool, /// Generates ref test. - #[clap(long)] + #[clap(long, conflicts_with("daemon"))] pub ref_test: bool, /// X11 window ID to embed Alacritty within (decimal or hexadecimal with "0x" prefix). @@ -62,6 +62,10 @@ pub struct Options { #[clap(short, conflicts_with("quiet"), action = ArgAction::Count)] verbose: u8, + /// Do not spawn an initial window. + #[clap(long)] + pub daemon: bool, + /// CLI options for config overrides. #[clap(skip)] pub config_options: ParsedOptions, @@ -88,8 +92,8 @@ impl Options { /// Override configuration file with options from the CLI. pub fn override_config(&mut self, config: &mut UiConfig) { #[cfg(unix)] - { - config.ipc_socket |= self.socket.is_some(); + if self.socket.is_some() { + config.ipc_socket = Some(true); } config.window.embed = self.embed.as_ref().and_then(|embed| parse_hex_or_decimal(embed)); @@ -216,10 +220,10 @@ impl WindowIdentity { /// Override the [`WindowIdentity`]'s fields with the [`WindowOptions`]. pub fn override_identity_config(&self, identity: &mut Identity) { if let Some(title) = &self.title { - identity.title = title.clone(); + identity.title.clone_from(title); } if let Some(class) = &self.class { - identity.class = class.clone(); + identity.class.clone_from(class); } } } @@ -524,7 +528,7 @@ mod tests { let generated = String::from_utf8_lossy(&generated); let mut completion = String::new(); - let mut file = File::open(format!("../extra/completions/{}", file)).unwrap(); + let mut file = File::open(format!("../extra/completions/{file}")).unwrap(); file.read_to_string(&mut completion).unwrap(); assert_eq!(generated, completion); diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index 62ca03a0b7f..dfe31853bc0 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -287,7 +287,7 @@ impl Display for Action { Action::ViMotion(motion) => motion.fmt(f), Action::Vi(action) => action.fmt(f), Action::Mouse(action) => action.fmt(f), - _ => write!(f, "{:?}", self), + _ => write!(f, "{self:?}"), } } } @@ -1024,8 +1024,7 @@ impl<'a> Deserialize<'a> for RawBinding { }, Err(_) => { return Err(::custom(format!( - "Invalid key binding, scancode is too big: {}", - scancode + "Invalid key binding, scancode is too big: {scancode}" ))); }, }, @@ -1080,8 +1079,7 @@ impl<'a> Deserialize<'a> for RawBinding { _ => return Err(err), }; return Err(V::Error::custom(format!( - "unknown keyboard action `{}`", - value + "unknown keyboard action `{value}`" ))); }, } @@ -1122,8 +1120,7 @@ impl<'a> Deserialize<'a> for RawBinding { (Some(action @ Action::Mouse(_)), None, None) => { if mouse.is_none() { return Err(V::Error::custom(format!( - "action `{}` is only available for mouse bindings", - action, + "action `{action}` is only available for mouse bindings", ))); } action diff --git a/alacritty/src/config/general.rs b/alacritty/src/config/general.rs new file mode 100644 index 00000000000..ba559262bb7 --- /dev/null +++ b/alacritty/src/config/general.rs @@ -0,0 +1,39 @@ +//! Miscellaneous configuration options. + +use std::path::PathBuf; + +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)] +pub struct General { + /// Configuration file imports. + /// + /// This is never read since the field is directly accessed through the config's + /// [`toml::Value`], but still present to prevent unused field warnings. + pub import: Vec, + + /// Shell startup directory. + pub working_directory: Option, + + /// Live config reload. + pub live_config_reload: bool, + + /// Offer IPC through a unix socket. + #[allow(unused)] + pub ipc_socket: bool, +} + +impl Default for General { + fn default() -> Self { + Self { + live_config_reload: true, + ipc_socket: true, + working_directory: Default::default(), + import: Default::default(), + } + } +} diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs index 488ef537769..ba9d674deb9 100644 --- a/alacritty/src/config/mod.rs +++ b/alacritty/src/config/mod.rs @@ -15,6 +15,7 @@ pub mod color; pub mod cursor; pub mod debug; pub mod font; +pub mod general; pub mod monitor; pub mod scrolling; pub mod selection; @@ -76,12 +77,12 @@ impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Error::ReadingEnvHome(err) => { - write!(f, "Unable to read $HOME environment variable: {}", err) + write!(f, "Unable to read $HOME environment variable: {err}") }, - Error::Io(err) => write!(f, "Error reading config file: {}", err), - Error::Toml(err) => write!(f, "Config error: {}", err), - Error::TomlSe(err) => write!(f, "Yaml conversion error: {}", err), - Error::Yaml(err) => write!(f, "Config error: {}", err), + Error::Io(err) => write!(f, "Error reading config file: {err}"), + Error::Toml(err) => write!(f, "Config error: {err}"), + Error::TomlSe(err) => write!(f, "Yaml conversion error: {err}"), + Error::Yaml(err) => write!(f, "Config error: {err}"), } } } @@ -278,15 +279,15 @@ fn load_imports( merged } -// TODO: Merge back with `load_imports` once `alacritty migrate` is dropped. -// /// Get all import paths for a configuration. pub fn imports( config: &Value, base_path: &Path, recursion_limit: usize, ) -> StdResult>, String> { - let imports = match config.get("import") { + let imports = + config.get("import").or_else(|| config.get("general").and_then(|g| g.get("import"))); + let imports = match imports { Some(Value::Array(imports)) => imports, Some(_) => return Err("Invalid import type: expected a sequence".into()), None => return Ok(Vec::new()), @@ -300,7 +301,7 @@ pub fn imports( let mut import_paths = Vec::new(); for import in imports { - let mut path = match import { + let path = match import { Value::String(path) => PathBuf::from(path), _ => { import_paths.push(Err("Invalid import element type: expected path string".into())); @@ -308,23 +309,32 @@ pub fn imports( }, }; - // Resolve paths relative to user's home directory. - if let (Ok(stripped), Some(home_dir)) = (path.strip_prefix("~/"), home::home_dir()) { - path = home_dir.join(stripped); - } - - if path.is_relative() { - if let Some(base_path) = base_path.parent() { - path = base_path.join(path) - } - } + let normalized = normalize_import(base_path, path); - import_paths.push(Ok(path)); + import_paths.push(Ok(normalized)); } Ok(import_paths) } +/// Normalize import paths. +pub fn normalize_import(base_config_path: &Path, import_path: impl Into) -> PathBuf { + let mut import_path = import_path.into(); + + // Resolve paths relative to user's home directory. + if let (Ok(stripped), Some(home_dir)) = (import_path.strip_prefix("~/"), home::home_dir()) { + import_path = home_dir.join(stripped); + } + + if import_path.is_relative() { + if let Some(base_config_dir) = base_config_path.parent() { + import_path = base_config_dir.join(import_path) + } + } + + import_path +} + /// Prune the nulls from the YAML to ensure TOML compatibility. fn prune_yaml_nulls(value: &mut serde_yaml::Value, warn_pruned: bool) { fn walk(value: &mut serde_yaml::Value, warn_pruned: bool) -> bool { diff --git a/alacritty/src/config/monitor.rs b/alacritty/src/config/monitor.rs index 53cff1c90c2..3f73f120101 100644 --- a/alacritty/src/config/monitor.rs +++ b/alacritty/src/config/monitor.rs @@ -1,3 +1,5 @@ +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; use std::path::PathBuf; use std::sync::mpsc::{self, RecvTimeoutError, Sender}; use std::thread::JoinHandle; @@ -23,6 +25,7 @@ const FALLBACK_POLLING_TIMEOUT: Duration = Duration::from_secs(1); pub struct ConfigMonitor { thread: JoinHandle<()>, shutdown_tx: Sender>, + watched_hash: Option, } impl ConfigMonitor { @@ -32,6 +35,9 @@ impl ConfigMonitor { return None; } + // Calculate the hash for the unmodified list of paths. + let watched_hash = Self::hash_paths(&paths); + // Exclude char devices like `/dev/null`, sockets, and so on, by checking that file type is // a regular file. paths.retain(|path| { @@ -139,7 +145,7 @@ impl ConfigMonitor { } }); - Some(Self { thread: join_handle, shutdown_tx: tx }) + Some(Self { watched_hash, thread: join_handle, shutdown_tx: tx }) } /// Synchronously shut down the monitor. @@ -154,4 +160,33 @@ impl ConfigMonitor { warn!("config monitor shutdown failed: {err:?}"); } } + + /// Check if the config monitor needs to be restarted. + /// + /// 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) + } + + /// Generate the hash for a list of paths. + fn hash_paths(files: &[PathBuf]) -> Option { + // Use file count limit to avoid allocations. + const MAX_PATHS: usize = 1024; + if files.len() > MAX_PATHS { + return None; + } + + // Sort files to avoid restart on order change. + let mut sorted_files = [None; MAX_PATHS]; + for (i, file) in files.iter().enumerate() { + sorted_files[i] = Some(file); + } + sorted_files.sort_unstable(); + + // Calculate hash for the paths, regardless of order. + let mut hasher = DefaultHasher::new(); + Hash::hash_slice(&sorted_files, &mut hasher); + Some(hasher.finish()) + } } diff --git a/alacritty/src/config/terminal.rs b/alacritty/src/config/terminal.rs index b41af5db640..d0c0d9da49d 100644 --- a/alacritty/src/config/terminal.rs +++ b/alacritty/src/config/terminal.rs @@ -4,12 +4,14 @@ use toml::Value; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use alacritty_terminal::term::Osc52; -use crate::config::ui_config::StringVisitor; +use crate::config::ui_config::{Program, StringVisitor}; -#[derive(ConfigDeserialize, Default, Copy, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] pub struct Terminal { /// OSC52 support mode. pub osc52: SerdeOsc52, + /// Path to a shell program to run on startup. + pub shell: Option, } #[derive(SerdeReplace, Default, Copy, Clone, Debug, PartialEq)] diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index c736517b026..04b577c88e3 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -26,7 +26,8 @@ use crate::config::color::Colors; use crate::config::cursor::Cursor; use crate::config::debug::Debug; use crate::config::font::Font; -use crate::config::mouse::{Mouse, MouseBindings}; +use crate::config::general::General; +use crate::config::mouse::Mouse; use crate::config::scrolling::Scrolling; use crate::config::selection::Selection; use crate::config::terminal::Terminal; @@ -38,8 +39,11 @@ use crate::config::LOG_TARGET_CONFIG; 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, Clone, Debug, PartialEq)] +#[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] pub struct UiConfig { + /// Miscellaneous configuration options. + pub general: General, + /// Extra environment variables. pub env: HashMap, @@ -64,14 +68,6 @@ pub struct UiConfig { /// Debug options. pub debug: Debug, - /// Send escape sequences using the alt key. - #[config(removed = "It's now always set to 'true'. If you're on macOS use \ - 'window.option_as_alt' to alter behavior of Option")] - pub alt_send_esc: Option, - - /// Live config reload. - pub live_config_reload: bool, - /// Bell configuration. pub bell: BellConfig, @@ -85,70 +81,35 @@ pub struct UiConfig { /// Regex hints for interacting with terminal content. pub hints: Hints, - /// Offer IPC through a unix socket. - #[cfg(unix)] - pub ipc_socket: bool, - /// Config for the alacritty_terminal itself. pub terminal: Terminal, - /// Path to a shell program to run on startup. - pub shell: Option, - - /// Shell startup directory. - pub working_directory: Option, - /// Keyboard configuration. keyboard: Keyboard, - /// Should draw bold text with brighter colors instead of bold font. - #[config(deprecated = "use colors.draw_bold_text_with_bright_colors instead")] - draw_bold_text_with_bright_colors: bool, - - /// Keybindings. - #[config(deprecated = "use keyboard.bindings instead")] - key_bindings: Option, - - /// Bindings for the mouse. - #[config(deprecated = "use mouse.bindings instead")] - mouse_bindings: Option, + /// Path to a shell program to run on startup. + #[config(deprecated = "use terminal.shell instead")] + shell: Option, /// Configuration file imports. /// /// This is never read since the field is directly accessed through the config's /// [`toml::Value`], but still present to prevent unused field warnings. - import: Vec, -} + #[config(deprecated = "use general.import instead")] + import: Option>, -impl Default for UiConfig { - fn default() -> Self { - Self { - live_config_reload: true, - #[cfg(unix)] - ipc_socket: true, - draw_bold_text_with_bright_colors: Default::default(), - working_directory: Default::default(), - mouse_bindings: Default::default(), - config_paths: Default::default(), - key_bindings: Default::default(), - alt_send_esc: Default::default(), - scrolling: Default::default(), - selection: Default::default(), - keyboard: Default::default(), - terminal: Default::default(), - import: Default::default(), - cursor: Default::default(), - window: Default::default(), - colors: Default::default(), - shell: Default::default(), - mouse: Default::default(), - debug: Default::default(), - hints: Default::default(), - font: Default::default(), - bell: Default::default(), - env: Default::default(), - } - } + /// Shell startup directory. + #[config(deprecated = "use general.working_directory instead")] + working_directory: Option, + + /// Live config reload. + #[config(deprecated = "use general.live_config_reload instead")] + live_config_reload: Option, + + /// Offer IPC through a unix socket. + #[cfg(unix)] + #[config(deprecated = "use general.ipc_socket instead")] + pub ipc_socket: Option, } impl UiConfig { @@ -166,26 +127,14 @@ impl UiConfig { /// Derive [`PtyOptions`] from the config. pub fn pty_config(&self) -> PtyOptions { - let shell = self.shell.clone().map(Into::into); - PtyOptions { - shell, - working_directory: self.working_directory.clone(), - hold: false, - env: HashMap::new(), - } + let shell = self.terminal.shell.clone().or_else(|| self.shell.clone()).map(Into::into); + let working_directory = + self.working_directory.clone().or_else(|| self.general.working_directory.clone()); + PtyOptions { working_directory, shell, hold: false, env: HashMap::new() } } /// Generate key bindings for all keyboard hints. pub fn generate_hint_bindings(&mut self) { - // Check which key bindings is most likely to be the user's configuration. - // - // Both will be non-empty due to the presence of the default keybindings. - let key_bindings = if let Some(key_bindings) = self.key_bindings.as_mut() { - &mut key_bindings.0 - } else { - &mut self.keyboard.bindings.0 - }; - for hint in &self.hints.enabled { let binding = match &hint.binding { Some(binding) => binding, @@ -200,7 +149,7 @@ impl UiConfig { action: Action::Hint(hint.clone()), }; - key_bindings.push(binding); + self.keyboard.bindings.0.push(binding); } } @@ -211,25 +160,23 @@ impl UiConfig { #[inline] pub fn key_bindings(&self) -> &[KeyBinding] { - if let Some(key_bindings) = self.key_bindings.as_ref() { - &key_bindings.0 - } else { - &self.keyboard.bindings.0 - } + &self.keyboard.bindings.0 } #[inline] pub fn mouse_bindings(&self) -> &[MouseBinding] { - if let Some(mouse_bindings) = self.mouse_bindings.as_ref() { - &mouse_bindings.0 - } else { - &self.mouse.bindings.0 - } + &self.mouse.bindings.0 } #[inline] - pub fn draw_bold_text_with_bright_colors(&self) -> bool { - self.colors.draw_bold_text_with_bright_colors || self.draw_bold_text_with_bright_colors + pub fn live_config_reload(&self) -> bool { + self.live_config_reload.unwrap_or(self.general.live_config_reload) + } + + #[cfg(unix)] + #[inline] + pub fn ipc_socket(&self) -> bool { + self.ipc_socket.unwrap_or(self.general.ipc_socket) } } @@ -362,7 +309,7 @@ impl Default for Hints { mouse: Some(HintMouse { enabled: true, mods: Default::default() }), binding: Some(HintBinding { key: BindingKey::Keycode { - key: Key::Character("u".into()), + key: Key::Character("o".into()), location: KeyLocation::Standard, }, mods: ModsWrapper(ModifiersState::SHIFT | ModifiersState::CONTROL), diff --git a/alacritty/src/daemon.rs b/alacritty/src/daemon.rs index df66646ae3d..c8fb88d1df0 100644 --- a/alacritty/src/daemon.rs +++ b/alacritty/src/daemon.rs @@ -94,7 +94,7 @@ pub fn foreground_process_path( } #[cfg(not(any(target_os = "macos", target_os = "freebsd")))] - let link_path = format!("/proc/{}/cwd", pid); + let link_path = format!("/proc/{pid}/cwd"); #[cfg(target_os = "freebsd")] let link_path = format!("/compat/linux/proc/{}/cwd", pid); diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs index f36f71b59c2..02ac50e3773 100644 --- a/alacritty/src/display/content.rs +++ b/alacritty/src/display/content.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::num::NonZeroU32; use std::ops::Deref; use std::{cmp, mem}; @@ -137,8 +138,13 @@ impl<'a> RenderableContent<'a> { text_color = self.config.colors.primary.background; } + let width = if cell.flags.contains(Flags::WIDE_CHAR) { + NonZeroU32::new(2).unwrap() + } else { + NonZeroU32::new(1).unwrap() + }; RenderableCursor { - is_wide: cell.flags.contains(Flags::WIDE_CHAR), + width, shape: self.cursor_shape, point: self.cursor_point, cursor_color, @@ -357,7 +363,7 @@ impl RenderableCell { _ => rgb.into(), }, Color::Named(ansi) => { - match (config.draw_bold_text_with_bright_colors(), flags & Flags::DIM_BOLD) { + match (config.colors.draw_bold_text_with_bright_colors, flags & Flags::DIM_BOLD) { // If no bright foreground is set, treat it like the BOLD flag doesn't exist. (_, Flags::DIM_BOLD) if ansi == NamedColor::Foreground @@ -377,7 +383,7 @@ impl RenderableCell { }, Color::Indexed(idx) => { let idx = match ( - config.draw_bold_text_with_bright_colors(), + config.colors.draw_bold_text_with_bright_colors, flags & Flags::DIM_BOLD, idx, ) { @@ -425,7 +431,7 @@ pub struct RenderableCursor { shape: CursorShape, cursor_color: Rgb, text_color: Rgb, - is_wide: bool, + width: NonZeroU32, point: Point, } @@ -434,15 +440,20 @@ impl RenderableCursor { let shape = CursorShape::Hidden; let cursor_color = Rgb::default(); let text_color = Rgb::default(); - let is_wide = false; + let width = NonZeroU32::new(1).unwrap(); let point = Point::default(); - Self { shape, cursor_color, text_color, is_wide, point } + Self { shape, cursor_color, text_color, width, point } } } impl RenderableCursor { - pub fn new(point: Point, shape: CursorShape, cursor_color: Rgb, is_wide: bool) -> Self { - Self { shape, cursor_color, text_color: cursor_color, is_wide, point } + pub fn new( + point: Point, + shape: CursorShape, + cursor_color: Rgb, + width: NonZeroU32, + ) -> Self { + Self { shape, cursor_color, text_color: cursor_color, width, point } } pub fn color(&self) -> Rgb { @@ -453,8 +464,8 @@ impl RenderableCursor { self.shape } - pub fn is_wide(&self) -> bool { - self.is_wide + pub fn width(&self) -> NonZeroU32 { + self.width } pub fn point(&self) -> Point { diff --git a/alacritty/src/display/cursor.rs b/alacritty/src/display/cursor.rs index ee9d51f21be..ebbf7afb477 100644 --- a/alacritty/src/display/cursor.rs +++ b/alacritty/src/display/cursor.rs @@ -24,9 +24,7 @@ impl IntoRects for RenderableCursor { let thickness = (thickness * width).round().max(1.); - if self.is_wide() { - width *= 2.; - } + width *= self.width().get() as f32; match self.shape() { CursorShape::Beam => beam(x, y, height, thickness, self.color()), diff --git a/alacritty/src/display/damage.rs b/alacritty/src/display/damage.rs index f70cd2f5b1b..62c2f35f833 100644 --- a/alacritty/src/display/damage.rs +++ b/alacritty/src/display/damage.rs @@ -189,6 +189,15 @@ impl FrameDamage { self.lines.push(LineDamageBounds::undamaged(line, num_cols)); } } + + /// Check if a range is damaged. + #[inline] + pub fn intersects(&self, start: Point, end: Point) -> bool { + self.full + || self.lines[start.line].left <= start.column + || self.lines[end.line].right >= end.column + || (start.line + 1..end.line).any(|line| self.lines[line].is_damaged()) + } } /// Convert viewport `y` coordinate to [`Rect`] damage coordinate. diff --git a/alacritty/src/display/hint.rs b/alacritty/src/display/hint.rs index f118dbe090f..a01a1d03cf9 100644 --- a/alacritty/src/display/hint.rs +++ b/alacritty/src/display/hint.rs @@ -183,7 +183,7 @@ impl HintState { /// Update the alphabet used for hint labels. pub fn update_alphabet(&mut self, alphabet: &str) { if self.alphabet != alphabet { - self.alphabet = alphabet.to_owned(); + alphabet.clone_into(&mut self.alphabet); self.keys.clear(); } } diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 1be84e16d2a..288bfa9c2f7 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -29,8 +29,7 @@ use alacritty_terminal::index::{Column, Direction, Line, Point}; use alacritty_terminal::selection::Selection; use alacritty_terminal::term::cell::Flags; use alacritty_terminal::term::{ - self, point_to_viewport, LineDamageBounds, Term, TermDamage, TermMode, MIN_COLUMNS, - MIN_SCREEN_LINES, + self, LineDamageBounds, Term, TermDamage, TermMode, MIN_COLUMNS, MIN_SCREEN_LINES, }; use alacritty_terminal::vte::ansi::{CursorShape, NamedColor}; @@ -270,10 +269,10 @@ impl SizeInfo { padding_right: f32, padding_top: f32, padding_bottom: f32, - dynamic_padding: bool, + _dynamic_padding: bool, ) -> SizeInfo { - let mut padding_x = (padding_left + padding_right) / 2.; - let mut padding_y = (padding_top + padding_bottom) / 2.; + let padding_x = (padding_left + padding_right) / 2.; // TODO: Reintroduce dynamic padding. + let padding_y = (padding_top + padding_bottom) / 2.; // TODO: Reintroduce dynamic padding. // TODO: Reintroduce dynamic padding. // if dynamic_padding { @@ -321,7 +320,7 @@ impl SizeInfo { /// Calculate padding to spread it evenly around the terminal content. #[inline] - fn dynamic_padding(padding: f32, dimension: f32, cell_dimension: f32) -> f32 { + fn _dynamic_padding(padding: f32, dimension: f32, cell_dimension: f32) -> f32 { // TODO: Reintroduce dynamic padding. padding + ((dimension - 2. * padding) % cell_dimension) / 2. } } @@ -806,41 +805,39 @@ impl Display { let vi_cursor_point = if vi_mode { Some(terminal.vi_mode_cursor.point) } else { None }; // Add damage from the terminal. - if self.collect_damage() { - match terminal.damage() { - TermDamage::Full => self.damage_tracker.frame().mark_fully_damaged(), - TermDamage::Partial(damaged_lines) => { - for damage in damaged_lines { - self.damage_tracker.frame().damage_line(damage); - } - }, - } - terminal.reset_damage(); + match terminal.damage() { + TermDamage::Full => self.damage_tracker.frame().mark_fully_damaged(), + TermDamage::Partial(damaged_lines) => { + for damage in damaged_lines { + self.damage_tracker.frame().damage_line(damage); + } + }, } + terminal.reset_damage(); let graphics_queues = terminal.graphics_take_queues(); // Drop terminal as early as possible to free lock. drop(terminal); - // Add damage from alacritty's UI elements overlapping terminal. - if self.collect_damage() { - let requires_full_damage = self.visual_bell.intensity() != 0. - || self.hint_state.active() - || search_state.regex().is_some(); + // Invalidate highlighted hints if grid has changed. + self.validate_hints(display_offset); - if requires_full_damage { - self.damage_tracker.frame().mark_fully_damaged(); - self.damage_tracker.next_frame().mark_fully_damaged(); - } - - let vi_cursor_viewport_point = - vi_cursor_point.and_then(|cursor| point_to_viewport(display_offset, cursor)); + // Add damage from alacritty's UI elements overlapping terminal. - self.damage_tracker.damage_vi_cursor(vi_cursor_viewport_point); - self.damage_tracker.damage_selection(selection_range, display_offset); + let requires_full_damage = self.visual_bell.intensity() != 0. + || self.hint_state.active() + || search_state.regex().is_some(); + if requires_full_damage { + self.damage_tracker.frame().mark_fully_damaged(); + self.damage_tracker.next_frame().mark_fully_damaged(); } + let vi_cursor_viewport_point = + vi_cursor_point.and_then(|cursor| term::point_to_viewport(display_offset, cursor)); + self.damage_tracker.damage_vi_cursor(vi_cursor_viewport_point); + self.damage_tracker.damage_selection(selection_range, display_offset); + // Make sure this window's OpenGL context is active. self.make_current(); @@ -869,42 +866,33 @@ impl Display { let vi_highlighted_hint = &self.vi_highlighted_hint; let damage_tracker = &mut self.damage_tracker; - self.renderer.draw_cells( - &size_info, - glyph_cache, - grid_cells.into_iter().map(|mut cell| { - // Underline hints hovered by mouse or vi mode cursor. - let point = term::viewport_to_point(display_offset, cell.point); + let cells = grid_cells.into_iter().map(|mut cell| { + let mut show_hint = false; - let mut show_hint = false; - - if has_highlighted_hint { - let hyperlink = - cell.extra.as_ref().and_then(|extra| extra.hyperlink.as_ref()); - if highlighted_hint - .as_ref() - .map_or(false, |hint| hint.should_highlight(point, hyperlink)) - || vi_highlighted_hint - .as_ref() - .map_or(false, |hint| hint.should_highlight(point, hyperlink)) - { - show_hint = true; - cell.flags.insert(Flags::UNDERLINE); - // Damage hints for the current and next frames. - damage_tracker.frame().damage_point(cell.point); - damage_tracker.next_frame().damage_point(cell.point); - } + // Underline hints hovered by mouse or vi mode cursor. + if has_highlighted_hint { + let point = term::viewport_to_point(display_offset, cell.point); + let hyperlink = cell.extra.as_ref().and_then(|extra| extra.hyperlink.as_ref()); + + let should_highlight = |hint: &Option| { + hint.as_ref().map_or(false, |hint| hint.should_highlight(point, hyperlink)) + }; + if should_highlight(highlighted_hint) || should_highlight(vi_highlighted_hint) { + show_hint = true; + damage_tracker.frame().damage_point(cell.point); + cell.flags.insert(Flags::UNDERLINE); } + } - // Update underline/strikeout. - lines.update(&cell); + // Update underline/strikeout. + lines.update(&cell); - // Track any graphic present in the cell. - graphics_list.update(&cell, show_hint); + // Track any graphic present in the cell. + graphics_list.update(&cell, show_hint); - cell - }), - ); + cell + }); + self.renderer.draw_cells(&size_info, glyph_cache, cells); } let mut rects = lines.rects(&metrics, &size_info); @@ -961,7 +949,9 @@ impl Display { if self.ime.preedit().is_none() { let fg = config.colors.footer_bar_foreground(); let shape = CursorShape::Underline; - let cursor = RenderableCursor::new(Point::new(line, column), shape, fg, false); + let cursor_width = NonZeroU32::new(1).unwrap(); + let cursor = + RenderableCursor::new(Point::new(line, column), shape, fg, cursor_width); rects.extend(cursor.rects(&size_info, config.cursor.thickness())); } @@ -969,8 +959,11 @@ impl Display { }, None => { let num_lines = self.size_info.screen_lines(); - term::point_to_viewport(display_offset, cursor_point) - .filter(|point| point.line < num_lines) + match vi_cursor_viewport_point { + None => term::point_to_viewport(display_offset, cursor_point) + .filter(|point| point.line < num_lines), + point => point, + } }, }; @@ -1100,10 +1093,17 @@ impl Display { let mut dirty = vi_highlighted_hint != self.vi_highlighted_hint; self.vi_highlighted_hint = vi_highlighted_hint; + // Force full redraw if the vi mode highlight was cleared. + if dirty && self.vi_highlighted_hint.is_none() { + self.damage_tracker.frame().mark_fully_damaged(); + } + // Abort if mouse highlighting conditions are not met. if !mouse.inside_text_area || !term.selection.as_ref().map_or(true, Selection::is_empty) { - dirty |= self.highlighted_hint.is_some(); - self.highlighted_hint = None; + if self.highlighted_hint.take().is_some() { + self.damage_tracker.frame().mark_fully_damaged(); + dirty = true; + } return dirty; } @@ -1127,9 +1127,15 @@ impl Display { } } - dirty |= self.highlighted_hint != highlighted_hint; + let mouse_highlight_dirty = self.highlighted_hint != highlighted_hint; + dirty |= mouse_highlight_dirty; self.highlighted_hint = highlighted_hint; + // Force full redraw if the mouse cursor highlight was cleared. + if mouse_highlight_dirty && self.highlighted_hint.is_none() { + self.damage_tracker.frame().mark_fully_damaged(); + } + dirty } @@ -1155,8 +1161,8 @@ impl Display { // Get the visible preedit. let visible_text: String = match (preedit.cursor_byte_offset, preedit.cursor_end_offset) { - (Some(byte_offset), Some(end_offset)) if end_offset > num_cols => StrShortener::new( - &preedit.text[byte_offset..], + (Some(byte_offset), Some(end_offset)) if end_offset.0 > num_cols => StrShortener::new( + &preedit.text[byte_offset.0..], num_cols, ShortenDirection::Right, Some(SHORTENER), @@ -1188,7 +1194,7 @@ impl Display { ); // Damage preedit inside the terminal viewport. - if self.collect_damage() && point.line < self.size_info.screen_lines() { + if point.line < self.size_info.screen_lines() { let damage = LineDamageBounds::new(start.line, 0, num_cols); self.damage_tracker.frame().damage_line(damage); self.damage_tracker.next_frame().damage_line(damage); @@ -1199,19 +1205,21 @@ impl Display { rects.extend(underline.rects(Flags::UNDERLINE, &metrics, &self.size_info)); let ime_popup_point = match preedit.cursor_end_offset { - Some(cursor_end_offset) if cursor_end_offset != 0 => { - let is_wide = preedit.text[preedit.cursor_byte_offset.unwrap_or_default()..] - .chars() - .next() - .map(|ch| ch.width() == Some(2)) - .unwrap_or_default(); + Some(cursor_end_offset) => { + // Use hollow block when multiple characters are changed at once. + let (shape, width) = if let Some(width) = + NonZeroU32::new((cursor_end_offset.0 - cursor_end_offset.1) as u32) + { + (CursorShape::HollowBlock, width) + } else { + (CursorShape::Beam, NonZeroU32::new(1).unwrap()) + }; let cursor_column = Column( - (end.column.0 as isize - cursor_end_offset as isize + 1).max(0) as usize, + (end.column.0 as isize - cursor_end_offset.0 as isize + 1).max(0) as usize, ); let cursor_point = Point::new(point.line, cursor_column); - let cursor = - RenderableCursor::new(cursor_point, CursorShape::HollowBlock, fg, is_wide); + let cursor = RenderableCursor::new(cursor_point, shape, fg, width); rects.extend(cursor.rects(&self.size_info, config.cursor.thickness())); cursor_point }, @@ -1299,13 +1307,11 @@ impl Display { let bg = config.colors.footer_bar_background(); for (uri, point) in uris.into_iter().zip(uri_lines) { // Damage the uri preview. - if self.collect_damage() { - let damage = LineDamageBounds::new(point.line, point.column.0, num_cols); - self.damage_tracker.frame().damage_line(damage); + let damage = LineDamageBounds::new(point.line, point.column.0, num_cols); + self.damage_tracker.frame().damage_line(damage); - // Damage the uri preview for the next frame as well. - self.damage_tracker.next_frame().damage_line(damage); - } + // Damage the uri preview for the next frame as well. + self.damage_tracker.next_frame().damage_line(damage); self.renderer.draw_string(point, fg, bg, uri, &self.size_info, &mut self.glyph_cache); } @@ -1316,7 +1322,7 @@ impl Display { fn draw_search(&mut self, config: &UiConfig, text: &str) { // Assure text length is at least num_cols. let num_cols = self.size_info.columns(); - let text = format!("{:<1$}", text, num_cols); + let text = format!("{text: bool { - matches!(self.raw_window_handle, RawWindowHandle::Wayland(_)) || self.damage_tracker.debug - } - /// Highlight damaged rects. /// /// This function is for debug purposes only. @@ -1409,6 +1405,34 @@ impl Display { } } + /// Check whether a hint highlight needs to be cleared. + fn validate_hints(&mut self, display_offset: usize) { + let frame = self.damage_tracker.frame(); + for (hint, reset_mouse) in + [(&mut self.highlighted_hint, true), (&mut self.vi_highlighted_hint, false)] + { + let (start, end) = match hint { + Some(hint) => (*hint.bounds().start(), *hint.bounds().end()), + None => return, + }; + + // Convert hint bounds to viewport coordinates. + let start = term::point_to_viewport(display_offset, start).unwrap_or_default(); + let end = term::point_to_viewport(display_offset, end).unwrap_or_else(|| { + Point::new(self.size_info.screen_lines() - 1, self.size_info.last_column()) + }); + + // Clear invalidated hints. + if frame.intersects(start, end) { + if reset_mouse { + self.window.set_mouse_cursor(CursorIcon::Default); + } + frame.mark_fully_damaged(); + *hint = None; + } + } + } + /// Request a new frame for a window on Wayland. fn request_frame(&mut self, scheduler: &mut Scheduler) { // Mark that we've used a frame. @@ -1494,20 +1518,22 @@ pub struct Preedit { /// Byte offset for cursor start into the preedit text. /// /// `None` means that the cursor is invisible. - cursor_byte_offset: Option, + cursor_byte_offset: Option<(usize, usize)>, - /// The cursor offset from the end of the preedit in char width. - cursor_end_offset: Option, + /// The cursor offset from the end of the start of the preedit in char width. + cursor_end_offset: Option<(usize, usize)>, } impl Preedit { - pub fn new(text: String, cursor_byte_offset: Option) -> Self { + pub fn new(text: String, cursor_byte_offset: Option<(usize, usize)>) -> Self { let cursor_end_offset = if let Some(byte_offset) = cursor_byte_offset { // Convert byte offset into char offset. - let cursor_end_offset = - text[byte_offset..].chars().fold(0, |acc, ch| acc + ch.width().unwrap_or(1)); + let start_to_end_offset = + text[byte_offset.0..].chars().fold(0, |acc, ch| acc + ch.width().unwrap_or(1)); + let end_to_end_offset = + text[byte_offset.1..].chars().fold(0, |acc, ch| acc + ch.width().unwrap_or(1)); - Some(cursor_end_offset) + Some((start_to_end_offset, end_to_end_offset)) } else { None }; diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index da5d85bcaac..1427dc75dc4 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -30,7 +30,7 @@ use winit::dpi::{PhysicalPosition, PhysicalSize}; use winit::event_loop::ActiveEventLoop; use winit::monitor::MonitorHandle; #[cfg(windows)] -use winit::platform::windows::IconExtWindows; +use winit::platform::windows::{IconExtWindows, WindowAttributesExtWindows}; use winit::raw_window_handle::{HasWindowHandle, RawWindowHandle}; use winit::window::{ CursorIcon, Fullscreen, ImePurpose, Theme, UserAttentionType, Window as WinitWindow, @@ -76,7 +76,7 @@ impl std::error::Error for Error { impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - Error::WindowCreation(err) => write!(f, "Error creating GL context; {}", err), + Error::WindowCreation(err) => write!(f, "Error creating GL context; {err}"), Error::Font(err) => err.fmt(f), } } @@ -302,7 +302,8 @@ impl Window { WinitWindow::default_attributes() .with_decorations(window_config.decorations != Decorations::None) - .with_window_icon(icon.ok()) + .with_window_icon(icon.as_ref().ok().cloned()) + .with_taskbar_icon(icon.ok()) } #[cfg(target_os = "macos")] diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index f2d615d0040..b391c95cf04 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -1,5 +1,7 @@ //! Process window events. +use crate::ConfigMonitor; +use glutin::config::GetGlConfig; use std::borrow::Cow; use std::cmp::min; use std::collections::{HashMap, HashSet, VecDeque}; @@ -15,7 +17,8 @@ use std::{env, f32, mem}; use ahash::RandomState; use crossfont::Size as FontSize; -use glutin::display::{Display as GlutinDisplay, GetGlDisplay}; +use glutin::config::Config as GlutinConfig; +use glutin::display::GetGlDisplay; use log::{debug, error, info, warn}; use winit::application::ApplicationHandler; use winit::event::{ @@ -33,6 +36,7 @@ use alacritty_terminal::index::{Boundary, Column, Direction, Line, Point, Side}; use alacritty_terminal::selection::{Selection, SelectionType}; use alacritty_terminal::term::search::{Match, RegexSearch}; use alacritty_terminal::term::{self, ClipboardType, Term, TermMode}; +use alacritty_terminal::vte::ansi::NamedColor; #[cfg(unix)] use crate::cli::{IpcConfig, ParsedOptions}; @@ -70,13 +74,15 @@ const TOUCH_ZOOM_FACTOR: f32 = 0.01; /// Stores some state from received events and dispatches actions when they are /// triggered. pub struct Processor { + pub config_monitor: Option, + clipboard: Clipboard, scheduler: Scheduler, initial_window_options: Option, initial_window_error: Option>, windows: HashMap, proxy: EventLoopProxy, - gl_display: Option, + gl_config: Option, #[cfg(unix)] global_ipc_options: ParsedOptions, cli_options: CliOptions, @@ -101,18 +107,29 @@ impl Processor { // which is done in `loop_exiting`. let clipboard = unsafe { Clipboard::new(event_loop.display_handle().unwrap().as_raw()) }; + // Create a config monitor. + // + // The monitor watches the config file for changes and reloads it. Pending + // config changes are processed in the main loop. + let mut config_monitor = None; + if config.live_config_reload() { + config_monitor = + ConfigMonitor::new(config.config_paths.clone(), event_loop.create_proxy()); + } + Processor { initial_window_options, initial_window_error: None, cli_options, proxy, scheduler, - gl_display: None, + gl_config: None, config: Rc::new(config), clipboard, windows: Default::default(), #[cfg(unix)] global_ipc_options: Default::default(), + config_monitor, } } @@ -123,12 +140,16 @@ impl Processor { pub fn create_initial_window( &mut self, event_loop: &ActiveEventLoop, - options: WindowOptions, ) -> Result<(), Box> { + let options = match self.initial_window_options.take() { + Some(options) => options, + None => return Ok(()), + }; + let window_context = WindowContext::initial(event_loop, self.proxy.clone(), self.config.clone(), options)?; - self.gl_display = Some(window_context.display.gl_context().display()); + self.gl_config = Some(window_context.display.gl_context().config()); self.windows.insert(window_context.id(), window_context); Ok(()) @@ -140,7 +161,7 @@ impl Processor { event_loop: &ActiveEventLoop, options: WindowOptions, ) -> Result<(), Box> { - let window = self.windows.iter().next().as_ref().unwrap().1; + let gl_config = self.gl_config.as_ref().unwrap(); // Override config with CLI/IPC options. let mut config_overrides = options.config_overrides(); @@ -149,9 +170,14 @@ impl Processor { let mut config = self.config.clone(); config = config_overrides.override_config_rc(config); - #[allow(unused_mut)] - let mut window_context = - window.additional(event_loop, self.proxy.clone(), config, options, config_overrides)?; + let window_context = WindowContext::additional( + gl_config, + event_loop, + self.proxy.clone(), + config, + options, + config_overrides, + )?; self.windows.insert(window_context.id(), window_context); Ok(()) @@ -160,8 +186,8 @@ impl Processor { /// Run the event loop. /// /// The result is exit code generate from the loop. - pub fn run(mut self, event_loop: EventLoop) -> Result<(), Box> { - let result = event_loop.run_app(&mut self); + pub fn run(&mut self, event_loop: EventLoop) -> Result<(), Box> { + let result = event_loop.run_app(self); if let Some(initial_window_error) = self.initial_window_error.take() { Err(initial_window_error) } else { @@ -195,16 +221,11 @@ impl ApplicationHandler for Processor { fn resumed(&mut self, _event_loop: &ActiveEventLoop) {} fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) { - if cause != StartCause::Init { + if cause != StartCause::Init || self.cli_options.daemon { return; } - let initial_window_options = match self.initial_window_options.take() { - Some(initial_window_options) => initial_window_options, - None => return, - }; - - if let Err(err) = self.create_initial_window(event_loop, initial_window_options) { + if let Err(err) = self.create_initial_window(event_loop) { self.initial_window_error = Some(err); event_loop.exit(); return; @@ -297,6 +318,17 @@ impl ApplicationHandler for Processor { if let Ok(config) = config::reload(path, &mut self.cli_options) { self.config = Rc::new(config); + // Restart config monitor if imports changed. + if let Some(monitor) = self.config_monitor.take() { + let paths = &self.config.config_paths; + self.config_monitor = if monitor.needs_restart(paths) { + monitor.shutdown(); + ConfigMonitor::new(paths.clone(), self.proxy.clone()) + } else { + Some(monitor) + }; + } + for window_context in self.windows.values_mut() { window_context.update_config(self.config.clone()); } @@ -312,7 +344,13 @@ impl ApplicationHandler for Processor { window_context.display.make_not_current(); } - if let Err(err) = self.create_window(event_loop, options.clone()) { + if self.gl_config.is_none() { + // Handle initial window creation in daemon mode. + if let Err(err) = self.create_initial_window(event_loop) { + self.initial_window_error = Some(err); + event_loop.exit(); + } + } else if let Err(err) = self.create_window(event_loop, options.clone()) { error!("Could not open window: {:?}", err); } }, @@ -349,7 +387,7 @@ impl ApplicationHandler for Processor { self.scheduler.unschedule_window(window_context.id()); // Shutdown if no more terminals are open. - if self.windows.is_empty() { + if self.windows.is_empty() && !self.cli_options.daemon { // Write ref tests of last window to disk. if self.config.debug.ref_test { window_context.write_ref_test_results(); @@ -413,7 +451,7 @@ impl ApplicationHandler for Processor { info!("Exiting the event loop"); } - match self.gl_display.take() { + match self.gl_config.take().map(|config| config.display()) { #[cfg(not(target_os = "macos"))] Some(glutin::display::Display::Egl(display)) => { // Ensure that all the windows are dropped, so the destructors for @@ -1192,6 +1230,8 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon for c in text.chars() { self.search_input(c); } + } else if self.inline_search_state.char_pending { + self.inline_search_input(text); } else if bracketed && self.terminal().mode().contains(TermMode::BRACKETED_PASTE) { self.on_terminal_input_start(); @@ -1265,6 +1305,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon self.inline_search_state.stop_short = stop_short; self.inline_search_state.direction = direction; self.inline_search_state.char_pending = true; + self.inline_search_state.character = None; } /// Jump to the next matching character in the line. @@ -1279,6 +1320,22 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon self.inline_search(direction); } + /// Process input during inline search. + fn inline_search_input(&mut self, text: &str) { + // Ignore input with empty text, like modifier keys. + let c = match text.chars().next() { + Some(c) => c, + None => return, + }; + + self.inline_search_state.char_pending = false; + self.inline_search_state.character = Some(c); + self.window().set_ime_allowed(false); + + // Immediately move to the captured character. + self.inline_search_next(); + } + fn message(&self) -> Option<&Message> { self.message_buffer.message() } @@ -1712,9 +1769,12 @@ impl input::Processor> { } }, TerminalEvent::ColorRequest(index, format) => { - let color = self.ctx.terminal().colors()[index] - .map(Rgb) - .unwrap_or(self.ctx.display.colors[index]); + let color = match self.ctx.terminal().colors()[index] { + Some(color) => Rgb(color), + // Ignore cursor color requests unless it was changed. + None if index == NamedColor::Cursor as usize => return, + None => self.ctx.display.colors[index], + }; self.ctx.write_to_pty(format(color.0).into_bytes()); }, TerminalEvent::TextAreaSizeRequest(format) => { @@ -1814,11 +1874,8 @@ impl input::Processor> { self.ctx.update_cursor_blinking(); }, Ime::Preedit(text, cursor_offset) => { - let preedit = if text.is_empty() { - None - } else { - Some(Preedit::new(text, cursor_offset.map(|offset| offset.0))) - }; + let preedit = + (!text.is_empty()).then(|| Preedit::new(text, cursor_offset)); if self.ctx.display.ime.preedit() != preedit.as_ref() { self.ctx.display.ime.set_preedit(preedit); diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs index d63da9f2bd0..147555940bd 100644 --- a/alacritty/src/input/keyboard.rs +++ b/alacritty/src/input/keyboard.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::mem; use winit::event::{ElementState, KeyEvent}; #[cfg(target_os = "macos")] @@ -29,6 +28,9 @@ impl> Processor { let mods = self.ctx.modifiers().state(); if key.state == ElementState::Released { + if self.ctx.inline_search_state().char_pending { + self.ctx.window().set_ime_allowed(true); + } self.key_release(key, mode, mods); return; } @@ -45,15 +47,8 @@ impl> Processor { // First key after inline search is captured. let inline_state = self.ctx.inline_search_state(); - if mem::take(&mut inline_state.char_pending) { - if let Some(c) = text.chars().next() { - inline_state.character = Some(c); - - // Immediately move to the captured character. - self.ctx.inline_search_next(); - } - - // Ignore all other characters in `text`. + if inline_state.char_pending { + self.ctx.inline_search_input(text); return; } @@ -294,7 +289,7 @@ fn build_sequence(key: KeyEvent, mods: ModifiersState, mode: TermMode) -> Vec return Vec::new(), }; - let mut payload = format!("\x1b[{}", payload); + let mut payload = format!("\x1b[{payload}"); // Add modifiers information. if kitty_event_type || !modifiers.is_empty() || associated_text.is_some() { diff --git a/alacritty/src/input/mod.rs b/alacritty/src/input/mod.rs index 8019ee6d433..11eb30fd51c 100644 --- a/alacritty/src/input/mod.rs +++ b/alacritty/src/input/mod.rs @@ -127,6 +127,7 @@ pub trait ActionContext { fn inline_search_state(&mut self) -> &mut InlineSearchState; fn start_inline_search(&mut self, _direction: Direction, _stop_short: bool) {} fn inline_search_next(&mut self) {} + fn inline_search_input(&mut self, _text: &str) {} fn inline_search_previous(&mut self) {} fn hint_input(&mut self, _character: char) {} fn trigger_hint(&mut self, _hint: &HintMatch) {} @@ -809,7 +810,7 @@ impl> Processor { if self.ctx.terminal().mode().contains(TermMode::FOCUS_IN_OUT) { let chr = if is_focused { "I" } else { "O" }; - let msg = format!("\x1b[{}", chr); + let msg = format!("\x1b[{chr}"); self.ctx.write_to_pty(msg.into_bytes()); } } @@ -1329,9 +1330,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::Click, input_delay: Duration::ZERO, @@ -1345,9 +1346,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Right, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::Click, input_delay: Duration::ZERO, @@ -1361,9 +1362,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Middle, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::Click, input_delay: Duration::ZERO, @@ -1377,9 +1378,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::DoubleClick, input_delay: Duration::ZERO, @@ -1393,9 +1394,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::Click, input_delay: CLICK_THRESHOLD, @@ -1409,9 +1410,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::TripleClick, input_delay: Duration::ZERO, @@ -1425,9 +1426,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Left, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::Click, input_delay: CLICK_THRESHOLD, @@ -1441,9 +1442,9 @@ mod tests { event: WindowEvent::MouseInput { state: ElementState::Pressed, button: MouseButton::Right, - device_id: unsafe { DeviceId::dummy() }, + device_id: DeviceId::dummy(), }, - window_id: unsafe { WindowId::dummy() }, + window_id: WindowId::dummy(), }, end_state: ClickState::Click, input_delay: Duration::ZERO, diff --git a/alacritty/src/ipc.rs b/alacritty/src/ipc.rs index 1cb7a1c8378..3d14c4cea52 100644 --- a/alacritty/src/ipc.rs +++ b/alacritty/src/ipc.rs @@ -20,13 +20,13 @@ const ALACRITTY_SOCKET_ENV: &str = "ALACRITTY_SOCKET"; /// Create an IPC socket. pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy) -> Option { - // Create the IPC socket and export its path as env variable if necessary. + // Create the IPC socket and export its path as env. + let socket_path = options.socket.clone().unwrap_or_else(|| { let mut path = socket_dir(); path.push(format!("{}-{}.sock", socket_prefix(), process::id())); path }); - env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str()); let listener = match UnixListener::bind(&socket_path) { Ok(listener) => listener, @@ -36,6 +36,11 @@ pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy) - }, }; + env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str()); + if options.daemon { + println!("ALACRITTY_SOCKET={}; export ALACRITTY_SOCKET", socket_path.display()); + } + // Spawn a thread to listen on the IPC socket. thread::spawn_named("socket listener", move || { let mut data = String::new(); @@ -111,7 +116,7 @@ fn find_socket(socket_path: Option) -> IoResult { if let Some(socket_path) = socket_path { // Ensure we inform the user about an invalid path. return UnixStream::connect(&socket_path).map_err(|err| { - let message = format!("invalid socket path {:?}", socket_path); + let message = format!("invalid socket path {socket_path:?}"); IoError::new(err.kind(), message) }); } diff --git a/alacritty/src/logging.rs b/alacritty/src/logging.rs index 59303649b0a..67cad63e46d 100644 --- a/alacritty/src/logging.rs +++ b/alacritty/src/logging.rs @@ -108,16 +108,16 @@ impl Logger { }; #[cfg(not(windows))] - let env_var = format!("${}", ALACRITTY_LOG_ENV); + let env_var = format!("${ALACRITTY_LOG_ENV}"); #[cfg(windows)] let env_var = format!("%{}%", ALACRITTY_LOG_ENV); let message = format!( - "[{}] See log at {} ({}):\n{}", + "[{}] {}\nSee log at {} ({})", record.level(), + record.args(), logfile_path, env_var, - record.args(), ); let mut message = Message::new(message, message_type); @@ -227,7 +227,7 @@ impl OnDemandLogFile { writeln!(io::stdout(), "Created log file at \"{}\"", self.path.display()); }, Err(e) => { - let _ = writeln!(io::stdout(), "Unable to create log file: {}", e); + let _ = writeln!(io::stdout(), "Unable to create log file: {e}"); return Err(e); }, } diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index 6219dd78e1c..6bbf8dfd5d3 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -172,19 +172,9 @@ fn alacritty(mut options: Options) -> Result<(), Box> { #[cfg(target_os = "macos")] locale::set_locale_environment(); - // Create a config monitor when config was loaded from path. - // - // The monitor watches the config file for changes and reloads it. Pending - // config changes are processed in the main loop. - let mut config_monitor = None; - if config.live_config_reload { - config_monitor = - ConfigMonitor::new(config.config_paths.clone(), window_event_loop.create_proxy()); - } - // Create the IPC socket listener. #[cfg(unix)] - let socket_path = if config.ipc_socket { + let socket_path = if config.ipc_socket() { ipc::spawn_ipc_socket(&options, window_event_loop.create_proxy()) } else { None @@ -199,7 +189,7 @@ fn alacritty(mut options: Options) -> Result<(), Box> { }; // Event processor. - let processor = Processor::new(config, options, &window_event_loop); + let mut processor = Processor::new(config, options, &window_event_loop); // Start event loop and block until shutdown. let result = processor.run(window_event_loop); @@ -219,7 +209,7 @@ fn alacritty(mut options: Options) -> Result<(), Box> { // FIXME: Change PTY API to enforce the correct drop order with the typesystem. // Terminate the config monitor. - if let Some(config_monitor) = config_monitor.take() { + if let Some(config_monitor) = processor.config_monitor.take() { config_monitor.shutdown(); } diff --git a/alacritty/src/migrate.rs b/alacritty/src/migrate.rs deleted file mode 100644 index 6d116858b06..00000000000 --- a/alacritty/src/migrate.rs +++ /dev/null @@ -1,267 +0,0 @@ -//! Configuration file migration. - -use std::fs; -use std::path::Path; - -use toml::map::Entry; -use toml::{Table, Value}; - -use crate::cli::MigrateOptions; -use crate::config; - -/// Handle migration. -pub fn migrate(options: MigrateOptions) { - // Find configuration file path. - let config_path = options - .config_file - .clone() - .or_else(|| config::installed_config("toml")) - .or_else(|| config::installed_config("yml")); - - // Abort if system has no installed configuration. - let config_path = match config_path { - Some(config_path) => config_path, - None => { - eprintln!("No configuration file found"); - std::process::exit(1); - }, - }; - - // If we're doing a wet run, perform a dry run first for safety. - if !options.dry_run { - #[allow(clippy::redundant_clone)] - let mut options = options.clone(); - options.silent = true; - options.dry_run = true; - if let Err(err) = migrate_config(&options, &config_path, config::IMPORT_RECURSION_LIMIT) { - eprintln!("Configuration file migration failed:"); - eprintln!(" {config_path:?}: {err}"); - std::process::exit(1); - } - } - - // Migrate the root config. - match migrate_config(&options, &config_path, config::IMPORT_RECURSION_LIMIT) { - Ok(new_path) => { - if !options.silent { - println!("Successfully migrated {config_path:?} to {new_path:?}"); - } - }, - Err(err) => { - eprintln!("Configuration file migration failed:"); - eprintln!(" {config_path:?}: {err}"); - std::process::exit(1); - }, - } -} - -/// Migrate a specific configuration file. -fn migrate_config( - options: &MigrateOptions, - path: &Path, - recursion_limit: usize, -) -> Result { - // Ensure configuration file has an extension. - let path_str = path.to_string_lossy(); - let (prefix, suffix) = match path_str.rsplit_once('.') { - Some((prefix, suffix)) => (prefix, suffix), - None => return Err("missing file extension".to_string()), - }; - - // Abort if config is already toml. - if suffix == "toml" { - return Err("already in TOML format".to_string()); - } - - // Try to parse the configuration file. - let mut config = match config::deserialize_config(path, !options.dry_run) { - Ok(config) => config, - Err(err) => return Err(format!("parsing error: {err}")), - }; - - // Migrate config imports. - if !options.skip_imports { - migrate_imports(options, &mut config, path, recursion_limit)?; - } - - // Migrate deprecated field names to their new location. - if !options.skip_renames { - migrate_renames(&mut config)?; - } - - // Convert to TOML format. - let toml = toml::to_string(&config).map_err(|err| format!("conversion error: {err}"))?; - let new_path = format!("{prefix}.toml"); - - if options.dry_run && !options.silent { - // Output new content to STDOUT. - println!( - "\nv-----Start TOML for {path:?}-----v\n\n{toml}\n^-----End TOML for {path:?}-----^\n" - ); - } else if !options.dry_run { - // Write the new toml configuration. - fs::write(&new_path, toml).map_err(|err| format!("filesystem error: {err}"))?; - } - - Ok(new_path) -} - -/// Migrate the imports of a config. -fn migrate_imports( - options: &MigrateOptions, - config: &mut Value, - base_path: &Path, - recursion_limit: usize, -) -> Result<(), String> { - let imports = match config::imports(config, base_path, recursion_limit) { - Ok(imports) => imports, - Err(err) => return Err(format!("import error: {err}")), - }; - - // Migrate the individual imports. - let mut new_imports = Vec::new(); - for import in imports { - let import = match import { - Ok(import) => import, - Err(err) => return Err(format!("import error: {err}")), - }; - - // Keep yaml import if path does not exist. - if !import.exists() { - if options.dry_run { - eprintln!("Keeping yaml config for nonexistent import: {import:?}"); - } - new_imports.push(Value::String(import.to_string_lossy().into())); - continue; - } - - let new_path = migrate_config(options, &import, recursion_limit - 1)?; - - // Print new import path. - if options.dry_run { - println!("Successfully migrated import {import:?} to {new_path:?}"); - } - - new_imports.push(Value::String(new_path)); - } - - // Update the imports field. - if let Some(import) = config.get_mut("import") { - *import = Value::Array(new_imports); - } - - Ok(()) -} - -/// Migrate deprecated fields. -fn migrate_renames(config: &mut Value) -> Result<(), String> { - let config_table = match config.as_table_mut() { - Some(config_table) => config_table, - None => return Ok(()), - }; - - // draw_bold_text_with_bright_colors -> colors.draw_bold_text_with_bright_colors - move_value(config_table, &["draw_bold_text_with_bright_colors"], &[ - "colors", - "draw_bold_text_with_bright_colors", - ])?; - - // key_bindings -> keyboard.bindings - move_value(config_table, &["key_bindings"], &["keyboard", "bindings"])?; - - // mouse_bindings -> mouse.bindings - move_value(config_table, &["mouse_bindings"], &["mouse", "bindings"])?; - - Ok(()) -} - -/// Move a toml value from one map to another. -fn move_value(config_table: &mut Table, origin: &[&str], target: &[&str]) -> Result<(), String> { - if let Some(value) = remove_node(config_table, origin)? { - if !insert_node_if_empty(config_table, target, value)? { - return Err(format!( - "conflict: both `{}` and `{}` are set", - origin.join("."), - target.join(".") - )); - } - } - - Ok(()) -} - -/// Remove a node from a tree of tables. -fn remove_node(table: &mut Table, path: &[&str]) -> Result, String> { - if path.len() == 1 { - Ok(table.remove(path[0])) - } else { - let next_table_value = match table.get_mut(path[0]) { - Some(next_table_value) => next_table_value, - None => return Ok(None), - }; - - let next_table = match next_table_value.as_table_mut() { - Some(next_table) => next_table, - None => return Err(format!("invalid `{}` table", path[0])), - }; - - remove_node(next_table, &path[1..]) - } -} - -/// Try to insert a node into a tree of tables. -/// -/// Returns `false` if the node already exists. -fn insert_node_if_empty(table: &mut Table, path: &[&str], node: Value) -> Result { - if path.len() == 1 { - match table.entry(path[0]) { - Entry::Vacant(vacant_entry) => { - vacant_entry.insert(node); - Ok(true) - }, - Entry::Occupied(_) => Ok(false), - } - } else { - let next_table_value = table.entry(path[0]).or_insert_with(|| Value::Table(Table::new())); - - let next_table = match next_table_value.as_table_mut() { - Some(next_table) => next_table, - None => return Err(format!("invalid `{}` table", path[0])), - }; - - insert_node_if_empty(next_table, &path[1..], node) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn move_values() { - let input = r#" -root_value = 3 - -[table] -table_value = 5 - -[preexisting] -not_moved = 9 - "#; - - let mut value: Value = toml::from_str(input).unwrap(); - let table = value.as_table_mut().unwrap(); - - move_value(table, &["root_value"], &["new_table", "root_value"]).unwrap(); - move_value(table, &["table", "table_value"], &["preexisting", "subtable", "new_name"]) - .unwrap(); - - let output = toml::to_string(table).unwrap(); - - assert_eq!( - output, - "[new_table]\nroot_value = 3\n\n[preexisting]\nnot_moved = \ - 9\n\n[preexisting.subtable]\nnew_name = 5\n\n[table]\n" - ); - } -} diff --git a/alacritty/src/migrate/mod.rs b/alacritty/src/migrate/mod.rs new file mode 100644 index 00000000000..2f806d361a1 --- /dev/null +++ b/alacritty/src/migrate/mod.rs @@ -0,0 +1,326 @@ +//! Configuration file migration. + +use std::fmt::Debug; +use std::path::Path; +use std::{fs, mem}; + +use tempfile::NamedTempFile; +use toml_edit::{DocumentMut, Item}; + +use crate::cli::MigrateOptions; +use crate::config; + +mod yaml; + +/// Handle migration. +pub fn migrate(options: MigrateOptions) { + // Find configuration file path. + let config_path = options + .config_file + .clone() + .or_else(|| config::installed_config("toml")) + .or_else(|| config::installed_config("yml")); + + // Abort if system has no installed configuration. + let config_path = match config_path { + Some(config_path) => config_path, + None => { + eprintln!("No configuration file found"); + std::process::exit(1); + }, + }; + + // If we're doing a wet run, perform a dry run first for safety. + if !options.dry_run { + #[allow(clippy::redundant_clone)] + let mut options = options.clone(); + options.silent = true; + options.dry_run = true; + if let Err(err) = migrate_config(&options, &config_path, config::IMPORT_RECURSION_LIMIT) { + eprintln!("Configuration file migration failed:"); + eprintln!(" {config_path:?}: {err}"); + std::process::exit(1); + } + } + + // Migrate the root config. + match migrate_config(&options, &config_path, config::IMPORT_RECURSION_LIMIT) { + Ok(migration) => { + if !options.silent { + println!("{}", migration.success_message(false)); + } + }, + Err(err) => { + eprintln!("Configuration file migration failed:"); + eprintln!(" {config_path:?}: {err}"); + std::process::exit(1); + }, + } +} + +/// Migrate a specific configuration file. +fn migrate_config<'a>( + options: &MigrateOptions, + path: &'a Path, + recursion_limit: usize, +) -> Result, String> { + // Ensure configuration file has an extension. + let path_str = path.to_string_lossy(); + let (prefix, suffix) = match path_str.rsplit_once('.') { + Some((prefix, suffix)) => (prefix, suffix), + None => return Err("missing file extension".to_string()), + }; + + // Handle legacy YAML files. + if suffix == "yml" { + let new_path = yaml::migrate(options, path, recursion_limit, prefix)?; + return Ok(Migration::Yaml((path, new_path))); + } + + // TOML only does renames, so return early if they are disabled. + if options.skip_renames { + if options.dry_run { + eprintln!("Ignoring TOML file {path:?} since `--skip-renames` was supplied"); + } + return Ok(Migration::Toml(path)); + } + + // Read TOML file and perform all in-file migrations. + let toml = fs::read_to_string(path).map_err(|err| format!("{err}"))?; + let mut migrated = migrate_toml(toml)?; + + // Recursively migrate imports. + migrate_imports(options, path, &mut migrated, recursion_limit)?; + + // Write migrated TOML file. + write_results(options, path, &migrated.to_string())?; + + Ok(Migration::Toml(path)) +} + +/// Migrate TOML config to the latest version. +fn migrate_toml(toml: String) -> Result { + // Parse TOML file. + let mut document = match toml.parse::() { + Ok(document) => document, + Err(err) => return Err(format!("TOML parsing error: {err}")), + }; + + // Move `draw_bold_text_with_bright_colors` to its own section. + move_value(&mut document, &["draw_bold_text_with_bright_colors"], &[ + "colors", + "draw_bold_text_with_bright_colors", + ])?; + + // Move bindings to their own section. + move_value(&mut document, &["key_bindings"], &["keyboard", "bindings"])?; + move_value(&mut document, &["mouse_bindings"], &["mouse", "bindings"])?; + + // Avoid warnings due to introduction of the new `general` section. + move_value(&mut document, &["live_config_reload"], &["general", "live_config_reload"])?; + move_value(&mut document, &["working_directory"], &["general", "working_directory"])?; + move_value(&mut document, &["ipc_socket"], &["general", "ipc_socket"])?; + move_value(&mut document, &["import"], &["general", "import"])?; + move_value(&mut document, &["shell"], &["terminal", "shell"])?; + + Ok(document) +} + +/// Migrate TOML imports to the latest version. +fn migrate_imports( + options: &MigrateOptions, + path: &Path, + document: &mut DocumentMut, + recursion_limit: usize, +) -> Result<(), String> { + // Check if any imports need to be processed. + let imports = match document + .get("general") + .and_then(|general| general.get("import")) + .and_then(|import| import.as_array()) + { + Some(array) if !array.is_empty() => array, + _ => return Ok(()), + }; + + // Abort once recursion limit is exceeded. + if recursion_limit == 0 { + return Err("Exceeded maximum configuration import depth".into()); + } + + // Migrate each import. + for import in imports.into_iter().filter_map(|item| item.as_str()) { + let normalized_path = config::normalize_import(path, import); + let migration = migrate_config(options, &normalized_path, recursion_limit)?; + if options.dry_run { + println!("{}", migration.success_message(true)); + } + } + + Ok(()) +} + +/// Move a TOML value from one map to another. +fn move_value(document: &mut DocumentMut, origin: &[&str], target: &[&str]) -> Result<(), String> { + // Find and remove the original item. + let (mut origin_key, mut origin_item) = (None, document.as_item_mut()); + for element in origin { + let table = match origin_item.as_table_like_mut() { + Some(table) => table, + None => panic!("Moving from unsupported TOML structure"), + }; + + let (key, item) = match table.get_key_value_mut(element) { + Some((key, item)) => (key, item), + None => return Ok(()), + }; + + origin_key = Some(key); + origin_item = item; + + // Ensure no empty tables are left behind. + if let Some(table) = origin_item.as_table_mut() { + table.set_implicit(true) + } + } + + let origin_key_decor = + origin_key.map(|key| (key.leaf_decor().clone(), key.dotted_decor().clone())); + let origin_item = mem::replace(origin_item, Item::None); + + // Create all dependencies for the new location. + let mut target_item = document.as_item_mut(); + for (i, element) in target.iter().enumerate() { + let table = match target_item.as_table_like_mut() { + Some(table) => table, + None => panic!("Moving into unsupported TOML structure"), + }; + + if i + 1 == target.len() { + table.insert(element, origin_item); + // Move original key decorations. + if let Some((leaf, dotted)) = origin_key_decor { + let mut key = table.key_mut(element).unwrap(); + *key.leaf_decor_mut() = leaf; + *key.dotted_decor_mut() = dotted; + } + + break; + } else { + // Create missing parent tables. + target_item = target_item[element].or_insert(toml_edit::table()); + } + } + + Ok(()) +} + +/// Write migrated TOML to its target location. +fn write_results

(options: &MigrateOptions, path: P, toml: &str) -> Result<(), String> +where + P: AsRef + Debug, +{ + let path = path.as_ref(); + if options.dry_run && !options.silent { + // Output new content to STDOUT. + println!( + "\nv-----Start TOML for {path:?}-----v\n\n{toml}\n^-----End TOML for {path:?}-----^\n" + ); + } else if !options.dry_run { + // Atomically replace the configuration file. + let tmp = NamedTempFile::new_in(path.parent().unwrap()) + .map_err(|err| format!("could not create temporary file: {err}"))?; + fs::write(tmp.path(), toml).map_err(|err| format!("filesystem error: {err}"))?; + tmp.persist(path).map_err(|err| format!("atomic replacement failed: {err}"))?; + } + Ok(()) +} + +/// Performed migration mode. +enum Migration<'a> { + /// In-place TOML migration. + Toml(&'a Path), + /// YAML to TOML migration. + Yaml((&'a Path, String)), +} + +impl<'a> Migration<'a> { + /// Get the success message for this migration. + fn success_message(&self, import: bool) -> String { + match self { + Self::Yaml((original_path, new_path)) if import => { + format!("Successfully migrated import {original_path:?} to {new_path:?}") + }, + Self::Yaml((original_path, new_path)) => { + format!("Successfully migrated {original_path:?} to {new_path:?}") + }, + Self::Toml(original_path) if import => { + format!("Successfully migrated import {original_path:?}") + }, + Self::Toml(original_path) => format!("Successfully migrated {original_path:?}"), + } + } + + /// Get the file path after migration. + fn new_path(&self) -> String { + match self { + Self::Toml(path) => path.to_string_lossy().into(), + Self::Yaml((_, path)) => path.into(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn move_values() { + let input = r#" +# This is a root_value. +# +# Use it with care. +root_value = 3 + +[table] +table_value = 5 + +[preexisting] +not_moved = 9 + "#; + + let mut document = input.parse::().unwrap(); + + move_value(&mut document, &["root_value"], &["new_table", "root_value"]).unwrap(); + move_value(&mut document, &["table", "table_value"], &[ + "preexisting", + "subtable", + "new_name", + ]) + .unwrap(); + + let output = document.to_string(); + + let expected = r#" +[preexisting] +not_moved = 9 + +[preexisting.subtable] +new_name = 5 + +[new_table] + +# This is a root_value. +# +# Use it with care. +root_value = 3 + "#; + + assert_eq!(output, expected); + } + + #[test] + fn migrate_empty() { + assert!(migrate_toml(String::new()).unwrap().to_string().is_empty()); + } +} diff --git a/alacritty/src/migrate/yaml.rs b/alacritty/src/migrate/yaml.rs new file mode 100644 index 00000000000..9607e95e463 --- /dev/null +++ b/alacritty/src/migrate/yaml.rs @@ -0,0 +1,87 @@ +//! Migration of legacy YAML files to TOML. + +use std::path::Path; + +use toml::Value; + +use crate::cli::MigrateOptions; +use crate::config; +use crate::migrate::{migrate_config, migrate_toml, write_results}; + +/// Migrate a legacy YAML config to TOML. +pub fn migrate( + options: &MigrateOptions, + path: &Path, + recursion_limit: usize, + prefix: &str, +) -> Result { + // Try to parse the configuration file. + let mut config = match config::deserialize_config(path, !options.dry_run) { + Ok(config) => config, + Err(err) => return Err(format!("YAML parsing error: {err}")), + }; + + // Migrate config imports. + if !options.skip_imports { + migrate_imports(options, &mut config, path, recursion_limit)?; + } + + // Convert to TOML format. + let mut toml = toml::to_string(&config).map_err(|err| format!("conversion error: {err}"))?; + let new_path = format!("{prefix}.toml"); + + // Apply TOML migration, without recursing through imports. + toml = migrate_toml(toml)?.to_string(); + + // Write migrated TOML config. + write_results(options, &new_path, &toml)?; + + Ok(new_path) +} + +/// Migrate the imports of a config. +fn migrate_imports( + options: &MigrateOptions, + config: &mut Value, + base_path: &Path, + recursion_limit: usize, +) -> Result<(), String> { + let imports = match config::imports(config, base_path, recursion_limit) { + Ok(imports) => imports, + Err(err) => return Err(format!("import error: {err}")), + }; + + // Migrate the individual imports. + let mut new_imports = Vec::new(); + for import in imports { + let import = match import { + Ok(import) => import, + Err(err) => return Err(format!("import error: {err}")), + }; + + // Keep yaml import if path does not exist. + if !import.exists() { + if options.dry_run { + eprintln!("Keeping yaml config for nonexistent import: {import:?}"); + } + new_imports.push(Value::String(import.to_string_lossy().into())); + continue; + } + + let migration = migrate_config(options, &import, recursion_limit - 1)?; + + // Print success message. + if options.dry_run { + println!("{}", migration.success_message(true)); + } + + new_imports.push(Value::String(migration.new_path())); + } + + // Update the imports field. + if let Some(import) = config.get_mut("import") { + *import = Value::Array(new_imports); + } + + Ok(()) +} diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 98285a02bc6..71dcd96d6ec 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -69,10 +69,10 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::Shader(err) => { - write!(f, "There was an error initializing the shaders: {}", err) + write!(f, "There was an error initializing the shaders: {err}") }, Error::Other(err) => { - write!(f, "{}", err) + write!(f, "{err}") }, } } @@ -115,9 +115,9 @@ fn gl_get_string( Ok(CStr::from_ptr(string_ptr as *const _).to_string_lossy()) }, gl::INVALID_ENUM => { - Err(format!("OpenGL error requesting {}: invalid enum", description).into()) + Err(format!("OpenGL error requesting {description}: invalid enum").into()) }, - error_id => Err(format!("OpenGL error {} requesting {}", error_id, description).into()), + error_id => Err(format!("OpenGL error {error_id} requesting {description}").into()), } } } diff --git a/alacritty/src/renderer/shader.rs b/alacritty/src/renderer/shader.rs index e3baab9e768..86938e4526c 100644 --- a/alacritty/src/renderer/shader.rs +++ b/alacritty/src/renderer/shader.rs @@ -196,9 +196,9 @@ impl std::error::Error for ShaderError {} impl fmt::Display for ShaderError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::Compile(reason) => write!(f, "Failed compiling shader: {}", reason), - Self::Link(reason) => write!(f, "Failed linking shader: {}", reason), - Self::Uniform(name) => write!(f, "Failed to get uniform location of {:?}", name), + Self::Compile(reason) => write!(f, "Failed compiling shader: {reason}"), + Self::Link(reason) => write!(f, "Failed linking shader: {reason}"), + Self::Uniform(name) => write!(f, "Failed to get uniform location of {name:?}"), } } } diff --git a/alacritty/src/string.rs b/alacritty/src/string.rs index e41b078578d..a7af439465d 100644 --- a/alacritty/src/string.rs +++ b/alacritty/src/string.rs @@ -51,6 +51,7 @@ impl<'a> StrShortener<'a> { if direction == ShortenDirection::Right { return Self { + #[allow(clippy::iter_skip_zero)] chars: text.chars().skip(0), accumulated_len: 0, text_action: TextAction::Char, diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index 062f9ef0cd7..cfc3cd9645d 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -9,7 +9,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use std::rc::Rc; use std::sync::Arc; -use glutin::config::GetGlConfig; +use glutin::config::Config as GlutinConfig; use glutin::display::GetGlDisplay; #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] use glutin::platform::x11::X11GlConfigExt; @@ -119,18 +119,14 @@ impl WindowContext { /// Create additional context with the graphics platform other windows are using. pub fn additional( - &self, + gl_config: &GlutinConfig, event_loop: &ActiveEventLoop, proxy: EventLoopProxy, config: Rc, options: WindowOptions, config_overrides: ParsedOptions, ) -> Result> { - // Get any window and take its GL config and display to build a new context. - let (gl_display, gl_config) = { - let gl_context = self.display.gl_context(); - (gl_context.display(), gl_context.config()) - }; + let gl_display = gl_config.display(); let mut identity = config.window.identity.clone(); options.window_identity.override_identity_config(&mut identity); @@ -147,11 +143,8 @@ impl WindowContext { // Create context. let raw_window_handle = window.raw_window_handle(); - let gl_context = renderer::platform::create_gl_context( - &gl_display, - &gl_config, - Some(raw_window_handle), - )?; + let gl_context = + renderer::platform::create_gl_context(&gl_display, gl_config, Some(raw_window_handle))?; // Check if new window will be opened as a tab. #[cfg(target_os = "macos")] diff --git a/alacritty/windows/wix/alacritty.wxs b/alacritty/windows/wix/alacritty.wxs index cd64ec7ba3e..cd00bda0bcd 100644 --- a/alacritty/windows/wix/alacritty.wxs +++ b/alacritty/windows/wix/alacritty.wxs @@ -1,5 +1,5 @@ - + diff --git a/alacritty_config/Cargo.toml b/alacritty_config/Cargo.toml index c09a05e2b7b..862c6eb875f 100644 --- a/alacritty_config/Cargo.toml +++ b/alacritty_config/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "alacritty_config" -version = "0.2.1-dev" +version = "0.2.2" authors = ["Christian Duerr "] 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.70.0" +rust-version = "1.74.0" [dependencies] log = { version = "0.4.17", features = ["serde"] } @@ -15,5 +15,5 @@ serde = "1.0.163" toml = "0.8.2" [dev-dependencies] -alacritty_config_derive = { version = "0.2.3-dev", path = "../alacritty_config_derive" } +alacritty_config_derive = { version = "0.2.4", path = "../alacritty_config_derive" } serde = { version = "1.0.163", features = ["derive"] } diff --git a/alacritty_config_derive/Cargo.toml b/alacritty_config_derive/Cargo.toml index dce132379b8..bf439ce75d1 100644 --- a/alacritty_config_derive/Cargo.toml +++ b/alacritty_config_derive/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "alacritty_config_derive" -version = "0.2.3-dev" +version = "0.2.4" authors = ["Christian Duerr "] 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.70.0" +rust-version = "1.74.0" [lib] proc-macro = true @@ -19,7 +19,7 @@ syn = { version = "2.0.16", features = ["derive", "parsing", "proc-macro", "prin [dev-dependencies.alacritty_config] path = "../alacritty_config" -version = "0.2.1-dev" +version = "0.2.2" [dev-dependencies] log = "0.4.11" diff --git a/alacritty_config_derive/src/config_deserialize/de_struct.rs b/alacritty_config_derive/src/config_deserialize/de_struct.rs index d2a7dd82af4..ad38863ed4c 100644 --- a/alacritty_config_derive/src/config_deserialize/de_struct.rs +++ b/alacritty_config_derive/src/config_deserialize/de_struct.rs @@ -155,6 +155,7 @@ fn field_deserializer(field_streams: &mut FieldStreams, field: &Field) -> Result if let Some(warning) = parsed.param { message = format!("{}; {}", message, warning.value()); } + message.push_str("\nUse `alacritty migrate` to automatically resolve it"); // Append stream to log deprecation/removal warning. match_assignment_stream.extend(quote! { diff --git a/alacritty_config_derive/src/serde_replace.rs b/alacritty_config_derive/src/serde_replace.rs index ddd0cf75767..cd56b3bcc95 100644 --- a/alacritty_config_derive/src/serde_replace.rs +++ b/alacritty_config_derive/src/serde_replace.rs @@ -112,11 +112,11 @@ fn match_arms(fields: &Punctuated) -> Result = OnceLock::new(); + let logger = LOGGER.get_or_init(Logger::default); log::set_logger(logger).unwrap(); log::set_max_level(log::LevelFilter::Warn); @@ -134,15 +132,16 @@ fn config_deserialize() { ]); let warn_logs = logger.warn_logs.lock().unwrap(); assert_eq!(warn_logs.as_slice(), [ - "Config warning: field1 has been deprecated; use field2 instead", - "Config warning: enom_error has been deprecated", - "Config warning: gone has been removed; it's gone", + "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: gone has been removed; it's gone\nUse `alacritty migrate` to \ + automatically resolve it", "Unused config key: field3", ]); } -static mut LOGGER: Option = None; - /// Logger storing all messages for later validation. #[derive(Default)] struct Logger { diff --git a/alacritty_terminal/CHANGELOG.md b/alacritty_terminal/CHANGELOG.md index 82636168706..e612e7498ec 100644 --- a/alacritty_terminal/CHANGELOG.md +++ b/alacritty_terminal/CHANGELOG.md @@ -8,7 +8,19 @@ sections should follow the order `Added`, `Changed`, `Deprecated`, `Fixed` and The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## 0.24.1-dev +## 0.24.1 + +### Changed + +- Shell RCs are no longer sourced on macOs + +### Fixed + +- Semantic search handling of fullwidth characters +- Inline search ignoring line wrapping flag +- Clearing of `XDG_ACTIVATION_TOKEN` and `DESKTOP_STARTUP_ID` in the main process +- FD leaks when closing PTYs on Unix +- Crash when ConPTY creation failed ## 0.24.0 diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 98c641710e1..b8c0db4c2b2 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alacritty_terminal" -version = "0.24.1-dev" +version = "0.24.1" authors = ["Christian Duerr ", "Joe Wilm "] license = "Apache-2.0" description = "Library for writing terminal emulators" @@ -8,7 +8,7 @@ readme = "../README.md" homepage = "https://alacritty.org" repository = "https://github.com/alacritty/alacritty" edition = "2021" -rust-version = "1.70.0" +rust-version = "1.74.0" [features] default = ["serde"] diff --git a/alacritty_terminal/src/grid/mod.rs b/alacritty_terminal/src/grid/mod.rs index 43302354b41..8c913de83c8 100644 --- a/alacritty_terminal/src/grid/mod.rs +++ b/alacritty_terminal/src/grid/mod.rs @@ -137,7 +137,7 @@ pub struct Grid { max_scroll_limit: usize, } -impl Grid { +impl Grid { pub fn new(lines: usize, columns: usize, max_scroll_limit: usize) -> Grid { Grid { raw: Storage::with_capacity(lines, columns), @@ -356,7 +356,7 @@ impl Grid { /// Reset a visible region within the grid. pub fn reset_region>(&mut self, bounds: R) where - T: ResetDiscriminant + GridCell + Clone + Default, + T: ResetDiscriminant + GridCell + Default, D: PartialEq, { let start = match bounds.start_bound() { @@ -392,7 +392,7 @@ impl Grid { #[inline] pub fn initialize_all(&mut self) where - T: GridCell + Clone + Default, + T: GridCell + Default, { // Remove all cached lines to clear them of any content. self.truncate(); diff --git a/alacritty_terminal/src/grid/resize.rs b/alacritty_terminal/src/grid/resize.rs index 92ee55d77db..751abae1b82 100644 --- a/alacritty_terminal/src/grid/resize.rs +++ b/alacritty_terminal/src/grid/resize.rs @@ -9,7 +9,7 @@ use crate::term::cell::{Flags, ResetDiscriminant}; use crate::grid::row::Row; use crate::grid::{Dimensions, Grid, GridCell}; -impl Grid { +impl Grid { /// Resize the grid's width and/or height. pub fn resize(&mut self, reflow: bool, lines: usize, columns: usize) where diff --git a/alacritty_terminal/src/grid/row.rs b/alacritty_terminal/src/grid/row.rs index 72f386ae282..9a7f81fb388 100644 --- a/alacritty_terminal/src/grid/row.rs +++ b/alacritty_terminal/src/grid/row.rs @@ -30,7 +30,7 @@ impl PartialEq for Row { } } -impl Row { +impl Row { /// Create a new terminal row. /// /// Ideally the `template` should be `Copy` in all performance sensitive scenarios. diff --git a/alacritty_terminal/src/grid/storage.rs b/alacritty_terminal/src/grid/storage.rs index 0a2be43b71a..abf5710347e 100644 --- a/alacritty_terminal/src/grid/storage.rs +++ b/alacritty_terminal/src/grid/storage.rs @@ -66,7 +66,7 @@ impl Storage { #[inline] pub fn with_capacity(visible_lines: usize, columns: usize) -> Storage where - T: Clone + Default, + T: Default, { // Initialize visible lines; the scrollback buffer is initialized dynamically. let mut inner = Vec::with_capacity(visible_lines); @@ -79,7 +79,7 @@ impl Storage { #[inline] pub fn grow_visible_lines(&mut self, next: usize) where - T: Clone + Default, + T: Default, { // Number of lines the buffer needs to grow. let additional_lines = next - self.visible_lines; @@ -125,7 +125,7 @@ impl Storage { #[inline] pub fn initialize(&mut self, additional_rows: usize, columns: usize) where - T: Clone + Default, + T: Default, { if self.len + additional_rows > self.inner.len() { self.rezero(); diff --git a/alacritty_terminal/src/term/cell.rs b/alacritty_terminal/src/term/cell.rs index 6b32c781abe..c91ef2f1f38 100644 --- a/alacritty_terminal/src/term/cell.rs +++ b/alacritty_terminal/src/term/cell.rs @@ -126,9 +126,7 @@ impl ResetDiscriminant for Cell { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct CellExtra { zerowidth: Vec, - underline_color: Option, - hyperlink: Option, #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 706bbe3244d..6b0ccccdf98 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -57,30 +57,30 @@ bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TermMode: u32 { const NONE = 0; - const SHOW_CURSOR = 0b0000_0000_0000_0000_0000_0001; - const APP_CURSOR = 0b0000_0000_0000_0000_0000_0010; - const APP_KEYPAD = 0b0000_0000_0000_0000_0000_0100; - const MOUSE_REPORT_CLICK = 0b0000_0000_0000_0000_0000_1000; - const BRACKETED_PASTE = 0b0000_0000_0000_0000_0001_0000; - const SGR_MOUSE = 0b0000_0000_0000_0000_0010_0000; - const MOUSE_MOTION = 0b0000_0000_0000_0000_0100_0000; - const LINE_WRAP = 0b0000_0000_0000_0000_1000_0000; - const LINE_FEED_NEW_LINE = 0b0000_0000_0000_0001_0000_0000; - const ORIGIN = 0b0000_0000_0000_0010_0000_0000; - const INSERT = 0b0000_0000_0000_0100_0000_0000; - const FOCUS_IN_OUT = 0b0000_0000_0000_1000_0000_0000; - const ALT_SCREEN = 0b0000_0000_0001_0000_0000_0000; - const MOUSE_DRAG = 0b0000_0000_0010_0000_0000_0000; - const MOUSE_MODE = 0b0000_0000_0010_0000_0100_1000; - const UTF8_MOUSE = 0b0000_0000_0100_0000_0000_0000; - const ALTERNATE_SCROLL = 0b0000_0000_1000_0000_0000_0000; - const VI = 0b0000_0001_0000_0000_0000_0000; - const URGENCY_HINTS = 0b0000_0010_0000_0000_0000_0000; - const DISAMBIGUATE_ESC_CODES = 0b0000_0100_0000_0000_0000_0000; - const REPORT_EVENT_TYPES = 0b0000_1000_0000_0000_0000_0000; - const REPORT_ALTERNATE_KEYS = 0b0001_0000_0000_0000_0000_0000; - const REPORT_ALL_KEYS_AS_ESC = 0b0010_0000_0000_0000_0000_0000; - const REPORT_ASSOCIATED_TEXT = 0b0100_0000_0000_0000_0000_0000; + const SHOW_CURSOR = 1; + const APP_CURSOR = 1 << 1; + const APP_KEYPAD = 1 << 2; + const MOUSE_REPORT_CLICK = 1 << 3; + const BRACKETED_PASTE = 1 << 4; + const SGR_MOUSE = 1 << 5; + const MOUSE_MOTION = 1 << 6; + const LINE_WRAP = 1 << 7; + const LINE_FEED_NEW_LINE = 1 << 8; + const ORIGIN = 1 << 9; + const INSERT = 1 << 10; + const FOCUS_IN_OUT = 1 << 11; + const ALT_SCREEN = 1 << 12; + const MOUSE_DRAG = 1 << 13; + const UTF8_MOUSE = 1 << 14; + const ALTERNATE_SCROLL = 1 << 15; + const VI = 1 << 16; + const URGENCY_HINTS = 1 << 17; + const DISAMBIGUATE_ESC_CODES = 1 << 18; + const REPORT_EVENT_TYPES = 1 << 19; + const REPORT_ALTERNATE_KEYS = 1 << 20; + const REPORT_ALL_KEYS_AS_ESC = 1 << 21; + const REPORT_ASSOCIATED_TEXT = 1 << 22; + const MOUSE_MODE = Self::MOUSE_REPORT_CLICK.bits() | Self::MOUSE_MOTION.bits() | Self::MOUSE_DRAG.bits(); const KITTY_KEYBOARD_PROTOCOL = Self::DISAMBIGUATE_ESC_CODES.bits() | Self::REPORT_EVENT_TYPES.bits() | Self::REPORT_ALTERNATE_KEYS.bits() diff --git a/alacritty_terminal/src/term/search.rs b/alacritty_terminal/src/term/search.rs index a5ae9337a96..33f6ee056b5 100644 --- a/alacritty_terminal/src/term/search.rs +++ b/alacritty_terminal/src/term/search.rs @@ -516,7 +516,14 @@ impl Term { #[must_use] pub fn semantic_search_left(&self, point: Point) -> Point { match self.inline_search_left(point, self.semantic_escape_chars()) { - Ok(point) => self.grid.iter_from(point).next().map_or(point, |cell| cell.point), + // If we found a match, reverse for at least one cell, skipping over wide cell spacers. + Ok(point) => { + let wide_spacer = Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER; + self.grid + .iter_from(point) + .find(|cell| !cell.flags.intersects(wide_spacer)) + .map_or(point, |cell| cell.point) + }, Err(point) => point, } } @@ -538,7 +545,7 @@ impl Term { let mut iter = self.grid.iter_from(point); let last_column = self.columns() - 1; - let wide = Flags::WIDE_CHAR | Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER; + let wide_spacer = Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER; while let Some(cell) = iter.prev() { if cell.point.column == last_column && !cell.flags.contains(Flags::WRAPLINE) { break; @@ -546,7 +553,7 @@ impl Term { point = cell.point; - if !cell.flags.intersects(wide) && needles.contains(cell.c) { + if !cell.flags.intersects(wide_spacer) && needles.contains(cell.c) { return Ok(point); } } @@ -559,7 +566,7 @@ impl Term { // Limit the starting point to the last line in the history point.line = max(point.line, self.topmost_line()); - let wide = Flags::WIDE_CHAR | Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER; + let wide_spacer = Flags::WIDE_CHAR_SPACER | Flags::LEADING_WIDE_CHAR_SPACER; let last_column = self.columns() - 1; // Immediately stop if start point in on line break. @@ -570,7 +577,7 @@ impl Term { for cell in self.grid.iter_from(point) { point = cell.point; - if !cell.flags.intersects(wide) && needles.contains(cell.c) { + if !cell.flags.intersects(wide_spacer) && needles.contains(cell.c) { return Ok(point); } @@ -1171,4 +1178,16 @@ mod tests { let match_end = Point::new(Line(1), Column(2)); assert_eq!(term.regex_search_left(&mut regex, start, end), Some(match_start..=match_end)); } + + #[test] + fn fullwidth_semantic() { + #[rustfmt::skip] + let mut term = mock_term("test-x-test"); + term.config.semantic_escape_chars = "-".into(); + + let start = term.semantic_search_left(Point::new(Line(0), Column(6))); + let end = term.semantic_search_right(Point::new(Line(0), Column(6))); + assert_eq!(start, Point::new(Line(0), Column(6))); + assert_eq!(end, Point::new(Line(0), Column(6))); + } } diff --git a/alacritty_terminal/src/tty/mod.rs b/alacritty_terminal/src/tty/mod.rs index 55d263ca5b1..eed2a76dc28 100644 --- a/alacritty_terminal/src/tty/mod.rs +++ b/alacritty_terminal/src/tty/mod.rs @@ -50,9 +50,10 @@ impl Shell { } } -/// This trait defines the behaviour needed to read and/or write to a stream. -/// It defines an abstraction over polling's interface in order to allow either one -/// read/write object or a separate read and write object. +/// Stream read and/or write behavior. +/// +/// This defines an abstraction over polling's interface in order to allow either +/// one read/write object or a separate read and write object. pub trait EventedReadWrite { type Reader: io::Read; type Writer: io::Write; @@ -97,10 +98,6 @@ pub fn setup_env() { // Advertise 24-bit color support. env::set_var("COLORTERM", "truecolor"); - - // Prevent child processes from inheriting startup notification env. - env::remove_var("DESKTOP_STARTUP_ID"); - env::remove_var("XDG_ACTIVATION_TOKEN"); } /// 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 8084a753b23..6565f20b8d9 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -227,6 +227,10 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd builder.env(key, value); } + // Prevent child processes from inheriting linux-specific startup notification env. + builder.env_remove("XDG_ACTIVATION_TOKEN"); + builder.env_remove("DESKTOP_STARTUP_ID"); + unsafe { builder.pre_exec(move || { // Create a new process group. diff --git a/alacritty_terminal/src/tty/windows/conpty.rs b/alacritty_terminal/src/tty/windows/conpty.rs index 244681e7c9f..28289f90e11 100644 --- a/alacritty_terminal/src/tty/windows/conpty.rs +++ b/alacritty_terminal/src/tty/windows/conpty.rs @@ -1,7 +1,7 @@ use log::{info, warn}; use std::collections::{HashMap, HashSet}; use std::ffi::OsStr; -use std::io::Error; +use std::io::{Error, Result}; use std::os::windows::ffi::OsStrExt; use std::os::windows::io::IntoRawHandle; use std::{mem, ptr}; @@ -107,7 +107,7 @@ impl Drop for Conpty { // The ConPTY handle can be sent between threads. unsafe impl Send for Conpty {} -pub fn new(config: &Options, window_size: WindowSize) -> Option { +pub fn new(config: &Options, window_size: WindowSize) -> Result { let api = ConptyApi::new(); let mut pty_handle: HPCON = 0; @@ -115,8 +115,8 @@ pub fn new(config: &Options, window_size: WindowSize) -> Option { // size to be used. There may be small performance and memory advantages // to be gained by tuning this in the future, but it's likely a reasonable // start point. - let (conout, conout_pty_handle) = miow::pipe::anonymous(0).unwrap(); - let (conin_pty_handle, conin) = miow::pipe::anonymous(0).unwrap(); + let (conout, conout_pty_handle) = miow::pipe::anonymous(0)?; + let (conin_pty_handle, conin) = miow::pipe::anonymous(0)?; // Create the Pseudo Console, using the pipes. let result = unsafe { @@ -154,7 +154,7 @@ pub fn new(config: &Options, window_size: WindowSize) -> Option { // This call was expected to return false. if failure { - panic_shell_spawn(); + return Err(Error::last_os_error()); } } @@ -180,7 +180,7 @@ pub fn new(config: &Options, window_size: WindowSize) -> Option { ) > 0; if !success { - panic_shell_spawn(); + return Err(Error::last_os_error()); } } @@ -197,7 +197,7 @@ pub fn new(config: &Options, window_size: WindowSize) -> Option { ) > 0; if !success { - panic_shell_spawn(); + return Err(Error::last_os_error()); } } @@ -230,17 +230,17 @@ pub fn new(config: &Options, window_size: WindowSize) -> Option { ) > 0; if !success { - panic_shell_spawn(); + return Err(Error::last_os_error()); } } let conin = UnblockedWriter::new(conin, PIPE_CAPACITY); let conout = UnblockedReader::new(conout, PIPE_CAPACITY); - let child_watcher = ChildExitWatcher::new(proc_info.hProcess).unwrap(); + let child_watcher = ChildExitWatcher::new(proc_info.hProcess)?; let conpty = Conpty { handle: pty_handle as HPCON, api }; - Some(Pty::new(conpty, conout, conin, child_watcher)) + Ok(Pty::new(conpty, conout, conin, child_watcher)) } // Windows environment variables are case-insensitive, and the caller is responsible for @@ -300,11 +300,6 @@ fn add_windows_env_key_value_to_block(block: &mut Vec, key: &OsStr, value: block.push(0); } -// Panic with the last os error as message. -fn panic_shell_spawn() { - panic!("Unable to spawn shell: {}", Error::last_os_error()); -} - impl OnResize for Conpty { fn on_resize(&mut self, window_size: WindowSize) { let result = unsafe { (self.api.resize)(self.handle, window_size.into()) }; diff --git a/alacritty_terminal/src/tty/windows/mod.rs b/alacritty_terminal/src/tty/windows/mod.rs index 6af162c83df..32e24677013 100644 --- a/alacritty_terminal/src/tty/windows/mod.rs +++ b/alacritty_terminal/src/tty/windows/mod.rs @@ -1,5 +1,5 @@ use std::ffi::OsStr; -use std::io::{self, Error, ErrorKind, Result}; +use std::io::{self, Result}; use std::iter::once; use std::os::windows::ffi::OsStrExt; use std::sync::mpsc::TryRecvError; @@ -35,7 +35,6 @@ pub struct Pty { pub fn new(config: &Options, window_size: WindowSize, _window_id: u64) -> Result { conpty::new(config, window_size) - .ok_or_else(|| Error::new(ErrorKind::Other, "failed to spawn conpty")) } impl Pty { diff --git a/extra/completions/_alacritty b/extra/completions/_alacritty index a510fb15f6f..0ccce66fbc0 100644 --- a/extra/completions/_alacritty +++ b/extra/completions/_alacritty @@ -14,7 +14,7 @@ _alacritty() { fi local context curcontext="$curcontext" state line - _arguments "${_arguments_options[@]}" \ + _arguments "${_arguments_options[@]}" : \ '--embed=[X11 window ID to embed Alacritty within (decimal or hexadecimal with "0x" prefix)]:EMBED: ' \ '--config-file=[Specify alternative configuration file \[default\: \$XDG_CONFIG_HOME/alacritty/alacritty.toml\]]:CONFIG_FILE:_files' \ '--socket=[Path for IPC socket creation]:SOCKET:_files' \ @@ -27,9 +27,10 @@ _alacritty() { '*-o+[Override configuration file options \[example\: '\''cursor.style="Beam"'\''\]]:OPTION: ' \ '*--option=[Override configuration file options \[example\: '\''cursor.style="Beam"'\''\]]:OPTION: ' \ '--print-events[Print all events to STDOUT]' \ -'--ref-test[Generates ref test]' \ +'(--daemon)--ref-test[Generates ref test]' \ '(-v)*-q[Reduces the level of verbosity (the min level is -qq)]' \ '(-q)*-v[Increases the level of verbosity (the max level is -vvv)]' \ +'--daemon[Do not spawn an initial window]' \ '--hold[Remain open after child process exit]' \ '-h[Print help]' \ '--help[Print help]' \ @@ -45,7 +46,7 @@ _alacritty() { curcontext="${curcontext%:*:*}:alacritty-command-$line[1]:" case $line[1] in (msg) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-s+[IPC socket connection path override]:SOCKET:_files' \ '--socket=[IPC socket connection path override]:SOCKET:_files' \ '-h[Print help]' \ @@ -61,7 +62,7 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:alacritty-msg-command-$line[1]:" case $line[1] in (create-window) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '--working-directory=[Start the shell in the specified working directory]:WORKING_DIRECTORY:_files' \ '*-e+[Command and args to execute (must be last argument)]:COMMAND: ' \ '*--command=[Command and args to execute (must be last argument)]:COMMAND: ' \ @@ -76,7 +77,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-w+[Window ID for the new config]:WINDOW_ID: ' \ '--window-id=[Window ID for the new config]:WINDOW_ID: ' \ '()-r[Clear all runtime configuration changes]' \ @@ -87,7 +88,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_alacritty__msg__help_commands" \ "*::: :->help" \ && ret=0 @@ -99,15 +100,15 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:alacritty-msg-help-command-$line[1]:" case $line[1] in (create-window) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -119,7 +120,7 @@ esac esac ;; (migrate) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-c+[Path to the configuration file]:CONFIG_FILE:_files' \ '--config-file=[Path to the configuration file]:CONFIG_FILE:_files' \ '-d[Only output TOML config to STDOUT]' \ @@ -134,7 +135,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_alacritty__help_commands" \ "*::: :->help" \ && ret=0 @@ -146,7 +147,7 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:alacritty-help-command-$line[1]:" case $line[1] in (msg) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_alacritty__help__msg_commands" \ "*::: :->msg" \ && ret=0 @@ -158,11 +159,11 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:alacritty-help-msg-command-$line[1]:" case $line[1] in (create-window) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -170,11 +171,11 @@ _arguments "${_arguments_options[@]}" \ esac ;; (migrate) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -195,36 +196,6 @@ _alacritty_commands() { ) _describe -t commands 'alacritty commands' commands "$@" } -(( $+functions[_alacritty__help__msg__config_commands] )) || -_alacritty__help__msg__config_commands() { - local commands; commands=() - _describe -t commands 'alacritty help msg config commands' commands "$@" -} -(( $+functions[_alacritty__msg__config_commands] )) || -_alacritty__msg__config_commands() { - local commands; commands=() - _describe -t commands 'alacritty msg config commands' commands "$@" -} -(( $+functions[_alacritty__msg__help__config_commands] )) || -_alacritty__msg__help__config_commands() { - local commands; commands=() - _describe -t commands 'alacritty msg help config commands' commands "$@" -} -(( $+functions[_alacritty__help__msg__create-window_commands] )) || -_alacritty__help__msg__create-window_commands() { - local commands; commands=() - _describe -t commands 'alacritty help msg create-window commands' commands "$@" -} -(( $+functions[_alacritty__msg__create-window_commands] )) || -_alacritty__msg__create-window_commands() { - local commands; commands=() - _describe -t commands 'alacritty msg create-window commands' commands "$@" -} -(( $+functions[_alacritty__msg__help__create-window_commands] )) || -_alacritty__msg__help__create-window_commands() { - local commands; commands=() - _describe -t commands 'alacritty msg help create-window commands' commands "$@" -} (( $+functions[_alacritty__help_commands] )) || _alacritty__help_commands() { local commands; commands=( @@ -239,46 +210,76 @@ _alacritty__help__help_commands() { local commands; commands=() _describe -t commands 'alacritty help help commands' commands "$@" } -(( $+functions[_alacritty__msg__help_commands] )) || -_alacritty__msg__help_commands() { +(( $+functions[_alacritty__help__migrate_commands] )) || +_alacritty__help__migrate_commands() { + local commands; commands=() + _describe -t commands 'alacritty help migrate commands' commands "$@" +} +(( $+functions[_alacritty__help__msg_commands] )) || +_alacritty__help__msg_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ -'help:Print this message or the help of the given subcommand(s)' \ ) - _describe -t commands 'alacritty msg help commands' commands "$@" + _describe -t commands 'alacritty help msg commands' commands "$@" } -(( $+functions[_alacritty__msg__help__help_commands] )) || -_alacritty__msg__help__help_commands() { +(( $+functions[_alacritty__help__msg__config_commands] )) || +_alacritty__help__msg__config_commands() { local commands; commands=() - _describe -t commands 'alacritty msg help help commands' commands "$@" + _describe -t commands 'alacritty help msg config commands' commands "$@" } -(( $+functions[_alacritty__help__migrate_commands] )) || -_alacritty__help__migrate_commands() { +(( $+functions[_alacritty__help__msg__create-window_commands] )) || +_alacritty__help__msg__create-window_commands() { local commands; commands=() - _describe -t commands 'alacritty help migrate commands' commands "$@" + _describe -t commands 'alacritty help msg create-window commands' commands "$@" } (( $+functions[_alacritty__migrate_commands] )) || _alacritty__migrate_commands() { local commands; commands=() _describe -t commands 'alacritty migrate commands' commands "$@" } -(( $+functions[_alacritty__help__msg_commands] )) || -_alacritty__help__msg_commands() { +(( $+functions[_alacritty__msg_commands] )) || +_alacritty__msg_commands() { local commands; commands=( 'create-window:Create a new window in the same Alacritty process' \ 'config:Update the Alacritty configuration' \ +'help:Print this message or the help of the given subcommand(s)' \ ) - _describe -t commands 'alacritty help msg commands' commands "$@" + _describe -t commands 'alacritty msg commands' commands "$@" } -(( $+functions[_alacritty__msg_commands] )) || -_alacritty__msg_commands() { +(( $+functions[_alacritty__msg__config_commands] )) || +_alacritty__msg__config_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg config commands' commands "$@" +} +(( $+functions[_alacritty__msg__create-window_commands] )) || +_alacritty__msg__create-window_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg create-window 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' \ 'help:Print this message or the help of the given subcommand(s)' \ ) - _describe -t commands 'alacritty msg commands' commands "$@" + _describe -t commands 'alacritty msg help commands' commands "$@" +} +(( $+functions[_alacritty__msg__help__config_commands] )) || +_alacritty__msg__help__config_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg help config commands' commands "$@" +} +(( $+functions[_alacritty__msg__help__create-window_commands] )) || +_alacritty__msg__help__create-window_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg help create-window commands' commands "$@" +} +(( $+functions[_alacritty__msg__help__help_commands] )) || +_alacritty__msg__help__help_commands() { + local commands; commands=() + _describe -t commands 'alacritty msg help help commands' commands "$@" } if [ "$funcstack[1]" = "_alacritty" ]; then diff --git a/extra/completions/alacritty.bash b/extra/completions/alacritty.bash index c1546f500a9..e2213b75799 100644 --- a/extra/completions/alacritty.bash +++ b/extra/completions/alacritty.bash @@ -61,7 +61,7 @@ _alacritty() { case "${cmd}" in alacritty) - opts="-q -v -e -T -o -h -V --print-events --ref-test --embed --config-file --socket --working-directory --hold --command --title --class --option --help --version msg migrate help" + opts="-q -v -e -T -o -h -V --print-events --ref-test --embed --config-file --socket --daemon --working-directory --hold --command --title --class --option --help --version msg migrate help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -72,15 +72,48 @@ _alacritty() { return 0 ;; --config-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --socket) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --working-directory) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --command) @@ -210,11 +243,33 @@ _alacritty() { fi case "${prev}" in --config-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -c) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; *) @@ -232,11 +287,33 @@ _alacritty() { fi case "${prev}" in --socket) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -s) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; *) @@ -276,7 +353,18 @@ _alacritty() { fi case "${prev}" in --working-directory) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --command) @@ -373,4 +461,8 @@ _alacritty() { esac } -complete -F _alacritty -o nosort -o bashdefault -o default alacritty +if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then + complete -F _alacritty -o nosort -o bashdefault -o default alacritty +else + complete -F _alacritty -o bashdefault -o default alacritty +fi diff --git a/extra/completions/alacritty.fish b/extra/completions/alacritty.fish index 72609f70ad6..7cfc333767b 100644 --- a/extra/completions/alacritty.fish +++ b/extra/completions/alacritty.fish @@ -1,47 +1,74 @@ -complete -c alacritty -n "__fish_use_subcommand" -l embed -d 'X11 window ID to embed Alacritty within (decimal or hexadecimal with "0x" prefix)' -r -complete -c alacritty -n "__fish_use_subcommand" -l config-file -d 'Specify alternative configuration file [default: $XDG_CONFIG_HOME/alacritty/alacritty.toml]' -r -F -complete -c alacritty -n "__fish_use_subcommand" -l socket -d 'Path for IPC socket creation' -r -F -complete -c alacritty -n "__fish_use_subcommand" -l working-directory -d 'Start the shell in the specified working directory' -r -F -complete -c alacritty -n "__fish_use_subcommand" -s e -l command -d 'Command and args to execute (must be last argument)' -r -complete -c alacritty -n "__fish_use_subcommand" -s T -l title -d 'Defines the window title [default: Alacritty]' -r -complete -c alacritty -n "__fish_use_subcommand" -l class -d 'Defines window class/app_id on X11/Wayland [default: Alacritty]' -r -complete -c alacritty -n "__fish_use_subcommand" -s o -l option -d 'Override configuration file options [example: \'cursor.style="Beam"\']' -r -complete -c alacritty -n "__fish_use_subcommand" -l print-events -d 'Print all events to STDOUT' -complete -c alacritty -n "__fish_use_subcommand" -l ref-test -d 'Generates ref test' -complete -c alacritty -n "__fish_use_subcommand" -s q -d 'Reduces the level of verbosity (the min level is -qq)' -complete -c alacritty -n "__fish_use_subcommand" -s v -d 'Increases the level of verbosity (the max level is -vvv)' -complete -c alacritty -n "__fish_use_subcommand" -l hold -d 'Remain open after child process exit' -complete -c alacritty -n "__fish_use_subcommand" -s h -l help -d 'Print help' -complete -c alacritty -n "__fish_use_subcommand" -s V -l version -d 'Print version' -complete -c alacritty -n "__fish_use_subcommand" -f -a "msg" -d 'Send a message to the Alacritty socket' -complete -c alacritty -n "__fish_use_subcommand" -f -a "migrate" -d 'Migrate the configuration file' -complete -c alacritty -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help" -s s -l socket -d 'IPC socket connection path override' -r -F -complete -c alacritty -n "__fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help" -f -a "config" -d 'Update the Alacritty configuration' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __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_seen_subcommand_from 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_seen_subcommand_from 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_seen_subcommand_from msg; and __fish_seen_subcommand_from create-window" -s T -l title -d 'Defines the window title [default: Alacritty]' -r -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from create-window" -l class -d 'Defines window class/app_id on X11/Wayland [default: Alacritty]' -r -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from create-window" -s o -l option -d 'Override configuration file options [example: \'cursor.style="Beam"\']' -r -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from create-window" -l hold -d 'Remain open after child process exit' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from create-window" -s h -l help -d 'Print help' -complete -c alacritty -n "__fish_seen_subcommand_from 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_seen_subcommand_from msg; and __fish_seen_subcommand_from config" -s r -l reset -d 'Clear all runtime configuration changes' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from config" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help" -f -a "create-window" -d 'Create a new window in the same Alacritty process' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from help" -f -a "config" -d 'Update the Alacritty configuration' -complete -c alacritty -n "__fish_seen_subcommand_from msg; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config; and not __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_seen_subcommand_from migrate" -s c -l config-file -d 'Path to the configuration file' -r -F -complete -c alacritty -n "__fish_seen_subcommand_from migrate" -s d -l dry-run -d 'Only output TOML config to STDOUT' -complete -c alacritty -n "__fish_seen_subcommand_from migrate" -s i -l skip-imports -d 'Do not recurse over imports' -complete -c alacritty -n "__fish_seen_subcommand_from migrate" -l skip-renames -d 'Do not move renamed fields to their new location' -complete -c alacritty -n "__fish_seen_subcommand_from migrate" -s s -l silent -d 'Do not output to STDOUT' -complete -c alacritty -n "__fish_seen_subcommand_from migrate" -s h -l help -d 'Print help' -complete -c alacritty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from migrate; and not __fish_seen_subcommand_from help" -f -a "msg" -d 'Send a message to the Alacritty socket' -complete -c alacritty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from migrate; and not __fish_seen_subcommand_from help" -f -a "migrate" -d 'Migrate the configuration file' -complete -c alacritty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from migrate; and not __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_seen_subcommand_from help; and __fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config" -f -a "create-window" -d 'Create a new window in the same Alacritty process' -complete -c alacritty -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from msg; and not __fish_seen_subcommand_from create-window; and not __fish_seen_subcommand_from config" -f -a "config" -d 'Update the Alacritty configuration' +# Print an optspec for argparse to handle cmd's options that are independent of any subcommand. +function __fish_alacritty_global_optspecs + string join \n print-events ref-test embed= config-file= socket= q v daemon working-directory= hold e/command= T/title= class= o/option= h/help V/version +end + +function __fish_alacritty_needs_command + # Figure out if the current invocation already has a command. + set -l cmd (commandline -opc) + set -e cmd[1] + argparse -s (__fish_alacritty_global_optspecs) -- $cmd 2>/dev/null + or return + if set -q argv[1] + # Also print the command, so this can be used to figure out what it is. + echo $argv[1] + return 1 + end + return 0 +end + +function __fish_alacritty_using_subcommand + set -l cmd (__fish_alacritty_needs_command) + test -z "$cmd" + and return 1 + contains -- $cmd[1] $argv +end + +complete -c alacritty -n "__fish_alacritty_needs_command" -l embed -d 'X11 window ID to embed Alacritty within (decimal or hexadecimal with "0x" prefix)' -r +complete -c alacritty -n "__fish_alacritty_needs_command" -l config-file -d 'Specify alternative configuration file [default: $XDG_CONFIG_HOME/alacritty/alacritty.toml]' -r -F +complete -c alacritty -n "__fish_alacritty_needs_command" -l socket -d 'Path for IPC socket creation' -r -F +complete -c alacritty -n "__fish_alacritty_needs_command" -l working-directory -d 'Start the shell in the specified working directory' -r -F +complete -c alacritty -n "__fish_alacritty_needs_command" -s e -l command -d 'Command and args to execute (must be last argument)' -r +complete -c alacritty -n "__fish_alacritty_needs_command" -s T -l title -d 'Defines the window title [default: Alacritty]' -r +complete -c alacritty -n "__fish_alacritty_needs_command" -l class -d 'Defines window class/app_id on X11/Wayland [default: Alacritty]' -r +complete -c alacritty -n "__fish_alacritty_needs_command" -s o -l option -d 'Override configuration file options [example: \'cursor.style="Beam"\']' -r +complete -c alacritty -n "__fish_alacritty_needs_command" -l print-events -d 'Print all events to STDOUT' +complete -c alacritty -n "__fish_alacritty_needs_command" -l ref-test -d 'Generates ref test' +complete -c alacritty -n "__fish_alacritty_needs_command" -s q -d 'Reduces the level of verbosity (the min level is -qq)' +complete -c alacritty -n "__fish_alacritty_needs_command" -s v -d 'Increases the level of verbosity (the max level is -vvv)' +complete -c alacritty -n "__fish_alacritty_needs_command" -l daemon -d 'Do not spawn an initial window' +complete -c alacritty -n "__fish_alacritty_needs_command" -l hold -d 'Remain open after child process exit' +complete -c alacritty -n "__fish_alacritty_needs_command" -s h -l help -d 'Print help' +complete -c alacritty -n "__fish_alacritty_needs_command" -s V -l version -d 'Print version' +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 __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 +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -l class -d 'Defines window class/app_id on X11/Wayland [default: Alacritty]' -r +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -s o -l option -d 'Override configuration file options [example: \'cursor.style="Beam"\']' -r +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -l hold -d 'Remain open after child process exit' +complete -c alacritty -n "__fish_alacritty_using_subcommand msg; and __fish_seen_subcommand_from create-window" -s h -l help -d 'Print help' +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 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 "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' +complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -s i -l skip-imports -d 'Do not recurse over imports' +complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -l skip-renames -d 'Do not move renamed fields to their new location' +complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -s s -l silent -d 'Do not output to STDOUT' +complete -c alacritty -n "__fish_alacritty_using_subcommand migrate" -s h -l help -d 'Print help' +complete -c alacritty -n "__fish_alacritty_using_subcommand help; and not __fish_seen_subcommand_from msg migrate help" -f -a "msg" -d 'Send a message to the Alacritty socket' +complete -c alacritty -n "__fish_alacritty_using_subcommand help; and not __fish_seen_subcommand_from msg migrate help" -f -a "migrate" -d 'Migrate the configuration file' +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' diff --git a/extra/logo/alacritty-term.svg b/extra/logo/alacritty-term.svg index 065df5387c8..9798a3df9ec 100644 --- a/extra/logo/alacritty-term.svg +++ b/extra/logo/alacritty-term.svg @@ -423,7 +423,6 @@ transform="translate(-16,35.820639)" sodipodi:insensitive="true"> \ No newline at end of file + sodipodi:nodetypes="cccc" /> diff --git a/extra/man/alacritty-bindings.5.scd b/extra/man/alacritty-bindings.5.scd index 3de2986ee89..7f0bdf34ea3 100644 --- a/extra/man/alacritty-bindings.5.scd +++ b/extra/man/alacritty-bindings.5.scd @@ -2,7 +2,7 @@ ALACRITTY-BINDINGS(5) # NAME -Alacritty Bindings - Default configuration file bindings. +alacritty-bindings - Default configuration file bindings. # SYNOPSIS diff --git a/extra/man/alacritty.1.scd b/extra/man/alacritty.1.scd index b82ba08e326..86630a65306 100644 --- a/extra/man/alacritty.1.scd +++ b/extra/man/alacritty.1.scd @@ -21,6 +21,10 @@ set of features with high performance. Remain open after child process exits. +*--daemon* + + Do not spawn an initial window. + *--print-events* Print all events to STDOUT. @@ -61,13 +65,17 @@ set of features with high performance. Specify alternative configuration file. - Alacritty looks for the configuration file at the following paths: + Alacritty doesn't create the config file for you, but it looks for one in the + following locations on UNIX systems: + . _$XDG_CONFIG_HOME/alacritty/alacritty.toml_ . _$XDG_CONFIG_HOME/alacritty.toml_ . _$HOME/.config/alacritty/alacritty.toml_ . _$HOME/.alacritty.toml_ - On Windows, the configuration file is located at _%APPDATA%\\alacritty\\alacritty.toml_. + On Windows, the config file will be looked for in: + + . _%APPDATA%\\alacritty\\alacritty.toml_ *--embed* __ diff --git a/extra/man/alacritty.5.scd b/extra/man/alacritty.5.scd index 15bc2127690..8e92734ad89 100644 --- a/extra/man/alacritty.5.scd +++ b/extra/man/alacritty.5.scd @@ -14,18 +14,18 @@ can be found at _https://toml.io/en/v1.0.0_. Alacritty doesn't create the config file for you, but it looks for one in the following locations on UNIX systems: -. `$XDG_CONFIG_HOME/alacritty/alacritty.toml` -. `$XDG_CONFIG_HOME/alacritty.toml` -. `$HOME/.config/alacritty/alacritty.toml` -. `$HOME/.alacritty.toml` +. _$XDG_CONFIG_HOME/alacritty/alacritty.toml_ +. _$XDG_CONFIG_HOME/alacritty.toml_ +. _$HOME/.config/alacritty/alacritty.toml_ +. _$HOME/.alacritty.toml_ On Windows, the config file will be looked for in: -. `%APPDATA%\alacritty\alacritty.toml` +. _%APPDATA%\\alacritty\\alacritty.toml_ # GENERAL -This section documents the root level of the configuration file. +This section documents the *[general]* table of the configuration file. *import* = [_""_,] @@ -46,20 +46,6 @@ This section documents the root level of the configuration file. _"alacritty-theme/themes/gruvbox_dark.toml"_,++ ] -*shell* = _""_ | { program = _""_, args = [_""_,] } - - You can set _shell.program_ to the path of your favorite shell, e.g. - _/bin/zsh_. Entries in _shell.args_ are passed as arguments to the shell. - - Default: - Linux/BSD/macOS: _$SHELL_ or the user's login shell, if _$SHELL_ is unset++ -Windows: _"powershell"_ - - Example: - *[shell]*++ -program = _"/bin/zsh"_++ -args = [_"-l"_] - *working_directory* = _""_ | _"None"_ Directory the shell is started in. When this is unset, or _"None"_, the @@ -104,7 +90,7 @@ This section documents the *[window]* table of the configuration file. Default: { columns = _0_, lines = _0_ } -*position* = _"None"_ | { x = __, y = __ } +*position* = _"None"_ | { x = __, y = __ } # _(has no effect on Wayland)_ Window startup position. @@ -197,13 +183,13 @@ This section documents the *[window]* table of the configuration file. Default: _"None"_ -*resize_increments* = _true_ | _false_ +*resize_increments* = _true_ | _false_ # _(works on macOS/X11)_ Prefer resizing window by discrete steps equal to cell dimensions. Default: _false_ -*option_as_alt* = _"OnlyLeft"_ | _"OnlyRight"_ | _"Both"_ | _"None"_ # _(macos only)_ +*option_as_alt* = _"OnlyLeft"_ | _"OnlyRight"_ | _"Both"_ | _"None"_ # _(macOS only)_ Make _Option_ key behave as _Alt_. @@ -605,6 +591,20 @@ This section documents the *[cursor]* table of the configuration file. This section documents the *[terminal]* table of the configuration file. +*shell* = _""_ | { program = _""_, args = [_""_,] } + + You can set _shell.program_ to the path of your favorite shell, e.g. + _/bin/zsh_. Entries in _shell.args_ are passed as arguments to the shell. + + Default: + Linux/BSD/macOS: _$SHELL_ or the user's login shell, if _$SHELL_ is unset++ +Windows: _"powershell"_ + + Example: + *[shell]*++ +program = _"/bin/zsh"_++ +args = [_"-l"_] + *osc52* = _"Disabled"_ | _"OnlyCopy"_ | _"OnlyPaste"_ | _"CopyPaste"_ Controls the ability to write to the system clipboard with the _OSC 52_ @@ -730,7 +730,7 @@ hyperlinks = _true_++ post_processing = _true_++ persist = _false_++ mouse.enabled = _true_++ -binding = { key = _"U"_, mods = _"Control|Shift"_ }++ +binding = { key = _"O"_, mods = _"Control|Shift"_ }++ regex = _"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)[^\\u0000-\\u001F\\u007F-\\u009F<>\\"\\\\s{-}\\\\^⟨⟩`]+"_ # KEYBOARD diff --git a/extra/osx/Alacritty.app/Contents/Info.plist b/extra/osx/Alacritty.app/Contents/Info.plist index 9d7ca942d39..dd551e0fc36 100644 --- a/extra/osx/Alacritty.app/Contents/Info.plist +++ b/extra/osx/Alacritty.app/Contents/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.14.0-dev + 0.14.0 CFBundleSupportedPlatforms MacOSX