如何为 Android Studio 制作一个简单的自定义鼠标悬停提示插件

How to make a simple plugin for Android Studio for custom mouse hover hint

在我 Android Studio 的 java 项目中,我有一个枚举,该枚举成员用作字符串数组中的索引以进行本地化。我不使用标准 Android 本地化工具,因为项目是可移植的。 我发现将鼠标移到枚举值上以查看相应字符串的前 50 个符号的提示会很方便。 Psevdocode 非常简单:

if classOf({word-under-mouse}) is MyStrIndEnum 
   then Hint(StringsArray[MyStrIndEnum.{word-under-mouse}.ordinal()]). 

但是是否可以编写脚本、插件或其他东西让 Android Studio 执行此操作? 我从来没有为 IDE 写过插件,所以请指教该走哪条路,为了方便而把它搞砸是否值得。

要做到这一点,必须使用 IntelliJ Idea 和子类 JavaDocumentationProvider 编写插件。

以防万一有人感兴趣:

in build.gradle: 
intellij {
    plugins 'java'
    plugins 'android'
    version '191.8026.42'
    type 'IC'
}
runIde {
    ideDirectory 'C:/Program Files/Android/Android Studio'
}

在plugin.xml中:

   <extensions defaultExtensionNs="com.intellij">
           <lang.documentationProvider order="first" language="JAVA" implementationClass="smpxg.TranslationDocumentationProvider" />
    </extensions>

其余 - 默认。

TranslationDocumentationProvider.java: (虽然 isTextEnum 和 getTextForEnum 方法特定于我的案例)

    public class TranslationDocumentationProvider extends JavaDocumentationProvider
    {
        @Override
        public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement)
        {
            if (isTextEnum(element))
            {
                return getTextForEnum(element);
            }
            else
            {
                return super.getQuickNavigateInfo(element, originalElement);
            }
        }

String getTextForEnum(PsiElement element)
    {
        final PsiClass base = JavaPsiFacade.getInstance(element.getProject()).findClass("smpxg.langloc.RstEng", element.getResolveScope());
        if (base != null)
        {
            String const_name = element.getText();
            String src        = base.getText();
            int    ind        = src.indexOf("ELT." + const_name);
            int    len        = ("ELT." + const_name).length();
            if (ind != -1)
            {
                int    ind1 = src.indexOf('\n', ind + len);
                String s    = "";
                if (ind1 == -1)
                    s = src.substring(ind + len);
                else
                    s = src.substring(ind + len, ind1);
                if (s.length() > 0)
                {
                    int from = 0;
                    for (int i = 0; i < s.length(); i++)
                    {
                        if (Character.isLetterOrDigit(s.charAt(i)))
                            break;
                        from++;
                    }
                    int to = s.length() - 1;
                    for (int i = s.length() - 1; i >= 0; i--)
                    {
                        if (Character.isLetterOrDigit(s.charAt(i)))
                            break;
                        to--;
                    }
                    if (from < to)
                    {
                        s = s.substring(from, to + 1);
                        if (s.length() > 150)
                            s = s.substring(0, 150) + "...";
                        return "<b>Eng:</b> " + s;
                    }
                }
            }
        }
        return element.getText();
    }

boolean isTextEnum(PsiElement element)
    {
        if (element != null)
        {
            ASTNode ast_node = element.getNode();

            if (ast_node == null)
            {
                return false;
            }
            String element_type = ast_node.getElementType().toString();
            if (element_type.equals("ENUM_CONSTANT"))
            {
                PsiEnumConstantImpl en = null;
                try
                {
                    en = (PsiEnumConstantImpl) element;
                }
                catch (Throwable e)
                {

                }
                if (en != null)
                {
                    PsiClass enum_class = en.getContainingClass();
                    if (enum_class != null)
                    {
                        String class_name = enum_class.getQualifiedName();
                        if (class_name != null && class_name.equals("smpxg.langloc.ELT"))
                            return true;
                    }
                }
            }
        }
        return false;
    }
}