Skip to content

Commit

Permalink
open zed urls (#9081)
Browse files Browse the repository at this point in the history
Release Notes:

- Added support for opening files on the zed protocol `open
zed:///Users/example/Desktop/a.txt`
([#8482](#8482)).
  • Loading branch information
ConradIrwin committed Mar 8, 2024
1 parent 1756c1f commit 977af37
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 215 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/zed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ go_to_line.workspace = true
gpui.workspace = true
install_cli.workspace = true
isahc.workspace = true
itertools.workspace = true
journal.workspace = true
language.workspace = true
language_selector.workspace = true
Expand Down
129 changes: 73 additions & 56 deletions crates/zed/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use env_logger::Builder;
use fs::RealFs;
#[cfg(target_os = "macos")]
use fsevent::StreamFlags;
use futures::StreamExt;
use futures::{future, StreamExt};
use gpui::{App, AppContext, AsyncAppContext, Context, SemanticVersion, Task};
use isahc::{prelude::Configurable, Request};
use language::LanguageRegistry;
Expand All @@ -36,7 +36,7 @@ use std::{
fs::OpenOptions,
io::{IsTerminal, Write},
panic,
path::{Path, PathBuf},
path::Path,
sync::{
atomic::{AtomicU32, Ordering},
Arc,
Expand All @@ -48,14 +48,15 @@ use util::{
async_maybe,
http::{HttpClient, HttpClientWithUrl},
paths::{self, CRASHES_DIR, CRASHES_RETIRED_DIR},
ResultExt,
ResultExt, TryFutureExt,
};
use uuid::Uuid;
use welcome::{show_welcome_view, BaseKeymap, FIRST_OPEN};
use workspace::{AppState, WorkspaceStore};
use zed::{
app_menus, build_window_options, ensure_only_instance, handle_cli_connection,
handle_keymap_file_changes, initialize_workspace, IsOnlyInstance, OpenListener, OpenRequest,
handle_keymap_file_changes, initialize_workspace, open_paths_with_positions, IsOnlyInstance,
OpenListener, OpenRequest,
};

#[global_allocator]
Expand Down Expand Up @@ -325,68 +326,82 @@ fn main() {
});
}

fn open_paths_and_log_errs(paths: &[PathBuf], app_state: Arc<AppState>, cx: &mut AppContext) {
let task = workspace::open_paths(&paths, app_state, None, cx);
cx.spawn(|_| async move {
if let Some((_window, results)) = task.await.log_err() {
fn handle_open_request(
request: OpenRequest,
app_state: Arc<AppState>,
cx: &mut AppContext,
) -> bool {
if let Some(connection) = request.cli_connection {
let app_state = app_state.clone();
cx.spawn(move |cx| handle_cli_connection(connection, app_state, cx))
.detach();
return false;
}

let mut task = None;
if !request.open_paths.is_empty() {
let app_state = app_state.clone();
task = Some(cx.spawn(|mut cx| async move {
let (_window, results) =
open_paths_with_positions(&request.open_paths, app_state, &mut cx).await?;
for result in results.into_iter().flatten() {
if let Err(err) = result {
log::error!("Error opening path: {err}",);
}
}
}
})
.detach();
}
anyhow::Ok(())
}));
}

fn handle_open_request(
request: OpenRequest,
app_state: Arc<AppState>,
cx: &mut AppContext,
) -> bool {
let mut triggered_authentication = false;
match request {
OpenRequest::Paths { paths } => open_paths_and_log_errs(&paths, app_state, cx),
OpenRequest::CliConnection { connection } => {
let app_state = app_state.clone();
cx.spawn(move |cx| handle_cli_connection(connection, app_state, cx))
.detach();
}
OpenRequest::JoinChannel { channel_id } => {
triggered_authentication = true;
cx.spawn(|cx| async move {
// ignore errors here, we'll show a generic "not signed in"
let _ = authenticate(app_state.client.clone(), &cx).await;
cx.update(|cx| {
workspace::join_channel(client::ChannelId(channel_id), app_state, None, cx)
})?
.await?;
anyhow::Ok(())
})
.detach_and_log_err(cx);
}
OpenRequest::OpenChannelNotes {
channel_id,
heading,
} => {
triggered_authentication = true;
if !request.open_channel_notes.is_empty() || request.join_channel.is_some() {
cx.spawn(|mut cx| async move {
if let Some(task) = task {
task.await?;
}
let client = app_state.client.clone();
cx.spawn(|mut cx| async move {
// ignore errors here, we'll show a generic "not signed in"
let _ = authenticate(client, &cx).await;
let workspace_window =
workspace::get_any_active_workspace(app_state, cx.clone()).await?;
let workspace = workspace_window.root_view(&cx)?;
cx.update_window(workspace_window.into(), |_, cx| {
ChannelView::open(client::ChannelId(channel_id), heading, workspace, cx)
// we continue even if authentication fails as join_channel/ open channel notes will
// show a visible error message.
authenticate(client, &cx).await.log_err();

if let Some(channel_id) = request.join_channel {
cx.update(|cx| {
workspace::join_channel(
client::ChannelId(channel_id),
app_state.clone(),
None,
cx,
)
})?
.await?;
anyhow::Ok(())
})
.detach_and_log_err(cx);
}

let workspace_window =
workspace::get_any_active_workspace(app_state, cx.clone()).await?;
let workspace = workspace_window.root_view(&cx)?;

let mut promises = Vec::new();
for (channel_id, heading) in request.open_channel_notes {
promises.push(cx.update_window(workspace_window.into(), |_, cx| {
ChannelView::open(
client::ChannelId(channel_id),
heading,
workspace.clone(),
cx,
)
.log_err()
})?)
}
future::join_all(promises).await;
anyhow::Ok(())
})
.detach_and_log_err(cx);
true
} else {
if let Some(task) = task {
task.detach_and_log_err(cx)
}
false
}
triggered_authentication
}

async fn authenticate(client: Arc<Client>, cx: &AsyncAppContext) -> Result<()> {
Expand Down Expand Up @@ -888,7 +903,9 @@ fn collect_url_args(cx: &AppContext) -> Vec<String> {
.filter_map(|arg| match std::fs::canonicalize(Path::new(&arg)) {
Ok(path) => Some(format!("file://{}", path.to_string_lossy())),
Err(error) => {
if let Some(_) = parse_zed_link(&arg, cx) {
if arg.starts_with("file://") {
Some(arg)
} else if let Some(_) = parse_zed_link(&arg, cx) {
Some(arg)
} else {
log::error!("error parsing path argument: {}", error);
Expand Down
Loading

0 comments on commit 977af37

Please sign in to comment.