mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	options: allow different highlights in windows
This commit is contained in:
		| @@ -3128,7 +3128,8 @@ A jump table for the options with a short description can be found at |Q_op|. | ||||
| 	use for that occasion.  The occasions are: | ||||
| 	|hl-SpecialKey|	 8  Meta and special keys listed with ":map" | ||||
| 	|hl-Whitespace|	 0 | ||||
| 	|hl-EndOfBuffer|   ~ lines after the last line in the buffer | ||||
| 	|hl-EndOfBuffer|   ~  lines after the last line in the buffer | ||||
| 	|hl-NormalNC|	 I  inactive (not the current) window | ||||
| 	|hl-TermCursor|	 z  Cursor in a focused terminal | ||||
| 	|hl-TermCursorNC|  Z Cursor in an unfocused terminal | ||||
| 	|hl-NonText|	 @  '@' at the end of the window and | ||||
|   | ||||
| @@ -4922,6 +4922,8 @@ NonText		'@' at the end of the window, characters from 'showbreak' | ||||
| 		fit at the end of the line). See also |hl-EndOfBuffer|. | ||||
| 							*hl-Normal* | ||||
| Normal		normal text | ||||
| 							*hl-NormalNC* | ||||
| NormalNC	normal text in non-current window | ||||
| 							*hl-Pmenu* | ||||
| Pmenu		Popup menu: normal item. | ||||
| 							*hl-PmenuSel* | ||||
|   | ||||
| @@ -233,6 +233,8 @@ typedef struct { | ||||
| # define w_p_crb_save w_onebuf_opt.wo_crb_save | ||||
|   char_u *wo_scl; | ||||
| # define w_p_scl w_onebuf_opt.wo_scl    // 'signcolumn' | ||||
|   char_u *wo_winhl; | ||||
| # define w_p_winhl w_onebuf_opt.wo_winhl    // 'winhighlight' | ||||
|  | ||||
|   int wo_scriptID[WV_COUNT];            /* SIDs for window-local options */ | ||||
| # define w_p_scriptID w_onebuf_opt.wo_scriptID | ||||
| @@ -930,6 +932,10 @@ struct window_S { | ||||
|  | ||||
|   synblock_T  *w_s;                 /* for :ownsyntax */ | ||||
|  | ||||
|   int w_hl_id;                      ///< 'winhighlight' id | ||||
|   int w_hl_id_inactive;             ///< 'winhighlight' id for inactive window | ||||
|   int w_hl_attr;                    ///< 'winhighlight' final attrs | ||||
|  | ||||
|   win_T       *w_prev;              /* link to previous window */ | ||||
|   win_T       *w_next;              /* link to next window */ | ||||
|   bool w_closing;                   /* window is being closed, don't let | ||||
|   | ||||
| @@ -465,6 +465,7 @@ typedef enum { | ||||
|   , HLF_MC          // 'colorcolumn' | ||||
|   , HLF_QFL         // selected quickfix line | ||||
|   , HLF_0           // Whitespace | ||||
|   , HLF_INACTIVE    // Inactive window | ||||
|   , HLF_COUNT       // MUST be the last one | ||||
| } hlf_T; | ||||
|  | ||||
| @@ -473,7 +474,7 @@ typedef enum { | ||||
| #define HL_FLAGS { '8', '~', 'z', 'Z', '@', 'd', 'e', 'i', 'l', 'm', 'M', 'n', \ | ||||
|                    'N', 'r', 's', 'S', 'c', 't', 'v', 'V', 'w', 'W', 'f', 'F', \ | ||||
|                    'A', 'C', 'D', 'T', '-', '>', 'B', 'P', 'R', 'L', '+', '=', \ | ||||
|                    'x', 'X', '*', '#', '_', '!', '.', 'o', 'q', '0' } | ||||
|                    'x', 'X', '*', '#', '_', '!', '.', 'o', 'q', '0', 'I' } | ||||
|  | ||||
| EXTERN int highlight_attr[HLF_COUNT];       /* Highl. attr for each context. */ | ||||
| EXTERN int highlight_user[9];                   /* User[1-9] attributes */ | ||||
|   | ||||
| @@ -252,7 +252,7 @@ typedef struct vimoption { | ||||
|   "B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel," \ | ||||
|   "x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill," \ | ||||
|   "!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine," \ | ||||
|   "0:Whitespace" | ||||
|   "0:Whitespace,I:NormalNC" | ||||
|  | ||||
| /* | ||||
|  * options[] is initialized here. | ||||
| @@ -3174,6 +3174,10 @@ did_set_string_option ( | ||||
|     if (!valid_filetype(*varp)) { | ||||
|       errmsg = e_invarg; | ||||
|     } | ||||
|   } else if (varp == &curwin->w_p_winhl) { | ||||
|     if (!parse_winhl_opt(curwin)) { | ||||
|       errmsg = e_invarg; | ||||
|     } | ||||
|   } else { | ||||
|     // Options that are a list of flags. | ||||
|     p = NULL; | ||||
| @@ -3582,6 +3586,38 @@ static char_u *compile_cap_prog(synblock_T *synblock) | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /// Handle setting `winhighlight' in window "wp" | ||||
| static bool parse_winhl_opt(win_T *wp) | ||||
| { | ||||
|   int w_hl_id = 0, w_hl_id_inactive = 0; | ||||
|  | ||||
|   const char *p = (const char *)wp->w_p_winhl; | ||||
|   while (*p) { | ||||
|     char *colon = strchr(p, ':'); | ||||
|     if (!colon) { | ||||
|       return false; | ||||
|     } | ||||
|     size_t nlen = (size_t)(colon-p); | ||||
|     char *hi = colon+1; | ||||
|     char *commap = xstrchrnul(hi, ','); | ||||
|     int hl_id = syn_check_group((char_u *)hi, (int)(commap-hi)); | ||||
|  | ||||
|     if (strncmp("Normal", p, nlen) == 0) { | ||||
|       w_hl_id = hl_id; | ||||
|     } else if (strncmp("NormalNC", p, nlen) == 0) { | ||||
|       w_hl_id_inactive = hl_id; | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     p = *commap ? commap+1 : ""; | ||||
|   } | ||||
|  | ||||
|   wp->w_hl_id = w_hl_id; | ||||
|   wp->w_hl_id_inactive = w_hl_id_inactive; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Set the scriptID for an option, taking care of setting the buffer- or | ||||
|  * window-local value. | ||||
| @@ -5491,6 +5527,7 @@ static char_u *get_varp(vimoption_T *p) | ||||
|   case PV_WM:     return (char_u *)&(curbuf->b_p_wm); | ||||
|   case PV_KMAP:   return (char_u *)&(curbuf->b_p_keymap); | ||||
|   case PV_SCL:    return (char_u *)&(curwin->w_p_scl); | ||||
|   case PV_WINHL:  return (char_u *)&(curwin->w_p_winhl); | ||||
|   default:        EMSG(_("E356: get_varp ERROR")); | ||||
|   } | ||||
|   /* always return a valid pointer to avoid a crash! */ | ||||
| @@ -5568,6 +5605,7 @@ void copy_winopt(winopt_T *from, winopt_T *to) | ||||
|   to->wo_fdt = vim_strsave(from->wo_fdt); | ||||
|   to->wo_fmr = vim_strsave(from->wo_fmr); | ||||
|   to->wo_scl = vim_strsave(from->wo_scl); | ||||
|   to->wo_winhl = vim_strsave(from->wo_winhl); | ||||
|   check_winopt(to);             // don't want NULL pointers | ||||
| } | ||||
|  | ||||
| @@ -5597,6 +5635,7 @@ static void check_winopt(winopt_T *wop) | ||||
|   check_string_option(&wop->wo_cc); | ||||
|   check_string_option(&wop->wo_cocu); | ||||
|   check_string_option(&wop->wo_briopt); | ||||
|   check_string_option(&wop->wo_winhl); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -5616,12 +5655,14 @@ void clear_winopt(winopt_T *wop) | ||||
|   clear_string_option(&wop->wo_cc); | ||||
|   clear_string_option(&wop->wo_cocu); | ||||
|   clear_string_option(&wop->wo_briopt); | ||||
|   clear_string_option(&wop->wo_winhl); | ||||
| } | ||||
|  | ||||
| void didset_window_options(win_T *wp) | ||||
| { | ||||
|   check_colorcolumn(wp); | ||||
|   briopt_check(wp); | ||||
|   parse_winhl_opt(wp); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -807,6 +807,7 @@ enum { | ||||
|   , WV_WFW | ||||
|   , WV_WRAP | ||||
|   , WV_SCL | ||||
|   , WV_WINHL | ||||
|   , WV_COUNT        // must be the last one | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -2701,6 +2701,14 @@ return { | ||||
|       varname='p_wak', | ||||
|       defaults={if_true={vi="menu"}} | ||||
|     }, | ||||
|     { | ||||
|       full_name='winhighlight', abbreviation='winhl', | ||||
|       type='string', scope={'window'}, | ||||
|       vi_def=true, | ||||
|       alloced=true, | ||||
|       redraw={'current_window'}, | ||||
|       defaults={if_true={vi=""}} | ||||
|     }, | ||||
|     { | ||||
|       full_name='window', abbreviation='wi', | ||||
|       type='number', scope={'global'}, | ||||
|   | ||||
| @@ -1584,6 +1584,11 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h | ||||
| # define FDC_OFF n | ||||
|   int fdc = compute_foldcolumn(wp, 0); | ||||
|  | ||||
|   int attr = hl_attr(hl); | ||||
|   if (wp->w_hl_attr != 0) { | ||||
|     attr = hl_combine_attr(wp->w_hl_attr, attr); | ||||
|   } | ||||
|  | ||||
|   if (wp->w_p_rl) { | ||||
|     // No check for cmdline window: should never be right-left. | ||||
|     n = fdc; | ||||
| @@ -1612,10 +1617,10 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h | ||||
|  | ||||
|     screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, | ||||
|                 wp->w_wincol, W_ENDCOL(wp) - 1 - FDC_OFF, | ||||
|                 c2, c2, hl_attr(hl)); | ||||
|                 c2, c2, attr); | ||||
|     screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, | ||||
|                 W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF, | ||||
|                 c1, c2, hl_attr(hl)); | ||||
|                 c1, c2, attr); | ||||
|   } else { | ||||
|     if (cmdwin_type != 0 && wp == curwin) { | ||||
|       /* draw the cmdline character in the leftmost column */ | ||||
| @@ -1653,7 +1658,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h | ||||
|  | ||||
|     screen_fill(wp->w_winrow + row, wp->w_winrow + endrow, | ||||
|                 wp->w_wincol + FDC_OFF, W_ENDCOL(wp), | ||||
|                 c1, c2, hl_attr(hl)); | ||||
|                 c1, c2, attr); | ||||
|   } | ||||
|   set_empty_rows(wp, row); | ||||
| } | ||||
| @@ -2418,6 +2423,10 @@ win_line ( | ||||
|     line_attr = hl_attr(HLF_QFL); | ||||
|   } | ||||
|  | ||||
|   if (wp->w_hl_attr != 0) { | ||||
|     line_attr = hl_combine_attr(wp->w_hl_attr, line_attr); | ||||
|   } | ||||
|  | ||||
|   if (line_attr != 0) { | ||||
|     area_highlighting = true; | ||||
|   } | ||||
| @@ -2849,6 +2858,10 @@ win_line ( | ||||
|         } else | ||||
|           char_attr = 0; | ||||
|       } | ||||
|  | ||||
|       if (wp->w_hl_attr != 0) { | ||||
|         char_attr = hl_combine_attr(wp->w_hl_attr, char_attr); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     /* When still displaying '$' of change command, stop at cursor */ | ||||
| @@ -3083,10 +3096,14 @@ win_line ( | ||||
|             mb_l = 1; | ||||
|             mb_utf8 = FALSE; | ||||
|             multi_attr = hl_attr(HLF_AT); | ||||
|             /* put the pointer back to output the double-width | ||||
|              * character at the start of the next line. */ | ||||
|             ++n_extra; | ||||
|             --p_extra; | ||||
|             if (wp->w_hl_attr != 0) { | ||||
|               multi_attr = hl_combine_attr(wp->w_hl_attr, multi_attr); | ||||
|             } | ||||
|  | ||||
|             // put the pointer back to output the double-width | ||||
|             // character at the start of the next line. | ||||
|             n_extra++; | ||||
|             p_extra--; | ||||
|           } else { | ||||
|             n_extra -= mb_l - 1; | ||||
|             p_extra += mb_l - 1; | ||||
| @@ -3221,11 +3238,15 @@ win_line ( | ||||
|           mb_utf8 = FALSE; | ||||
|           mb_l = 1; | ||||
|           multi_attr = hl_attr(HLF_AT); | ||||
|           /* Put pointer back so that the character will be | ||||
|            * displayed at the start of the next line. */ | ||||
|           --ptr; | ||||
|         } else if (*ptr != NUL) | ||||
|           if (wp->w_hl_attr != 0) { | ||||
|             multi_attr = hl_combine_attr(wp->w_hl_attr, multi_attr); | ||||
|           } | ||||
|           // Put pointer back so that the character will be | ||||
|           // displayed at the start of the next line. | ||||
|           ptr--; | ||||
|         } else if (*ptr != NUL) { | ||||
|           ptr += mb_l - 1; | ||||
|         } | ||||
|  | ||||
|         /* If a double-width char doesn't fit at the left side display | ||||
|          * a '<' in the first column.  Don't do this for unprintable | ||||
| @@ -3752,7 +3773,10 @@ win_line ( | ||||
|         mb_utf8 = false;  // don't draw as UTF-8 | ||||
|       } | ||||
|       saved_attr3 = char_attr;  // save current attr | ||||
|       char_attr = hl_attr(HLF_AT);  // later copied to char_attr | ||||
|       char_attr = hl_attr(HLF_AT);  // overwriting char_attr | ||||
|       if (wp->w_hl_attr != 0) { | ||||
|         char_attr = hl_combine_attr(wp->w_hl_attr, char_attr); | ||||
|       } | ||||
|       n_attr3 = 1; | ||||
|     } | ||||
|  | ||||
| @@ -3836,6 +3860,10 @@ win_line ( | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         if (wp->w_hl_attr != 0) { | ||||
|           char_attr = hl_combine_attr(wp->w_hl_attr, char_attr); | ||||
|         } | ||||
|         ScreenAttrs[off] = char_attr; | ||||
|         if (wp->w_p_rl) { | ||||
|           --col; | ||||
| @@ -3897,6 +3925,14 @@ win_line ( | ||||
|             if (rightmost_vcol < color_cols[i]) | ||||
|               rightmost_vcol = color_cols[i]; | ||||
|  | ||||
|         int cuc_attr = hl_attr(HLF_CUC); | ||||
|         int mc_attr = hl_attr(HLF_MC); | ||||
|         if (wp->w_hl_attr != 0) { | ||||
|           cuc_attr = hl_combine_attr(wp->w_hl_attr, cuc_attr); | ||||
|           mc_attr = hl_combine_attr(wp->w_hl_attr, mc_attr); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         while (col < wp->w_width) { | ||||
|           ScreenLines[off] = ' '; | ||||
|           if (enc_utf8) | ||||
| @@ -3906,12 +3942,13 @@ win_line ( | ||||
|             draw_color_col = advance_color_col(VCOL_HLC, | ||||
|                 &color_cols); | ||||
|  | ||||
|           if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol) | ||||
|             ScreenAttrs[off++] = hl_attr(HLF_CUC); | ||||
|           else if (draw_color_col && VCOL_HLC == *color_cols) | ||||
|             ScreenAttrs[off++] = hl_attr(HLF_MC); | ||||
|           else | ||||
|             ScreenAttrs[off++] = 0; | ||||
|           if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol) { | ||||
|             ScreenAttrs[off++] = cuc_attr; | ||||
|           } else if (draw_color_col && VCOL_HLC == *color_cols) { | ||||
|             ScreenAttrs[off++] = mc_attr; | ||||
|           } else { | ||||
|             ScreenAttrs[off++] = wp->w_hl_attr; | ||||
|           } | ||||
|  | ||||
|           if (VCOL_HLC >= rightmost_vcol) | ||||
|             break; | ||||
| @@ -3920,6 +3957,7 @@ win_line ( | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // TODO(bfredl): integrate with the common beyond-the-end-loop | ||||
|       if (wp->w_buffer->terminal) { | ||||
|         // terminal buffers may need to highlight beyond the end of the | ||||
|         // logical line | ||||
| @@ -3961,6 +3999,9 @@ win_line ( | ||||
|             || (n_extra && (c_extra != NUL || *p_extra != NUL)))) { | ||||
|       c = lcs_ext; | ||||
|       char_attr = hl_attr(HLF_AT); | ||||
|       if (wp->w_hl_attr != 0) { | ||||
|         char_attr = hl_combine_attr(wp->w_hl_attr, char_attr); | ||||
|       } | ||||
|       mb_c = c; | ||||
|       if (enc_utf8 && (*mb_char2len)(c) > 1) { | ||||
|         mb_utf8 = TRUE; | ||||
| @@ -5510,7 +5551,19 @@ static void init_search_hl(win_T *wp) | ||||
|   search_hl.buf = wp->w_buffer; | ||||
|   search_hl.lnum = 0; | ||||
|   search_hl.first_lnum = 0; | ||||
|   /* time limit is set at the toplevel, for all windows */ | ||||
|   // time limit is set at the toplevel, for all windows | ||||
|  | ||||
|   // determine window specific background set in 'winhighlight' | ||||
|   if (wp != curwin && wp->w_hl_id_inactive > 0) { | ||||
|     wp->w_hl_attr = syn_id2attr(wp->w_hl_id_inactive); | ||||
|   } else if (wp->w_hl_id > 0) { | ||||
|     wp->w_hl_attr = syn_id2attr(wp->w_hl_id); | ||||
|   } else { | ||||
|     wp->w_hl_attr = 0; | ||||
|   } | ||||
|   if (wp != curwin) { | ||||
|     wp->w_hl_attr = hl_combine_attr(hl_attr(HLF_INACTIVE), wp->w_hl_attr); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -3722,6 +3722,12 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, | ||||
|   if (restart_edit) | ||||
|     redraw_later(VALID);        /* causes status line redraw */ | ||||
|  | ||||
|   if (hl_attr(HLF_INACTIVE) | ||||
|       || (prevwin && prevwin->w_hl_id_inactive) | ||||
|       || curwin->w_hl_id_inactive) { | ||||
|     redraw_all_later(NOT_VALID); | ||||
|   } | ||||
|  | ||||
|   /* set window height to desired minimal value */ | ||||
|   if (curwin->w_height < p_wh && !curwin->w_p_wfh) | ||||
|     win_setheight((int)p_wh); | ||||
|   | ||||
| @@ -194,8 +194,8 @@ describe('ui/cursor', function() | ||||
|         if m.blinkoff then m.blinkoff = 400 end | ||||
|         if m.blinkwait then m.blinkwait = 700 end | ||||
|       end | ||||
|       if m.hl_id then m.hl_id = 46 end | ||||
|       if m.id_lm then m.id_lm = 47 end | ||||
|       if m.hl_id then m.hl_id = 47 end | ||||
|       if m.id_lm then m.id_lm = 48 end | ||||
|     end | ||||
|  | ||||
|     -- Assert the new expectation. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Björn Linse
					Björn Linse