mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-22 11:46:11 +03:00
termio: take reader as option
This commit is contained in:
@ -426,6 +426,25 @@ pub fn init(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Start our IO implementation
|
// Start our IO implementation
|
||||||
|
var io_exec = try termio.Exec.init(alloc, .{
|
||||||
|
.command = config.command,
|
||||||
|
.shell_integration = config.@"shell-integration",
|
||||||
|
.shell_integration_features = config.@"shell-integration-features",
|
||||||
|
.working_directory = config.@"working-directory",
|
||||||
|
.resources_dir = main.state.resources_dir,
|
||||||
|
.term = config.term,
|
||||||
|
|
||||||
|
// Get the cgroup if we're on linux and have the decl. I'd love
|
||||||
|
// to change this from a decl to a surface options struct because
|
||||||
|
// then we can do memory management better (don't need to retain
|
||||||
|
// the string around).
|
||||||
|
.linux_cgroup = if (comptime builtin.os.tag == .linux and
|
||||||
|
@hasDecl(apprt.runtime.Surface, "cgroup"))
|
||||||
|
rt_surface.cgroup()
|
||||||
|
else
|
||||||
|
Command.linux_cgroup_default,
|
||||||
|
});
|
||||||
|
errdefer io_exec.deinit();
|
||||||
var io_writer = try termio.Writer.initMailbox(alloc);
|
var io_writer = try termio.Writer.initMailbox(alloc);
|
||||||
errdefer io_writer.deinit(alloc);
|
errdefer io_writer.deinit(alloc);
|
||||||
try termio.Termio.init(&self.io, alloc, .{
|
try termio.Termio.init(&self.io, alloc, .{
|
||||||
@ -434,6 +453,7 @@ pub fn init(
|
|||||||
.padding = padding,
|
.padding = padding,
|
||||||
.full_config = config,
|
.full_config = config,
|
||||||
.config = try termio.Termio.DerivedConfig.init(alloc, config),
|
.config = try termio.Termio.DerivedConfig.init(alloc, config),
|
||||||
|
.reader = .{ .exec = io_exec },
|
||||||
.writer = io_writer,
|
.writer = io_writer,
|
||||||
.resources_dir = main.state.resources_dir,
|
.resources_dir = main.state.resources_dir,
|
||||||
.renderer_state = &self.renderer_state,
|
.renderer_state = &self.renderer_state,
|
||||||
|
@ -13,6 +13,7 @@ pub const Termio = @import("termio/Termio.zig");
|
|||||||
pub const Thread = @import("termio/Thread.zig");
|
pub const Thread = @import("termio/Thread.zig");
|
||||||
pub const DerivedConfig = Termio.DerivedConfig;
|
pub const DerivedConfig = Termio.DerivedConfig;
|
||||||
pub const Mailbox = writer.Mailbox;
|
pub const Mailbox = writer.Mailbox;
|
||||||
|
pub const Reader = reader.Reader;
|
||||||
pub const StreamHandler = stream_handler.StreamHandler;
|
pub const StreamHandler = stream_handler.StreamHandler;
|
||||||
pub const Writer = writer.Writer;
|
pub const Writer = writer.Writer;
|
||||||
|
|
||||||
|
@ -25,6 +25,9 @@ full_config: *const Config,
|
|||||||
/// The derived configuration for this termio implementation.
|
/// The derived configuration for this termio implementation.
|
||||||
config: termio.Termio.DerivedConfig,
|
config: termio.Termio.DerivedConfig,
|
||||||
|
|
||||||
|
/// The reader for the terminal.
|
||||||
|
reader: termio.Reader,
|
||||||
|
|
||||||
/// The writer for the terminal. This is how messages are delivered.
|
/// The writer for the terminal. This is how messages are delivered.
|
||||||
/// If you're using termio.Thread this MUST be "mailbox".
|
/// If you're using termio.Thread this MUST be "mailbox".
|
||||||
writer: termio.Writer,
|
writer: termio.Writer,
|
||||||
|
@ -33,8 +33,8 @@ const log = std.log.scoped(.io_exec);
|
|||||||
/// Allocator
|
/// Allocator
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
|
|
||||||
/// This is the pty fd created for the subcommand.
|
/// This is the implementation responsible for io.
|
||||||
subprocess: termio.Exec,
|
reader: termio.Reader,
|
||||||
|
|
||||||
/// The derived configuration for this termio implementation.
|
/// The derived configuration for this termio implementation.
|
||||||
config: DerivedConfig,
|
config: DerivedConfig,
|
||||||
@ -169,18 +169,8 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
|
|||||||
term.screen.cursor.cursor_style = opts.config.cursor_style;
|
term.screen.cursor.cursor_style = opts.config.cursor_style;
|
||||||
|
|
||||||
// Setup our reader.
|
// Setup our reader.
|
||||||
// TODO: for manual, we need to set the terminal width/height
|
var reader = opts.reader;
|
||||||
var subprocess = try termio.Exec.init(alloc, .{
|
reader.initTerminal(&term);
|
||||||
.command = opts.full_config.command,
|
|
||||||
.shell_integration = opts.full_config.@"shell-integration",
|
|
||||||
.shell_integration_features = opts.full_config.@"shell-integration-features",
|
|
||||||
.working_directory = opts.full_config.@"working-directory",
|
|
||||||
.resources_dir = opts.resources_dir,
|
|
||||||
.term = opts.config.term,
|
|
||||||
.linux_cgroup = opts.linux_cgroup,
|
|
||||||
});
|
|
||||||
errdefer subprocess.deinit();
|
|
||||||
subprocess.initTerminal(&term);
|
|
||||||
|
|
||||||
// Setup our terminal size in pixels for certain requests.
|
// Setup our terminal size in pixels for certain requests.
|
||||||
const screen_size = opts.screen_size.subPadding(opts.padding);
|
const screen_size = opts.screen_size.subPadding(opts.padding);
|
||||||
@ -220,13 +210,13 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
|
|||||||
self.* = .{
|
self.* = .{
|
||||||
.alloc = alloc,
|
.alloc = alloc,
|
||||||
.terminal = term,
|
.terminal = term,
|
||||||
.subprocess = subprocess,
|
|
||||||
.config = opts.config,
|
.config = opts.config,
|
||||||
.renderer_state = opts.renderer_state,
|
.renderer_state = opts.renderer_state,
|
||||||
.renderer_wakeup = opts.renderer_wakeup,
|
.renderer_wakeup = opts.renderer_wakeup,
|
||||||
.renderer_mailbox = opts.renderer_mailbox,
|
.renderer_mailbox = opts.renderer_mailbox,
|
||||||
.surface_mailbox = opts.surface_mailbox,
|
.surface_mailbox = opts.surface_mailbox,
|
||||||
.grid_size = opts.grid_size,
|
.grid_size = opts.grid_size,
|
||||||
|
.reader = opts.reader,
|
||||||
.writer = opts.writer,
|
.writer = opts.writer,
|
||||||
.terminal_stream = .{
|
.terminal_stream = .{
|
||||||
.handler = handler,
|
.handler = handler,
|
||||||
@ -242,7 +232,7 @@ pub fn init(self: *Termio, alloc: Allocator, opts: termio.Options) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Termio) void {
|
pub fn deinit(self: *Termio) void {
|
||||||
self.subprocess.deinit();
|
self.reader.deinit();
|
||||||
self.terminal.deinit(self.alloc);
|
self.terminal.deinit(self.alloc);
|
||||||
self.config.deinit();
|
self.config.deinit();
|
||||||
self.writer.deinit(self.alloc);
|
self.writer.deinit(self.alloc);
|
||||||
@ -272,11 +262,11 @@ pub fn threadEnter(self: *Termio, thread: *termio.Thread, data: *ThreadData) !vo
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup our reader
|
// Setup our reader
|
||||||
try self.subprocess.threadEnter(alloc, self, data);
|
try self.reader.threadEnter(alloc, self, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn threadExit(self: *Termio, data: *ThreadData) void {
|
pub fn threadExit(self: *Termio, data: *ThreadData) void {
|
||||||
self.subprocess.threadExit(data);
|
self.reader.threadExit(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a message using the writer. Depending on the writer type in
|
/// Send a message using the writer. Depending on the writer type in
|
||||||
@ -310,7 +300,7 @@ pub inline fn queueWrite(
|
|||||||
data: []const u8,
|
data: []const u8,
|
||||||
linefeed: bool,
|
linefeed: bool,
|
||||||
) !void {
|
) !void {
|
||||||
try self.subprocess.queueWrite(self.alloc, td, data, linefeed);
|
try self.reader.queueWrite(self.alloc, td, data, linefeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the configuration.
|
/// Update the configuration.
|
||||||
@ -373,7 +363,7 @@ pub fn resize(
|
|||||||
) !void {
|
) !void {
|
||||||
// Update the size of our pty.
|
// Update the size of our pty.
|
||||||
const padded_size = screen_size.subPadding(padding);
|
const padded_size = screen_size.subPadding(padding);
|
||||||
try self.subprocess.resize(grid_size, padded_size);
|
try self.reader.resize(grid_size, padded_size);
|
||||||
|
|
||||||
// Update our cached grid size
|
// Update our cached grid size
|
||||||
self.grid_size = grid_size;
|
self.grid_size = grid_size;
|
||||||
@ -476,7 +466,7 @@ pub fn childExitedAbnormally(self: *Termio, exit_code: u32, runtime_ms: u64) !vo
|
|||||||
self.renderer_state.mutex.lock();
|
self.renderer_state.mutex.lock();
|
||||||
defer self.renderer_state.mutex.unlock();
|
defer self.renderer_state.mutex.unlock();
|
||||||
const t = self.renderer_state.terminal;
|
const t = self.renderer_state.terminal;
|
||||||
try self.subprocess.childExitedAbnormally(self.alloc, t, exit_code, runtime_ms);
|
try self.reader.childExitedAbnormally(self.alloc, t, exit_code, runtime_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process output from the pty. This is the manual API that users can
|
/// Process output from the pty. This is the manual API that users can
|
||||||
|
@ -9,6 +9,7 @@ const configpkg = @import("../config.zig");
|
|||||||
const internal_os = @import("../os/main.zig");
|
const internal_os = @import("../os/main.zig");
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
const shell_integration = @import("shell_integration.zig");
|
const shell_integration = @import("shell_integration.zig");
|
||||||
|
const terminal = @import("../terminal/main.zig");
|
||||||
const termio = @import("../termio.zig");
|
const termio = @import("../termio.zig");
|
||||||
const Command = @import("../Command.zig");
|
const Command = @import("../Command.zig");
|
||||||
const SegmentedPool = @import("../segmented_pool.zig").SegmentedPool;
|
const SegmentedPool = @import("../segmented_pool.zig").SegmentedPool;
|
||||||
@ -44,6 +45,74 @@ pub const Reader = union(Kind) {
|
|||||||
.exec => |*exec| exec.deinit(),
|
.exec => |*exec| exec.deinit(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn initTerminal(self: *Reader, t: *terminal.Terminal) void {
|
||||||
|
switch (self.*) {
|
||||||
|
.manual => {},
|
||||||
|
.exec => |*exec| exec.initTerminal(t),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn threadEnter(
|
||||||
|
self: *Reader,
|
||||||
|
alloc: Allocator,
|
||||||
|
io: *termio.Termio,
|
||||||
|
td: *termio.Termio.ThreadData,
|
||||||
|
) !void {
|
||||||
|
switch (self.*) {
|
||||||
|
.manual => {},
|
||||||
|
.exec => |*exec| try exec.threadEnter(alloc, io, td),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn threadExit(self: *Reader, td: *termio.Termio.ThreadData) void {
|
||||||
|
switch (self.*) {
|
||||||
|
.manual => {},
|
||||||
|
.exec => |*exec| exec.threadExit(td),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(
|
||||||
|
self: *Reader,
|
||||||
|
grid_size: renderer.GridSize,
|
||||||
|
screen_size: renderer.ScreenSize,
|
||||||
|
) !void {
|
||||||
|
switch (self.*) {
|
||||||
|
.manual => {},
|
||||||
|
.exec => |*exec| try exec.resize(grid_size, screen_size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn queueWrite(
|
||||||
|
self: *Reader,
|
||||||
|
alloc: Allocator,
|
||||||
|
td: *termio.Termio.ThreadData,
|
||||||
|
data: []const u8,
|
||||||
|
linefeed: bool,
|
||||||
|
) !void {
|
||||||
|
switch (self.*) {
|
||||||
|
.manual => {},
|
||||||
|
.exec => |*exec| try exec.queueWrite(alloc, td, data, linefeed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn childExitedAbnormally(
|
||||||
|
self: *Reader,
|
||||||
|
gpa: Allocator,
|
||||||
|
t: *terminal.Terminal,
|
||||||
|
exit_code: u32,
|
||||||
|
runtime_ms: u64,
|
||||||
|
) !void {
|
||||||
|
switch (self.*) {
|
||||||
|
.manual => {},
|
||||||
|
.exec => |*exec| try exec.childExitedAbnormally(
|
||||||
|
gpa,
|
||||||
|
t,
|
||||||
|
exit_code,
|
||||||
|
runtime_ms,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Termio thread data. See termio.ThreadData for docs.
|
/// Termio thread data. See termio.ThreadData for docs.
|
||||||
|
Reference in New Issue
Block a user