获得;可用的;vim脚本中的窗口宽度

获得;可用的;vim脚本中的窗口宽度,vim,Vim,如何在vim脚本中获得宽度3(在图像中用绿色标记) 如果没有符号列,并且没有其他“特殊列”,我可以用 winwidth(0)-(max([len(line('$),&numberwidth-1])+1)我认为,您应该能够使用以下方法获得该宽度: :set virtualedit=all :norm! g$ :echo virtcol('.') 或者,您可以检查是否存在标志栏(例如,使用redir) My有一个ingo#window#dimensions#NetWindowWidth()函数用于

如何在vim脚本中获得宽度3(在图像中用绿色标记)

如果没有符号列,并且没有其他“特殊列”,我可以用


winwidth(0)-(max([len(line('$),&numberwidth-1])+1)

我认为,您应该能够使用以下方法获得该宽度:

:set virtualedit=all
:norm! g$
:echo virtcol('.')
或者,您可以检查是否存在标志栏(例如,使用
redir


My有一个
ingo#window#dimensions#NetWindowWidth()
函数用于此功能。

正在回答,因为我还不能发表评论:

Christian的回答给出了错误的结果,如果文件中的实际行数超过
&numberwidth
(因为
&numberwidth
只是一个最小值,正如kshenoy指出的那样)。不过,修复非常简单,只需使用
&numberwidth
max()
和缓冲区中最后一行的位数(加上一个以说明vim添加的填充):


Kale的回答纠正了一个极端情况,即行数超过了
&numberwidth
所能显示的行数。这里我修复了另一个角落的情况,
signcolumn
选项未设置为
auto

function! BufWidth()
  let width = winwidth(0)
  let numberwidth = max([&numberwidth, strlen(line('$'))+1])
  let numwidth = (&number || &relativenumber)? numberwidth : 0
  let foldwidth = &foldcolumn

  if &signcolumn == 'yes'
    let signwidth = 2
  elseif &signcolumn == 'auto'
    let signs = execute(printf('sign place buffer=%d', bufnr('')))
    let signs = split(signs, "\n")
    let signwidth = len(signs)>2? 2: 0
  else
    let signwidth = 0
  endif
  return width - numwidth - foldwidth - signwidth
endfunction

上述答案均未考虑以下几点-

  • 插件使用符号组(如果可用),因此只需运行
    exe“silent sign place buffer=“.bufnr(“”)
    不会显示符号在插件组中的位置

  • Neovim支持可变符号列宽度

这就是最终让我感到高兴的答案。当然,它受到上述所有答案的影响-

function! BufferWidth()
    let width = winwidth(0)
    let numberwidth = max([&numberwidth, strlen(line('$')) + 1])
    let numwidth = (&number || &relativenumber) ? numberwidth : 0
    let foldwidth = &foldcolumn

    if &signcolumn == 'yes'
        let signwidth = 2
    elseif &signcolumn =~ 'yes'
        let signwidth = &signcolumn
        let signwidth = split(signwidth, ':')[1]
        let signwidth *= 2  " each signcolumn is 2-char wide
    elseif &signcolumn == 'auto'
        let supports_sign_groups = has('nvim-0.4.2') || has('patch-8.1.614')
        let signlist = execute(printf('sign place ' . (supports_sign_groups ? 'group=* ' : '') . 'buffer=%d', bufnr('')))
        let signlist = split(signlist, "\n")
        let signwidth = len(signlist) > 2 ? 2 : 0
    elseif &signcolumn =~ 'auto'
        let signwidth = 0
        if len(sign_getplaced(bufnr(),{'group':'*'})[0].signs)
            let signwidth = 0
            for l:sign in sign_getplaced(bufnr(),{'group':'*'})[0].signs
                let lnum = l:sign.lnum
                let signs = len(sign_getplaced(bufnr(),{'group':'*', 'lnum':lnum})[0].signs)
                let signwidth = (signs > signwidth ? signs : signwidth)
            endfor
        endif
        let signwidth *= 2   " each signcolumn is 2-char wide
    else
        let signwidth = 0
    endif

    return width - numwidth - foldwidth - signwidth
endfunction


我将使用第二个,第一个解决方案将具有视觉效果,这是脚本中不需要的。我现在不会接受你的回答,(但谢谢:-)看看是否有人能想出类似于
editareawidth()
。没有这样的函数,也不需要它。@ChristianBrabandt我不会说它不需要。如果您想要的只是编辑一些文本,则不需要使用缓冲区,但如果您想在其中拥有一些接口,则不需要使用缓冲区。虽然仅仅为符号编写一个健全的脚本界面就足够了。@ZyX作为几个使用符号功能的插件的作者,我同意,一个人需要更好的VimL集成。我甚至为此写了补丁。但不是因为有editareawidth函数是的,你在这里确实是对的。注意,现在可以使用
sign\u getplace()
将符号放置在缓冲区中。人们不再需要重拨了。我不理解关于signcolumn超过2的评论,除非neovim改变这种行为,否则signcolumn不能超过2列
function! BufWidth()
  let width = winwidth(0)
  let numberwidth = max([&numberwidth, strlen(line('$'))+1])
  let numwidth = (&number || &relativenumber)? numberwidth : 0
  let foldwidth = &foldcolumn

  if &signcolumn == 'yes'
    let signwidth = 2
  elseif &signcolumn == 'auto'
    let signs = execute(printf('sign place buffer=%d', bufnr('')))
    let signs = split(signs, "\n")
    let signwidth = len(signs)>2? 2: 0
  else
    let signwidth = 0
  endif
  return width - numwidth - foldwidth - signwidth
endfunction
function! BufferWidth()
    let width = winwidth(0)
    let numberwidth = max([&numberwidth, strlen(line('$')) + 1])
    let numwidth = (&number || &relativenumber) ? numberwidth : 0
    let foldwidth = &foldcolumn

    if &signcolumn == 'yes'
        let signwidth = 2
    elseif &signcolumn =~ 'yes'
        let signwidth = &signcolumn
        let signwidth = split(signwidth, ':')[1]
        let signwidth *= 2  " each signcolumn is 2-char wide
    elseif &signcolumn == 'auto'
        let supports_sign_groups = has('nvim-0.4.2') || has('patch-8.1.614')
        let signlist = execute(printf('sign place ' . (supports_sign_groups ? 'group=* ' : '') . 'buffer=%d', bufnr('')))
        let signlist = split(signlist, "\n")
        let signwidth = len(signlist) > 2 ? 2 : 0
    elseif &signcolumn =~ 'auto'
        let signwidth = 0
        if len(sign_getplaced(bufnr(),{'group':'*'})[0].signs)
            let signwidth = 0
            for l:sign in sign_getplaced(bufnr(),{'group':'*'})[0].signs
                let lnum = l:sign.lnum
                let signs = len(sign_getplaced(bufnr(),{'group':'*', 'lnum':lnum})[0].signs)
                let signwidth = (signs > signwidth ? signs : signwidth)
            endfor
        endif
        let signwidth *= 2   " each signcolumn is 2-char wide
    else
        let signwidth = 0
    endif

    return width - numwidth - foldwidth - signwidth
endfunction