@@ -103,17 +103,17 @@ namespace detail {
103
103
// how wide the margin for the line number should be
104
104
constexpr std::size_t margin_width = 8 ;
105
105
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 ) {
114
114
const auto & manager = get_manager (path);
115
115
if (!manager.ok ()) {
116
- return " " ;
116
+ return nullopt ;
117
117
}
118
118
auto begin = target_line <= context_size + 1 ? 1 : target_line - context_size;
119
119
auto original_begin = begin;
@@ -129,39 +129,78 @@ namespace detail {
129
129
while (end > target_line && lines[end - original_begin].empty ()) {
130
130
end--;
131
131
}
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) {
133
136
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;
152
141
}
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;
163
151
}
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 ) {
165
204
snippet += ' \n ' ;
166
205
}
167
206
}
0 commit comments