core: look for resources in "ghostty" subdirectory for "share" paths

Installing resources directly under ${prefix}/share causes conflicts
with other packages. This will become more problematic whenever Ghostty
is opened and becomes packaged in distributions.

Instead, install all resources under a "ghostty" subdirectory (i.e.
${prefix}/share/ghostty). This includes themes, shell integration, and
terminfo files.

Only "/usr/share" style paths use the "ghostty" subdirectory. On macOS,
Ghostty is already isolated within its app bundle, and if
$GHOSTTY_RESOURCES_DIR is set then we assume that points to the actual
resources dir (without needing to append "ghostty" to it).
This commit is contained in:
Gregory Anders
2023-12-20 09:27:37 -06:00
committed by Mitchell Hashimoto
parent e2916f8d63
commit 8751502878
4 changed files with 27 additions and 8 deletions

View File

@ -288,7 +288,7 @@ pub fn build(b: *std.Build) !void {
const install = b.addInstallDirectory(.{
.source_dir = .{ .path = "src/shell-integration" },
.install_dir = .{ .custom = "share" },
.install_subdir = "shell-integration",
.install_subdir = b.pathJoin(&.{ "ghostty", "shell-integration" }),
.exclude_extensions = &.{".md"},
});
b.getInstallStep().dependOn(&install.step);
@ -311,7 +311,7 @@ pub fn build(b: *std.Build) !void {
const install = b.addInstallDirectory(.{
.source_dir = upstream.path("ghostty"),
.install_dir = .{ .custom = "share" },
.install_subdir = "themes",
.install_subdir = b.pathJoin(&.{ "ghostty", "themes" }),
.exclude_extensions = &.{".md"},
});
b.getInstallStep().dependOn(&install.step);

View File

@ -17,8 +17,8 @@ pub const Options = struct {
///
/// Themes require that Ghostty have access to the resources directory.
/// On macOS this is embedded in the app bundle. On Linux, this is usually
/// in `/usr/share`. If you're compiling from source, this is the
/// `zig-out/share` directory. You can also set the `GHOSTTY_RESOURCES_DIR`
/// in `/usr/share/ghostty`. If you're compiling from source, this is the
/// `zig-out/share/ghostty` directory. You can also set the `GHOSTTY_RESOURCES_DIR`
/// environment variable to point to the resources directory. Themes
/// live in the `themes` subdirectory of the resources directory.
pub fn run(alloc: Allocator) !u8 {

View File

@ -44,7 +44,9 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 {
// is valid even on Mac since there is nothing that requires
// Ghostty to be in an app bundle.
if (try maybeDir(&dir_buf, dir, "share", sentinel)) |v| {
return try alloc.dupe(u8, v);
// When found under a "share" prefix, the resources directory is the
// "ghostty" subdirectory.
return try std.fs.path.join(alloc, &.{ v, "ghostty" });
}
}

View File

@ -759,11 +759,28 @@ const Subprocess = struct {
// For now, we just look up a bundled dir but in the future we should
// also load the terminfo database and look for it.
if (opts.resources_dir) |base| {
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const dir = try std.fmt.bufPrint(&buf, "{s}/terminfo", .{base});
try env.put("TERM", opts.config.term);
try env.put("COLORTERM", "truecolor");
try env.put("TERMINFO", dir);
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const terminfo_dir = terminfo_dir: {
// On macOS the terminfo directory can be inside the resources
// directory, so check if that is the case
if (comptime builtin.target.isDarwin()) {
if (try internal_os.maybeDir(&buf, base, "terminfo", "ghostty.termcap")) |v| {
break :terminfo_dir v;
}
}
// Otherwise we assume the terminfo directory is adjacent to the
// resources directory
const parent = std.fs.path.basename(base);
break :terminfo_dir try internal_os.maybeDir(&buf, parent, "terminfo", "ghostty.termcap");
};
if (terminfo_dir) |dir| {
try env.put("TERMINFO", dir);
}
} else {
if (comptime builtin.target.isDarwin()) {
log.warn("ghostty terminfo not found, using xterm-256color", .{});