comparison src/drawline.c @ 31371:1c43d8bad31d v9.0.1019

patch 9.0.1019: 'smoothscroll' and virtual text above don't work together Commit: https://github.com/vim/vim/commit/56a40fea9c28f8fc918a0db6de4c048da241cf32 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Dec 6 14:17:57 2022 +0000 patch 9.0.1019: 'smoothscroll' and virtual text above don't work together Problem: 'smoothscroll' and virtual text above don't work together. (Yee Cheng Chin) Solution: Skip virtual text above when w_skipcol is non-zero. (closes #11665)
author Bram Moolenaar <Bram@vim.org>
date Tue, 06 Dec 2022 15:30:04 +0100
parents a93392e93a53
children 552ca9b4218d
comparison
equal deleted inserted replaced
31370:b34c56a60bcb 31371:1c43d8bad31d
635 int vcol, // current text column 635 int vcol, // current text column
636 int scr_col, // current screen column 636 int scr_col, // current screen column
637 int *n_extra, // nr of bytes for virtual text 637 int *n_extra, // nr of bytes for virtual text
638 char_u **p_extra, // virtual text 638 char_u **p_extra, // virtual text
639 int *n_attr, // attribute cells, NULL if not used 639 int *n_attr, // attribute cells, NULL if not used
640 int *n_attr_skip) // cells to skip attr, NULL if not used 640 int *n_attr_skip, // cells to skip attr, NULL if not used
641 int do_skip) // skip_cells is not zero
641 { 642 {
642 int right = (tp->tp_flags & TP_FLAG_ALIGN_RIGHT); 643 int right = (tp->tp_flags & TP_FLAG_ALIGN_RIGHT);
643 int above = (tp->tp_flags & TP_FLAG_ALIGN_ABOVE); 644 int above = (tp->tp_flags & TP_FLAG_ALIGN_ABOVE);
644 int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW); 645 int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW);
645 int wrap = (tp->tp_flags & TP_FLAG_WRAP); 646 int wrap = (tp->tp_flags & TP_FLAG_WRAP);
688 if (before < 0) 689 if (before < 0)
689 before = 0; 690 before = 0;
690 else 691 else
691 n_used = *n_extra; 692 n_used = *n_extra;
692 } 693 }
694 else if (below && before > vcol && do_skip)
695 before -= vcol;
693 else 696 else
694 before = 0; 697 before = 0;
695 } 698 }
696 } 699 }
697 700
1498 { 1501 {
1499 wlv.win_attr = wlv.wcr_attr; 1502 wlv.win_attr = wlv.wcr_attr;
1500 area_highlighting = TRUE; 1503 area_highlighting = TRUE;
1501 } 1504 }
1502 1505
1506 // When w_skipcol is non-zero and there is virtual text above the actual
1507 // text, then this much of the virtual text is skipped.
1508 int skipcol_in_text_prop_above = 0;
1509
1503 #ifdef FEAT_PROP_POPUP 1510 #ifdef FEAT_PROP_POPUP
1504 if (WIN_IS_POPUP(wp)) 1511 if (WIN_IS_POPUP(wp))
1505 wlv.screen_line_flags |= SLF_POPUP; 1512 wlv.screen_line_flags |= SLF_POPUP;
1513
1514 char_u *prop_start;
1515 text_prop_count = get_text_props(wp->w_buffer, lnum, &prop_start, FALSE);
1516 if (text_prop_count > 0)
1517 {
1518 // Make a copy of the properties, so that they are properly
1519 // aligned.
1520 text_props = ALLOC_MULT(textprop_T, text_prop_count);
1521 if (text_props != NULL)
1522 mch_memmove(text_props, prop_start,
1523 text_prop_count * sizeof(textprop_T));
1524
1525 // Allocate an array for the indexes.
1526 text_prop_idxs = ALLOC_MULT(int, text_prop_count);
1527 if (text_prop_idxs == NULL)
1528 VIM_CLEAR(text_props);
1529
1530 if (text_props != NULL)
1531 {
1532 area_highlighting = TRUE;
1533 extra_check = TRUE;
1534
1535 // When skipping virtual text the props need to be sorted. The
1536 // order is reversed!
1537 if (lnum == wp->w_topline && wp->w_skipcol > 0)
1538 {
1539 for (int i = 0; i < text_prop_count; ++i)
1540 text_prop_idxs[i] = i;
1541 sort_text_props(wp->w_buffer, text_props,
1542 text_prop_idxs, text_prop_count);
1543 }
1544
1545 // Text props "above" move the line number down to where the text
1546 // is. Only count the ones that are visible, not those that are
1547 // skipped because of w_skipcol.
1548 int text_width = wp->w_width - win_col_off(wp);
1549 for (int i = text_prop_count - 1; i >= 0; --i)
1550 if (text_props[i].tp_flags & TP_FLAG_ALIGN_ABOVE)
1551 {
1552 if (lnum == wp->w_topline
1553 && wp->w_skipcol - skipcol_in_text_prop_above
1554 >= text_width)
1555 {
1556 // This virtual text above is skipped, remove it from
1557 // the array.
1558 skipcol_in_text_prop_above += text_width;
1559 for (int j = i + 1; j < text_prop_count; ++j)
1560 text_props[j - 1] = text_props[j];
1561 ++i;
1562 --text_prop_count;
1563 }
1564 else
1565 ++wlv.text_prop_above_count;
1566 }
1567 }
1568 }
1506 #endif 1569 #endif
1507 1570
1508 // 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the 1571 // 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the
1509 // first character to be displayed. 1572 // first character to be displayed.
1510 if (wp->w_p_wrap) 1573 if (wp->w_p_wrap)
1511 v = startrow == 0 ? wp->w_skipcol : 0; 1574 v = startrow == 0 ? wp->w_skipcol - skipcol_in_text_prop_above : 0;
1512 else 1575 else
1513 v = wp->w_leftcol; 1576 v = wp->w_leftcol;
1514 if (v > 0 && !number_only) 1577 if (v > 0 && !number_only)
1515 { 1578 {
1516 char_u *prev_ptr = ptr; 1579 char_u *prev_ptr = ptr;
1557 } 1620 }
1558 1621
1559 #ifdef FEAT_PROP_POPUP 1622 #ifdef FEAT_PROP_POPUP
1560 // If there the text doesn't reach to the desired column, need to skip 1623 // If there the text doesn't reach to the desired column, need to skip
1561 // "skip_cells" cells when virtual text follows. 1624 // "skip_cells" cells when virtual text follows.
1562 if (!wp->w_p_wrap && v > wlv.vcol) 1625 if ((!wp->w_p_wrap || (lnum == wp->w_topline && wp->w_skipcol > 0))
1626 && v > wlv.vcol)
1563 skip_cells = v - wlv.vcol; 1627 skip_cells = v - wlv.vcol;
1564 #endif 1628 #endif
1565 1629
1566 // Adjust for when the inverted text is before the screen, 1630 // Adjust for when the inverted text is before the screen,
1567 // and when the start of the inverted text is before the screen. 1631 // and when the start of the inverted text is before the screen.
1697 { 1761 {
1698 line_attr_save = wlv.line_attr; 1762 line_attr_save = wlv.line_attr;
1699 margin_columns_win(wp, &left_curline_col, &right_curline_col); 1763 margin_columns_win(wp, &left_curline_col, &right_curline_col);
1700 } 1764 }
1701 area_highlighting = TRUE; 1765 area_highlighting = TRUE;
1702 }
1703 }
1704 #endif
1705
1706 #ifdef FEAT_PROP_POPUP
1707 {
1708 char_u *prop_start;
1709
1710 text_prop_count = get_text_props(wp->w_buffer, lnum,
1711 &prop_start, FALSE);
1712 if (text_prop_count > 0)
1713 {
1714 // Make a copy of the properties, so that they are properly
1715 // aligned.
1716 text_props = ALLOC_MULT(textprop_T, text_prop_count);
1717 if (text_props != NULL)
1718 mch_memmove(text_props, prop_start,
1719 text_prop_count * sizeof(textprop_T));
1720
1721 // Allocate an array for the indexes.
1722 text_prop_idxs = ALLOC_MULT(int, text_prop_count);
1723 if (text_prop_idxs == NULL)
1724 VIM_CLEAR(text_props);
1725
1726 if (text_props != NULL)
1727 {
1728 area_highlighting = TRUE;
1729 extra_check = TRUE;
1730 // text props "above" move the line number down to where the
1731 // text is.
1732 for (int i = 0; i < text_prop_count; ++i)
1733 if (text_props[i].tp_flags & TP_FLAG_ALIGN_ABOVE)
1734 ++wlv.text_prop_above_count;
1735 }
1736 } 1766 }
1737 } 1767 }
1738 #endif 1768 #endif
1739 1769
1740 win_line_start(wp, &wlv, FALSE); 1770 win_line_start(wp, &wlv, FALSE);
2057 // exactly the same. 2087 // exactly the same.
2058 start_line = text_prop_position(wp, tp, 2088 start_line = text_prop_position(wp, tp,
2059 wlv.vcol, 2089 wlv.vcol,
2060 wlv.col, 2090 wlv.col,
2061 &wlv.n_extra, &wlv.p_extra, 2091 &wlv.n_extra, &wlv.p_extra,
2062 &n_attr, &wlv.n_attr_skip); 2092 &n_attr, &wlv.n_attr_skip,
2093 skip_cells > 0);
2063 if (wlv.p_extra != prev_p_extra) 2094 if (wlv.p_extra != prev_p_extra)
2064 { 2095 {
2065 // wlv.p_extra was allocated 2096 // wlv.p_extra was allocated
2066 vim_free(p_extra_free2); 2097 vim_free(p_extra_free2);
2067 p_extra_free2 = wlv.p_extra; 2098 p_extra_free2 = wlv.p_extra;