Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lsp code action #81

Merged
merged 8 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
60 changes: 60 additions & 0 deletions AnyText/AnyText.Core/CodeActionInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
namespace NMF.AnyText
{
/// <summary>
/// Represents the information about a code action.
/// </summary>
public class CodeActionInfo
{
/// <summary>
/// The title is typically displayed in the UI to describe the action.
/// </summary>
public string Title { get; set; }

/// <summary>
/// Kind of the code action.
/// Possible values:
/// - "quickfix"
/// - "refactor"
/// - "refactor.extract"
/// - "refactor.inline"
/// - "refactor.rewrite"
/// - "source"
/// - "source.organizeImports"
/// </summary>
public string Kind { get; set; }

/// <summary>
/// This array holds diagnostics for which this action is relevant. If no diagnostics are set, the action may apply generally.
/// </summary>
public string[] Diagnostics { get; set; }

/// <summary>
/// A value of <c>true</c> indicates that the code action is preferred; otherwise, <c>false</c> or <c>null</c> if there's no preference.
/// </summary>
public bool IsPreferred { get; set; }

/// <summary>
/// This is the text that describes the command to execute, which can be shown to the user.
/// </summary>
public string CommandTitle { get; set; }

/// <summary>
/// The command is the identifier or name of the action to execute when the user selects it.
/// </summary>
public string Command { get; set; }

/// <summary>
/// These are the parameters passed to the command when it is executed.
/// </summary>
public object[] Arguments { get; set; }
/// <summary>
/// Identifies the Diagnostic that this Action fixes
/// </summary>
public string DiagnosticIdentifier { get; set; }
/// <summary>
/// Defines the Workspace changes this action executes
/// </summary>
public WorkspaceEdit WorkspaceEdit { get; set; }

}
}
11 changes: 11 additions & 0 deletions AnyText/AnyText.Core/Grammars/Grammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,16 @@ public Rule Root
/// <param name="context">a context to resolve the root rule</param>
/// <returns>the root rule for this grammar</returns>
protected abstract Rule GetRootRule(GrammarContext context);

/// <summary>
/// Gets the list of code actions supported by this grammar.
/// </summary>
public virtual IEnumerable<CodeActionInfo> SupportedCodeActions { get; } = new List<CodeActionInfo>();
georghinkel marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Dictionary of executable actions.
/// The key is the action identifier, and the value is the action executor.
/// </summary>
public virtual Dictionary<string, Func<object[], object>> ExecutableCodeActions { get; } = new Dictionary<string, Func<object[], object>>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mit object[] verlieren wir jegliche Typsicherheit! Außerdem kann jeder das Dictionary zu jedem Zeitpunkt löschen. Virtual macht hier glaube ich auch mehr Schaden als Nutzen. Daher würde ich gern

  1. Das Dictionary entweder mindestens mal protected machen
  2. Das virtual rausnehmen
  3. Eine passendere Signatur als Func<object[],object>
  4. Alternativ könnte man auch nur Methoden protected anbieten, um Code Actions hinzuzufügen.

}
}
219 changes: 219 additions & 0 deletions AnyText/AnyText.Core/WorkspaceEdit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
using System.Collections.Generic;

namespace NMF.AnyText
{
/// <summary>
/// Represents changes to a workspace, including text edits, document changes, and change annotations.
/// </summary>
public class WorkspaceEdit
{
/// <summary>
/// A dictionary of changes to text documents, keyed by document URI, with the value being the text edits for that document.
/// </summary>
public Dictionary<string, TextEdit[]> Changes { get; set; }

/// <summary>
/// A list of document-level changes (e.g., file creation, renaming, deletion).
/// </summary>
public List<DocumentChange> DocumentChanges { get; set; }

/// <summary>
/// A dictionary of annotations associated with changes, keyed by annotation ID.
/// </summary>
public Dictionary<string, ChangeAnnotation> ChangeAnnotations { get; set; }
}

/// <summary>
/// Represents a change to a document, including text edits, file creation, renaming, or deletion.
/// </summary>
public class DocumentChange
georghinkel marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Text document edits (e.g., line insertions, deletions).
/// </summary>
public TextDocumentEdit TextDocumentEdit { get; set; }

/// <summary>
/// Information for creating a new file.
/// </summary>
public CreateFile CreateFile { get; set; }

/// <summary>
/// Information for renaming an existing file.
/// </summary>
public RenameFile RenameFile { get; set; }

/// <summary>
/// Information for deleting an existing file.
/// </summary>
public DeleteFile DeleteFile { get; set; }
}

/// <summary>
/// Represents metadata or instructions for an annotation associated with a change.
/// </summary>
public class ChangeAnnotation
{
/// <summary>
/// A label for the annotation (e.g., "Refactor").
/// </summary>
public string Label { get; set; }

/// <summary>
/// Indicates if the change requires user confirmation.
/// </summary>
public bool? NeedsConfirmation { get; set; }

/// <summary>
/// A description or explanation of the annotation.
/// </summary>
public string Description { get; set; }
}

