Change PathLikeWithPosition<P> into a non-generic type and replace ad-hoc Windows path parsing (#15373)

This simplifies `PathWithPosition` by making the common use case
concrete and removing the manual, incomplete Windows path parsing.
Windows paths also don't get '/'s replaced by '\\'s anymore to limit the
responsibility of the code to just parsing out the suffix and creating
`PathBuf` from the rest. `Path::file_name()` is now used to extract the
filename and potential suffix instead of manual parsing from the full
input. This way e.g. Windows paths that begin with a drive letter are
handled correctly without platform-specific hacks.

Release Notes:

- N/A
This commit is contained in:
Santeri Salmijärvi 2024-07-30 16:39:33 +03:00 committed by GitHub
parent 41c550cbe1
commit 13dcb42c1c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 184 additions and 270 deletions

View file

@ -14,12 +14,10 @@ use futures::{FutureExt, SinkExt, StreamExt};
use gpui::{AppContext, AsyncAppContext, Global, WindowHandle};
use language::{Bias, Point};
use remote::SshConnectionOptions;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use std::{process, thread};
use util::paths::PathLikeWithPosition;
use util::paths::PathWithPosition;
use util::ResultExt;
use welcome::{show_welcome_view, FIRST_OPEN};
use workspace::item::ItemHandle;
@ -28,7 +26,7 @@ use workspace::{AppState, Workspace};
#[derive(Default, Debug)]
pub struct OpenRequest {
pub cli_connection: Option<(mpsc::Receiver<CliRequest>, IpcSender<CliResponse>)>,
pub open_paths: Vec<PathLikeWithPosition<PathBuf>>,
pub open_paths: Vec<PathWithPosition>,
pub open_channel_notes: Vec<(u64, Option<String>)>,
pub join_channel: Option<u64>,
pub ssh_connection: Option<SshConnectionOptions>,
@ -58,11 +56,8 @@ impl OpenRequest {
fn parse_file_path(&mut self, file: &str) {
if let Some(decoded) = urlencoding::decode(file).log_err() {
if let Some(path_buf) =
PathLikeWithPosition::parse_str(&decoded, |_, s| PathBuf::try_from(s)).log_err()
{
self.open_paths.push(path_buf)
}
let path_buf = PathWithPosition::parse_str(&decoded);
self.open_paths.push(path_buf)
}
}
@ -193,7 +188,7 @@ fn connect_to_cli(
}
pub async fn open_paths_with_positions(
path_likes: &Vec<PathLikeWithPosition<PathBuf>>,
path_positions: &Vec<PathWithPosition>,
app_state: Arc<AppState>,
open_options: workspace::OpenOptions,
cx: &mut AsyncAppContext,
@ -203,10 +198,10 @@ pub async fn open_paths_with_positions(
)> {
let mut caret_positions = HashMap::default();
let paths = path_likes
let paths = path_positions
.iter()
.map(|path_with_position| {
let path = path_with_position.path_like.clone();
let path = path_with_position.path.clone();
if let Some(row) = path_with_position.row {
if path.is_file() {
let row = row.saturating_sub(1);
@ -364,8 +359,8 @@ async fn open_workspaces(
location
.paths()
.iter()
.map(|path| PathLikeWithPosition {
path_like: path.clone(),
.map(|path| PathWithPosition {
path: path.clone(),
row: None,
column: None,
})
@ -380,10 +375,7 @@ async fn open_workspaces(
let paths_with_position = paths
.into_iter()
.map(|path_with_position_string| {
PathLikeWithPosition::parse_str(&path_with_position_string, |_, path_str| {
Ok::<_, std::convert::Infallible>(Path::new(path_str).to_path_buf())
})
.expect("Infallible")
PathWithPosition::parse_str(&path_with_position_string)
})
.collect();
vec![paths_with_position]
@ -434,7 +426,7 @@ async fn open_workspaces(
}
async fn open_workspace(
workspace_paths: Vec<PathLikeWithPosition<PathBuf>>,
workspace_paths: Vec<PathWithPosition>,
open_new_workspace: Option<bool>,
wait: bool,
responses: &IpcSender<CliResponse>,
@ -542,7 +534,7 @@ mod tests {
use editor::Editor;
use gpui::TestAppContext;
use serde_json::json;
use util::paths::PathLikeWithPosition;
use util::paths::PathWithPosition;
use workspace::{AppState, Workspace};
use crate::zed::{open_listener::open_workspace, tests::init_test};
@ -656,9 +648,9 @@ mod tests {
) {
let (response_tx, _) = ipc::channel::<CliResponse>().unwrap();
let path_like = PathBuf::from(path);
let workspace_paths = vec![PathLikeWithPosition {
path_like,
let path = PathBuf::from(path);
let workspace_paths = vec![PathWithPosition {
path,
row: None,
column: None,
}];