简体   繁体   English

Vim:将地图转换为命令

[英]Vim: Convert map to command

I'd like to convert this map to a command . 我想将此map转换为command I've tried the "obvious," copying the command part of the map line to a command line: 我尝试过“明显的”,将map行的命令部分复制到command行:

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

However, when using this with selected text it just fails with " E481: No range allowed ". 但是,当使用选定的文本时,它只会失败“ E481: No range allowed ”。 My Google-fu is not strong enough, and the manual is ... computer parseable, let's say. 我的Google-fu不够强大,而且手册是...计算机可解析的,让我们说。

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

This command is dirty as it clobbers the unnamed register. 这个命令很脏,因为它破坏了未命名的寄存器。

To avoid this you must save the register and restore it when you are done. 为避免这种情况,您必须保存寄存器并在完成后将其恢复。 The best way to do this is by using a function. 最好的方法是使用一个函数。

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

Here's a different approach that makes use of only 2 commands ( :call and :delete ). 这是一种不同的方法,只使用2个命令( :call:delete )。 The process is explained below. 该过程解释如下。

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

Notice that I used 3 lines with the correspondent continuation characters for the sake of readability, but you could have used only one. 请注意,为了便于阅读,我使用了3行和相应的连续符,但是你只能使用一行。

The command itself 命令本身

The command is defined as "Sort" and has two special characteristics: 该命令定义为“排序”,具有两个特殊特征:

  • -range makes it able to receive a range, obviously. 显然, -range使它能够接收范围。 Also, it sets the default range to the current line (see help for :command-range ). 此外,它将默认范围设置为当前行(请参阅help :command-range )。
  • -nargs=0 could be omitted, as it will only guarantee that you or future users of your command won't pass any arguments to it. -nargs=0可以省略,因为它只能保证您或您未来的命令用户不会传递任何参数。

Before the command is processed, the text marked as <line1> will be replaced by the line number of the range start. 在处理命令之前,标记为<line1>的文本将替换为范围start的行号。 Similarly, <line2> will be replaced by the line number of the range end. 类似地, <line2>将被范围结束的行号替换。 Check help on <line1> and subsequent lines to know more about replacement text in commands. 检查<line1>和后续行的帮助,以了解有关命令中替换文本的更多信息。

What it does 它能做什么

The command will execute its task in two takes. 该命令将在两次执行中执行其任务。 The first is a chain of functions that can be read from inside out. 第一个是可以从里到外读取的一系列功能。 Let's consider the command was called with a visual selection range ( '< , '> ) that translates as (1,3). 让我们考虑使用视觉选择范围( '<'> )调用命令,该范围转换为(1,3)。 The functions will be executed as: 这些功能将执行为:

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

From a different point of view: 从不同的角度来看:

#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

If you started with this text: 如果你开始使用这个文本:

f e
d c
b a

Now you should have this: 现在你应该有这个:

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

It's just a matter of deleting those lines. 这只是删除这些行的问题。 This is exactly that the next part of the command does: 这正是命令的下一部分:

1,3d _

d is a short for the ex command :delete , and _ is the register to put the deleted text in. In this case, it's the black hole register. d是ex命令的缩写:delete_是将删除的文本放入的寄存器。在这种情况下,它是黑洞寄存器。

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

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