Skip to content

Commit

Permalink
feat: add document symbol support
Browse files Browse the repository at this point in the history
Fixes #417
  • Loading branch information
CppCXY authored and angelozerr committed Sep 23, 2024
1 parent eca7ca6 commit 03e4194
Show file tree
Hide file tree
Showing 9 changed files with 496 additions and 12 deletions.
14 changes: 14 additions & 0 deletions src/main/java/com/redhat/devtools/lsp4ij/LSPFileSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.redhat.devtools.lsp4ij.features.completion.LSPCompletionSupport;
import com.redhat.devtools.lsp4ij.features.declaration.LSPDeclarationSupport;
import com.redhat.devtools.lsp4ij.features.documentLink.LSPDocumentLinkSupport;
import com.redhat.devtools.lsp4ij.features.documentSymbol.LSPDocumentSymbolSupport;
import com.redhat.devtools.lsp4ij.features.documentation.LSPHoverSupport;
import com.redhat.devtools.lsp4ij.features.foldingRange.LSPFoldingRangeSupport;
import com.redhat.devtools.lsp4ij.features.formatting.LSPFormattingSupport;
Expand Down Expand Up @@ -81,6 +82,8 @@ public class LSPFileSupport extends UserDataHolderBase implements Disposable {

private final LSPSemanticTokensSupport semanticTokensSupport;

private final LSPDocumentSymbolSupport documentSymbolSupport;

private LSPFileSupport(@NotNull PsiFile file) {
this.file = file;
this.codeLensSupport = new LSPCodeLensSupport(file);
Expand All @@ -101,6 +104,7 @@ private LSPFileSupport(@NotNull PsiFile file) {
this.declarationSupport = new LSPDeclarationSupport(file);
this.typeDefinitionSupport = new LSPTypeDefinitionSupport(file);
this.semanticTokensSupport = new LSPSemanticTokensSupport(file);
this.documentSymbolSupport = new LSPDocumentSymbolSupport(file);
file.putUserData(LSP_FILE_SUPPORT_KEY, this);
}

Expand All @@ -126,6 +130,7 @@ public void dispose() {
getDeclarationSupport().cancel();
getTypeDefinitionSupport().cancel();
getSemanticTokensSupport().cancel();
getDocumentSymbolSupport().cancel();
var map = getUserMap();
for (var key : map.getKeys()) {
var value = map.get(key);
Expand Down Expand Up @@ -297,6 +302,15 @@ public LSPSemanticTokensSupport getSemanticTokensSupport() {
return semanticTokensSupport;
}

/**
* Returns the LSP document symbol support.
*
* @return the LSP document symbol support.
*/
public LSPDocumentSymbolSupport getDocumentSymbolSupport() {
return documentSymbolSupport;
}

/**
* Return the existing LSP file support for the given Psi file, or create a new one if necessary.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class LSPRequestConstants {
public static final String TEXT_DOCUMENT_PREPARE_RENAME = "textDocument/prepareRename";
public static final String TEXT_DOCUMENT_RENAME = "textDocument/rename";
public static final String TEXT_DOCUMENT_DOCUMENT_COMPLETION = "textDocument/completion";
public static final String TEXT_DOCUMENT_DOCUMENT_SYMBOL = "textDocument/documentSymbol";

// workspace/* LSP requests
public static final String WORKSPACE_SYMBOL = "workspace/symbol";
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/redhat/devtools/lsp4ij/LanguageServerItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,16 @@ public SemanticTokensColorsProvider getSemanticTokensColorsProvider() {
return getServerWrapper().getServerDefinition().getSemanticTokensColorsProvider();
}

/**
* Returns true if the language server can support document symbol and false otherwise.
*
* @return true if the language server can support document symbol and false otherwise.
*/
public static boolean isDocumentSymbolSupported(@Nullable ServerCapabilities serverCapabilities) {
return serverCapabilities != null &&
hasCapability(serverCapabilities.getDocumentSymbolProvider());
}

/**
* Returns true if the language server can support workspace symbol and false otherwise.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at https://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* CppCXY
******************************************************************************/
package com.redhat.devtools.lsp4ij.features.documentSymbol;

import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.util.NlsSafe;
import com.redhat.devtools.lsp4ij.ui.IconMapper;
import org.eclipse.lsp4j.DocumentSymbol;
import org.eclipse.lsp4j.SymbolKind;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;


/**
* LSP document symbol data.
*
* @param documentSymbol the LSP document symbol
*/
record DocumentSymbolData(@NotNull DocumentSymbol documentSymbol) {

private record LSPItemPresentation(String name, SymbolKind symbolKind, String locationString) implements ItemPresentation {

public String name() {
return name;
}

@Override
public @NlsSafe @Nullable String getPresentableText() {
return name();
}

@Override
public @Nullable Icon getIcon(boolean unused) {
return IconMapper.getIcon(symbolKind);
}

@Override
public @NlsSafe @Nullable String getLocationString() {
return locationString;
}

}

public ItemPresentation getPresentation() {
return new LSPItemPresentation(documentSymbol.getName(), documentSymbol.getKind(), documentSymbol.getDetail());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at https://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* CppCXY
******************************************************************************/
package com.redhat.devtools.lsp4ij.features.documentSymbol;

import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
import com.intellij.lang.PsiStructureViewFactory;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LanguageServersRegistry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* LSP document symbol structure view factory.
*/
public class LSPDocumentSymbolStructureViewFactory implements PsiStructureViewFactory {

@Override
public @Nullable StructureViewBuilder getStructureViewBuilder(@NotNull PsiFile psiFile) {
if (!LanguageServersRegistry.getInstance().isFileSupported(psiFile)) {
return null;
}
return new LSPDocumentSymbolStructureViewBuilder(psiFile);
}

private static class LSPDocumentSymbolStructureViewBuilder extends TreeBasedStructureViewBuilder {
private final PsiFile psiFile;

public LSPDocumentSymbolStructureViewBuilder(@NotNull PsiFile psiFile) {
this.psiFile = psiFile;
}

@Override
public @NotNull StructureViewModel createStructureViewModel(@Nullable Editor editor) {
return new LSPDocumentSymbolStructureViewModel(psiFile, editor);
}
}
}
Loading

0 comments on commit 03e4194

Please sign in to comment.