vim-patch:8.0.1123: cannot define a toolbar for a window

Problem:    Cannot define a toolbar for a window.
Solution:   Add a window-local toolbar.
1b9645de3c

"WinBar" code in "screen.c" was not ported.

Fix https://github.com/neovim/neovim/issues/11513#issuecomment-562012827
This commit is contained in:
Jan Edmund Lazo 2020-03-13 22:05:05 -04:00
parent 5f41717838
commit 64b61d49c2
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15
7 changed files with 295 additions and 161 deletions

View File

@ -1060,6 +1060,48 @@ typedef struct
pos_T w_cursor_corr; // corrected cursor position
} pos_save_T;
/// Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode
/// \addtogroup MENU_INDEX
/// @{
enum {
MENU_INDEX_INVALID = -1,
MENU_INDEX_NORMAL = 0,
MENU_INDEX_VISUAL = 1,
MENU_INDEX_SELECT = 2,
MENU_INDEX_OP_PENDING = 3,
MENU_INDEX_INSERT = 4,
MENU_INDEX_CMDLINE = 5,
MENU_INDEX_TIP = 6,
MENU_MODES = 7,
};
typedef struct VimMenu vimmenu_T;
struct VimMenu {
int modes; ///< Which modes is this menu visible for
int enabled; ///< for which modes the menu is enabled
char_u *name; ///< Name of menu, possibly translated
char_u *dname; ///< Displayed Name ("name" without '&')
char_u *en_name; ///< "name" untranslated, NULL when
///< was not translated
char_u *en_dname; ///< NULL when "dname" untranslated
int mnemonic; ///< mnemonic key (after '&')
char_u *actext; ///< accelerator text (after TAB)
long priority; ///< Menu order priority
char_u *strings[MENU_MODES]; ///< Mapped string for each mode
int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode
bool silent[MENU_MODES]; ///< A silent flag for each mode
vimmenu_T *children; ///< Children of sub-menu
vimmenu_T *parent; ///< Parent of menu
vimmenu_T *next; ///< Next item in menu
};
typedef struct {
int wb_startcol;
int wb_endcol;
vimmenu_T *wb_menu;
} winbar_item_T;
/// Structure which contains all information that belongs to a window.
///
/// All row numbers are relative to the start of the window, except w_winrow.
@ -1161,7 +1203,7 @@ struct window_S {
//
int w_winrow; // first row of window in screen
int w_height; // number of rows in window, excluding
// status/command line(s)
// status/command/winbar line(s)
int w_status_height; // number of status lines (0 or 1)
int w_wincol; // Leftmost column of window in screen.
int w_width; // Width of window, excluding separation.
@ -1269,13 +1311,15 @@ struct window_S {
char_u *w_localdir; /* absolute path of local directory or
NULL */
/*
* Options local to a window.
* They are local because they influence the layout of the window or
* depend on the window layout.
* There are two values: w_onebuf_opt is local to the buffer currently in
* this window, w_allbuf_opt is for all buffers in this window.
*/
vimmenu_T *w_winbar; // The root of the WinBar menu hierarchy.
winbar_item_T *w_winbar_items; // list of items in the WinBar
int w_winbar_height; // 1 if there is a window toolbar
// Options local to a window.
// They are local because they influence the layout of the window or
// depend on the window layout.
// There are two values: w_onebuf_opt is local to the buffer currently in
// this window, w_allbuf_opt is for all buffers in this window.
winopt_T w_onebuf_opt;
winopt_T w_allbuf_opt;

View File

@ -7323,6 +7323,7 @@ dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr)
tv_dict_add_nr(dict, S_LEN("winrow"), wp->w_winrow + 1);
tv_dict_add_nr(dict, S_LEN("topline"), wp->w_topline);
tv_dict_add_nr(dict, S_LEN("botline"), wp->w_botline - 1);
tv_dict_add_nr(dict, S_LEN("winbar"), wp->w_winbar_height);
tv_dict_add_nr(dict, S_LEN("width"), wp->w_width);
tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum);
tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol + 1);
@ -10364,13 +10365,7 @@ void ex_echo(exarg_T *eap)
*/
void ex_echohl(exarg_T *eap)
{
int id;
id = syn_name2id(eap->arg);
if (id == 0)
echo_attr = 0;
else
echo_attr = syn_id2attr(id);
echo_attr = syn_name2attr(eap->arg);
}
/*

View File

@ -27,6 +27,7 @@
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/eval/typval.h"
#include "nvim/screen.h"
#define MENUDEPTH 10 /* maximum depth of menus */
@ -46,6 +47,24 @@ static char_u e_notsubmenu[] = N_(
static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
// Return true if "name" is a window toolbar menu name.
static bool menu_is_winbar(const char_u *const name)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
return (STRNCMP(name, "WinBar", 5) == 0);
}
int winbar_height(const win_T *const wp)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
return wp->w_winbar != NULL && wp->w_winbar->children != NULL ? 1 : 0;
}
static vimmenu_T **get_root_menu(const char_u *const name)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
return menu_is_winbar(name) ? &curwin->w_winbar : &root_menu;
}
/// Do the :menu command and relatives.
/// @param eap Ex command arguments
@ -170,6 +189,12 @@ ex_menu(exarg_T *eap)
goto theend;
}
vimmenu_T **root_menu_ptr = get_root_menu(menu_path);
if (root_menu_ptr == &curwin->w_winbar) {
// Assume the window toolbar menu will change.
redraw_later(NOT_VALID);
}
if (enable != kNone) {
// Change sensitivity of the menu.
// For the PopUp menu, remove a menu for each mode separately.
@ -182,11 +207,11 @@ ex_menu(exarg_T *eap)
for (i = 0; i < MENU_INDEX_TIP; ++i)
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
menu_enable_recurse(root_menu, p, MENU_ALL_MODES, enable);
menu_enable_recurse(*root_menu_ptr, p, MENU_ALL_MODES, enable);
xfree(p);
}
}
menu_enable_recurse(root_menu, menu_path, modes, enable);
menu_enable_recurse(*root_menu_ptr, menu_path, modes, enable);
} else if (unmenu) {
/*
* Delete menu(s).
@ -201,13 +226,13 @@ ex_menu(exarg_T *eap)
for (i = 0; i < MENU_INDEX_TIP; ++i)
if (modes & (1 << i)) {
p = popup_mode_name(menu_path, i);
remove_menu(&root_menu, p, MENU_ALL_MODES, TRUE);
remove_menu(root_menu_ptr, p, MENU_ALL_MODES, true);
xfree(p);
}
}
/* Careful: remove_menu() changes menu_path */
remove_menu(&root_menu, menu_path, modes, FALSE);
// Careful: remove_menu() changes menu_path
remove_menu(root_menu_ptr, menu_path, modes, false);
} else {
/*
* Add menu(s).
@ -244,6 +269,19 @@ ex_menu(exarg_T *eap)
xfree(map_buf);
}
if (root_menu_ptr == &curwin->w_winbar) {
const int h = winbar_height(curwin);
if (h != curwin->w_winbar_height) {
if (h == 0) {
curwin->w_height++;
} else if (curwin->w_height > 0) {
curwin->w_height--;
}
curwin->w_winbar_height = h;
}
}
ui_call_update_menu();
theend:
@ -266,7 +304,6 @@ add_menu_path(
{
char_u *path_name;
int modes = menuarg->modes;
vimmenu_T **menup;
vimmenu_T *menu = NULL;
vimmenu_T *parent;
vimmenu_T **lower_pri;
@ -285,7 +322,8 @@ add_menu_path(
/* Make a copy so we can stuff around with it, since it could be const */
path_name = vim_strsave(menu_path);
menup = &root_menu;
vimmenu_T **root_menu_ptr = get_root_menu(menu_path);
vimmenu_T **menup = root_menu_ptr;
parent = NULL;
name = path_name;
while (*name) {
@ -468,14 +506,16 @@ erret:
/* Delete any empty submenu we added before discovering the error. Repeat
* for higher levels. */
while (parent != NULL && parent->children == NULL) {
if (parent->parent == NULL)
menup = &root_menu;
else
if (parent->parent == NULL) {
menup = root_menu_ptr;
} else {
menup = &parent->parent->children;
for (; *menup != NULL && *menup != parent; menup = &((*menup)->next))
;
if (*menup == NULL) /* safety check */
}
for (; *menup != NULL && *menup != parent; menup = &((*menup)->next)) {
}
if (*menup == NULL) { // safety check
break;
}
parent = parent->parent;
free_menu(menup);
}
@ -620,6 +660,14 @@ remove_menu (
return OK;
}
// Remove the WinBar menu from window "wp".
void remove_winbar(win_T *wp)
FUNC_ATTR_NONNULL_ALL
{
remove_menu(&wp->w_winbar, (char_u *)"", MENU_ALL_MODES, true);
xfree(wp->w_winbar_items);
}
/*
* Free the given menu structure and remove it from the linked list.
*/
@ -740,7 +788,7 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
/// @return false if could not find path_name
bool menu_get(char_u *const path_name, int modes, list_T *list)
{
vimmenu_T *menu = find_menu(root_menu, path_name, modes);
vimmenu_T *menu = find_menu(*get_root_menu(path_name), path_name, modes);
if (!menu) {
return false;
}
@ -802,10 +850,8 @@ static vimmenu_T *find_menu(vimmenu_T *menu, char_u *name, int modes)
/// Show the mapping associated with a menu item or hierarchy in a sub-menu.
static int show_menus(char_u *const path_name, int modes)
{
vimmenu_T *menu;
// First, find the (sub)menu with the given name
menu = find_menu(root_menu, path_name, modes);
vimmenu_T *menu = find_menu(*get_root_menu(path_name), path_name, modes);
if (!menu) {
return FAIL;
}
@ -890,6 +936,7 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
* Used when expanding menu names.
*/
static vimmenu_T *expand_menu = NULL;
static vimmenu_T *expand_menu_alt = NULL;
static int expand_modes = 0x0;
static int expand_emenu; /* TRUE for ":emenu" command */
@ -940,14 +987,15 @@ char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forc
// ":popup" only uses menues, not entries
expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
expand_emenu = (*cmd == 'e');
if (expand_menus && ascii_iswhite(*p))
return NULL; /* TODO: check for next command? */
if (*p == NUL) { /* Complete the menu name */
/*
* With :unmenu, you only want to match menus for the appropriate mode.
* With :menu though you might want to add a menu with the same name as
* one in another mode, so match menus from other modes too.
*/
if (expand_menus && ascii_iswhite(*p)) {
return NULL; // TODO(vim): check for next command?
}
if (*p == NUL) { // Complete the menu name
bool try_alt_menu = true;
// With :unmenu, you only want to match menus for the appropriate mode.
// With :menu though you might want to add a menu with the same name as
// one in another mode, so match menus from other modes too.
expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu);
if (!unmenu)
expand_modes = MENU_ALL_MODES;
@ -976,6 +1024,10 @@ char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forc
break;
}
menu = menu->next;
if (menu == NULL && try_alt_menu) {
menu = curwin->w_winbar;
try_alt_menu = false;
}
}
if (menu == NULL) {
/* No menu found with the name we were looking for */
@ -984,14 +1036,21 @@ char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forc
}
name = p;
menu = menu->children;
try_alt_menu = false;
}
xfree(path_name);
xp->xp_context = expand_menus ? EXPAND_MENUNAMES : EXPAND_MENUS;
xp->xp_pattern = after_dot;
expand_menu = menu;
} else /* We're in the mapping part */
if (expand_menu == root_menu) {
expand_menu_alt = curwin->w_winbar;
} else {
expand_menu_alt = NULL;
}
} else { // We're in the mapping part
xp->xp_context = EXPAND_NOTHING;
}
return NULL;
}
@ -1002,19 +1061,26 @@ char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forc
char_u *get_menu_name(expand_T *xp, int idx)
{
static vimmenu_T *menu = NULL;
static bool did_alt_menu = false;
char_u *str;
static int should_advance = FALSE;
if (idx == 0) { /* first call: start at first item */
menu = expand_menu;
should_advance = FALSE;
did_alt_menu = false;
should_advance = false;
}
/* Skip PopUp[nvoci]. */
while (menu != NULL && (menu_is_hidden(menu->dname)
|| menu_is_separator(menu->dname)
|| menu->children == NULL))
|| menu->children == NULL)) {
menu = menu->next;
if (menu == NULL && !did_alt_menu) {
menu = expand_menu_alt;
did_alt_menu = true;
}
}
if (menu == NULL) /* at end of linked list */
return NULL;
@ -1030,9 +1096,14 @@ char_u *get_menu_name(expand_T *xp, int idx)
else
str = (char_u *)"";
if (should_advance)
/* Advance to next menu entry. */
if (should_advance) {
// Advance to next menu entry.
menu = menu->next;
if (menu == NULL && !did_alt_menu) {
menu = expand_menu_alt;
did_alt_menu = true;
}
}
should_advance = !should_advance;
@ -1046,6 +1117,7 @@ char_u *get_menu_name(expand_T *xp, int idx)
char_u *get_menu_names(expand_T *xp, int idx)
{
static vimmenu_T *menu = NULL;
static bool did_alt_menu = false;
#define TBUFFER_LEN 256
static char_u tbuffer[TBUFFER_LEN]; /*hack*/
char_u *str;
@ -1053,16 +1125,21 @@ char_u *get_menu_names(expand_T *xp, int idx)
if (idx == 0) { /* first call: start at first item */
menu = expand_menu;
should_advance = FALSE;
did_alt_menu = false;
should_advance = false;
}
/* Skip Browse-style entries, popup menus and separators. */
while (menu != NULL
&& ( menu_is_hidden(menu->dname)
|| (expand_emenu && menu_is_separator(menu->dname))
|| menu->dname[STRLEN(menu->dname) - 1] == '.'
))
&& (menu_is_hidden(menu->dname)
|| (expand_emenu && menu_is_separator(menu->dname))
|| menu->dname[STRLEN(menu->dname) - 1] == '.')) {
menu = menu->next;
if (menu == NULL && !did_alt_menu) {
menu = expand_menu_alt;
did_alt_menu = true;
}
}
if (menu == NULL) /* at end of linked list */
return NULL;
@ -1092,9 +1169,14 @@ char_u *get_menu_names(expand_T *xp, int idx)
} else
str = (char_u *)"";
if (should_advance)
/* Advance to next menu entry. */
if (should_advance) {
// Advance to next menu entry.
menu = menu->next;
if (menu == NULL && !did_alt_menu) {
menu = expand_menu_alt;
did_alt_menu = true;
}
}
should_advance = !should_advance;
@ -1325,53 +1407,15 @@ static int menu_is_hidden(char_u *name)
|| (menu_is_popup(name) && name[5] != NUL);
}
/*
* Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy and
* execute it.
*/
void ex_emenu(exarg_T *eap)
// Execute "menu". Use by ":emenu" and the window toolbar.
// "eap" is NULL for the window toolbar.
static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
FUNC_ATTR_NONNULL_ARG(2)
{
vimmenu_T *menu;
char_u *name;
char_u *saved_name;
char_u *p;
int idx;
char_u *mode;
char_u *mode;
saved_name = vim_strsave(eap->arg);
menu = root_menu;
name = saved_name;
while (*name) {
/* Find in the menu hierarchy */
p = menu_name_skip(name);
while (menu != NULL) {
if (menu_name_equal(name, menu)) {
if (*p == NUL && menu->children != NULL) {
EMSG(_("E333: Menu path must lead to a menu item"));
menu = NULL;
} else if (*p != NUL && menu->children == NULL) {
EMSG(_(e_notsubmenu));
menu = NULL;
}
break;
}
menu = menu->next;
}
if (menu == NULL || *p == NUL)
break;
menu = menu->children;
name = p;
}
xfree(saved_name);
if (menu == NULL) {
EMSG2(_("E334: Menu not found: %s"), eap->arg);
return;
}
/* Found the menu, so execute.
* Use the Insert mode entry when returning to Insert mode. */
// Use the Insert mode entry when returning to Insert mode.
if (((State & INSERT) || restart_edit) && !current_sctx.sc_sid) {
mode = (char_u *)"Insert";
idx = MENU_INDEX_INSERT;
@ -1384,7 +1428,7 @@ void ex_emenu(exarg_T *eap)
* is. Just execute the visual binding for the menu. */
mode = (char_u *)"Visual";
idx = MENU_INDEX_VISUAL;
} else if (eap->addr_count) {
} else if (eap != NULL && eap->addr_count) {
pos_T tpos;
mode = (char_u *)"Visual";
@ -1432,19 +1476,92 @@ void ex_emenu(exarg_T *eap)
assert(idx != MENU_INDEX_INVALID);
if (menu->strings[idx] != NULL) {
// When executing a script or function execute the commands right now.
// Also for the window toolbar
// Otherwise put them in the typeahead buffer.
if (current_sctx.sc_sid != 0) {
if (eap == NULL || current_sctx.sc_sid != 0) {
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
menu->silent[idx]);
} else {
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0, true,
menu->silent[idx]);
}
} else {
} else if (eap != NULL) {
EMSG2(_("E335: Menu not defined for %s mode"), mode);
}
}
// Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy and
// execute it.
void ex_emenu(exarg_T *eap)
{
char_u *saved_name = vim_strsave(eap->arg);
vimmenu_T *menu = *get_root_menu(saved_name);
char_u *name = saved_name;
while (*name) {
// Find in the menu hierarchy
char_u *p = menu_name_skip(name);
while (menu != NULL) {
if (menu_name_equal(name, menu)) {
if (*p == NUL && menu->children != NULL) {
EMSG(_("E333: Menu path must lead to a menu item"));
menu = NULL;
} else if (*p != NUL && menu->children == NULL) {
EMSG(_(e_notsubmenu));
menu = NULL;
}
break;
}
menu = menu->next;
}
if (menu == NULL || *p == NUL) {
break;
}
menu = menu->children;
name = p;
}
xfree(saved_name);
if (menu == NULL) {
EMSG2(_("E334: Menu not found: %s"), eap->arg);
return;
}
// Found the menu, so execute.
execute_menu(eap, menu);
}
// Handle a click in the window toolbar of "wp" at column "col".
void winbar_click(win_T *wp, int col)
FUNC_ATTR_NONNULL_ALL
{
if (wp->w_winbar_items == NULL) {
return;
}
for (int idx = 0; wp->w_winbar_items[idx].wb_menu != NULL; idx++) {
winbar_item_T *item = &wp->w_winbar_items[idx];
if (col >= item->wb_startcol && col <= item->wb_endcol) {
win_T *save_curwin = NULL;
if (wp != curwin) {
// Clicking in the window toolbar of a not-current window.
// Make that window the current one and go to Normal mode.
save_curwin = curwin;
curwin = wp;
curbuf = curwin->w_buffer;
check_cursor();
}
execute_menu(NULL, item->wb_menu);
if (save_curwin != NULL) {
curwin = save_curwin;
curbuf = curwin->w_buffer;
}
}
}
}
/*
* Translation of menu names. Just a simple lookup table.
*/

