APIs to perform a global search and replace

I'm attempting to write a plug-in to automate a global search and replace/"Replace in Path" task that I perform often.  Basically, I'd like to write a plugin which performs a global search and replace on all files (regardless file type, regardless if they are open in the editor or not) in the project.

I'm in the process of learning the plugin SDK... I've created the basis of the plugin, created some UI, but now I could use some help performing the sarch and replace.  Are there any APIs or classes I can use to perform a global search and replace?  (I've been searching through the online docs, as well as the "200+ open-source third-party plugins" but haven't come across what I need yet)l.

Thanks,

Jeff

6 comments
Comment actions Permalink

Do you want to see a preview of the usages before replacement, or do you want to replace all occurrences globally without any extra prompts for the user?

0
Comment actions Permalink

No preview, without any UI promts.

Thanks,

Jeff

0
Comment actions Permalink

Such an operation is never used in IntelliJ IDEA, so we don't have any API for it. All our existing APIs for global search & replace are integrated with the UI: they show progress as they run and display results in the Usages view. You can of course implement the operation yourself, using something like ProjectFileIndex.getInstance(project).iterateContent() to scan all the files, LoadTextUtil.loadText() to load the text of each file and a simple string search & replace to perform the replacement.

0
Comment actions Permalink

Thanks Dmitry, that helps a lot.
Here's my current code, in which I'm searching files for "abc" and replacing with "xyz".

1) I'm still getting my feet wet, so if this is the wrong approach, please let me know.
2) I'm getting the CharSequence from the VirtualFile, then making a copy into a String.  This seems a bit wasteful, but it works.  Is there a better way?
3) Once I've called replace(), how do I set the contents of the VirtualFile to the str?


 
final ContentIterator contentIterator = new ContentIterator()
{
   public boolean processFile(final VirtualFile child)
   {
      try
      
{
         if( child.isValid() ) {
            if ( !child.isDirectory() ) {
               CharSequence charSequence = LoadTextUtil.loadText(child);
               String str = charSequence.toString();
               str = str.replace("abc", "xyz");

               ???

           }
         }

        return true;
      } catch(Exception ex) {
 
        return true;
      }
   }
};

 
if(projectFileIndex.iterateContent(contentIterator) == true) {
   FileDocumentManager.getInstance().saveAllDocuments();
}
0
Comment actions Permalink

One way is to use LoadTextUtil.write(). A probably better solution (that deals with unsaved documents correctly) is to use FileDocumentManager: use FileDocumentManager.getDocument(VirtualFile).getText() to get the text and Document.setText() to change the context after replacing.

0
Comment actions Permalink

Thanks Dmitry!  That's all I needed.  I've got it up and running now.

Thanks,

Jeff

0

Please sign in to leave a comment.