@Nullable public static VirtualFile getDirectory(@NotNull final FindModel findModel) { String directoryName = findModel.getDirectoryName(); if (findModel.isProjectScope() || StringUtil.isEmpty(directoryName)) { return null; } String path = directoryName.replace(File.separatorChar, '/'); VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path); if (virtualFile == null || !virtualFile.isDirectory()) { virtualFile = null; for (LocalFileProvider provider : ((VirtualFileManagerEx) VirtualFileManager.getInstance()).getLocalFileProviders()) { VirtualFile file = provider.findLocalVirtualFileByPath(path); if (file != null && file.isDirectory()) { if (file.getChildren().length > 0) { virtualFile = file; break; } if (virtualFile == null) { virtualFile = file; } } } } return virtualFile; }
public void replaceInProject(@NotNull DataContext dataContext) { final FindManager findManager = FindManager.getInstance(myProject); final FindModel findModel = (FindModel) findManager.getFindInProjectModel().clone(); findModel.setReplaceState(true); FindInProjectUtil.setDirectoryName(findModel, dataContext); Editor editor = CommonDataKeys.EDITOR.getData(dataContext); FindUtil.initStringToFindWithSelection(findModel, editor); findManager.showFindDialog( findModel, new Runnable() { @Override public void run() { final PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(findModel, myProject); if (!findModel.isProjectScope() && psiDirectory == null && findModel.getModuleName() == null && findModel.getCustomScope() == null) { return; } UsageViewManager manager = UsageViewManager.getInstance(myProject); if (manager == null) return; findManager.getFindInProjectModel().copyFrom(findModel); final FindModel findModelCopy = (FindModel) findModel.clone(); final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(true, findModelCopy); final FindUsagesProcessPresentation processPresentation = FindInProjectUtil.setupProcessPresentation(myProject, true, presentation); UsageSearcherFactory factory = new UsageSearcherFactory(findModelCopy, psiDirectory, processPresentation); searchAndShowUsages( manager, factory, findModelCopy, presentation, processPresentation, findManager); } }); }
@NotNull public static UsageViewPresentation setupViewPresentation( final boolean toOpenInNewTab, @NotNull FindModel findModel) { final UsageViewPresentation presentation = new UsageViewPresentation(); final String scope = getTitleForScope(findModel); final String stringToFind = findModel.getStringToFind(); presentation.setScopeText(scope); if (stringToFind.isEmpty()) { presentation.setTabText("Files"); presentation.setToolwindowTitle(BundleBase.format("Files in {0}", scope)); presentation.setUsagesString("files"); } else { FindModel.SearchContext searchContext = findModel.getSearchContext(); String contextText = ""; if (searchContext != FindModel.SearchContext.ANY) { contextText = FindBundle.message( "find.context.presentation.scope.label", FindDialog.getPresentableName(searchContext)); } presentation.setTabText( FindBundle.message("find.usage.view.tab.text", stringToFind, contextText)); presentation.setToolwindowTitle( FindBundle.message("find.usage.view.toolwindow.title", stringToFind, scope, contextText)); presentation.setUsagesString(FindBundle.message("find.usage.view.usages.text", stringToFind)); presentation.setUsagesWord(FindBundle.message("occurrence")); presentation.setCodeUsagesString(FindBundle.message("found.occurrences")); presentation.setContextText(contextText); } presentation.setOpenInNewTab(toOpenInNewTab); presentation.setCodeUsages(false); presentation.setUsageTypeFilteringAvailable(true); return presentation; }
private static int addToUsages( @NotNull Document document, @NotNull Processor<UsageInfo> consumer, @NotNull FindModel findModel, @NotNull final PsiFile psiFile, @NotNull int[] offsetRef, int maxUsages) { int count = 0; CharSequence text = document.getCharsSequence(); int textLength = document.getTextLength(); int offset = offsetRef[0]; Project project = psiFile.getProject(); FindManager findManager = FindManager.getInstance(project); while (offset < textLength) { FindResult result = findManager.findString(text, offset, findModel, psiFile.getVirtualFile()); if (!result.isStringFound()) break; final SearchScope customScope = findModel.getCustomScope(); if (customScope instanceof LocalSearchScope) { final TextRange range = new TextRange(result.getStartOffset(), result.getEndOffset()); if (!((LocalSearchScope) customScope).containsRange(psiFile, range)) break; } UsageInfo info = new FindResultUsageInfo(findManager, psiFile, offset, findModel, result); if (!consumer.process(info)) { throw new ProcessCanceledException(); } count++; final int prevOffset = offset; offset = result.getEndOffset(); if (prevOffset == offset) { // for regular expr the size of the match could be zero -> could be infinite loop in finding // usages! ++offset; } if (maxUsages > 0 && count >= maxUsages) { break; } } offsetRef[0] = offset; return count; }
public static void setDirectoryName(@NotNull FindModel model, @NotNull DataContext dataContext) { PsiElement psiElement = null; Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project != null && !DumbServiceImpl.getInstance(project).isDumb()) { try { psiElement = CommonDataKeys.PSI_ELEMENT.getData(dataContext); } catch (IndexNotReadyException ignore) { } } String directoryName = null; if (psiElement instanceof PsiDirectory) { directoryName = ((PsiDirectory) psiElement).getVirtualFile().getPresentableUrl(); } if (directoryName == null && psiElement instanceof PsiDirectoryContainer) { final PsiDirectory[] directories = ((PsiDirectoryContainer) psiElement).getDirectories(); directoryName = directories.length == 1 ? directories[0].getVirtualFile().getPresentableUrl() : null; } Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext); if (module != null) { model.setModuleName(module.getName()); } Editor editor = CommonDataKeys.EDITOR.getData(dataContext); if (model.getModuleName() == null || editor == null) { model.setDirectoryName(directoryName); model.setProjectScope( directoryName == null && module == null && !model.isCustomScope() || editor != null); if (directoryName != null) { model.setCustomScope(false); // to select "Directory: " radio button } // for convenience set directory name to directory of current file, note that we doesn't // change default projectScope if (directoryName == null) { VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); if (virtualFile != null && !virtualFile.isDirectory()) virtualFile = virtualFile.getParent(); if (virtualFile != null) model.setDirectoryName(virtualFile.getPresentableUrl()); } } }
@NotNull private static String getTitleForScope(@NotNull final FindModel findModel) { String scopeName; if (findModel.isProjectScope()) { scopeName = FindBundle.message("find.scope.project.title"); } else if (findModel.getModuleName() != null) { scopeName = FindBundle.message("find.scope.module.title", findModel.getModuleName()); } else if (findModel.getCustomScopeName() != null) { scopeName = findModel.getCustomScopeName(); } else { scopeName = FindBundle.message("find.scope.directory.title", findModel.getDirectoryName()); } String result = scopeName; if (findModel.getFileFilter() != null) { result += " " + FindBundle.message("find.scope.files.with.mask", findModel.getFileFilter()); } return result; }
// returns number of hits static int processUsagesInFile( @NotNull final PsiFile psiFile, @NotNull final FindModel findModel, @NotNull final Processor<UsageInfo> consumer) { if (findModel.getStringToFind().isEmpty()) { if (!ApplicationManager.getApplication() .runReadAction((Computable<Boolean>) () -> consumer.process(new UsageInfo(psiFile)))) { throw new ProcessCanceledException(); } return 1; } final VirtualFile virtualFile = psiFile.getVirtualFile(); if (virtualFile == null) return 0; if (virtualFile.getFileType().isBinary()) return 0; // do not decompile .class files final Document document = ApplicationManager.getApplication() .runReadAction( (Computable<Document>) () -> virtualFile.isValid() ? FileDocumentManager.getInstance().getDocument(virtualFile) : null); if (document == null) return 0; final int[] offset = {0}; int count = 0; int found; ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator()); TooManyUsagesStatus tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator); do { tooManyUsagesStatus.pauseProcessingIfTooManyUsages(); // wait for user out of read action found = ApplicationManager.getApplication() .runReadAction( (Computable<Integer>) () -> { if (!psiFile.isValid()) return 0; return addToUsages( document, consumer, findModel, psiFile, offset, USAGES_PER_READ_ACTION); }); count += found; } while (found != 0); return count; }
public void searchAndShowUsages( @NotNull UsageViewManager manager, @NotNull Factory<UsageSearcher> usageSearcherFactory, @NotNull final FindModel findModelCopy, @NotNull UsageViewPresentation presentation, @NotNull FindUsagesProcessPresentation processPresentation, final FindManager findManager) { presentation.setMergeDupLinesAvailable(false); final ReplaceContext[] context = new ReplaceContext[1]; manager.searchAndShowUsages( new UsageTarget[] { new FindInProjectUtil.StringUsageTarget(myProject, findModelCopy.getStringToFind()) }, usageSearcherFactory, processPresentation, presentation, new UsageViewManager.UsageViewStateListener() { @Override public void usageViewCreated(@NotNull UsageView usageView) { context[0] = new ReplaceContext(usageView, findModelCopy); addReplaceActions(context[0]); } @Override public void findingUsagesFinished(final UsageView usageView) { if (context[0] != null && findManager.getFindInProjectModel().isPromptOnReplace()) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { replaceWithPrompt(context[0]); context[0].invalidateExcludedSetCache(); } }); } } }); }
@NotNull static SearchScope getScopeFromModel(@NotNull Project project, @NotNull FindModel findModel) { SearchScope customScope = findModel.getCustomScope(); VirtualFile directory = getDirectory(findModel); Module module = findModel.getModuleName() == null ? null : ModuleManager.getInstance(project).findModuleByName(findModel.getModuleName()); return findModel.isCustomScope() && customScope != null ? customScope.intersectWith(GlobalSearchScope.allScope(project)) : // we don't have to check for myProjectFileIndex.isExcluded(file) here like // FindInProjectTask.collectFilesInScope() does // because all found usages are guaranteed to be not in excluded dir directory != null ? forDirectory(project, findModel.isWithSubdirectories(), directory) : module != null ? module.getModuleContentScope() : findModel.isProjectScope() ? ProjectScope.getContentScope(project) : GlobalSearchScope.allScope(project); }
@Override public String getName() { return myFindModel.getStringToFind().isEmpty() ? myFindModel.getFileFilter() : myFindModel.getStringToFind(); }