获得;可用的;vim脚本中的窗口宽度
如何在vim脚本中获得宽度3(在图像中用绿色标记) 如果没有符号列,并且没有其他“特殊列”,我可以用获得;可用的;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()函数用于
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