Attempt to open rows and columns from CLI input

This commit is contained in:
Kirill Bulatov 2023-05-12 18:13:28 +03:00
parent d719352152
commit 628558aa39
5 changed files with 91 additions and 32 deletions

View File

@ -1,6 +1,7 @@
pub use ipc_channel::ipc; pub use ipc_channel::ipc;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::PathBuf; use std::path::PathBuf;
use util::paths::PathLikeWithPosition;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct IpcHandshake { pub struct IpcHandshake {
@ -10,7 +11,11 @@ pub struct IpcHandshake {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub enum CliRequest { pub enum CliRequest {
Open { paths: Vec<PathBuf>, wait: bool }, Open {
// TODO kb old cli won't be able to communicate to new Zed with this change
paths: Vec<PathLikeWithPosition<PathBuf>>,
wait: bool,
},
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]

View File

@ -21,7 +21,7 @@ use util::paths::PathLikeWithPosition;
#[derive(Parser)] #[derive(Parser)]
#[clap(name = "zed", global_setting(clap::AppSettings::NoAutoVersion))] #[clap(name = "zed", global_setting(clap::AppSettings::NoAutoVersion))]
struct Args { 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)] #[clap(short, long)]
wait: bool, wait: bool,
/// A sequence of space-separated paths that you want to open. /// A sequence of space-separated paths that you want to open.
@ -78,12 +78,13 @@ fn main() -> Result<()> {
paths: args paths: args
.paths_with_position .paths_with_position
.into_iter() .into_iter()
// TODO kb continue sendint path with the position further .map(|path_with_position| {
.map(|path_with_position| path_with_position.path_like) path_with_position.convert_path(|path| {
.map(|path| { fs::canonicalize(&path)
fs::canonicalize(&path).with_context(|| format!("path {path:?} canonicalization")) .with_context(|| format!("path {path:?} canonicalization"))
}) })
.collect::<Result<Vec<PathBuf>>>()?, })
.collect::<Result<_>>()?,
wait: args.wait, wait: args.wait,
})?; })?;

View File

@ -295,8 +295,6 @@ impl PickerDelegate for FileFinderDelegate {
let point = snapshot let point = snapshot
.buffer_snapshot .buffer_snapshot
.clip_point(Point::new(row, col), Bias::Left); .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| { editor.change_selections(Some(Autoscroll::center()), cx, |s| {
s.select_ranges([point..point]) s.select_ranges([point..point])
}); });

View File

@ -1,5 +1,7 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub static ref HOME: PathBuf = dirs::home_dir().expect("failed to determine home directory"); 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"); 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 = ':'; pub const FILE_ROW_COLUMN_DELIMITER: char = ':';
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PathLikeWithPosition<P> { pub struct PathLikeWithPosition<P> {
pub path_like: P, pub path_like: P,
pub row: Option<u32>, pub row: Option<u32>,
@ -106,4 +108,15 @@ impl<P> PathLikeWithPosition<P> {
}, },
}) })
} }
pub fn convert_path<P2, E>(
self,
mapping: impl FnOnce(P) -> Result<P2, E>,
) -> Result<PathLikeWithPosition<P2>, E> {
Ok(PathLikeWithPosition {
path_like: mapping(self.path_like)?,
row: self.row,
column: self.column,
})
}
} }

View File

@ -10,7 +10,7 @@ use cli::{
}; };
use client::{self, UserStore, ZED_APP_VERSION, ZED_SECRET_CLIENT_TOKEN}; use client::{self, UserStore, ZED_APP_VERSION, ZED_SECRET_CLIENT_TOKEN};
use db::kvp::KEY_VALUE_STORE; use db::kvp::KEY_VALUE_STORE;
use editor::Editor; use editor::{scroll::autoscroll::Autoscroll, Editor};
use futures::{ use futures::{
channel::{mpsc, oneshot}, channel::{mpsc, oneshot},
FutureExt, SinkExt, StreamExt, FutureExt, SinkExt, StreamExt,
@ -30,6 +30,7 @@ use settings::{
use simplelog::ConfigBuilder; use simplelog::ConfigBuilder;
use smol::process::Command; use smol::process::Command;
use std::{ use std::{
collections::HashMap,
env, env,
ffi::OsStr, ffi::OsStr,
fs::OpenOptions, fs::OpenOptions,
@ -44,7 +45,9 @@ use std::{
thread, thread,
time::Duration, time::Duration,
}; };
use sum_tree::Bias;
use terminal_view::{get_working_directory, TerminalView}; use terminal_view::{get_working_directory, TerminalView};
use text::Point;
use util::http::{self, HttpClient}; use util::http::{self, HttpClient};
use welcome::{show_welcome_experience, FIRST_OPEN}; use welcome::{show_welcome_experience, FIRST_OPEN};
@ -678,13 +681,29 @@ async fn handle_cli_connection(
if let Some(request) = requests.next().await { if let Some(request) = requests.next().await {
match request { match request {
CliRequest::Open { paths, wait } => { CliRequest::Open { paths, wait } => {
let mut caret_positions = HashMap::new();
let paths = if paths.is_empty() { let paths = if paths.is_empty() {
workspace::last_opened_workspace_paths() workspace::last_opened_workspace_paths()
.await .await
.map(|location| location.paths().to_vec()) .map(|location| location.paths().to_vec())
.unwrap_or(paths) .unwrap_or_default()
} else { } else {
paths 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; let mut errored = false;
@ -694,11 +713,37 @@ async fn handle_cli_connection(
{ {
Ok((workspace, items)) => { Ok((workspace, items)) => {
let mut item_release_futures = Vec::new(); let mut item_release_futures = Vec::new();
cx.update(|cx| {
for (item, path) in items.into_iter().zip(&paths) { for (item, path) in items.into_iter().zip(&paths) {
match item { match item {
Some(Ok(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::<Editor>() {
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(); let released = oneshot::channel();
cx.update(|cx| {
item.on_release( item.on_release(
cx, cx,
Box::new(move |_| { Box::new(move |_| {
@ -706,15 +751,13 @@ async fn handle_cli_connection(
}), }),
) )
.detach(); .detach();
});
item_release_futures.push(released.1); item_release_futures.push(released.1);
} }
Some(Err(err)) => { Some(Err(err)) => {
responses responses
.send(CliResponse::Stderr { .send(CliResponse::Stderr {
message: format!( message: format!("error opening {:?}: {}", path, err),
"error opening {:?}: {}",
path, err
),
}) })
.log_err(); .log_err();
errored = true; errored = true;
@ -722,7 +765,6 @@ async fn handle_cli_connection(
None => {} None => {}
} }
} }
});
if wait { if wait {
let background = cx.background(); let background = cx.background();