From b09653ccc50c8e83dbd7a789e4a264cbceb4be6d Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 14 Dec 2019 23:18:34 +1100 Subject: [PATCH] highlighters.cc: Add a '-min-digits' flag to the number-lines highlighter. Fixes #3260. --- doc/pages/highlighters.asciidoc | 5 +++++ src/highlighters.cc | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/doc/pages/highlighters.asciidoc b/doc/pages/highlighters.asciidoc index 3eae3bb9..fd95b49f 100644 --- a/doc/pages/highlighters.asciidoc +++ b/doc/pages/highlighters.asciidoc @@ -62,6 +62,11 @@ from the remaining parameters. specify a string to separate the line numbers column with the rest of the buffer (default is '|') + *-min-digits* ::: + always reserve room for at least *num* digits, + so text doesn't jump around as lines are added or removed + (default is 2) + *wrap* [options]:: soft wrap buffer text at window width, with the following *options*: diff --git a/src/highlighters.cc b/src/highlighters.cc index fceb1e68..8878a726 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -1079,17 +1079,19 @@ private: struct LineNumbersHighlighter : Highlighter { - LineNumbersHighlighter(bool relative, bool hl_cursor_line, String separator) + LineNumbersHighlighter(bool relative, bool hl_cursor_line, String separator, int min_digits) : Highlighter{HighlightPass::Move}, m_relative{relative}, m_hl_cursor_line{hl_cursor_line}, - m_separator{std::move(separator)} {} + m_separator{std::move(separator)}, + m_min_digits{min_digits} {} static std::unique_ptr create(HighlighterParameters params, Highlighter*) { static const ParameterDesc param_desc{ { { "relative", { false, "" } }, { "separator", { true, "" } }, + { "min-digits", { true, "" } }, { "hlcursor", { false, "" } } }, ParameterDesc::Flags::None, 0, 0 }; @@ -1099,7 +1101,13 @@ struct LineNumbersHighlighter : Highlighter if (separator.length() > 10) throw runtime_error("separator length is limited to 10 bytes"); - return std::make_unique((bool)parser.get_switch("relative"), (bool)parser.get_switch("hlcursor"), separator.str()); + int min_digits = parser.get_switch("min-digits").map(str_to_int).value_or(2); + if (min_digits < 0) + throw runtime_error("min digits must be positive"); + if (min_digits > 10) + throw runtime_error("min digits is limited to 10"); + + return std::make_unique((bool)parser.get_switch("relative"), (bool)parser.get_switch("hlcursor"), separator.str(), min_digits); } private: @@ -1151,18 +1159,19 @@ private: unique_ids.push_back(ms_id); } - static int compute_digit_count(const Context& context) + int compute_digit_count(const Context& context) const { int digit_count = 0; LineCount last_line = context.buffer().line_count(); for (LineCount c = last_line; c > 0; c /= 10) ++digit_count; - return digit_count; + return std::max(digit_count, m_min_digits); } const bool m_relative; const bool m_hl_cursor_line; const String m_separator; + const int m_min_digits; }; constexpr StringView LineNumbersHighlighter::ms_id; @@ -2194,7 +2203,7 @@ void register_highlighters() "number-lines", { LineNumbersHighlighter::create, "Display line numbers \n" - "Parameters: -relative, -hlcursor, -separator \n" } }); + "Parameters: -relative, -hlcursor, -separator , -min-digits \n" } }); registry.insert({ "show-matching", { create_matching_char_highlighter,