From 9aad602af7b71e24377518e9dee9febc7ab96779 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Mon, 28 Aug 2023 18:20:10 +0200 Subject: [PATCH 1/4] chore: Bump memchr to 2.6.0 (#2902) Fresh off the press, memchr 2.6.0 adds vector search routines for aarch64. That directly improves our search performance for both text and regex searches. Per BurntSushi's claims, the simple string searches in ripgrep got ~2 times faster (more details available in https://github.com/BurntSushi/memchr/pull/129). Release Notes: - N/A --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfdb1b6092d1b221697a356a845e2db3ee4d6b02..347976691d7bc138cff4b6202314c8afcea02764 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4269,9 +4269,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" [[package]] name = "memfd" From a1d2ae3095a7e279cbd202ab6bbbd97f06e7035e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 28 Aug 2023 13:32:30 -0600 Subject: [PATCH 2/4] Add -l option to build script When you pass -l, we build for the local architecture only and copy the resulting app bundle to /Applications. You can provide a bundle name as an optional argument. --- script/bundle | 163 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 117 insertions(+), 46 deletions(-) diff --git a/script/bundle b/script/bundle index 9f50862cd590e12fb30a3cc896aaa403652b45ac..49da1072ceaff28bff27e101caadf85e58d2e2c4 100755 --- a/script/bundle +++ b/script/bundle @@ -5,11 +5,29 @@ set -e build_flag="--release" target_dir="release" open_result=false +local_only=false +overwrite_local_app=false +bundle_name="" + +# Function for displaying help info +help_info() { + echo " +Usage: ${0##*/} [options] [bundle_name] +Build the application bundle. + +Options: + -d Compile in debug mode and print the app bundle's path. + -l Compile for local architecture only and copy bundle to /Applications. + -o Open the resulting DMG or the app itself in local mode. + -f Overwrite the local app bundle if it exists. + -h Display this help and exit. + " +} # If -o option is specified, the folder of the resulting dmg will be opened in finder # If -d is specified, Zed will be compiled in debug mode and the application's path printed # If -od or -do is specified Zed will be bundled in debug and the application will be run. -while getopts 'od' flag +while getopts 'dlfoh' flag do case "${flag}" in o) open_result=true;; @@ -17,9 +35,21 @@ do build_flag=""; target_dir="debug" ;; + l) local_only=true;; + f) overwrite_local_app=true;; + h) + help_info + exit 0 + ;; esac done +shift $((OPTIND-1)) + +if [ "$1" ]; then + bundle_name=$1 +fi + export ZED_BUNDLE=true export MACOSX_DEPLOYMENT_TARGET=10.15.7 @@ -33,14 +63,24 @@ rustup target add wasm32-wasi # Deal with versions of macOS that don't include libstdc++ headers export CXXFLAGS="-stdlib=libc++" -echo "Compiling zed binary for aarch64-apple-darwin" -cargo build ${build_flag} --package zed --target aarch64-apple-darwin -echo "Compiling zed binary for x86_64-apple-darwin" -cargo build ${build_flag} --package zed --target x86_64-apple-darwin -echo "Compiling cli binary for aarch64-apple-darwin" -cargo build ${build_flag} --package cli --target aarch64-apple-darwin -echo "Compiling cli binary for x86_64-apple-darwin" -cargo build ${build_flag} --package cli --target x86_64-apple-darwin +version_info=$(rustc --version --verbose) +host_line=$(echo "$version_info" | grep host) +local_target_triple=${host_line#*: } + +if [ "$local_only" = true ]; then + echo "Building for local target only." + cargo build ${build_flag} --package zed + cargo build ${build_flag} --package cli +else + echo "Compiling zed binary for aarch64-apple-darwin" + cargo build ${build_flag} --package zed --target aarch64-apple-darwin + echo "Compiling zed binary for x86_64-apple-darwin" + cargo build ${build_flag} --package zed --target x86_64-apple-darwin + echo "Compiling cli binary for aarch64-apple-darwin" + cargo build ${build_flag} --package cli --target aarch64-apple-darwin + echo "Compiling cli binary for x86_64-apple-darwin" + cargo build ${build_flag} --package cli --target x86_64-apple-darwin +fi echo "Creating application bundle" pushd crates/zed @@ -50,27 +90,34 @@ sed \ -i .backup \ "s/package.metadata.bundle-${channel}/package.metadata.bundle/" \ Cargo.toml -app_path=$(cargo bundle ${build_flag} --target x86_64-apple-darwin --select-workspace-root | xargs) + +if [ "$local_only" = true ]; then + app_path=$(cargo bundle ${build_flag} --select-workspace-root | xargs) +else + app_path=$(cargo bundle ${build_flag} --target x86_64-apple-darwin --select-workspace-root | xargs) +fi mv Cargo.toml.backup Cargo.toml popd echo "Bundled ${app_path}" -echo "Creating fat binaries" -lipo \ - -create \ - target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/Zed \ - -output \ - "${app_path}/Contents/MacOS/zed" -lipo \ - -create \ - target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/cli \ - -output \ - "${app_path}/Contents/MacOS/cli" +if [ "$local_only" = false ]; then + echo "Creating fat binaries" + lipo \ + -create \ + target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/Zed \ + -output \ + "${app_path}/Contents/MacOS/zed" + lipo \ + -create \ + target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/cli \ + -output \ + "${app_path}/Contents/MacOS/cli" +fi echo "Copying WebRTC.framework into the frameworks folder" mkdir "${app_path}/Contents/Frameworks" -cp -R target/x86_64-apple-darwin/${target_dir}/WebRTC.framework "${app_path}/Contents/Frameworks/" +cp -R target/${local_target_triple}/${target_dir}/WebRTC.framework "${app_path}/Contents/Frameworks/" if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then echo "Signing bundle with Apple-issued certificate" @@ -99,31 +146,55 @@ if [ "$target_dir" = "debug" ]; then exit 0 fi -dmg_target_directory="target/${target_dir}" -dmg_source_directory="${dmg_target_directory}/dmg" -dmg_file_path="${dmg_target_directory}/Zed.dmg" - -echo "Creating DMG" -rm -rf ${dmg_source_directory} -mkdir -p ${dmg_source_directory} -mv "${app_path}" "${dmg_source_directory}" - -ln -s /Applications ${dmg_source_directory} -hdiutil create -volname Zed -srcfolder "${dmg_source_directory}" -ov -format UDZO "${dmg_file_path}" -# If someone runs this bundle script locally, a symlink will be placed in `dmg_source_directory`. -# This symlink causes CPU issues with Zed if the Zed codebase is the project being worked on, so we simply remove it for now. -rm ${dmg_source_directory}/Applications +if [ "$local_only" = true ]; then + # If bundle_name is not set or empty, use the basename of $app_path + if [ -z "$bundle_name" ]; then + bundle_name=$(basename "$app_path") + else + # If bundle_name doesn't end in .app, append it + if [[ "$bundle_name" != *.app ]]; then + bundle_name="$bundle_name.app" + fi + fi -echo "Adding license agreement to DMG" -npm install --global dmg-license minimist -dmg-license script/eula/eula.json "${dmg_file_path}" + if [ "$overwrite_local_app" = true ]; then + rm -rf "/Applications/$bundle_name" + fi + mv "$app_path" "/Applications/$bundle_name" -if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then - echo "Notarizing DMG with Apple" - npm install -g notarize-cli - npx notarize-cli --file "${dmg_file_path}" --bundle-id dev.zed.Zed --username "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" -fi + if [ "$open_result" = true ]; then + open "/Applications/$bundle_name" + else + echo "Installed application bundle:" + echo "/Applications/$bundle_name" + fi +else + echo "Creating DMG" + dmg_target_directory="target/${target_dir}" + dmg_source_directory="${dmg_target_directory}/dmg" + dmg_file_path="${dmg_target_directory}/Zed.dmg" + + rm -rf ${dmg_source_directory} + mkdir -p ${dmg_source_directory} + mv "${app_path}" "${dmg_source_directory}" + + ln -s /Applications ${dmg_source_directory} + hdiutil create -volname Zed -srcfolder "${dmg_source_directory}" -ov -format UDZO "${dmg_file_path}" + # If someone runs this bundle script locally, a symlink will be placed in `dmg_source_directory`. + # This symlink causes CPU issues with Zed if the Zed codebase is the project being worked on, so we simply remove it for now. + rm ${dmg_source_directory}/Applications + + echo "Adding license agreement to DMG" + npm install --global dmg-license minimist + dmg-license script/eula/eula.json "${dmg_file_path}" + + if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then + echo "Notarizing DMG with Apple" + npm install -g notarize-cli + npx notarize-cli --file "${dmg_file_path}" --bundle-id dev.zed.Zed --username "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" + fi -if [ "$open_result" = true ]; then - open $dmg_target_directory + if [ "$open_result" = true ]; then + open $dmg_target_directory + fi fi From 7c498feb85dc6d704036f8a9f6dcda12da3b8a0c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 29 Aug 2023 10:40:20 +0300 Subject: [PATCH 3/4] Trim off surrounding `[]` when parsing terminal hover links Terminal has to accept `[` and `]` as valid word parts, due to `[slug].tsx` being a valid file name. Yet, terminal has to exclude these to match paths in strings like `[/some/path/[slug].tsx]`. --- crates/terminal/src/terminal.rs | 37 ++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 83ba056485664057a13c731033ccf1557a332fc8..ea919c8f84c9f87e08558309cb2c5adca811c5cf 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -8,7 +8,7 @@ use alacritty_terminal::{ event::{Event as AlacTermEvent, EventListener, Notify, WindowSize}, event_loop::{EventLoop, Msg, Notifier}, grid::{Dimensions, Scroll as AlacScroll}, - index::{Column, Direction as AlacDirection, Line, Point}, + index::{Boundary, Column, Direction as AlacDirection, Line, Point}, selection::{Selection, SelectionRange, SelectionType}, sync::FairMutex, term::{ @@ -724,14 +724,13 @@ impl Terminal { self.last_content.size, term.grid().display_offset(), ) - .grid_clamp(term, alacritty_terminal::index::Boundary::Grid); + .grid_clamp(term, Boundary::Grid); let link = term.grid().index(point).hyperlink(); let found_word = if link.is_some() { let mut min_index = point; loop { - let new_min_index = - min_index.sub(term, alacritty_terminal::index::Boundary::Cursor, 1); + let new_min_index = min_index.sub(term, Boundary::Cursor, 1); if new_min_index == min_index { break; } else if term.grid().index(new_min_index).hyperlink() != link { @@ -743,8 +742,7 @@ impl Terminal { let mut max_index = point; loop { - let new_max_index = - max_index.add(term, alacritty_terminal::index::Boundary::Cursor, 1); + let new_max_index = max_index.add(term, Boundary::Cursor, 1); if new_max_index == max_index { break; } else if term.grid().index(new_max_index).hyperlink() != link { @@ -761,11 +759,34 @@ impl Terminal { } else if let Some(word_match) = regex_match_at(term, point, &WORD_REGEX) { let maybe_url_or_path = term.bounds_to_string(*word_match.start(), *word_match.end()); + let original_match = word_match.clone(); + let (sanitized_match, sanitized_word) = + if maybe_url_or_path.starts_with('[') && maybe_url_or_path.ends_with(']') { + ( + Match::new( + word_match.start().add(term, Boundary::Cursor, 1), + word_match.end().sub(term, Boundary::Cursor, 1), + ), + maybe_url_or_path[1..maybe_url_or_path.len() - 1].to_owned(), + ) + } else { + (word_match, maybe_url_or_path) + }; + let is_url = match regex_match_at(term, point, &URL_REGEX) { - Some(url_match) => url_match == word_match, + Some(url_match) => { + // `]` is a valid symbol in the `file://` URL, so the regex match will include it + // consider that when ensuring that the URL match is the same as the original word + if sanitized_match != original_match { + url_match.start() == sanitized_match.start() + && url_match.end() == original_match.end() + } else { + url_match == sanitized_match + } + } None => false, }; - Some((maybe_url_or_path, is_url, word_match)) + Some((sanitized_word, is_url, sanitized_match)) } else { None }; From ea0e5e880e839ab2e0b3fd2e0dd456f418352d9c Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Tue, 29 Aug 2023 15:56:50 +0200 Subject: [PATCH 4/4] chore: Use IsTerminal trait instead of relying on libc to detect stdout being a terminal (#2908) IsTerminal was added in 1.70. Release Notes: - N/A --- crates/zed/src/main.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index da726eef65d16e9ffeaa84141506c7e1b184a76a..3e0a8a7a073fcd75dae725f900fe09d328b092b5 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -31,7 +31,7 @@ use std::{ env, ffi::OsStr, fs::OpenOptions, - io::Write as _, + io::{IsTerminal, Write as _}, os::unix::prelude::OsStrExt, panic, path::{Path, PathBuf}, @@ -635,8 +635,7 @@ async fn load_login_shell_environment() -> Result<()> { } fn stdout_is_a_pty() -> bool { - std::env::var(FORCE_CLI_MODE_ENV_VAR_NAME).ok().is_none() - && unsafe { libc::isatty(libc::STDOUT_FILENO as i32) != 0 } + std::env::var(FORCE_CLI_MODE_ENV_VAR_NAME).ok().is_none() && std::io::stdout().is_terminal() } fn collect_path_args() -> Vec {