@@ -1000,6 +1000,7 @@ const HighlighterDesc line_numbers_desc = {
10001000 " Display line numbers" ,
10011001 { {
10021002 { " relative" , { {}, " show line numbers relative to the main cursor line" } },
1003+ { " full-relative" , { {}, " show line numbers relative to the main cursor line and the main cursor line as 0" } },
10031004 { " separator" , { ArgCompleter{}, " string to separate the line numbers column from the rest of the buffer (default '|')" } },
10041005 { " cursor-separator" , { ArgCompleter{}, " identical to -separator but applies only to the line of the cursor (default is the same value passed to -separator)" } },
10051006 { " min-digits" , { ArgCompleter{}, " use at least the given number of columns to display line numbers (default 2)" } },
@@ -1009,9 +1010,10 @@ const HighlighterDesc line_numbers_desc = {
10091010};
10101011struct LineNumbersHighlighter : Highlighter
10111012{
1012- LineNumbersHighlighter (bool relative, bool hl_cursor_line, String separator, String cursor_separator, int min_digits)
1013+ LineNumbersHighlighter (bool relative, bool zero_cursor_line, bool hl_cursor_line, String separator, String cursor_separator, int min_digits)
10131014 : Highlighter{HighlightPass::Move},
10141015 m_relative{relative},
1016+ m_zero_cursor_line{zero_cursor_line},
10151017 m_hl_cursor_line{hl_cursor_line},
10161018 m_separator{std::move (separator)},
10171019 m_cursor_separator{std::move (cursor_separator)},
@@ -1035,8 +1037,9 @@ struct LineNumbersHighlighter : Highlighter
10351037 throw runtime_error (" min digits must be positive" );
10361038 if (min_digits > 10 )
10371039 throw runtime_error (" min digits is limited to 10" );
1038-
1039- return make_unique_ptr<LineNumbersHighlighter>((bool )parser.get_switch (" relative" ), (bool )parser.get_switch (" hlcursor" ), separator.str (), cursor_separator.str (), min_digits);
1040+ const bool relative = (bool )parser.get_switch (" relative" );
1041+ const bool full_relative = (bool )parser.get_switch (" full-relative" );
1042+ return make_unique_ptr<LineNumbersHighlighter>(relative or full_relative, full_relative, (bool )parser.get_switch (" hlcursor" ), separator.str (), cursor_separator.str (), min_digits);
10401043 }
10411044
10421045private:
@@ -1051,7 +1054,7 @@ struct LineNumbersHighlighter : Highlighter
10511054 const Face face = faces[" LineNumbers" ];
10521055 const Face face_wrapped = faces[" LineNumbersWrapped" ];
10531056 const Face face_absolute = faces[" LineNumberCursor" ];
1054- int digit_count = compute_digit_count (context. context );
1057+ int digit_count = compute_digit_count (context);
10551058
10561059 char format[16 ];
10571060 format_to (format, " \\ {:{}}" , digit_count);
@@ -1061,7 +1064,7 @@ struct LineNumbersHighlighter : Highlighter
10611064 {
10621065 const int current_line = (int )line.range ().begin .line + 1 ;
10631066 const bool is_cursor_line = main_line == current_line;
1064- const int line_to_format = (m_relative and not is_cursor_line) ?
1067+ const int line_to_format = (m_relative and ( not is_cursor_line or m_zero_cursor_line) ) ?
10651068 current_line - main_line : current_line;
10661069 char buffer[16 ];
10671070 format_to (buffer, format, std::abs (line_to_format));
@@ -1083,7 +1086,7 @@ struct LineNumbersHighlighter : Highlighter
10831086 if (contains (context.disabled_ids , ms_id))
10841087 return ;
10851088
1086- ColumnCount width = compute_digit_count (context. context ) + m_separator.column_length ();
1089+ ColumnCount width = compute_digit_count (context) + m_separator.column_length ();
10871090 setup.widget_columns += width;
10881091 }
10891092
@@ -1092,16 +1095,21 @@ struct LineNumbersHighlighter : Highlighter
10921095 unique_ids.push_back (ms_id);
10931096 }
10941097
1095- int compute_digit_count (const Context & context) const
1098+ int compute_digit_count (const HighlightContext & context) const
10961099 {
10971100 int digit_count = 0 ;
1098- LineCount last_line = context.buffer ().line_count ();
1099- for (LineCount c = last_line; c > 0 ; c /= 10 )
1101+ auto cursor_line = context.context .selections ().main ().cursor ().line + 1 ;
1102+ LineCount line_count = (m_relative and m_zero_cursor_line)
1103+ ? std::max (abs (context.setup .first_line - cursor_line),
1104+ abs (context.setup .first_line + context.setup .line_count - cursor_line))
1105+ : context.context .buffer ().line_count ();
1106+ for (LineCount c = line_count; c > 0 ; c /= 10 )
11001107 ++digit_count;
11011108 return std::max (digit_count, m_min_digits);
11021109 }
11031110
11041111 const bool m_relative;
1112+ const bool m_zero_cursor_line;
11051113 const bool m_hl_cursor_line;
11061114 const String m_separator;
11071115 const String m_cursor_separator;
0 commit comments