aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/vim.c18
-rw-r--r--src/nvim/api/window.c5
-rw-r--r--src/nvim/buffer.c5
-rw-r--r--src/nvim/buffer_defs.h14
-rw-r--r--src/nvim/highlight.c21
-rw-r--r--src/nvim/option.c3
-rw-r--r--src/nvim/screen.c3
-rw-r--r--src/nvim/window.c48
8 files changed, 98 insertions, 19 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 8e5650633a..dbe3b66fd5 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1064,6 +1064,19 @@ fail:
/// - `external`: GUI should display the window as an external
/// top-level window. Currently accepts no other positioning
/// configuration together with this.
+/// - `style`: Configure the apparance of the window. Currently only takes
+/// one non-empty value:
+/// - "minimal" Nvim will display the window with many UI options
+/// disabled. This is useful when displaing a temporary
+/// float where the text should not be edited. Disables
+/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn',
+/// 'spell' and 'list' options. 'signcolumn' is changed to
+/// `auto`. The end-of-buffer region is hidden by setting
+/// `eob` flag of 'fillchars' to a space char, and clearing
+/// the |EndOfBuffer| region in 'winhighlight'.
+///
+/// top-level window. Currently accepts no other positioning
+/// configuration together with this.
/// @param[out] err Error details, if any
///
/// @return Window handle, or 0 on error
@@ -1085,6 +1098,11 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config,
if (buffer > 0) {
nvim_win_set_buf(wp->handle, buffer, err);
}
+
+ if (fconfig.style == kWinStyleMinimal) {
+ win_set_minimal_style(wp);
+ didset_window_options(wp);
+ }
return wp->handle;
}
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 9fd1818a5c..4922dd7efc 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -13,6 +13,7 @@
#include "nvim/vim.h"
#include "nvim/buffer.h"
#include "nvim/cursor.h"
+#include "nvim/option.h"
#include "nvim/window.h"
#include "nvim/screen.h"
#include "nvim/move.h"
@@ -475,6 +476,10 @@ void nvim_win_set_config(Window window, Dictionary config, Error *err)
win_config_float(win, fconfig);
win->w_pos_changed = true;
}
+ if (fconfig.style == kWinStyleMinimal) {
+ win_set_minimal_style(win);
+ didset_window_options(win);
+ }
}
/// Return window configuration.
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 5678f518f5..cd31adbaff 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -2543,6 +2543,11 @@ void get_winopts(buf_T *buf)
} else
copy_winopt(&curwin->w_allbuf_opt, &curwin->w_onebuf_opt);
+ if (curwin->w_float_config.style == kWinStyleMinimal) {
+ didset_window_options(curwin);
+ win_set_minimal_style(curwin);
+ }
+
// Set 'foldlevel' to 'foldlevelstart' if it's not negative.
if (p_fdls >= 0) {
curwin->w_p_fdl = p_fdls;
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index ad10f6baa2..a27672488e 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -972,7 +972,6 @@ struct matchitem {
};
typedef int FloatAnchor;
-typedef int FloatRelative;
enum {
kFloatAnchorEast = 1,
@@ -985,15 +984,20 @@ enum {
// SE -> kFloatAnchorSouth | kFloatAnchorEast
EXTERN const char *const float_anchor_str[] INIT(= { "NW", "NE", "SW", "SE" });
-enum {
+typedef enum {
kFloatRelativeEditor = 0,
kFloatRelativeWindow = 1,
kFloatRelativeCursor = 2,
-};
+} FloatRelative;
EXTERN const char *const float_relative_str[] INIT(= { "editor", "window",
"cursor" });
+typedef enum {
+ kWinStyleUnused = 0,
+ kWinStyleMinimal, /// Minimal UI: no number column, eob markers, etc
+} WinStyle;
+
typedef struct {
Window window;
int height, width;
@@ -1002,12 +1006,14 @@ typedef struct {
FloatRelative relative;
bool external;
bool focusable;
+ WinStyle style;
} FloatConfig;
#define FLOAT_CONFIG_INIT ((FloatConfig){ .height = 0, .width = 0, \
.row = 0, .col = 0, .anchor = 0, \
.relative = 0, .external = false, \
- .focusable = true })
+ .focusable = true, \
+ .style = kWinStyleUnused })
// Structure to store last cursor position and topline. Used by check_lnums()
// and reset_lnums().
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index 15c3d0eb7b..e5cbb4f944 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -141,10 +141,12 @@ int hl_get_ui_attr(int idx, int final_id, bool optional)
HlAttrs attrs = HLATTRS_INIT;
bool available = false;
- int syn_attr = syn_id2attr(final_id);
- if (syn_attr != 0) {
- attrs = syn_attr2entry(syn_attr);
- available = true;
+ if (final_id > 0) {
+ int syn_attr = syn_id2attr(final_id);
+ if (syn_attr != 0) {
+ attrs = syn_attr2entry(syn_attr);
+ available = true;
+ }
}
if (HLF_PNI <= idx && idx <= HLF_PST) {
@@ -176,15 +178,14 @@ void update_window_hl(win_T *wp, bool invalid)
// determine window specific background set in 'winhighlight'
bool float_win = wp->w_floating && !wp->w_float_config.external;
- if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] > 0) {
+ if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] != 0) {
wp->w_hl_attr_normal = hl_get_ui_attr(HLF_INACTIVE,
wp->w_hl_ids[HLF_INACTIVE],
!has_blend);
- } else if (float_win && wp->w_hl_ids[HLF_NFLOAT] > 0) {
+ } else if (float_win && wp->w_hl_ids[HLF_NFLOAT] != 0) {
wp->w_hl_attr_normal = hl_get_ui_attr(HLF_NFLOAT,
- // 'cursorline'
wp->w_hl_ids[HLF_NFLOAT], !has_blend);
- } else if (wp->w_hl_id_normal > 0) {
+ } else if (wp->w_hl_id_normal != 0) {
wp->w_hl_attr_normal = hl_get_ui_attr(-1, wp->w_hl_id_normal, !has_blend);
} else {
wp->w_hl_attr_normal = float_win ? HL_ATTR(HLF_NFLOAT) : 0;
@@ -199,14 +200,14 @@ void update_window_hl(win_T *wp, bool invalid)
}
}
- if (wp != curwin) {
+ if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] == 0) {
wp->w_hl_attr_normal = hl_combine_attr(HL_ATTR(HLF_INACTIVE),
wp->w_hl_attr_normal);
}
for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
int attr;
- if (wp->w_hl_ids[hlf] > 0) {
+ if (wp->w_hl_ids[hlf] != 0) {
attr = hl_get_ui_attr(hlf, wp->w_hl_ids[hlf], false);
} else {
attr = HL_ATTR(hlf);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index e8e246c277..2c96dae64e 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -3762,7 +3762,8 @@ static bool parse_winhl_opt(win_T *wp)
size_t nlen = (size_t)(colon-p);
char *hi = colon+1;
char *commap = xstrchrnul(hi, ',');
- int hl_id = syn_check_group((char_u *)hi, (int)(commap-hi));
+ int len = (int)(commap-hi);
+ int hl_id = len ? syn_check_group((char_u *)hi, len) : -1;
if (strncmp("Normal", p, nlen) == 0) {
w_hl_id_normal = hl_id;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index acff44164f..94887e113a 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -1612,7 +1612,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row,
}
}
- int attr = hl_combine_attr(wp->w_hl_attr_normal, win_hl_attr(wp, hl));
+ int attr = hl_combine_attr(wp->w_hl_attr_normal,
+ hl ? win_hl_attr(wp, hl) : 0);
if (wp->w_p_rl) {
grid_fill(&wp->w_grid, row, endrow, wp->w_wincol, W_ENDCOL(wp) - 1 - n,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index a3b1efeaaa..acaff8327d 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -584,15 +584,43 @@ win_T *win_new_float(win_T *wp, FloatConfig fconfig, Error *err)
wp->w_status_height = 0;
wp->w_vsep_width = 0;
- // TODO(bfredl): use set_option_to() after merging #9110 ?
- wp->w_p_nu = false;
- wp->w_allbuf_opt.wo_nu = false;
win_config_float(wp, fconfig);
wp->w_pos_changed = true;
redraw_win_later(wp, VALID);
return wp;
}
+void win_set_minimal_style(win_T *wp)
+{
+ wp->w_p_nu = false;
+ wp->w_p_rnu = false;
+ wp->w_p_cul = false;
+ wp->w_p_cuc = false;
+ wp->w_p_spell = false;
+ wp->w_p_list = false;
+
+ // Hide EOB region: use " " fillchar and cleared highlighting
+ if (wp->w_p_fcs_chars.eob != ' ') {
+ char_u *old = wp->w_p_fcs;
+ wp->w_p_fcs = ((*old == NUL)
+ ? (char_u *)xstrdup("eob: ")
+ : concat_str(old, (char_u *)",eob: "));
+ xfree(old);
+ }
+ if (wp->w_hl_ids[HLF_EOB] != -1) {
+ char_u *old = wp->w_p_winhl;
+ wp->w_p_winhl = ((*old == NUL)
+ ? (char_u *)xstrdup("EndOfBuffer:")
+ : concat_str(old, (char_u *)",EndOfBuffer:"));
+ xfree(old);
+ }
+
+ if (wp->w_p_scl[0] != 'a') {
+ xfree(wp->w_p_scl);
+ wp->w_p_scl = (char_u *)xstrdup("auto");
+ }
+}
+
void win_config_float(win_T *wp, FloatConfig fconfig)
{
wp->w_width = MAX(fconfig.width, 1);
@@ -821,6 +849,20 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf,
"'focusable' key must be Boolean");
return false;
}
+ } else if (!strcmp(key, "style")) {
+ if (val.type != kObjectTypeString) {
+ api_set_error(err, kErrorTypeValidation,
+ "'style' key must be String");
+ return false;
+ }
+ if (val.data.string.data[0] == NUL) {
+ fconfig->style = kWinStyleUnused;
+ } else if (striequal(val.data.string.data, "minimal")) {
+ fconfig->style = kWinStyleMinimal;
+ } else {
+ api_set_error(err, kErrorTypeValidation,
+ "Invalid value of 'style' key");
+ }
} else {
api_set_error(err, kErrorTypeValidation,
"Invalid key '%s'", key);