Auto-closing braces in a custom language, BraceMatcher not working
I'm working on a custom language plugin, and am trying to get matching braces to be automatically inserted. Aka. if I type "(", I want intellij to automatically add a matching ")". From the documentation, I should implement a PairedBraceMatcher:
public class DBraceMatcher implements PairedBraceMatcher {
private static final BracePair[] PAIRS = new BracePair[]{
new BracePair(DLanguageTypes.OP_PAR_LEFT, DLanguageTypes.OP_PAR_RIGHT, false),
new BracePair(DLanguageTypes.OP_BRACES_LEFT, DLanguageTypes.OP_BRACES_RIGHT, true),
new BracePair(DLanguageTypes.OP_BRACKET_LEFT, DLanguageTypes.OP_BRACKET_RIGHT, false),
};
@Override
public BracePair[] getPairs() {
return PAIRS;
}
@Override
public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) {
return true;
}
@Override
public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
return openingBraceOffset;
}
}
And then register the brace matcher in plugin.xml:
<lang.braceMatcher language="D" implementationClass="net.masterthought.dlanguage.features.DBraceMatcher"/>
For some reason I am not getting autoclosing braces, and when running under debugger the method "isPairedBracesAllowedBeforeType", seems to never be called.
Thanks in advance for any help.
Please sign in to leave a comment.
Try to debug com.intellij.codeInsight.editorActions.TypedHandler#handleAfterLParen method.
I had this same problem because I was trying to match angle brackets ("<>"), and after doing some I discovered that in com.intellij.codeInsight.editorActions.TypedHandler#handleAfterLParen(), it checks to see if an angle bracket was inputted:
BUT! It only ever gets called in com.intellij.codeInsight.editorActions.TypedHandler#execute() like this:
Notice that lparenChar can never be "<" because handleAfterParen() only gets called if the character typed is "(", "[", or "{". So this seems to me to be a bug, because "<" can be matched pretty often. Although, it would make sense to me to allow ANY brace pairs specified in the PairedBraceMatcher to be auto-paired instead of just the 3 or 4 specified here. For example, if you a brace pair for ("BEGIN", "END") and you wrote "Here's my story BEGIN", intellij would automatically add "END" after your caret.
But if they never fix this, the way I solved it was by implementing a TypedHandlerDelegate (which can be added the plugin with the com.intellij.lang.typedHandler extension) then basically copied the code from handleAfterLParen and adjusted it to my needs into the charTyped() method.
I'm facing the same issue, basically the same code as yours but none of the braces (i.e {, (, [) get completion and isPairedBracesAllowedBeforeType doesn't get invoked at all. Does it have any prerequisites? Do I have to add anything other than braceMatcher in plugin.xml or anywhere else in the codebase?
Have you found a solution to this problem?
I faced the same issue and looked at the java plugin for reference. They add a custom TypedHandlerDelegate to handle this case. An implementation might look like this
I recommend looking at the docs and implementation of TypedHandlerUtil to get a better understanding of this code snippet.
References:
https://github.com/JetBrains/intellij-community/blob/master/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java#L109-L119
https://github.com/JetBrains/intellij-community/blob/3a9d9eccaf61e4583d46d889698a09f681647208/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java#L327
Additionally, I can recommend adapting their brace matcher as well if you don't want highlighted braces for </> in normal expressions. You might only want this for generic parameter as an example. This can be achieved with a custom brace matcher like this (requires dependency on "com.intellij.java")
Reference:
https://github.com/JetBrains/intellij-community/blob/6dec3dca0e3675e048dc3665a99f65721c584e42/java/java-impl/src/com/intellij/codeInsight/highlighting/JavaPairedBraceMatcher.java