aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2017-04-26 11:59:59 +0200
committerGitHub <noreply@github.com>2017-04-26 11:59:59 +0200
commit0b59f988f447e23af692d972a83989156c6aad02 (patch)
treee7fba1e2be738d0a89d9aafdfb1ae0c92586af05 /src
parent7e571bca5d5e00e9e33e266b983a48bb4014183f (diff)
parent6944abad2f3f443027af1966a2a310034d2179b2 (diff)
downloadrneovim-0b59f988f447e23af692d972a83989156c6aad02.tar.gz
rneovim-0b59f988f447e23af692d972a83989156c6aad02.tar.bz2
rneovim-0b59f988f447e23af692d972a83989156c6aad02.zip
Merge #6583 from justinmk/ui-tabline
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui.c39
-rw-r--r--src/nvim/popupmnu.c9
-rw-r--r--src/nvim/screen.c25
-rw-r--r--src/nvim/tui/tui.c4
-rw-r--r--src/nvim/ui.c27
-rw-r--r--src/nvim/ui.h11
-rw-r--r--src/nvim/ui_bridge.c5
-rw-r--r--src/nvim/window.c4
8 files changed, 103 insertions, 21 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index f0da0d1812..3c0e8bc049 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -68,7 +68,6 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
ui->width = (int)width;
ui->height = (int)height;
ui->rgb = true;
- ui->pum_external = false;
ui->resize = remote_ui_resize;
ui->clear = remote_ui_clear;
ui->eol_clear = remote_ui_eol_clear;
@@ -95,6 +94,8 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
ui->set_icon = remote_ui_set_icon;
ui->event = remote_ui_event;
+ memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
+
for (size_t i = 0; i < options.size; i++) {
ui_set_option(ui, options.items[i].key, options.items[i].value, err);
if (ERROR_SET(err)) {
@@ -170,23 +171,47 @@ void nvim_ui_set_option(uint64_t channel_id, String name,
}
}
-static void ui_set_option(UI *ui, String name, Object value, Error *error) {
- if (strcmp(name.data, "rgb") == 0) {
+static void ui_set_option(UI *ui, String name, Object value, Error *error)
+{
+#define UI_EXT_OPTION(o, e) \
+ do { \
+ if (strequal(name.data, #o)) { \
+ if (value.type != kObjectTypeBoolean) { \
+ api_set_error(error, kErrorTypeValidation, #o " must be a Boolean"); \
+ return; \
+ } \
+ ui->ui_ext[(e)] = value.data.boolean; \
+ return; \
+ } \
+ } while (0)
+
+ if (strequal(name.data, "rgb")) {
if (value.type != kObjectTypeBoolean) {
api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean");
return;
}
ui->rgb = value.data.boolean;
- } else if (strcmp(name.data, "popupmenu_external") == 0) {
+ return;
+ }
+
+ UI_EXT_OPTION(ext_cmdline, kUICmdline);
+ UI_EXT_OPTION(ext_popupmenu, kUIPopupmenu);
+ UI_EXT_OPTION(ext_tabline, kUITabline);
+ UI_EXT_OPTION(ext_wildmenu, kUIWildmenu);
+
+ if (strequal(name.data, "popupmenu_external")) {
+ // LEGACY: Deprecated option, use `ui_ext` instead.
if (value.type != kObjectTypeBoolean) {
api_set_error(error, kErrorTypeValidation,
"popupmenu_external must be a Boolean");
return;
}
- ui->pum_external = value.data.boolean;
- } else {
- api_set_error(error, kErrorTypeValidation, "No such ui option");
+ ui->ui_ext[kUIPopupmenu] = value.data.boolean;
+ return;
}
+
+ api_set_error(error, kErrorTypeValidation, "No such ui option");
+#undef UI_EXT_OPTION
}
static void push_call(UI *ui, char *name, Array args)
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 6e81c5a171..b8650d8c62 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -41,9 +41,7 @@ static int pum_row; // top row of pum
static int pum_col; // left column of pum
static bool pum_is_visible = false;
-
static bool pum_external = false;
-static bool pum_wants_external = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "popupmnu.c.generated.h"
@@ -80,7 +78,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed)
if (!pum_is_visible) {
// To keep the code simple, we only allow changing the
// draw mode when the popup menu is not being displayed
- pum_external = pum_wants_external;
+ pum_external = ui_is_external(kUIPopupmenu);
}
redo:
@@ -751,8 +749,3 @@ int pum_get_height(void)
{
return pum_height;
}
-
-void pum_set_external(bool external)
-{
- pum_wants_external = external;
-}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 10dc86d5fa..de24156579 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -132,6 +132,7 @@
#include "nvim/version.h"
#include "nvim/window.h"
#include "nvim/os/time.h"
+#include "nvim/api/private/helpers.h"
#define MB_FILLER_CHAR '<' /* character used when a double-width character
* doesn't fit. */
@@ -6887,6 +6888,10 @@ static void draw_tabline(void)
}
redraw_tabline = false;
+ if (ui_is_external(kUITabline)) {
+ ui_ext_tabline_update();
+ return;
+ }
if (tabline_height() < 1)
return;
@@ -7027,6 +7032,26 @@ static void draw_tabline(void)
redraw_tabline = FALSE;
}
+void ui_ext_tabline_update(void)
+{
+ Array args = ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(curtab->handle));
+ Array tabs = ARRAY_DICT_INIT;
+ FOR_ALL_TABS(tp) {
+ Dictionary tab_info = ARRAY_DICT_INIT;
+ PUT(tab_info, "tab", TABPAGE_OBJ(tp->handle));
+
+ win_T *cwp = (tp == curtab) ? curwin : tp->tp_curwin;
+ get_trans_bufname(cwp->w_buffer);
+ PUT(tab_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff)));
+
+ ADD(tabs, DICTIONARY_OBJ(tab_info));
+ }
+ ADD(args, ARRAY_OBJ(tabs));
+
+ ui_event("tabline_update", args);
+}
+
/*
* Get buffer name for "buf" into NameBuff[].
* Takes care of special buffer names and translates special characters.
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index e1b97f5306..21abc19c47 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -109,7 +109,6 @@ UI *tui_start(void)
UI *ui = xcalloc(1, sizeof(UI));
ui->stop = tui_stop;
ui->rgb = p_tgc;
- ui->pum_external = false;
ui->resize = tui_resize;
ui->clear = tui_clear;
ui->eol_clear = tui_eol_clear;
@@ -135,6 +134,9 @@ UI *tui_start(void)
ui->set_title = tui_set_title;
ui->set_icon = tui_set_icon;
ui->event = tui_event;
+
+ memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
+
return ui_bridge_attach(ui, tui_main, tui_scheduler);
}
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 69916fa4cd..713dffb46c 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -47,6 +47,7 @@
#define MAX_UI_COUNT 16
static UI *uis[MAX_UI_COUNT];
+static bool ui_ext[UI_WIDGETS] = { 0 };
static size_t ui_count = 0;
static int row = 0, col = 0;
static struct {
@@ -166,18 +167,25 @@ void ui_refresh(void)
}
int width = INT_MAX, height = INT_MAX;
- bool pum_external = true;
+ bool ext_widgets[UI_WIDGETS];
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ ext_widgets[i] = true;
+ }
for (size_t i = 0; i < ui_count; i++) {
UI *ui = uis[i];
width = MIN(ui->width, width);
height = MIN(ui->height, height);
- pum_external &= ui->pum_external;
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ ext_widgets[i] &= ui->ui_ext[i];
+ }
}
row = col = 0;
screen_resize(width, height);
- pum_set_external(pum_external);
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ ui_set_external(i, ext_widgets[i]);
+ }
ui_mode_info_set();
old_mode_idx = -1;
ui_cursor_shape();
@@ -557,3 +565,16 @@ void ui_cursor_shape(void)
conceal_check_cursur_line();
}
+/// Returns true if `widget` is externalized.
+bool ui_is_external(UIWidget widget)
+{
+ return ui_ext[widget];
+}
+
+/// Sets `widget` as "external".
+/// Such widgets are not drawn by Nvim; external UIs are expected to handle
+/// higher-level UI events and present the data.
+void ui_set_external(UIWidget widget, bool external)
+{
+ ui_ext[widget] = external;
+}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index fcf52ac9e1..9338ab3ea3 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -8,6 +8,14 @@
#include "api/private/defs.h"
#include "nvim/buffer_defs.h"
+typedef enum {
+ kUICmdline = 0,
+ kUIPopupmenu,
+ kUITabline,
+ kUIWildmenu,
+} UIWidget;
+#define UI_WIDGETS (kUIWildmenu + 1)
+
typedef struct {
bool bold, underline, undercurl, italic, reverse;
int foreground, background, special;
@@ -16,7 +24,8 @@ typedef struct {
typedef struct ui_t UI;
struct ui_t {
- bool rgb, pum_external;
+ bool rgb;
+ bool ui_ext[UI_WIDGETS]; ///< Externalized widgets
int width, height;
void *data;
void (*resize)(UI *ui, int rows, int columns);
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 5697c765ba..b7b12ae39e 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -57,7 +57,6 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
UIBridgeData *rv = xcalloc(1, sizeof(UIBridgeData));
rv->ui = ui;
rv->bridge.rgb = ui->rgb;
- rv->bridge.pum_external = ui->pum_external;
rv->bridge.stop = ui_bridge_stop;
rv->bridge.resize = ui_bridge_resize;
rv->bridge.clear = ui_bridge_clear;
@@ -85,6 +84,10 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
rv->bridge.set_icon = ui_bridge_set_icon;
rv->scheduler = scheduler;
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ rv->bridge.ui_ext[i] = ui->ui_ext[i];
+ }
+
rv->ui_main = ui_main;
uv_mutex_init(&rv->mutex);
uv_cond_init(&rv->cond);
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 60bba19b07..69c0a838ea 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -48,6 +48,7 @@
#include "nvim/syntax.h"
#include "nvim/terminal.h"
#include "nvim/undo.h"
+#include "nvim/ui.h"
#include "nvim/os/os.h"
@@ -5223,6 +5224,9 @@ static void last_status_rec(frame_T *fr, int statusline)
*/
int tabline_height(void)
{
+ if (ui_is_external(kUITabline)) {
+ return 0;
+ }
assert(first_tabpage);
switch (p_stal) {
case 0: return 0;