繁体   English   中英

Vim:将地图转换为命令

[英]Vim: Convert map to command

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

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

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

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

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

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

请注意,为了便于阅读,我使用了3行和相应的连续符,但是你只能使用一行。

命令本身

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

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

在处理命令之前,标记为<line1>的文本将替换为范围start的行号。 类似地, <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_是将删除的文本放入的寄存器。在这种情况下,它是黑洞寄存器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM