Skip to content

Commit

Permalink
added CodeAction for opening XML binding wizard and added client capa…
Browse files Browse the repository at this point in the history
…bilities dependency
  • Loading branch information
Alexander Chen authored and angelozerr committed Jul 26, 2021
1 parent d633fbc commit afe0257
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 26 deletions.
Expand Up @@ -197,6 +197,7 @@ public void updateClientCapabilities(ClientCapabilities capabilities,
sharedSettings
.setActionableNotificationSupport(extendedClientCapabilities.isActionableNotificationSupport());
sharedSettings.setOpenSettingsCommandSupport(extendedClientCapabilities.isOpenSettingsCommandSupport());
sharedSettings.setBindingWizardSupport(extendedClientCapabilities.isBindingWizardSupport());
}

}
Expand Down
Expand Up @@ -13,9 +13,9 @@

/**
* Extended client capabilities not defined by the LSP.
*
*
* @author Angelo ZERR
*
*
* @see https://github.com/microsoft/language-server-protocol/issues/788
*/
public class ExtendedClientCapabilities {
Expand All @@ -26,6 +26,8 @@ public class ExtendedClientCapabilities {

private boolean openSettingsCommandSupport;

private boolean bindingWizardSupport;

private boolean shouldLanguageServerExitOnShutdown;

public ExtendedCodeLensCapabilities getCodeLens() {
Expand All @@ -38,10 +40,10 @@ public void setCodeLens(ExtendedCodeLensCapabilities codeLens) {

/**
* Returns true if the client supports actionable notifications and false otherwise
*
*
* See {@link org.eclipse.lemminx.customservice.ActionableNotification} and
* {@link org.eclipse.lemminx.customservice.XMLLanguageClientAPI#actionableNotification}
*
*
* @return true if the client supports actionable notifications and false otherwise
*/
public boolean isActionableNotificationSupport() {
Expand All @@ -50,7 +52,7 @@ public boolean isActionableNotificationSupport() {

/**
* Sets the actionableNotificationSupport boolean
*
*
* @param actionableNotificationSupport
*/
public void setActionableNotificationSupport(boolean actionableNotificationSupport) {
Expand All @@ -59,9 +61,9 @@ public void setActionableNotificationSupport(boolean actionableNotificationSuppo

/**
* Returns true if the client supports the open settings command and false otherwise
*
*
* See {@link org.eclipse.lemminx.client.ClientCommands#OPEN_SETTINGS}
*
*
* @return true if the client supports the open settings command and false otherwise
*/
public boolean isOpenSettingsCommandSupport() {
Expand All @@ -70,13 +72,31 @@ public boolean isOpenSettingsCommandSupport() {

/**
* Sets the openSettingsCommandSupport boolean
*
*
* @param openSettingsCommandSupport
*/
public void setOpenSettingsCommandSupport(boolean openSettingsCommandSupport) {
this.openSettingsCommandSupport = openSettingsCommandSupport;
}

/**
* Returns true if the client supports the `xml.open.binding.wizard` command using dropdown and false otherwise
*
* @return bindingWizardSupport
*/
public boolean isBindingWizardSupport() {
return this.bindingWizardSupport;
}

/**
* Sets the bindingWizardSupport boolean
*
* @param bindingWizardSupport
*/
public void setBindingWizardSupport(boolean bindingWizardSupport) {
this.bindingWizardSupport = bindingWizardSupport;
}

/**
* Sets the boolean permitting language server to exit on client
* shutdown() request, without waiting for client to call exit()
Expand Down
Expand Up @@ -20,6 +20,7 @@

import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.CodeActionKind;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CreateFile;
import org.eclipse.lsp4j.CreateFileOptions;
import org.eclipse.lsp4j.Diagnostic;
Expand All @@ -41,7 +42,7 @@ public class CodeActionFactory {

/**
* Create a CodeAction to remove the content from the given range.
*
*
* @param title
* @param range
* @param document
Expand All @@ -54,13 +55,13 @@ public static CodeAction remove(String title, Range range, TextDocumentItem docu

/**
* Create a CodeAction to insert a new content at the end of the given range.
*
*
* @param title
* @param range
* @param insertText
* @param document
* @param diagnostic
*
*
* @return the CodeAction to insert a new content at the end of the given range.
*/
public static CodeAction insert(String title, Position position, String insertText, TextDocumentItem document,
Expand All @@ -77,11 +78,11 @@ public static CodeAction insert(String title, Position position, String insertTe

/**
* Returns the text edit to insert a new content at the end of the given range.
*
*
* @param insertText text to insert.
* @param position the position.
* @param document the text document.
*
*
* @return the text edit to insert a new content at the end of the given range.
*/
public static TextDocumentEdit insertEdit(String insertText, Position position, TextDocumentItem document) {
Expand Down Expand Up @@ -142,7 +143,7 @@ public static CodeAction replaceAt(String title, String replaceText, TextDocumen

/**
* Makes a CodeAction to create a file and add content to the file.
*
*
* @param title The displayed name of the CodeAction
* @param docURI The file to create
* @param content The text to put into the newly created document.
Expand All @@ -169,4 +170,22 @@ public static CodeAction createFile(String title, String docURI, String content,

return codeAction;
}

/**
* Makes a CodeAction to call a command from the available server commands.
*
* @param title The displayed name of the CodeAction
* @param commandId The id of the given command to add as CodeAction
* @param commandParams The document URI of the document the command is called on
* @param diagnostic The diagnostic that this CodeAction will fix
*/
public static CodeAction createCommand(String title, String commandId, List<Object> commandParams, Diagnostic diagnostic) {
CodeAction codeAction = new CodeAction(title);
Command command = new Command(title, commandId, commandParams);
codeAction.setCommand(command);
codeAction.setDiagnostics(Collections.singletonList(diagnostic));
codeAction.setKind(CodeActionKind.QuickFix);

return codeAction;
}
}
Expand Up @@ -11,6 +11,8 @@
*******************************************************************************/
package org.eclipse.lemminx.extensions.contentmodel.participants.codeactions;

import static org.eclipse.lemminx.client.ClientCommands.OPEN_BINDING_WIZARD;

import java.io.File;
import java.net.URI;
import java.nio.file.Files;
Expand Down Expand Up @@ -101,17 +103,26 @@ public void doCodeAction(Diagnostic diagnostic, Range range, DOMDocument documen
diagnostic);
codeActions.add(dtdWithXmlModelAction);

// ---------- Open Binding Wizard
if (sharedSettings.isBindingWizardSupport()) {
String documentURI = document.getDocumentURI();
String title = "Bind to existing grammar/schema";
List<Object> commandParams = Arrays.asList(documentURI);
CodeAction bindWithExistingGrammar = CodeActionFactory.createCommand(title, OPEN_BINDING_WIZARD, commandParams, diagnostic);
codeActions.add(bindWithExistingGrammar);
}

} catch (BadLocationException e) {
LOGGER.log(Level.SEVERE, "In NoGrammarConstraintsCodeAction position error", e);
}
}

/**
* Returns the unique grammar URI file.
*
*
* @param documentURI the XML document URI.
* @param fileExtension the grammar file extension.
*
*
* @return the unique grammar URI file.
*/
static String getGrammarURI(String documentURI, String fileExtension) {
Expand Down
Expand Up @@ -29,6 +29,7 @@ public class SharedSettings {
private final XMLWorkspaceSettings workspaceSettings;
private boolean actionableNotificationSupport;
private boolean openSettingsCommandSupport;
private boolean bindingWizardSupport;

public SharedSettings() {
this.completionSettings = new XMLCompletionSettings();
Expand All @@ -55,6 +56,7 @@ public SharedSettings(SharedSettings newSettings) {
this.preferences.merge(newSettings.getPreferences());
this.actionableNotificationSupport = newSettings.isActionableNotificationSupport();
this.openSettingsCommandSupport = newSettings.isOpenSettingsCommandSupport();
this.bindingWizardSupport = newSettings.isBindingWizardSupport();
}

public XMLCompletionSettings getCompletionSettings() {
Expand Down Expand Up @@ -96,10 +98,10 @@ public XMLWorkspaceSettings getWorkspaceSettings() {
/**
* Returns true if the client supports actionable notifications and false
* otherwise
*
*
* See {@link org.eclipse.lemminx.customservice.ActionableNotification} and
* {@link org.eclipse.lemminx.customservice.XMLLanguageClientAPI}
*
*
* @return true if the client supports actionable notifications and false
* otherwise
*/
Expand All @@ -109,7 +111,7 @@ public boolean isActionableNotificationSupport() {

/**
* Sets the actionableNotificationSupport boolean
*
*
* @param actionableNotificationSupport
*/
public void setActionableNotificationSupport(boolean actionableNotificationSupport) {
Expand All @@ -119,9 +121,9 @@ public void setActionableNotificationSupport(boolean actionableNotificationSuppo
/**
* Returns true if the client supports the open settings command and false
* otherwise
*
*
* See {@link org.eclipse.lemminx.client.ClientCommands#OPEN_SETTINGS}
*
*
* @return true if the client supports the open settings command and false
* otherwise
*/
Expand All @@ -131,11 +133,29 @@ public boolean isOpenSettingsCommandSupport() {

/**
* Sets the openSettingsCommandSupport boolean
*
*
* @param openSettingsCommandSupport
*/
public void setOpenSettingsCommandSupport(boolean openSettingsCommandSupport) {
this.openSettingsCommandSupport = openSettingsCommandSupport;
}

/**
* Returns true if the client supports the `xml.open.binding.wizard` command using dropdown and false otherwise
*
* @return bindingWizardSupport
*/
public boolean isBindingWizardSupport() {
return this.bindingWizardSupport;
}

/**
* Sets the bindingWizardSupport boolean
*
* @param bindingWizardSupport
*/
public void setBindingWizardSupport(boolean bindingWizardSupport) {
this.bindingWizardSupport = bindingWizardSupport;
}

}
Expand Up @@ -609,7 +609,6 @@ public static void testCodeActionsFor(String xml, Diagnostic diagnostic, String
public static void assertCodeActions(List<CodeAction> actual, CodeAction... expected) {
actual.stream().forEach(ca -> {
// we don't want to compare title, etc
ca.setCommand(null);
ca.setKind(null);
ca.setTitle("");
if (ca.getDiagnostics() != null) {
Expand All @@ -636,6 +635,19 @@ public static CodeAction ca(Diagnostic d, TextEdit... te) {
return codeAction;
}

/**
* Mock code action for creating a command code action
*/
public static CodeAction ca(Diagnostic d, Command c) {
CodeAction codeAction = new CodeAction();
codeAction.setTitle("");
codeAction.setDiagnostics(Arrays.asList(d));

codeAction.setCommand(c);

return codeAction;
}

public static TextDocumentEdit tde(String uri, int version, TextEdit... te) {
VersionedTextDocumentIdentifier versionedTextDocumentIdentifier = new VersionedTextDocumentIdentifier(uri,
version);
Expand Down
Expand Up @@ -12,6 +12,8 @@
*/
package org.eclipse.lemminx.extensions.contentmodel;

import static org.eclipse.lemminx.client.ClientCommands.OPEN_BINDING_WIZARD;

import static java.lang.System.lineSeparator;
import static org.eclipse.lemminx.XMLAssert.ca;
import static org.eclipse.lemminx.XMLAssert.createFile;
Expand All @@ -22,6 +24,7 @@

import java.util.Arrays;

import org.eclipse.lsp4j.Command;
import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lemminx.extensions.contentmodel.participants.XMLSyntaxErrorCode;
import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings;
Expand Down Expand Up @@ -74,6 +77,8 @@ private static void noGrammarHint(boolean selfClose) throws BadLocationException
workspaceEdit.setResourceOperations(Arrays.asList(ResourceOperationKind.Create));
workspace.setWorkspaceEdit(workspaceEdit);
settings.getWorkspaceSettings().setCapabilities(workspace);
// Expose `xml.open.binding.wizard` command
settings.setBindingWizardSupport(true);

// Code action to generate DTD, XSD
String schemaTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + lineSeparator() + //
Expand Down Expand Up @@ -110,8 +115,10 @@ private static void noGrammarHint(boolean selfClose) throws BadLocationException
teOp("test.dtd", 0, 0, 0, 0, //
dtdTemplate), //
teOp("test.xml", 0, 0, 0, 0, //
"<?xml-model href=\"test.dtd\"?>" + lineSeparator() //
)));
"<?xml-model href=\"test.dtd\"?>" + lineSeparator())),
// Open binding wizard command
ca(d, new Command("Bind to existing grammar/schema", OPEN_BINDING_WIZARD, Arrays.asList(new Object[]{"test.xml"})))
);

}
}
Expand Up @@ -95,7 +95,8 @@ public void cleanup() {
" }\r\n" + " }\r\n" + " },\r\n" + " \"extendedClientCapabilities\": {\r\n"
+ " \"codeLens\": {\r\n" + " \"codeLensKind\": {\r\n" + " \"valueSet\": [\r\n"
+ " \"references\"\r\n" + " ]\r\n" + " }\r\n" + " },\r\n"
+ " actionableNotificationSupport: true,\r\n" + " openSettingsCommandSupport: true\r\n" + " }"
+ " actionableNotificationSupport: true,\r\n" + " openSettingsCommandSupport: true,\r\n"
+ " bindingWizardSupport: true\r\n" + " }"
+ "}";
// @formatter:on

Expand Down Expand Up @@ -249,6 +250,7 @@ public void extendedClientCapabilitiesTest() {
assertEquals(CodeLensKind.References, clientCapabilities.getCodeLens().getCodeLensKind().getValueSet().get(0));
assertTrue(clientCapabilities.isActionableNotificationSupport());
assertTrue(clientCapabilities.isOpenSettingsCommandSupport());
assertTrue(clientCapabilities.isBindingWizardSupport());
}

@Test
Expand Down

0 comments on commit afe0257

Please sign in to comment.