mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +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,
|
.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 {
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user