From bfce498c035ca25c16f09fb295285b9e43776a61 Mon Sep 17 00:00:00 2001 From: Fred Bricon Date: Wed, 10 Jan 2024 18:17:38 +0100 Subject: [PATCH] feat: emulate vscode's "editor.action.triggerSuggest" command Signed-off-by: Fred Bricon --- .../commands/editor/TriggerSuggestAction.java | 61 +++++++++++++++++++ .../completion/LSPCompletionProposal.java | 11 ++-- src/main/resources/META-INF/plugin.xml | 7 +++ 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/redhat/devtools/lsp4ij/commands/editor/TriggerSuggestAction.java diff --git a/src/main/java/com/redhat/devtools/lsp4ij/commands/editor/TriggerSuggestAction.java b/src/main/java/com/redhat/devtools/lsp4ij/commands/editor/TriggerSuggestAction.java new file mode 100644 index 000000000..679eed7e8 --- /dev/null +++ b/src/main/java/com/redhat/devtools/lsp4ij/commands/editor/TriggerSuggestAction.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.lsp4ij.commands.editor; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionUtil; +import com.intellij.openapi.actionSystem.impl.SimpleDataContext; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.project.Project; +import com.redhat.devtools.lsp4ij.commands.LSPCommand; +import com.redhat.devtools.lsp4ij.commands.LSPCommandAction; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Emulates Visual Studio Code's "editor.action.triggerSuggest" command, to trigger code completion after selecting a completion item. + */ +public class TriggerSuggestAction extends LSPCommandAction { + + private static final String CODE_COMPLETION_ACTION = "CodeCompletion"; + + @Override + protected void commandPerformed(@NotNull LSPCommand command, @NotNull AnActionEvent e) { + Project project = e.getProject(); + if (project == null) { + return; + } + @Nullable TextEditor activeEditor = findActiveEditor(project); + if (activeEditor == null) { + return; + } + AnAction codeCompletionAction = ActionManager.getInstance().getAction(CODE_COMPLETION_ACTION); + if (codeCompletionAction != null ) { + DataContext dataContext = createDataContext(activeEditor, project); + ActionUtil.invokeAction(codeCompletionAction, dataContext, ActionPlaces.UNKNOWN, null, null); + } + } + + private static DataContext createDataContext(TextEditor activeEditor, Project project) { + SimpleDataContext.Builder contextBuilder = SimpleDataContext.builder(); + contextBuilder.add(CommonDataKeys.PROJECT, project) + .add(CommonDataKeys.EDITOR, activeEditor.getEditor()); + return contextBuilder.build(); + } + + public static @Nullable TextEditor findActiveEditor(Project project) { + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + FileEditor editor = fileEditorManager.getSelectedEditor(); + return editor instanceof TextEditor? (TextEditor) editor: null; + } +} diff --git a/src/main/java/com/redhat/devtools/lsp4ij/operations/completion/LSPCompletionProposal.java b/src/main/java/com/redhat/devtools/lsp4ij/operations/completion/LSPCompletionProposal.java index fa7fd50ad..49cf7bb77 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/operations/completion/LSPCompletionProposal.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/operations/completion/LSPCompletionProposal.java @@ -107,6 +107,11 @@ public void handleInsert(@NotNull InsertionContext context) { EditorModificationUtil.moveCaretRelatively(editor, -template.getTemplateText().length()); TemplateManager.getInstance(context.getProject()).startTemplate(context.getEditor(), template); } + // Execute custom command of the completion item if needed + Command command = item.getCommand(); + if (command != null) { + executeCustomCommand(command, LSPIJUtils.toUri(context.getDocument())); + } } /** @@ -267,11 +272,7 @@ protected void apply(Document document, char trigger, int stateMask, int offset) LSPIJUtils.applyEdits(editor, document, Collections.singletonList(textEdit)); } - // Execute custom command of the completion item if needed - Command command = item.getCommand(); - if (command != null) { - executeCustomCommand(command, LSPIJUtils.toUri(document)); - } + } catch (RuntimeException ex) { LOGGER.warn(ex.getLocalizedMessage(), ex); } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index fd5a57930..220e1652c 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -173,6 +173,13 @@ id="lsp.console.explorer.copy.command" class="com.redhat.devtools.lsp4ij.console.explorer.actions.CopyStartServerCommandAction" icon="AllIcons.Actions.Copy"/> + + + + +