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