CreateFileFromTemplateAction: How to add a file name validator?

Answered

Hi,

I have an action in my custom language plugin that allows users to create new scripts. This action extends CreateFileFromTemplateAction and has the following implementation:

public class NewKobuScriptAction extends CreateFileFromTemplateAction {

public NewKobuScriptAction() {
super("Kobu Script", "Create a new Kobu script", KobuIcons.FILE);
}

@Override
protected void buildDialog(@NotNull Project project, @NotNull PsiDirectory directory, CreateFileFromTemplateDialog.@NotNull Builder builder) {
builder.setTitle("New Kobu Script")
.addKind("Kobu file", KobuIcons.FILE, "Kobu File")
.setValidator(new InputValidator() {
@Override
public boolean checkInput(@NlsSafe String inputString) {
return inputString.matches("[a-zA-Z_][a-zA-Z0-9_]*");
}

@Override
public boolean canClose(@NlsSafe String inputString) {
return true;
}
});
}

@Override
protected @NlsContexts.Command String getActionName(PsiDirectory directory, @NonNls @NotNull String newName, @NonNls String templateName) {
return "Create Kobu Script " + newName;
}
}

It's also registered in the plugin.xml file:

<action id="Kobu.NewKobuScript" class="dev.kobu.intellij.language.actions.NewKobuScriptAction">
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewFromTemplate"/>
</action>

Everything is working fine, except for the file name validation. The input dialog isn't calling the InputValidator's methods, and it accepts any string without blocking.

Is this the correct way to validate the user's input? Or is there a better way? I also tried to use the "com.intellij.lang.namesValidator" extension point, but it seems to be used only for refactoring.

Thanks.

1 comment
Comment actions Permalink

After spending some time debugging the code and reading other plugins implementations, I found a way to validate the file name:

@Override
protected void buildDialog(@NotNull Project project, @NotNull PsiDirectory directory, CreateFileFromTemplateDialog.@NotNull Builder builder) {
builder.setTitle("New Kobu Script")
.addKind("Kobu file", KobuIcons.FILE, "Kobu File")
.setValidator(new InputValidatorEx() {
@Override
public @NlsContexts.DetailedDescription @Nullable String getErrorText(@NonNls String inputString) {
if (inputString.isBlank()) {
return "Name can't be empty";
} else if (!inputString.matches("[a-zA-Z_][a-zA-Z0-9_]*")) {
return "Invalid name";
}
return null;
}

@Override
public boolean canClose(String inputString) {
return getErrorText(inputString) == null;
}
});
}

The main point is that the "canClose" method should return true only if the input is valid. Also, implementing "InputValidatorEx" instead of "InputValidator" allows customizing the error message.

Thanks.

1

Please sign in to leave a comment.