ClassName completion in custom language
Let's assume I have a minimal custom language. The language actually only contains references to Java project/library classes, with some minimal syntax:
-
{
...java.lang.String,
...org.foo.Bar,
...java.util.LinkedList
}
-
(above snippet would be a valid example of the language)
Now, when I type a Java classname in this language, I'd like to have the convenience of ClassName completion:
-
{
...java.lang.String,
...SDF<Ctrl-Alt-Space> // Should suggest 'java.text.SimpleDateFormat' and other matches
}
-
It seems I'm looking for two pieces of functionality:
1) Given a CamelHumps pattern, find a list of matching types.
In addition, I'd like to filter in arbitrary ways, for example: "both abstract and concrete classes, but no interfaces or enums"
I suspect this is the OpenAPI somewhere.
2) A way to hook into the ClassNameCompletion action.
In this case, the custom language would not be injected (separate filetype), if that makes any difference.
If this is not possible at the moment, I'll take that for an answer.
Regards,
-tt
(apologies for any duplicate messages, seems posting to the openapi group is a bit unreliable today)
Please sign in to leave a comment.
I don't think there's any dedicated API to extend the ClassNameCompletion (just the same as for SmartCompletion). The most promising approach might be to subclass com.intellij.codeInsight.completion.actions.ClassNameCompletionAction and to register the action either with a custom shortcut or to hook the original action.
You can probably post-process the result you get from the original completion handler (or the CompletionData it uses) to filter out stuff you don't want in a certain situation.
Sascha
How do I hook an existing action? (For a specific filetype only, if possible)
I have not done any tests yet, but the more I think about it the less likely it seems this will work. The original completion handler should not be able to do anything meaningful, because my language will be totally unknown to it.
In this case I have my own FileType, if I do CompletionUtil.registerCompletionData(), will that provide me with something usable?
I think that I can implement the actual work that "Class-Completion" does, in the context of my language. It seems the only thing I want do is: block the call to the regular ClassNameCompletionAction, and execute my own action instead, but only when the current editor has a file of my specific filetype.
See the XSLT support's refactoring actions implementation. The basic procedure is:
- Get old action from ActionManager
- Unregister old action
- Create a wrapper action that either executes custom logic (if the filetype matches) or delegates to the old action
- Register new action with same ID as the old one
I forgot about that, but you should be able to supply your own CompletionData implementation to a subclass of ClassCompletionHandler.
Probably only for the "regular" ctrl-space completion.
Sascha
Ok, this was my first idea: intercept the original action, do the CamelHump matching, filtering, showing popup, etc myself.
Did you mean to type "ClassNameCompletionHandler"? I suppose that that's the default action that runs when I type Ctrl-Alt-Space? I guess this class has a companion in ClassNameCompletionData...
Now, it seems that this duo works in XML attributes as well, so that's encouraging.
However, apart from not understanding what most of the methods on those classes do, don't they contain some dependenies on the Java filetype? Optimizing imports after class completion is one example I can think of.
Yep.
I don't think there are dependencies that would make your use-case impossible to imlpement. AFAIK, e.g. the generation of an import statement is done by PsiManager.getCodeStyleManager().shortenClassReferences().
Sascha
I'll certainly try to make your suggestion work.
Just for my own understanding, how does the ClassNameCompletionHandler operate? I mean, I have my own custom PSI, so that is out of the question.
Is it likely that it just looks at the caret position, and tries to match a CamelCase string up to certain terminal characters?