/// <summary>
/// Represents the text document edit instructions, including the document and the edits.
/// </summary>
public class TextDocumentEdit
{
/// <summary>
/// Identifies the text document to edit, including optional version information.
/// </summary>
public OptionalVersionedTextDocumentIdentifier TextDocument { get; set; }

/// <summary>
/// An Array of edits to perform on the document (e.g., insertions, deletions).
/// </summary>
public TextEdit[] Edits { get; set; }
}

/// <summary>
/// Identifies a text document with optional versioning.
/// </summary>
public class OptionalVersionedTextDocumentIdentifier
{
/// <summary>
/// The URI of the text document.
/// </summary>
public string Uri { get; set; }

/// <summary>
/// An optional version number for the document, if versioning is supported.
/// </summary>
public int? Version { get; set; }
}

/// <summary>
/// Represents the information needed to create a new file.
/// </summary>
public class CreateFile
{
/// <summary>
/// The type of file creation (e.g., "create").
/// </summary>
public string Kind { get; set; }

/// <summary>
/// The URI of the file to be created.
/// </summary>
public string Uri { get; set; }

/// <summary>
/// File options (e.g., whether to overwrite an existing file).
/// </summary>
public FileOptions Options { get; set; }

/// <summary>
/// An optional annotation ID related to the file creation.
/// </summary>
public string AnnotationId { get; set; }
}

/// <summary>
/// Represents the information needed to rename an existing file.
/// </summary>
public class RenameFile
{
/// <summary>
/// The type of file operation (e.g., "rename").
/// </summary>
public string Kind { get; set; }

/// <summary>
/// The URI of the old file name.
/// </summary>
public string OldUri { get; set; }

/// <summary>
/// The URI of the new file name.
/// </summary>
public string NewUri { get; set; }

/// <summary>
/// File options (e.g., whether to overwrite).
/// </summary>
public FileOptions Options { get; set; }

/// <summary>
/// An optional annotation ID related to the file rename.
/// </summary>
public string AnnotationId { get; set; }
}

/// <summary>
/// Represents the information needed to delete an existing file.
/// </summary>
public class DeleteFile
{
/// <summary>
/// The type of file operation (e.g., "delete").
/// </summary>
public string Kind { get; set; }

/// <summary>
/// The URI of the file to be deleted.
/// </summary>
public string Uri { get; set; }

/// <summary>
/// File deletion options (e.g., whether to delete recursively).
/// </summary>
public DeleteFileOptions Options { get; set; }

/// <summary>
/// An optional annotation ID related to the file deletion.
/// </summary>
public string AnnotationId { get; set; }
}

/// <summary>
/// Options for creating or renaming files, such as overwrite behavior.
/// </summary>
public class FileOptions
{
/// <summary>
/// If true, overwrite an existing file.
/// </summary>
public bool? Overwrite { get; set; }

/// <summary>
/// If true, ignore the operation if the file already exists.
/// </summary>
public bool? IgnoreIfExists { get; set; }
}

/// <summary>
/// Options for deleting files, such as recursive deletion and handling missing files.
/// </summary>
public class DeleteFileOptions
{
/// <summary>
/// If true, delete directories recursively.
/// </summary>
public bool? Recursive { get; set; }

/// <summary>
/// If true, ignore the operation if the file does not exist.
/// </summary>
public bool? IgnoreIfNotExists { get; set; }
}
}
16 changes: 16 additions & 0 deletions AnyText/AnyText.Lsp/ILspServer.CodeAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using LspTypes;
using Newtonsoft.Json.Linq;
using StreamJsonRpc;

namespace NMF.AnyText
{
public partial interface ILspServer
{
/// <summary>
/// Handles the <c>textDocument/codeAction</c> request from the client.
/// </summary>
/// <param name="arg">The JSON token containing the parameters of the request. (CodeActionParams)</param>
[JsonRpcMethod(Methods.TextDocumentCodeActionName)]
CodeAction[] CodeAction(JToken arg);
}
}
10 changes: 9 additions & 1 deletion AnyText/AnyText.Lsp/ILspServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,19 @@ public InitializeResult Initialize(
void Shutdown();

/// <summary>
/// Handles the <c>*/setTrace</c> request from the client. This is used to set the trace setting of the server.
/// Handles the <c>$/setTrace</c> request from the client. This is used to set the trace setting of the server.
/// </summary>
/// <param name="arg">The JSON token containing the parameters of the request. (SetTraceParams)</param>
[JsonRpcMethod(MethodConstants.SetTrace)]
public void SetTrace(JToken arg);

/// <summary>
/// Handles the <c>workspace/ececuteCommand</c> request from the client. This is used to execute an action on the
/// Server.
/// </summary>
/// <param name="arg">The JSON token containing the parameters of the request. (ExceuteCommandParams)</param>
[JsonRpcMethod(Methods.WorkspaceExecuteCommandName)]
public void ExecuteCommand(JToken arg);

}
}
Loading