comparison src/drawline.c @ 30395:e516c566fd0c v9.0.0533

patch 9.0.0533: the win_line() function is much too long Commit: https://github.com/vim/vim/commit/e49f9acecc03755db850410b2590ad7312c5224b Author: Bram Moolenaar <Bram@vim.org> Date: Wed Sep 21 15:41:28 2022 +0100 patch 9.0.0533: the win_line() function is much too long Problem: The win_line() function is much too long. Solution: Move code to separate functions.
author Bram Moolenaar <Bram@vim.org>
date Wed, 21 Sep 2022 16:45:04 +0200
parents 5aaacdeee0a1
children 3f2fcc517d79
comparison
equal deleted inserted replaced
30394:c627252d9340 30395:e516c566fd0c
101 unsigned off; // offset in ScreenLines/ScreenAttrs 101 unsigned off; // offset in ScreenLines/ScreenAttrs
102 102
103 int win_attr; // background for the whole window, except 103 int win_attr; // background for the whole window, except
104 // margins and "~" lines. 104 // margins and "~" lines.
105 int wcr_attr; // attributes from 'wincolor' 105 int wcr_attr; // attributes from 'wincolor'
106 #ifdef FEAT_SYN_HL
107 int cul_attr; // set when 'cursorline' active
108 #endif
106 109
107 int screen_line_flags; // flags for screen_line() 110 int screen_line_flags; // flags for screen_line()
108 111
109 int fromcol; // start of inverting 112 int fromcol; // start of inverting
110 int tocol; // end of inverting 113 int tocol; // end of inverting
111 114
112 #ifdef FEAT_LINEBREAK 115 #ifdef FEAT_LINEBREAK
116 long vcol_sbr; // virtual column after showbreak
113 int need_showbreak; // overlong line, skipping first x chars 117 int need_showbreak; // overlong line, skipping first x chars
114 int dont_use_showbreak; // do not use 'showbreak' 118 int dont_use_showbreak; // do not use 'showbreak'
115 #endif 119 #endif
116 120
117 // TRUE when 'cursorlineopt' has "screenline" and cursor is in this line 121 // TRUE when 'cursorlineopt' has "screenline" and cursor is in this line
120 int char_attr; // attributes for the next character 124 int char_attr; // attributes for the next character
121 125
122 int n_extra; // number of extra bytes 126 int n_extra; // number of extra bytes
123 char_u *p_extra; // string of extra chars, plus NUL, only used 127 char_u *p_extra; // string of extra chars, plus NUL, only used
124 // when c_extra and c_final are NUL 128 // when c_extra and c_final are NUL
129 char_u *p_extra_free; // p_extra buffer that needs to be freed
125 int c_extra; // extra chars, all the same 130 int c_extra; // extra chars, all the same
126 int c_final; // final char, mandatory if set 131 int c_final; // final char, mandatory if set
127
128 char_u *p_extra_free; // p_extra buffer that needs to be freed
129 132
130 // saved "extra" items for when draw_state becomes WL_LINE (again) 133 // saved "extra" items for when draw_state becomes WL_LINE (again)
131 int saved_n_extra; 134 int saved_n_extra;
132 char_u *saved_p_extra; 135 char_u *saved_p_extra;
133 int saved_c_extra; 136 int saved_c_extra;
486 // required when 'linebreak' is also set. 489 // required when 'linebreak' is also set.
487 if (wlv->tocol == wlv->vcol) 490 if (wlv->tocol == wlv->vcol)
488 wlv->tocol += wlv->n_extra; 491 wlv->tocol += wlv->n_extra;
489 } 492 }
490 } 493 }
494 }
495 #endif
496
497 #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
498 static void
499 handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv)
500 {
501 # ifdef FEAT_DIFF
502 if (wlv->filler_todo > 0)
503 {
504 // Draw "deleted" diff line(s).
505 if (char2cells(wp->w_fill_chars.diff) > 1)
506 {
507 wlv->c_extra = '-';
508 wlv->c_final = NUL;
509 }
510 else
511 {
512 wlv->c_extra = wp->w_fill_chars.diff;
513 wlv->c_final = NUL;
514 }
515 # ifdef FEAT_RIGHTLEFT
516 if (wp->w_p_rl)
517 wlv->n_extra = wlv->col + 1;
518 else
519 # endif
520 wlv->n_extra = wp->w_width - wlv->col;
521 wlv->char_attr = HL_ATTR(HLF_DED);
522 }
523 # endif
524
525 # ifdef FEAT_LINEBREAK
526 char_u *sbr = get_showbreak_value(wp);
527 if (*sbr != NUL && wlv->need_showbreak)
528 {
529 // Draw 'showbreak' at the start of each broken line.
530 wlv->p_extra = sbr;
531 wlv->c_extra = NUL;
532 wlv->c_final = NUL;
533 wlv->n_extra = (int)STRLEN(sbr);
534 if (wp->w_skipcol == 0 || !wp->w_p_wrap)
535 wlv->need_showbreak = FALSE;
536 wlv->vcol_sbr = wlv->vcol + MB_CHARLEN(sbr);
537 // Correct end of highlighted area for 'showbreak',
538 // required when 'linebreak' is also set.
539 if (wlv->tocol == wlv->vcol)
540 wlv->tocol += wlv->n_extra;
541 // combine 'showbreak' with 'wincolor'
542 wlv->char_attr = hl_combine_attr(wlv->win_attr, HL_ATTR(HLF_AT));
543 # ifdef FEAT_SYN_HL
544 // combine 'showbreak' with 'cursorline'
545 if (wlv->cul_attr != 0)
546 wlv->char_attr = hl_combine_attr(wlv->char_attr, wlv->cul_attr);
547 # endif
548 }
549 # endif
491 } 550 }
492 #endif 551 #endif
493 552
494 #if defined(FEAT_PROP_POPUP) || defined(PROTO) 553 #if defined(FEAT_PROP_POPUP) || defined(PROTO)
495 /* 554 /*
800 wlv->n_extra = 0; 859 wlv->n_extra = 0;
801 } 860 }
802 } 861 }
803 862
804 /* 863 /*
864 * Called when wlv->draw_state is set to WL_LINE.
865 */
866 static void
867 win_line_continue(winlinevars_T *wlv)
868 {
869 if (wlv->saved_n_extra > 0)
870 {
871 // Continue item from end of wrapped line.
872 wlv->n_extra = wlv->saved_n_extra;
873 wlv->c_extra = wlv->saved_c_extra;
874 wlv->c_final = wlv->saved_c_final;
875 wlv->p_extra = wlv->saved_p_extra;
876 wlv->char_attr = wlv->saved_char_attr;
877 }
878 else
879 wlv->char_attr = wlv->win_attr;
880 }
881
882 /*
805 * Display line "lnum" of window 'wp' on the screen. 883 * Display line "lnum" of window 'wp' on the screen.
806 * Start at row "startrow", stop when "endrow" is reached. 884 * Start at row "startrow", stop when "endrow" is reached.
807 * wp->w_virtcol needs to be valid. 885 * wp->w_virtcol needs to be valid.
808 * 886 *
809 * Return the number of last row the line occupies. 887 * Return the number of last row the line occupies.
818 int number_only) // only update the number column 896 int number_only) // only update the number column
819 { 897 {
820 winlinevars_T wlv; // variables passed between functions 898 winlinevars_T wlv; // variables passed between functions
821 899
822 int c = 0; // init for GCC 900 int c = 0; // init for GCC
823 #ifdef FEAT_LINEBREAK
824 long vcol_sbr = -1; // virtual column after showbreak
825 #endif
826 long vcol_prev = -1; // "wlv.vcol" of previous character 901 long vcol_prev = -1; // "wlv.vcol" of previous character
827 char_u *line; // current line 902 char_u *line; // current line
828 char_u *ptr; // current position in "line" 903 char_u *ptr; // current position in "line"
829 904
830 #ifdef FEAT_PROP_POPUP 905 #ifdef FEAT_PROP_POPUP
935 int did_line_attr = 0; 1010 int did_line_attr = 0;
936 #endif 1011 #endif
937 #ifdef FEAT_TERMINAL 1012 #ifdef FEAT_TERMINAL
938 int get_term_attr = FALSE; 1013 int get_term_attr = FALSE;
939 #endif 1014 #endif
1015
940 #ifdef FEAT_SYN_HL 1016 #ifdef FEAT_SYN_HL
941 int cul_attr = 0; // set when 'cursorline' active
942
943 // margin columns for the screen line, needed for when 'cursorlineopt' 1017 // margin columns for the screen line, needed for when 'cursorlineopt'
944 // contains "screenline" 1018 // contains "screenline"
945 int left_curline_col = 0; 1019 int left_curline_col = 0;
946 int right_curline_col = 0; 1020 int right_curline_col = 0;
947 #endif 1021 #endif
986 wlv.startrow = startrow; 1060 wlv.startrow = startrow;
987 wlv.row = startrow; 1061 wlv.row = startrow;
988 wlv.screen_row = wlv.row + W_WINROW(wp); 1062 wlv.screen_row = wlv.row + W_WINROW(wp);
989 wlv.fromcol = -10; 1063 wlv.fromcol = -10;
990 wlv.tocol = MAXCOL; 1064 wlv.tocol = MAXCOL;
1065 #ifdef FEAT_LINEBREAK
1066 wlv.vcol_sbr = -1;
1067 #endif
991 1068
992 if (!number_only) 1069 if (!number_only)
993 { 1070 {
994 // To speed up the loop below, set extra_check when there is linebreak, 1071 // To speed up the loop below, set extra_check when there is linebreak,
995 // trailing white space and/or syntax processing to be done. 1072 // trailing white space and/or syntax processing to be done.
1479 1556
1480 // Only set line_attr here when "screenline" is not present in 1557 // Only set line_attr here when "screenline" is not present in
1481 // 'cursorlineopt'. Otherwise it's done later. 1558 // 'cursorlineopt'. Otherwise it's done later.
1482 if (!wlv.cul_screenline) 1559 if (!wlv.cul_screenline)
1483 { 1560 {
1484 cul_attr = HL_ATTR(HLF_CUL); 1561 wlv.cul_attr = HL_ATTR(HLF_CUL);
1485 # ifdef FEAT_SIGNS 1562 # ifdef FEAT_SIGNS
1486 // Combine the 'cursorline' and sign highlighting, depending on 1563 // Combine the 'cursorline' and sign highlighting, depending on
1487 // the sign priority. 1564 // the sign priority.
1488 if (sign_present && wlv.sattr.sat_linehl > 0) 1565 if (sign_present && wlv.sattr.sat_linehl > 0)
1489 { 1566 {
1490 if (wlv.sattr.sat_priority >= 100) 1567 if (wlv.sattr.sat_priority >= 100)
1491 line_attr = hl_combine_attr(cul_attr, line_attr); 1568 line_attr = hl_combine_attr(wlv.cul_attr, line_attr);
1492 else 1569 else
1493 line_attr = hl_combine_attr(line_attr, cul_attr); 1570 line_attr = hl_combine_attr(line_attr, wlv.cul_attr);
1494 } 1571 }
1495 else 1572 else
1496 # endif 1573 # endif
1497 # if defined(FEAT_QUICKFIX) 1574 # if defined(FEAT_QUICKFIX)
1498 // let the line attribute overrule 'cursorline', otherwise 1575 // let the line attribute overrule 'cursorline', otherwise
1499 // it disappears when both have background set; 1576 // it disappears when both have background set;
1500 // 'cursorline' can use underline or bold to make it show 1577 // 'cursorline' can use underline or bold to make it show
1501 line_attr = hl_combine_attr(cul_attr, line_attr); 1578 line_attr = hl_combine_attr(wlv.cul_attr, line_attr);
1502 # else 1579 # else
1503 line_attr = cul_attr; 1580 line_attr = wlv.cul_attr;
1504 # endif 1581 # endif
1505 } 1582 }
1506 else 1583 else
1507 { 1584 {
1508 line_attr_save = line_attr; 1585 line_attr_save = line_attr;
1556 if (wlv.draw_state != WL_LINE) 1633 if (wlv.draw_state != WL_LINE)
1557 { 1634 {
1558 #ifdef FEAT_SYN_HL 1635 #ifdef FEAT_SYN_HL
1559 if (wlv.cul_screenline) 1636 if (wlv.cul_screenline)
1560 { 1637 {
1561 cul_attr = 0; 1638 wlv.cul_attr = 0;
1562 line_attr = line_attr_save; 1639 line_attr = line_attr_save;
1563 } 1640 }
1564 #endif 1641 #endif
1565
1566 #ifdef FEAT_CMDWIN 1642 #ifdef FEAT_CMDWIN
1567 if (wlv.draw_state == WL_CMDLINE - 1 && wlv.n_extra == 0) 1643 if (wlv.draw_state == WL_CMDLINE - 1 && wlv.n_extra == 0)
1568 { 1644 {
1569 wlv.draw_state = WL_CMDLINE; 1645 wlv.draw_state = WL_CMDLINE;
1570 if (cmdwin_type != 0 && wp == curwin) 1646 if (cmdwin_type != 0 && wp == curwin)
1576 wlv.char_attr = 1652 wlv.char_attr =
1577 hl_combine_attr(wlv.wcr_attr, HL_ATTR(HLF_AT)); 1653 hl_combine_attr(wlv.wcr_attr, HL_ATTR(HLF_AT));
1578 } 1654 }
1579 } 1655 }
1580 #endif 1656 #endif
1581
1582 #ifdef FEAT_FOLDING 1657 #ifdef FEAT_FOLDING
1583 if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) 1658 if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0)
1584 { 1659 {
1585 wlv.draw_state = WL_FOLD; 1660 wlv.draw_state = WL_FOLD;
1586 handle_foldcolumn(wp, &wlv); 1661 handle_foldcolumn(wp, &wlv);
1587 } 1662 }
1588 #endif 1663 #endif
1589
1590 #ifdef FEAT_SIGNS 1664 #ifdef FEAT_SIGNS
1591 if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0) 1665 if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0)
1592 { 1666 {
1593 // Show the sign column when desired or when using Netbeans. 1667 // Show the sign column when desired or when using Netbeans.
1594 wlv.draw_state = WL_SIGN; 1668 wlv.draw_state = WL_SIGN;
1595 if (signcolumn_on(wp)) 1669 if (signcolumn_on(wp))
1596 get_sign_display_info(FALSE, wp, &wlv); 1670 get_sign_display_info(FALSE, wp, &wlv);
1597 } 1671 }
1598 #endif 1672 #endif
1599
1600 if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0) 1673 if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0)
1601 { 1674 {
1602 // Show the line number, if desired. 1675 // Show the line number, if desired.
1603 wlv.draw_state = WL_NR; 1676 wlv.draw_state = WL_NR;
1604 handle_lnum_col(wp, &wlv, sign_present, num_attr); 1677 handle_lnum_col(wp, &wlv, sign_present, num_attr);
1605 } 1678 }
1606
1607 #ifdef FEAT_LINEBREAK 1679 #ifdef FEAT_LINEBREAK
1608 // Check if 'breakindent' applies and show it. 1680 // Check if 'breakindent' applies and show it.
1609 // May change wlv.draw_state to WL_BRI or WL_BRI - 1. 1681 // May change wlv.draw_state to WL_BRI or WL_BRI - 1.
1610 if (wlv.n_extra == 0) 1682 if (wlv.n_extra == 0)
1611 handle_breakindent(wp, &wlv); 1683 handle_breakindent(wp, &wlv);
1612 #endif 1684 #endif
1613
1614 #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF) 1685 #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF)
1615 if (wlv.draw_state == WL_SBR - 1 && wlv.n_extra == 0) 1686 if (wlv.draw_state == WL_SBR - 1 && wlv.n_extra == 0)
1616 { 1687 {
1617 char_u *sbr;
1618
1619 wlv.draw_state = WL_SBR; 1688 wlv.draw_state = WL_SBR;
1620 # ifdef FEAT_DIFF 1689 handle_showbreak_and_filler(wp, &wlv);
1621 if (wlv.filler_todo > 0) 1690 }
1622 { 1691 #endif
1623 // Draw "deleted" diff line(s).
1624 if (char2cells(wp->w_fill_chars.diff) > 1)
1625 {
1626 wlv.c_extra = '-';
1627 wlv.c_final = NUL;
1628 }
1629 else
1630 {
1631 wlv.c_extra = wp->w_fill_chars.diff;
1632 wlv.c_final = NUL;
1633 }
1634 # ifdef FEAT_RIGHTLEFT
1635 if (wp->w_p_rl)
1636 wlv.n_extra = wlv.col + 1;
1637 else
1638 # endif
1639 wlv.n_extra = wp->w_width - wlv.col;
1640 wlv.char_attr = HL_ATTR(HLF_DED);
1641 }
1642 # endif
1643 # ifdef FEAT_LINEBREAK
1644 sbr = get_showbreak_value(wp);
1645 if (*sbr != NUL && wlv.need_showbreak)
1646 {
1647 // Draw 'showbreak' at the start of each broken line.
1648 wlv.p_extra = sbr;
1649 wlv.c_extra = NUL;
1650 wlv.c_final = NUL;
1651 wlv.n_extra = (int)STRLEN(sbr);
1652 if (wp->w_skipcol == 0 || !wp->w_p_wrap)
1653 wlv.need_showbreak = FALSE;
1654 vcol_sbr = wlv.vcol + MB_CHARLEN(sbr);
1655 // Correct end of highlighted area for 'showbreak',
1656 // required when 'linebreak' is also set.
1657 if (wlv.tocol == wlv.vcol)
1658 wlv.tocol += wlv.n_extra;
1659 // combine 'showbreak' with 'wincolor'
1660 wlv.char_attr = hl_combine_attr(wlv.win_attr,
1661 HL_ATTR(HLF_AT));
1662 # ifdef FEAT_SYN_HL
1663 // combine 'showbreak' with 'cursorline'
1664 if (cul_attr != 0)
1665 wlv.char_attr = hl_combine_attr(wlv.char_attr,
1666 cul_attr);
1667 # endif
1668 }
1669 # endif
1670 }
1671 #endif
1672
1673 if (wlv.draw_state == WL_LINE - 1 && wlv.n_extra == 0) 1692 if (wlv.draw_state == WL_LINE - 1 && wlv.n_extra == 0)
1674 { 1693 {
1675 wlv.draw_state = WL_LINE; 1694 wlv.draw_state = WL_LINE;
1676 if (wlv.saved_n_extra) 1695 win_line_continue(&wlv); // use wlv.saved_ values
1677 { 1696 }
1678 // Continue item from end of wrapped line. 1697 }
1679 wlv.n_extra = wlv.saved_n_extra; 1698
1680 wlv.c_extra = wlv.saved_c_extra;
1681 wlv.c_final = wlv.saved_c_final;
1682 wlv.p_extra = wlv.saved_p_extra;
1683 wlv.char_attr = wlv.saved_char_attr;
1684 }
1685 else
1686 wlv.char_attr = wlv.win_attr;
1687 }
1688 }
1689 #ifdef FEAT_SYN_HL 1699 #ifdef FEAT_SYN_HL
1690 if (wlv.cul_screenline && wlv.draw_state == WL_LINE 1700 if (wlv.cul_screenline && wlv.draw_state == WL_LINE
1691 && wlv.vcol >= left_curline_col 1701 && wlv.vcol >= left_curline_col
1692 && wlv.vcol < right_curline_col) 1702 && wlv.vcol < right_curline_col)
1693 { 1703 {
1694 cul_attr = HL_ATTR(HLF_CUL); 1704 wlv.cul_attr = HL_ATTR(HLF_CUL);
1695 line_attr = cul_attr; 1705 line_attr = wlv.cul_attr;
1696 } 1706 }
1697 #endif 1707 #endif
1698 1708
1699 // When still displaying '$' of change command, stop at cursor. 1709 // When still displaying '$' of change command, stop at cursor.
1700 // When only displaying the (relative) line number and that's done, 1710 // When only displaying the (relative) line number and that's done,
2224 mb_c = c; 2234 mb_c = c;
2225 mb_l = 1; 2235 mb_l = 1;
2226 mb_utf8 = FALSE; 2236 mb_utf8 = FALSE;
2227 multi_attr = HL_ATTR(HLF_AT); 2237 multi_attr = HL_ATTR(HLF_AT);
2228 #ifdef FEAT_SYN_HL 2238 #ifdef FEAT_SYN_HL
2229 if (cul_attr) 2239 if (wlv.cul_attr)
2230 multi_attr = hl_combine_attr(multi_attr, cul_attr); 2240 multi_attr = hl_combine_attr(
2241 multi_attr, wlv.cul_attr);
2231 #endif 2242 #endif
2232 multi_attr = hl_combine_attr(wlv.win_attr, multi_attr); 2243 multi_attr = hl_combine_attr(wlv.win_attr, multi_attr);
2233 2244
2234 // put the pointer back to output the double-width 2245 // put the pointer back to output the double-width
2235 // character at the start of the next line. 2246 // character at the start of the next line.
2563 wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1; 2574 wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1;
2564 clear_chartabsize_arg(&cts); 2575 clear_chartabsize_arg(&cts);
2565 2576
2566 // We have just drawn the showbreak value, no need to add 2577 // We have just drawn the showbreak value, no need to add
2567 // space for it again. 2578 // space for it again.
2568 if (wlv.vcol == vcol_sbr) 2579 if (wlv.vcol == wlv.vcol_sbr)
2569 { 2580 {
2570 wlv.n_extra -= MB_CHARLEN(get_showbreak_value(wp)); 2581 wlv.n_extra -= MB_CHARLEN(get_showbreak_value(wp));
2571 if (wlv.n_extra < 0) 2582 if (wlv.n_extra < 0)
2572 wlv.n_extra = 0; 2583 wlv.n_extra = 0;
2573 } 2584 }
2708 #ifdef FEAT_LINEBREAK 2719 #ifdef FEAT_LINEBREAK
2709 char_u *sbr = get_showbreak_value(wp); 2720 char_u *sbr = get_showbreak_value(wp);
2710 2721
2711 // only adjust the tab_len, when at the first column 2722 // only adjust the tab_len, when at the first column
2712 // after the showbreak value was drawn 2723 // after the showbreak value was drawn
2713 if (*sbr != NUL && wlv.vcol == vcol_sbr && wp->w_p_wrap) 2724 if (*sbr != NUL && wlv.vcol == wlv.vcol_sbr && wp->w_p_wrap)
2714 vcol_adjusted = wlv.vcol - MB_CHARLEN(sbr); 2725 vcol_adjusted = wlv.vcol - MB_CHARLEN(sbr);
2715 #endif 2726 #endif
2716 // tab amount depends on current column 2727 // tab amount depends on current column
2717 #ifdef FEAT_VARTABS 2728 #ifdef FEAT_VARTABS
2718 tab_len = tabstop_padding(vcol_adjusted, 2729 tab_len = tabstop_padding(vcol_adjusted,