diff --git a/README.asciidoc b/README.asciidoc index a66ead88..35d7540f 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -637,7 +637,8 @@ general highlighters are: . * +show_matching+: highlight matching char of the character under the selections cursor using +MatchingChar+ face. - * +number_lines+: show line numbers + * +number_lines <-relative>+: show line numbers. The -relative switch will enable relative + line numbers. * +fill +: fill using given face, mostly useful with the +regions+ highlighter (see below) @@ -895,6 +896,8 @@ there are some builtins faces used by internal Kakoune functionalities: * +PrimaryCursor+: cursor of the primary selection * +SecondaryCursor+: cursor of the secondary selection * +LineNumbers+: face used by the number_lines highlighter + * +LineNumberAbsolute+: face used to highlight the line number of the main + selection * +MenuForeground+: face for the selected element in menus * +MenuBackground+: face for the not selected elements in menus * +Information+: face for the informations windows and information messages diff --git a/src/face_registry.cc b/src/face_registry.cc index 367b99b4..ffdf5ab6 100644 --- a/src/face_registry.cc +++ b/src/face_registry.cc @@ -96,6 +96,7 @@ FaceRegistry::FaceRegistry() { "PrimaryCursor", Face{ Colors::Black, Colors::White } }, { "SecondaryCursor", Face{ Colors::Black, Colors::White } }, { "LineNumbers", Face{ Colors::Default, Colors::Default } }, + { "LineNumberAbsolute", Face{ Colors::Black, Colors::Blue } }, { "MenuForeground", Face{ Colors::White, Colors::Blue } }, { "MenuBackground", Face{ Colors::Blue, Colors::White } }, { "Information", Face{ Colors::Black, Colors::Yellow } }, diff --git a/src/highlighters.cc b/src/highlighters.cc index 900835cf..4f9e45f3 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -594,26 +594,58 @@ void show_whitespaces(const Context& context, HighlightFlags flags, DisplayBuffe } } +template void show_line_numbers(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer, BufferRange) { + const Face face = get_face("LineNumbers"); + const Face face_absolute = get_face("LineNumberAbsolute"); LineCount last_line = context.buffer().line_count(); int digit_count = 0; for (LineCount c = last_line; c > 0; c /= 10) ++digit_count; char format[] = "%?d│"; - format[1] = '0' + digit_count; - const Face face = get_face("LineNumbers"); + format[1] = '0' + digit_count + (relative ? 1 : 0); + int main_selection = (int)context.selections().main().cursor().line + 1; for (auto& line : display_buffer.lines()) { + int current_line = (int)line.range().first.line + 1; char buffer[16]; - snprintf(buffer, 16, format, (int)line.range().first.line + 1); - DisplayAtom atom{buffer}; - atom.face = face; - line.insert(line.begin(), std::move(atom)); + if (relative) + { + if (main_selection == current_line) + { + snprintf(buffer, 16, format, current_line); + DisplayAtom atom{buffer}; + atom.face = face_absolute; + line.insert(line.begin(), std::move(atom)); + } + else { + snprintf(buffer, 16, format, current_line - main_selection); + DisplayAtom atom{buffer}; + atom.face = face; + line.insert(line.begin(), std::move(atom)); + } + } + else { + snprintf(buffer, 16, format, current_line); + DisplayAtom atom{buffer}; + (main_selection == current_line) ? atom.face = face_absolute + : atom.face = face; + line.insert(line.begin(), std::move(atom)); + } } } +HighlighterAndId number_lines_factory(HighlighterParameters params) +{ + if (params.size() > 1) + throw runtime_error("wrong parameter count"); + + return (params.size() == 1 && params[0] == "-relative") ? HighlighterAndId("number_lines_relative", make_simple_highlighter(show_line_numbers)) + : HighlighterAndId("number_lines", make_simple_highlighter(show_line_numbers)); +} + void show_matching_char(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer, BufferRange) { const Face face = get_face("MatchingChar"); @@ -1208,8 +1240,9 @@ void register_highlighters() registry.append({ "number_lines", - { simple_factory("number_lines", show_line_numbers), - "Display line numbers" } }); + { number_lines_factory, + "Display line numbers \n" + "Parameters: -relative" } }); registry.append({ "show_matching", { simple_factory("show_matching", show_matching_char),