Vim中的智能包装


79

我一直想知道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>


随着情况的变化,您应该重新查看答案。

1
使用:set autoindent:set smartindent
Shammel Lee

Answers:


61

此功能已于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始终保留字符。


2
简而言之,添加set breakindent到您的vim配置中将使行在缩进处折断并换行-而不是像在新行中那样在下一行开始折行。
james2doyle

3
并且添加set breakindentopt=shift:4到您的vim配置将缩进额外的4个空格。
fritzo

通过添加更多示例可以帮助获得此答案breakindentopt。语法在帮助文档中并不明显。感谢@fritzo作为您评论中的示例。
Mnebuerquo '18

33

有一个补丁程序,但是已经徘徊了很多,上次我检查的结果并不干净。请参阅http://groups.google.com/group/vim_dev/web/vim-patches中的“正确缩进换行”条目-我真希望这能进入主线。

更新:该链接似乎已经烂掉了。这是该修补程序的最新版本

更新2:它已被合并到上游(从7.4.345开始),所以现在您只需要合并:set breakindent


我非常喜欢,我将使html标记的可读性更好
Jose Elera 2011年

我在该网站上看不到任何补丁。其他人可以确认吗?
puk 2012年

显然,该站点是最近重建的,这些链接已断开。在同一站点上,最近有一个博客条目,其中包含更新的补丁程序。
ergosys

1
这确实是缺少的。我不明白为什么它不在主线中,特别是。因为补丁写得很好。
cseelus 2014年

2
感谢@Vitor Eiji的更新。这真是个好消息。
ergosys 2014年

17

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

:set showbreak=>>>

例:

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

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


5
您也可以使用:set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ (反斜杠空格组合形成分隔符空间。因此,您可以添加足够的空格,使其比大多数包装代码要深(例如,10个空格要比2个四个空格选项卡要深,而14个空格要比2个空格键要深) 3个四个空间标签);该空间的一个不错的功能是,它在视觉上的干扰较小(如果您
要这样做

7
@Jeromy Anglim一个较小的修正:set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ 可读性不如let &showbreak=repeat(' ', 14)
ZyX

8

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


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

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


5

据我所知,您可以执行此操作的唯一方法是使用返回字符(如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'

3
:set smartindent
:set autoindent

我认为您仍然必须使用回报


2

如果您的HTML格式正确,则通过xmllint运行它可能会有所帮助:

:%!xmllint --html --format

2

宏解决方案:


编辑:

操作会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个字符或更长,则此宏将中断。

  • 该宏不会执行智能操作,例如在标记后缩进行。

  • 使用lazyredraw设置(:set lazyredraw)可以加快速度

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.