diff --git a/src/config/Config.zig b/src/config/Config.zig index e2843508a..d88347e2e 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1809,14 +1809,10 @@ pub fn deinit(self: *Config) void { /// Load the configuration according to the default rules: /// /// 1. Defaults -/// 2. Configuration Files -/// 3. CLI flags -/// 4. Recursively defined configuration files -/// -/// Configuration files are loaded in the follow order: -/// -/// 1. XDG Config File -/// 2. "Application Support" Config File on macOS +/// 2. XDG config dir +/// 3. "Application Support" directory (macOS only) +/// 4. CLI flags +/// 5. Recursively defined configuration files /// pub fn load(alloc_gpa: Allocator) !Config { var result = try default(alloc_gpa); @@ -2423,8 +2419,8 @@ pub fn loadDefaultFiles(self: *Config, alloc: Allocator) !void { defer alloc.free(xdg_path); self.loadOptionalFile(alloc, xdg_path); - if (builtin.os.tag == .macos) { - const app_support_path = try internal_os.macos.getAppSupportDir(alloc, "config"); + if (comptime builtin.os.tag == .macos) { + const app_support_path = try internal_os.macos.appSupportDir(alloc, "config"); defer alloc.free(app_support_path); self.loadOptionalFile(alloc, app_support_path); } diff --git a/src/os/macos.zig b/src/os/macos.zig index 62ba87c5a..fe312c6e1 100644 --- a/src/os/macos.zig +++ b/src/os/macos.zig @@ -4,15 +4,9 @@ const assert = std.debug.assert; const objc = @import("objc"); const Allocator = std.mem.Allocator; -pub const NSOperatingSystemVersion = extern struct { - major: i64, - minor: i64, - patch: i64, -}; - /// Verifies that the running macOS system version is at least the given version. pub fn isAtLeastVersion(major: i64, minor: i64, patch: i64) bool { - assert(builtin.target.isDarwin()); + comptime assert(builtin.target.isDarwin()); const NSProcessInfo = objc.getClass("NSProcessInfo").?; const info = NSProcessInfo.msgSend(objc.Object, objc.sel("processInfo"), .{}); @@ -21,20 +15,24 @@ pub fn isAtLeastVersion(major: i64, minor: i64, patch: i64) bool { }); } -pub const NSSearchPathDirectory = enum(c_ulong) { - NSApplicationSupportDirectory = 14, -}; +pub const AppSupportDirError = Allocator.Error || error{AppleAPIFailed}; -pub const NSSearchPathDomainMask = enum(c_ulong) { - NSUserDomainMask = 1, -}; +/// Return the path to the application support directory for Ghostty +/// with the given sub path joined. This allocates the result using the +/// given allocator. +pub fn appSupportDir( + alloc: Allocator, + sub_path: []const u8, +) AppSupportDirError![]u8 { + comptime assert(builtin.target.isDarwin()); -pub fn getAppSupportDir(alloc: Allocator, sub_path: []const u8) ![]u8 { - assert(builtin.target.isDarwin()); - - const err: ?*anyopaque = undefined; const NSFileManager = objc.getClass("NSFileManager").?; - const manager = NSFileManager.msgSend(objc.Object, objc.sel("defaultManager"), .{}); + const manager = NSFileManager.msgSend( + objc.Object, + objc.sel("defaultManager"), + .{}, + ); + const url = manager.msgSend( objc.Object, objc.sel("URLForDirectory:inDomain:appropriateForURL:create:error:"), @@ -43,12 +41,36 @@ pub fn getAppSupportDir(alloc: Allocator, sub_path: []const u8) ![]u8 { NSSearchPathDomainMask.NSUserDomainMask, @as(?*anyopaque, null), true, - &err, + @as(?*anyopaque, null), }, ); + + // I don't think this is possible but just in case. + if (url.value == null) return error.AppleAPIFailed; + + // Get the UTF-8 string from the URL. const path = url.getProperty(objc.Object, "path"); - const c_str = path.getProperty([*:0]const u8, "UTF8String"); + const c_str = path.getProperty(?[*:0]const u8, "UTF8String") orelse + return error.AppleAPIFailed; const app_support_dir = std.mem.sliceTo(c_str, 0); - return try std.fs.path.join(alloc, &.{ app_support_dir, "com.mitchellh.ghostty", sub_path }); + return try std.fs.path.join(alloc, &.{ + app_support_dir, + "com.mitchellh.ghostty", + sub_path, + }); } + +pub const NSOperatingSystemVersion = extern struct { + major: i64, + minor: i64, + patch: i64, +}; + +pub const NSSearchPathDirectory = enum(c_ulong) { + NSApplicationSupportDirectory = 14, +}; + +pub const NSSearchPathDomainMask = enum(c_ulong) { + NSUserDomainMask = 1, +};