mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(column): corrupted screen with minwid sign item in 'statuscolumn'
This commit is contained in:
		| @@ -1031,6 +1031,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n | |||||||
|   int evaldepth  = 0; |   int evaldepth  = 0; | ||||||
|  |  | ||||||
|   int curitem = 0; |   int curitem = 0; | ||||||
|  |   int foldsignitem = -1; | ||||||
|   bool prevchar_isflag = true; |   bool prevchar_isflag = true; | ||||||
|   bool prevchar_isitem = false; |   bool prevchar_isitem = false; | ||||||
|  |  | ||||||
| @@ -1655,6 +1656,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n | |||||||
|       if (width == 0) { |       if (width == 0) { | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|  |       foldsignitem = curitem; | ||||||
|  |  | ||||||
|       char *p = NULL; |       char *p = NULL; | ||||||
|       if (fold) { |       if (fold) { | ||||||
| @@ -1664,34 +1666,24 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n | |||||||
|         p[n] = NUL; |         p[n] = NUL; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       *buf_tmp = NUL; |       size_t buflen = 0; | ||||||
|       varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM); |       varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM); | ||||||
|       for (int i = 0; i <= width; i++) { |       for (int i = 0; i < width; i++) { | ||||||
|         if (i == width) { |         if (!fold) { | ||||||
|           if (*buf_tmp == NUL) { |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|           stl_items[curitem].minwid = 0; |  | ||||||
|         } else if (!fold) { |  | ||||||
|           SignTextAttrs *sattr = virtnum ? NULL : sign_get_attr(i, stcp->sattrs, wp->w_scwidth); |           SignTextAttrs *sattr = virtnum ? NULL : sign_get_attr(i, stcp->sattrs, wp->w_scwidth); | ||||||
|           p = sattr && sattr->text ? sattr->text : "  "; |           p = sattr && sattr->text ? sattr->text : "  "; | ||||||
|           stl_items[curitem].minwid = -(sattr ? stcp->sign_cul_id ? stcp->sign_cul_id |           stl_items[curitem].minwid = -(sattr ? stcp->sign_cul_id ? stcp->sign_cul_id | ||||||
|                                         : sattr->hl_id : (stcp->use_cul ? HLF_CLS : HLF_SC) + 1); |                                         : sattr->hl_id : (stcp->use_cul ? HLF_CLS : HLF_SC) + 1); | ||||||
|         } |         } | ||||||
|         size_t buflen = strlen(buf_tmp); |  | ||||||
|         stl_items[curitem].type = Highlight; |         stl_items[curitem].type = Highlight; | ||||||
|         stl_items[curitem].start = out_p + buflen; |         stl_items[curitem].start = out_p + buflen; | ||||||
|  |         xstrlcpy(buf_tmp + buflen, p, TMPLEN - buflen); | ||||||
|  |         buflen += strlen(p); | ||||||
|         curitem++; |         curitem++; | ||||||
|         if (i == width) { |       } | ||||||
|       str = buf_tmp; |       str = buf_tmp; | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|         int rc = snprintf(buf_tmp + buflen, sizeof(buf_tmp) - buflen, "%s", p); |  | ||||||
|         (void)rc;  // Avoid unused warning on release build |  | ||||||
|         assert(rc > 0); |  | ||||||
|       } |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     case STL_FILETYPE: |     case STL_FILETYPE: | ||||||
|       // Copy the filetype if it is not null and the formatted string will fit |       // Copy the filetype if it is not null and the formatted string will fit | ||||||
| @@ -1832,6 +1824,13 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n | |||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         minwid = 0; |         minwid = 0; | ||||||
|  |         // For a 'statuscolumn' sign or fold item, shift the added items | ||||||
|  |         if (foldsignitem >= 0) { | ||||||
|  |           ptrdiff_t offset = out_p - stl_items[foldsignitem].start; | ||||||
|  |           for (int i = foldsignitem; i < curitem; i++) { | ||||||
|  |             stl_items[i].start += offset; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|       } else { |       } else { | ||||||
|         // Note: The negative value denotes a left aligned item. |         // Note: The negative value denotes a left aligned item. | ||||||
|         //       Here we switch the minimum width back to a positive value. |         //       Here we switch the minimum width back to a positive value. | ||||||
| @@ -1851,6 +1850,14 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n | |||||||
|       } |       } | ||||||
|       // } |       // } | ||||||
|  |  | ||||||
|  |       // For a 'statuscolumn' sign or fold item, add an item to reset the highlight group | ||||||
|  |       if (foldsignitem >= 0) { | ||||||
|  |         foldsignitem = -1; | ||||||
|  |         stl_items[curitem].type = Highlight; | ||||||
|  |         stl_items[curitem].start = out_p; | ||||||
|  |         stl_items[curitem].minwid = 0; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       // For left-aligned items, fill any remaining space with the fillchar |       // For left-aligned items, fill any remaining space with the fillchar | ||||||
|       for (; l < minwid && out_p < out_end_p; l++) { |       for (; l < minwid && out_p < out_end_p; l++) { | ||||||
|         MB_CHAR2BYTES(fillchar, out_p); |         MB_CHAR2BYTES(fillchar, out_p); | ||||||
|   | |||||||
| @@ -424,6 +424,21 @@ describe('statuscolumn', function() | |||||||
|     ]]) |     ]]) | ||||||
|   end) |   end) | ||||||
|  |  | ||||||
|  |   it('does not corrupt the screen with minwid sign item', function() | ||||||
|  |     screen:try_resize(screen._width, 3) | ||||||
|  |     screen:set_default_attr_ids({ | ||||||
|  |       [0] = {foreground = Screen.colors.Brown}, | ||||||
|  |       [1] = {foreground = Screen.colors.Blue4, background = Screen.colors.Gray}, | ||||||
|  |     }) | ||||||
|  |     command([[set stc=%6s\ %l]]) | ||||||
|  |     exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 7, 0, {sign_text = "𒀀"})') | ||||||
|  |     screen:expect([[ | ||||||
|  |       {0:    𒀀  8}^aaaaa                                        | | ||||||
|  |       {0:    }{1:  }{0: 9}aaaaa                                        | | ||||||
|  |                                                            | | ||||||
|  |     ]]) | ||||||
|  |   end) | ||||||
|  |  | ||||||
|   for _, model in ipairs(mousemodels) do |   for _, model in ipairs(mousemodels) do | ||||||
|     it("works with 'statuscolumn' clicks with mousemodel=" .. model, function() |     it("works with 'statuscolumn' clicks with mousemodel=" .. model, function() | ||||||
|       command('set mousemodel=' .. model) |       command('set mousemodel=' .. model) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Luuk van Baal
					Luuk van Baal