Plugins Eclipse CDT插件-操作仅限于函数名

Plugins Eclipse CDT插件-操作仅限于函数名,plugins,eclipse-plugin,editor,eclipse-cdt,plugin.xml,Plugins,Eclipse Plugin,Editor,Eclipse Cdt,Plugin.xml,目前我正在为EclipseCDT开发一个插件。我已成功地在plugin.xml文件中声明了操作 <extension point="org.eclipse.ui.popupMenus"> <objectContribution id="MyOwnPlugin.contribution1" nameFilter="*.c" objectClass="org.eclipse.ui.IEditorInput">

目前我正在为EclipseCDT开发一个插件。我已成功地在plugin.xml文件中声明了操作

<extension
     point="org.eclipse.ui.popupMenus">
  <objectContribution
        id="MyOwnPlugin.contribution1"
        nameFilter="*.c"
        objectClass="org.eclipse.ui.IEditorInput">
     <action
           class="myownplugin.popup.actions.DoTestsAction"
           enablesFor="1"
           id="myownplugin.doTests"
           label="Do Tests"
           menubarPath="additions">
     </action>
  </objectContribution>
</extension>

当我右键单击编辑器并选择操作时,这将成功声明一个弹出操作

但是,我想实现的是,只有在我右键单击函数名/函数声明时,操作才会出现。有没有办法做到这一点?我一直在plugin.XML中尝试filter XML标记,但没有成功


谢谢

我自己也没有尝试过,但我相信你想要的是可行的(将评论中描述的点击位置与插入符号位置问题进行模块化)。您使用
元素的方法是正确的,但要使其正常工作,还需要其他一些步骤


首先要认识到的是上下文菜单与对象相关,对于编辑器的上下文菜单,该对象是表示编辑器选项卡内容的
IEditorInput

任何使上下文菜单操作的存在依赖于某些条件的机制,都只能将该对象作为输入。因此,条件必须基于对象的状态(仅限)。这就是为什么我们可以基于插入符号位置而不是单击本身的位置:“编辑器中的当前插入符号位置”是
IEditorInput
状态的一部分,但“编辑器中当前单击的位置”不是(据我所知)


元素的

此元素用于评估每个对象的属性状态 在当前选择中。仅当选择中的每个对象 具有指定的属性状态。选择中的每个对象都必须 实现或适应org.eclipse.ui.IActionFilter

之所以提到“选择”,是因为在某些视图中,可以在选择多个对象的情况下调用上下文菜单(例如,在Project Explorer视图中,选择多个文件/文件夹)。在不适用的编辑器上下文中;“选择”中只有一个对象,类型为
IEditorInput

不幸的是,
IEditorInput
没有实现
IActionFilter
。但是,它确实实现了
IAdaptable
,因此我们可以使用,让我们的插件支持将其调整为
IActionFilter

这将涉及到在
plugin.xml中添加类似的内容:

  <extension point="org.eclipse.core.runtime.adapters">
     <factory 
        class="your.plugin.EditorInputAdapterFactory" 
        adaptableType="org.eclipse.ui.IEditorInput">
        <adapter type="org.eclipse.ui.IActionFilter"/>
     </factory>
  </extension>
其中,
EditorInputActionFilter
也是我们要编写的类型


好的,现在我们有了一个操作过滤器,它可以处理
IEditorInput
对象,使我们能够使用
元素

元素使用一个“属性名”和一个“属性值”,这将被传递给
IActionFilter
。作为动作过滤器的作者,我们开始发明这些。例如,我们可以创建一个名为StReDeleMyType < /C> >的属性名(其中“选择元素”是指插入符号当前的C++元素的类型),以及一个名为“代码>函数 < < /P>的值”。 然后我们的过滤器声明将如下所示:

public class EditorInputAdapterFactory implements IAdapterFactory {
    @Override
    public <T> T getAdapter(Object adaptable, Class<T> adapterType) {
        if (adaptable instanceof IEditorInput && adapterType.equals(IActionFilter.class)) {
            return new EditorInputActionFilter((IEditorInput) adaptable);
        }
        return null;
    }
}
<filter name="selectedElementType" value="function" />


最后,我们需要实现我们的操作过滤器,以便它评估我们为
IEditorInput
对象定义的属性。我不会在这里详细介绍完整的实现,但要概括如下:

  • 使用
    CDTUITools.getWorkingCopyManager()
    ieditor输入映射到
    IWorkingCopy
    ,后者实现了
    ITranslationUnit
  • 使用类似于
    CUIPlugin.getActivePage().findEditor(editorInput.getEditorSite().getSelectionProvider().getSelection()
    (中间有适当的空检查)的内容获取编辑器的当前插入符号位置。也许有一种更简单的方法可以做到这一点,但这就是我想到的。由于您在编辑器中,因此返回的选择应具有类型
    ITextSelection
  • 使用
    SharedASTJob
    访问编辑器的共享AST(
    IASTTranslationUnit
    )。请注意,您需要在作业上阻塞,并且(我假设)将在UI线程上调用操作过滤器,这并不理想。(更多信息请参见下文。)
  • 使用
    IASTTranslationUnit.getNodeSelector(null).findEnclosingName(偏移量,长度)
    ,使用
    ITextSelection
    的偏移量和长度,以获得表示插入符号下名称的
    IASTName
  • 使用
    IASTName.resolveBinding()
    获取名称所引用的绑定(C++语义模型对象)
  • 检查绑定是否实现了
    IFunction
所有这些都将在
IActionFilter.testAttribute()的实现中实现。该函数的
target
参数将是
IEditorInput
。为了更好地测量,在执行任何操作之前,应检查
名称
参数是否与您创建的属性名称相对应(
selectedElementType
函数
)(最初,您的操作筛选器将仅由
元素调用,因此它们将始终匹配,但您可以想象将来扩展此机制以支持其他选定的元素类型。)


最后一个关于性能的注释:你在这里做的是调整UI元素的响应性(弹出窗口的外观)在C++代码的属性上,这可能是解析和分析的慢。这必然意味着弹出窗口可能需要更长的时间才能出现。(这反映在您需要在

SharedASTJob
上阻止的操作筛选器中)。通过使用
SharedASTJob
,您可以通过重新使用已解析的AST(如果存在),例如,如果您刚刚打开一个编辑器并