Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.lsp4ij.features.documentSymbol.DocumentSymbolData;
Expand Down Expand Up @@ -127,4 +129,10 @@ public boolean canNavigate(@NotNull DocumentSymbol documentSymbol,
var selectionRange = documentSymbol.getSelectionRange();
return selectionRange != null && selectionRange.getStart() != null;
}

public boolean isSame(@NotNull DocumentSymbolData documentSymbolData,
@NotNull PsiElement psiElement) {
TextRange textRange = documentSymbolData.getSelectionTextRange() != null ? documentSymbolData.getSelectionTextRange() : documentSymbolData.getTextRange();
return textRange.equals(psiElement.getTextRange());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.jetbrains.annotations.Nullable;

import javax.swing.Icon;
import java.util.Objects;


/**
Expand All @@ -39,6 +40,7 @@ public class DocumentSymbolData extends FakePsiElement {
private final DocumentSymbolData parent;
private final @NotNull LanguageServerItem languageServer;
private volatile TextRange textRange = null;
private volatile TextRange selectionTextRange = null;
private DocumentSymbolData[] cachedChildren;

public DocumentSymbolData(@NotNull DocumentSymbol documentSymbol,
Expand Down Expand Up @@ -95,6 +97,21 @@ public TextRange getTextRange() {
return textRange;
}

public @Nullable TextRange getSelectionTextRange() {
if (documentSymbol.getSelectionRange() == null) {
return null;
}
if (selectionTextRange == null) {
synchronized (this) {
if (selectionTextRange == null) {
Range range = documentSymbol.getSelectionRange();
Document document = LSPIJUtils.getDocument(psiFile);
this.selectionTextRange = (document != null) ? LSPIJUtils.toTextRange(range, document) : null;
}
}
}
return selectionTextRange;
}
@Override
public void navigate(boolean requestFocus) {
getClientFeatures().getDocumentSymbolFeature().navigate(documentSymbol, psiFile, requestFocus);
Expand Down Expand Up @@ -124,6 +141,26 @@ public boolean canNavigate() {
return cachedChildren;
}

@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (getClass() == o.getClass()) {
DocumentSymbolData that = (DocumentSymbolData) o;
return Objects.equals(documentSymbol, that.documentSymbol);
}
if (o instanceof PsiElement psiElement) {
return getClientFeatures().getDocumentSymbolFeature().isSame(this, psiElement);
}
return false;
}

@Override
public int hashCode() {
return Objects.hashCode(documentSymbol);
}

public @NotNull LSPClientFeatures getClientFeatures() {
return languageServer.getClientFeatures();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ArrayUtil;
import com.redhat.devtools.lsp4ij.LSPFileSupport;
import com.redhat.devtools.lsp4ij.client.indexing.ProjectIndexingManager;
import com.redhat.devtools.lsp4ij.features.semanticTokens.viewProvider.LSPSemanticTokenPsiElement;
import com.redhat.devtools.lsp4ij.internal.PsiFileChangedException;
import org.eclipse.lsp4j.DocumentSymbolParams;
import org.eclipse.lsp4j.TextDocumentIdentifier;
Expand Down Expand Up @@ -55,6 +57,12 @@ public boolean isAlwaysLeaf(StructureViewTreeElement element) {
return element.getChildren().length == 0;
}

@Override
protected Class @NotNull [] getSuitableClasses() {
// Any PSI element
return new Class[] {PsiElement.class};
}

@Override
public void dispose() {
super.dispose();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.redhat.devtools.lsp4ij.features.documentSymbol;

import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.StructureViewBuilderProvider;
import com.intellij.ide.structureView.logical.PhysicalAndLogicalStructureViewBuilder;
import com.intellij.lang.LanguageStructureViewBuilder;
import com.intellij.lang.PsiStructureViewFactory;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.redhat.devtools.lsp4ij.LanguageServersRegistry;
import com.redhat.devtools.lsp4ij.client.ExecuteLSPFeatureStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class LSPStructureViewBuilderProvider implements StructureViewBuilderProvider {
@Override
public @Nullable StructureViewBuilder getStructureViewBuilder(@NotNull FileType fileType, @NotNull VirtualFile file, @NotNull Project project) {
if (!(fileType instanceof AbstractFileType)) {
return null;
}
if (!LanguageServersRegistry.getInstance().isFileSupported(file, project)) {
// The file is not associated to a language server, don't execute the LSP feature.
return null;
}
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
if (psiFile == null) return null;

PsiStructureViewFactory factory = LanguageStructureViewBuilder.getInstance().forLanguage(psiFile.getLanguage());
if (factory == null) return null;
StructureViewBuilder physicalBuilder = factory.getStructureViewBuilder(psiFile);
return PhysicalAndLogicalStructureViewBuilder.Companion.wrapPhysicalBuilderIfPossible(physicalBuilder, psiFile);
}
}
4 changes: 4 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@
implementationClass="com.redhat.devtools.lsp4ij.features.documentLink.LSPDocumentLinkDocumentationProvider"/>

<!-- LSP textDocument/documentSymbol request support -->
<structureViewBuilder
id="LSPStructureViewBuilderProvider"
factoryClass="com.redhat.devtools.lsp4ij.features.documentSymbol.LSPStructureViewBuilderProvider"
order="last"/>
<lang.psiStructureViewFactory
id="LSPDocumentSymbolStructureViewFactoryForText"
language="TEXT"
Expand Down
Loading