diff options
-rw-r--r-- | runtime/doc/api.txt | 2 | ||||
-rw-r--r-- | runtime/doc/motion.txt | 2 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/api.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/api_keysets.lua | 1 | ||||
-rw-r--r-- | src/nvim/api/keysets.h | 1 | ||||
-rw-r--r-- | src/nvim/api/win_config.c | 6 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/regexp.c | 51 | ||||
-rw-r--r-- | src/nvim/window.c | 4 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 83 |
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 |