我经常想在选项卡页面中临时最大化缓冲区,然后返回到我正在查看的旧缓冲区配置。我当前执行此操作的工作流程是使用<c-w>o关闭所有其他缓冲区,或者将当前正在查看的缓冲区移至其自己的选项卡<c-w>T。第二种方法的问题是它从原始选项卡页中删除了缓冲区。

我分别用a.txtb.txtc.txt填充了三个文件abc

% echo a > a.txt
% echo b > b.txt
% echo c > c.txt


当我在一个标签页中打开所有这三个文件时,得到以下内容。



然后我可以将a.txt自身移动到选项卡上。但是,当我这样做时,将从原始选项卡页面删除a.txt。 (因此,应在<c-w>Tgt之后)



我希望能够选择按<c-w>T来保存原始内容的时间缓冲区,创建一个仅包含当前焦点所在的缓冲区的新选项卡页,然后关注刚刚创建的新选项卡页。换句话说,该命令几乎与<c-w>T完全相同,只是保留了原始标签页,而现在a.txt位于两个标签页中。

有没有办法做到这一点?

#1 楼

我不确定,但是您可以尝试使用:tab split(或更短版本的:tab sp)。


如果要更改:split的行为,可以这样重新映射它:

nnoremap <C-w>T :tab split<CR>



更一般而言,每次找到分割窗口的命令,而是希望创建一个新的标签页时,都可以在其前面加上a.txt

例如,它可以用于请在新标签页中读取帮助缓冲区:

:tab help {your_topic}



默认情况下,新标签页将显示在当前标签页之后。但是,如果要使其出现在其他位置,则可以在:tab前面加上一个计数。

例如,要在第3个标签页后的标签页中复制当前视口,可以键入:

:3tab split


并使其第一个出现:

:0tab split



有关更多信息,您可以阅读C-w T

:[count]tab {cmd}                   *:tab*
        Execute {cmd} and when it opens a new window open a new tab
        page instead.  Doesn't work for |:diffsplit|, |:diffpatch|,
        |:execute| and |:normal|.
        If [count] is given the new tab page appears after the tab
        page [count] otherwise the new tab page will appear after the
        current one.
        Examples:

            :tab split      " opens current buffer in new tab page
            :tab help gt    " opens tab page with help for "gt"
            :.tab help gt   " as above
            :+tab help      " opens tab page with help after the next
                            " tab page
            :-tab help      " opens tab page with help before the
                            " current one
            :0tab help      " opens tab page with help before the
                            " first one
            :$tab help      " opens tab page with help after the last
                            " one


#2 楼

由于这个问题,我一直在避免使用制表符,但是现在我有了一个具有所需的制表符重复行为的函数。我已经测试过了,但是还没有认真使用它。此工作流程可能存在一些隐藏的缺点。

该函数的一个问题是,它不会复制前一个缓冲区-窗口对中的某些状态(例如set number是否打开) 。推测一下,c-w T可能不会出现此问题,因为不执行任何重复操作,并且窗口可能只是重新创建了窗口。

Vim有几个基于1的列表,用于缓冲区,选项卡和窗口。据我所知,它们是基于1的,因为0键用于移至行的开头,因此不可能将零作为数字参数传递。

我们关心三个用于模拟此功能的列表:


选项卡页的全局列表
每个[选项卡页]的Windows列表
缓冲区的全局列表
/>
我们保存所有这些值,然后通过“ tabnew”创建一个新标签。新选项卡始终在右侧创建,因此tabnew所基于的选项卡下面的索引均不会无效。 (但是,更健壮的方法可能会更好。)

tabnew命令还将焦点移至新选项卡和其中的单个窗口。从那里我们可以使用buffer命令在最初具有焦点的缓冲区上创建视图。

然后,我们使用原始选项卡的已保存索引将焦点恢复到该选项卡。然后,在很大程度上避免了偏执狂,我们将该选项卡内的焦点设置为原始窗口。 Vim似乎记得哪个窗口集中在不可见的选项卡上,但我不喜欢依赖于此。

(一些风格上的要点:显式数值转换0+,全局变量和断言是全部为故意)

function! TabDuplicate()
  " set vars, sanity checking
  let g:tabdup_win      = 0+ winnr()
  let g:tabdup_buf      = 0+ bufnr('%')
  let g:tabdup_tabpage  = 0+ tabpagenr()
  call assert_true(g:tabdup_win > 0)
  call assert_true(g:tabdup_buf > 0)
  call assert_true(g:tabdup_tabpage > 0)
  " make a new tab page,
  " the new tab page will have focus
  " none of the indices, which are all
  " less than the current index, are
  " invalidated by creating a new tab
  execute "tabnew"
  " visit the buffer we saved
  execute "buffer " . g:tabdup_buf
  " return to the original tab page
  execute "tabnext " . g:tabdup_tabpage
  " return focus to original window
  execute g:tabdup_win . " windcmd w"
endfunction