mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: support env vars for surface config, clean up surface config
This commit is contained in:
@ -385,6 +385,11 @@ typedef struct {
|
|||||||
bool rectangle;
|
bool rectangle;
|
||||||
} ghostty_selection_s;
|
} ghostty_selection_s;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* key;
|
||||||
|
const char* value;
|
||||||
|
} ghostty_env_var_s;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* nsview;
|
void* nsview;
|
||||||
} ghostty_platform_macos_s;
|
} ghostty_platform_macos_s;
|
||||||
@ -406,6 +411,8 @@ typedef struct {
|
|||||||
float font_size;
|
float font_size;
|
||||||
const char* working_directory;
|
const char* working_directory;
|
||||||
const char* command;
|
const char* command;
|
||||||
|
ghostty_env_var_s* env_vars;
|
||||||
|
size_t env_var_count;
|
||||||
} ghostty_surface_config_s;
|
} ghostty_surface_config_s;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -807,7 +814,8 @@ void ghostty_app_set_color_scheme(ghostty_app_t, ghostty_color_scheme_e);
|
|||||||
|
|
||||||
ghostty_surface_config_s ghostty_surface_config_new();
|
ghostty_surface_config_s ghostty_surface_config_new();
|
||||||
|
|
||||||
ghostty_surface_t ghostty_surface_new(ghostty_app_t, ghostty_surface_config_s*);
|
ghostty_surface_t ghostty_surface_new(ghostty_app_t,
|
||||||
|
const ghostty_surface_config_s*);
|
||||||
void ghostty_surface_free(ghostty_surface_t);
|
void ghostty_surface_free(ghostty_surface_t);
|
||||||
void* ghostty_surface_userdata(ghostty_surface_t);
|
void* ghostty_surface_userdata(ghostty_surface_t);
|
||||||
ghostty_app_t ghostty_surface_app(ghostty_surface_t);
|
ghostty_app_t ghostty_surface_app(ghostty_surface_t);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
A50297352DFA0F3400B4E924 /* Double+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50297342DFA0F3300B4E924 /* Double+Extension.swift */; };
|
A50297352DFA0F3400B4E924 /* Double+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50297342DFA0F3300B4E924 /* Double+Extension.swift */; };
|
||||||
A511940F2E050595007258CC /* CloseTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A511940E2E050590007258CC /* CloseTerminalIntent.swift */; };
|
A511940F2E050595007258CC /* CloseTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A511940E2E050590007258CC /* CloseTerminalIntent.swift */; };
|
||||||
A51194112E05A483007258CC /* QuickTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194102E05A480007258CC /* QuickTerminalIntent.swift */; };
|
A51194112E05A483007258CC /* QuickTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194102E05A480007258CC /* QuickTerminalIntent.swift */; };
|
||||||
|
A51194132E05D006007258CC /* Optional+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194122E05D003007258CC /* Optional+Extension.swift */; };
|
||||||
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
||||||
A514C8D72B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
A514C8D72B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
||||||
A514C8D82B54DC6800493A16 /* Ghostty.App.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */; };
|
A514C8D82B54DC6800493A16 /* Ghostty.App.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */; };
|
||||||
@ -153,6 +154,7 @@
|
|||||||
A50297342DFA0F3300B4E924 /* Double+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Extension.swift"; sourceTree = "<group>"; };
|
A50297342DFA0F3300B4E924 /* Double+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Extension.swift"; sourceTree = "<group>"; };
|
||||||
A511940E2E050590007258CC /* CloseTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloseTerminalIntent.swift; sourceTree = "<group>"; };
|
A511940E2E050590007258CC /* CloseTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloseTerminalIntent.swift; sourceTree = "<group>"; };
|
||||||
A51194102E05A480007258CC /* QuickTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalIntent.swift; sourceTree = "<group>"; };
|
A51194102E05A480007258CC /* QuickTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalIntent.swift; sourceTree = "<group>"; };
|
||||||
|
A51194122E05D003007258CC /* Optional+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Optional+Extension.swift"; sourceTree = "<group>"; };
|
||||||
A514C8D52B54A16400493A16 /* Ghostty.Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Config.swift; sourceTree = "<group>"; };
|
A514C8D52B54A16400493A16 /* Ghostty.Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Config.swift; sourceTree = "<group>"; };
|
||||||
A51544FD2DFB1110009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitlebarTabsTahoeTerminalWindow.swift; sourceTree = "<group>"; };
|
A51544FD2DFB1110009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitlebarTabsTahoeTerminalWindow.swift; sourceTree = "<group>"; };
|
||||||
A51544FF2DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TerminalTabsTitlebarTahoe.xib; sourceTree = "<group>"; };
|
A51544FF2DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TerminalTabsTitlebarTahoe.xib; sourceTree = "<group>"; };
|
||||||
@ -506,6 +508,7 @@
|
|||||||
A586366E2DF25D8300E04A10 /* Duration+Extension.swift */,
|
A586366E2DF25D8300E04A10 /* Duration+Extension.swift */,
|
||||||
A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */,
|
A53A29802DB44A5E00B6E02C /* KeyboardShortcut+Extension.swift */,
|
||||||
A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */,
|
A53A297E2DB4480A00B6E02C /* EventModifiers+Extension.swift */,
|
||||||
|
A51194122E05D003007258CC /* Optional+Extension.swift */,
|
||||||
C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */,
|
C159E81C2B66A06B00FDFE9C /* OSColor+Extension.swift */,
|
||||||
A599CDAF2CF103F20049FA26 /* NSAppearance+Extension.swift */,
|
A599CDAF2CF103F20049FA26 /* NSAppearance+Extension.swift */,
|
||||||
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */,
|
A5A2A3CB2D444AB80033CF96 /* NSApplication+Extension.swift */,
|
||||||
@ -786,6 +789,7 @@
|
|||||||
CFBB5FEA2D231E5000FD62EE /* QuickTerminalSpaceBehavior.swift in Sources */,
|
CFBB5FEA2D231E5000FD62EE /* QuickTerminalSpaceBehavior.swift in Sources */,
|
||||||
A54B0CE92D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift in Sources */,
|
A54B0CE92D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift in Sources */,
|
||||||
A5D0AF3D2B37804400D21823 /* CodableBridge.swift in Sources */,
|
A5D0AF3D2B37804400D21823 /* CodableBridge.swift in Sources */,
|
||||||
|
A51194132E05D006007258CC /* Optional+Extension.swift in Sources */,
|
||||||
A5D0AF3B2B36A1DE00D21823 /* TerminalRestorable.swift in Sources */,
|
A5D0AF3B2B36A1DE00D21823 /* TerminalRestorable.swift in Sources */,
|
||||||
C1F26EA72B738B9900404083 /* NSView+Extension.swift in Sources */,
|
C1F26EA72B738B9900404083 /* NSView+Extension.swift in Sources */,
|
||||||
A586366F2DF25D8600E04A10 /* Duration+Extension.swift in Sources */,
|
A586366F2DF25D8600E04A10 /* Duration+Extension.swift in Sources */,
|
||||||
|
@ -419,17 +419,35 @@ extension Ghostty {
|
|||||||
/// Explicit command to set
|
/// Explicit command to set
|
||||||
var command: String? = nil
|
var command: String? = nil
|
||||||
|
|
||||||
|
/// Environment variables to set for the terminal
|
||||||
|
var environmentVariables: [String: String] = [:]
|
||||||
|
|
||||||
init() {}
|
init() {}
|
||||||
|
|
||||||
init(from config: ghostty_surface_config_s) {
|
init(from config: ghostty_surface_config_s) {
|
||||||
self.fontSize = config.font_size
|
self.fontSize = config.font_size
|
||||||
self.workingDirectory = String.init(cString: config.working_directory, encoding: .utf8)
|
if let workingDirectory = config.working_directory {
|
||||||
self.command = String.init(cString: config.command, encoding: .utf8)
|
self.workingDirectory = String.init(cString: workingDirectory, encoding: .utf8)
|
||||||
|
}
|
||||||
|
if let command = config.command {
|
||||||
|
self.command = String.init(cString: command, encoding: .utf8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the C env vars to Swift dictionary
|
||||||
|
if config.env_var_count > 0, let envVars = config.env_vars {
|
||||||
|
for i in 0..<config.env_var_count {
|
||||||
|
let envVar = envVars[i]
|
||||||
|
if let key = String(cString: envVar.key, encoding: .utf8),
|
||||||
|
let value = String(cString: envVar.value, encoding: .utf8) {
|
||||||
|
self.environmentVariables[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the ghostty configuration for this surface configuration struct. The memory
|
/// Provides a C-compatible ghostty configuration within a closure. The configuration
|
||||||
/// in the returned struct is only valid as long as this struct is retained.
|
/// and all its string pointers are only valid within the closure.
|
||||||
func ghosttyConfig(view: SurfaceView) -> ghostty_surface_config_s {
|
func withCValue<T>(view: SurfaceView, _ body: (inout ghostty_surface_config_s) throws -> T) rethrows -> T {
|
||||||
var config = ghostty_surface_config_new()
|
var config = ghostty_surface_config_new()
|
||||||
config.userdata = Unmanaged.passUnretained(view).toOpaque()
|
config.userdata = Unmanaged.passUnretained(view).toOpaque()
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
@ -438,7 +456,6 @@ extension Ghostty {
|
|||||||
nsview: Unmanaged.passUnretained(view).toOpaque()
|
nsview: Unmanaged.passUnretained(view).toOpaque()
|
||||||
))
|
))
|
||||||
config.scale_factor = NSScreen.main!.backingScaleFactor
|
config.scale_factor = NSScreen.main!.backingScaleFactor
|
||||||
|
|
||||||
#elseif os(iOS)
|
#elseif os(iOS)
|
||||||
config.platform_tag = GHOSTTY_PLATFORM_IOS
|
config.platform_tag = GHOSTTY_PLATFORM_IOS
|
||||||
config.platform = ghostty_platform_u(ios: ghostty_platform_ios_s(
|
config.platform = ghostty_platform_u(ios: ghostty_platform_ios_s(
|
||||||
@ -453,15 +470,42 @@ extension Ghostty {
|
|||||||
#error("unsupported target")
|
#error("unsupported target")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if let fontSize = fontSize { config.font_size = fontSize }
|
// Zero is our default value that means to inherit the font size.
|
||||||
if let workingDirectory = workingDirectory {
|
config.font_size = fontSize ?? 0
|
||||||
config.working_directory = (workingDirectory as NSString).utf8String
|
|
||||||
}
|
|
||||||
if let command = command {
|
|
||||||
config.command = (command as NSString).utf8String
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
// Use withCString to ensure strings remain valid for the duration of the closure
|
||||||
|
return try workingDirectory.withCString { cWorkingDir in
|
||||||
|
config.working_directory = cWorkingDir
|
||||||
|
|
||||||
|
return try command.withCString { cCommand in
|
||||||
|
config.command = cCommand
|
||||||
|
|
||||||
|
// Convert dictionary to arrays for easier processing
|
||||||
|
let keys = Array(environmentVariables.keys)
|
||||||
|
let values = Array(environmentVariables.values)
|
||||||
|
|
||||||
|
// Create C strings for all keys and values
|
||||||
|
return try keys.withCStrings { keyCStrings in
|
||||||
|
return try values.withCStrings { valueCStrings in
|
||||||
|
// Create array of ghostty_env_var_s
|
||||||
|
var envVars = Array<ghostty_env_var_s>()
|
||||||
|
envVars.reserveCapacity(environmentVariables.count)
|
||||||
|
for i in 0..<environmentVariables.count {
|
||||||
|
envVars.append(ghostty_env_var_s(
|
||||||
|
key: keyCStrings[i],
|
||||||
|
value: valueCStrings[i]
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return try envVars.withUnsafeMutableBufferPointer { buffer in
|
||||||
|
config.env_vars = buffer.baseAddress
|
||||||
|
config.env_var_count = environmentVariables.count
|
||||||
|
return try body(&config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +290,10 @@ extension Ghostty {
|
|||||||
|
|
||||||
// Setup our surface. This will also initialize all the terminal IO.
|
// Setup our surface. This will also initialize all the terminal IO.
|
||||||
let surface_cfg = baseConfig ?? SurfaceConfiguration()
|
let surface_cfg = baseConfig ?? SurfaceConfiguration()
|
||||||
var surface_cfg_c = surface_cfg.ghosttyConfig(view: self)
|
let surface = surface_cfg.withCValue(view: self) { surface_cfg_c in
|
||||||
guard let surface = ghostty_surface_new(app, &surface_cfg_c) else {
|
ghostty_surface_new(app, &surface_cfg_c)
|
||||||
|
}
|
||||||
|
guard let surface = surface else {
|
||||||
self.error = Ghostty.Error.apiFailed
|
self.error = Ghostty.Error.apiFailed
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,10 @@ extension Ghostty {
|
|||||||
|
|
||||||
// Setup our surface. This will also initialize all the terminal IO.
|
// Setup our surface. This will also initialize all the terminal IO.
|
||||||
let surface_cfg = baseConfig ?? SurfaceConfiguration()
|
let surface_cfg = baseConfig ?? SurfaceConfiguration()
|
||||||
var surface_cfg_c = surface_cfg.ghosttyConfig(view: self)
|
let surface = surface_cfg.withCValue(view: self) { surface_cfg_c in
|
||||||
guard let surface = ghostty_surface_new(app, &surface_cfg_c) else {
|
ghostty_surface_new(app, &surface_cfg_c)
|
||||||
|
}
|
||||||
|
guard let surface = surface else {
|
||||||
// TODO
|
// TODO
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -21,3 +21,28 @@ extension Array {
|
|||||||
return i + 1
|
return i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Array where Element == String {
|
||||||
|
/// Executes a closure with an array of C string pointers.
|
||||||
|
func withCStrings<T>(_ body: ([UnsafePointer<Int8>?]) throws -> T) rethrows -> T {
|
||||||
|
// Handle empty array
|
||||||
|
if isEmpty {
|
||||||
|
return try body([])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursive helper to process strings
|
||||||
|
func helper(index: Int, accumulated: [UnsafePointer<Int8>?], body: ([UnsafePointer<Int8>?]) throws -> T) rethrows -> T {
|
||||||
|
if index == count {
|
||||||
|
return try body(accumulated)
|
||||||
|
} else {
|
||||||
|
return try self[index].withCString { cStr in
|
||||||
|
var newAccumulated = accumulated
|
||||||
|
newAccumulated.append(cStr)
|
||||||
|
return try helper(index: index + 1, accumulated: newAccumulated, body: body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return try helper(index: 0, accumulated: [], body: body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
10
macos/Sources/Helpers/Extensions/Optional+Extension.swift
Normal file
10
macos/Sources/Helpers/Extensions/Optional+Extension.swift
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
extension Optional where Wrapped == String {
|
||||||
|
/// Executes a closure with a C string pointer, handling nil gracefully.
|
||||||
|
func withCString<T>(_ body: (UnsafePointer<Int8>?) throws -> T) rethrows -> T {
|
||||||
|
if let string = self {
|
||||||
|
return try string.withCString(body)
|
||||||
|
} else {
|
||||||
|
return try body(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -376,6 +376,14 @@ pub const PlatformTag = enum(c_int) {
|
|||||||
ios = 2,
|
ios = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const EnvVar = extern struct {
|
||||||
|
/// The name of the environment variable.
|
||||||
|
key: [*:0]const u8,
|
||||||
|
|
||||||
|
/// The value of the environment variable.
|
||||||
|
value: [*:0]const u8,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Surface = struct {
|
pub const Surface = struct {
|
||||||
app: *App,
|
app: *App,
|
||||||
platform: Platform,
|
platform: Platform,
|
||||||
@ -407,7 +415,7 @@ pub const Surface = struct {
|
|||||||
font_size: f32 = 0,
|
font_size: f32 = 0,
|
||||||
|
|
||||||
/// The working directory to load into.
|
/// The working directory to load into.
|
||||||
working_directory: [*:0]const u8 = "",
|
working_directory: ?[*:0]const u8 = null,
|
||||||
|
|
||||||
/// The command to run in the new surface. If this is set then
|
/// The command to run in the new surface. If this is set then
|
||||||
/// the "wait-after-command" option is also automatically set to true,
|
/// the "wait-after-command" option is also automatically set to true,
|
||||||
@ -417,7 +425,11 @@ pub const Surface = struct {
|
|||||||
/// despite Ghostty allowing directly executed commands via config.
|
/// despite Ghostty allowing directly executed commands via config.
|
||||||
/// This is a legacy thing and we should probably change it in the
|
/// This is a legacy thing and we should probably change it in the
|
||||||
/// future once we have a concrete use case.
|
/// future once we have a concrete use case.
|
||||||
command: [*:0]const u8 = "",
|
command: ?[*:0]const u8 = null,
|
||||||
|
|
||||||
|
/// Extra environment variables to set for the surface.
|
||||||
|
env_vars: ?[*]EnvVar = null,
|
||||||
|
env_var_count: usize = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
||||||
@ -443,41 +455,59 @@ pub const Surface = struct {
|
|||||||
defer config.deinit();
|
defer config.deinit();
|
||||||
|
|
||||||
// If we have a working directory from the options then we set it.
|
// If we have a working directory from the options then we set it.
|
||||||
const wd = std.mem.sliceTo(opts.working_directory, 0);
|
if (opts.working_directory) |c_wd| {
|
||||||
if (wd.len > 0) wd: {
|
const wd = std.mem.sliceTo(c_wd, 0);
|
||||||
var dir = std.fs.openDirAbsolute(wd, .{}) catch |err| {
|
if (wd.len > 0) wd: {
|
||||||
log.warn(
|
var dir = std.fs.openDirAbsolute(wd, .{}) catch |err| {
|
||||||
"error opening requested working directory dir={s} err={}",
|
log.warn(
|
||||||
.{ wd, err },
|
"error opening requested working directory dir={s} err={}",
|
||||||
);
|
.{ wd, err },
|
||||||
break :wd;
|
);
|
||||||
};
|
break :wd;
|
||||||
defer dir.close();
|
};
|
||||||
|
defer dir.close();
|
||||||
|
|
||||||
const stat = dir.stat() catch |err| {
|
const stat = dir.stat() catch |err| {
|
||||||
log.warn(
|
log.warn(
|
||||||
"failed to stat requested working directory dir={s} err={}",
|
"failed to stat requested working directory dir={s} err={}",
|
||||||
.{ wd, err },
|
.{ wd, err },
|
||||||
);
|
);
|
||||||
break :wd;
|
break :wd;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (stat.kind != .directory) {
|
if (stat.kind != .directory) {
|
||||||
log.warn(
|
log.warn(
|
||||||
"requested working directory is not a directory dir={s}",
|
"requested working directory is not a directory dir={s}",
|
||||||
.{wd},
|
.{wd},
|
||||||
);
|
);
|
||||||
break :wd;
|
break :wd;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.@"working-directory" = wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.@"working-directory" = wd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a command from the options then we set it.
|
// If we have a command from the options then we set it.
|
||||||
const cmd = std.mem.sliceTo(opts.command, 0);
|
if (opts.command) |c_command| {
|
||||||
if (cmd.len > 0) {
|
const cmd = std.mem.sliceTo(c_command, 0);
|
||||||
config.command = .{ .shell = cmd };
|
if (cmd.len > 0) {
|
||||||
config.@"wait-after-command" = true;
|
config.command = .{ .shell = cmd };
|
||||||
|
config.@"wait-after-command" = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply any environment variables that were requested.
|
||||||
|
if (opts.env_var_count > 0) {
|
||||||
|
const alloc = config.arenaAlloc();
|
||||||
|
for (opts.env_vars.?[0..opts.env_var_count]) |env_var| {
|
||||||
|
const key = std.mem.sliceTo(env_var.key, 0);
|
||||||
|
const value = std.mem.sliceTo(env_var.value, 0);
|
||||||
|
try config.env.map.put(
|
||||||
|
alloc,
|
||||||
|
try alloc.dupeZ(u8, key),
|
||||||
|
try alloc.dupeZ(u8, value),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize our surface right away. We're given a view that is
|
// Initialize our surface right away. We're given a view that is
|
||||||
|
@ -3004,6 +3004,11 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the arena allocator associated with the configuration.
|
||||||
|
pub fn arenaAlloc(self: *Config) Allocator {
|
||||||
|
return self._arena.?.allocator();
|
||||||
|
}
|
||||||
|
|
||||||
/// Change the state of conditionals and reload the configuration
|
/// Change the state of conditionals and reload the configuration
|
||||||
/// based on the new state. This returns a new configuration based
|
/// based on the new state. This returns a new configuration based
|
||||||
/// on the new state. The caller must free the old configuration if they
|
/// on the new state. The caller must free the old configuration if they
|
||||||
|
Reference in New Issue
Block a user