mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
plumb through the resources dir to termio
This commit is contained in:
@ -182,6 +182,7 @@ pub fn init(
|
|||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
config: *const configpkg.Config,
|
config: *const configpkg.Config,
|
||||||
app_mailbox: App.Mailbox,
|
app_mailbox: App.Mailbox,
|
||||||
|
app_resources_dir: ?[]const u8,
|
||||||
rt_surface: *apprt.runtime.Surface,
|
rt_surface: *apprt.runtime.Surface,
|
||||||
) !void {
|
) !void {
|
||||||
// Initialize our renderer with our initialized surface.
|
// Initialize our renderer with our initialized surface.
|
||||||
@ -405,6 +406,7 @@ pub fn init(
|
|||||||
.screen_size = screen_size,
|
.screen_size = screen_size,
|
||||||
.full_config = config,
|
.full_config = config,
|
||||||
.config = try termio.Impl.DerivedConfig.init(alloc, config),
|
.config = try termio.Impl.DerivedConfig.init(alloc, config),
|
||||||
|
.resources_dir = app_resources_dir,
|
||||||
.renderer_state = &self.renderer_state,
|
.renderer_state = &self.renderer_state,
|
||||||
.renderer_wakeup = render_thread.wakeup,
|
.renderer_wakeup = render_thread.wakeup,
|
||||||
.renderer_mailbox = render_thread.mailbox,
|
.renderer_mailbox = render_thread.mailbox,
|
||||||
|
@ -363,6 +363,7 @@ pub const Surface = struct {
|
|||||||
app.app.alloc,
|
app.app.alloc,
|
||||||
&config,
|
&config,
|
||||||
.{ .rt_app = app, .mailbox = &app.app.mailbox },
|
.{ .rt_app = app, .mailbox = &app.app.mailbox },
|
||||||
|
app.app.resources_dir,
|
||||||
self,
|
self,
|
||||||
);
|
);
|
||||||
errdefer self.core_surface.deinit();
|
errdefer self.core_surface.deinit();
|
||||||
|
@ -765,6 +765,7 @@ pub const Surface = struct {
|
|||||||
self.app.core_app.alloc,
|
self.app.core_app.alloc,
|
||||||
&config,
|
&config,
|
||||||
.{ .rt_app = self.app, .mailbox = &self.app.core_app.mailbox },
|
.{ .rt_app = self.app, .mailbox = &self.app.core_app.mailbox },
|
||||||
|
self.app.core_app.resources_dir,
|
||||||
self,
|
self,
|
||||||
);
|
);
|
||||||
errdefer self.core_surface.deinit();
|
errdefer self.core_surface.deinit();
|
||||||
|
@ -544,26 +544,12 @@ const Subprocess = struct {
|
|||||||
};
|
};
|
||||||
errdefer env.deinit();
|
errdefer env.deinit();
|
||||||
|
|
||||||
// Get our bundled resources directory, if it exists. We use this
|
// If we have a resources dir then set our env var
|
||||||
// for terminfo, shell-integration, etc.
|
|
||||||
const resources_key = "GHOSTTY_RESOURCES_DIR";
|
const resources_key = "GHOSTTY_RESOURCES_DIR";
|
||||||
const resources_dir = dir: {
|
if (opts.resources_dir) |dir| {
|
||||||
if (env.get(resources_key)) |dir| {
|
log.info("found Ghostty resources dir: {s}", .{dir});
|
||||||
if (dir.len > 0) {
|
try env.put(resources_key, dir);
|
||||||
log.info("using Ghostty resources dir from env var: {s}", .{dir});
|
}
|
||||||
break :dir dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (try resourcesDir(alloc)) |dir| {
|
|
||||||
log.info("found Ghostty resources dir: {s}", .{dir});
|
|
||||||
try env.put(resources_key, dir);
|
|
||||||
break :dir dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.warn("Ghostty resources dir not found, some features disabled", .{});
|
|
||||||
break :dir null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set our TERM var. This is a bit complicated because we want to use
|
// Set our TERM var. This is a bit complicated because we want to use
|
||||||
// the ghostty TERM value but we want to only do that if we have
|
// the ghostty TERM value but we want to only do that if we have
|
||||||
@ -571,7 +557,9 @@ const Subprocess = struct {
|
|||||||
//
|
//
|
||||||
// For now, we just look up a bundled dir but in the future we should
|
// For now, we just look up a bundled dir but in the future we should
|
||||||
// also load the terminfo database and look for it.
|
// also load the terminfo database and look for it.
|
||||||
if (try terminfoDir(alloc, resources_dir)) |dir| {
|
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", "xterm-ghostty");
|
try env.put("TERM", "xterm-ghostty");
|
||||||
try env.put("COLORTERM", "truecolor");
|
try env.put("COLORTERM", "truecolor");
|
||||||
try env.put("TERMINFO", dir);
|
try env.put("TERMINFO", dir);
|
||||||
@ -641,7 +629,7 @@ const Subprocess = struct {
|
|||||||
.zsh => .zsh,
|
.zsh => .zsh,
|
||||||
};
|
};
|
||||||
|
|
||||||
const dir = resources_dir orelse break :shell null;
|
const dir = opts.resources_dir orelse break :shell null;
|
||||||
break :shell try shell_integration.setup(
|
break :shell try shell_integration.setup(
|
||||||
dir,
|
dir,
|
||||||
final_path,
|
final_path,
|
||||||
@ -860,73 +848,6 @@ const Subprocess = struct {
|
|||||||
fn killCommandFlatpak(command: *FlatpakHostCommand) !void {
|
fn killCommandFlatpak(command: *FlatpakHostCommand) !void {
|
||||||
try command.signal(c.SIGHUP, true);
|
try command.signal(c.SIGHUP, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the directory to the terminfo database, if it can be detected.
|
|
||||||
/// The memory returned can't be easily freed so the alloc should be
|
|
||||||
/// an arena or something similar.
|
|
||||||
fn terminfoDir(alloc: Allocator, base: ?[]const u8) !?[]const u8 {
|
|
||||||
const dir = base orelse return null;
|
|
||||||
return try tryDir(alloc, dir, "terminfo", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the directory to the bundled resources directory, if it
|
|
||||||
/// exists (not all platforms or packages have it).
|
|
||||||
///
|
|
||||||
/// The memory returned can't be easily freed so the alloc should be
|
|
||||||
/// an arena or something similar.
|
|
||||||
fn resourcesDir(alloc: Allocator) !?[]const u8 {
|
|
||||||
// This is the sentinel value we look for in the path to know
|
|
||||||
// we've found the resources directory.
|
|
||||||
const sentinel = "terminfo/ghostty.termcap";
|
|
||||||
|
|
||||||
// Get the path to our running binary
|
|
||||||
var exe_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
|
||||||
var exe: []const u8 = std.fs.selfExePath(&exe_buf) catch return null;
|
|
||||||
|
|
||||||
// We have an exe path! Climb the tree looking for the terminfo
|
|
||||||
// bundle as we expect it.
|
|
||||||
while (std.fs.path.dirname(exe)) |dir| {
|
|
||||||
exe = dir;
|
|
||||||
|
|
||||||
// On MacOS, we look for the app bundle path.
|
|
||||||
if (comptime builtin.target.isDarwin()) {
|
|
||||||
if (try tryDir(alloc, dir, "Contents/Resources", sentinel)) |v| {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// On all platforms, we look for a /usr/share style path. This
|
|
||||||
// is valid even on Mac since there is nothing that requires
|
|
||||||
// Ghostty to be in an app bundle.
|
|
||||||
if (try tryDir(alloc, dir, "share", sentinel)) |v| {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Little helper to check if the "base/sub/suffix" directory exists and
|
|
||||||
/// if so, duplicate the "base/sub" path and return it.
|
|
||||||
fn tryDir(
|
|
||||||
alloc: Allocator,
|
|
||||||
base: []const u8,
|
|
||||||
sub: []const u8,
|
|
||||||
suffix: []const u8,
|
|
||||||
) !?[]const u8 {
|
|
||||||
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
|
||||||
const path = try std.fmt.bufPrint(&buf, "{s}/{s}/{s}", .{ base, sub, suffix });
|
|
||||||
|
|
||||||
if (std.fs.accessAbsolute(path, .{})) {
|
|
||||||
const len = path.len - suffix.len - 1;
|
|
||||||
return try alloc.dupe(u8, path[0..len]);
|
|
||||||
} else |_| {
|
|
||||||
// Folder doesn't exist. If a different error happens its okay
|
|
||||||
// we just ignore it and move on.
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The read thread sits in a loop doing the following pseudo code:
|
/// The read thread sits in a loop doing the following pseudo code:
|
||||||
|
@ -20,6 +20,9 @@ full_config: *const Config,
|
|||||||
/// The derived configuration for this termio implementation.
|
/// The derived configuration for this termio implementation.
|
||||||
config: termio.Impl.DerivedConfig,
|
config: termio.Impl.DerivedConfig,
|
||||||
|
|
||||||
|
/// The application resources directory.
|
||||||
|
resources_dir: ?[]const u8,
|
||||||
|
|
||||||
/// The render state. The IO implementation can modify anything here. The
|
/// The render state. The IO implementation can modify anything here. The
|
||||||
/// surface thread will setup the initial "terminal" pointer but the IO impl
|
/// surface thread will setup the initial "terminal" pointer but the IO impl
|
||||||
/// is free to change that if that is useful (i.e. doing some sort of dual
|
/// is free to change that if that is useful (i.e. doing some sort of dual
|
||||||
|
Reference in New Issue
Block a user