VIM:如何在标签上显示的文件夹名称,但只有两个文件具有相同的名称

问题描述:

我想在VIM以下特点(GVIM尤其是)。我认为崇高的文本有这样的事情:VIM:如何在标签上显示的文件夹名称,但只有两个文件具有相同的名称

  1. 在“正常”情况下,标签名称应该仅仅是该文件的名称,但...
  2. 如果有两个打开的文件具有相同的名称,但在不同的目录,我想看一个标签名称父文件夹名称+文件名称。

例子:

当有标签下列文件:

  • C:\我的\目录\与\文件\ justAfile.txt
  • C:\我的\目录\与\文件\ myfile.txt的
  • C:\我的\目录\与\备份\ myfile.txt的

标签名称就为t母鸡:

justAfile.txt | files\myfile.txt | backup\myfile.txt 

这是可行的一些巧妙的配置?

在GVIM,你可以自定义的选项'guitablabel'选项卡的标签。

在终端的Vim;没有相应的'guitablabel';一个必须呈现整个'tabline'。幸运的是,Vim的帮助有一个例子,它将标签渲染委托给一个单独的函数,因此重新使用您的自定义函数非常容易。

的帮助页面,上面提到的选项链接到的例子;您可能必须使用fnamemodify()来将所有缓冲区的路径规范化为完全绝对路径,找到公共基本目录,然后将其从路径中剥离。另一方面,如果您可以将:cd添加到基本目录,那么您可以非常容易地获得这种标签标签。

由于英戈建议你可以使用guitablabel。在我的安装中,它仅配置为显示文件名(:echo &guitablabel报告%M%t)。要设置它以显示相对路径,请执行:set guitablabel=%M%f。像Ingo说的那样,使用:cd DIRECTORY来设置主目录,并使用:pwd来查看它当前的设置。

:help statusline的(很多)更多的格式选项。

假设下列文件:

z.txt 
a/b/c/d.txt 
a/b/f/d.txt 

我现在的建立将使tabline看起来像这样(我反向工程,从崇高文本2的行为):

z.txt | d.txt - c | d.txt - f 

的代码有一个很多额外功能,如特殊处理Nerdtree/FZF选项卡,并在有分割时根据最左边的缓冲区命名该选项卡。但是如果你不想要它们,你可以自己去除这些额外的东西,或者改变任何你不喜欢的东西。我也只使用Unix。

无论如何,我只是提供下面的代码没有保证,作为您进一步自定义的起点。

set tabline=%!GetTabLine() 

function! GetTabLine() 
    let tabs = BuildTabs() 
    let line = '' 
    for i in range(len(tabs)) 
    let line .= (i+1 == tabpagenr()) ? '%#TabLineSel#' : '%#TabLine#' 
    let line .= '%' . (i + 1) . 'T' 
    let line .= ' ' . tabs[i].uniq_name . ' ' 
    endfor 
    let line .= '%#TabLineFill#%T' 
    return line 
endfunction 

function! BuildTabs() 
    let tabs = [] 
    for i in range(tabpagenr('$')) 
    let tabnum = i + 1 
    let buflist = tabpagebuflist(tabnum) 
    let file_path = '' 
    let tab_name = bufname(buflist[0]) 
    if tab_name =~ 'NERD_tree' && len(buflist) > 1 
     let tab_name = bufname(buflist[1]) 
    end 
    let is_custom_name = 0 
    if tab_name == '' 
     let tab_name = '[No Name]' 
     let is_custom_name = 1 
    elseif tab_name =~ 'fzf' 
     let tab_name = 'FZF' 
     let is_custom_name = 1 
    else 
     let file_path = fnamemodify(tab_name, ':p') 
     let tab_name = fnamemodify(tab_name, ':p:t') 
    end 
    let tab = { 
     \ 'name': tab_name, 
     \ 'uniq_name': tab_name, 
     \ 'file_path': file_path, 
     \ 'is_custom_name': is_custom_name 
     \ } 
    call add(tabs, tab) 
    endfor 
    call CalculateTabUniqueNames(tabs) 
    return tabs 
endfunction 

function! CalculateTabUniqueNames(tabs) 
    for tab in a:tabs 
    if tab.is_custom_name | continue | endif 
    let tab_common_path = '' 
    for other_tab in a:tabs 
     if tab.name != other_tab.name || tab.file_path == other_tab.file_path 
     \ || other_tab.is_custom_name 
     continue 
     endif 
     let common_path = GetCommonPath(tab.file_path, other_tab.file_path) 
     if tab_common_path == '' || len(common_path) < len(tab_common_path) 
     let tab_common_path = common_path 
     endif 
    endfor 
    if tab_common_path == '' | continue | endif 
    let common_path_has_immediate_child = 0 
    for other_tab in a:tabs 
     if tab.name == other_tab.name && !other_tab.is_custom_name 
     \ && tab_common_path == fnamemodify(other_tab.file_path, ':h') 
     let common_path_has_immediate_child = 1 
     break 
     endif 
    endfor 
    if common_path_has_immediate_child 
     let tab_common_path = fnamemodify(common_path, ':h') 
    endif 
    let path = tab.file_path[len(tab_common_path)+1:-1] 
    let path = fnamemodify(path, ':~:.:h') 
    let dirs = split(path, '/', 1) 
    if len(dirs) >= 5 
     let path = dirs[0] . '/.../' . dirs[-1] 
    endif 
    let tab.uniq_name = tab.name . ' - ' . path 
    endfor 
endfunction 

function! GetCommonPath(path1, path2) 
    let dirs1 = split(a:path1, '/', 1) 
    let dirs2 = split(a:path2, '/', 1) 
    let i_different = 0 
    for i in range(len(dirs1)) 
    if get(dirs1, i) != get(dirs2, i) 
     let i_different = i 
     break 
    endif 
    endfor 
    return join(dirs1[0:i_different-1], '/') 
endfunction