Merge pull request #2074 from zed-industries/decode-openurl-to-pathbuf

Julia created

Decode URL from `openURLs` to handle percent encoded paths

Change summary

Cargo.lock                               | 1 +
crates/gpui/src/platform/mac/platform.rs | 4 ++--
crates/zed/Cargo.toml                    | 1 +
crates/zed/src/main.rs                   | 7 +++++--
4 files changed, 9 insertions(+), 4 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -8310,6 +8310,7 @@ dependencies = [
  "tree-sitter-typescript",
  "unindent",
  "url",
+ "urlencoding",
  "util",
  "vim",
  "workspace",

crates/gpui/src/platform/mac/platform.rs 🔗

@@ -853,8 +853,8 @@ extern "C" fn open_urls(this: &mut Object, _: Sel, _: id, urls: id) {
         (0..urls.count())
             .into_iter()
             .filter_map(|i| {
-                let path = urls.objectAtIndex(i);
-                match CStr::from_ptr(path.absoluteString().UTF8String() as *mut c_char).to_str() {
+                let url = urls.objectAtIndex(i);
+                match CStr::from_ptr(url.absoluteString().UTF8String() as *mut c_char).to_str() {
                     Ok(string) => Some(string.to_string()),
                     Err(err) => {
                         log::error!("error converting path to string: {}", err);

crates/zed/Cargo.toml 🔗

@@ -110,6 +110,7 @@ tree-sitter-html = "0.19.0"
 tree-sitter-scheme = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "af0fd1fa452cb2562dc7b5c8a8c55551c39273b9"}
 tree-sitter-racket = { git = "https://github.com/zed-industries/tree-sitter-racket", rev = "eb010cf2c674c6fd9a6316a84e28ef90190fe51a"}
 url = "2.2"
+urlencoding = "2.1.2"
 
 [dev-dependencies]
 call = { path = "../call", features = ["test-support"] }

crates/zed/src/main.rs 🔗

@@ -32,8 +32,8 @@ use settings::{
 };
 use simplelog::ConfigBuilder;
 use smol::process::Command;
-use std::fs::OpenOptions;
 use std::{env, ffi::OsStr, panic, path::PathBuf, sync::Arc, thread, time::Duration};
+use std::{fs::OpenOptions, os::unix::prelude::OsStrExt};
 use terminal_view::{get_working_directory, TerminalView};
 
 use fs::RealFs;
@@ -90,7 +90,10 @@ fn main() {
             let paths: Vec<_> = urls
                 .iter()
                 .flat_map(|url| url.strip_prefix("file://"))
-                .map(|path| PathBuf::from(path))
+                .map(|url| {
+                    let decoded = urlencoding::decode_binary(url.as_bytes());
+                    PathBuf::from(OsStr::from_bytes(decoded.as_ref()))
+                })
                 .collect();
             open_paths_tx
                 .unbounded_send(paths)