Mercurial > vim
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; |