From 628558aa3901caf1c44bd62fb85ec889c4507028 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 12 May 2023 18:13:28 +0300 Subject: [PATCH] Attempt to open rows and columns from CLI input --- crates/cli/src/cli.rs | 7 ++- crates/cli/src/main.rs | 13 ++-- crates/file_finder/src/file_finder.rs | 2 - crates/util/src/paths.rs | 15 ++++- crates/zed/src/main.rs | 86 ++++++++++++++++++++------- 5 files changed, 91 insertions(+), 32 deletions(-) diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs index de7b14e142..8281bcb651 100644 --- a/crates/cli/src/cli.rs +++ b/crates/cli/src/cli.rs @@ -1,6 +1,7 @@ pub use ipc_channel::ipc; use serde::{Deserialize, Serialize}; use std::path::PathBuf; +use util::paths::PathLikeWithPosition; #[derive(Serialize, Deserialize)] pub struct IpcHandshake { @@ -10,7 +11,11 @@ pub struct IpcHandshake { #[derive(Debug, Serialize, Deserialize)] pub enum CliRequest { - Open { paths: Vec, wait: bool }, + Open { + // TODO kb old cli won't be able to communicate to new Zed with this change + paths: Vec>, + wait: bool, + }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 80ec2bbf99..ff7a65c2fc 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -21,7 +21,7 @@ use util::paths::PathLikeWithPosition; #[derive(Parser)] #[clap(name = "zed", global_setting(clap::AppSettings::NoAutoVersion))] struct Args { - /// Wait for all of the given paths to be closed before exiting. + /// Wait for all of the given paths to be opened/closed before exiting. #[clap(short, long)] wait: bool, /// A sequence of space-separated paths that you want to open. @@ -78,12 +78,13 @@ fn main() -> Result<()> { paths: args .paths_with_position .into_iter() - // TODO kb continue sendint path with the position further - .map(|path_with_position| path_with_position.path_like) - .map(|path| { - fs::canonicalize(&path).with_context(|| format!("path {path:?} canonicalization")) + .map(|path_with_position| { + path_with_position.convert_path(|path| { + fs::canonicalize(&path) + .with_context(|| format!("path {path:?} canonicalization")) + }) }) - .collect::>>()?, + .collect::>()?, wait: args.wait, })?; diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index fae9bd565c..063067891a 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -295,8 +295,6 @@ impl PickerDelegate for FileFinderDelegate { let point = snapshot .buffer_snapshot .clip_point(Point::new(row, col), Bias::Left); - let point = - snapshot.buffer_snapshot.clip_point(point, Bias::Left); editor.change_selections(Some(Autoscroll::center()), cx, |s| { s.select_ranges([point..point]) }); diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index 280d3cad02..8a0c91aba6 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -1,5 +1,7 @@ use std::path::{Path, PathBuf}; +use serde::{Deserialize, Serialize}; + lazy_static::lazy_static! { pub static ref HOME: PathBuf = dirs::home_dir().expect("failed to determine home directory"); pub static ref CONFIG_DIR: PathBuf = HOME.join(".config").join("zed"); @@ -73,7 +75,7 @@ pub fn compact(path: &Path) -> PathBuf { pub const FILE_ROW_COLUMN_DELIMITER: char = ':'; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct PathLikeWithPosition

{ pub path_like: P, pub row: Option, @@ -106,4 +108,15 @@ impl

PathLikeWithPosition

{ }, }) } + + pub fn convert_path( + self, + mapping: impl FnOnce(P) -> Result, + ) -> Result, E> { + Ok(PathLikeWithPosition { + path_like: mapping(self.path_like)?, + row: self.row, + column: self.column, + }) + } } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 60a2fc66be..369a657527 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -10,7 +10,7 @@ use cli::{ }; use client::{self, UserStore, ZED_APP_VERSION, ZED_SECRET_CLIENT_TOKEN}; use db::kvp::KEY_VALUE_STORE; -use editor::Editor; +use editor::{scroll::autoscroll::Autoscroll, Editor}; use futures::{ channel::{mpsc, oneshot}, FutureExt, SinkExt, StreamExt, @@ -30,6 +30,7 @@ use settings::{ use simplelog::ConfigBuilder; use smol::process::Command; use std::{ + collections::HashMap, env, ffi::OsStr, fs::OpenOptions, @@ -44,7 +45,9 @@ use std::{ thread, time::Duration, }; +use sum_tree::Bias; use terminal_view::{get_working_directory, TerminalView}; +use text::Point; use util::http::{self, HttpClient}; use welcome::{show_welcome_experience, FIRST_OPEN}; @@ -678,13 +681,29 @@ async fn handle_cli_connection( if let Some(request) = requests.next().await { match request { CliRequest::Open { paths, wait } => { + let mut caret_positions = HashMap::new(); + let paths = if paths.is_empty() { workspace::last_opened_workspace_paths() .await .map(|location| location.paths().to_vec()) - .unwrap_or(paths) + .unwrap_or_default() } else { paths + .into_iter() + .map(|path_with_position| { + let path = path_with_position.path_like; + if let Some(row) = path_with_position.row { + if path.is_file() { + let row = row.saturating_sub(1); + let col = + path_with_position.column.unwrap_or(0).saturating_sub(1); + caret_positions.insert(path.clone(), Point::new(row, col)); + } + } + path + }) + .collect() }; let mut errored = false; @@ -694,11 +713,37 @@ async fn handle_cli_connection( { Ok((workspace, items)) => { let mut item_release_futures = Vec::new(); - cx.update(|cx| { - for (item, path) in items.into_iter().zip(&paths) { - match item { - Some(Ok(item)) => { - let released = oneshot::channel(); + + for (item, path) in items.into_iter().zip(&paths) { + match item { + Some(Ok(item)) => { + if let Some(point) = caret_positions.remove(path) { + // TODO kb does not work + log::info!("@@@@@@@@ {path:?}@{point:?}"); + if let Some(active_editor) = item.downcast::() { + log::info!("@@@@@@@@ editor"); + active_editor + .downgrade() + .update(&mut cx, |editor, cx| { + log::info!("@@@@@@@@ update"); + let snapshot = + editor.snapshot(cx).display_snapshot; + let point = snapshot + .buffer_snapshot + .clip_point(point, Bias::Left); + editor.change_selections( + Some(Autoscroll::center()), + cx, + |s| s.select_ranges([point..point]), + ); + log::info!("@@@@@@@@ finished"); + }) + .log_err(); + } + } + + let released = oneshot::channel(); + cx.update(|cx| { item.on_release( cx, Box::new(move |_| { @@ -706,23 +751,20 @@ async fn handle_cli_connection( }), ) .detach(); - item_release_futures.push(released.1); - } - Some(Err(err)) => { - responses - .send(CliResponse::Stderr { - message: format!( - "error opening {:?}: {}", - path, err - ), - }) - .log_err(); - errored = true; - } - None => {} + }); + item_release_futures.push(released.1); } + Some(Err(err)) => { + responses + .send(CliResponse::Stderr { + message: format!("error opening {:?}: {}", path, err), + }) + .log_err(); + errored = true; + } + None => {} } - }); + } if wait { let background = cx.background();