How to allow Rename Refactoring to handle spaces in referencing Elements?

I have implemented references between wiki links in the MultiMarkdown plugin and the file that they are refering to.

I can rename the file and all the links refering to it get renamed. Awesome.

I can also do rename on the link and the file rename dialog opens.

1. However, if the file name contains dashes (which in the link become spaces) or other non-identifier characters, the link still refers to the correct file, I traced it and can do rename refactoring on the link and the file rename dialog opens, but when the file is renamed its refering links do not get renamed.

Something seems to filter references based on the text they contain because I traced the code as far as I could in the action and the usageInfo is empty if the links have non-standard characters but the links still return references that resolve to the correct PsiFile as witnessed by rename on the link opening the file rename dialog.

2. Additionally, two links refering to the same file will not get wordhighlighted when the caret is on one of them if the link has a space but will highlight if the link has no spaces. They will highlight if the link has non-standard identifier characters like @.

3. Not refactoring but completions, work fine for spaces or no spaces but if the link has non-standard chars @ then hitting tab on a completion replaces text only to the @ and not the full node's text. This too requires to override, implement something to allow replacing of the whole text of the element.

I implemented a Manipulator, NamesValidator, UsagesProvider, RefactoringSupportProvider, ReferenceContributor, CompletionContributor.

What extensions/interfaces/listeners do I need to implement so that I can override the behaviour in these 3 cases. It seems they have similar but not identical causes so I am assuming I will need to address them separately.

I have spent two days reading code, posts, searching the docs and got it working to this point but I did not find anything that deals with non-standard identifier refactoring or code completion.

Any pointer in the right direction will be greatly appreciated.


Here is the 10 cent solution. After all the hours of work searching, tracing, single-stepping all it took to solve the problem is:

public class MultiMarkdownReferenceSearch extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {     public MultiMarkdownReferenceSearch() {         super(true);     }     @Override     public void processQuery(@NotNull ReferencesSearch.SearchParameters p, @NotNull Processor<PsiReference> consumer) {         final PsiElement refElement = p.getElementToSearch();         String text = null;         if (refElement instanceof MultiMarkdownFile) {             text = ((MultiMarkdownFile) refElement).getWikiPageRef();         }         if (StringUtil.isNotEmpty(text)) {             final SearchScope searchScope = p.getEffectiveSearchScope();             p.getOptimizer().searchWord(text, searchScope, refElement.getLanguage().isCaseSensitive(), refElement);         }     } }

and this added to the plugin.xml:

    <referencesSearch implementation="com.vladsch.idea.multimarkdown.language.MultiMarkdownReferenceSearch"/>

I love IntelliJ IDEA. When you figure out how to do it and how simple it is once you figure it out, you realize how brilliantly it is designed. The more I get to know the code (which I barely scratched the surface) the more I love its power. Amazing job done by the developers. I learn from the code every time I have to dive into it.


Thank you gentlemen for guiding me in the right direction. The plugin is now working. Some minor glitches but I think I have the experience to dive deeper into the code. ;)


> The plugin is now working.


Well done Vladimir.

Cheers for posting the solution.

It is important to mention that I first learnt about QueryExecutorBase from Sergey Ignatov's code:

Thanks go to him, too.


Please sign in to leave a comment.