Answers:
这就是我的做法。将此添加到您的.vimrc
vnoremap if [[O][
说明:vnoremap表示在可视模式下将左侧映射if
到右侧[[mO][
。if
表示In Function,尽管您可以根据需要重命名。[[
跳转到函数的开头。O
移至您视觉选择的文本的另一端,然后][
移至函数的末尾。
因此,如果要搜索功能,则现在使用进入可视模式v
,然后使用选择整个功能if
。现在使用退出可视模式<esc>
,并使用搜索/\%V
。\%V
将您的搜索限制为先前选择的文本。如果您不想打<esc>/\%V
,也可以将其添加到您的.vimrc
:
vnoremap / <esc>/\%V
然后,您的击键顺序将如下所示:
vif/foo<enter>
这将查找当前函数中所有出现的foo。
此方法的唯一缺点是,它期望打开和闭合大括号的缩进均为0。如果您经常使用没有此功能的代码,例如
int foo() {
bar()
}
那么这个稍微复杂一些的版本将可以工作:
vnoremap if ][ma%O'a
这只希望右括号有0个缩进。如果开头括号有凹痕,则它仍然有效,尽管它确实有痕迹。如果您经常使用标记“ a”,则可以移动例如
vnoremap if ][mb%O'b
vnoremap if ][mc%O'c
...
{
,然后使用%
到达底行。不确定如何找到以C ++开头的函数,但是对于Javascript来说可以正常工作:vnoremap if <Esc>?^\s*function<CR>v/{<CR>%o
CTRL-]
跳转到光标下方的标签。没有到当前功能的开始。这不会有帮助。
:linenumber
,vim可以做我在插件中所做的事情。但是不能保证,这些命令可以改为搜索-Vim /pattern
不能测试所有模式来知道哪个模式与当前函数匹配。IOW,我不知道有任何vim动作跳转到当前模式的开始。功能
DJ McMayhem的解决方案激发了我编写依赖ctags和matchit对功能边界进行适当分析的自己的解决方案。
困难的部分已经由lh-dev和lh-tags完成了几年:
template
和inline
部分可能会被ctags遗漏)end
可与C,C ++,Python和Vim一起使用的字段,该字段也可用于查找函数的结尾。注意,该算法的任何部分都可以基于文件类型被覆盖。即python函数的边界检测可以搜索def
和分析缩进,我们可以只function
在javascript中搜索,依此类推-换句话说,当前版本还可以与Java,Vim和其他一些语言一起使用(我仍然有一些工作为Python做)
因此,我现在定义两个新的映射:可视模式映射和操作员待处理的模式映射:
onoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr>
xnoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr><esc>gv
依靠:
function! lh#dev#_select_current_function() abort
let fn = lh#dev#find_function_boundaries(line('.'))
exe fn.lines[0]
normal! v
exe fn.lines[1]
endfunction
我为您节省了几百行代码 lh#dev#find_function_boundaries()
多亏了DJ McMayhem的映射
" Note that my vim settings requires two backslashes here instead of one
vnoremap / <esc>/\\%V
我们可以在当前函数中vif/pattern
进行搜索pattern
。
我们还可以使用删除函数,使用删除dif
它们yif
,等等。
很难找到函数的开头和结尾,尤其是在没有function
关键字的语言中……以及许多相互矛盾的缩进样式。
如果您的函数以单独的右括号结尾(例如,在此处列出的13种样式中的10种),则可以通过以下方式直观地选择它:
xnoremap if /^\s*}<CR><Esc>V%
从那里开始,在foo
函数中进行搜索仅需考虑以下事项:
:'<,'>g/foo/#
放在一起,我们可以得到一个相当不错的映射:
xnoremap if /^\s*}<CR><Esc>V%
nmap <key> vif:g//#<Left><Left>
也就是说,可视模式映射很可能会被a while
或a愚弄,if
因此它可能会受益于一些改进。另外,保持视觉选择可能不是一个好主意……
if
,for
,while
等
另一种方式:
使用Osyo Manga的搜索运算符(取决于vim-operator-user)仅在当前块内搜索。例如:
" configure the plugin (once, vimrc):
map g/ <Plug>(operator-search)
" 1. use ctags etc. to jump to the beginning of the target function;
" 2. move cursor inside the function definition, then:
g/i{
...现在您可以在给定的提示下插入搜索词;点击n
查看如何将搜索结果限制为当前提供的运动/文本对象。由于这是一个Vim(即可组合)运算符,因此,如果您有一个功能良好的文本对象,则在搜索之前甚至不需要在定义体内移动,而是直接使用诸如g/if
或类似的东西。
lh#dev#find_function_boundaries
lh-dev 的函数中执行此操作