mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
apprt/embedded: ghostty_cli_main
This commit is contained in:
@ -351,6 +351,7 @@ typedef struct {
|
|||||||
// Published API
|
// Published API
|
||||||
|
|
||||||
int ghostty_init(void);
|
int ghostty_init(void);
|
||||||
|
void ghostty_cli_main(uintptr_t, char **);
|
||||||
ghostty_info_s ghostty_info(void);
|
ghostty_info_s ghostty_info(void);
|
||||||
|
|
||||||
ghostty_config_t ghostty_config_new();
|
ghostty_config_t ghostty_config_new();
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import AppKit
|
import AppKit
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
import GhosttyKit
|
||||||
|
|
||||||
// We put the GHOSTTY_MAC_APP env var into the Info.plist to detect
|
// We put the GHOSTTY_MAC_APP env var into the Info.plist to detect
|
||||||
// whether we launch from the app or not. A user can fake this if
|
// whether we launch from the app or not. A user can fake this if
|
||||||
// they want but they're doing so at their own detriment...
|
// they want but they're doing so at their own detriment...
|
||||||
let process = ProcessInfo.processInfo
|
let process = ProcessInfo.processInfo
|
||||||
if (process.environment["GHOSTTY_MAC_APP"] == "") {
|
if (process.environment["GHOSTTY_MAC_APP"] == "") {
|
||||||
AppDelegate.logger.warning("NOT IN THE MAC APP")
|
ghostty_cli_main(UInt(CommandLine.argc), CommandLine.unsafeArgv)
|
||||||
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
|
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
|
||||||
|
40
src/main.zig
40
src/main.zig
@ -23,7 +23,13 @@ const Ghostty = @import("main_c.zig").Ghostty;
|
|||||||
/// rely on allocators being passed in as parameters.
|
/// rely on allocators being passed in as parameters.
|
||||||
pub var state: GlobalState = undefined;
|
pub var state: GlobalState = undefined;
|
||||||
|
|
||||||
pub fn main() !void {
|
/// The return type for main() depends on the build artifact.
|
||||||
|
const MainReturn = switch (build_config.artifact) {
|
||||||
|
.lib => noreturn,
|
||||||
|
else => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() !MainReturn {
|
||||||
// We first start by initializing our global state. This will setup
|
// We first start by initializing our global state. This will setup
|
||||||
// process-level state we need to run the terminal. The reason we use
|
// process-level state we need to run the terminal. The reason we use
|
||||||
// a global is because the C API needs to be able to access this state;
|
// a global is because the C API needs to be able to access this state;
|
||||||
@ -67,6 +73,24 @@ pub fn main() !void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (comptime build_config.app_runtime == .none) {
|
||||||
|
const stdout = std.io.getStdOut().writer();
|
||||||
|
try stdout.print("Usage: ghostty +<action> [flags]\n\n", .{});
|
||||||
|
try stdout.print(
|
||||||
|
\\This is the Ghostty helper CLI that accompanies the graphical Ghostty app.
|
||||||
|
\\To launch the terminal directly, please launch the graphical app
|
||||||
|
\\(i.e. Ghostty.app on macOS). This CLI can be used to perform various
|
||||||
|
\\actions such as inspecting the version, listing fonts, etc.
|
||||||
|
\\
|
||||||
|
\\We don't have proper help output yet, sorry! Please refer to the
|
||||||
|
\\source code or Discord community for help for now. We'll fix this in time.
|
||||||
|
,
|
||||||
|
.{},
|
||||||
|
);
|
||||||
|
|
||||||
|
std.os.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Create our app state
|
// Create our app state
|
||||||
var app = try App.create(alloc);
|
var app = try App.create(alloc);
|
||||||
defer app.destroy();
|
defer app.destroy();
|
||||||
@ -156,6 +180,7 @@ pub const GlobalState = struct {
|
|||||||
stderr: void,
|
stderr: void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Initialize the global state.
|
||||||
pub fn init(self: *GlobalState) !void {
|
pub fn init(self: *GlobalState) !void {
|
||||||
// Initialize ourself to nothing so we don't have any extra state.
|
// Initialize ourself to nothing so we don't have any extra state.
|
||||||
// IMPORTANT: this MUST be initialized before any log output because
|
// IMPORTANT: this MUST be initialized before any log output because
|
||||||
@ -201,15 +226,12 @@ pub const GlobalState = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// We first try to parse any action that we may be executing.
|
// We first try to parse any action that we may be executing.
|
||||||
// We do not execute this in the lib because os.argv is not set.
|
self.action = try cli_action.Action.detectCLI(self.alloc);
|
||||||
if (comptime build_config.artifact != .lib) {
|
|
||||||
self.action = try cli_action.Action.detectCLI(self.alloc);
|
|
||||||
|
|
||||||
// If we have an action executing, we disable logging by default
|
// If we have an action executing, we disable logging by default
|
||||||
// since we write to stderr we don't want logs messing up our
|
// since we write to stderr we don't want logs messing up our
|
||||||
// output.
|
// output.
|
||||||
if (self.action != null) self.logging = .{ .disabled = {} };
|
if (self.action != null) self.logging = .{ .disabled = {} };
|
||||||
}
|
|
||||||
|
|
||||||
// I don't love the env var name but I don't have it in my heart
|
// I don't love the env var name but I don't have it in my heart
|
||||||
// to parse CLI args 3 times (once for actions, once for config,
|
// to parse CLI args 3 times (once for actions, once for config,
|
||||||
|
@ -42,13 +42,33 @@ const Info = extern struct {
|
|||||||
/// one global state but it has zero practical benefit.
|
/// one global state but it has zero practical benefit.
|
||||||
export fn ghostty_init() c_int {
|
export fn ghostty_init() c_int {
|
||||||
assert(builtin.link_libc);
|
assert(builtin.link_libc);
|
||||||
|
|
||||||
|
// Since in the lib we don't go through start.zig, we need
|
||||||
|
// to populate argv so that inspecting std.os.argv doesn't
|
||||||
|
// touch uninitialized memory.
|
||||||
|
var argv: [0][*:0]u8 = .{};
|
||||||
|
std.os.argv = &argv;
|
||||||
|
|
||||||
main.state.init() catch |err| {
|
main.state.init() catch |err| {
|
||||||
std.log.err("failed to initialize ghostty error={}", .{err});
|
std.log.err("failed to initialize ghostty error={}", .{err});
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is the entrypoint for the CLI version of Ghostty. This
|
||||||
|
/// is mutually exclusive to ghostty_init. Do NOT run ghostty_init
|
||||||
|
/// if you are going to run this. This will not return.
|
||||||
|
export fn ghostty_cli_main(argc: usize, argv: [*][*:0]u8) noreturn {
|
||||||
|
std.os.argv = argv[0..argc];
|
||||||
|
main.main() catch |err| {
|
||||||
|
std.log.err("failed to run ghostty error={}", .{err});
|
||||||
|
std.os.exit(1);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return metadata about Ghostty, such as version, build mode, etc.
|
||||||
export fn ghostty_info() Info {
|
export fn ghostty_info() Info {
|
||||||
return .{
|
return .{
|
||||||
.mode = switch (builtin.mode) {
|
.mode = switch (builtin.mode) {
|
||||||
|
Reference in New Issue
Block a user