mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-10-24 06:04:08 +00:00
Style IME pre-edit text with italics and a dashed underline
Pre-edit text was drawn in reverse video, which is a solid inverted block moving through the line as you compose. Draw it as italic with a dashed underline in the highlight color instead. Underline rather than reverse video is what other terminals do: VTE renders the pre-edit run with the input method's own attributes and marks only the cursored cell distinctly, and foot underlines the run explicitly, excluding the part under the cursor. Dashed avoids the underline styles applications already use: curly for spell checking and straight for hyperlinks, which is the collision that made reverse video look like the safer choice. The styling is applied to the overlay's own cursor and restored afterwards, alongside the wrap, cursor-visibility and insert-replace modes already saved there. The previous code toggled reverse with XOR, which restored itself; the three new attributes are saved and put back explicitly. Closes #10382
This commit is contained in:
parent
17d2814b4d
commit
dbabd12ba6
2 changed files with 44 additions and 2 deletions
|
|
@ -4785,7 +4785,24 @@ screen_draw_overlay_line(Screen *self) {
|
|||
self->modes.mIRM = false;
|
||||
Cursor *orig_cursor = self->cursor;
|
||||
self->cursor = &(self->overlay_line.original_line.cursor);
|
||||
self->cursor->sgr.reverse ^= true;
|
||||
// Mark the pre-edit text as distinct from committed text: italic, with a
|
||||
// dashed underline in the highlight color. Underline rather than reverse
|
||||
// video matches what other terminals do (VTE and foot both underline), and
|
||||
// dashed avoids colliding with the styles applications already use: curly
|
||||
// for spell checking and straight for hyperlinks. Saved and restored around
|
||||
// the draw, like the modes above.
|
||||
const bool orig_italic = self->cursor->sgr.italic;
|
||||
const uint8_t orig_decoration = self->cursor->sgr.decoration;
|
||||
const color_type orig_decoration_fg = self->cursor->sgr.decoration_fg;
|
||||
self->cursor->sgr.italic = true;
|
||||
self->cursor->sgr.decoration = 5; // dashed
|
||||
self->cursor->sgr.decoration_fg =
|
||||
((colorprofile_to_color_with_fallback(self->color_profile, self->color_profile->overridden.highlight_bg,
|
||||
self->color_profile->configured.highlight_bg, self->color_profile->overridden.default_fg,
|
||||
self->color_profile->configured.default_fg)
|
||||
& COL_MASK)
|
||||
<< 8)
|
||||
| 2;
|
||||
self->cursor->x = xstart;
|
||||
self->cursor->y = self->overlay_line.ynum;
|
||||
self->overlay_line.xnum = 0;
|
||||
|
|
@ -4837,7 +4854,9 @@ screen_draw_overlay_line(Screen *self) {
|
|||
self->overlay_line.xnum += len;
|
||||
}
|
||||
self->overlay_line.cursor_x = self->cursor->x;
|
||||
self->cursor->sgr.reverse ^= true;
|
||||
self->cursor->sgr.italic = orig_italic;
|
||||
self->cursor->sgr.decoration = orig_decoration;
|
||||
self->cursor->sgr.decoration_fg = orig_decoration_fg;
|
||||
self->cursor = orig_cursor;
|
||||
self->modes.mDECAWM = orig_line_wrap_mode;
|
||||
self->modes.mDECTCEM = orig_cursor_enable_mode;
|
||||
|
|
|
|||
|
|
@ -2119,6 +2119,29 @@ class TestScreen(BaseTest):
|
|||
s.reset()
|
||||
self.assertTrue(s.is_main_linebuf())
|
||||
|
||||
def test_ime_preedit_styling(self):
|
||||
# Pre-edit text is marked with italics and a dashed underline in the
|
||||
# highlight color, rather than reverse video.
|
||||
s = self.create_screen(cols=10, lines=3)
|
||||
s.draw('xy')
|
||||
before = s.line(0).cursor_from(0)
|
||||
s.test_draw_overlay_line('ab', 0, 0)
|
||||
line = s.line(0)
|
||||
for x in (0, 1):
|
||||
c = line.cursor_from(x)
|
||||
self.assertTrue(c.italic, f'pre-edit cell {x} is not italic')
|
||||
self.assertFalse(c.reverse, f'pre-edit cell {x} is in reverse video')
|
||||
self.ae(c.decoration, 5, f'pre-edit cell {x} is not dashed-underlined')
|
||||
# decoration_fg is packed as (rgb << 8) | type, type 2 being RGB
|
||||
self.ae(c.decoration_fg & 0xff, 2)
|
||||
self.ae(c.decoration_fg >> 8, 0xfffacd) # default selection_background
|
||||
|
||||
# the styling is applied to the overlay's own cursor and must be
|
||||
# restored, not leaked into the screen's cursor
|
||||
self.assertFalse(s.cursor.italic)
|
||||
self.ae(s.cursor.decoration, before.decoration)
|
||||
self.ae(s.cursor.decoration_fg, before.decoration_fg)
|
||||
|
||||
|
||||
def detect_url(self, scale=1):
|
||||
s = self.create_screen(cols=30 * scale)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue