当前位置:K88软件开发文章中心编程工具Vim → 文章内容

Vimscript Potion段移动

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-24 10:54:17

由 Loen 创建, 最后一次修改 2016-02-24 既然知道了段移动的工作原理,让我们重新映射这些命令来使得它们对于Potion文件起作用。首先我们要决定Potion文件中"段"的意义。 有两对段移动命令,所以我们可以总结出两套组合,我们的用户可以选择自己喜欢的一个。让我们使用下面两个组合来决定哪里是Potion中的段:任何在空行之后的,第一个字符为非空字符的行,以及文件首行。任何第一个字符为非空字符,包括一个等于号,并以冒号结尾的行。稍微拓展我们的factorial.pn例子,这就是那些规则当作段头的地方:# factorial.pn 1# Print some factorials, just for fun.factorial = (n): 1 2 total = 1 n to 1 (i): total *= i. total.print_line = (): 1 2 "-=-=-=-=-=-=-=-\n" print.print_factorial = (i): 1 2 i string print '! is: ' print factorial (i) string print "\n" print."Here are some factorials:\n\n" print 1print_line () 110 times (i): print_factorial (i).print_line ()我们的第一个定义更加自由。它定义一个段为一个"顶级的文本块"。第二个定义则严格一点。它定义一个段为一个函数定义。自定义映射在你的插件的repo中创建ftplugin/potion/sections.vim。 这将是我们放置段移动代码的地方。记得一旦一个缓冲区的filetype设置为potion,这里的代码就会执行。我们将重新映射全部四个段移动命令,所以继续并创建一个骨架:noremap <script> <buffer> <silent> [[ <nop>noremap <script> <buffer> <silent> ]] <nop>noremap <script> <buffer> <silent> [] <nop>noremap <script> <buffer> <silent> ][ <nop>Notice that we use?noremap?commands instead of?nnoremap, because we want these to work in operator-pending mode too. That way you'll be able to do things like?d]]?to "delete from here to the next section". 注意我们使用noremap而不是nnoremap,因为我们想要这些命令也能在operator-pending模式下工作。 这样你就能使用d]]命令来删除从这到下一段之间的内容。我们设置映射生效于buffer-local,所以它们只对Potion文件起作用,不会替换全局选项。我们也设置了silent,因为用户不应关心我们实现段移动的细节。使用一个函数每个命令中实现段移动的代码会是非常相似的,所以让我们把它抽象出供映射调用的一个函数。你将在那些创建了一些相似的映射的Vim插件中频繁看到这种策略。 比起把所有的功能堆砌于各个映射中,这样做不仅更易读,而且更易维护。在sections.vim文件中加上下面内容:function! s:NextSection(type, backwards)endfunctionnoremap <script> <buffer> <silent> ]] \ :call <SID>NextSection(1, 0)<cr>noremap <script> <buffer> <silent> [[ \ :call <SID>NextSection(1, 1)<cr>noremap <script> <buffer> <silent> ][ \ :call <SID>NextSection(2, 0)<cr>noremap <script> <buffer> <silent> [] \ :call <SID>NextSection(2, 1)<cr>这里我用到了Vimscript的断行特性,因为我不想看到又长又臭的代码。 注意反斜杠是放在第二行前面进行转义的。阅读:help line-continuation以了解更多。注意我们使用<SID>和一个脚本本地命名空间内定义的函数来避免污染全局空间。每个映射简单地以适当参数调用NextSection实现对应的移动。 现在我们可以开始实现NextSection了。基本移动让我们考虑下我们的函数需要做什么。 我们想要移动光标到下一段,而移动光标,有一个简单的办法就是利用/和?命令。编辑NextSection成这样:function! s:NextSection(type, backwards) if a:backwards let dir = '?' else let dir = '/' endif execute 'silent normal! ' . dir . 'foo' . "\r"endfunction现在这个函数使用我们之前见过的execute normal!来执行/foo或?foo,取决于backwards的值。 这将是个好的开始。继续前进,我们显然需要搜索foo以外的东西,是什么则取决于用的是段头的第一个还是第二个定义。把NextSection改成这样:function! s:NextSection(type, backwards) if a:type == 1 let pattern = 'one' elseif a:type == 2 let pattern = 'two' endif if a:backwards let dir = '?' else let dir = '/' endif execute 'silent normal! ' . dir . pattern . "\r"endfunction现在只需要补上匹配的模式了(pattern),让我们继续完成它吧。顶级文本段用下面一行替换掉第一个let pattern = '...':let pattern = '\v(\n\n^\S|%^)'如果不理解这个正则表达式是干什么的,请回忆我们正在实现的"段"的定义。任何在空行之后的,第一个字符为非空字符的行,以及文件首行。开头的\v强制切换为"very magic"模式,一如之前的几次。剩下的正则表达式由两个选项组成。第一个,\n\n^\S,搜索"两个换行符,接着之后是一个非空字符"。 这正好是我们的定义中的第一种情况。另一个是%^,在Vim中,这是一个代表文件开头的特殊正则符号。我们现在已经到了尝试前两个映射的时机了。 保存ftplugin/potion/sections.vim并在你的Potion例子缓冲区中执行:set filetype=potion。?[[和]]命令应该可以工作,但会显得古怪。搜索标记你大概注意到了,在段之间移动时光标会位于真正想要移动到的地方上方的空行。 在继续阅读之前,先想想为什么会这样。问题在于我们使用/(或?)进行搜索,而在默认情况下Vim会把光标移动到匹配开始处。 举个例子,当你执行/foo光标会位于foo中的f。为了让Vim把光标移动到匹配结束处而不是开始处,我们可以使用搜索标记(search flag)。 试试在Potion文件中这么搜索:/factorial/eVim将找到factorial并带你到那。按下几次n来在匹配处之间移动。?e标记将使得Vim把光标移动到到匹配结束处而不是开始处。在另一个方向也试试:?factorial?e让我们来修改我们的函数,用搜索标记来放置光标到匹配的段头的另一端。function! s:NextSection(type, backwards) if a:type == 1 let pat

[1] [2]  下一页


Vimscript Potion段移动