diff --git a/Cargo.lock b/Cargo.lock index 9ba54c3b4ee75375719120c6dd8092f7afa883bb..e87ff3d9910515513111c5dc9ab7dde5dc2e40de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4275,9 +4275,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" 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 }; 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 { 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