Vim:将地图转换为命令

时间:2011-09-14 11:33:27

标签: vim

我想将this map转换为command。我尝试过“明显的”,将map行的命令部分复制到command行:

command SortWords d:execute 'normal i' . join(sort(split(getreg('"'))), ' ')<CR>

但是,在选定文本中使用它时,它只会以“E481: No range allowed”失败。我的Google-fu不够强大,而且手册是......计算机可解析的,让我们说吧。

2 个答案:

答案 0 :(得分:5)

command! -nargs=0 -range SortWords exe 'norm! gvd'|call setreg('"', join(sort(split(@")), ' '), visualmode()[0])|norm! P

这个命令很脏,因为它破坏了未命名的寄存器。

为避免这种情况,您必须保存寄存器并在完成后将其恢复。最好的方法是使用函数。

command! -nargs=0 -range SortWords call VisualSortWords()

function! VisualSortWords()
  let rv = @"
  let rt = getregtype('"')
  try
    norm! gvy
    call setreg('"', join(sort(split(@")), ' '), visualmode()[0])
    norm! `>pgvd
  finally
    call setreg('"', rv, rt)
  endtry
endfunction

答案 1 :(得分:3)

这是一种不同的方法,只使用2个命令(:call:delete)。该过程解释如下。

command! -range -nargs=0 Sort
  \ call append(<line2>,join(sort(split(join(getline(<line1>,<line2>)))), ' ')) |
  \ <line1>,<line2>d _

请注意,我使用了3行与对应的连续符号 为了便于阅读,但你只能使用一个。

命令本身

该命令被定义为“排序”,具有两个特殊的特征:

    显然,
  • -range可以接收范围。而且,它设置了 默认范围为当前行(请参阅:command-range的帮助)。
  • -nargs=0可以省略,因为它只会保证您或将来 命令的用户不会传递任何参数。

在处理命令之前,将替换标记为<line1>的文本 由范围的行号开始。同样,<line2>将被替换为 范围结束的行号。查看<line1>及其后的帮助 行以了解有关命令中替换文本的更多信息。

它做什么

该命令将在两次执行中执行其任务。第一个是链条 可以从里到外读取的功能。让我们考虑命令是 使用视觉选择范围('<'>)调用,转换为(1,3)。该 函数将执行为:

append(3, join(sort(split(join(getline(1,3)))), ' '))

从不同的角度来看:

#1 getline(1,3)  " the result is a list with text from lines 1 to 3
#2 join(#1)      " joins that list into a string
#3 split(#2)     " splits the string on whitespace, resulting in a list
#4 sort(#3)      " sorts that list
#5 join(#4, ' ') " joins the elements into a string separated by single space
#6 append(3, #5) " insert that string after line 3

如果你开始使用这个文字:

f e
d c
b a

现在你应该有这个:

f e
d c
b a
a b c d e f

这只是删除这些行的问题。这正是下一部分 命令的作用:

1,3d _

d是ex命令:delete的缩写,_是要放入的寄存器 已删除的文本。在这种情况下,它是black hole寄存器。