From 6a6e71dc0f86214eb63dfbc605f648b261137f56 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 24 Feb 2018 21:24:06 +1100 Subject: [PATCH] Highlight cursors differently when they lie on an end of line When on an end of line, certain behaviours can be surprising, for example delete will join the following line (which makes sense, and is consistent, but hard to predict if we do not know the cursor is on and end of line). As Kakoune is moving more and more towards treating end of lines as any other character, making it clear when the cursor lies on them seems like a good way to reduce surprise. --- colors/default.kak | 2 ++ doc/pages/faces.asciidoc | 6 ++++++ src/face_registry.cc | 2 ++ src/highlighters.cc | 17 ++++++++++------- .../display | 2 +- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/colors/default.kak b/colors/default.kak index 4c2307d3..4a00045c 100644 --- a/colors/default.kak +++ b/colors/default.kak @@ -31,6 +31,8 @@ face PrimarySelection white,blue face SecondarySelection black,blue face PrimaryCursor black,white face SecondaryCursor black,white +face PrimaryCursorEol black,cyan +face SecondaryCursorEol black,cyan face LineNumbers default,default face LineNumberCursor default,default+r face MenuForeground white,blue diff --git a/doc/pages/faces.asciidoc b/doc/pages/faces.asciidoc index 54e6414a..a0eed951 100644 --- a/doc/pages/faces.asciidoc +++ b/doc/pages/faces.asciidoc @@ -57,6 +57,12 @@ areas of the user interface: *SecondaryCursor*:: cursor of the secondary selection +*PrimaryCursorEol*:: + cursor of the primary selection when it lies on and end of line character + +*SecondaryCursorEol*:: + cursor of the secondary selection when it lies on and end of line character + *LineNumbers*:: face used by the number_lines highlighter diff --git a/src/face_registry.cc b/src/face_registry.cc index 65e5506b..4ee2f557 100644 --- a/src/face_registry.cc +++ b/src/face_registry.cc @@ -133,6 +133,8 @@ FaceRegistry::FaceRegistry() { "SecondarySelection", {Face{ Color::Black, Color::Blue }} }, { "PrimaryCursor", {Face{ Color::Black, Color::White }} }, { "SecondaryCursor", {Face{ Color::Black, Color::White }} }, + { "PrimaryCursorEol", {Face{ Color::Black, Color::Cyan }} }, + { "SecondaryCursorEol", {Face{ Color::Black, Color::Cyan }} }, { "LineNumbers", {Face{ Color::Default, Color::Default }} }, { "LineNumberCursor", {Face{ Color::Default, Color::Default, Attribute::Reverse }} }, { "LineNumbersWrapped", {Face{ Color::Default, Color::Default, Attribute::Italic }} }, diff --git a/src/highlighters.cc b/src/highlighters.cc index 626a4e60..544ddc5f 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -1163,10 +1163,11 @@ HighlighterAndId create_matching_char_highlighter(HighlighterParameters params) void highlight_selections(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) { const auto& buffer = context.context.buffer(); - const Face primary_face = get_face("PrimarySelection"); - const Face secondary_face = get_face("SecondarySelection"); - const Face primary_cursor_face = get_face("PrimaryCursor"); - const Face secondary_cursor_face = get_face("SecondaryCursor"); + const Face faces[6] = { + get_face("PrimarySelection"), get_face("SecondarySelection"), + get_face("PrimaryCursor"), get_face("SecondaryCursor"), + get_face("PrimaryCursorEol"), get_face("SecondaryCursorEol"), + }; const auto& selections = context.context.selections(); for (size_t i = 0; i < selections.size(); ++i) @@ -1178,14 +1179,16 @@ void highlight_selections(HighlightContext context, DisplayBuffer& display_buffe const bool primary = (i == selections.main_index()); highlight_range(display_buffer, begin, end, false, - apply_face(primary ? primary_face : secondary_face)); + apply_face(faces[primary ? 0 : 1])); } for (size_t i = 0; i < selections.size(); ++i) { auto& sel = selections[i]; + const BufferCoord coord = sel.cursor(); const bool primary = (i == selections.main_index()); - highlight_range(display_buffer, sel.cursor(), buffer.char_next(sel.cursor()), false, - apply_face(primary ? primary_cursor_face : secondary_cursor_face)); + const bool eol = buffer[coord.line].length() - 1 == coord.column; + highlight_range(display_buffer, coord, buffer.char_next(coord), false, + apply_face(faces[2 + (eol ? 2 : 0) + (primary ? 0 : 1)])); } } diff --git a/test/regression/1435-misplaced-cursor-with-show_matching-hl/display b/test/regression/1435-misplaced-cursor-with-show_matching-hl/display index aa0eb66c..1f7c4a5a 100644 --- a/test/regression/1435-misplaced-cursor-with-show_matching-hl/display +++ b/test/regression/1435-misplaced-cursor-with-show_matching-hl/display @@ -1,4 +1,4 @@ -{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "·" }, { "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] } +{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "·" }, { "face": { "fg": "black", "bg": "cyan", "attributes": [] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] } { "jsonrpc": "2.0", "method": "menu_hide", "params": [] } { "jsonrpc": "2.0", "method": "info_hide", "params": [] } { "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:2 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "yellow", "bg": "default", "attributes": [] }, "contents": "insert" }, { "face": { "fg": "cyan", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sels (1)" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - unnamed0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }