From 106064c73402c035b92028aecb4b0abf17e1e27c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 13 May 2023 11:39:35 +0300 Subject: [PATCH] Do not break Zed & Zed CLI compatibility --- crates/cli/src/cli.rs | 13 ++++++------- crates/cli/src/main.rs | 5 +++-- crates/util/src/paths.rs | 16 ++++++++++++++++ crates/zed/src/main.rs | 20 ++++++++++++++++---- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs index 8281bcb651..3a0abbaec7 100644 --- a/crates/cli/src/cli.rs +++ b/crates/cli/src/cli.rs @@ -1,7 +1,5 @@ pub use ipc_channel::ipc; use serde::{Deserialize, Serialize}; -use std::path::PathBuf; -use util::paths::PathLikeWithPosition; #[derive(Serialize, Deserialize)] pub struct IpcHandshake { @@ -11,11 +9,12 @@ pub struct IpcHandshake { #[derive(Debug, Serialize, Deserialize)] pub enum CliRequest { - Open { - // TODO kb old cli won't be able to communicate to new Zed with this change - paths: Vec>, - wait: bool, - }, + // The filed is named `path` for compatibility, but now CLI can request + // opening a path at a certain row and/or column: `some/path:123` and `some/path:123:456`. + // + // Since Zed CLI has to be installed separately, there can be situations when old CLI is + // querying new Zed editors, support both formats by using `String` here and parsing it on Zed side later. + Open { paths: Vec, wait: bool }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index ff7a65c2fc..d4b75f9533 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -79,10 +79,11 @@ fn main() -> Result<()> { .paths_with_position .into_iter() .map(|path_with_position| { - path_with_position.convert_path(|path| { + let path_with_position = path_with_position.convert_path(|path| { fs::canonicalize(&path) .with_context(|| format!("path {path:?} canonicalization")) - }) + })?; + Ok(path_with_position.to_string(|path| path.display().to_string())) }) .collect::>()?, wait: args.wait, diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index 8a0c91aba6..96311fabf8 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -119,4 +119,20 @@ impl

PathLikeWithPosition

{ column: self.column, }) } + + pub fn to_string(&self, path_like_to_string: F) -> String + where + F: Fn(&P) -> String, + { + let path_like_string = path_like_to_string(&self.path_like); + if let Some(row) = self.row { + if let Some(column) = self.column { + format!("{path_like_string}:{row}:{column}") + } else { + format!("{path_like_string}:{row}") + } + } else { + path_like_string + } + } } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 369a657527..03fdbf7067 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -37,7 +37,7 @@ use std::{ io::Write as _, os::unix::prelude::OsStrExt, panic, - path::PathBuf, + path::{Path, PathBuf}, sync::{ atomic::{AtomicBool, Ordering}, Arc, Weak, @@ -48,7 +48,10 @@ use std::{ use sum_tree::Bias; use terminal_view::{get_working_directory, TerminalView}; use text::Point; -use util::http::{self, HttpClient}; +use util::{ + http::{self, HttpClient}, + paths::PathLikeWithPosition, +}; use welcome::{show_welcome_experience, FIRST_OPEN}; use fs::RealFs; @@ -691,7 +694,16 @@ async fn handle_cli_connection( } else { paths .into_iter() - .map(|path_with_position| { + .filter_map(|path_with_position_string| { + let path_with_position = PathLikeWithPosition::parse_str( + &path_with_position_string, + |path_str| { + Ok::<_, std::convert::Infallible>( + Path::new(path_str).to_path_buf(), + ) + }, + ) + .expect("Infallible"); let path = path_with_position.path_like; if let Some(row) = path_with_position.row { if path.is_file() { @@ -701,7 +713,7 @@ async fn handle_cli_connection( caret_positions.insert(path.clone(), Point::new(row, col)); } } - path + Some(path) }) .collect() };