View File

@ -6,18 +6,6 @@
#include "nvim/types.h" // for char_u and expand_T
#include "nvim/ex_cmds_defs.h" // for exarg_T
/// Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode
/// \addtogroup MENU_INDEX
/// @{
#define MENU_INDEX_INVALID -1
#define MENU_INDEX_NORMAL 0
#define MENU_INDEX_VISUAL 1
#define MENU_INDEX_SELECT 2
#define MENU_INDEX_OP_PENDING 3
#define MENU_INDEX_INSERT 4
#define MENU_INDEX_CMDLINE 5
#define MENU_INDEX_TIP 6
#define MENU_MODES 7
/// @}
/// note MENU_INDEX_TIP is not a 'real' mode
@ -37,28 +25,6 @@
/// Start a menu name with this to not include it on the main menu bar
#define MNU_HIDDEN_CHAR ']'
typedef struct VimMenu vimmenu_T;
struct VimMenu {
int modes; ///< Which modes is this menu visible for
int enabled; ///< for which modes the menu is enabled
char_u *name; ///< Name of menu, possibly translated
char_u *dname; ///< Displayed Name ("name" without '&')
char_u *en_name; ///< "name" untranslated, NULL when
///< was not translated
char_u *en_dname; ///< NULL when "dname" untranslated
int mnemonic; ///< mnemonic key (after '&')
char_u *actext; ///< accelerator text (after TAB)
long priority; ///< Menu order priority
char_u *strings[MENU_MODES]; ///< Mapped string for each mode
int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode
bool silent[MENU_MODES]; ///< A silent flag for each mode
vimmenu_T *children; ///< Children of sub-menu
vimmenu_T *parent; ///< Parent of menu
vimmenu_T *next; ///< Next item in menu
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "menu.h.generated.h"
#endif

View File

@ -134,6 +134,14 @@ retnomove:
}
fdc = win_fdccol_count(wp);
dragwin = NULL;
if (row == -1) {
// A click in the window toolbar does not enter another window or
// change Visual highlighting.
winbar_click(wp, col);
return IN_OTHER_WIN;
}
// winpos and height may change in win_enter()!
if (grid == DEFAULT_GRID_HANDLE && row >= wp->w_height) {
// In (or below) status line
@ -471,6 +479,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp)
// exist.
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp == fp->fr_win) {
*rowp -= wp->w_winbar_height;
return wp;
}
}

