patch 9.1.1391: Vim does not have a vertical tabpanel

Problem:  Vim does not have a tabpanel
Solution: include the tabpanel feature
          (Naruhiko Nishino, thinca)

closes: #17263

Co-authored-by: thinca <thinca@gmail.com>
Signed-off-by: Naruhiko Nishino <naru123456789@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_tabpanel.vim b/src/testdir/test_tabpanel.vim
new file mode 100644
index 0000000..630226f
--- /dev/null
+++ b/src/testdir/test_tabpanel.vim
@@ -0,0 +1,480 @@
+" Tests for tabpanel
+
+source check.vim
+source screendump.vim
+CheckFeature tabpanel
+
+function! s:reset()
+  set tabpanel&
+  set tabpanelopt&
+  set showtabpanel&
+endfunc
+
+function! Test_tabpanel_mouse()
+  let save_showtabline = &showtabline
+  let save_mouse = &mouse
+  set showtabline=0 mouse=a
+
+  tabnew
+  tabnew
+
+  call test_setmouse(1, 1)
+  call feedkeys("\<LeftMouse>", 'xt')
+  call assert_equal(3, tabpagenr())
+
+  set showtabpanel=2 tabpanelopt=columns:10
+
+  call test_setmouse(1, 1)
+  call feedkeys("\<LeftMouse>", 'xt')
+  call assert_equal(1, tabpagenr())
+  call test_setmouse(2, 1)
+  call feedkeys("\<LeftMouse>", 'xt')
+  call assert_equal(2, tabpagenr())
+  call test_setmouse(3, 1)
+  call feedkeys("\<LeftMouse>", 'xt')
+  call assert_equal(3, tabpagenr())
+
+  call feedkeys("\<LeftMouse>", 'xt')
+  call test_setmouse(2, 3)
+  let pos = getmousepos()
+  call assert_equal(2, pos['winrow'])
+  call assert_equal(0, pos['wincol'])
+  call assert_equal(2, pos['screenrow'])
+  call assert_equal(3, pos['screencol'])
+
+  call test_setmouse(1, 11)
+  call feedkeys("\<LeftMouse>", 'xt')
+  let pos = getmousepos()
+  call assert_equal(1, pos['winrow'])
+  call assert_equal(1, pos['wincol'])
+  call assert_equal(1, pos['screenrow'])
+  call assert_equal(11, pos['screencol'])
+
+  new
+  wincmd x
+
+  call test_setmouse(10, 11)
+  call feedkeys("\<LeftMouse>", 'xt')
+  let pos = getmousepos()
+  call assert_equal(10, pos['winrow'])
+  call assert_equal(1, pos['wincol'])
+  call assert_equal(10, pos['screenrow'])
+  call assert_equal(11, pos['screencol'])
+
+  tabonly!
+  call s:reset()
+  let &mouse = save_mouse
+  let &showtabline = save_showtabline
+endfunc
+
+function! Test_tabpanel_drawing()
+  CheckScreendump
+
+  let lines =<< trim END
+    function! MyTabPanel()
+      let n = g:actual_curtabpage
+      let hi = n == tabpagenr() ? 'TabLineSel' : 'TabLine'
+      let label = printf("\n%%#%sTabNumber#%d:%%#%s#", hi, n, hi)
+      let label ..= '%1*%f%*'
+      return label
+    endfunction
+    hi User1 ctermfg=12
+
+    set showtabline=0
+    set showtabpanel=0
+    set tabpanelopt=columns:16
+    set tabpanel=
+    silent edit Xtabpanel1
+
+    nnoremap \01 <Cmd>set showtabpanel=2<CR>
+    nnoremap \02 <C-w>v
+    nnoremap \03 <Cmd>call setline(1, ['a', 'b', 'c'])<CR>
+    nnoremap \04 <Cmd>silent tabnew Xtabpanel2<CR><Cmd>call setline(1, ['d', 'e', 'f'])<CR>
+    nnoremap \05 <Cmd>set tabpanel=%!MyTabPanel()<CR>
+    nnoremap \06 <Cmd>set tabpanelopt+=align:right<CR>
+    nnoremap \07 <Cmd>tab terminal NONE<CR><C-w>N
+    nnoremap \08 <Cmd>tabclose!<CR><Cmd>tabclose!<CR>
+  END
+  call writefile(lines, 'XTest_tabpanel', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel', {'rows': 6, 'cols': 45})
+
+  call VerifyScreenDump(buf, 'Test_tabpanel_drawing_00', {})
+
+  for i in range(1, 8)
+    let n = printf('%02d', i)
+    call term_sendkeys(buf, '\' .. n)
+    call VerifyScreenDump(buf, 'Test_tabpanel_drawing_' .. n, {})
+  endfor
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_drawing_with_popupwin()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:20
+    set showtabline=0
+    tabnew
+    setlocal buftype=nofile
+    call setbufline(bufnr(), 1, repeat([repeat('.', &columns - 20)], &lines))
+    highlight TestingForTabPanelPopupwin guibg=#7777ff guifg=#000000
+    for line in [1, &lines]
+      for col in [1, &columns - 20 - 2]
+        call popup_create([
+          \   '@',
+          \ ], {
+          \   'line': line,
+          \   'col': col,
+          \   'border': [],
+          \   'highlight': 'TestingForTabPanelPopupwin',
+          \ })
+      endfor
+    endfor
+    call cursor(4, 10)
+    call popup_atcursor('atcursor', {
+      \   'highlight': 'TestingForTabPanelPopupwin',
+      \ })
+  END
+  call writefile(lines, 'XTest_tabpanel_with_popupwin', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_with_popupwin', {'rows': 10, 'cols': 45})
+
+  call VerifyScreenDump(buf, 'Test_tabpanel_drawing_with_popupwin_0', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_drawing_fill_tailing()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:20
+    set showtabline=0
+    e aaa.txt
+    tabnew
+    e bbb.txt
+    let &tabpanel = "abc"
+    redraw!
+    " Check whether "abc" is cleared
+    let &tabpanel = "\nTOP\n%f\nBOTTOM"
+  END
+  call writefile(lines, 'XTest_tabpanel_fill_tailing', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_fill_tailing', {'rows': 10, 'cols': 45})
+
+  call VerifyScreenDump(buf, 'Test_tabpanel_drawing_fill_tailing_0', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_drawing_pum()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:20
+    set showtabline=0
+    e aaa.txt
+    tabnew
+    e bbb.txt
+  END
+  call writefile(lines, 'XTest_tabpanel_pum', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_pum', {'rows': 10, 'cols': 45})
+
+  call term_sendkeys(buf, "i\<C-x>\<C-v>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_drawing_pum_0', {})
+
+  call term_sendkeys(buf, "\<cr>  ab\<C-x>\<C-v>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_drawing_pum_1', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_scrolling()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:20
+    set showtabline=0
+    set nowrap
+    set number
+    e aaa.txt
+    tabnew
+    e bbb.txt
+    vsplit
+    call setbufline(bufnr(), 1, repeat(['text text text text'], 100))
+    wincmd =
+  END
+  call writefile(lines, 'XTest_tabpanel_scrolling', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_scrolling', {'rows': 10, 'cols': 45})
+  let n = 0
+  for c in ['H', 'J', 'K', 'L']
+    call term_sendkeys(buf, ":wincmd " .. c ..  "\<cr>")
+    call term_sendkeys(buf, "\<C-d>\<C-d>")
+    call term_sendkeys(buf, "r@")
+    call VerifyScreenDump(buf, 'Test_tabpanel_drawing_scrolling_' .. n, {})
+    let n += 1
+  endfor
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_many_tabpages()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:10
+    set showtabline=0
+    set tabpanel=%{g:actual_curtabpage}:tab
+    execute join(repeat(['tabnew'], 20), ' | ')
+  END
+  call writefile(lines, 'XTest_tabpanel_many_tabpages', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_many_tabpages', {'rows': 10, 'cols': 45})
+  for n in range(0, 3)
+    call term_sendkeys(buf, "gt")
+    call VerifyScreenDump(buf, 'Test_tabpanel_many_tabpages_' .. n, {})
+  endfor
+  call term_sendkeys(buf, ":tabnext +10\<cr>")
+  call term_sendkeys(buf, ":tabnext -3\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_many_tabpages_4', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_visual()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:10
+    set showtabline=0
+    tabnew
+    call setbufline(bufnr(), 1, ['aaa1 bbb1 ccc1 ddd1', 'aaa2 bbb2 ccc2 ddd2', 'aaa3 bbb3 ccc3 ddd3', 'aaa4 bbb4 ccc4 ddd4'])
+  END
+  call writefile(lines, 'XTest_tabpanel_visual', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_visual', {'rows': 10, 'cols': 45})
+  call term_sendkeys(buf, "v2w")
+  call VerifyScreenDump(buf, 'Test_tabpanel_visual_0', {})
+  call term_sendkeys(buf, "\<esc>0jw")
+  call term_sendkeys(buf, "v2wge")
+  call VerifyScreenDump(buf, 'Test_tabpanel_visual_1', {})
+  call term_sendkeys(buf, "y:echo @\"\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_visual_2', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_commandline()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:10
+    set showtabline=0
+    tabnew
+  END
+  call writefile(lines, 'XTest_tabpanel_commandline', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_commandline', {'rows': 10, 'cols': 45})
+  call term_sendkeys(buf, ":ab\<tab>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_commandline_0', {})
+
+  call term_sendkeys(buf, "\<esc>")
+  call term_sendkeys(buf, ":set wildoptions=pum\<cr>")
+  call term_sendkeys(buf, ":ab\<tab>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_commandline_1', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_tabline_and_tabpanel()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:10,vert
+    set fillchars=tpl_vert:│
+    set showtabline=2
+    e aaa.txt
+    tabnew
+    e bbb.txt
+    tabnew
+    e ccc.txt
+  END
+  call writefile(lines, 'XTest_tabpanel_tabline_and_tabpanel', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_tabline_and_tabpanel', {'rows': 10, 'cols': 45})
+  call VerifyScreenDump(buf, 'Test_tabpanel_tabline_and_tabpanel_0', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_dont_overflow_into_tabpanel()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:10
+    set showtabline=2
+    tabnew
+    call setline(1, repeat('x', 100))
+    set wrap
+  END
+  call writefile(lines, 'XTest_tabpanel_dont_overflow_into_tabpanel', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_dont_overflow_into_tabpanel', {'rows': 10, 'cols': 45})
+  call VerifyScreenDump(buf, 'Test_tabpanel_dont_overflow_into_tabpanel_0', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_dont_vert_is_multibytes_left()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=columns:10,vert
+    set fillchars=tpl_vert:│
+    set showtabline=2
+    tabnew
+  END
+  call writefile(lines, 'XTest_tabpanel_vert_is_multibyte_lefts', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_vert_is_multibyte_lefts', {'rows': 10, 'cols': 45})
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_left_0', {})
+
+  call term_sendkeys(buf, ":set tabpanelopt=columns:1,vert\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_left_1', {})
+
+  call term_sendkeys(buf, ":set tabpanelopt=columns:10,vert\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_left_2', {})
+
+  call term_sendkeys(buf, ":set tabpanelopt=columns:2,vert\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_left_3', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_dont_vert_is_multibytes_right()
+  CheckScreendump
+
+  let lines =<< trim END
+    set showtabpanel=2
+    set tabpanelopt=align:right,columns:10,vert
+    set fillchars=tpl_vert:│
+    set showtabline=2
+    tabnew
+  END
+  call writefile(lines, 'XTest_tabpanel_vert_is_multibytes_right', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_vert_is_multibytes_right', {'rows': 10, 'cols': 45})
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_right_0', {})
+
+  call term_sendkeys(buf, ":set tabpanelopt=align:right,columns:1,vert\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_right_1', {})
+
+  call term_sendkeys(buf, ":set tabpanelopt=align:right,columns:10,vert\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_right_2', {})
+
+  call term_sendkeys(buf, ":set tabpanelopt=align:right,columns:2,vert\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_vert_is_multibytes_right_3', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_eval_tabpanel_statusline_tabline()
+  CheckScreendump
+
+  let lines =<< trim END
+    function! Expr()
+      return "$%=[%f]%=$"
+    endfunction
+    set laststatus=2
+    set showtabline=2
+    set showtabpanel=2
+    set statusline=%!Expr()
+    set tabline=%!Expr()
+    set tabpanel=%!Expr()
+    set tabpanelopt=columns:10,vert
+    set fillchars=tpl_vert:│
+    e aaa
+    tabnew
+    e bbb
+    tabnew
+    e ccc
+  END
+  call writefile(lines, 'XTest_tabpanel_eval_tabpanel_statusline_tabline', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_eval_tabpanel_statusline_tabline', {'rows': 10, 'cols': 45})
+  call VerifyScreenDump(buf, 'Test_tabpanel_eval_tabpanel_statusline_tabline_0', {})
+  call term_sendkeys(buf, ":set tabpanelopt+=align:right\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_eval_tabpanel_statusline_tabline_1', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_noeval_tabpanel_statusline_tabline()
+  CheckScreendump
+
+  let lines =<< trim END
+    set laststatus=2
+    set showtabline=2
+    set showtabpanel=2
+    set statusline=$%=[%f]%=$
+    set tabline=$%=[%f]%=$
+    set tabpanel=$%=[%f]%=$
+    set tabpanelopt=columns:10,vert
+    set fillchars=tpl_vert:│
+    e aaa
+    tabnew
+    e bbb
+    tabnew
+    e ccc
+  END
+  call writefile(lines, 'XTest_tabpanel_noeval_tabpanel_statusline_tabline', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_noeval_tabpanel_statusline_tabline', {'rows': 10, 'cols': 45})
+  call VerifyScreenDump(buf, 'Test_tabpanel_noeval_tabpanel_statusline_tabline_0', {})
+  call term_sendkeys(buf, ":set tabpanelopt+=align:right\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_noeval_tabpanel_statusline_tabline_1', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+function! Test_tabpanel_eval_tabpanel_with_linebreaks()
+  CheckScreendump
+
+  let lines =<< trim END
+    function! Expr()
+      return "top\n$%=[%f]%=$\nbottom"
+    endfunction
+    set showtabpanel=2
+    set tabpanel=%!Expr()
+    set tabpanelopt=columns:10
+    e aaa
+    tabnew
+    e bbb
+    tabnew
+    e ccc
+  END
+  call writefile(lines, 'XTest_tabpanel_eval_tabpanel_with_linebreaks', 'D')
+
+  let buf = RunVimInTerminal('-S XTest_tabpanel_eval_tabpanel_with_linebreaks', {'rows': 10, 'cols': 45})
+  call VerifyScreenDump(buf, 'Test_tabpanel_eval_tabpanel_with_linebreaks_0', {})
+  call term_sendkeys(buf, ":set tabpanelopt+=align:right\<cr>")
+  call VerifyScreenDump(buf, 'Test_tabpanel_eval_tabpanel_with_linebreaks_1', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab