我想将this map
转换为command
。我尝试过“明显的”,将map
行的命令部分复制到command
行:
command SortWords d:execute 'normal i' . join(sort(split(getreg('"'))), ' ')<CR>
但是,在选定文本中使用它时,它只会以“E481: No range allowed
”失败。我的Google-fu不够强大,而且手册是......计算机可解析的,让我们说吧。
答案 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寄存器。