comparison src/drawline.c @ 30367:95bf6aa369ee v9.0.0519

patch 9.0.0519: the win_line() function is much too long Commit: https://github.com/vim/vim/commit/d7657e95b21f660a202a5118af059aa17ad37120 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Sep 20 18:59:30 2022 +0100 patch 9.0.0519: the win_line() function is much too long Problem: The win_line() function is much too long. Solution: Move the code to draw the line number to a separate function.
author Bram Moolenaar <Bram@vim.org>
date Tue, 20 Sep 2022 20:00:04 +0200
parents 748b8dcfba57
children ba7db97776b2
comparison
equal deleted inserted replaced
30366:bf0aec628dad 30367:95bf6aa369ee
100 100
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 106
106 int screen_line_flags; // flags for screen_line() 107 int screen_line_flags; // flags for screen_line()
107 108
108 // TRUE when 'cursorlineopt' has "screenline" and cursor is in this line 109 // TRUE when 'cursorlineopt' has "screenline" and cursor is in this line
109 int cul_screenline; 110 int cul_screenline;
121 char_u *saved_p_extra; 122 char_u *saved_p_extra;
122 int saved_c_extra; 123 int saved_c_extra;
123 int saved_c_final; 124 int saved_c_final;
124 int saved_char_attr; 125 int saved_char_attr;
125 126
127 char_u extra[21]; // "%ld " and 'fdc' must fit in here
128
126 #ifdef FEAT_DIFF 129 #ifdef FEAT_DIFF
127 hlf_T diff_hlf; // type of diff highlighting 130 hlf_T diff_hlf; // type of diff highlighting
131 #endif
132 int filler_lines; // nr of filler lines to be drawn
133 int filler_todo; // nr of filler lines still to do + 1
134 #ifdef FEAT_SIGNS
135 sign_attrs_T sattr;
128 #endif 136 #endif
129 } winlinevars_T; 137 } winlinevars_T;
130 138
131 // draw_state values for items that are drawn in sequence: 139 // draw_state values for items that are drawn in sequence:
132 #define WL_START 0 // nothing done yet, must be zero 140 #define WL_START 0 // nothing done yet, must be zero
169 && lnum == wp->w_cursor.lnum 177 && lnum == wp->w_cursor.lnum
170 && (wp->w_p_culopt_flags & CULOPT_NBR); 178 && (wp->w_p_culopt_flags & CULOPT_NBR);
171 } 179 }
172 180
173 /* 181 /*
174 * Get information needed to display the sign in line 'lnum' in window 'wp'. 182 * Get information needed to display the sign in line "wlv->lnum" in window
175 * If 'nrcol' is TRUE, the sign is going to be displayed in the number column. 183 * "wp".
184 * If "nrcol" is TRUE, the sign is going to be displayed in the number column.
176 * Otherwise the sign is going to be displayed in the sign column. 185 * Otherwise the sign is going to be displayed in the sign column.
177 */ 186 */
178 static void 187 static void
179 get_sign_display_info( 188 get_sign_display_info(
180 int nrcol, 189 int nrcol,
181 win_T *wp, 190 win_T *wp,
182 linenr_T lnum, 191 winlinevars_T *wlv)
183 winlinevars_T *wlv,
184 sign_attrs_T *sattr,
185 int wcr_attr,
186 int filler_lines UNUSED,
187 int filler_todo UNUSED,
188 char_u *extra)
189 { 192 {
190 int text_sign; 193 int text_sign;
191 # ifdef FEAT_SIGN_ICONS 194 # ifdef FEAT_SIGN_ICONS
192 int icon_sign; 195 int icon_sign;
193 # endif 196 # endif
197 wlv->c_final = NUL; 200 wlv->c_final = NUL;
198 if (nrcol) 201 if (nrcol)
199 wlv->n_extra = number_width(wp) + 1; 202 wlv->n_extra = number_width(wp) + 1;
200 else 203 else
201 { 204 {
202 if (use_cursor_line_sign(wp, lnum)) 205 if (use_cursor_line_sign(wp, wlv->lnum))
203 wlv->char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLS)); 206 wlv->char_attr = hl_combine_attr(wlv->wcr_attr, HL_ATTR(HLF_CLS));
204 else 207 else
205 wlv->char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC)); 208 wlv->char_attr = hl_combine_attr(wlv->wcr_attr, HL_ATTR(HLF_SC));
206 wlv->n_extra = 2; 209 wlv->n_extra = 2;
207 } 210 }
208 211
209 if (wlv->row == wlv->startrow 212 if (wlv->row == wlv->startrow
210 #ifdef FEAT_DIFF 213 #ifdef FEAT_DIFF
211 + filler_lines && filler_todo <= 0 214 + wlv->filler_lines && wlv->filler_todo <= 0
212 #endif 215 #endif
213 ) 216 )
214 { 217 {
215 text_sign = (sattr->sat_text != NULL) ? sattr->sat_typenr : 0; 218 text_sign = (wlv->sattr.sat_text != NULL) ? wlv->sattr.sat_typenr : 0;
216 # ifdef FEAT_SIGN_ICONS 219 # ifdef FEAT_SIGN_ICONS
217 icon_sign = (sattr->sat_icon != NULL) ? sattr->sat_typenr : 0; 220 icon_sign = (wlv->sattr.sat_icon != NULL) ? wlv->sattr.sat_typenr : 0;
218 if (gui.in_use && icon_sign != 0) 221 if (gui.in_use && icon_sign != 0)
219 { 222 {
220 // Use the image in this position. 223 // Use the image in this position.
221 if (nrcol) 224 if (nrcol)
222 { 225 {
223 wlv->c_extra = NUL; 226 wlv->c_extra = NUL;
224 sprintf((char *)extra, "%-*c ", number_width(wp), SIGN_BYTE); 227 sprintf((char *)wlv->extra, "%-*c ",
225 wlv->p_extra = extra; 228 number_width(wp), SIGN_BYTE);
229 wlv->p_extra = wlv->extra;
226 wlv->n_extra = (int)STRLEN(wlv->p_extra); 230 wlv->n_extra = (int)STRLEN(wlv->p_extra);
227 } 231 }
228 else 232 else
229 wlv->c_extra = SIGN_BYTE; 233 wlv->c_extra = SIGN_BYTE;
230 # ifdef FEAT_NETBEANS_INTG 234 # ifdef FEAT_NETBEANS_INTG
231 if (netbeans_active() && (buf_signcount(wp->w_buffer, lnum) > 1)) 235 if (netbeans_active() && (buf_signcount(wp->w_buffer, wlv->lnum)
236 > 1))
232 { 237 {
233 if (nrcol) 238 if (nrcol)
234 { 239 {
235 wlv->c_extra = NUL; 240 wlv->c_extra = NUL;
236 sprintf((char *)extra, "%-*c ", number_width(wp), 241 sprintf((char *)wlv->extra, "%-*c ", number_width(wp),
237 MULTISIGN_BYTE); 242 MULTISIGN_BYTE);
238 wlv->p_extra = extra; 243 wlv->p_extra = wlv->extra;
239 wlv->n_extra = (int)STRLEN(wlv->p_extra); 244 wlv->n_extra = (int)STRLEN(wlv->p_extra);
240 } 245 }
241 else 246 else
242 wlv->c_extra = MULTISIGN_BYTE; 247 wlv->c_extra = MULTISIGN_BYTE;
243 } 248 }
247 } 252 }
248 else 253 else
249 # endif 254 # endif
250 if (text_sign != 0) 255 if (text_sign != 0)
251 { 256 {
252 wlv->p_extra = sattr->sat_text; 257 wlv->p_extra = wlv->sattr.sat_text;
253 if (wlv->p_extra != NULL) 258 if (wlv->p_extra != NULL)
254 { 259 {
255 if (nrcol) 260 if (nrcol)
256 { 261 {
257 int n, width = number_width(wp) - 2; 262 int n, width = number_width(wp) - 2;
258 263
259 for (n = 0; n < width; n++) 264 for (n = 0; n < width; n++)
260 extra[n] = ' '; 265 wlv->extra[n] = ' ';
261 extra[n] = 0; 266 wlv->extra[n] = 0;
262 STRCAT(extra, wlv->p_extra); 267 STRCAT(wlv->extra, wlv->p_extra);
263 STRCAT(extra, " "); 268 STRCAT(wlv->extra, " ");
264 wlv->p_extra = extra; 269 wlv->p_extra = wlv->extra;
265 } 270 }
266 wlv->c_extra = NUL; 271 wlv->c_extra = NUL;
267 wlv->c_final = NUL; 272 wlv->c_final = NUL;
268 wlv->n_extra = (int)STRLEN(wlv->p_extra); 273 wlv->n_extra = (int)STRLEN(wlv->p_extra);
269 } 274 }
270 275
271 if (use_cursor_line_sign(wp, lnum) && sattr->sat_culhl > 0) 276 if (use_cursor_line_sign(wp, wlv->lnum)
272 wlv->char_attr = sattr->sat_culhl; 277 && wlv->sattr.sat_culhl > 0)
278 wlv->char_attr = wlv->sattr.sat_culhl;
273 else 279 else
274 wlv->char_attr = sattr->sat_texthl; 280 wlv->char_attr = wlv->sattr.sat_texthl;
275 } 281 }
276 } 282 }
277 } 283 }
278 #endif 284 #endif
279 285
286 /*
287 * Display the absolute or relative line number. After the first row fill with
288 * blanks when the 'n' flag isn't in 'cpo'.
289 */
290 static void
291 handle_lnum_col(
292 win_T *wp,
293 winlinevars_T *wlv,
294 int sign_present UNUSED,
295 int num_attr)
296 {
297 if ((wp->w_p_nu || wp->w_p_rnu)
298 && (wlv->row == wlv->startrow + wlv->filler_lines
299 || vim_strchr(p_cpo, CPO_NUMCOL) == NULL))
300 {
301 #ifdef FEAT_SIGNS
302 // If 'signcolumn' is set to 'number' and a sign is present
303 // in 'lnum', then display the sign instead of the line
304 // number.
305 if ((*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u') && sign_present)
306 get_sign_display_info(TRUE, wp, wlv);
307 else
308 #endif
309 {
310 // Draw the line number (empty space after wrapping).
311 if (wlv->row == wlv->startrow + wlv->filler_lines)
312 {
313 long num;
314 char *fmt = "%*ld ";
315
316 if (wp->w_p_nu && !wp->w_p_rnu)
317 // 'number' + 'norelativenumber'
318 num = (long)wlv->lnum;
319 else
320 {
321 // 'relativenumber', don't use negative numbers
322 num = labs((long)get_cursor_rel_lnum(wp, wlv->lnum));
323 if (num == 0 && wp->w_p_nu && wp->w_p_rnu)
324 {
325 // 'number' + 'relativenumber'
326 num = wlv->lnum;
327 fmt = "%-*ld ";
328 }
329 }
330
331 sprintf((char *)wlv->extra, fmt, number_width(wp), num);
332 if (wp->w_skipcol > 0)
333 for (wlv->p_extra = wlv->extra; *wlv->p_extra == ' ';
334 ++wlv->p_extra)
335 *wlv->p_extra = '-';
336 #ifdef FEAT_RIGHTLEFT
337 if (wp->w_p_rl) // reverse line numbers
338 {
339 char_u *p1, *p2;
340 int t;
341
342 // like rl_mirror(), but keep the space at the end
343 p2 = skipwhite(wlv->extra);
344 p2 = skiptowhite(p2) - 1;
345 for (p1 = skipwhite(wlv->extra); p1 < p2; ++p1, --p2)
346 {
347 t = *p1;
348 *p1 = *p2;
349 *p2 = t;
350 }
351 }
352 #endif
353 wlv->p_extra = wlv->extra;
354 wlv->c_extra = NUL;
355 wlv->c_final = NUL;
356 }
357 else
358 {
359 wlv->c_extra = ' ';
360 wlv->c_final = NUL;
361 }
362 wlv->n_extra = number_width(wp) + 1;
363 wlv->char_attr = hl_combine_attr(wlv->wcr_attr, HL_ATTR(HLF_N));
364 #ifdef FEAT_SYN_HL
365 // When 'cursorline' is set highlight the line number of
366 // the current line differently.
367 // When 'cursorlineopt' does not have "line" only
368 // highlight the line number itself.
369 // TODO: Can we use CursorLine instead of CursorLineNr
370 // when CursorLineNr isn't set?
371 if (wp->w_p_cul
372 && wlv->lnum == wp->w_cursor.lnum
373 && (wp->w_p_culopt_flags & CULOPT_NBR)
374 && (wlv->row == wlv->startrow + wlv->filler_lines
375 || (wlv->row > wlv->startrow + wlv->filler_lines
376 && (wp->w_p_culopt_flags & CULOPT_LINE))))
377 wlv->char_attr = hl_combine_attr(wlv->wcr_attr, HL_ATTR(HLF_CLN));
378 #endif
379 if (wp->w_p_rnu && wlv->lnum < wp->w_cursor.lnum
380 && HL_ATTR(HLF_LNA) != 0)
381 // Use LineNrAbove
382 wlv->char_attr = hl_combine_attr(wlv->wcr_attr, HL_ATTR(HLF_LNA));
383 if (wp->w_p_rnu && wlv->lnum > wp->w_cursor.lnum
384 && HL_ATTR(HLF_LNB) != 0)
385 // Use LineNrBelow
386 wlv->char_attr = hl_combine_attr(wlv->wcr_attr, HL_ATTR(HLF_LNB));
387 }
388 #ifdef FEAT_SIGNS
389 if (num_attr)
390 wlv->char_attr = num_attr;
391 #endif
392 }
393 }
280 #if defined(FEAT_PROP_POPUP) || defined(PROTO) 394 #if defined(FEAT_PROP_POPUP) || defined(PROTO)
281 /* 395 /*
282 * Return the cell size of virtual text after truncation. 396 * Return the cell size of virtual text after truncation.
283 */ 397 */
284 static int 398 static int
611 #endif 725 #endif
612 long vcol_prev = -1; // "wlv.vcol" of previous character 726 long vcol_prev = -1; // "wlv.vcol" of previous character
613 char_u *line; // current line 727 char_u *line; // current line
614 char_u *ptr; // current position in "line" 728 char_u *ptr; // current position in "line"
615 729
616 char_u extra[21]; // "%ld " and 'fdc' must fit in here
617 char_u *p_extra_free = NULL; // p_extra needs to be freed 730 char_u *p_extra_free = NULL; // p_extra needs to be freed
618 #ifdef FEAT_PROP_POPUP 731 #ifdef FEAT_PROP_POPUP
619 char_u *p_extra_free2 = NULL; // another p_extra to be freed 732 char_u *p_extra_free2 = NULL; // another p_extra to be freed
620 #endif 733 #endif
621 int extra_attr = 0; // attributes when n_extra != 0 734 int extra_attr = 0; // attributes when n_extra != 0
647 int attr_pri = FALSE; // char_attr has priority 760 int attr_pri = FALSE; // char_attr has priority
648 int area_highlighting = FALSE; // Visual or incsearch highlighting 761 int area_highlighting = FALSE; // Visual or incsearch highlighting
649 // in this line 762 // in this line
650 int vi_attr = 0; // attributes for Visual and incsearch 763 int vi_attr = 0; // attributes for Visual and incsearch
651 // highlighting 764 // highlighting
652 int wcr_attr = 0; // attributes from 'wincolor'
653 int area_attr = 0; // attributes desired by highlighting 765 int area_attr = 0; // attributes desired by highlighting
654 int search_attr = 0; // attributes desired by 'hlsearch' 766 int search_attr = 0; // attributes desired by 'hlsearch'
655 #ifdef FEAT_SYN_HL 767 #ifdef FEAT_SYN_HL
656 int vcol_save_attr = 0; // saved attr for 'cursorcolumn' 768 int vcol_save_attr = 0; // saved attr for 'cursorcolumn'
657 int syntax_attr = 0; // attributes desired by syntax 769 int syntax_attr = 0; // attributes desired by syntax
700 int multi_attr = 0; // attributes desired by multibyte 812 int multi_attr = 0; // attributes desired by multibyte
701 int mb_l = 1; // multi-byte byte length 813 int mb_l = 1; // multi-byte byte length
702 int mb_c = 0; // decoded multi-byte character 814 int mb_c = 0; // decoded multi-byte character
703 int mb_utf8 = FALSE; // screen char is UTF-8 char 815 int mb_utf8 = FALSE; // screen char is UTF-8 char
704 int u8cc[MAX_MCO]; // composing UTF-8 chars 816 int u8cc[MAX_MCO]; // composing UTF-8 chars
705 #if defined(FEAT_DIFF) || defined(FEAT_SIGNS)
706 int filler_lines = 0; // nr of filler lines to be drawn
707 int filler_todo = 0; // nr of filler lines still to do + 1
708 #else
709 # define filler_lines 0
710 #endif
711 #ifdef FEAT_DIFF 817 #ifdef FEAT_DIFF
712 int change_start = MAXCOL; // first col of changed area 818 int change_start = MAXCOL; // first col of changed area
713 int change_end = -1; // last col of changed area 819 int change_end = -1; // last col of changed area
714 #endif 820 #endif
715 colnr_T trailcol = MAXCOL; // start of trailing spaces 821 colnr_T trailcol = MAXCOL; // start of trailing spaces
727 int line_attr = 0; // attribute for the whole line 833 int line_attr = 0; // attribute for the whole line
728 int line_attr_save = 0; 834 int line_attr_save = 0;
729 #endif 835 #endif
730 #ifdef FEAT_SIGNS 836 #ifdef FEAT_SIGNS
731 int sign_present = FALSE; 837 int sign_present = FALSE;
732 sign_attrs_T sattr;
733 int num_attr = 0; // attribute for the number column 838 int num_attr = 0; // attribute for the number column
734 #endif 839 #endif
735 #ifdef FEAT_ARABIC 840 #ifdef FEAT_ARABIC
736 int prev_c = 0; // previous Arabic character 841 int prev_c = 0; // previous Arabic character
737 int prev_c1 = 0; // first composing char for prev_c 842 int prev_c1 = 0; // first composing char for prev_c
994 vi_attr = HL_ATTR(HLF_I); 1099 vi_attr = HL_ATTR(HLF_I);
995 } 1100 }
996 } 1101 }
997 1102
998 #ifdef FEAT_DIFF 1103 #ifdef FEAT_DIFF
999 filler_lines = diff_check(wp, lnum); 1104 wlv.filler_lines = diff_check(wp, lnum);
1000 if (filler_lines < 0) 1105 if (wlv.filler_lines < 0)
1001 { 1106 {
1002 if (filler_lines == -1) 1107 if (wlv.filler_lines == -1)
1003 { 1108 {
1004 if (diff_find_change(wp, lnum, &change_start, &change_end)) 1109 if (diff_find_change(wp, lnum, &change_start, &change_end))
1005 wlv.diff_hlf = HLF_ADD; // added line 1110 wlv.diff_hlf = HLF_ADD; // added line
1006 else if (change_start == 0) 1111 else if (change_start == 0)
1007 wlv.diff_hlf = HLF_TXD; // changed text 1112 wlv.diff_hlf = HLF_TXD; // changed text
1008 else 1113 else
1009 wlv.diff_hlf = HLF_CHD; // changed line 1114 wlv.diff_hlf = HLF_CHD; // changed line
1010 } 1115 }
1011 else 1116 else
1012 wlv.diff_hlf = HLF_ADD; // added line 1117 wlv.diff_hlf = HLF_ADD; // added line
1013 filler_lines = 0; 1118 wlv.filler_lines = 0;
1014 area_highlighting = TRUE; 1119 area_highlighting = TRUE;
1015 } 1120 }
1016 if (lnum == wp->w_topline) 1121 if (lnum == wp->w_topline)
1017 filler_lines = wp->w_topfill; 1122 wlv.filler_lines = wp->w_topfill;
1018 filler_todo = filler_lines; 1123 wlv.filler_todo = wlv.filler_lines;
1019 #endif 1124 #endif
1020 1125
1021 #ifdef FEAT_SIGNS 1126 #ifdef FEAT_SIGNS
1022 sign_present = buf_get_signattrs(wp, lnum, &sattr); 1127 sign_present = buf_get_signattrs(wp, lnum, &wlv.sattr);
1023 if (sign_present) 1128 if (sign_present)
1024 num_attr = sattr.sat_numhl; 1129 num_attr = wlv.sattr.sat_numhl;
1025 #endif 1130 #endif
1026 1131
1027 #ifdef LINE_ATTR 1132 #ifdef LINE_ATTR
1028 # ifdef FEAT_SIGNS 1133 # ifdef FEAT_SIGNS
1029 // If this line has a sign with line highlighting set line_attr. 1134 // If this line has a sign with line highlighting set line_attr.
1030 if (sign_present) 1135 if (sign_present)
1031 line_attr = sattr.sat_linehl; 1136 line_attr = wlv.sattr.sat_linehl;
1032 # endif 1137 # endif
1033 # if defined(FEAT_QUICKFIX) 1138 # if defined(FEAT_QUICKFIX)
1034 // Highlight the current line in the quickfix window. 1139 // Highlight the current line in the quickfix window.
1035 if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) 1140 if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum)
1036 line_attr = HL_ATTR(HLF_QFL); 1141 line_attr = HL_ATTR(HLF_QFL);
1112 // keep track of the first column not filled with spaces 1217 // keep track of the first column not filled with spaces
1113 leadcol += (colnr_T)(ptr - line) + 1; 1218 leadcol += (colnr_T)(ptr - line) + 1;
1114 } 1219 }
1115 } 1220 }
1116 1221
1117 wcr_attr = get_wcr_attr(wp); 1222 wlv.wcr_attr = get_wcr_attr(wp);
1118 if (wcr_attr != 0) 1223 if (wlv.wcr_attr != 0)
1119 { 1224 {
1120 wlv.win_attr = wcr_attr; 1225 wlv.win_attr = wlv.wcr_attr;
1121 area_highlighting = TRUE; 1226 area_highlighting = TRUE;
1122 } 1227 }
1123 1228
1124 #ifdef FEAT_PROP_POPUP 1229 #ifdef FEAT_PROP_POPUP
1125 if (WIN_IS_POPUP(wp)) 1230 if (WIN_IS_POPUP(wp))
1284 { 1389 {
1285 cul_attr = HL_ATTR(HLF_CUL); 1390 cul_attr = HL_ATTR(HLF_CUL);
1286 # ifdef FEAT_SIGNS 1391 # ifdef FEAT_SIGNS
1287 // Combine the 'cursorline' and sign highlighting, depending on 1392 // Combine the 'cursorline' and sign highlighting, depending on
1288 // the sign priority. 1393 // the sign priority.
1289 if (sign_present && sattr.sat_linehl > 0) 1394 if (sign_present && wlv.sattr.sat_linehl > 0)
1290 { 1395 {
1291 if (sattr.sat_priority >= 100) 1396 if (wlv.sattr.sat_priority >= 100)
1292 line_attr = hl_combine_attr(cul_attr, line_attr); 1397 line_attr = hl_combine_attr(cul_attr, line_attr);
1293 else 1398 else
1294 line_attr = hl_combine_attr(line_attr, cul_attr); 1399 line_attr = hl_combine_attr(line_attr, cul_attr);
1295 } 1400 }
1296 else 1401 else
1372 { 1477 {
1373 // Draw the cmdline character. 1478 // Draw the cmdline character.
1374 wlv.n_extra = 1; 1479 wlv.n_extra = 1;
1375 wlv.c_extra = cmdwin_type; 1480 wlv.c_extra = cmdwin_type;
1376 wlv.c_final = NUL; 1481 wlv.c_final = NUL;
1377 wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_AT)); 1482 wlv.char_attr =
1483 hl_combine_attr(wlv.wcr_attr, HL_ATTR(HLF_AT));
1378 } 1484 }
1379 } 1485 }
1380 #endif 1486 #endif
1381 1487
1382 #ifdef FEAT_FOLDING 1488 #ifdef FEAT_FOLDING
1385 int fdc = compute_foldcolumn(wp, 0); 1491 int fdc = compute_foldcolumn(wp, 0);
1386 1492
1387 wlv.draw_state = WL_FOLD; 1493 wlv.draw_state = WL_FOLD;
1388 if (fdc > 0) 1494 if (fdc > 0)
1389 { 1495 {
1390 // Draw the 'foldcolumn'. Allocate a buffer, "extra" may 1496 // Draw the 'foldcolumn'. Allocate a buffer, "wlv.extra"
1391 // already be in use. 1497 // may already be in use.
1392 vim_free(p_extra_free); 1498 vim_free(p_extra_free);
1393 p_extra_free = alloc(MAX_MCO * fdc + 1); 1499 p_extra_free = alloc(MAX_MCO * fdc + 1);
1394 if (p_extra_free != NULL) 1500 if (p_extra_free != NULL)
1395 { 1501 {
1396 wlv.n_extra = (int)fill_foldcolumn(p_extra_free, wp, 1502 wlv.n_extra = (int)fill_foldcolumn(p_extra_free, wp,
1399 wlv.p_extra = p_extra_free; 1505 wlv.p_extra = p_extra_free;
1400 wlv.c_extra = NUL; 1506 wlv.c_extra = NUL;
1401 wlv.c_final = NUL; 1507 wlv.c_final = NUL;
1402 if (use_cursor_line_sign(wp, lnum)) 1508 if (use_cursor_line_sign(wp, lnum))
1403 wlv.char_attr = 1509 wlv.char_attr =
1404 hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLF)); 1510 hl_combine_attr(wlv.wcr_attr, HL_ATTR(HLF_CLF));
1405 else 1511 else
1406 wlv.char_attr = 1512 wlv.char_attr =
1407 hl_combine_attr(wcr_attr, HL_ATTR(HLF_FC)); 1513 hl_combine_attr(wlv.wcr_attr, HL_ATTR(HLF_FC));
1408 } 1514 }
1409 } 1515 }
1410 } 1516 }
1411 #endif 1517 #endif
1412 1518
1413 #ifdef FEAT_SIGNS 1519 #ifdef FEAT_SIGNS
1414 if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0) 1520 if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0)
1415 { 1521 {
1522 // Show the sign column when desired or when using Netbeans.
1416 wlv.draw_state = WL_SIGN; 1523 wlv.draw_state = WL_SIGN;
1417 // Show the sign column when there are any signs in this
1418 // buffer or when using Netbeans.
1419 if (signcolumn_on(wp)) 1524 if (signcolumn_on(wp))
1420 get_sign_display_info(FALSE, wp, lnum, &wlv, &sattr, 1525 get_sign_display_info(FALSE, wp, &wlv);
1421 wcr_attr, filler_lines, filler_todo, extra);
1422 } 1526 }
1423 #endif 1527 #endif
1424 1528
1425 if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0) 1529 if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0)
1426 { 1530 {
1531 // Show the line number, if desired.
1427 wlv.draw_state = WL_NR; 1532 wlv.draw_state = WL_NR;
1428 // Display the absolute or relative line number. After the 1533 handle_lnum_col(wp, &wlv, sign_present, num_attr);
1429 // first fill with blanks when the 'n' flag isn't in 'cpo'
1430 if ((wp->w_p_nu || wp->w_p_rnu)
1431 && (wlv.row == startrow + filler_lines
1432 || vim_strchr(p_cpo, CPO_NUMCOL) == NULL))
1433 {
1434 #ifdef FEAT_SIGNS
1435 // If 'signcolumn' is set to 'number' and a sign is present
1436 // in 'lnum', then display the sign instead of the line
1437 // number.
1438 if ((*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')
1439 && sign_present)
1440 get_sign_display_info(TRUE, wp, lnum, &wlv, &sattr,
1441 wcr_attr, filler_lines, filler_todo, extra);
1442 else
1443 #endif
1444 {
1445 // Draw the line number (empty space after wrapping).
1446 if (wlv.row == startrow + filler_lines)
1447 {
1448 long num;
1449 char *fmt = "%*ld ";
1450
1451 if (wp->w_p_nu && !wp->w_p_rnu)
1452 // 'number' + 'norelativenumber'
1453 num = (long)lnum;
1454 else
1455 {
1456 // 'relativenumber', don't use negative numbers
1457 num = labs((long)get_cursor_rel_lnum(wp, lnum));
1458 if (num == 0 && wp->w_p_nu && wp->w_p_rnu)
1459 {
1460 // 'number' + 'relativenumber'
1461 num = lnum;
1462 fmt = "%-*ld ";
1463 }
1464 }
1465
1466 sprintf((char *)extra, fmt,
1467 number_width(wp), num);
1468 if (wp->w_skipcol > 0)
1469 for (wlv.p_extra = extra; *wlv.p_extra == ' ';
1470 ++wlv.p_extra)
1471 *wlv.p_extra = '-';
1472 #ifdef FEAT_RIGHTLEFT
1473 if (wp->w_p_rl) // reverse line numbers
1474 {
1475 char_u *p1, *p2;
1476 int t;
1477
1478 // like rl_mirror(), but keep the space at the end
1479 p2 = skipwhite(extra);
1480 p2 = skiptowhite(p2) - 1;
1481 for (p1 = skipwhite(extra); p1 < p2; ++p1, --p2)
1482 {
1483 t = *p1;
1484 *p1 = *p2;
1485 *p2 = t;
1486 }
1487 }
1488 #endif
1489 wlv.p_extra = extra;
1490 wlv.c_extra = NUL;
1491 wlv.c_final = NUL;
1492 }
1493 else
1494 {
1495 wlv.c_extra = ' ';
1496 wlv.c_final = NUL;
1497 }
1498 wlv.n_extra = number_width(wp) + 1;
1499 wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_N));
1500 #ifdef FEAT_SYN_HL
1501 // When 'cursorline' is set highlight the line number of
1502 // the current line differently.
1503 // When 'cursorlineopt' does not have "line" only
1504 // highlight the line number itself.
1505 // TODO: Can we use CursorLine instead of CursorLineNr
1506 // when CursorLineNr isn't set?
1507 if (wp->w_p_cul
1508 && lnum == wp->w_cursor.lnum
1509 && (wp->w_p_culopt_flags & CULOPT_NBR)
1510 && (wlv.row == startrow + filler_lines
1511 || (wlv.row > startrow + filler_lines
1512 && (wp->w_p_culopt_flags & CULOPT_LINE))))
1513 wlv.char_attr = hl_combine_attr(wcr_attr,
1514 HL_ATTR(HLF_CLN));
1515 #endif
1516 if (wp->w_p_rnu && lnum < wp->w_cursor.lnum
1517 && HL_ATTR(HLF_LNA) != 0)
1518 // Use LineNrAbove
1519 wlv.char_attr = hl_combine_attr(wcr_attr,
1520 HL_ATTR(HLF_LNA));
1521 if (wp->w_p_rnu && lnum > wp->w_cursor.lnum
1522 && HL_ATTR(HLF_LNB) != 0)
1523 // Use LineNrBelow
1524 wlv.char_attr = hl_combine_attr(wcr_attr,
1525 HL_ATTR(HLF_LNB));
1526 }
1527 #ifdef FEAT_SIGNS
1528 if (num_attr)
1529 wlv.char_attr = num_attr;
1530 #endif
1531 }
1532 } 1534 }
1533 1535
1534 #ifdef FEAT_LINEBREAK 1536 #ifdef FEAT_LINEBREAK
1535 if (wp->w_briopt_sbr && wlv.draw_state == WL_BRI - 1 1537 if (wp->w_briopt_sbr && wlv.draw_state == WL_BRI - 1
1536 && wlv.n_extra == 0 1538 && wlv.n_extra == 0
1547 { 1549 {
1548 wlv.draw_state = WL_BRI; 1550 wlv.draw_state = WL_BRI;
1549 // if need_showbreak is set, breakindent also applies 1551 // if need_showbreak is set, breakindent also applies
1550 if (wp->w_p_bri && (wlv.row != startrow || need_showbreak) 1552 if (wp->w_p_bri && (wlv.row != startrow || need_showbreak)
1551 # ifdef FEAT_DIFF 1553 # ifdef FEAT_DIFF
1552 && filler_lines == 0 1554 && wlv.filler_lines == 0
1553 # endif 1555 # endif
1554 # ifdef FEAT_PROP_POPUP 1556 # ifdef FEAT_PROP_POPUP
1555 && !dont_use_showbreak 1557 && !dont_use_showbreak
1556 # endif 1558 # endif
1557 ) 1559 )
1587 { 1589 {
1588 char_u *sbr; 1590 char_u *sbr;
1589 1591
1590 wlv.draw_state = WL_SBR; 1592 wlv.draw_state = WL_SBR;
1591 # ifdef FEAT_DIFF 1593 # ifdef FEAT_DIFF
1592 if (filler_todo > 0) 1594 if (wlv.filler_todo > 0)
1593 { 1595 {
1594 // Draw "deleted" diff line(s). 1596 // Draw "deleted" diff line(s).
1595 if (char2cells(wp->w_fill_chars.diff) > 1) 1597 if (char2cells(wp->w_fill_chars.diff) > 1)
1596 { 1598 {
1597 wlv.c_extra = '-'; 1599 wlv.c_extra = '-';
1672 // stop here. 1674 // stop here.
1673 if (((dollar_vcol >= 0 && wp == curwin 1675 if (((dollar_vcol >= 0 && wp == curwin
1674 && lnum == wp->w_cursor.lnum && wlv.vcol >= (long)wp->w_virtcol) 1676 && lnum == wp->w_cursor.lnum && wlv.vcol >= (long)wp->w_virtcol)
1675 || (number_only && wlv.draw_state > WL_NR)) 1677 || (number_only && wlv.draw_state > WL_NR))
1676 #ifdef FEAT_DIFF 1678 #ifdef FEAT_DIFF
1677 && filler_todo <= 0 1679 && wlv.filler_todo <= 0
1678 #endif 1680 #endif
1679 ) 1681 )
1680 { 1682 {
1681 screen_line(wp, wlv.screen_row, wp->w_wincol, wlv.col, -wp->w_width, 1683 screen_line(wp, wlv.screen_row, wp->w_wincol, wlv.col, -wp->w_width,
1682 wlv.screen_line_flags); 1684 wlv.screen_line_flags);
2277 || (mb_l >= 1 && mb_c == 0) 2279 || (mb_l >= 1 && mb_c == 0)
2278 || (mb_l > 1 && (!vim_isprintc(mb_c)))) 2280 || (mb_l > 1 && (!vim_isprintc(mb_c))))
2279 { 2281 {
2280 // Illegal UTF-8 byte: display as <xx>. 2282 // Illegal UTF-8 byte: display as <xx>.
2281 // Non-BMP character : display as ? or fullwidth ?. 2283 // Non-BMP character : display as ? or fullwidth ?.
2282 transchar_hex(extra, mb_c); 2284 transchar_hex(wlv.extra, mb_c);
2283 # ifdef FEAT_RIGHTLEFT 2285 # ifdef FEAT_RIGHTLEFT
2284 if (wp->w_p_rl) // reverse 2286 if (wp->w_p_rl) // reverse
2285 rl_mirror(extra); 2287 rl_mirror(wlv.extra);
2286 # endif 2288 # endif
2287 wlv.p_extra = extra; 2289 wlv.p_extra = wlv.extra;
2288 c = *wlv.p_extra; 2290 c = *wlv.p_extra;
2289 mb_c = mb_ptr2char_adv(&wlv.p_extra); 2291 mb_c = mb_ptr2char_adv(&wlv.p_extra);
2290 mb_utf8 = (c >= 0x80); 2292 mb_utf8 = (c >= 0x80);
2291 wlv.n_extra = (int)STRLEN(wlv.p_extra); 2293 wlv.n_extra = (int)STRLEN(wlv.p_extra);
2292 wlv.c_extra = NUL; 2294 wlv.c_extra = NUL;
2346 { 2348 {
2347 if (ptr[1] == NUL) 2349 if (ptr[1] == NUL)
2348 { 2350 {
2349 // head byte at end of line 2351 // head byte at end of line
2350 mb_l = 1; 2352 mb_l = 1;
2351 transchar_nonprint(wp->w_buffer, extra, c); 2353 transchar_nonprint(wp->w_buffer, wlv.extra, c);
2352 } 2354 }
2353 else 2355 else
2354 { 2356 {
2355 // illegal tail byte 2357 // illegal tail byte
2356 mb_l = 2; 2358 mb_l = 2;
2357 STRCPY(extra, "XX"); 2359 STRCPY(wlv.extra, "XX");
2358 } 2360 }
2359 wlv.p_extra = extra; 2361 wlv.p_extra = wlv.extra;
2360 wlv.n_extra = (int)STRLEN(extra) - 1; 2362 wlv.n_extra = (int)STRLEN(wlv.extra) - 1;
2361 wlv.c_extra = NUL; 2363 wlv.c_extra = NUL;
2362 wlv.c_final = NUL; 2364 wlv.c_final = NUL;
2363 c = *wlv.p_extra++; 2365 c = *wlv.p_extra++;
2364 if (area_attr == 0 && search_attr == 0) 2366 if (area_attr == 0 && search_attr == 0)
2365 { 2367 {
3165 && wp->w_p_list 3167 && wp->w_p_list
3166 && (wp->w_p_wrap ? 3168 && (wp->w_p_wrap ?
3167 (wp->w_skipcol > 0 && wlv.row == 0) : 3169 (wp->w_skipcol > 0 && wlv.row == 0) :
3168 wp->w_leftcol > 0) 3170 wp->w_leftcol > 0)
3169 #ifdef FEAT_DIFF 3171 #ifdef FEAT_DIFF
3170 && filler_todo <= 0 3172 && wlv.filler_todo <= 0
3171 #endif 3173 #endif
3172 && wlv.draw_state > WL_NR 3174 && wlv.draw_state > WL_NR
3173 && c != NUL) 3175 && c != NUL)
3174 { 3176 {
3175 c = wp->w_lcs_chars.prec; 3177 c = wp->w_lcs_chars.prec;
3321 if (wp->w_lcs_chars.ext != NUL 3323 if (wp->w_lcs_chars.ext != NUL
3322 && wlv.draw_state == WL_LINE 3324 && wlv.draw_state == WL_LINE
3323 && wp->w_p_list 3325 && wp->w_p_list
3324 && !wp->w_p_wrap 3326 && !wp->w_p_wrap
3325 #ifdef FEAT_DIFF 3327 #ifdef FEAT_DIFF
3326 && filler_todo <= 0 3328 && wlv.filler_todo <= 0
3327 #endif 3329 #endif
3328 && ( 3330 && (
3329 #ifdef FEAT_RIGHTLEFT 3331 #ifdef FEAT_RIGHTLEFT
3330 wp->w_p_rl ? wlv.col == 0 : 3332 wp->w_p_rl ? wlv.col == 0 :
3331 #endif 3333 #endif
3365 || wlv.draw_state == WL_SBR) 3367 || wlv.draw_state == WL_SBR)
3366 && !lnum_in_visual_area 3368 && !lnum_in_visual_area
3367 && search_attr == 0 3369 && search_attr == 0
3368 && area_attr == 0) 3370 && area_attr == 0)
3369 # ifdef FEAT_DIFF 3371 # ifdef FEAT_DIFF
3370 && filler_todo <= 0 3372 && wlv.filler_todo <= 0
3371 # endif 3373 # endif
3372 ) 3374 )
3373 { 3375 {
3374 if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol 3376 if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol
3375 && lnum != wp->w_cursor.lnum) 3377 && lnum != wp->w_cursor.lnum)
3447 else 3449 else
3448 // DBCS: Put second byte in the second screen char. 3450 // DBCS: Put second byte in the second screen char.
3449 ScreenLines[wlv.off] = mb_c & 0xff; 3451 ScreenLines[wlv.off] = mb_c & 0xff;
3450 if (wlv.draw_state > WL_NR 3452 if (wlv.draw_state > WL_NR
3451 #ifdef FEAT_DIFF 3453 #ifdef FEAT_DIFF
3452 && filler_todo <= 0 3454 && wlv.filler_todo <= 0
3453 #endif 3455 #endif
3454 ) 3456 )
3455 ++wlv.vcol; 3457 ++wlv.vcol;
3456 // When "tocol" is halfway a character, set it to the end of 3458 // When "tocol" is halfway a character, set it to the end of
3457 // the character, otherwise highlighting won't stop. 3459 // the character, otherwise highlighting won't stop.
3569 3571
3570 // Only advance the "wlv.vcol" when after the 'number' or 3572 // Only advance the "wlv.vcol" when after the 'number' or
3571 // 'relativenumber' column. 3573 // 'relativenumber' column.
3572 if (wlv.draw_state > WL_NR 3574 if (wlv.draw_state > WL_NR
3573 #ifdef FEAT_DIFF 3575 #ifdef FEAT_DIFF
3574 && filler_todo <= 0 3576 && wlv.filler_todo <= 0
3575 #endif 3577 #endif
3576 ) 3578 )
3577 ++wlv.vcol; 3579 ++wlv.vcol;
3578 3580
3579 #ifdef FEAT_SYN_HL 3581 #ifdef FEAT_SYN_HL
3600 #endif 3602 #endif
3601 (wlv.col >= wp->w_width)) 3603 (wlv.col >= wp->w_width))
3602 && (wlv.draw_state != WL_LINE 3604 && (wlv.draw_state != WL_LINE
3603 || *ptr != NUL 3605 || *ptr != NUL
3604 #ifdef FEAT_DIFF 3606 #ifdef FEAT_DIFF
3605 || filler_todo > 0 3607 || wlv.filler_todo > 0
3606 #endif 3608 #endif
3607 #ifdef FEAT_PROP_POPUP 3609 #ifdef FEAT_PROP_POPUP
3608 || text_prop_above || text_prop_follows 3610 || text_prop_above || text_prop_follows
3609 #endif 3611 #endif
3610 || (wp->w_p_list && wp->w_lcs_chars.eol != NUL 3612 || (wp->w_p_list && wp->w_lcs_chars.eol != NUL
3627 3629
3628 // When not wrapping and finished diff lines, or when displayed 3630 // When not wrapping and finished diff lines, or when displayed
3629 // '$' and highlighting until last column, break here. 3631 // '$' and highlighting until last column, break here.
3630 if ((!wp->w_p_wrap 3632 if ((!wp->w_p_wrap
3631 #ifdef FEAT_DIFF 3633 #ifdef FEAT_DIFF
3632 && filler_todo <= 0 3634 && wlv.filler_todo <= 0
3633 #endif 3635 #endif
3634 #ifdef FEAT_PROP_POPUP 3636 #ifdef FEAT_PROP_POPUP
3635 && !text_prop_above && !text_prop_follows 3637 && !text_prop_above && !text_prop_follows
3636 #endif 3638 #endif
3637 ) || lcs_eol_one == -1) 3639 ) || lcs_eol_one == -1)
3648 #endif 3650 #endif
3649 3651
3650 // When the window is too narrow draw all "@" lines. 3652 // When the window is too narrow draw all "@" lines.
3651 if (wlv.draw_state != WL_LINE 3653 if (wlv.draw_state != WL_LINE
3652 #ifdef FEAT_DIFF 3654 #ifdef FEAT_DIFF
3653 && filler_todo <= 0 3655 && wlv.filler_todo <= 0
3654 #endif 3656 #endif
3655 ) 3657 )
3656 { 3658 {
3657 win_draw_end(wp, '@', ' ', TRUE, wlv.row, wp->w_height, HLF_AT); 3659 win_draw_end(wp, '@', ' ', TRUE, wlv.row, wp->w_height, HLF_AT);
3658 draw_vsep_win(wp, wlv.row); 3660 draw_vsep_win(wp, wlv.row);
3666 break; 3668 break;
3667 } 3669 }
3668 3670
3669 if (screen_cur_row == wlv.screen_row - 1 3671 if (screen_cur_row == wlv.screen_row - 1
3670 #ifdef FEAT_DIFF 3672 #ifdef FEAT_DIFF
3671 && filler_todo <= 0 3673 && wlv.filler_todo <= 0
3672 #endif 3674 #endif
3673 #ifdef FEAT_PROP_POPUP 3675 #ifdef FEAT_PROP_POPUP
3674 && !text_prop_above && !text_prop_follows 3676 && !text_prop_above && !text_prop_follows
3675 #endif 3677 #endif
3676 && wp->w_width == Columns) 3678 && wp->w_width == Columns)
3729 3731
3730 lcs_prec_todo = wp->w_lcs_chars.prec; 3732 lcs_prec_todo = wp->w_lcs_chars.prec;
3731 #ifdef FEAT_LINEBREAK 3733 #ifdef FEAT_LINEBREAK
3732 if (!dont_use_showbreak 3734 if (!dont_use_showbreak
3733 # ifdef FEAT_DIFF 3735 # ifdef FEAT_DIFF
3734 && filler_todo <= 0 3736 && wlv.filler_todo <= 0
3735 # endif 3737 # endif
3736 ) 3738 )
3737 need_showbreak = TRUE; 3739 need_showbreak = TRUE;
3738 #endif 3740 #endif
3739 #ifdef FEAT_DIFF 3741 #ifdef FEAT_DIFF
3740 --filler_todo; 3742 --wlv.filler_todo;
3741 // When the filler lines are actually below the last line of the 3743 // When the filler lines are actually below the last line of the
3742 // file, don't draw the line itself, break here. 3744 // file, don't draw the line itself, break here.
3743 if (filler_todo == 0 && wp->w_botfill) 3745 if (wlv.filler_todo == 0 && wp->w_botfill)
3744 break; 3746 break;
3745 #endif 3747 #endif
3746 } 3748 }
3747 3749
3748 } // for every character in the line 3750 } // for every character in the line