mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
keybinding jump_to_prompt for semantic prompts
This commit is contained in:
@ -1106,6 +1106,13 @@ pub fn keyCallback(
|
|||||||
try self.io_thread.wakeup.notify();
|
try self.io_thread.wakeup.notify();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.jump_to_prompt => |delta| {
|
||||||
|
_ = self.io_thread.mailbox.push(.{
|
||||||
|
.jump_to_prompt = @intCast(delta),
|
||||||
|
}, .{ .forever = {} });
|
||||||
|
try self.io_thread.wakeup.notify();
|
||||||
|
},
|
||||||
|
|
||||||
.toggle_dev_mode => if (DevMode.enabled) {
|
.toggle_dev_mode => if (DevMode.enabled) {
|
||||||
DevMode.instance.visible = !DevMode.instance.visible;
|
DevMode.instance.visible = !DevMode.instance.visible;
|
||||||
try self.queueRender();
|
try self.queueRender();
|
||||||
|
@ -491,6 +491,18 @@ pub const Config = struct {
|
|||||||
.{ .clear_screen = {} },
|
.{ .clear_screen = {} },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Semantic prompts
|
||||||
|
try result.keybind.set.put(
|
||||||
|
alloc,
|
||||||
|
.{ .key = .up, .mods = .{ .super = true, .shift = true } },
|
||||||
|
.{ .jump_to_prompt = -1 },
|
||||||
|
);
|
||||||
|
try result.keybind.set.put(
|
||||||
|
alloc,
|
||||||
|
.{ .key = .down, .mods = .{ .super = true, .shift = true } },
|
||||||
|
.{ .jump_to_prompt = 1 },
|
||||||
|
);
|
||||||
|
|
||||||
// Mac windowing
|
// Mac windowing
|
||||||
try result.keybind.set.put(
|
try result.keybind.set.put(
|
||||||
alloc,
|
alloc,
|
||||||
|
@ -169,6 +169,11 @@ pub const Action = union(enum) {
|
|||||||
/// Clear the screen. This also clears all scrollback.
|
/// Clear the screen. This also clears all scrollback.
|
||||||
clear_screen: void,
|
clear_screen: void,
|
||||||
|
|
||||||
|
/// Jump the viewport forward or back by prompt. Positive
|
||||||
|
/// number is the number of prompts to jump forward, negative
|
||||||
|
/// is backwards.
|
||||||
|
jump_to_prompt: i16,
|
||||||
|
|
||||||
/// Dev mode
|
/// Dev mode
|
||||||
toggle_dev_mode: void,
|
toggle_dev_mode: void,
|
||||||
|
|
||||||
|
@ -1682,6 +1682,8 @@ fn jumpPrompt(self: *Screen, delta: isize) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//log.warn("delta={} delta_rem={} start_y={} y={}", .{ delta, delta_rem, start_y, y });
|
||||||
|
|
||||||
// If we didn't find any, do nothing.
|
// If we didn't find any, do nothing.
|
||||||
if (delta_rem == delta_start) return false;
|
if (delta_rem == delta_start) return false;
|
||||||
|
|
||||||
@ -1690,6 +1692,7 @@ fn jumpPrompt(self: *Screen, delta: isize) bool {
|
|||||||
const new_y: usize = @intCast(start_y + y_delta);
|
const new_y: usize = @intCast(start_y + y_delta);
|
||||||
const old_viewport = self.viewport;
|
const old_viewport = self.viewport;
|
||||||
self.scroll(.{ .row = .{ .screen = new_y } }) catch unreachable;
|
self.scroll(.{ .row = .{ .screen = new_y } }) catch unreachable;
|
||||||
|
//log.warn("delta={} y_delta={} start_y={} new_y={}", .{ delta, y_delta, start_y, new_y });
|
||||||
return self.viewport != old_viewport;
|
return self.viewport != old_viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,7 +1504,7 @@ pub fn setScrollingRegion(self: *Terminal, top: usize, bottom: usize) void {
|
|||||||
/// (OSC 133) only allow setting this for wherever the current active cursor
|
/// (OSC 133) only allow setting this for wherever the current active cursor
|
||||||
/// is located.
|
/// is located.
|
||||||
pub fn markSemanticPrompt(self: *Terminal, p: SemanticPrompt) void {
|
pub fn markSemanticPrompt(self: *Terminal, p: SemanticPrompt) void {
|
||||||
// log.warn("semantic_prompt: {}", .{p});
|
//log.warn("semantic_prompt y={} p={}", .{ self.screen.cursor.y, p });
|
||||||
const row = self.screen.getRow(.{ .active = self.screen.cursor.y });
|
const row = self.screen.getRow(.{ .active = self.screen.cursor.y });
|
||||||
row.setSemanticPrompt(switch (p) {
|
row.setSemanticPrompt(switch (p) {
|
||||||
.prompt => .prompt,
|
.prompt => .prompt,
|
||||||
|
@ -288,6 +288,21 @@ pub fn clearScreen(self: *Exec, history: bool) !void {
|
|||||||
try self.queueWrite(&[_]u8{0x0C});
|
try self.queueWrite(&[_]u8{0x0C});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Jump the viewport to the prompt.
|
||||||
|
pub fn jumpToPrompt(self: *Exec, delta: isize) !void {
|
||||||
|
const wakeup: bool = wakeup: {
|
||||||
|
self.renderer_state.mutex.lock();
|
||||||
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
break :wakeup self.terminal.screen.jump(.{
|
||||||
|
.prompt_delta = delta,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (wakeup) {
|
||||||
|
try self.renderer_wakeup.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn queueWrite(self: *Exec, data: []const u8) !void {
|
pub inline fn queueWrite(self: *Exec, data: []const u8) !void {
|
||||||
const ev = self.data.?;
|
const ev = self.data.?;
|
||||||
|
|
||||||
|
@ -156,6 +156,7 @@ fn drainMailbox(self: *Thread) !void {
|
|||||||
},
|
},
|
||||||
.resize => |v| self.handleResize(v),
|
.resize => |v| self.handleResize(v),
|
||||||
.clear_screen => |v| try self.impl.clearScreen(v.history),
|
.clear_screen => |v| try self.impl.clearScreen(v.history),
|
||||||
|
.jump_to_prompt => |v| try self.impl.jumpToPrompt(v),
|
||||||
.write_small => |v| try self.impl.queueWrite(v.data[0..v.len]),
|
.write_small => |v| try self.impl.queueWrite(v.data[0..v.len]),
|
||||||
.write_stable => |v| try self.impl.queueWrite(v),
|
.write_stable => |v| try self.impl.queueWrite(v),
|
||||||
.write_alloc => |v| {
|
.write_alloc => |v| {
|
||||||
|
@ -45,6 +45,9 @@ pub const Message = union(enum) {
|
|||||||
history: bool,
|
history: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Jump forward/backward n prompts.
|
||||||
|
jump_to_prompt: isize,
|
||||||
|
|
||||||
/// Write where the data fits in the union.
|
/// Write where the data fits in the union.
|
||||||
write_small: WriteReq.Small,
|
write_small: WriteReq.Small,
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user