Vim 中的智能换行

发布于 2024-07-29 06:53:06 字数 461 浏览 2 评论 0原文

我一直想知道 Vim 是否有能力智能换行代码,以便它保持与缩进的行相同的缩进。 我在其他一些文本编辑器(例如电子文本编辑器)上注意到了它,并发现它可以帮助我更轻松地理解我正在查看的内容。

例如,而不是

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
an example
    </a>
</p>

它会显示为

<p>
    <a href="somelink">
        This is a bogus link, used to demonstrate
        an example
    </a>
</p>

I have been wondering if Vim has the capability to smart wrap lines of code, so that it keeps the same indentation as the line that it is indenting. I have noticed it on some other text editor, such as e-text editor, and found that it helped me to comprehend what I'm looking at easier.

For example rather than

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
an example
    </a>
</p>

it would appear as

<p>
    <a href="somelink">
        This is a bogus link, used to demonstrate
        an example
    </a>
</p>

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

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

发布评论

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

评论(8

提笔书几行 2024-08-05 06:53:06

此功能已于 2014 年 6 月 25 日作为补丁 7.4.338 实施 。 随后有几个补丁完善了该功能,最后一个是 7.4.354,所以这就是您想要的版本。

:help breakindent
:help breakindentopt

下面摘录自 vim 帮助:

'breakindent'     'bri'   boolean (default off)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Every wrapped line will continue visually indented (same amount of
        space as the beginning of that line), thus preserving horizontal blocks
        of text.

'breakindentopt' 'briopt' string (default empty)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Settings for 'breakindent'. It can consist of the following optional
        items and must be seperated by a comma:
                  min:{n}     Minimum text width that will be kept after
                              applying 'breakindent', even if the resulting
                              text should normally be narrower. This prevents
                              text indented almost to the right window border
                              occupying lot of vertical space when broken.
                  shift:{n}   After applying 'breakindent', wrapped line
                              beginning will be shift by given number of
                              characters. It permits dynamic French paragraph
                              indentation (negative) or emphasizing the line
                              continuation (positive).
                  sbr         Display the 'showbreak' value before applying the 
                              additional indent.
        The default value for min is 20 and shift is 0.

与此相关的还有 showbreak 设置,这将以您指定的字符作为偏移量的后缀。

配置示例

" enable indentation
set breakindent

" ident by an additional 2 characters on wrapped lines, when line >= 40 characters, put 'showbreak' at start of line
set breakindentopt=shift:2,min:40,sbr

" append '>>' to indent
set showbreak=>>   

行为注意事项

如果您不指定 sbr 选项,则任何 showbreak 字符都会附加到缩进中。 从上面的示例中删除 sbr 会导致 4 个字符的有效缩进; 使用该设置,如果您只想使用 showbreak 而无需额外缩进,请指定 shift:0

您还可以进行负移位,这会产生将 showbreak 字符和换行文本拖回任何可用缩进空间的效果。

指定 min 值时,如果终端宽度较窄,则移位量将被压缩,但始终保留 showbreak 字符。

This feature has been implemented on June 25, 2014 as patch 7.4.338. There followed a few patches refining the feature, last one being 7.4.354, so that's the version you'll want.

:help breakindent
:help breakindentopt

Excerpts from vim help below:

'breakindent'     'bri'   boolean (default off)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Every wrapped line will continue visually indented (same amount of
        space as the beginning of that line), thus preserving horizontal blocks
        of text.

'breakindentopt' 'briopt' string (default empty)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Settings for 'breakindent'. It can consist of the following optional
        items and must be seperated by a comma:
                  min:{n}     Minimum text width that will be kept after
                              applying 'breakindent', even if the resulting
                              text should normally be narrower. This prevents
                              text indented almost to the right window border
                              occupying lot of vertical space when broken.
                  shift:{n}   After applying 'breakindent', wrapped line
                              beginning will be shift by given number of
                              characters. It permits dynamic French paragraph
                              indentation (negative) or emphasizing the line
                              continuation (positive).
                  sbr         Display the 'showbreak' value before applying the 
                              additional indent.
        The default value for min is 20 and shift is 0.

Also relevant to this is the showbreak setting, this will suffix your shift amount with character(s) you specify.

Example configuration

" enable indentation
set breakindent

" ident by an additional 2 characters on wrapped lines, when line >= 40 characters, put 'showbreak' at start of line
set breakindentopt=shift:2,min:40,sbr

" append '>>' to indent
set showbreak=>>   

Note on behaviour

If you don't specify the sbr option, any showbreak any characters put appended to the indentation. Removing sbr from the above example causes an effective indent of 4 characters; with that setting, if you just want to use showbreak without additional indentation, specify shift:0.

You can also give a negative shift, which would have the effect of dragging showbreak characters, and wrapped text, back into any available indent space.

When specifying a min value, the shifted amount will be squashed if you terminal width is narrower, but showbreak characters are always preserved.

为你拒绝所有暧昧 2024-08-05 06:53:06

有一个针对此问题的补丁,但它已经存在了几年,而且我上次检查时并没有完全应用。 请参阅 http://groups.google.com 中的“正确缩进换行”条目/group/vim_dev/web/vim-patches ——我真的希望这能进入主线。

更新:该链接似乎已损坏。 这是该补丁的更新版本

更新 2:它已合并上游(截至 7.4.345),因此现在你只需要 :set breakindent

There is a patch for this, but it's been lingering for years and last time I checked did not apply cleanly. See the "Correctly indent wrapped lines" entry in http://groups.google.com/group/vim_dev/web/vim-patches -- I really wish this would get in the mainline.

Update: that link seems to have bitrotted. Here is a more up to date version of the patch.

Update 2: it has been merged upstream (as of 7.4.345), so now you only have to :set breakindent.

丢了幸福的猪 2024-08-05 06:53:06

我认为不可能有完全相同的缩进,但您仍然可以通过设置“showbreak”选项获得更好的视图。

:set showbreak=>>>

示例:

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
>>>an example
    </a>
</p>

真实的代码看起来比上面的示例代码更好,因为 Vim 对 '>>' 使用了不同的颜色。

I don't think it's possible to have exactly the same indentation, but you can still get a better view by setting the 'showbreak' option.

:set showbreak=>>>

Example:

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
>>>an example
    </a>
</p>

The real thing looks better than the example code above, because Vim uses a different colour for '>>>'.

何以心动 2024-08-05 06:53:06

更新:2014 年 6 月,一个补丁支持 breakindent 选项 已合并到 Vim(版本 7.4.346 或更高版本以获得最佳支持)。


您也可以尝试 :set nowrap 这将允许 vim 通过向右滚动来显示长行。 这对于检查文档的整体结构可能很有用,但对于实际编辑来说可能不太方便。

其他接近您要查找的选项是 linebreakshowbreak。 使用 showbreak,您可以修改换行行左边距显示的内容,但不幸的是,它不允许根据当前上下文进行变量缩进。

UPDATE: In June 2014, a patch to support a breakindent option was merged into Vim (version 7.4.346 or later for best support).


You might also try :set nowrap which will allow vim to display long lines by scrolling to the right. This may be useful for examining the overall structure of a document, but can be less convenient for actually editing.

Other options close to what you're looking for are linebreak and showbreak. With showbreak, you can modify what is displayed at the left margin of lines that are wrapped, but unfortunately it doesn't allow a variable indent depending on the current context.

坏尐絯 2024-08-05 06:53:06

据我所知,您可以执行此操作的唯一方法是使用返回字符(如 Cfreak 提到的)并将 textwidth 选项与各种缩进选项结合起来。 如果您的缩进配置正确(我相信默认情况下使用的是 html 语法,但否则请参阅 autoindentsmartindent 选项),您可以:

:set formatoptions = tcqw
:set textwidth = 50
gggqG

如果您有自定义 formatoptions 设置,最好简单地执行以下操作:

:set fo += w
:set tw = 50
gggqG

它的作用:

:set fo+=w  " Add the 'w' flag to the formatoptions so 
            " that reformatting is only done when lines
            " end in spaces or are too long (so your <p>
            " isn't moved onto the same line as your <a...).
:set tw=50  " Set the textwidth up to wrap at column 50
gg          " Go to the start of the file
gq{motion}  " Reformat the lines that {motion} moves over.
G           " Motion that goes to the end of the file.

请注意,这与软换行不同:它将换行源文件中的行以及屏幕(当然除非你不保存它!)。 还有其他设置可以添加到 formatoptions 中,这些设置将在您键入时自动格式化::help fo-table 中的详细信息。

有关更多信息,请参阅:

:help 'formatoptions'
:help fo-table
:help 'textwidth'
:help gq
:help gg
:help G
:help 'autoindent'
:help 'smartindent'

The only way I know of that you could do this would be to use a return character (as mentioned by Cfreak) and combine the textwidth option with the various indentation options. If your indent is configured correctly (as it is by default with the html syntax I believe, but otherwise see the autoindent and smartindent options), you can:

:set formatoptions = tcqw
:set textwidth = 50
gggqG

If you have any customisation of the formatoptions setting, it may be better to simply do:

:set fo += w
:set tw = 50
gggqG

What this does:

:set fo+=w  " Add the 'w' flag to the formatoptions so 
            " that reformatting is only done when lines
            " end in spaces or are too long (so your <p>
            " isn't moved onto the same line as your <a...).
:set tw=50  " Set the textwidth up to wrap at column 50
gg          " Go to the start of the file
gq{motion}  " Reformat the lines that {motion} moves over.
G           " Motion that goes to the end of the file.

Note that this is not the same as a soft wrap: it will wrap the lines in the source file as well as on the screen (unless you don't save it of course!). There are other settings that can be added to formatoptions that will auto-format as you type: details in :help fo-table.

For more information, see:

:help 'formatoptions'
:help fo-table
:help 'textwidth'
:help gq
:help gg
:help G
:help 'autoindent'
:help 'smartindent'
何处潇湘 2024-08-05 06:53:06
:set smartindent
:set autoindent

我认为你仍然需要使用退货

:set smartindent
:set autoindent

I think you still have to use a return though

柏林苍穹下 2024-08-05 06:53:06

如果您的 HTML 格式足够好,通过 xmllint 运行它可能会有所帮助:

:%!xmllint --html --format

If your HTML is sufficiently well formed, running it through xmllint might help:

:%!xmllint --html --format
奈何桥上唱咆哮 2024-08-05 06:53:06

宏解决方案:


编辑:

操作gq{motion}自动格式化为变量“textwidth”设置的值。 这比使用我的宏的 80lBi^M 更容易/更好。


如果启用了自动缩进,

:set autoindent

则在行尾输入回车将使下一行缩进相同的量。 如果您愿意,可以使用它来硬输入换行。 以下宏利用此功能自动缩进文本:

将寄存器 z 设置为:

gg/\v^.{80,}$^M@x (change 80 to whatever length you want your text to be)

并将寄存器 x 设置为:

80lBi^M^[n@x (change 80 to whatever length you want your text to be)

然后执行

@x   

激活宏。 几秒钟后,您的文本将全部位于 80 个或更少字符的正确缩进行中。

说明:

这是对宏的剖析:

第 1 部分(宏 z):

gg/\v^.{80,}$^M@x

gg - start at the top of the file (this avoids some formatting issues)
/  - begin search
\v - switch search mode to use a more generic regex input style - no weird vim 'magic'
^.{80,}$ - regex for lines that contain 80 or more characters
^M - enter - do the search (don't type this, you can enter it with ctrl+v then enter)
@x - do macro x

第 2 部分(宏 x):

80lBi^M^[n@x

80l - move right 80 characters
B   - move back one WORD (WORDS include characters like "[];:" etc.)
i^M - enter insert mode and then add a return (again don't type this, use ctrl+v)
^[  - escape out of insert mode (enter this with ctrl+v then escape)
@x  - repeat the macro (macro will run until there are no more lines of 80 characters or more)

注意事项:

  • 如果存在 80 个字符或更长的 WORD,此宏将中断。

  • 此宏不会执行诸如在标签后缩进线之类的智能操作。

  • 使用lazyredraw设置(:setlazyredraw)来加速

A Macro Solution:


Edit:

The operate gq{motion} auto-formats to whatever the variable "textwidth" is set to. This is easier/better than using the 80lBi^M I have for my macro.


If you have autoindent enabled

:set autoindent

Then entering a return at the end of a line will indent the next line the same amount. You can use this to hard enter in linewraps if you'd like. The following macro takes advantage of this to automatically indent your text:

set register z to:

gg/\v^.{80,}$^M@x (change 80 to whatever length you want your text to be)

and set register x to:

80lBi^M^[n@x (change 80 to whatever length you want your text to be)

Then do

@x   

to activate the macros. After a few seconds you're text will all be in properly indented lines of 80 characters or less.

Explanation:

Here's a dissection of the macros:

Part 1 (macro z):

gg/\v^.{80,}$^M@x

gg - start at the top of the file (this avoids some formatting issues)
/  - begin search
\v - switch search mode to use a more generic regex input style - no weird vim 'magic'
^.{80,}$ - regex for lines that contain 80 or more characters
^M - enter - do the search (don't type this, you can enter it with ctrl+v then enter)
@x - do macro x

Part 2 (macro x):

80lBi^M^[n@x

80l - move right 80 characters
B   - move back one WORD (WORDS include characters like "[];:" etc.)
i^M - enter insert mode and then add a return (again don't type this, use ctrl+v)
^[  - escape out of insert mode (enter this with ctrl+v then escape)
@x  - repeat the macro (macro will run until there are no more lines of 80 characters or more)

Caveats:

  • This macro will break if the there's a WORD that is 80 characters or longer.

  • This macro will not do smart things like indent lines past tags.

  • Use the lazyredraw setting (:set lazyredraw) to speed this up

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