mirror of
https://github.com/neovim/neovim.git
synced 2025-09-12 14:28:18 +00:00
Merge pull request #12018 from janlazo/vim-8.0.1123
[RFC]vim-patch:8.0.{1123,1125,1138,1139,1142,1292,1334,1375},8.1.1264
This commit is contained in:
@@ -334,7 +334,7 @@ typedef struct {
|
|||||||
// Struct to hold the saved typeahead for save_typeahead().
|
// Struct to hold the saved typeahead for save_typeahead().
|
||||||
typedef struct {
|
typedef struct {
|
||||||
typebuf_T save_typebuf;
|
typebuf_T save_typebuf;
|
||||||
int typebuf_valid; // TRUE when save_typebuf valid
|
bool typebuf_valid; // true when save_typebuf valid
|
||||||
int old_char;
|
int old_char;
|
||||||
int old_mod_mask;
|
int old_mod_mask;
|
||||||
buffheader_T save_readbuf1;
|
buffheader_T save_readbuf1;
|
||||||
@@ -1062,6 +1062,48 @@ typedef struct
|
|||||||
pos_T w_cursor_corr; // corrected cursor position
|
pos_T w_cursor_corr; // corrected cursor position
|
||||||
} pos_save_T;
|
} 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.
|
/// Structure which contains all information that belongs to a window.
|
||||||
///
|
///
|
||||||
/// All row numbers are relative to the start of the window, except w_winrow.
|
/// All row numbers are relative to the start of the window, except w_winrow.
|
||||||
@@ -1163,7 +1205,7 @@ struct window_S {
|
|||||||
//
|
//
|
||||||
int w_winrow; // first row of window in screen
|
int w_winrow; // first row of window in screen
|
||||||
int w_height; // number of rows in window, excluding
|
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_status_height; // number of status lines (0 or 1)
|
||||||
int w_wincol; // Leftmost column of window in screen.
|
int w_wincol; // Leftmost column of window in screen.
|
||||||
int w_width; // Width of window, excluding separation.
|
int w_width; // Width of window, excluding separation.
|
||||||
@@ -1271,13 +1313,15 @@ struct window_S {
|
|||||||
|
|
||||||
char_u *w_localdir; /* absolute path of local directory or
|
char_u *w_localdir; /* absolute path of local directory or
|
||||||
NULL */
|
NULL */
|
||||||
/*
|
vimmenu_T *w_winbar; // The root of the WinBar menu hierarchy.
|
||||||
* Options local to a window.
|
winbar_item_T *w_winbar_items; // list of items in the WinBar
|
||||||
* They are local because they influence the layout of the window or
|
int w_winbar_height; // 1 if there is a window toolbar
|
||||||
* depend on the window layout.
|
|
||||||
* There are two values: w_onebuf_opt is local to the buffer currently in
|
// Options local to a window.
|
||||||
* this window, w_allbuf_opt is for all buffers in this 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_onebuf_opt;
|
||||||
winopt_T w_allbuf_opt;
|
winopt_T w_allbuf_opt;
|
||||||
|
|
||||||
|
@@ -6305,6 +6305,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("winrow"), wp->w_winrow + 1);
|
||||||
tv_dict_add_nr(dict, S_LEN("topline"), wp->w_topline);
|
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("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("width"), wp->w_width);
|
||||||
tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum);
|
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);
|
tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol + 1);
|
||||||
@@ -9258,13 +9259,7 @@ void ex_echo(exarg_T *eap)
|
|||||||
*/
|
*/
|
||||||
void ex_echohl(exarg_T *eap)
|
void ex_echohl(exarg_T *eap)
|
||||||
{
|
{
|
||||||
int id;
|
echo_attr = syn_name2attr(eap->arg);
|
||||||
|
|
||||||
id = syn_name2id(eap->arg);
|
|
||||||
if (id == 0)
|
|
||||||
echo_attr = 0;
|
|
||||||
else
|
|
||||||
echo_attr = syn_id2attr(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -8210,6 +8210,57 @@ void update_topline_cursor(void)
|
|||||||
update_curswant();
|
update_curswant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the current State and go to Normal mode.
|
||||||
|
// Return true if the typeahead could be saved.
|
||||||
|
bool save_current_state(save_state_T *sst)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
sst->save_msg_scroll = msg_scroll;
|
||||||
|
sst->save_restart_edit = restart_edit;
|
||||||
|
sst->save_msg_didout = msg_didout;
|
||||||
|
sst->save_State = State;
|
||||||
|
sst->save_insertmode = p_im;
|
||||||
|
sst->save_finish_op = finish_op;
|
||||||
|
sst->save_opcount = opcount;
|
||||||
|
sst->save_reg_executing = reg_executing;
|
||||||
|
|
||||||
|
msg_scroll = false; // no msg scrolling in Normal mode
|
||||||
|
restart_edit = 0; // don't go to Insert mode
|
||||||
|
p_im = false; // don't use 'insertmode
|
||||||
|
|
||||||
|
// Save the current typeahead. This is required to allow using ":normal"
|
||||||
|
// from an event handler and makes sure we don't hang when the argument
|
||||||
|
// ends with half a command.
|
||||||
|
save_typeahead(&sst->tabuf);
|
||||||
|
return sst->tabuf.typebuf_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void restore_current_state(save_state_T *sst)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
// Restore the previous typeahead.
|
||||||
|
restore_typeahead(&sst->tabuf);
|
||||||
|
|
||||||
|
msg_scroll = sst->save_msg_scroll;
|
||||||
|
if (force_restart_edit) {
|
||||||
|
force_restart_edit = false;
|
||||||
|
} else {
|
||||||
|
// Some function (terminal_enter()) was aware of ex_normal and decided to
|
||||||
|
// override the value of restart_edit anyway.
|
||||||
|
restart_edit = sst->save_restart_edit;
|
||||||
|
}
|
||||||
|
p_im = sst->save_insertmode;
|
||||||
|
finish_op = sst->save_finish_op;
|
||||||
|
opcount = sst->save_opcount;
|
||||||
|
reg_executing = sst->save_reg_executing;
|
||||||
|
msg_didout |= sst->save_msg_didout; // don't reset msg_didout now
|
||||||
|
|
||||||
|
// Restore the state (needed when called from a function executed for
|
||||||
|
// 'indentexpr'). Update the mouse and cursor, they may have changed.
|
||||||
|
State = sst->save_State;
|
||||||
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ":normal[!] {commands}": Execute normal mode commands.
|
* ":normal[!] {commands}": Execute normal mode commands.
|
||||||
*/
|
*/
|
||||||
@@ -8219,15 +8270,7 @@ static void ex_normal(exarg_T *eap)
|
|||||||
EMSG("Can't re-enter normal mode from terminal mode");
|
EMSG("Can't re-enter normal mode from terminal mode");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int save_msg_scroll = msg_scroll;
|
save_state_T save_state;
|
||||||
int save_restart_edit = restart_edit;
|
|
||||||
int save_msg_didout = msg_didout;
|
|
||||||
int save_State = State;
|
|
||||||
tasave_T tabuf;
|
|
||||||
int save_insertmode = p_im;
|
|
||||||
int save_finish_op = finish_op;
|
|
||||||
long save_opcount = opcount;
|
|
||||||
const int save_reg_executing = reg_executing;
|
|
||||||
char_u *arg = NULL;
|
char_u *arg = NULL;
|
||||||
int l;
|
int l;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
@@ -8240,11 +8283,6 @@ static void ex_normal(exarg_T *eap)
|
|||||||
EMSG(_("E192: Recursive use of :normal too deep"));
|
EMSG(_("E192: Recursive use of :normal too deep"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++ex_normal_busy;
|
|
||||||
|
|
||||||
msg_scroll = FALSE; /* no msg scrolling in Normal mode */
|
|
||||||
restart_edit = 0; /* don't go to Insert mode */
|
|
||||||
p_im = FALSE; /* don't use 'insertmode' */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vgetc() expects a CSI and K_SPECIAL to have been escaped. Don't do
|
* vgetc() expects a CSI and K_SPECIAL to have been escaped. Don't do
|
||||||
@@ -8278,19 +8316,11 @@ static void ex_normal(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
ex_normal_busy++;
|
||||||
* Save the current typeahead. This is required to allow using ":normal"
|
if (save_current_state(&save_state)) {
|
||||||
* from an event handler and makes sure we don't hang when the argument
|
// Repeat the :normal command for each line in the range. When no
|
||||||
* ends with half a command.
|
// range given, execute it just once, without positioning the cursor
|
||||||
*/
|
// first.
|
||||||
save_typeahead(&tabuf);
|
|
||||||
// TODO(philix): after save_typeahead() this is always TRUE
|
|
||||||
if (tabuf.typebuf_valid) {
|
|
||||||
/*
|
|
||||||
* Repeat the :normal command for each line in the range. When no
|
|
||||||
* range given, execute it just once, without positioning the cursor
|
|
||||||
* first.
|
|
||||||
*/
|
|
||||||
do {
|
do {
|
||||||
if (eap->addr_count != 0) {
|
if (eap->addr_count != 0) {
|
||||||
curwin->w_cursor.lnum = eap->line1++;
|
curwin->w_cursor.lnum = eap->line1++;
|
||||||
@@ -8307,29 +8337,12 @@ static void ex_normal(exarg_T *eap)
|
|||||||
/* Might not return to the main loop when in an event handler. */
|
/* Might not return to the main loop when in an event handler. */
|
||||||
update_topline_cursor();
|
update_topline_cursor();
|
||||||
|
|
||||||
/* Restore the previous typeahead. */
|
restore_current_state(&save_state);
|
||||||
restore_typeahead(&tabuf);
|
|
||||||
|
|
||||||
--ex_normal_busy;
|
ex_normal_busy--;
|
||||||
msg_scroll = save_msg_scroll;
|
|
||||||
if (force_restart_edit) {
|
|
||||||
force_restart_edit = false;
|
|
||||||
} else {
|
|
||||||
// Some function (terminal_enter()) was aware of ex_normal and decided to
|
|
||||||
// override the value of restart_edit anyway.
|
|
||||||
restart_edit = save_restart_edit;
|
|
||||||
}
|
|
||||||
p_im = save_insertmode;
|
|
||||||
finish_op = save_finish_op;
|
|
||||||
opcount = save_opcount;
|
|
||||||
reg_executing = save_reg_executing;
|
|
||||||
msg_didout |= save_msg_didout; // don't reset msg_didout now
|
|
||||||
|
|
||||||
/* Restore the state (needed when called from a function executed for
|
|
||||||
* 'indentexpr'). Update the mouse and cursor, they may have changed. */
|
|
||||||
State = save_State;
|
|
||||||
setmouse();
|
setmouse();
|
||||||
ui_cursor_shape(); /* may show different cursor shape */
|
ui_cursor_shape(); // may show different cursor shape
|
||||||
xfree(arg);
|
xfree(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,6 +20,20 @@
|
|||||||
#define EXMODE_NORMAL 1
|
#define EXMODE_NORMAL 1
|
||||||
#define EXMODE_VIM 2
|
#define EXMODE_VIM 2
|
||||||
|
|
||||||
|
// Structure used to save the current state. Used when executing Normal mode
|
||||||
|
// commands while in any other mode.
|
||||||
|
typedef struct {
|
||||||
|
int save_msg_scroll;
|
||||||
|
int save_restart_edit;
|
||||||
|
int save_msg_didout;
|
||||||
|
int save_State;
|
||||||
|
int save_insertmode;
|
||||||
|
bool save_finish_op;
|
||||||
|
long save_opcount;
|
||||||
|
int save_reg_executing;
|
||||||
|
tasave_T tabuf;
|
||||||
|
} save_state_T;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "ex_docmd.h.generated.h"
|
# include "ex_docmd.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1216,7 +1216,7 @@ void save_typeahead(tasave_T *tp)
|
|||||||
{
|
{
|
||||||
tp->save_typebuf = typebuf;
|
tp->save_typebuf = typebuf;
|
||||||
alloc_typebuf();
|
alloc_typebuf();
|
||||||
tp->typebuf_valid = TRUE;
|
tp->typebuf_valid = true;
|
||||||
tp->old_char = old_char;
|
tp->old_char = old_char;
|
||||||
tp->old_mod_mask = old_mod_mask;
|
tp->old_mod_mask = old_mod_mask;
|
||||||
old_char = -1;
|
old_char = -1;
|
||||||
|
346
src/nvim/menu.c
346
src/nvim/menu.c
@@ -27,6 +27,8 @@
|
|||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
|
#include "nvim/screen.h"
|
||||||
|
#include "nvim/window.h"
|
||||||
|
|
||||||
#define MENUDEPTH 10 /* maximum depth of menus */
|
#define MENUDEPTH 10 /* maximum depth of menus */
|
||||||
|
|
||||||
@@ -46,6 +48,24 @@ static char_u e_notsubmenu[] = N_(
|
|||||||
static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
|
static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
|
||||||
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
|
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", 6) == 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.
|
/// Do the :menu command and relatives.
|
||||||
/// @param eap Ex command arguments
|
/// @param eap Ex command arguments
|
||||||
@@ -170,6 +190,12 @@ ex_menu(exarg_T *eap)
|
|||||||
goto theend;
|
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) {
|
if (enable != kNone) {
|
||||||
// Change sensitivity of the menu.
|
// Change sensitivity of the menu.
|
||||||
// For the PopUp menu, remove a menu for each mode separately.
|
// For the PopUp menu, remove a menu for each mode separately.
|
||||||
@@ -182,11 +208,11 @@ ex_menu(exarg_T *eap)
|
|||||||
for (i = 0; i < MENU_INDEX_TIP; ++i)
|
for (i = 0; i < MENU_INDEX_TIP; ++i)
|
||||||
if (modes & (1 << i)) {
|
if (modes & (1 << i)) {
|
||||||
p = popup_mode_name(menu_path, 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);
|
xfree(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
menu_enable_recurse(root_menu, menu_path, modes, enable);
|
menu_enable_recurse(*root_menu_ptr, menu_path, modes, enable);
|
||||||
} else if (unmenu) {
|
} else if (unmenu) {
|
||||||
/*
|
/*
|
||||||
* Delete menu(s).
|
* Delete menu(s).
|
||||||
@@ -201,13 +227,13 @@ ex_menu(exarg_T *eap)
|
|||||||
for (i = 0; i < MENU_INDEX_TIP; ++i)
|
for (i = 0; i < MENU_INDEX_TIP; ++i)
|
||||||
if (modes & (1 << i)) {
|
if (modes & (1 << i)) {
|
||||||
p = popup_mode_name(menu_path, 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);
|
xfree(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Careful: remove_menu() changes menu_path */
|
// Careful: remove_menu() changes menu_path
|
||||||
remove_menu(&root_menu, menu_path, modes, FALSE);
|
remove_menu(root_menu_ptr, menu_path, modes, false);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Add menu(s).
|
* Add menu(s).
|
||||||
@@ -244,6 +270,19 @@ ex_menu(exarg_T *eap)
|
|||||||
xfree(map_buf);
|
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();
|
ui_call_update_menu();
|
||||||
|
|
||||||
theend:
|
theend:
|
||||||
@@ -266,7 +305,6 @@ add_menu_path(
|
|||||||
{
|
{
|
||||||
char_u *path_name;
|
char_u *path_name;
|
||||||
int modes = menuarg->modes;
|
int modes = menuarg->modes;
|
||||||
vimmenu_T **menup;
|
|
||||||
vimmenu_T *menu = NULL;
|
vimmenu_T *menu = NULL;
|
||||||
vimmenu_T *parent;
|
vimmenu_T *parent;
|
||||||
vimmenu_T **lower_pri;
|
vimmenu_T **lower_pri;
|
||||||
@@ -285,7 +323,8 @@ add_menu_path(
|
|||||||
|
|
||||||
/* Make a copy so we can stuff around with it, since it could be const */
|
/* Make a copy so we can stuff around with it, since it could be const */
|
||||||
path_name = vim_strsave(menu_path);
|
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;
|
parent = NULL;
|
||||||
name = path_name;
|
name = path_name;
|
||||||
while (*name) {
|
while (*name) {
|
||||||
@@ -468,14 +507,16 @@ erret:
|
|||||||
/* Delete any empty submenu we added before discovering the error. Repeat
|
/* Delete any empty submenu we added before discovering the error. Repeat
|
||||||
* for higher levels. */
|
* for higher levels. */
|
||||||
while (parent != NULL && parent->children == NULL) {
|
while (parent != NULL && parent->children == NULL) {
|
||||||
if (parent->parent == NULL)
|
if (parent->parent == NULL) {
|
||||||
menup = &root_menu;
|
menup = root_menu_ptr;
|
||||||
else
|
} else {
|
||||||
menup = &parent->parent->children;
|
menup = &parent->parent->children;
|
||||||
for (; *menup != NULL && *menup != parent; menup = &((*menup)->next))
|
}
|
||||||
;
|
for (; *menup != NULL && *menup != parent; menup = &((*menup)->next)) {
|
||||||
if (*menup == NULL) /* safety check */
|
}
|
||||||
|
if (*menup == NULL) { // safety check
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
parent = parent->parent;
|
parent = parent->parent;
|
||||||
free_menu(menup);
|
free_menu(menup);
|
||||||
}
|
}
|
||||||
@@ -620,6 +661,14 @@ remove_menu (
|
|||||||
return OK;
|
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.
|
* Free the given menu structure and remove it from the linked list.
|
||||||
*/
|
*/
|
||||||
@@ -740,7 +789,7 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
|
|||||||
/// @return false if could not find path_name
|
/// @return false if could not find path_name
|
||||||
bool menu_get(char_u *const path_name, int modes, list_T *list)
|
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) {
|
if (!menu) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -802,10 +851,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.
|
/// 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)
|
static int show_menus(char_u *const path_name, int modes)
|
||||||
{
|
{
|
||||||
vimmenu_T *menu;
|
|
||||||
|
|
||||||
// First, find the (sub)menu with the given name
|
// 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) {
|
if (!menu) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -890,6 +937,7 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
|
|||||||
* Used when expanding menu names.
|
* Used when expanding menu names.
|
||||||
*/
|
*/
|
||||||
static vimmenu_T *expand_menu = NULL;
|
static vimmenu_T *expand_menu = NULL;
|
||||||
|
static vimmenu_T *expand_menu_alt = NULL;
|
||||||
static int expand_modes = 0x0;
|
static int expand_modes = 0x0;
|
||||||
static int expand_emenu; /* TRUE for ":emenu" command */
|
static int expand_emenu; /* TRUE for ":emenu" command */
|
||||||
|
|
||||||
@@ -940,14 +988,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
|
// ":popup" only uses menues, not entries
|
||||||
expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
|
expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
|
||||||
expand_emenu = (*cmd == 'e');
|
expand_emenu = (*cmd == 'e');
|
||||||
if (expand_menus && ascii_iswhite(*p))
|
if (expand_menus && ascii_iswhite(*p)) {
|
||||||
return NULL; /* TODO: check for next command? */
|
return NULL; // TODO(vim): check for next command?
|
||||||
if (*p == NUL) { /* Complete the menu name */
|
}
|
||||||
/*
|
if (*p == NUL) { // Complete the menu name
|
||||||
* With :unmenu, you only want to match menus for the appropriate mode.
|
bool try_alt_menu = true;
|
||||||
* 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.
|
// 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);
|
expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu);
|
||||||
if (!unmenu)
|
if (!unmenu)
|
||||||
expand_modes = MENU_ALL_MODES;
|
expand_modes = MENU_ALL_MODES;
|
||||||
@@ -976,6 +1025,10 @@ char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forc
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
menu = menu->next;
|
menu = menu->next;
|
||||||
|
if (menu == NULL && try_alt_menu) {
|
||||||
|
menu = curwin->w_winbar;
|
||||||
|
try_alt_menu = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (menu == NULL) {
|
if (menu == NULL) {
|
||||||
/* No menu found with the name we were looking for */
|
/* No menu found with the name we were looking for */
|
||||||
@@ -984,14 +1037,21 @@ char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forc
|
|||||||
}
|
}
|
||||||
name = p;
|
name = p;
|
||||||
menu = menu->children;
|
menu = menu->children;
|
||||||
|
try_alt_menu = false;
|
||||||
}
|
}
|
||||||
xfree(path_name);
|
xfree(path_name);
|
||||||
|
|
||||||
xp->xp_context = expand_menus ? EXPAND_MENUNAMES : EXPAND_MENUS;
|
xp->xp_context = expand_menus ? EXPAND_MENUNAMES : EXPAND_MENUS;
|
||||||
xp->xp_pattern = after_dot;
|
xp->xp_pattern = after_dot;
|
||||||
expand_menu = menu;
|
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;
|
xp->xp_context = EXPAND_NOTHING;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1002,19 +1062,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)
|
char_u *get_menu_name(expand_T *xp, int idx)
|
||||||
{
|
{
|
||||||
static vimmenu_T *menu = NULL;
|
static vimmenu_T *menu = NULL;
|
||||||
|
static bool did_alt_menu = false;
|
||||||
char_u *str;
|
char_u *str;
|
||||||
static int should_advance = FALSE;
|
static int should_advance = FALSE;
|
||||||
|
|
||||||
if (idx == 0) { /* first call: start at first item */
|
if (idx == 0) { /* first call: start at first item */
|
||||||
menu = expand_menu;
|
menu = expand_menu;
|
||||||
should_advance = FALSE;
|
did_alt_menu = false;
|
||||||
|
should_advance = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip PopUp[nvoci]. */
|
/* Skip PopUp[nvoci]. */
|
||||||
while (menu != NULL && (menu_is_hidden(menu->dname)
|
while (menu != NULL && (menu_is_hidden(menu->dname)
|
||||||
|| menu_is_separator(menu->dname)
|
|| menu_is_separator(menu->dname)
|
||||||
|| menu->children == NULL))
|
|| menu->children == NULL)) {
|
||||||
menu = menu->next;
|
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 */
|
if (menu == NULL) /* at end of linked list */
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1030,9 +1097,14 @@ char_u *get_menu_name(expand_T *xp, int idx)
|
|||||||
else
|
else
|
||||||
str = (char_u *)"";
|
str = (char_u *)"";
|
||||||
|
|
||||||
if (should_advance)
|
if (should_advance) {
|
||||||
/* Advance to next menu entry. */
|
// Advance to next menu entry.
|
||||||
menu = menu->next;
|
menu = menu->next;
|
||||||
|
if (menu == NULL && !did_alt_menu) {
|
||||||
|
menu = expand_menu_alt;
|
||||||
|
did_alt_menu = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
should_advance = !should_advance;
|
should_advance = !should_advance;
|
||||||
|
|
||||||
@@ -1046,6 +1118,7 @@ char_u *get_menu_name(expand_T *xp, int idx)
|
|||||||
char_u *get_menu_names(expand_T *xp, int idx)
|
char_u *get_menu_names(expand_T *xp, int idx)
|
||||||
{
|
{
|
||||||
static vimmenu_T *menu = NULL;
|
static vimmenu_T *menu = NULL;
|
||||||
|
static bool did_alt_menu = false;
|
||||||
#define TBUFFER_LEN 256
|
#define TBUFFER_LEN 256
|
||||||
static char_u tbuffer[TBUFFER_LEN]; /*hack*/
|
static char_u tbuffer[TBUFFER_LEN]; /*hack*/
|
||||||
char_u *str;
|
char_u *str;
|
||||||
@@ -1053,16 +1126,21 @@ char_u *get_menu_names(expand_T *xp, int idx)
|
|||||||
|
|
||||||
if (idx == 0) { /* first call: start at first item */
|
if (idx == 0) { /* first call: start at first item */
|
||||||
menu = expand_menu;
|
menu = expand_menu;
|
||||||
should_advance = FALSE;
|
did_alt_menu = false;
|
||||||
|
should_advance = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip Browse-style entries, popup menus and separators. */
|
/* Skip Browse-style entries, popup menus and separators. */
|
||||||
while (menu != NULL
|
while (menu != NULL
|
||||||
&& ( menu_is_hidden(menu->dname)
|
&& (menu_is_hidden(menu->dname)
|
||||||
|| (expand_emenu && menu_is_separator(menu->dname))
|
|| (expand_emenu && menu_is_separator(menu->dname))
|
||||||
|| menu->dname[STRLEN(menu->dname) - 1] == '.'
|
|| menu->dname[STRLEN(menu->dname) - 1] == '.')) {
|
||||||
))
|
|
||||||
menu = menu->next;
|
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 */
|
if (menu == NULL) /* at end of linked list */
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1092,9 +1170,14 @@ char_u *get_menu_names(expand_T *xp, int idx)
|
|||||||
} else
|
} else
|
||||||
str = (char_u *)"";
|
str = (char_u *)"";
|
||||||
|
|
||||||
if (should_advance)
|
if (should_advance) {
|
||||||
/* Advance to next menu entry. */
|
// Advance to next menu entry.
|
||||||
menu = menu->next;
|
menu = menu->next;
|
||||||
|
if (menu == NULL && !did_alt_menu) {
|
||||||
|
menu = expand_menu_alt;
|
||||||
|
did_alt_menu = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
should_advance = !should_advance;
|
should_advance = !should_advance;
|
||||||
|
|
||||||
@@ -1279,29 +1362,27 @@ static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext)
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true if "name" can be a menu in the MenuBar.
|
||||||
* Return TRUE if "name" can be a menu in the MenuBar.
|
bool menu_is_menubar(const char_u *const name)
|
||||||
*/
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
||||||
int menu_is_menubar(char_u *name)
|
|
||||||
{
|
{
|
||||||
return !menu_is_popup(name)
|
return !menu_is_popup(name)
|
||||||
&& !menu_is_toolbar(name)
|
&& !menu_is_toolbar(name)
|
||||||
|
&& !menu_is_winbar(name)
|
||||||
&& *name != MNU_HIDDEN_CHAR;
|
&& *name != MNU_HIDDEN_CHAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Return true if "name" is a popup menu name.
|
||||||
* Return TRUE if "name" is a popup menu name.
|
bool menu_is_popup(const char_u *const name)
|
||||||
*/
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
||||||
int menu_is_popup(char_u *name)
|
|
||||||
{
|
{
|
||||||
return STRNCMP(name, "PopUp", 5) == 0;
|
return STRNCMP(name, "PopUp", 5) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
// Return true if "name" is a toolbar menu name.
|
||||||
* Return TRUE if "name" is a toolbar menu name.
|
bool menu_is_toolbar(const char_u *const name)
|
||||||
*/
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
||||||
int menu_is_toolbar(char_u *name)
|
|
||||||
{
|
{
|
||||||
return STRNCMP(name, "ToolBar", 7) == 0;
|
return STRNCMP(name, "ToolBar", 7) == 0;
|
||||||
}
|
}
|
||||||
@@ -1325,53 +1406,15 @@ static int menu_is_hidden(char_u *name)
|
|||||||
|| (menu_is_popup(name) && name[5] != NUL);
|
|| (menu_is_popup(name) && name[5] != NUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Execute "menu". Use by ":emenu" and the window toolbar.
|
||||||
* Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy and
|
// "eap" is NULL for the window toolbar.
|
||||||
* execute it.
|
static void execute_menu(const exarg_T *eap, vimmenu_T *menu)
|
||||||
*/
|
FUNC_ATTR_NONNULL_ARG(2)
|
||||||
void ex_emenu(exarg_T *eap)
|
|
||||||
{
|
{
|
||||||
vimmenu_T *menu;
|
int idx = -1;
|
||||||
char_u *name;
|
char_u *mode;
|
||||||
char_u *saved_name;
|
|
||||||
char_u *p;
|
|
||||||
int idx;
|
|
||||||
char_u *mode;
|
|
||||||
|
|
||||||
saved_name = vim_strsave(eap->arg);
|
// Use the Insert mode entry when returning to Insert mode.
|
||||||
|
|
||||||
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. */
|
|
||||||
if (((State & INSERT) || restart_edit) && !current_sctx.sc_sid) {
|
if (((State & INSERT) || restart_edit) && !current_sctx.sc_sid) {
|
||||||
mode = (char_u *)"Insert";
|
mode = (char_u *)"Insert";
|
||||||
idx = MENU_INDEX_INSERT;
|
idx = MENU_INDEX_INSERT;
|
||||||
@@ -1384,7 +1427,7 @@ void ex_emenu(exarg_T *eap)
|
|||||||
* is. Just execute the visual binding for the menu. */
|
* is. Just execute the visual binding for the menu. */
|
||||||
mode = (char_u *)"Visual";
|
mode = (char_u *)"Visual";
|
||||||
idx = MENU_INDEX_VISUAL;
|
idx = MENU_INDEX_VISUAL;
|
||||||
} else if (eap->addr_count) {
|
} else if (eap != NULL && eap->addr_count) {
|
||||||
pos_T tpos;
|
pos_T tpos;
|
||||||
|
|
||||||
mode = (char_u *)"Visual";
|
mode = (char_u *)"Visual";
|
||||||
@@ -1422,9 +1465,13 @@ void ex_emenu(exarg_T *eap)
|
|||||||
|
|
||||||
/* Adjust the cursor to make sure it is in the correct pos
|
/* Adjust the cursor to make sure it is in the correct pos
|
||||||
* for exclusive mode */
|
* for exclusive mode */
|
||||||
if (*p_sel == 'e' && gchar_cursor() != NUL)
|
if (*p_sel == 'e' && gchar_cursor() != NUL) {
|
||||||
++curwin->w_cursor.col;
|
curwin->w_cursor.col++;
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the WinBar menu always use the Normal mode menu.
|
||||||
|
if (idx == -1 || eap == NULL) {
|
||||||
mode = (char_u *)"Normal";
|
mode = (char_u *)"Normal";
|
||||||
idx = MENU_INDEX_NORMAL;
|
idx = MENU_INDEX_NORMAL;
|
||||||
}
|
}
|
||||||
@@ -1432,19 +1479,114 @@ void ex_emenu(exarg_T *eap)
|
|||||||
assert(idx != MENU_INDEX_INVALID);
|
assert(idx != MENU_INDEX_INVALID);
|
||||||
if (menu->strings[idx] != NULL) {
|
if (menu->strings[idx] != NULL) {
|
||||||
// When executing a script or function execute the commands right now.
|
// When executing a script or function execute the commands right now.
|
||||||
|
// Also for the window toolbar
|
||||||
// Otherwise put them in the typeahead buffer.
|
// 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],
|
save_state_T save_state;
|
||||||
menu->silent[idx]);
|
|
||||||
|
ex_normal_busy++;
|
||||||
|
if (save_current_state(&save_state)) {
|
||||||
|
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
|
||||||
|
menu->silent[idx]);
|
||||||
|
}
|
||||||
|
restore_current_state(&save_state);
|
||||||
|
ex_normal_busy--;
|
||||||
} else {
|
} else {
|
||||||
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0, true,
|
ins_typebuf(menu->strings[idx], menu->noremap[idx], 0, true,
|
||||||
menu->silent[idx]);
|
menu->silent[idx]);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (eap != NULL) {
|
||||||
EMSG2(_("E335: Menu not defined for %s mode"), mode);
|
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;
|
||||||
|
const pos_T save_visual = VIsual;
|
||||||
|
const int save_visual_active = VIsual_active;
|
||||||
|
const int save_visual_select = VIsual_select;
|
||||||
|
const int save_visual_reselect = VIsual_reselect;
|
||||||
|
const int save_visual_mode = VIsual_mode;
|
||||||
|
|
||||||
|
if (wp != curwin) {
|
||||||
|
// Clicking in the window toolbar of a not-current window.
|
||||||
|
// Make that window the current one and save Visual mode.
|
||||||
|
save_curwin = curwin;
|
||||||
|
VIsual_active = false;
|
||||||
|
curwin = wp;
|
||||||
|
curbuf = curwin->w_buffer;
|
||||||
|
check_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: the command might close the current window.
|
||||||
|
execute_menu(NULL, item->wb_menu);
|
||||||
|
|
||||||
|
if (save_curwin != NULL && win_valid(save_curwin)) {
|
||||||
|
curwin = save_curwin;
|
||||||
|
curbuf = curwin->w_buffer;
|
||||||
|
VIsual = save_visual;
|
||||||
|
VIsual_active = save_visual_active;
|
||||||
|
VIsual_select = save_visual_select;
|
||||||
|
VIsual_reselect = save_visual_reselect;
|
||||||
|
VIsual_mode = save_visual_mode;
|
||||||
|
}
|
||||||
|
if (!win_valid(wp)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translation of menu names. Just a simple lookup table.
|
* Translation of menu names. Just a simple lookup table.
|
||||||
*/
|
*/
|
||||||
|
@@ -6,18 +6,6 @@
|
|||||||
#include "nvim/types.h" // for char_u and expand_T
|
#include "nvim/types.h" // for char_u and expand_T
|
||||||
#include "nvim/ex_cmds_defs.h" // for exarg_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
|
/// 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
|
/// Start a menu name with this to not include it on the main menu bar
|
||||||
#define MNU_HIDDEN_CHAR ']'
|
#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
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "menu.h.generated.h"
|
# include "menu.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -60,6 +60,7 @@ int jump_to_mouse(int flags,
|
|||||||
{
|
{
|
||||||
static int on_status_line = 0; // #lines below bottom of window
|
static int on_status_line = 0; // #lines below bottom of window
|
||||||
static int on_sep_line = 0; // on separator right of window
|
static int on_sep_line = 0; // on separator right of window
|
||||||
|
static bool in_winbar = false;
|
||||||
static int prev_row = -1;
|
static int prev_row = -1;
|
||||||
static int prev_col = -1;
|
static int prev_col = -1;
|
||||||
static win_T *dragwin = NULL; // window being dragged
|
static win_T *dragwin = NULL; // window being dragged
|
||||||
@@ -93,10 +94,24 @@ int jump_to_mouse(int flags,
|
|||||||
retnomove:
|
retnomove:
|
||||||
// before moving the cursor for a left click which is NOT in a status
|
// before moving the cursor for a left click which is NOT in a status
|
||||||
// line, stop Visual mode
|
// line, stop Visual mode
|
||||||
if (on_status_line)
|
if (on_status_line) {
|
||||||
return IN_STATUS_LINE;
|
return IN_STATUS_LINE;
|
||||||
if (on_sep_line)
|
}
|
||||||
|
if (on_sep_line) {
|
||||||
return IN_SEP_LINE;
|
return IN_SEP_LINE;
|
||||||
|
}
|
||||||
|
if (in_winbar) {
|
||||||
|
// A quick second click may arrive as a double-click, but we use it
|
||||||
|
// as a second click in the WinBar.
|
||||||
|
if ((mod_mask & MOD_MASK_MULTI_CLICK) && !(flags & MOUSE_RELEASED)) {
|
||||||
|
wp = mouse_find_win(&grid, &row, &col);
|
||||||
|
if (wp == NULL) {
|
||||||
|
return IN_UNKNOWN;
|
||||||
|
}
|
||||||
|
winbar_click(wp, col);
|
||||||
|
}
|
||||||
|
return IN_OTHER_WIN | MOUSE_WINBAR;
|
||||||
|
}
|
||||||
if (flags & MOUSE_MAY_STOP_VIS) {
|
if (flags & MOUSE_MAY_STOP_VIS) {
|
||||||
end_visual_mode();
|
end_visual_mode();
|
||||||
redraw_curbuf_later(INVERTED); // delete the inversion
|
redraw_curbuf_later(INVERTED); // delete the inversion
|
||||||
@@ -134,6 +149,16 @@ retnomove:
|
|||||||
}
|
}
|
||||||
fdc = win_fdccol_count(wp);
|
fdc = win_fdccol_count(wp);
|
||||||
dragwin = NULL;
|
dragwin = NULL;
|
||||||
|
|
||||||
|
if (row == -1) {
|
||||||
|
// A click in the window toolbar does not enter another window or
|
||||||
|
// change Visual highlighting.
|
||||||
|
winbar_click(wp, col);
|
||||||
|
in_winbar = true;
|
||||||
|
return IN_OTHER_WIN | MOUSE_WINBAR;
|
||||||
|
}
|
||||||
|
in_winbar = false;
|
||||||
|
|
||||||
// winpos and height may change in win_enter()!
|
// winpos and height may change in win_enter()!
|
||||||
if (grid == DEFAULT_GRID_HANDLE && row >= wp->w_height) {
|
if (grid == DEFAULT_GRID_HANDLE && row >= wp->w_height) {
|
||||||
// In (or below) status line
|
// In (or below) status line
|
||||||
@@ -223,6 +248,9 @@ retnomove:
|
|||||||
did_drag |= count;
|
did_drag |= count;
|
||||||
}
|
}
|
||||||
return IN_SEP_LINE; // Cursor didn't move
|
return IN_SEP_LINE; // Cursor didn't move
|
||||||
|
} else if (in_winbar) {
|
||||||
|
// After a click on the window toolbar don't start Visual mode.
|
||||||
|
return IN_OTHER_WIN | MOUSE_WINBAR;
|
||||||
} else {
|
} else {
|
||||||
// keep_window_focus must be true
|
// keep_window_focus must be true
|
||||||
// before moving the cursor for a left click, stop Visual mode
|
// before moving the cursor for a left click, stop Visual mode
|
||||||
@@ -471,6 +499,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp)
|
|||||||
// exist.
|
// exist.
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
if (wp == fp->fr_win) {
|
if (wp == fp->fr_win) {
|
||||||
|
*rowp -= wp->w_winbar_height;
|
||||||
return wp;
|
return wp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#define CURSOR_MOVED 0x100
|
#define CURSOR_MOVED 0x100
|
||||||
#define MOUSE_FOLD_CLOSE 0x200 // clicked on '-' in fold column
|
#define MOUSE_FOLD_CLOSE 0x200 // clicked on '-' in fold column
|
||||||
#define MOUSE_FOLD_OPEN 0x400 // clicked on '+' in fold column
|
#define MOUSE_FOLD_OPEN 0x400 // clicked on '+' in fold column
|
||||||
|
#define MOUSE_WINBAR 0x800 // in window toolbar
|
||||||
|
|
||||||
// flags for jump_to_mouse()
|
// flags for jump_to_mouse()
|
||||||
#define MOUSE_FOCUS 0x01 // need to stay in this window
|
#define MOUSE_FOCUS 0x01 // need to stay in this window
|
||||||
|
@@ -2561,7 +2561,14 @@ do_mouse (
|
|||||||
* JUMP!
|
* JUMP!
|
||||||
*/
|
*/
|
||||||
jump_flags = jump_to_mouse(jump_flags,
|
jump_flags = jump_to_mouse(jump_flags,
|
||||||
oap == NULL ? NULL : &(oap->inclusive), which_button);
|
oap == NULL ? NULL : &(oap->inclusive),
|
||||||
|
which_button);
|
||||||
|
|
||||||
|
// A click in the window toolbar has no side effects.
|
||||||
|
if (jump_flags & MOUSE_WINBAR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
moved = (jump_flags & CURSOR_MOVED);
|
moved = (jump_flags & CURSOR_MOVED);
|
||||||
in_status_line = (jump_flags & IN_STATUS_LINE);
|
in_status_line = (jump_flags & IN_STATUS_LINE);
|
||||||
in_sep_line = (jump_flags & IN_SEP_LINE);
|
in_sep_line = (jump_flags & IN_SEP_LINE);
|
||||||
|
@@ -1741,6 +1741,31 @@ static int advance_color_col(int vcol, int **color_cols)
|
|||||||
return **color_cols >= 0;
|
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
|
// Compute the width of the foldcolumn. Based on 'foldcolumn' and how much
|
||||||
// space is available for window "wp", minus "col".
|
// space is available for window "wp", minus "col".
|
||||||
static int compute_foldcolumn(win_T *wp, int 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".
|
// 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
|
// Right-left text is put in columns 0 - number-col, normal text is put
|
||||||
// in columns number-col - window-width.
|
// in columns number-col - window-width.
|
||||||
int idx;
|
col = text_to_screenline(wp, text, col, off);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the rest of the line with the fold filler */
|
/* Fill the rest of the line with the fold filler */
|
||||||
if (wp->w_p_rl)
|
if (wp->w_p_rl)
|
||||||
|
@@ -1112,7 +1112,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
|||||||
|
|
||||||
// add a status line when p_ls == 1 and splitting the first window
|
// add a status line when p_ls == 1 and splitting the first window
|
||||||
if (one_nonfloat() && p_ls == 1 && oldwin->w_status_height == 0) {
|
if (one_nonfloat() && p_ls == 1 && oldwin->w_status_height == 0) {
|
||||||
if (oldwin->w_height <= p_wmh && new_in_layout) {
|
if ((oldwin->w_height + oldwin->w_winbar_height) <= p_wmh
|
||||||
|
&& new_in_layout) {
|
||||||
EMSG(_(e_noroom));
|
EMSG(_(e_noroom));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@@ -1209,7 +1210,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
|||||||
* height.
|
* height.
|
||||||
*/
|
*/
|
||||||
// Current window requires at least 1 space.
|
// Current window requires at least 1 space.
|
||||||
wmh1 = (p_wmh == 0 ? 1 : p_wmh);
|
wmh1 = (p_wmh == 0 ? 1 : p_wmh) + curwin->w_winbar_height;
|
||||||
needed = wmh1 + STATUS_HEIGHT;
|
needed = wmh1 + STATUS_HEIGHT;
|
||||||
if (flags & WSP_ROOM) {
|
if (flags & WSP_ROOM) {
|
||||||
needed += p_wh - wmh1;
|
needed += p_wh - wmh1;
|
||||||
@@ -1407,12 +1408,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
|||||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||||
/* set height and row of new window to full height */
|
/* set height and row of new window to full height */
|
||||||
wp->w_winrow = tabline_height();
|
wp->w_winrow = tabline_height();
|
||||||
win_new_height(wp, curfrp->fr_height - (p_ls > 0));
|
win_new_height(wp, curfrp->fr_height - (p_ls > 0) - wp->w_winbar_height);
|
||||||
wp->w_status_height = (p_ls > 0);
|
wp->w_status_height = (p_ls > 0);
|
||||||
} else {
|
} else {
|
||||||
/* height and row of new window is same as current window */
|
/* height and row of new window is same as current window */
|
||||||
wp->w_winrow = oldwin->w_winrow;
|
wp->w_winrow = oldwin->w_winrow;
|
||||||
win_new_height(wp, oldwin->w_height);
|
win_new_height(wp, oldwin->w_height + oldwin->w_winbar_height);
|
||||||
wp->w_status_height = oldwin->w_status_height;
|
wp->w_status_height = oldwin->w_status_height;
|
||||||
}
|
}
|
||||||
frp->fr_height = curfrp->fr_height;
|
frp->fr_height = curfrp->fr_height;
|
||||||
@@ -1459,7 +1460,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
|||||||
* one row for the status line */
|
* one row for the status line */
|
||||||
win_new_height(wp, new_size);
|
win_new_height(wp, new_size);
|
||||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||||
int new_fr_height = curfrp->fr_height - new_size;
|
int new_fr_height = curfrp->fr_height - new_size + wp->w_winbar_height;
|
||||||
|
|
||||||
if (!((flags & WSP_BOT) && p_ls == 0)) {
|
if (!((flags & WSP_BOT) && p_ls == 0)) {
|
||||||
new_fr_height -= STATUS_HEIGHT;
|
new_fr_height -= STATUS_HEIGHT;
|
||||||
@@ -1472,8 +1473,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
|||||||
wp->w_winrow = oldwin->w_winrow;
|
wp->w_winrow = oldwin->w_winrow;
|
||||||
wp->w_status_height = STATUS_HEIGHT;
|
wp->w_status_height = STATUS_HEIGHT;
|
||||||
oldwin->w_winrow += wp->w_height + STATUS_HEIGHT;
|
oldwin->w_winrow += wp->w_height + STATUS_HEIGHT;
|
||||||
} else { /* new window below current one */
|
} else { // new window below current one
|
||||||
wp->w_winrow = oldwin->w_winrow + oldwin->w_height + STATUS_HEIGHT;
|
wp->w_winrow = oldwin->w_winrow + oldwin->w_height
|
||||||
|
+ STATUS_HEIGHT + oldwin->w_winbar_height;
|
||||||
wp->w_status_height = oldwin->w_status_height;
|
wp->w_status_height = oldwin->w_status_height;
|
||||||
if (!(flags & WSP_BOT)) {
|
if (!(flags & WSP_BOT)) {
|
||||||
oldwin->w_status_height = STATUS_HEIGHT;
|
oldwin->w_status_height = STATUS_HEIGHT;
|
||||||
@@ -1689,8 +1691,9 @@ make_windows (
|
|||||||
maxcount = (curwin->w_width + curwin->w_vsep_width
|
maxcount = (curwin->w_width + curwin->w_vsep_width
|
||||||
- (p_wiw - p_wmw)) / (p_wmw + 1);
|
- (p_wiw - p_wmw)) / (p_wmw + 1);
|
||||||
} else {
|
} else {
|
||||||
/* Each window needs at least 'winminheight' lines and a status line. */
|
// Each window needs at least 'winminheight' lines and a status line.
|
||||||
maxcount = (curwin->w_height + curwin->w_status_height
|
maxcount = (curwin->w_height + curwin->w_winbar_height
|
||||||
|
+ curwin->w_status_height
|
||||||
- (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT);
|
- (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3144,15 +3147,18 @@ frame_new_height (
|
|||||||
int wfh /* obey 'winfixheight' when there is a choice;
|
int wfh /* obey 'winfixheight' when there is a choice;
|
||||||
may cause the height not to be set */
|
may cause the height not to be set */
|
||||||
)
|
)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
frame_T *frp;
|
frame_T *frp;
|
||||||
int extra_lines;
|
int extra_lines;
|
||||||
int h;
|
int h;
|
||||||
|
|
||||||
if (topfrp->fr_win != NULL) {
|
if (topfrp->fr_win != NULL) {
|
||||||
/* Simple case: just one window. */
|
// Simple case: just one window.
|
||||||
win_new_height(topfrp->fr_win,
|
win_new_height(topfrp->fr_win,
|
||||||
height - topfrp->fr_win->w_status_height);
|
height
|
||||||
|
- topfrp->fr_win->w_status_height
|
||||||
|
- topfrp->fr_win->w_winbar_height);
|
||||||
} else if (topfrp->fr_layout == FR_ROW) {
|
} else if (topfrp->fr_layout == FR_ROW) {
|
||||||
do {
|
do {
|
||||||
// All frames in this row get the same new height.
|
// All frames in this row get the same new height.
|
||||||
@@ -3457,8 +3463,10 @@ static void frame_fix_width(win_T *wp)
|
|||||||
* Set frame height from the window it contains.
|
* Set frame height from the window it contains.
|
||||||
*/
|
*/
|
||||||
static void frame_fix_height(win_T *wp)
|
static void frame_fix_height(win_T *wp)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
wp->w_frame->fr_height = wp->w_height + wp->w_status_height;
|
wp->w_frame->fr_height =
|
||||||
|
wp->w_height + wp->w_status_height + wp->w_winbar_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3475,14 +3483,18 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin)
|
|||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (topfrp->fr_win != NULL) {
|
if (topfrp->fr_win != NULL) {
|
||||||
if (topfrp->fr_win == next_curwin)
|
if (topfrp->fr_win == next_curwin) {
|
||||||
m = p_wh + topfrp->fr_win->w_status_height;
|
m = p_wh + topfrp->fr_win->w_status_height;
|
||||||
else {
|
} else {
|
||||||
/* window: minimal height of the window plus status line */
|
// window: minimal height of the window plus status line
|
||||||
m = p_wmh + topfrp->fr_win->w_status_height;
|
m = p_wmh + topfrp->fr_win->w_status_height;
|
||||||
/* Current window is minimal one line high */
|
if (topfrp->fr_win == curwin && next_curwin == NULL) {
|
||||||
if (p_wmh == 0 && topfrp->fr_win == curwin && next_curwin == NULL)
|
// Current window is minimal one line high and WinBar is visible.
|
||||||
++m;
|
if (p_wmh == 0) {
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
m += curwin->w_winbar_height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (topfrp->fr_layout == FR_ROW) {
|
} else if (topfrp->fr_layout == FR_ROW) {
|
||||||
/* get the minimal height from each frame in this row */
|
/* get the minimal height from each frame in this row */
|
||||||
@@ -4782,6 +4794,7 @@ win_free (
|
|||||||
|
|
||||||
qf_free_all(wp);
|
qf_free_all(wp);
|
||||||
|
|
||||||
|
remove_winbar(wp);
|
||||||
|
|
||||||
xfree(wp->w_p_cc_cols);
|
xfree(wp->w_p_cc_cols);
|
||||||
|
|
||||||
@@ -5048,7 +5061,9 @@ static void frame_comp_pos(frame_T *topfrp, int *row, int *col)
|
|||||||
wp->w_redr_status = true;
|
wp->w_redr_status = true;
|
||||||
wp->w_pos_changed = true;
|
wp->w_pos_changed = true;
|
||||||
}
|
}
|
||||||
*row += wp->w_height + wp->w_status_height;
|
// WinBar will not show if the window height is zero
|
||||||
|
const int h = wp->w_height + wp->w_winbar_height + wp->w_status_height;
|
||||||
|
*row += h > topfrp->fr_height ? topfrp->fr_height : h;
|
||||||
*col += wp->w_width + wp->w_vsep_width;
|
*col += wp->w_width + wp->w_vsep_width;
|
||||||
} else {
|
} else {
|
||||||
startrow = *row;
|
startrow = *row;
|
||||||
@@ -5081,12 +5096,15 @@ void win_setheight(int height)
|
|||||||
void win_setheight_win(int height, win_T *win)
|
void win_setheight_win(int height, win_T *win)
|
||||||
{
|
{
|
||||||
if (win == curwin) {
|
if (win == curwin) {
|
||||||
/* Always keep current window at least one line high, even when
|
// Always keep current window at least one line high, even when
|
||||||
* 'winminheight' is zero. */
|
// 'winminheight' is zero.
|
||||||
if (height < p_wmh)
|
if (height < p_wmh) {
|
||||||
height = p_wmh;
|
height = p_wmh;
|
||||||
if (height == 0)
|
}
|
||||||
|
if (height == 0) {
|
||||||
height = 1;
|
height = 1;
|
||||||
|
}
|
||||||
|
height += curwin->w_winbar_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win->w_floating) {
|
if (win->w_floating) {
|
||||||
@@ -5183,7 +5201,7 @@ static void frame_setheight(frame_T *curfrp, int height)
|
|||||||
} else {
|
} else {
|
||||||
win_T *wp = lastwin_nofloating();
|
win_T *wp = lastwin_nofloating();
|
||||||
room_cmdline = Rows - p_ch - (wp->w_winrow
|
room_cmdline = Rows - p_ch - (wp->w_winrow
|
||||||
+ wp->w_height +
|
+ wp->w_height + wp->w_winbar_height +
|
||||||
wp->w_status_height);
|
wp->w_status_height);
|
||||||
if (room_cmdline < 0) {
|
if (room_cmdline < 0) {
|
||||||
room_cmdline = 0;
|
room_cmdline = 0;
|
||||||
@@ -5708,11 +5726,10 @@ void set_fraction(win_T *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Set the height of a window.
|
||||||
* 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
|
// This takes care of the things inside the window, not what happens to the
|
||||||
* window position, the frame or to other windows.
|
// window position, the frame or to other windows.
|
||||||
*/
|
|
||||||
void win_new_height(win_T *wp, int height)
|
void win_new_height(win_T *wp, int height)
|
||||||
{
|
{
|
||||||
// Don't want a negative height. Happens when splitting a tiny window.
|
// Don't want a negative height. Happens when splitting a tiny window.
|
||||||
|
Reference in New Issue
Block a user