View File

@ -1741,6 +1741,31 @@ static int advance_color_col(int vcol, int **color_cols)
return **color_cols >= 0;
}
// Returns the next grid column.
static int text_to_screenline(win_T *wp, char_u *text, int col, int off)
FUNC_ATTR_NONNULL_ALL
{
int idx = wp->w_p_rl ? off : off + col;
LineState s = LINE_STATE(text);
while (*s.p != NUL) {
// TODO(bfredl): cargo-culted from the old Vim code:
// if(col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { break; }
// This is obvious wrong. If Vim ever fixes this, solve for "cells" again
// in the correct condition.
const int maxcells = wp->w_grid.Columns - col - (wp->w_p_rl ? col : 0);
const int cells = line_putchar(&s, &linebuf_char[idx], maxcells,
wp->w_p_rl);
if (cells == -1) {
break;
}
col += cells;
idx += cells;
}
return col;
}
// Compute the width of the foldcolumn. Based on 'foldcolumn' and how much
// space is available for window "wp", minus "col".
static int compute_foldcolumn(win_T *wp, int col)
@ -1942,29 +1967,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
// 5. move the text to linebuf_char[off]. Fill up with "fold".
// Right-left text is put in columns 0 - number-col, normal text is put
// in columns number-col - window-width.
int idx;
if (wp->w_p_rl) {
idx = off;
} else {
idx = off + col;
}
LineState s = LINE_STATE(text);
while (*s.p != NUL) {
// TODO(bfredl): cargo-culted from the old Vim code:
// if(col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { break; }
// This is obvious wrong. If Vim ever fixes this, solve for "cells" again
// in the correct condition.
int maxcells = wp->w_grid.Columns - col - (wp->w_p_rl ? col : 0);
int cells = line_putchar(&s, &linebuf_char[idx], maxcells, wp->w_p_rl);
if (cells == -1) {
break;
}
col += cells;
idx += cells;
}
col = text_to_screenline(wp, text, col, off);
/* Fill the rest of the line with the fold filler */
if (wp->w_p_rl)

View File

@ -4782,6 +4782,7 @@ win_free (
qf_free_all(wp);
remove_winbar(wp);
xfree(wp->w_p_cc_cols);
@ -5708,11 +5709,10 @@ void set_fraction(win_T *wp)
}
}
/*
* Set the height of a window.
* This takes care of the things inside the window, not what happens to the
* window position, the frame or to other windows.
*/
// Set the height of a window.
// "height" excludes any window toolbar.
// This takes care of the things inside the window, not what happens to the
// window position, the frame or to other windows.
void win_new_height(win_T *wp, int height)
{
// Don't want a negative height. Happens when splitting a tiny window.