1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
const std = @import("std");
const Allocator = std.mem.Allocator;
const posix = std.posix;
const renderer = @import("../renderer.zig");
const terminal = @import("../terminal/main.zig");
const termio = @import("../termio.zig");
const ProcessInfo = @import("../pty.zig").ProcessInfo;
// The preallocation size for the write request pool. This should be big
// enough to satisfy most write requests. It must be a power of 2.
const WRITE_REQ_PREALLOC = std.math.pow(usize, 2, 5);
/// The kinds of backends.
pub const Kind = enum { exec };
/// Configuration for the various backend types.
pub const Config = union(Kind) {
/// Exec uses posix exec to run a command with a pty.
exec: termio.Exec.Config,
};
/// Backend implementations. A backend is responsible for owning the pty
/// behavior and providing read/write capabilities.
pub const Backend = union(Kind) {
exec: termio.Exec,
pub fn deinit(self: *Backend) void {
switch (self.*) {
.exec => |*exec| exec.deinit(),
}
}
pub fn initTerminal(self: *Backend, t: *terminal.Terminal) void {
switch (self.*) {
.exec => |*exec| exec.initTerminal(t),
}
}
pub fn threadEnter(
self: *Backend,
alloc: Allocator,
io: *termio.Termio,
td: *termio.Termio.ThreadData,
) !void {
switch (self.*) {
.exec => |*exec| try exec.threadEnter(alloc, io, td),
}
}
pub fn threadExit(self: *Backend, td: *termio.Termio.ThreadData) void {
switch (self.*) {
.exec => |*exec| exec.threadExit(td),
}
}
pub fn focusGained(
self: *Backend,
td: *termio.Termio.ThreadData,
focused: bool,
) !void {
switch (self.*) {
.exec => |*exec| try exec.focusGained(td, focused),
}
}
pub fn resize(
self: *Backend,
grid_size: renderer.GridSize,
screen_size: renderer.ScreenSize,
) !void {
switch (self.*) {
.exec => |*exec| try exec.resize(grid_size, screen_size),
}
}
pub fn queueWrite(
self: *Backend,
alloc: Allocator,
td: *termio.Termio.ThreadData,
data: []const u8,
linefeed: bool,
) !void {
switch (self.*) {
.exec => |*exec| try exec.queueWrite(alloc, td, data, linefeed),
}
}
pub fn childExitedAbnormally(
self: *Backend,
gpa: Allocator,
t: *terminal.Terminal,
exit_code: u32,
runtime_ms: u64,
) !void {
switch (self.*) {
.exec => |*exec| try exec.childExitedAbnormally(
gpa,
t,
exit_code,
runtime_ms,
),
}
}
/// Get information about the process(es) attached to the backend. Returns
/// `null` if there was an error getting the information or the information
/// is not available on a particular platform.
pub fn getProcessInfo(self: *Backend, comptime info: ProcessInfo) ?ProcessInfo.Type(info) {
return switch (self.*) {
.exec => |*exec| exec.getProcessInfo(info),
};
}
};
/// Termio thread data. See termio.ThreadData for docs.
pub const ThreadData = union(Kind) {
exec: termio.Exec.ThreadData,
pub fn deinit(self: *ThreadData, alloc: Allocator) void {
switch (self.*) {
.exec => |*exec| exec.deinit(alloc),
}
}
pub fn changeConfig(self: *ThreadData, config: *termio.DerivedConfig) void {
_ = self;
_ = config;
}
};
|