macos: normalize action working directory paths

Discussion #14048

Directory URLs no longer export a trailing slash through PWD, which
keeps zsh's %1~ prompt expansion from resolving to an empty string.

A shared URL helper removes trailing separators while preserving the
filesystem root and percent-decoding behavior. Tests cover normal,
repeated, encoded, and root paths.
This commit is contained in:
Mitchell Hashimoto
2026-08-27 14:34:15 -07:00
parent e9ad4b1d63
commit 2de1596115
4 changed files with 39 additions and 2 deletions

View File

@@ -74,7 +74,7 @@ struct NewTerminalIntent: AppIntent {
// If we were given a working directory then open that directory
if let url = workingDirectory?.fileURL {
let dir = url.hasDirectoryPath ? url : url.deletingLastPathComponent()
config.workingDirectory = dir.path(percentEncoded: false)
config.workingDirectory = dir.pathWithoutTrailingSlash
}
// Parse environment variables from KEY=VALUE format

View File

@@ -59,7 +59,7 @@ class ServiceProvider: NSObject {
for url in directoryURLs {
var config = Ghostty.SurfaceConfiguration()
config.workingDirectory = url.path(percentEncoded: false)
config.workingDirectory = url.pathWithoutTrailingSlash
switch target {
case .window:

View File

@@ -0,0 +1,12 @@
import Foundation
extension URL {
/// The decoded path with trailing separators removed, except for the root path.
var pathWithoutTrailingSlash: String {
var result = path(percentEncoded: false)
while result.count > 1 && result.hasSuffix("/") {
result.removeLast()
}
return result
}
}

View File

@@ -0,0 +1,25 @@
import Foundation
import Testing
@testable import Ghostty
struct URLTests {
@Test func pathWithoutTrailingSlash() {
let url = URL(string: "file:///tmp/example/")!
#expect(url.pathWithoutTrailingSlash == "/tmp/example")
}
@Test func pathWithoutMultipleTrailingSlashes() {
let url = URL(string: "file:///tmp/example///")!
#expect(url.pathWithoutTrailingSlash == "/tmp/example")
}
@Test func pathWithoutTrailingSlashDecodesPath() {
let url = URL(string: "file:///tmp/example%20directory/")!
#expect(url.pathWithoutTrailingSlash == "/tmp/example directory")
}
@Test func pathWithoutTrailingSlashPreservesRoot() {
let url = URL(string: "file:///")!
#expect(url.pathWithoutTrailingSlash == "/")
}
}