Vim提供非常有用的动作命令以跳转到下一个 方法的开始/结束:] m,] M,[m和] m。
这些适用于Java或类似的结构化语言。 (如:help] m和:help 29.3)
似乎可以将最外层的花括号视为类 声明和下一级花括号作为方法声明。
当有一对外花括号时,这些动作命令不起作用 围绕类定义,这在C#语言中有点常见。
我想知道是否有一些技巧来制作这些命令(单独和 以运算符为前缀,例如y [m,V] M)对此代码起作用:
namespace ABC.DEF
{
class A
{
protected string strID;
public string PortID { get { return strID; } set { strID = value; } }
protected MyType x;
public MyType X
{
get { return x; }
set { x = value; if ( x != null ) func1(); }
}
int func1()
{
return 1;
}
int func2(int flag)
{
if (flag == 0)
return flag;
if (flag > 3)
{
return flag;
}
return 2;
}
int func3()
{
return 3;
}
}
}
答案 0 :(得分:5)
我不认为]m
映射族可以自定义。在这种情况下,通常的做法是使用自定义逻辑覆盖它。我提出了一些vimscript,应做你所描述的。基本上,它跳过花括号,并查看相关的行来决定做什么。在这种情况下,它只是忽略“class”和“namespace”声明。
nnoremap <buffer> ]m :<c-u>call <SID>JumpMethod('{', 'W', 'n')<cr>
nnoremap <buffer> [m :<c-u>call <SID>JumpMethod('{', 'Wb', 'n')<cr>
nnoremap <buffer> ]M :<c-u>call <SID>JumpMethod('}', 'W', 'n')<cr>
nnoremap <buffer> [M :<c-u>call <SID>JumpMethod('}', 'Wb', 'n')<cr>
xnoremap <buffer> ]m :<c-u>call <SID>JumpMethod('{', 'W', 'v')<cr>
xnoremap <buffer> [m :<c-u>call <SID>JumpMethod('{', 'Wb', 'v')<cr>
xnoremap <buffer> ]M :<c-u>call <SID>JumpMethod('}', 'W', 'v')<cr>
xnoremap <buffer> [M :<c-u>call <SID>JumpMethod('}', 'Wb', 'v')<cr>
onoremap <buffer> ]m :<c-u>call <SID>JumpMethod('{', 'W', 'o')<cr>
onoremap <buffer> [m :<c-u>call <SID>JumpMethod('{', 'Wb', 'o')<cr>
onoremap <buffer> ]M :<c-u>call <SID>JumpMethod('}', 'W', 'o')<cr>
onoremap <buffer> [M :<c-u>call <SID>JumpMethod('}', 'Wb', 'o')<cr>
function! s:JumpMethod(char, flags, mode)
let original_cursor = getpos('.')
if a:mode == 'v'
normal! gv
elseif a:mode == 'o'
normal! v
endif
while search(a:char, a:flags) > 0
if a:char == '}'
" jump to the opening one to analyze the definition
normal! %
endif
let current_line = line('.')
if getline(current_line) =~ '^\s*{'
" it's alone on the line, check the above one
let method_line = current_line - 1
else
let method_line = current_line
endif
let method_line_body = getline(method_line)
if method_line_body =~ '\k\+\s*(.*)' && method_line_body !~ '\<\(for\|foreach\|if\|while\|switch\|using\|catch\|get\|set\)\>'
" it's probably a function call
if a:char == '}'
" we need to go back to the closing bracket
normal! %
endif
echo
return
else
if a:char == '}'
" we still need to go back to the closing bracket
normal! %
endif
endif
endwhile
" if we're here, the search has failed, restore cursor position
echo
call setpos('.', original_cursor)
endfunction
请记住,我并不是很了解很多C#,所以它可能在所有情况下都无法正常工作,但如果你给我一些破解的例子,我或许可以找出一些东西。
要尝试它,你应该把它放在你的vimfiles目录下的“ftplugin”下,作为“cs.vim”。任何其他以“cs”开头并以“.vim”结尾的文件名也是好的,如果你已经有一个“cs.vim”文件。
答案 1 :(得分:3)
OmniSharp现在有:OmniSharpNavigateUp
和:OmniSharpNavigateDown
。它始终是&#34;开始&#34; (因此这适用于]m
和[m
映射。我在ftplugin\cs.vim
nnoremap <buffer> ]m :OmniSharpNavigateDown<cr>
nnoremap <buffer> [m :OmniSharpNavigateUp<cr>
nnoremap <buffer> ]M :OmniSharpNavigateDown<cr>
nnoremap <buffer> [M :OmniSharpNavigateUp<cr>
xnoremap <buffer> ]m :OmniSharpNavigateDown<cr>
xnoremap <buffer> [m :OmniSharpNavigateUp<cr>
xnoremap <buffer> ]M :OmniSharpNavigateDown<cr>
xnoremap <buffer> [M :OmniSharpNavigateUp<cr>
onoremap <buffer> ]m :OmniSharpNavigateDown<cr>
onoremap <buffer> [m :OmniSharpNavigateUp<cr>
onoremap <buffer> ]M :OmniSharpNavigateDown<cr>
onoremap <buffer> [M :OmniSharpNavigateUp<cr>
答案 2 :(得分:2)
几个星期前,在vim邮件列表上提出了类似的问题,但是对于C ++。 这是the solution I came up with。
它依赖于ctags和我的一些其他插件:lh-dev,lh-tag和lh-vim-lib。 您可以通过vim-addon-manager安装lh-dev,这将依次安装lh-tag和lh-vim-lib。
HTH,
答案 3 :(得分:2)
Andrew Radev给出了一个答案,idbrii变成了一个插件。
我在这里修改了该插件:https://github.com/RobertCWebb/vim-jumpmethod/
我修复了各种问题,并为[[和]]添加了改进的映射
关于后者,我发现停止类定义和属性也更有用。
C#中的属性可以包含get和set方法,但我认为仅在属性本身的定义处停止一次就足够了。
对于类,我注意到我会从一个函数中的方法跳转到另一个函数中的方法,甚至没有意识到我在另一个类中。对我来说这似乎很危险,所以也很高兴停在类定义上。 [[和]]映射将执行此操作。
答案 4 :(得分:0)
你可以使用9]}。它有点被迫,但是嘿,它有效。