diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-09-17 23:03:31 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-09-17 23:03:31 +0200 |
commit | 1b9645de3c05f37b5c30e78f999351b0cf486ade (patch) | |
tree | 4041a73d7fd4ab444372919e99962587a689388a /src/screen.c | |
parent | dde403c2d8f3dabe6fefa7b526958b49a8f2e6e9 (diff) | |
download | vim-git-1b9645de3c05f37b5c30e78f999351b0cf486ade.tar.gz |
patch 8.0.1123: cannot define a toolbar for a windowv8.0.1123
Problem: Cannot define a toolbar for a window.
Solution: Add a window-local toolbar.
Diffstat (limited to 'src/screen.c')
-rw-r--r-- | src/screen.c | 362 |
1 files changed, 233 insertions, 129 deletions
diff --git a/src/screen.c b/src/screen.c index d93ce50f3..9f39edf04 100644 --- a/src/screen.c +++ b/src/screen.c @@ -107,6 +107,9 @@ static int screen_cur_row, screen_cur_col; /* last known cursor position */ static match_T search_hl; /* used for 'hlsearch' highlight matching */ #endif +#if defined(FEAT_MENU) || defined(FEAT_FOLDING) +static int text_to_screenline(win_T *wp, char_u *text, int col); +#endif #ifdef FEAT_FOLDING static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ static int compute_foldcolumn(win_T *wp, int col); @@ -160,6 +163,9 @@ static void recording_mode(int attr); static void draw_tabline(void); static int fillchar_status(int *attr, win_T *wp); static int fillchar_vsep(int *attr); +#ifdef FEAT_MENU +static void redraw_win_toolbar(win_T *wp); +#endif #ifdef FEAT_STL_OPT static void win_redr_custom(win_T *wp, int draw_ruler); #endif @@ -455,7 +461,7 @@ redraw_after_callback(int call_update_screen) * editing the command. */ redrawcmdline_ex(FALSE); } - else if (State & (NORMAL | INSERT)) + else if (State & (NORMAL | INSERT | TERMINAL)) { /* keep the command line if possible */ update_screen(VALID_NO_UPDATE); @@ -1804,6 +1810,15 @@ win_update(win_T *wp) win_foldinfo.fi_level = 0; #endif +#ifdef FEAT_MENU + /* + * Draw the window toolbar, if there is one. + * TODO: only when needed. + */ + if (winbar_height(wp) > 0) + redraw_win_toolbar(wp); +#endif + /* * Update all the window rows. */ @@ -2433,6 +2448,143 @@ advance_color_col(int vcol, int **color_cols) } #endif +#if defined(FEAT_MENU) || defined(FEAT_FOLDING) +/* + * Copy "text" to ScreenLines using "attr". + * Returns the next screen column. + */ + static int +text_to_screenline(win_T *wp, char_u *text, int col) +{ + int off = (int)(current_ScreenLine - ScreenLines); + +#ifdef FEAT_MBYTE + if (has_mbyte) + { + int cells; + int u8c, u8cc[MAX_MCO]; + int i; + int idx; + int c_len; + char_u *p; +# ifdef FEAT_ARABIC + int prev_c = 0; /* previous Arabic character */ + int prev_c1 = 0; /* first composing char for prev_c */ +# endif + +# ifdef FEAT_RIGHTLEFT + if (wp->w_p_rl) + idx = off; + else +# endif + idx = off + col; + + /* Store multibyte characters in ScreenLines[] et al. correctly. */ + for (p = text; *p != NUL; ) + { + cells = (*mb_ptr2cells)(p); + c_len = (*mb_ptr2len)(p); + if (col + cells > W_WIDTH(wp) +# ifdef FEAT_RIGHTLEFT + - (wp->w_p_rl ? col : 0) +# endif + ) + break; + ScreenLines[idx] = *p; + if (enc_utf8) + { + u8c = utfc_ptr2char(p, u8cc); + if (*p < 0x80 && u8cc[0] == 0) + { + ScreenLinesUC[idx] = 0; +#ifdef FEAT_ARABIC + prev_c = u8c; +#endif + } + else + { +#ifdef FEAT_ARABIC + if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c)) + { + /* Do Arabic shaping. */ + int pc, pc1, nc; + int pcc[MAX_MCO]; + int firstbyte = *p; + + /* The idea of what is the previous and next + * character depends on 'rightleft'. */ + if (wp->w_p_rl) + { + pc = prev_c; + pc1 = prev_c1; + nc = utf_ptr2char(p + c_len); + prev_c1 = u8cc[0]; + } + else + { + pc = utfc_ptr2char(p + c_len, pcc); + nc = prev_c; + pc1 = pcc[0]; + } + prev_c = u8c; + + u8c = arabic_shape(u8c, &firstbyte, &u8cc[0], + pc, pc1, nc); + ScreenLines[idx] = firstbyte; + } + else + prev_c = u8c; +#endif + /* Non-BMP character: display as ? or fullwidth ?. */ +#ifdef UNICODE16 + if (u8c >= 0x10000) + ScreenLinesUC[idx] = (cells == 2) ? 0xff1f : (int)'?'; + else +#endif + ScreenLinesUC[idx] = u8c; + for (i = 0; i < Screen_mco; ++i) + { + ScreenLinesC[i][idx] = u8cc[i]; + if (u8cc[i] == 0) + break; + } + } + if (cells > 1) + ScreenLines[idx + 1] = 0; + } + else if (enc_dbcs == DBCS_JPNU && *p == 0x8e) + /* double-byte single width character */ + ScreenLines2[idx] = p[1]; + else if (cells > 1) + /* double-width character */ + ScreenLines[idx + 1] = p[1]; + col += cells; + idx += cells; + p += c_len; + } + } + else +#endif + { + int len = (int)STRLEN(text); + + if (len > W_WIDTH(wp) - col) + len = W_WIDTH(wp) - col; + if (len > 0) + { +#ifdef FEAT_RIGHTLEFT + if (wp->w_p_rl) + STRNCPY(current_ScreenLine, text, len); + else +#endif + STRNCPY(current_ScreenLine + col, text, len); + col += len; + } + } + return col; +} +#endif + #ifdef FEAT_FOLDING /* * Compute the width of the foldcolumn. Based on 'foldcolumn' and how much @@ -2618,128 +2770,7 @@ fold_line( * Right-left text is put in columns 0 - number-col, normal text is put * in columns number-col - window-width. */ -#ifdef FEAT_MBYTE - if (has_mbyte) - { - int cells; - int u8c, u8cc[MAX_MCO]; - int i; - int idx; - int c_len; - char_u *p; -# ifdef FEAT_ARABIC - int prev_c = 0; /* previous Arabic character */ - int prev_c1 = 0; /* first composing char for prev_c */ -# endif - -# ifdef FEAT_RIGHTLEFT - if (wp->w_p_rl) - idx = off; - else -# endif - idx = off + col; - - /* Store multibyte characters in ScreenLines[] et al. correctly. */ - for (p = text; *p != NUL; ) - { - cells = (*mb_ptr2cells)(p); - c_len = (*mb_ptr2len)(p); - if (col + cells > W_WIDTH(wp) -# ifdef FEAT_RIGHTLEFT - - (wp->w_p_rl ? col : 0) -# endif - ) - break; - ScreenLines[idx] = *p; - if (enc_utf8) - { - u8c = utfc_ptr2char(p, u8cc); - if (*p < 0x80 && u8cc[0] == 0) - { - ScreenLinesUC[idx] = 0; -#ifdef FEAT_ARABIC - prev_c = u8c; -#endif - } - else - { -#ifdef FEAT_ARABIC - if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c)) - { - /* Do Arabic shaping. */ - int pc, pc1, nc; - int pcc[MAX_MCO]; - int firstbyte = *p; - - /* The idea of what is the previous and next - * character depends on 'rightleft'. */ - if (wp->w_p_rl) - { - pc = prev_c; - pc1 = prev_c1; - nc = utf_ptr2char(p + c_len); - prev_c1 = u8cc[0]; - } - else - { - pc = utfc_ptr2char(p + c_len, pcc); - nc = prev_c; - pc1 = pcc[0]; - } - prev_c = u8c; - - u8c = arabic_shape(u8c, &firstbyte, &u8cc[0], - pc, pc1, nc); - ScreenLines[idx] = firstbyte; - } - else - prev_c = u8c; -#endif - /* Non-BMP character: display as ? or fullwidth ?. */ -#ifdef UNICODE16 - if (u8c >= 0x10000) - ScreenLinesUC[idx] = (cells == 2) ? 0xff1f : (int)'?'; - else -#endif - ScreenLinesUC[idx] = u8c; - for (i = 0; i < Screen_mco; ++i) - { - ScreenLinesC[i][idx] = u8cc[i]; - if (u8cc[i] == 0) - break; - } - } - if (cells > 1) - ScreenLines[idx + 1] = 0; - } - else if (enc_dbcs == DBCS_JPNU && *p == 0x8e) - /* double-byte single width character */ - ScreenLines2[idx] = p[1]; - else if (cells > 1) - /* double-width character */ - ScreenLines[idx + 1] = p[1]; - col += cells; - idx += cells; - p += c_len; - } - } - else -#endif - { - len = (int)STRLEN(text); - if (len > W_WIDTH(wp) - col) - len = W_WIDTH(wp) - col; - if (len > 0) - { -#ifdef FEAT_RIGHTLEFT - if (wp->w_p_rl) - STRNCPY(current_ScreenLine, text, len); - else -#endif - STRNCPY(current_ScreenLine + col, text, len); - col += len; - } - } + col = text_to_screenline(wp, text, col); /* Fill the rest of the line with the fold filler */ #ifdef FEAT_RIGHTLEFT @@ -8397,6 +8428,17 @@ redraw_block(int row, int end, win_T *wp) screen_draw_rectangle(row, col, end - row, width, FALSE); } + static void +space_to_screenline(int off, int attr) +{ + ScreenLines[off] = ' '; + ScreenAttrs[off] = attr; +# ifdef FEAT_MBYTE + if (enc_utf8) + ScreenLinesUC[off] = 0; +# endif +} + /* * Fill the screen from 'start_row' to 'end_row', from 'start_col' to 'end_col' * with character 'c1' in first column followed by 'c2' in the other columns. @@ -8502,12 +8544,7 @@ screen_fill( col = end_col - col; while (col--) /* clear chars in ScreenLines */ { - ScreenLines[off] = ' '; -#ifdef FEAT_MBYTE - if (enc_utf8) - ScreenLinesUC[off] = 0; -#endif - ScreenAttrs[off] = 0; + space_to_screenline(off, 0); ++off; } } @@ -10671,6 +10708,73 @@ messaging(void) return (!(p_lz && char_avail() && !KeyTyped)); } +#ifdef FEAT_MENU +/* + * Draw the window toolbar. + */ + static void +redraw_win_toolbar(win_T *wp) +{ + vimmenu_T *menu; + int item_idx = 0; + int item_count = 0; + int col = 0; + int next_col; + int off = (int)(current_ScreenLine - ScreenLines); + int fill_attr = syn_name2attr((char_u *)"ToolbarLine"); + int button_attr = syn_name2attr((char_u *)"ToolbarButton"); + + vim_free(wp->w_winbar_items); + for (menu = wp->w_winbar->children; menu != NULL; menu = menu->next) + ++item_count; + wp->w_winbar_items = (winbar_item_T *)alloc_clear( + (unsigned)sizeof(winbar_item_T) * (item_count + 1)); + + /* TODO: use fewer spaces if there is not enough room */ + for (menu = wp->w_winbar->children; + menu != NULL && col < W_WIDTH(wp); menu = menu->next) + { + space_to_screenline(off + col, fill_attr); + if (++col >= W_WIDTH(wp)) + break; + if (col > 1) + { + space_to_screenline(off + col, fill_attr); + if (++col >= W_WIDTH(wp)) + break; + } + + wp->w_winbar_items[item_idx].wb_startcol = col; + space_to_screenline(off + col, button_attr); + if (++col >= W_WIDTH(wp)) + break; + + next_col = text_to_screenline(wp, menu->name, col); + while (col < next_col) + { + ScreenAttrs[off + col] = button_attr; + ++col; + } + wp->w_winbar_items[item_idx].wb_endcol = col; + wp->w_winbar_items[item_idx].wb_menu = menu; + ++item_idx; + + if (col >= W_WIDTH(wp)) + break; + space_to_screenline(off + col, button_attr); + ++col; + } + while (col < W_WIDTH(wp)) + { + space_to_screenline(off + col, fill_attr); + ++col; + } + wp->w_winbar_items[item_idx].wb_menu = NULL; /* end marker */ + + screen_line(wp->w_winrow, W_WINCOL(wp), (int)W_WIDTH(wp), + (int)W_WIDTH(wp), FALSE); +} +#endif /* * Show current status info in ruler and various other places * If always is FALSE, only show ruler if position has changed. |