From 234e99583dfe529faf2a704912540954f4a92b11 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Thu, 26 Jan 2023 18:14:47 -0500 Subject: [PATCH] Fix duplicate entries in QuickSearch dialog for nested projects - add code to find innermost project file for a LineItem - fixes #31 --- .../quicksearch/internal/core/LineItem.java | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/org.eclipse.text.quicksearch/src/org/eclipse/text/quicksearch/internal/core/LineItem.java b/org.eclipse.text.quicksearch/src/org/eclipse/text/quicksearch/internal/core/LineItem.java index 8088577a793..8d8b4982b52 100644 --- a/org.eclipse.text.quicksearch/src/org/eclipse/text/quicksearch/internal/core/LineItem.java +++ b/org.eclipse.text.quicksearch/src/org/eclipse/text/quicksearch/internal/core/LineItem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Pivotal Software, Inc. + * Copyright (c) 2013, 2023 Pivotal Software, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -9,12 +9,16 @@ * * Contributors: * Pivotal Software, Inc. - initial API and implementation + * Red Hat Inc. - fix duplicate items when projects are nested *******************************************************************************/ package org.eclipse.text.quicksearch.internal.core; import java.util.Objects; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; import org.eclipse.search.internal.ui.text.FileMatch; @SuppressWarnings("restriction") @@ -26,19 +30,50 @@ public class LineItem { int lineOffset; public LineItem(IFile f, String line, int lineNumber, int lineOffset) { - this.f = f; + this.f = getInnermostProjectFile(f); this.line = line; this.lineNumber = lineNumber; this.lineOffset = lineOffset; } public LineItem(FileMatch match) { - this.f = match.getFile(); + this.f = getInnermostProjectFile(match.getFile()); this.line = match.getLineElement().getContents(); this.lineNumber = match.getLineElement().getLine(); this.lineOffset = match.getLineElement().getOffset(); } + private IFile getInnermostProjectFile(IFile file) { + // In the case where projects are nested, a text search will find a result more than once. + // We want to refine the outer project(s) matches to avoid duplicates but also because an outer match + // when opened will use an editor chosen by the outer project which may be incorrect (e.g. outer + // project is generic and inner project is Java). So, we convert the file to be the IResource found in + // the innermost project. This fixes: Bug 559340 https://bugs.eclipse.org/bugs/show_bug.cgi?id=559340 + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + IPath filePath = file.getLocation(); + IProject fileProject = file.getProject(); + IPath currentPath = fileProject.getLocation(); + IProject innermostProject = file.getProject(); + for (IProject project : projects) { + if (project == fileProject) { + continue; + } + IPath projectPath = project.getLocation(); + if (projectPath.isPrefixOf(filePath) && currentPath.isPrefixOf(projectPath)) { + currentPath = projectPath; + innermostProject = project; + } + } + if (innermostProject != fileProject) { + IPath newFilePath = filePath.removeFirstSegments(currentPath.segmentCount()); + IFile newFile = innermostProject.getFile(newFilePath); + if (newFile.exists()) { + file = newFile; + } + } + return file; + } + @Override public String toString() { return lineNumber + ": " + line + " (" +f.getProjectRelativePath() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$