mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: implement config reloading callback
This commit is contained in:
@ -243,6 +243,7 @@ int ghostty_init(void);
|
||||
|
||||
ghostty_config_t ghostty_config_new();
|
||||
void ghostty_config_free(ghostty_config_t);
|
||||
void ghostty_config_load_cli_args(ghostty_config_t);
|
||||
void ghostty_config_load_string(ghostty_config_t, const char *, uintptr_t);
|
||||
void ghostty_config_load_default_files(ghostty_config_t);
|
||||
void ghostty_config_load_recursive_files(ghostty_config_t);
|
||||
|
@ -12,12 +12,25 @@ extension Ghostty {
|
||||
/// The readiness value of the state.
|
||||
@Published var readiness: AppReadiness = .loading
|
||||
|
||||
/// The ghostty global configuration.
|
||||
var config: ghostty_config_t? = nil
|
||||
/// The ghostty global configuration. This should only be changed when it is definitely
|
||||
/// safe to change. It is definite safe to change only when the embedded app runtime
|
||||
/// in Ghostty says so (usually, only in a reload configuration callback).
|
||||
var config: ghostty_config_t? = nil {
|
||||
didSet {
|
||||
// Free the old value whenever we change
|
||||
guard let old = oldValue else { return }
|
||||
ghostty_config_free(old)
|
||||
}
|
||||
}
|
||||
|
||||
/// The ghostty app instance. We only have one of these for the entire app, although I guess
|
||||
/// in theory you can have multiple... I don't know why you would...
|
||||
var app: ghostty_app_t? = nil
|
||||
var app: ghostty_app_t? = nil {
|
||||
didSet {
|
||||
guard let old = oldValue else { return }
|
||||
ghostty_app_free(old)
|
||||
}
|
||||
}
|
||||
|
||||
/// Cached clipboard string for `read_clipboard` callback.
|
||||
private var cached_clipboard_string: String? = nil
|
||||
@ -31,24 +44,12 @@ extension Ghostty {
|
||||
}
|
||||
|
||||
// Initialize the global configuration.
|
||||
guard let cfg = ghostty_config_new() else {
|
||||
GhosttyApp.logger.critical("ghostty_config_new failed")
|
||||
guard let cfg = Self.reloadConfig() else {
|
||||
readiness = .error
|
||||
return
|
||||
}
|
||||
self.config = cfg;
|
||||
|
||||
// Load our configuration files from the home directory.
|
||||
ghostty_config_load_default_files(cfg);
|
||||
ghostty_config_load_recursive_files(cfg);
|
||||
|
||||
// TODO: we'd probably do some config loading here... for now we'd
|
||||
// have to do this synchronously. When we support config updating we can do
|
||||
// this async and update later.
|
||||
|
||||
// Finalize will make our defaults available.
|
||||
ghostty_config_finalize(cfg)
|
||||
|
||||
// Create our "runtime" config. The "runtime" is the configuration that ghostty
|
||||
// uses to interface with the application runtime environment.
|
||||
var runtime_cfg = ghostty_runtime_config_s(
|
||||
@ -75,8 +76,32 @@ extension Ghostty {
|
||||
}
|
||||
|
||||
deinit {
|
||||
ghostty_app_free(app)
|
||||
ghostty_config_free(config)
|
||||
// This will force the didSet callbacks to run which free.
|
||||
self.app = nil
|
||||
self.config = nil
|
||||
}
|
||||
|
||||
/// Initializes a new configuration and loads all the values.
|
||||
static func reloadConfig() -> ghostty_config_t? {
|
||||
// Initialize the global configuration.
|
||||
guard let cfg = ghostty_config_new() else {
|
||||
GhosttyApp.logger.critical("ghostty_config_new failed")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Load our configuration files from the home directory.
|
||||
ghostty_config_load_default_files(cfg);
|
||||
ghostty_config_load_cli_args(cfg);
|
||||
ghostty_config_load_recursive_files(cfg);
|
||||
|
||||
// TODO: we'd probably do some config loading here... for now we'd
|
||||
// have to do this synchronously. When we support config updating we can do
|
||||
// this async and update later.
|
||||
|
||||
// Finalize will make our defaults available.
|
||||
ghostty_config_finalize(cfg)
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func appTick() {
|
||||
@ -142,10 +167,17 @@ extension Ghostty {
|
||||
}
|
||||
|
||||
static func reloadConfig(_ userdata: UnsafeMutableRawPointer?) -> ghostty_config_t? {
|
||||
// TODO: implement config reloading in the mac app
|
||||
guard let newConfig = AppState.reloadConfig() else {
|
||||
GhosttyApp.logger.warning("failed to reload configuration")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Assign the new config. This will automatically free the old config.
|
||||
// It is safe to free the old config from within this function call.
|
||||
let state = Unmanaged<AppState>.fromOpaque(userdata!).takeUnretainedValue()
|
||||
_ = state
|
||||
return nil
|
||||
state.config = newConfig
|
||||
|
||||
return newConfig
|
||||
}
|
||||
|
||||
static func wakeup(_ userdata: UnsafeMutableRawPointer?) {
|
||||
|
@ -217,11 +217,7 @@ pub const Config = struct {
|
||||
try result.loadDefaultFiles(alloc_gpa);
|
||||
|
||||
// Parse the config from the CLI args
|
||||
{
|
||||
var iter = try std.process.argsWithAllocator(alloc_gpa);
|
||||
defer iter.deinit();
|
||||
try cli_args.parse(Config, alloc_gpa, &result, &iter);
|
||||
}
|
||||
try result.loadCliArgs(alloc_gpa);
|
||||
|
||||
// Parse the config files that were added from our file and CLI args.
|
||||
try result.loadRecursiveFiles(alloc_gpa);
|
||||
@ -564,6 +560,14 @@ pub const Config = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// Load and parse the CLI args.
|
||||
pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void {
|
||||
// Parse the config from the CLI args
|
||||
var iter = try std.process.argsWithAllocator(alloc_gpa);
|
||||
defer iter.deinit();
|
||||
try cli_args.parse(Config, alloc_gpa, self, &iter);
|
||||
}
|
||||
|
||||
/// Load and parse the config files that were added in the "config-file" key.
|
||||
pub fn loadRecursiveFiles(self: *Config, alloc: Allocator) !void {
|
||||
// TODO(mitchellh): we should parse the files form the homedir first
|
||||
@ -1190,6 +1194,13 @@ pub const CAPI = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// Load the configuration from the CLI args.
|
||||
export fn ghostty_config_load_cli_args(self: *Config) void {
|
||||
self.loadCliArgs(global.alloc) catch |err| {
|
||||
log.err("error loading config err={}", .{err});
|
||||
};
|
||||
}
|
||||
|
||||
/// Load the configuration from a string in the same format as
|
||||
/// the file-based syntax for the desktop version of the terminal.
|
||||
export fn ghostty_config_load_string(
|
||||
|
Reference in New Issue
Block a user