summaryrefslogtreecommitdiff
path: root/src/draw.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/draw.zig')
-rw-r--r--src/draw.zig16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/draw.zig b/src/draw.zig
index 0dbf5bae..2d757635 100644
--- a/src/draw.zig
+++ b/src/draw.zig
@@ -598,9 +598,10 @@ fn joinCells(s: *Surface, x: u16, y: u16, cells: []const Cell, from: usize, w: u
fn tagTintRange(pane: *const Pane, tag: []const u8, prefix_len: usize) ?struct { lo: usize, hi: usize } {
if (pane.isTerminal()) {
- var words = std.mem.tokenizeAny(u8, tag[prefix_len..], " \t\r\n");
+ // `tag` is the first row; a prefix longer than it ran to a second.
+ var words = std.mem.tokenizeAny(u8, tag[@min(prefix_len, tag.len)..], " \t\r\n");
while (words.next()) |word| {
- if (!std.mem.eql(u8, word, "Tty")) continue;
+ if (!std.mem.eql(u8, word, "Tty") and !std.mem.startsWith(u8, word, "Tty+")) continue;
const lo = @intFromPtr(word.ptr) - @intFromPtr(tag.ptr);
return .{ .lo = lo, .hi = lo + word.len };
}
@@ -611,7 +612,7 @@ fn tagTintRange(pane: *const Pane, tag: []const u8, prefix_len: usize) ?struct {
if (pane.prompt == .name) pane.input.own orelse file.path else file.path
else if (pane.image) |state| blk: {
// Image tags put renderer controls before the path.
- start = std.mem.lastIndexOf(u8, tag[0..prefix_len], state.path) orelse return null;
+ start = std.mem.lastIndexOf(u8, tag[0..@min(prefix_len, tag.len)], state.path) orelse return null;
break :blk state.path;
} else if (comptime pdf_enabled) blk: {
break :blk if (pane.pdf) |state| state.path else return null;
@@ -772,13 +773,16 @@ fn joinNotice(p: *Pardes, s: *Surface, arena: std.mem.Allocator, region: Region)
const motion: Messages.MessageMotion = if (Messages.noticeLife(pane, i)) |life| Messages.messageMotion(p, life) else .{};
const page = th.bg orelse chrome.tag_bg;
const bg = Messages.blendRgb(chrome.tag_bg, page, motion.alpha);
- const fg = Messages.blendRgb(chrome.tag_fg, page, motion.alpha);
+ // Where an exec was sent to a REPL reads in the tag's name tint, set
+ // apart from what the editor says.
+ const ink = if (kind == .message and pane.msg_sent) chrome.tag_name_fg else chrome.tag_fg;
+ const fg = Messages.blendRgb(ink, page, motion.alpha);
// Nothing to say, or too narrow for a layer: a blank chip on the grid.
if (text.len == 0 or r.w <= TAG_TEXT_INSET) {
s.fill(region.rect.x, region.rect.y, chip, 1, .{ .bg = .{ .rgb = bg }, .font_role = .tagline });
if (text.len == 0) return;
const printed = Messages.printRight(s, region.rect.x, region.rect.y, chip -| 1, text, .{ .fg = .{ .rgb = fg }, .bg = .{ .rgb = bg }, .font_role = .tagline });
- if (kind != .prompt or id != p.active or pane.prompt == .del_side) return;
+ if (kind != .prompt or id != p.active or pane.prompt == .del_side or pane.prompt == .repl_choice) return;
const prompt_col = panes.File.displayWidth(text[0..@min(@as(usize, @intCast(@max(0, pane.input.cur_col))), text.len)]);
if (prompt_col < printed.dropped) return;
s.cursor = .{ .x = @intCast(printed.left + (prompt_col - printed.dropped)), .y = region.rect.y, .bar = pane.input.mode == .insert };
@@ -807,7 +811,7 @@ fn joinNotice(p: *Pardes, s: *Surface, arena: std.mem.Allocator, region: Region)
layer.slide = motion.slide;
layer.fade = motion.alpha;
// The caret rides the band, where the prompt's glyphs are.
- if (kind == .prompt and id == p.active and pane.prompt != .del_side) caret: {
+ if (kind == .prompt and id == p.active and pane.prompt != .del_side and pane.prompt != .repl_choice) caret: {
const typed = panes.File.displayWidth(text[0..@min(@as(usize, @intCast(@max(0, pane.input.cur_col))), text.len)]);
const dropped = shown - panes.File.displayWidth(kept);
if (typed < dropped) break :caret;