49

假设我有一个标签(光标位于 *):

<h1 class="blah" id="moo">H*ello!</h1>

我想将其更改为:

*<h2 class="blah" id="moo">Hello</h2>

即更改标签的类型,但保留所有元素。

使用环绕.vim,我可以这样做:

cst<h2>

但这会将 HTML 更改为:

*<h2>Hello</h2>

是否可以更改标签,但保留所有属性?环绕文档似乎不包含这样的东西......

4

5 回答 5

122

Surround.vim添加了在保留属性的同时替换标签

cst<p>替换整个标签,而cst<p(不带右括号)保留属性。

于 2015-06-28T10:26:10.547 回答
34

您可以使用cstt它,它会显示<在底部并输入标签名称而不>

在这种情况下,cstth2然后按 Enter。

于 2016-03-10T11:40:05.233 回答
7

我有 xml.vim 插件(https://github.com/othree/xml.vim)。如果你也有,你的要求就很简单了。

只需将光标移动到标签上,按<leader>c(小写 c),然后输入新的标签名,只会更改标签名。

如果您按<leader>C(Big C),还可以重命名标签/元素,但也会删除原始属性。

于 2013-05-03T08:48:36.030 回答
2

Surround 没有内置此功能。您可以<c-r>"拉出属性,然后在输入替换标签时使用以将它们带回来,但这有点蹩脚。

我提出了一个新的映射和函数来自动化这个任务。以下将提供cse映射,也就是更改周围元素。把它放在你的~/.vimrc文件中,或者~/.vim/after/plugin/surround_change_element.vim如果你觉得过于混乱。

function! s:ChangeElement()
  execute "normal! vat\<esc>"
  call setpos('.', getpos("'<"))
  let restore = @"
  normal! yi>
  let attributes = substitute(@", '^[^ ]*', '', '')
  let @" = restore
  let dounmapb = 0
  if !maparg(">","c")
    let dounmapb = 1
    " Hide from AsNeeded
    exe "cn"."oremap > <CR>"
  endif
  let tag = input('<', '')
  if dounmapb
    silent! cunmap >
  endif
  let tag = substitute(tag, '>*$', '', '')
  exe "normal cst<" . tag . attributes . ">"
endfunction
nnoremap cse :call <SID>ChangeElement()<cr>

e注意:如果您通过g:surround_101或创建了任何环境,这将影响某些环境情况b:surround_101。如果是这种情况,请将映射形式更改为cse其他形式,csn以更改周围节点。

编辑

截至 2015 年 2 月 22 日,此答案已过时。请参阅@Wojtek Kruszewski 帖子或:h surround-replacements了解如何在本地使用环绕声来执行此操作。

于 2013-05-02T16:01:45.307 回答
1

就我而言,我会尝试matchit.vimor text-object

matchit.vim 解决方案:

matchit.vim包含在 vim 中。

source $VIMRUNTIME/macros/matchit.vim

然后0l%%lr2<Ctrl-o>llr20

文本对象解决方案:

您还可以在替换之前将 html 内容转移到寄存器中。

dit:.s/h1/h2/g<Ctrl-o>P0

于 2013-05-03T06:19:58.843 回答