aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglepnir <glephunter@gmail.com>2023-10-09 18:47:10 +0800
committerglepnir <glephunter@gmail.com>2023-10-10 21:17:08 +0800
commit372aa2eb3db375385cf19dc0a6571f790b858241 (patch)
tree6c90cc4a0c9aa152c46ebf7d7c2bc2c6bb7239e8
parent9abced6ad95f6300ae80cd8b8aa124ebcf511b50 (diff)
downloadrneovim-372aa2eb3db375385cf19dc0a6571f790b858241.tar.gz
rneovim-372aa2eb3db375385cf19dc0a6571f790b858241.tar.bz2
rneovim-372aa2eb3db375385cf19dc0a6571f790b858241.zip
feat(float): add fclose command
-rw-r--r--runtime/doc/index.txt1
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--runtime/doc/windows.txt5
-rw-r--r--src/nvim/ex_cmds.lua6
-rw-r--r--src/nvim/ex_docmd.c6
-rw-r--r--src/nvim/window.c26
-rw-r--r--test/functional/ui/float_spec.lua180
7 files changed, 226 insertions, 0 deletions
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index b0ead51d0c..9e34cb5eab 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1288,6 +1288,7 @@ tag command action ~
|:execute| :exe[cute] execute result of expressions
|:exit| :exi[t] same as ":xit"
|:exusage| :exu[sage] overview of Ex commands
+|:fclose| :fc[lose] close floating window
|:file| :f[ile] show or set the current file name
|:files| :files list all files in the buffer list
|:filetype| :filet[ype] switch file type detection on/off
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index b0f3b76587..ceacb2e5da 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -188,6 +188,8 @@ The following new APIs and features were added.
• |$NVIM_APPNAME| can be set to a relative path instead of only a name.
+• Added |:fclose| command.
+
==============================================================================
CHANGED FEATURES *news-changed*
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index e0c0772f18..eb3c4df511 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -392,6 +392,11 @@ CTRL-W CTRL-O *CTRL-W_CTRL-O* *:on* *:only*
given, then they become hidden. But modified buffers are
never abandoned, so changes cannot get lost.
+ *:fc* *:fclose*
+:[count]fc[lose][!]
+ Close [count]th floating window by zindex order. '!' to close
+ all floating windows.
+
==============================================================================
4. Moving cursor to other windows *window-move-cursor*
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 88f3bc0b43..27f8535a1c 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -1045,6 +1045,12 @@ module.cmds = {
func='ex_function',
},
{
+ command='fclose',
+ flags=bit.bor(BANG, RANGE),
+ addr_type='ADDR_OTHER',
+ func='ex_floatclose',
+ },
+ {
command='global',
flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, DFLALL, SBOXOK, CMDWIN, LOCK_OK),
addr_type='ADDR_LINES',
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index eb89e0fc9d..e18912c8a0 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7357,6 +7357,12 @@ static void ex_terminal(exarg_T *eap)
do_cmdline_cmd(ex_cmd);
}
+/// ":fclose"
+static void ex_floatclose(exarg_T *eap)
+{
+ win_float_remove(eap->forceit, eap->line1);
+}
+
void verify_command(char *cmd)
{
if (strcmp("smile", cmd) != 0) {
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 04b5afe624..d688c58ff5 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -7658,3 +7658,29 @@ win_T *lastwin_nofloating(void)
}
return res;
}
+
+static int floating_zindex_compare(const void *a, const void *b)
+{
+ return (*(win_T **)b)->w_float_config.zindex - (*(win_T **)a)->w_float_config.zindex;
+}
+
+void win_float_remove(bool bang, int count)
+{
+ kvec_t(win_T *) float_win_arr = KV_INITIAL_VALUE;
+ for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
+ kv_push(float_win_arr, wp);
+ }
+ qsort(float_win_arr.items, float_win_arr.size, sizeof(win_T *), floating_zindex_compare);
+ for (size_t i = 0; i < float_win_arr.size; i++) {
+ if (win_close(float_win_arr.items[i], false, false) == FAIL) {
+ break;
+ }
+ if (!bang) {
+ count--;
+ if (count == 0) {
+ break;
+ }
+ }
+ }
+ kv_destroy(float_win_arr);
+}
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 18c8a7370f..ab02094beb 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -10927,6 +10927,186 @@ describe('float window', function()
]])
end
end)
+
+ it('fclose command #9663', function()
+ local bufA = meths.create_buf(false,false)
+ local bufB = meths.create_buf(false,false)
+ local bufC = meths.create_buf(false,false)
+ local bufD = meths.create_buf(false,false)
+ local config_A = {relative='editor', width=11, height=11, row=5, col=5, border ='single', zindex=50}
+ local config_B = {relative='editor', width=8, height=8, row=7, col=7, border ='single', zindex=70}
+ local config_C = {relative='editor', width=4, height=4, row=9, col=9, border ='single',zindex=90}
+ local config_D = {relative='editor', width=2, height=2, row=10, col=10, border ='single',zindex=100}
+ meths.open_win(bufA, false, config_A)
+ meths.open_win(bufB, false, config_B)
+ meths.open_win(bufC, false, config_C)
+ meths.open_win(bufD, false, config_D)
+ --close window which have higher zindex value
+ command('fclose')
+ local expected_pos = {
+ [4]={{id=1001}, 'NW', 1, 5, 5, true, 50},
+ [5]={{id=1002}, 'NW', 1, 7, 7, true, 70},
+ [6]={{id=1003}, 'NW', 1, 9, 9, true, 90},
+ }
+ 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
+ {5:┌───────────┐}|
+ {5:│}{1: }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:└───────────┘}|
+ ## grid 5
+ {5:┌────────┐}|
+ {5:│}{1: }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:└────────┘}|
+ ## grid 6
+ {5:┌────┐}|
+ {5:│}{1: }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:└────┘}|
+ ]],float_pos= expected_pos}
+ else
+ screen:expect([[
+ ^ {5:┌─┌─┌────┐─┐┐} |
+ {0:~ }{5:│}{1: }{5:│}{1: }{5:│}{1: }{5:│}{1: }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~}{5:│}{2:~ }{5:│}{2: }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~}{5:│}{2:~ }{5:│}{2: }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~}{5:│}{2:~ }{5:│}{2: }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~}{5:└────┘}{2: }{5:││}{0: }|
+ |
+ ]])
+ end
+ -- with range
+ command('1fclose')
+ expected_pos[6]=nil
+ 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
+ {5:┌───────────┐}|
+ {5:│}{1: }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:└───────────┘}|
+ ## grid 5
+ {5:┌────────┐}|
+ {5:│}{1: }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:│}{2:~ }{5:│}|
+ {5:└────────┘}|
+ ]],float_pos= expected_pos}
+ else
+ screen:expect([[
+ ^ {5:┌─┌────────┐┐} |
+ {0:~ }{5:│}{1: }{5:│}{1: }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }|
+ {0:~ }{5:│}{2:~}{5:│}{2:~ }{5:││}{0: }|
+ |
+ ]])
+ end
+ --with bang
+ command('fclose!')
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+
+ ]],float_pos= {}}
+ else
+ screen:expect([[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end
+ end)
end
describe('with ext_multigrid', function()