@@ -260,7 +260,7 @@ view_curses::mvwattrline(ncplane* window,
260260 int y,
261261 const int x,
262262 attr_line_t & al,
263- const struct line_range & lr_chars,
263+ const line_range& lr_chars,
264264 role_t base_role)
265265{
266266 auto & sa = al.get_attrs ();
@@ -286,9 +286,12 @@ view_curses::mvwattrline(ncplane* window,
286286 }
287287 }
288288
289+ auto last_ch_col_count = 0 ;
290+ std::optional<int > join_start_index;
289291 for (size_t lpc = 0 ; lpc < line.size ();) {
290292 int exp_start_index = expanded_line.size ();
291293 auto ch = static_cast <unsigned char >(line[lpc]);
294+ auto curr_ch_col_count = 0 ;
292295
293296 if (char_index == lr_chars.lr_start ) {
294297 lr_bytes.lr_start = exp_start_index;
@@ -299,8 +302,10 @@ view_curses::mvwattrline(ncplane* window,
299302
300303 switch (ch) {
301304 case ' \t ' : {
305+ auto tab_size = 0 ;
302306 do {
303307 expanded_line.push_back (' ' );
308+ tab_size += 1 ;
304309 char_index += 1 ;
305310 if (char_index == lr_chars.lr_start ) {
306311 lr_bytes.lr_start = expanded_line.size ();
@@ -309,7 +314,8 @@ view_curses::mvwattrline(ncplane* window,
309314 lr_bytes.lr_end = expanded_line.size ();
310315 retval.mr_chars_out = char_index;
311316 }
312- } while (expanded_line.size () % 8 );
317+ } while (expanded_line.size () % 8 > 0 );
318+ curr_ch_col_count = tab_size;
313319 utf_adjustments.emplace_back (
314320 lpc, expanded_line.size () - exp_start_index - 1 );
315321 lpc += 1 ;
@@ -319,27 +325,31 @@ view_curses::mvwattrline(ncplane* window,
319325 case ' \x1b ' :
320326 expanded_line.append (" \u238b " );
321327 utf_adjustments.emplace_back (lpc, -1 );
328+ curr_ch_col_count = 1 ;
322329 char_index += 1 ;
323330 lpc += 1 ;
324331 break ;
325332
326333 case ' \b ' :
327334 expanded_line.append (" \u232b " );
328335 utf_adjustments.emplace_back (lpc, -1 );
336+ curr_ch_col_count = 1 ;
329337 char_index += 1 ;
330338 lpc += 1 ;
331339 break ;
332340
333341 case ' \x07 ' :
334342 expanded_line.append (" \U0001F514 " );
335343 utf_adjustments.emplace_back (lpc, -1 );
344+ curr_ch_col_count = 1 ;
336345 char_index += 1 ;
337346 lpc += 1 ;
338347 break ;
339348
340349 case ' \r ' :
341350 case ' \n ' :
342351 expanded_line.push_back (' ' );
352+ curr_ch_col_count = 1 ;
343353 char_index += 1 ;
344354 lpc += 1 ;
345355 break ;
@@ -349,6 +359,7 @@ view_curses::mvwattrline(ncplane* window,
349359 expanded_line.push_back (0xe2 );
350360 expanded_line.push_back (0x90 );
351361 expanded_line.push_back (0x80 + ch);
362+ curr_ch_col_count = 1 ;
352363 char_index += 1 ;
353364 lpc += 1 ;
354365 break ;
@@ -368,21 +379,26 @@ view_curses::mvwattrline(ncplane* window,
368379 " error:%d:%zu:%s" , y, x + lpc, read_res.unwrapErr ());
369380 expanded_line.resize (exp_read_start);
370381 expanded_line.push_back (' ?' );
382+ curr_ch_col_count = 1 ;
371383 char_index += 1 ;
372384 lpc = lpc_start + 1 ;
373385 } else {
374386 auto wch = read_res.unwrap ();
387+ if (wch == L' \u200d ' ) {
388+ join_start_index = char_index - last_ch_col_count;
389+ continue ;
390+ }
375391 auto wcw_res = uc_width (wch, " UTF-8" );
376392 if (wcw_res < 0 ) {
377- log_trace (
378- " uc_width(%x) does not recognize width character" ,
379- wch);
393+ log_trace (" uc_width(%x) does not recognize character" ,
394+ wch);
380395 wcw_res = 1 ;
381396 }
382397 if (lpc > (lpc_start + 1 )) {
383398 utf_adjustments.emplace_back (
384399 lpc_start, wcw_res - (lpc - lpc_start));
385400 }
401+ curr_ch_col_count = wcw_res;
386402 char_index += wcw_res;
387403 if (lr_bytes.lr_end == -1 && char_index > lr_chars.lr_end ) {
388404 lr_bytes.lr_end = exp_start_index;
@@ -392,6 +408,15 @@ view_curses::mvwattrline(ncplane* window,
392408 break ;
393409 }
394410 }
411+ if (join_start_index) {
412+ curr_ch_col_count = std::max (last_ch_col_count, curr_ch_col_count);
413+ char_index = join_start_index.value () + curr_ch_col_count;
414+ if (char_index > lr_chars.lr_end ) {
415+ retval.mr_chars_out = char_index;
416+ }
417+ join_start_index = std::nullopt ;
418+ }
419+ last_ch_col_count = curr_ch_col_count;
395420 }
396421 if (lr_bytes.lr_start == -1 ) {
397422 lr_bytes.lr_start = expanded_line.size ();
@@ -947,7 +972,8 @@ view_colors::init_roles(const lnav_theme& lt,
947972 std::string err;
948973
949974 size_t icon_index = 0 ;
950- for (const auto & ic : {
975+ for (const auto & ic :
976+ {
951977 lt.lt_icon_hidden ,
952978 lt.lt_icon_ok ,
953979 lt.lt_icon_info ,
@@ -1167,8 +1193,7 @@ view_colors::init_roles(const lnav_theme& lt,
11671193 auto new_cursor_bg = this ->match_color (
11681194 styling::color_unit::from_rgb (adjusted_cursor.to_rgb ()));
11691195 this ->get_role_attrs (role_t ::VCR_CURSOR_LINE)
1170- .ra_normal .ta_bg_color
1171- = new_cursor_bg;
1196+ .ra_normal .ta_bg_color = new_cursor_bg;
11721197 }
11731198 if (lt.lt_style_popup .pp_value .sc_background_color .empty ()) {
11741199 auto adjusted_cursor = bg_as_lab;
@@ -1192,8 +1217,7 @@ view_colors::init_roles(const lnav_theme& lt,
11921217 auto new_cursor_bg = this ->match_color (
11931218 styling::color_unit::from_rgb (adjusted_cursor.to_rgb ()));
11941219 this ->get_role_attrs (role_t ::VCR_INLINE_CODE)
1195- .ra_normal .ta_bg_color
1196- = new_cursor_bg;
1220+ .ra_normal .ta_bg_color = new_cursor_bg;
11971221 }
11981222 if (lt.lt_style_quoted_code .pp_value .sc_background_color .empty ()) {
11991223 auto adjusted_cursor = bg_as_lab;
@@ -1205,11 +1229,9 @@ view_colors::init_roles(const lnav_theme& lt,
12051229 auto new_cursor_bg = this ->match_color (
12061230 styling::color_unit::from_rgb (adjusted_cursor.to_rgb ()));
12071231 this ->get_role_attrs (role_t ::VCR_QUOTED_CODE)
1208- .ra_normal .ta_bg_color
1209- = new_cursor_bg;
1232+ .ra_normal .ta_bg_color = new_cursor_bg;
12101233 this ->get_role_attrs (role_t ::VCR_CODE_BORDER)
1211- .ra_normal .ta_bg_color
1212- = new_cursor_bg;
1234+ .ra_normal .ta_bg_color = new_cursor_bg;
12131235 }
12141236 }
12151237 }
0 commit comments