-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathtext_editor.zig
More file actions
155 lines (131 loc) · 5.22 KB
/
Copy pathtext_editor.zig
File metadata and controls
155 lines (131 loc) · 5.22 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! ZigZag Text Editor Example
//! Demonstrates the TextArea component for multi-line editing.
const std = @import("std");
const zz = @import("zigzag");
const Model = struct {
editor: zz.components.TextArea,
status_message: []const u8,
pub const Msg = union(enum) {
key: zz.KeyEvent,
};
pub fn init(self: *Model, ctx: *zz.Context) !zz.Cmd(Msg) {
self.editor = zz.components.TextArea.init(ctx.persistent_allocator);
self.editor.setSize(ctx.width -| 4, ctx.height -| 8);
self.editor.line_numbers = true;
self.editor.placeholder = "Start typing...";
try // Sample text
self.editor.setValue(
\\// Welcome to ZigZag Text Editor!
\\//
\\// This is a demo of the TextArea component.
\\// You can edit this text using standard editor controls.
\\
\\const std = @import("std");
\\
\\pub fn main() !void {
\\ std.debug.print("Hello, World!\n", .{});
\\}
);
self.status_message = "";
return .none;
}
pub fn update(self: *Model, msg: Msg, ctx: *zz.Context) zz.Cmd(Msg) {
switch (msg) {
.key => |k| {
// Handle Ctrl+Q to quit
if (k.modifiers.ctrl) {
switch (k.key) {
.char => |c| {
switch (c) {
'q' => return .quit,
's' => {
self.status_message = "Saved! (not really)";
return .none;
},
else => {},
}
},
else => {},
}
}
// Handle escape to quit
if (k.key == .escape) {
return .quit;
}
// Pass to editor
self.editor.handleKey(k);
self.status_message = "";
// Update size based on context
self.editor.setSize(ctx.width -| 4, ctx.height -| 8);
},
}
return .none;
}
pub fn view(self: *const Model, ctx: *const zz.Context) ![]const u8 {
// Title
var title_style = zz.Style{};
title_style = title_style.bold(true);
title_style = title_style.fg(zz.Color.cyan);
title_style = title_style.inline_style(true);
const title = try title_style.render(ctx.allocator, "ZigZag Text Editor");
// Editor with border
var editor_style = zz.Style{};
editor_style = editor_style.borderAll(zz.Border.rounded);
editor_style = editor_style.borderForeground(zz.Color.gray(12));
const editor_content = try self.editor.view(ctx.allocator);
const editor_box = try editor_style.render(ctx.allocator, editor_content);
// Status bar
const cursor_info = try std.fmt.allocPrint(
ctx.allocator,
"Ln {d}, Col {d} | {d} lines",
.{ self.editor.cursor_row + 1, self.editor.cursorDisplayColumn() + 1, self.editor.lineCount() },
);
var status_style = zz.Style{};
status_style = status_style.fg(zz.Color.gray(18));
status_style = status_style.inline_style(true);
const status = try status_style.render(ctx.allocator, cursor_info);
// Status message
var msg_style = zz.Style{};
msg_style = msg_style.fg(zz.Color.green);
msg_style = msg_style.inline_style(true);
const msg = try msg_style.render(ctx.allocator, self.status_message);
// Help
var help_style = zz.Style{};
help_style = help_style.fg(zz.Color.gray(12));
help_style = help_style.inline_style(true);
const help = try help_style.render(
ctx.allocator,
"Ctrl+S: Save Ctrl+Q: Quit Arrow keys: Navigate",
);
// Get max width for centering
const editor_width = zz.measure.maxLineWidth(editor_box);
const title_width = zz.measure.width(title);
const help_width = zz.measure.width(help);
const max_width = @max(editor_width, @max(title_width, help_width));
// Center title and help relative to editor width
const centered_title = try zz.place.place(ctx.allocator, max_width, 1, .center, .top, title);
const centered_help = try zz.place.place(ctx.allocator, max_width, 1, .center, .top, help);
const content = try std.fmt.allocPrint(
ctx.allocator,
"{s}\n\n{s}\n\n{s} {s}\n{s}",
.{ centered_title, editor_box, status, msg, centered_help },
);
// Center horizontally, keep at top vertically (editor needs space)
return zz.place.place(
ctx.allocator,
ctx.width,
ctx.height,
.center,
.top,
content,
);
}
pub fn deinit(self: *Model) void {
self.editor.deinit();
}
};
pub fn main(init: std.process.Init) !void {
var program = zz.Program(Model).init(init.gpa, init.io, init.environ_map);
defer program.deinit();
try program.run();
}