hook up keybindings for copy/paste and arrow keys

This commit is contained in:
Mitchell Hashimoto
2022-08-24 11:08:39 -07:00
parent e6f09093dd
commit 80376ce6da
4 changed files with 89 additions and 55 deletions

View File

@ -530,13 +530,59 @@ fn keyCallback(
.x => .x, .x => .x,
.y => .y, .y => .y,
.z => .z, .z => .z,
.up => .up,
.down => .down,
.right => .right,
.left => .left,
else => .invalid, else => .invalid,
}, },
}; };
if (win.config.keybind.set.get(trigger)) |binding_action| { if (win.config.keybind.set.get(trigger)) |binding_action| {
log.warn("BINDING ACTION={}", .{binding_action}); //log.warn("BINDING ACTION={}", .{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 // Bindings always result in us ignoring the char if printable
win.ignore_char = true; win.ignore_char = true;
@ -594,57 +640,6 @@ fn keyCallback(
log.err("error queueing write in keyCallback err={}", .{err}); 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 { fn focusCallback(window: glfw.Window, focused: bool) void {

View File

@ -20,7 +20,7 @@ pub const Config = struct {
/// The command to run, usually a shell. If this is not an absolute path, /// The command to run, usually a shell. If this is not an absolute path,
/// it'll be looked up in the 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 /// Key bindings. The format is "trigger=action". Duplicate triggers
/// will overwrite previously set values. /// will overwrite previously set values.
@ -63,6 +63,38 @@ pub const Config = struct {
if (self._arena) |arena| arena.deinit(); if (self._arena) |arena| arena.deinit();
self.* = undefined; 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. /// Color represents a color using RGB.

View File

@ -49,6 +49,12 @@ pub const Key = enum {
y, y,
z, z,
// control
up,
down,
right,
left,
// To support more keys (there are obviously more!) add them here // To support more keys (there are obviously more!) add them here
// and ensure the mapping is up to date in the Window key handler. // and ensure the mapping is up to date in the Window key handler.
}; };

View File

@ -39,7 +39,8 @@ pub fn main() !void {
// Parse the config from the CLI args // Parse the config from the CLI args
var config = config: { var config = config: {
var result: Config = .{}; var result = try Config.default(alloc);
errdefer result.deinit();
var iter = try std.process.argsWithAllocator(alloc); var iter = try std.process.argsWithAllocator(alloc);
defer iter.deinit(); defer iter.deinit();
try cli_args.parse(Config, alloc, &result, &iter); try cli_args.parse(Config, alloc, &result, &iter);