如何在Vim中快速关闭HTML标签?

126

我已经有一段时间没有在 Vim 中编写类似于 HTML 的代码了,但最近又遇到了这个问题。假设我正在编写一些简单的 HTML

<html><head><title>This is a title</title></head></html>

如何快速编写、<head>和<html>的闭合标记?我感觉自己错过了某种非常简单的方法,不需要一个一个地编写它们。</p> <p>当然,我可以使用<kbd>Ctrl</kbd><kbd>P</kbd>来自动完成单个标记名称,但在我的笔记本电脑键盘上,让我苦恼的是如何正确输入括号和斜杠。</p>

11个回答

78

我发现使用xmledit插件非常有用,它添加了两个功能:

  1. 当你打开标签(例如键入<p>)时,它会在你键入闭合的>后将标记展开为<p></p>并将光标置于插入模式下的标记内。
  2. 如果你随后立即输入另一个>(例如,你键入<p>>),它将其展开为:
  3. <p>

    </p>

    并将光标置于插入模式下、缩进一次的标记内。

xml vim插件为这些功能增加了代码折叠和嵌套标记匹配。

当然,如果你在Markdown中编写HTML内容并使用%!将Vim缓冲区通过你选择的Markdown处理器过滤,就根本不必担心关闭标签的问题 :)


2
这个插件能否在输入'</'时自动关闭标签?或者只是通过某些按键插入闭合标签?有时候你会删除闭合标签,希望之后再插入它... - bzx
9
我不喜欢这个插件,因为它没有提供一种简单的方法来让你的光标越过生成的标签。比如,如果你想写“祝你<b>愉快</b>”,那么你会开始输入“祝你<b>愉快”,结果显示为“祝你<b>愉快|</b>”。然后你需要要么向右移动光标,要么退出插入模式才能继续写下文本。这就是为什么按一个键插入结束标签的解决方案更好的原因。 - exclipy
2
@exclipy Vim有很多内置的方法可以完成这个任务。首先尝试使用'E'、'f'和'A'命令。 - user456584
3
我使用命令 git clone https://github.com/sukima/xmledit.git ~/.vim/bundle/xmledit 安装了 xmledit 插件。但是它只在编辑 .xml 文件时起作用。当文件扩展名为 .html 或 .htm 时,它无法正常工作。 - Leo
3
目前,我的解决方案是将文件复制粘贴到相同的目录,并将其重命名为 "html.vim",以便它也可以影响 HTML 文件。现在,我在 ~/.vim/ftplugin 目录下有两个完全相同的文件(xml.vim 和 html.vim)。 - SilentDev
显示剩余2条评论

60

我喜欢简约的东西,

imap ,/ </<C-X><C-O>

4
<C-X><C-O> 是什么意思?对我来说没有任何作用。 - exclipy
9
有时候人们想要写“/,/”,所以我更倾向于使用不同的快捷方式。另一个细节是全能补全应该被关闭,而不是等待额外的输入。所以代码为:imap <silent> <C-c> </<C-X><C-O><C-X> - user699082
1
非常酷。还在末尾添加了<Esc>F<i,这样它会将光标放回标签内部。 - mVChr
要使用此命令,请处于插入模式,然后按 ,/ 以关闭标签。 - thedanotto
3
上面的解决方案得到了很多赞,但对于像我这样的初学者来说,它缺乏解释。它是如何工作的,人们如何使用它? - Phemelo Khetho
显示剩余4条评论

53

我觉得让vim为我编写完整的标签(包括开头和结尾),而不仅仅是结尾,更加方便。您可以使用由Tim Pope编写的优秀ragtag插件。使用方法如下(让|代表光标位置):

span|

按下CTRL+xSPACE

然后您将得到

<span>|</span>

您也可以使用CTRL+xENTER而不是CTRL+xSPACE, 然后您将获得

<span>
|
</span>

Ragtag能够完成更多任务(例如:在当前位置插入 <%= stuff %> 或 DOCTYPE)。您可能还想查看ragtag作者的其他插件,尤其是surround


+1 太棒了!顺便说一下,现在它被称为 ragtag:http://www.vim.org/scripts/script.php?script_id=1896 - neezer
这个肯定是最简单的。Textmate也不错,但Vim在这方面更胜一筹,感谢Krzysiek。 - josemota

38

我已经安装了这个。它没有自动完成闭合标签。有什么快捷键吗?我尝试了 Ctrl-_,但这会使我的终端字体变小。 - alhelal

24

如果你想做一些复杂的事情,sparkup 是非常好的。

这是他们网站上的一个例子:

ul > li.item-$*3会扩展为:

<ul>
    <li class="item-1"></li>
    <li class="item-2"></li>
    <li class="item-3"></li>
</ul>

使用 <C-e> 键执行此操作。

要执行问题中所给出的示例,

html > head > title{This is a title}
产生。
<html>
  <head>
    <title>This is a title</title>
  </head>
</html>

