macos: normalize action working directory paths (#14051)

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 15:22:38 -07:00
committed by GitHub
4 changed files with 36 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,9 @@
import Foundation
import System
extension URL {
/// The decoded path with trailing separators removed, except for the root path.
var pathWithoutTrailingSlash: String {
FilePath(path(percentEncoded: false)).string
}
}

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 == "/")
}
}