aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/api.txt2
-rw-r--r--runtime/doc/motion.txt2
-rw-r--r--runtime/lua/vim/_meta/api.lua2
-rw-r--r--runtime/lua/vim/_meta/api_keysets.lua1
-rw-r--r--src/nvim/api/keysets.h1
-rw-r--r--src/nvim/api/win_config.c6
-rw-r--r--src/nvim/buffer_defs.h4
-rw-r--r--src/nvim/regexp.c51
-rw-r--r--src/nvim/window.c4
-rw-r--r--test/functional/ui/float_spec.lua83
10 files changed, 118 insertions, 38 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index ffd90ec3d7..f04fe9bb87 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -3177,6 +3177,8 @@ nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()*
• noautocmd: If true then no buffer-related autocommand
events such as |BufEnter|, |BufLeave| or |BufWinEnter| may
fire from calling this function.
+ • fixed: If true when anchor is NW or SW, the float window
+ would be kept fixed even if the window would be truncated.
Return: ~
Window handle, or 0 on error
diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt
index 05244cde91..dc92601bfc 100644
--- a/runtime/doc/motion.txt
+++ b/runtime/doc/motion.txt
@@ -660,6 +660,7 @@ i` *v_i`* *i`*
Special case: With a count of 2 the quotes are
included, but no extra white space as with a"/a'/a`.
+ *o_object-select*
When used after an operator:
For non-block objects:
For the "a" commands: The operator applies to the object and the white
@@ -675,6 +676,7 @@ For a block object:
the surrounding braces are excluded. For the "a" commands, the braces
are included.
+ *v_object-select*
When used in Visual mode:
When start and end of the Visual area are the same (just after typing "v"):
One object is selected, the same as for using an operator.
diff --git a/runtime/lua/vim/_meta/api.lua b/runtime/lua/vim/_meta/api.lua
index c0c8cabfb9..41bb5636b8 100644
--- a/runtime/lua/vim/_meta/api.lua
+++ b/runtime/lua/vim/_meta/api.lua
@@ -1611,6 +1611,8 @@ function vim.api.nvim_open_term(buffer, opts) end
--- • noautocmd: If true then no buffer-related autocommand
--- events such as `BufEnter`, `BufLeave` or `BufWinEnter` may
--- fire from calling this function.
+--- • fixed: If true when anchor is NW or SW, the float window
+--- would be kept fixed even if the window would be truncated.
--- @return integer
function vim.api.nvim_open_win(buffer, enter, config) end
diff --git a/runtime/lua/vim/_meta/api_keysets.lua b/runtime/lua/vim/_meta/api_keysets.lua
index 4d08563ce2..b249f6629f 100644
--- a/runtime/lua/vim/_meta/api_keysets.lua
+++ b/runtime/lua/vim/_meta/api_keysets.lua
@@ -112,6 +112,7 @@ error('Cannot require a meta file')
--- @field footer_pos? string
--- @field style? string
--- @field noautocmd? boolean
+--- @field fixed? boolean
--- @class vim.api.keyset.get_autocmds
--- @field event? any
diff --git a/src/nvim/api/keysets.h b/src/nvim/api/keysets.h
index 4e5e7af619..736ca9ce07 100644
--- a/src/nvim/api/keysets.h
+++ b/src/nvim/api/keysets.h
@@ -112,6 +112,7 @@ typedef struct {
String footer_pos;
String style;
Boolean noautocmd;
+ Boolean fixed;
} Dict(float_config);
typedef struct {
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index a579b0dde5..3d77d65fbc 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -163,6 +163,8 @@
/// - noautocmd: If true then no buffer-related autocommand events such as
/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from
/// calling this function.
+/// - fixed: If true when anchor is NW or SW, the float window
+/// would be kept fixed even if the window would be truncated.
///
/// @param[out] err Error details, if any
///
@@ -845,6 +847,10 @@ static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig,
fconfig->noautocmd = config->noautocmd;
}
+ if (HAS_KEY_X(config, fixed)) {
+ fconfig->fixed = config->fixed;
+ }
+
return true;
#undef HAS_KEY_X
}
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 2698af98e2..ff0fca1a56 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -966,6 +966,7 @@ typedef struct {
VirtText footer_chunks;
int footer_width;
bool noautocmd;
+ bool fixed;
} FloatConfig;
#define FLOAT_CONFIG_INIT ((FloatConfig){ .height = 0, .width = 0, \
@@ -975,7 +976,8 @@ typedef struct {
.focusable = true, \
.zindex = kZIndexFloatDefault, \
.style = kWinStyleUnused, \
- .noautocmd = false })
+ .noautocmd = false, \
+ .fixed = false })
// Structure to store last cursor position and topline. Used by check_lnums()
// and reset_lnums().
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 1d0a987780..14c7e56e97 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -59,11 +59,7 @@
#define un_Magic(x) ((x) + 256)
#define is_Magic(x) ((x) < 0)
-// We should define ftpr as a pointer to a function returning a pointer to
-// a function returning a pointer to a function ...
-// This is impossible, so we declare a pointer to a function returning a
-// pointer to a function returning void. This should work for all compilers.
-typedef void (*(*fptr_T)(int *, int))(void);
+typedef void (*fptr_T)(int *, int);
static int no_Magic(int x)
{
@@ -1494,34 +1490,14 @@ static inline char *cstrchr(const char *const s, const int c)
// regsub stuff //
////////////////////////////////////////////////////////////////
-// This stuff below really confuses cc on an SGI -- webb
-
-static fptr_T do_upper(int *d, int c)
+static void do_upper(int *d, int c)
{
*d = mb_toupper(c);
-
- return (fptr_T)NULL;
-}
-
-static fptr_T do_Upper(int *d, int c)
-{
- *d = mb_toupper(c);
-
- return (fptr_T)do_Upper;
}
-static fptr_T do_lower(int *d, int c)
+static void do_lower(int *d, int c)
{
*d = mb_tolower(c);
-
- return (fptr_T)NULL;
-}
-
-static fptr_T do_Lower(int *d, int c)
-{
- *d = mb_tolower(c);
-
- return (fptr_T)do_Lower;
}
/// regtilde(): Replace tildes in the pattern by the old pattern.
@@ -1886,16 +1862,16 @@ static int vim_regsub_both(char *source, typval_T *expr, char *dest, int destlen
} else if (vim_strchr("uUlLeE", (uint8_t)(*src))) {
switch (*src++) {
case 'u':
- func_one = (fptr_T)do_upper;
+ func_one = do_upper;
continue;
case 'U':
- func_all = (fptr_T)do_Upper;
+ func_all = do_upper;
continue;
case 'l':
- func_one = (fptr_T)do_lower;
+ func_one = do_lower;
continue;
case 'L':
- func_all = (fptr_T)do_Lower;
+ func_all = do_lower;
continue;
case 'e':
case 'E':
@@ -1954,11 +1930,13 @@ static int vim_regsub_both(char *source, typval_T *expr, char *dest, int destlen
} else {
c = utf_ptr2char(src - 1);
}
+
// Write to buffer, if copy is set.
if (func_one != NULL) {
- func_one = (fptr_T)(func_one(&cc, c));
+ func_one(&cc, c);
+ func_one = NULL;
} else if (func_all != NULL) {
- func_all = (fptr_T)(func_all(&cc, c));
+ func_all(&cc, c);
} else {
// just copy
cc = c;
@@ -2061,11 +2039,10 @@ static int vim_regsub_both(char *source, typval_T *expr, char *dest, int destlen
c = utf_ptr2char(s);
if (func_one != (fptr_T)NULL) {
- // Turbo C complains without the typecast
- func_one = (fptr_T)(func_one(&cc, c));
+ func_one(&cc, c);
+ func_one = NULL;
} else if (func_all != (fptr_T)NULL) {
- // Turbo C complains without the typecast
- func_all = (fptr_T)(func_all(&cc, c));
+ func_all(&cc, c);
} else { // just copy
cc = c;
}
diff --git a/src/nvim/window.c b/src/nvim/window.c
index c0d399c4c4..10334083ce 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1010,6 +1010,10 @@ void ui_ext_win_position(win_T *wp, bool validate)
comp_col += grid->comp_col;
comp_row = MAX(MIN(comp_row, Rows - wp->w_height_outer - (p_ch > 0 ? 1 : 0)), 0);
comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
+ int right_extra = Columns - (int)c.col - wp->w_width - (c.border_chars[2][0] != 0);
+ if (!(c.anchor & kFloatAnchorEast) && c.fixed && right_extra < 0) {
+ comp_col = (int)c.col;
+ }
wp->w_winrow = comp_row;
wp->w_wincol = comp_col;
ui_comp_put_grid(&wp->w_grid_alloc, comp_row, comp_col,
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index e37b3ccb5f..fcda0dad74 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -939,6 +939,89 @@ describe('float window', function()
end
end)
+ it('window position fixed', function()
+ local buf = meths.create_buf(false,false)
+ command("set nowrap")
+ local win = meths.open_win(buf, false, {
+ relative='editor', width=20, height=2, row=2, col=30, anchor = 'NW', fixed = true})
+ local expected_pos = {
+ [4]={{id=1001}, 'NW', 1, 2, 30, true},
+ }
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ {1: }|
+ {2:~ }|
+ ]], float_pos=expected_pos}
+ else
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }{1: }|
+ {0:~ }{2:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end
+
+ meths.win_set_config(win, {
+ relative='editor', width=20, height=2, row=2, col=30, anchor = 'NW', fixed = false})
+
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 4
+ {1: }|
+ {2:~ }|
+ ]], float_pos=expected_pos}
+ else
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }{1: }|
+ {0:~ }{2:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end
+ end)
+
it('draws correctly with redrawdebug=compositor', function()
-- NB: we do not test that it produces the "correct" debug info
-- (as it is intermediate only, and is allowed to change by internal