Vim 中任意宽度窗口中的 80 个字符软换行

发布于 2024-07-25 07:41:58 字数 852 浏览 4 评论 0原文

我想使用 Vim 的 软包装 功能 (:set wrap) 将一些代码包装在 80 个字符处,而不管我的实际窗口宽度如何。

我还没有找到一种方法来做到这一点 - 所有软包装似乎都与窗口的宽度相关

  • textwidthwrapmargin 都用于硬包装(他们在文件中插入换行符)
  • 垂直拆分为多个窗口,并在其中一个窗口上使用 :vertical resize 80 (可能使用 :set breakat= 以允许在任何字符上中断)它们可以工作(尽管有点hackish),但是在使用 :set number 时会中断,因为行号占据可变数量的列(取决于文件长度),并且这些是80.

有没有办法在vim中做到这一点? 根据其他消息来源,这看起来前景并不乐观

现在我的近似是将 /^.\{80}\zs.\+ 作为我的默认搜索,因此它至少会突出显示。 我考虑过为其添加一个 :syntax 项,但是当它与其他语法项重叠时,它就会崩溃,所以我放弃了这个想法。

I want to use Vim's soft wrap capability (:set wrap) to wrap some code at 80 characters, regardless of my actual window width.

I haven't been able to find a way to do this yet - all the soft wrapping seems tied to the width of the window

  • textwidth and wrapmargin are both for hard wrapping (they insert newline characters into the file)
  • vertical splitting into multiple windows and using :vertical resize 80 (possibly with :set breakat= to allow breaks on any character) on one of them sort of works (even though it's a bit hackish), but breaks when using :set number as the line numbers take up a variable number of columns (depending on the file length) and these are part of the 80.

Is there any way to do this in vim? It doesn't look promising, according to other sources.

Right now my approximation is just to have /^.\{80}\zs.\+ as my default search so it's at least highlighted. I thought about adding a :syntax item for it, but that broke when it overlapped other syntax items, so I dropped that idea.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

挽心 2024-08-01 07:41:58

您可以

  • 通过 :set numberwidth=6 为行号列设置较大的最小宽度,然后
  • 您可以使用 :set columns=86 (或使用鼠标)到适当的尺寸。

如果您编辑一个包含一百万行的文件,您可能会遇到麻烦,但这不太可能。 这样您也浪费了 6 列的屏幕空间。 所以还是存在各种各样的问题。

您可以使用 :match 突出显示第 80 列,就像它所说的 此处此处

除此之外,我看不到任何方法可以做到这一点。 不过,这似乎是一个不错的功能。

You could

  • set a large minimum width for the line numbers column via :set numberwidth=6 and
  • then you could resize your window with :set columns=86 (or with the mouse) to the proper size.

If you edit a file with a million lines in it, you may have trouble, but that's unlikely. You're wasting 6 columns of screen real estate this way too. So there are still all kinds of problems.

You can highlight past the 80th column using :match like it says here and here.

Beyond that I can't see any way to do this. Seems like it'd be a nice feature though.

梦太阳 2024-08-01 07:41:58

试试这个:

set columns=80
autocmd VimResized * if (&columns > 80) | set columns=80 | endif
set wrap
set linebreak
set showbreak=+++

如果您总是想要 80 列,则可以删除 if (&columns > 80) |

Try this:

set columns=80
autocmd VimResized * if (&columns > 80) | set columns=80 | endif
set wrap
set linebreak
set showbreak=+++

You can remove the if (&columns > 80) | if you always want 80 columns.

不醒的梦 2024-08-01 07:41:58

我没有软包装的解决方案,但对于标记列,从 Vim 7.3(2010-08-15 发布)开始 :set colorcolumn=80 将突出显示第 80 列。颜色将取决于您的语法文件。

请参阅 Vim 80 列布局问题:h colorcolumn

I don't have a solution to the soft wrap, but as for marking a column, as of Vim 7.3 (released 2010-08-15) :set colorcolumn=80 will highlight column 80. The color will depend on your syntax file.

See Vim 80 column layout concerns, :h colorcolumn.

救赎№ 2024-08-01 07:41:58

eborisch的答案与我在这里找到的其他一些答案以及我必须解决的问题相结合,我想出了以下两个-部分解决方案:

第一部分使编辑长行文本变得更容易:

" Allow enabling by running the command ":Freeform", or <leader>sw
command! Softwrap :call SetupSoftwrap()
map <Leader>sw :call SetupSoftwrap() <CR>

func! SetupFreeform()
  " Use setlocal for all of these so they don't affect other buffers

  " Enable line wrapping.
  setlocal wrap
  " Only break at words.
  setlocal linebreak
  " Turn on spellchecking
  setlocal spell

  " Make jk and 0$ work on visual lines.
  nnoremap <buffer> j gj
  nnoremap <buffer> k gk
  nnoremap <buffer> 0 g0
  nnoremap <buffer> $ g$

  " Disable colorcolumn, in case you use it as a column-width indicator
  " I use: let &colorcolumn = join(range(101, 300), ",")
  " so this overrides that.
  setlocal colorcolumn=

  " cursorline and cursorcolumn don't work as well in wrap mode, so
  " you may want to disable them. cursorline highlights the whole line,
  " so if you write a whole paragraph on a single line, the whole
  " paragraph will be highlighted. cursorcolumn only highlights the actual
  " column number, not the visual line, so the highlighting will be broken
  " up on wrapped lines.
  setlocal nocursorline
  setlocal nocursorcolumn
endfunc

仅凭这一点,您就可以获得不错的文本换行,以便编写诸如 Markdown 或自述文件之类的内容。

正如其他答案中所述,以精确的列宽进行换行需要准确地告诉 vim 有多少列,并在每次调整 vim 大小时覆盖该列:

command! -nargs=? Draft :call SetupDraftMode(<args>)
func! SetupDraftMode()
  " I like 80 columns + 4 for line numbers
  set columns=84
  autocmd VimResized * if (&columns > 84) | set columns=84 | endif

  :Softwrap
endfunc

这仍然存在一些问题:

  • vim 不会清除外部屏幕调用 set columns 后指定的列的数量,我不知道如何告诉它,所以理想情况下,您应该在打开 vim 后立即调用它,
  • vim 在打开它时显示带有版本号的提示和一些有用的命令,所以这些不会被清除。 您可以添加 set shm+=I 来禁用该提示
  • 您无法打开任何垂直拆分,因为这样两个拆分都将约为 40 列。 您需要将列设置为所需宽度的 2 倍,然后始终打开拆分。
  • 我的 vim 脚本很糟糕,但理想情况下有人可以修改上面的 Draft 函数以将列宽作为参数,或者使用全局变量(g:explicit_vim_width?)如果您的窗口大小发生变化,请手动设置。

Combining eborisch's answer with some other answers I found here and things I had to work around, I came up with the following two-part solution:

This first part makes it easier to edit text with long lines:

" Allow enabling by running the command ":Freeform", or <leader>sw
command! Softwrap :call SetupSoftwrap()
map <Leader>sw :call SetupSoftwrap() <CR>

func! SetupFreeform()
  " Use setlocal for all of these so they don't affect other buffers

  " Enable line wrapping.
  setlocal wrap
  " Only break at words.
  setlocal linebreak
  " Turn on spellchecking
  setlocal spell

  " Make jk and 0$ work on visual lines.
  nnoremap <buffer> j gj
  nnoremap <buffer> k gk
  nnoremap <buffer> 0 g0
  nnoremap <buffer> $ g$

  " Disable colorcolumn, in case you use it as a column-width indicator
  " I use: let &colorcolumn = join(range(101, 300), ",")
  " so this overrides that.
  setlocal colorcolumn=

  " cursorline and cursorcolumn don't work as well in wrap mode, so
  " you may want to disable them. cursorline highlights the whole line,
  " so if you write a whole paragraph on a single line, the whole
  " paragraph will be highlighted. cursorcolumn only highlights the actual
  " column number, not the visual line, so the highlighting will be broken
  " up on wrapped lines.
  setlocal nocursorline
  setlocal nocursorcolumn
endfunc

With this alone you can get decent text wrapping for writing something like markdown, or a Readme.

As noted in other answers, getting wrapping at an exact column width requires telling vim exactly how many columns there are, and overwriting that each time vim gets resized:

command! -nargs=? Draft :call SetupDraftMode(<args>)
func! SetupDraftMode()
  " I like 80 columns + 4 for line numbers
  set columns=84
  autocmd VimResized * if (&columns > 84) | set columns=84 | endif

  :Softwrap
endfunc

There are still a couple of problems with this:

  • vim won't clear the screen outside of the columns you specify after calling set columns, and I can't figure out how to tell it to, so ideally you should call this immediately after opening vim
  • vim shows a prompt with the version number and some helpful commands when you open it, so these won't be cleared. You can add set shm+=I to disable that prompt
  • You can't open any vertical splits, because then both splits will be ~40 column. You would need to set columns to 2x your desired width and then always have a split open.
  • My vimscript is awful, but ideally someone could modify the Draft function above to take a column width as an argument, or use a global variable (g:explicit_vim_width?) that can be set manually if your window size changes.
惟欲睡 2024-08-01 07:41:58

您尝试过'linebreak'吗?

        *'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'*
  'linebreak' 'lbr' boolean (default off)
        local to window
        {not in Vi}
        {not available when compiled without the  |+linebreak|
        feature}
If on Vim will wrap long lines at a character in 'breakat' rather
than at the last character that fits on the screen.  Unlike
'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file,
it only affects the way the file is displayed, not its contents.  The
value of 'showbreak' is used to put in front of wrapped lines.
This option is not used when the 'wrap' option is off or 'list' is on.
Note that <Tab> characters after an <EOL> are mostly not displayed
with the right amount of white space.

Have you tried 'linebreak'?

        *'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'*
  'linebreak' 'lbr' boolean (default off)
        local to window
        {not in Vi}
        {not available when compiled without the  |+linebreak|
        feature}
If on Vim will wrap long lines at a character in 'breakat' rather
than at the last character that fits on the screen.  Unlike
'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file,
it only affects the way the file is displayed, not its contents.  The
value of 'showbreak' is used to put in front of wrapped lines.
This option is not used when the 'wrap' option is off or 'list' is on.
Note that <Tab> characters after an <EOL> are mostly not displayed
with the right amount of white space.
冬天旳寂寞 2024-08-01 07:41:58

没有什么好的办法。 如果我们修改 @eborisch 答案,我们可以使用 autocmd 破解一个临时的 setlocal softwrap 。 如果我们每次进入缓冲区时都调整大小,并且在设置局部变量 softwrap 时调整大小到特定长度,我们就会得到所需的行为。

假设我们想要软包装到 80 列,我们可以在 .vimrc 中编写以下内容。

augroup softwrap
    autocmd VimResized * if (exists('b:softwrap') && &columns > 80) | set columns=80 | endif
    autocmd BufEnter * set columns=999
augroup END

要打开特定缓冲区的模式,请使用以下命令:

let b:softwrap=1
set columns=80

There is no good way to do it. We can hack a makeshift setlocal softwrap with autocmd if we modify @eborisch answer. If we resize every time we enter a buffer, and we resize to a particular length when the local variable softwrap is set, we get the desired behaviour.

Let's suppose that we want to soft wrap to 80 columns, we can write the following in .vimrc.

augroup softwrap
    autocmd VimResized * if (exists('b:softwrap') && &columns > 80) | set columns=80 | endif
    autocmd BufEnter * set columns=999
augroup END

To turn on the mode for a particular buffer, use the following commands:

let b:softwrap=1
set columns=80
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文