将缓冲区复制到新选项卡中,而不是将其移动


10

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

我填充三个文件a.txtb.txt以及c.txtabc分别。

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

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

在此处输入图片说明

然后,我可以自己移动a.txt到选项卡。但是,当我这样做时,a.txt将从原来的标签页中删除。(因此,在a之后<c-w>Tgt

在此处输入图片说明

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

有没有办法做到这一点?

Answers:


13

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

:split命令应复制显示的视口a.txt,而:tab修改器应将此视口移动到专用的标签页中。


如果您想更改的行为C-w T,可以这样重新映射它:

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

更一般而言,每次找到分割窗口的命令时,您宁愿它创建一个新的标签页,则可以给它加上前缀:tab

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

:tab help {your_topic}

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

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

:3tab split

并使其显示为第一个:

:0tab split

有关更多信息,您可以阅读:h :tab

:[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键用于移动到行的开头,因此不可能将零作为数字参数传递。

我们关心用于仿真此功能的三个列表:

  • 标签页的全局列表
  • 每个[标签页]的窗口列表
  • 缓冲区的全局列表

我们保存所有这些值,然后通过“ 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.