非常感谢!这比我以前见过的任何编辑器都要酷,不仅是Vim,而且是所有其他编辑器中最好的!太棒了! - Chris
这是一个很棒的插件。 - DenicioCode
这个插件是从Zen-Coding演变而来的。后者现在被称为Emmet,并且具有稍微更大的功能集。 - chb

19

还有一个名为zencoding的vim插件:https://github.com/mattn/zencoding-vim

教程: https://github.com/mattn/zencoding-vim/blob/master/TUTORIAL


更新:现在称为Emmethttp://emmet.io/


教程摘录:

1. Expand Abbreviation

  Type abbreviation as 'div>p#foo$*3>a' and type '<c-y>,'.
  ---------------------
  <div>
      <p id="foo1">
          <a href=""></a>
      </p>
      <p id="foo2">
          <a href=""></a>
      </p>
      <p id="foo3">
          <a href=""></a>
      </p>
  </div>
  ---------------------

2. Wrap with Abbreviation

  Write as below.
  ---------------------
  test1
  test2
  test3
  ---------------------
  Then do visual select(line wize) and type '<c-y>,'.
  If you request 'Tag:', then type 'ul>li*'.
  ---------------------
  <ul>
      <li>test1</li>
      <li>test2</li>
      <li>test3</li>
  </ul>
  ---------------------

...

12. Make anchor from URL

  Move cursor to URL
  ---------------------
  http://www.google.com/
  ---------------------
  Type '<c-y>a'
  ---------------------
  <a href="http://www.google.com/">Google</a>
  ---------------------

哇,那是 Ruby 的创造者吗? - tjklemz

16

映射

我喜欢尽可能简单地使用快捷键立即关闭我的块标签(与内联标签相对),并避免使用特殊键,如CTRL,尽可能地简化操作。当我开始编写块标签时,我喜欢使用这个快捷方式(感谢@kimilhee的回答; 这是他回答的改进版):

inoremap ><Tab> ><Esc>F<lyt>o</<C-r>"><Esc>O<Space>

示例用法

类型:

<p>[Tab]

结果——

<p>
 |
</p>

其中|表示光标位置。

解释

  • inoremap表示在插入模式下创建映射
  • ><Tab>表示一个右尖括号和一个制表符;这是要匹配的内容
  • ><Esc>表示结束第一个标记并从插入模式中退出到普通模式
  • F<表示查找最后一个左尖括号
  • l表示将光标向右移动一位(不复制左尖括号)
  • yt>表示从光标位置复制到下一个右尖括号之前(即复制标记内容)
  • o</表示在插入模式下开始新行并添加一个左尖括号和一个斜杠
  • <C-r>"表示从默认寄存器(")中在插入模式下粘贴
  • ><Esc>表示关闭闭合标记并从插入模式中退出
  • O<Space>表示在光标上方插入一个新行并插入一个空格

哇,是啊,我从来没有想过 l 表示的是“右”而不是“左”,哈哈...多么有趣的错误。你觉得我的帖子怎么样?我注意到你没有点赞。 - Keith Pinson
当然不错。最近我开始使用xml.vim插件(它的确非常好用)。我建议您将其添加到您的.vimrc文件中,并使用特定于文件类型的自动命令,例如:au filetype html inoremap <buffer> ... - wds
1
最终,一种自动关闭命令如此完美地发挥作用——简单易懂! - cnp
1
我喜欢将光标保持在标签之间,因此我修改了它以适应我的需求。inoremap ><Tab> ><Esc>F<lyt>o</<C-r>"><Esc>kJxi 我删除了 0<Space> 并添加了 kJxi。 向上移动一步,连接两行,删除一个字符,然后进入插入模式。 - Samundra

11

查看 vim-closetag

它是一个非常简单的脚本(也可以作为vundle插件使用),可以自动关闭(X)HTML标签。来自它的README

如果这是当前内容:

<table|

现在你按下>键,内容将变为:

<table>|</table>

如果您再次按下>,内容将变为:

<table>
   |
</table>
请提供需要翻译的具体内容,谢谢。

7

1
太棒了回答!!!没有插件!!!(第二个项目链接已经失效),但仍然可能是最好的答案,因为修改 .vimrc 文件似乎比处理插件更快。此外,这是最简约的回答。 - nilon
这会在闭合标签后添加空格 :( - Vitaly Zdanevich

6

allml(现在是Ragtag)和Omni-completion(<C-X><C-O>)在像.py或.java这样的文件中不起作用。

如果您想在这些文件中自动关闭标签,可以映射如下。

imap <C-j> <ESC>F<lyt>$a</^R">

( ^R 是 Contrl+R:您可以像这样输入 Control+v 然后 Control+r )

(| 是光标位置) 现在如果您键入...

<p>abcde|

并键入^j

那么它会像这样关闭标签。

<p>abcde</p>|


使用 imap <C-j> <ESC>mfF<lyt>`fa</<C-R>"> 命令,克隆标签将出现在你输入 ^j 的光标位置,而不是行尾 ($)。 - Pietro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接