aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/config/file_load.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/config/file_load.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/config/file_load.zig')
-rw-r--r--vendor/libghostty-vt/src/config/file_load.zig166
1 files changed, 166 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/config/file_load.zig b/vendor/libghostty-vt/src/config/file_load.zig
new file mode 100644
index 00000000..7885de32
--- /dev/null
+++ b/vendor/libghostty-vt/src/config/file_load.zig
@@ -0,0 +1,166 @@
+const std = @import("std");
+const builtin = @import("builtin");
+const assert = @import("../quirks.zig").inlineAssert;
+const Allocator = std.mem.Allocator;
+const internal_os = @import("../os/main.zig");
+
+const log = std.log.scoped(.config);
+
+/// Default path for the XDG home configuration file. Returned value
+/// must be freed by the caller.
+pub fn defaultXdgPath(alloc: Allocator) ![]const u8 {
+ return try internal_os.xdg.config(
+ alloc,
+ .{ .subdir = "ghostty/config.ghostty" },
+ );
+}
+
+/// Ghostty <1.3.0 default path for the XDG home configuration file.
+/// Returned value must be freed by the caller.
+pub fn legacyDefaultXdgPath(alloc: Allocator) ![]const u8 {
+ return try internal_os.xdg.config(
+ alloc,
+ .{ .subdir = "ghostty/config" },
+ );
+}
+
+/// Preferred default path for the XDG home configuration file.
+/// Returned value must be freed by the caller.
+pub fn preferredXdgPath(alloc: Allocator) ![]const u8 {
+ // If the XDG path exists, use that.
+ const xdg_path = try defaultXdgPath(alloc);
+ if (open(xdg_path)) |f| {
+ f.close();
+ return xdg_path;
+ } else |_| {}
+
+ // Try the legacy path
+ errdefer alloc.free(xdg_path);
+ const legacy_xdg_path = try legacyDefaultXdgPath(alloc);
+ if (open(legacy_xdg_path)) |f| {
+ f.close();
+ alloc.free(xdg_path);
+ return legacy_xdg_path;
+ } else |_| {}
+
+ // Legacy path and XDG path both don't exist. Return the
+ // new one.
+ alloc.free(legacy_xdg_path);
+ return xdg_path;
+}
+
+/// Default path for the macOS Application Support configuration file.
+/// Returned value must be freed by the caller.
+pub fn defaultAppSupportPath(alloc: Allocator) ![]const u8 {
+ return try internal_os.macos.appSupportDir(alloc, "config.ghostty");
+}
+
+/// Ghostty <1.3.0 default path for the macOS Application Support
+/// configuration file. Returned value must be freed by the caller.
+pub fn legacyDefaultAppSupportPath(alloc: Allocator) ![]const u8 {
+ return try internal_os.macos.appSupportDir(alloc, "config");
+}
+
+/// Preferred default path for the macOS Application Support configuration file.
+/// Returned value must be freed by the caller.
+pub fn preferredAppSupportPath(alloc: Allocator) ![]const u8 {
+ // If the app support path exists, use that.
+ const app_support_path = try defaultAppSupportPath(alloc);
+ if (open(app_support_path)) |f| {
+ f.close();
+ return app_support_path;
+ } else |_| {}
+
+ // Try the legacy path
+ errdefer alloc.free(app_support_path);
+ const legacy_app_support_path = try legacyDefaultAppSupportPath(alloc);
+ if (open(legacy_app_support_path)) |f| {
+ f.close();
+ alloc.free(app_support_path);
+ return legacy_app_support_path;
+ } else |_| {}
+
+ // Legacy path and app support path both don't exist. Return the
+ // new one.
+ alloc.free(legacy_app_support_path);
+ return app_support_path;
+}
+
+/// Returns the path to the preferred default configuration file.
+/// This is the file where users should place their configuration.
+///
+/// This doesn't create or populate the file with any default
+/// contents; downstream callers must handle this.
+///
+/// The returned value must be freed by the caller.
+pub fn preferredDefaultFilePath(alloc: Allocator) ![]const u8 {
+ switch (builtin.os.tag) {
+ .macos => {
+ // macOS prefers the Application Support directory
+ // if it exists.
+ const app_support_path = try preferredAppSupportPath(alloc);
+ const app_support_file = open(app_support_path) catch {
+ // Try the XDG path if it exists
+ const xdg_path = try preferredXdgPath(alloc);
+ const xdg_file = open(xdg_path) catch {
+ // If neither file exists, use app support
+ alloc.free(xdg_path);
+ return app_support_path;
+ };
+ xdg_file.close();
+ alloc.free(app_support_path);
+ return xdg_path;
+ };
+ app_support_file.close();
+ return app_support_path;
+ },
+
+ // All other platforms use XDG only
+ else => return try preferredXdgPath(alloc),
+ }
+}
+
+const OpenFileError = error{
+ FileNotFound,
+ FileIsEmpty,
+ FileOpenFailed,
+ NotAFile,
+};
+
+/// Opens the file at the given path and returns the file handle
+/// if it exists and is non-empty. This also constrains the possible
+/// errors to a smaller set that we can explicitly handle.
+pub fn open(path: []const u8) OpenFileError!std.fs.File {
+ assert(std.fs.path.isAbsolute(path));
+
+ var file = std.fs.openFileAbsolute(
+ path,
+ .{},
+ ) catch |err| switch (err) {
+ error.FileNotFound => return OpenFileError.FileNotFound,
+ else => {
+ log.warn("unexpected file open error path={s} err={}", .{
+ path,
+ err,
+ });
+ return OpenFileError.FileOpenFailed;
+ },
+ };
+ errdefer file.close();
+
+ const stat = file.stat() catch |err| {
+ log.warn("error getting file stat path={s} err={}", .{
+ path,
+ err,
+ });
+ return OpenFileError.FileOpenFailed;
+ };
+ switch (stat.kind) {
+ .file => {},
+ else => return OpenFileError.NotAFile,
+ }
+
+ if (stat.size == 0) return OpenFileError.FileIsEmpty;
+
+ return file;
+}