@@ -103,17 +103,17 @@ namespace detail {
103103 // how wide the margin for the line number should be
104104 constexpr std::size_t margin_width = 8 ;
105105
106- // 1-indexed line
107- std::string get_snippet (
108- const std::string& path,
109- std::size_t target_line,
110- nullable <std::uint32_t > column,
111- std:: size_t context_size,
112- bool color
113- ) {
106+ struct snippet_context {
107+ std::size_t original_begin;
108+ std::size_t begin;
109+ std::size_t end;
110+ std::vector <std::string> lines;
111+ };
112+
113+ optional<snippet_context> get_lines ( const std::string& path, std:: size_t target_line, std:: size_t context_size ) {
114114 const auto & manager = get_manager (path);
115115 if (!manager.ok ()) {
116- return " " ;
116+ return nullopt ;
117117 }
118118 auto begin = target_line <= context_size + 1 ? 1 : target_line - context_size;
119119 auto original_begin = begin;
@@ -129,39 +129,78 @@ namespace detail {
129129 while (end > target_line && lines[end - original_begin].empty ()) {
130130 end--;
131131 }
132- // make the snippet
132+ return snippet_context{original_begin, begin, end, std::move (lines)};
133+ }
134+
135+ std::string write_line_number (std::size_t line, std::size_t target_line, bool color) {
133136 std::string snippet;
134- for (auto line = begin; line <= end; line++) {
135- auto line_str = std::to_string (line);
136- if (line == target_line) {
137- if (color) {
138- snippet += YELLOW;
139- }
140- auto line_width = line_str.size () + 3 ;
141- snippet += microfmt::format (
142- " {>{}} > {}: " ,
143- line_width > margin_width ? 0 : margin_width - line_width,
144- " " ,
145- line_str
146- );
147- if (color) {
148- snippet += RESET;
149- }
150- } else {
151- snippet += microfmt::format (" {>{}}: " , margin_width, line_str);
137+ auto line_str = std::to_string (line);
138+ if (line == target_line) {
139+ if (color) {
140+ snippet += YELLOW;
152141 }
153- snippet += lines[line - original_begin];
154- if (line == target_line && column.has_value ()) {
155- snippet += microfmt::format (" \n {>{}}" , margin_width + 2 + column.value () - 1 , " " );
156- if (color) {
157- snippet += YELLOW;
158- }
159- snippet += " ^" ;
160- if (color) {
161- snippet += RESET;
162- }
142+ auto line_width = line_str.size () + 3 ;
143+ snippet += microfmt::format (
144+ " {>{}} > {}: " ,
145+ line_width > margin_width ? 0 : margin_width - line_width,
146+ " " ,
147+ line_str
148+ );
149+ if (color) {
150+ snippet += RESET;
163151 }
164- if (line != end) {
152+ } else {
153+ snippet += microfmt::format (" {>{}}: " , margin_width, line_str);
154+ }
155+ return snippet;
156+ }
157+
158+ std::string write_carrot (std::uint32_t column, bool color) {
159+ std::string snippet;
160+ snippet += microfmt::format (" \n {>{}}" , margin_width + 2 + column - 1 , " " );
161+ if (color) {
162+ snippet += YELLOW;
163+ }
164+ snippet += " ^" ;
165+ if (color) {
166+ snippet += RESET;
167+ }
168+ return snippet;
169+ }
170+
171+ std::string write_line (
172+ std::size_t line,
173+ nullable<std::uint32_t > column,
174+ std::size_t target_line,
175+ bool color,
176+ const snippet_context& context
177+ ) {
178+ std::string snippet;
179+ snippet += write_line_number (line, target_line, color);
180+ snippet += context.lines [line - context.original_begin ];
181+ if (line == target_line && column.has_value ()) {
182+ snippet += write_carrot (column.value (), color);
183+ }
184+ return snippet;
185+ }
186+
187+ // 1-indexed line
188+ std::string get_snippet (
189+ const std::string& path,
190+ std::size_t target_line,
191+ nullable<std::uint32_t > column,
192+ std::size_t context_size,
193+ bool color
194+ ) {
195+ const auto context_res = get_lines (path, target_line, context_size);
196+ if (!context_res) {
197+ return " " ;
198+ }
199+ const auto & context = context_res.unwrap ();
200+ std::string snippet;
201+ for (auto line = context.begin ; line <= context.end ; line++) {
202+ snippet += write_line (line, column, target_line, color, context);
203+ if (line != context.end ) {
165204 snippet += ' \n ' ;
166205 }
167206 }
0 commit comments