mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
hook up keybindings for copy/paste and arrow keys
This commit is contained in:
101
src/Window.zig
101
src/Window.zig
@ -530,13 +530,59 @@ fn keyCallback(
|
||||
.x => .x,
|
||||
.y => .y,
|
||||
.z => .z,
|
||||
.up => .up,
|
||||
.down => .down,
|
||||
.right => .right,
|
||||
.left => .left,
|
||||
else => .invalid,
|
||||
},
|
||||
};
|
||||
|
||||
if (win.config.keybind.set.get(trigger)) |binding_action| {
|
||||
log.warn("BINDING ACTION={}", .{binding_action});
|
||||
_ = binding_action;
|
||||
//log.warn("BINDING ACTION={}", .{binding_action});
|
||||
|
||||
switch (binding_action) {
|
||||
.unbind => unreachable,
|
||||
.ignore => {},
|
||||
|
||||
.csi => |data| {
|
||||
win.queueWrite("\x1B[") catch |err|
|
||||
log.err("error queueing write in keyCallback err={}", .{err});
|
||||
win.queueWrite(data) catch |err|
|
||||
log.warn("error pasting clipboard: {}", .{err});
|
||||
},
|
||||
|
||||
.copy_to_clipboard => {
|
||||
if (win.terminal.selection) |sel| {
|
||||
var buf = win.terminal.screen.selectionString(win.alloc, sel) catch |err| {
|
||||
log.err("error reading selection string err={}", .{err});
|
||||
return;
|
||||
};
|
||||
defer win.alloc.free(buf);
|
||||
|
||||
glfw.setClipboardString(buf) catch |err| {
|
||||
log.err("error setting clipboard string err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
.paste_from_clipboard => {
|
||||
const data = glfw.getClipboardString() catch |err| {
|
||||
log.warn("error reading clipboard: {}", .{err});
|
||||
return;
|
||||
};
|
||||
|
||||
if (data.len > 0) {
|
||||
if (win.bracketed_paste) win.queueWrite("\x1B[200~") catch |err|
|
||||
log.err("error queueing write in keyCallback err={}", .{err});
|
||||
win.queueWrite(data) catch |err|
|
||||
log.warn("error pasting clipboard: {}", .{err});
|
||||
if (win.bracketed_paste) win.queueWrite("\x1B[201~") catch |err|
|
||||
log.err("error queueing write in keyCallback err={}", .{err});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Bindings always result in us ignoring the char if printable
|
||||
win.ignore_char = true;
|
||||
@ -594,57 +640,6 @@ fn keyCallback(
|
||||
log.err("error queueing write in keyCallback err={}", .{err});
|
||||
}
|
||||
}
|
||||
|
||||
if (action == .press and mods.super) {
|
||||
switch (key) {
|
||||
// Copy
|
||||
.c => {
|
||||
// Ignore this character for writing
|
||||
win.ignore_char = true;
|
||||
|
||||
// If we have a selection, copy it.
|
||||
if (win.terminal.selection) |sel| {
|
||||
var buf = win.terminal.screen.selectionString(win.alloc, sel) catch |err| {
|
||||
log.err("error reading selection string err={}", .{err});
|
||||
return;
|
||||
};
|
||||
defer win.alloc.free(buf);
|
||||
|
||||
glfw.setClipboardString(buf) catch |err| {
|
||||
log.err("error setting clipboard string err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
},
|
||||
|
||||
// Paste
|
||||
.v => {
|
||||
|
||||
// Ignore this character for writing
|
||||
win.ignore_char = true;
|
||||
|
||||
const data = glfw.getClipboardString() catch |err| {
|
||||
log.warn("error reading clipboard: {}", .{err});
|
||||
return;
|
||||
};
|
||||
|
||||
if (data.len > 0) {
|
||||
if (win.bracketed_paste) win.queueWrite("\x1B[200~") catch |err|
|
||||
log.err("error queueing write in keyCallback err={}", .{err});
|
||||
win.queueWrite(data) catch |err|
|
||||
log.warn("error pasting clipboard: {}", .{err});
|
||||
if (win.bracketed_paste) win.queueWrite("\x1B[201~") catch |err|
|
||||
log.err("error queueing write in keyCallback err={}", .{err});
|
||||
}
|
||||
|
||||
return;
|
||||
},
|
||||
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn focusCallback(window: glfw.Window, focused: bool) void {
|
||||
|
@ -20,7 +20,7 @@ pub const Config = struct {
|
||||
|
||||
/// The command to run, usually a shell. If this is not an absolute path,
|
||||
/// it'll be looked up in the PATH.
|
||||
command: ?[]const u8 = null,
|
||||
command: ?[]const u8,
|
||||
|
||||
/// Key bindings. The format is "trigger=action". Duplicate triggers
|
||||
/// will overwrite previously set values.
|
||||
@ -63,6 +63,38 @@ pub const Config = struct {
|
||||
if (self._arena) |arena| arena.deinit();
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn default(alloc_gpa: Allocator) Allocator.Error!Config {
|
||||
var arena = ArenaAllocator.init(alloc_gpa);
|
||||
errdefer arena.deinit();
|
||||
const alloc = arena.allocator();
|
||||
|
||||
// Build up our basic config
|
||||
var result: Config = .{
|
||||
._arena = arena,
|
||||
.command = "sh",
|
||||
};
|
||||
|
||||
// Add our default keybindings
|
||||
try result.keybind.set.put(
|
||||
alloc,
|
||||
.{ .key = .c, .mods = .{ .super = true } },
|
||||
.{ .copy_to_clipboard = 0 },
|
||||
);
|
||||
|
||||
try result.keybind.set.put(
|
||||
alloc,
|
||||
.{ .key = .v, .mods = .{ .super = true } },
|
||||
.{ .paste_from_clipboard = 0 },
|
||||
);
|
||||
|
||||
try result.keybind.set.put(alloc, .{ .key = .up }, .{ .csi = "A" });
|
||||
try result.keybind.set.put(alloc, .{ .key = .down }, .{ .csi = "B" });
|
||||
try result.keybind.set.put(alloc, .{ .key = .right }, .{ .csi = "C" });
|
||||
try result.keybind.set.put(alloc, .{ .key = .left }, .{ .csi = "D" });
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// Color represents a color using RGB.
|
||||
|
@ -49,6 +49,12 @@ pub const Key = enum {
|
||||
y,
|
||||
z,
|
||||
|
||||
// control
|
||||
up,
|
||||
down,
|
||||
right,
|
||||
left,
|
||||
|
||||
// To support more keys (there are obviously more!) add them here
|
||||
// and ensure the mapping is up to date in the Window key handler.
|
||||
};
|
||||
|
@ -39,7 +39,8 @@ pub fn main() !void {
|
||||
|
||||
// Parse the config from the CLI args
|
||||
var config = config: {
|
||||
var result: Config = .{};
|
||||
var result = try Config.default(alloc);
|
||||
errdefer result.deinit();
|
||||
var iter = try std.process.argsWithAllocator(alloc);
|
||||
defer iter.deinit();
|
||||
try cli_args.parse(Config, alloc, &result, &iter);
|
||||
|
Reference in New Issue
Block a user