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 4 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
63 changes: 63 additions & 0 deletions AnyText/AnyText.Core/CodeActionInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System.Collections.Generic;
using NMF.AnyText.Workspace;

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 Dictionary<string, 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; }

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

namespace NMF.AnyText
{
/// <summary>
/// Represents a CodeLens item used for a Language Server Protocol (LSP) server.
/// CodeLens provides information or actions associated with specific locations in a text document.
/// </summary>
public class CodeLensInfo
{
/// <summary>
/// Gets or sets the title of the CodeLens item, typically a label displayed in the editor.
/// </summary>
public string Title { get; set; }

/// <summary>
/// Gets or sets the identifier for the command to be executed when the CodeLens is activated.
/// </summary>
public string CommandIdentifier { get; set; }

/// <summary>
/// Gets or sets the dictionary of arguments to be passed along with the command when invoked.
/// </summary>
public Dictionary<string, object> Arguments { get; set; }

/// <summary>
/// Gets or sets the start position of the text range that this CodeLens is associated with.
/// </summary>
public ParsePosition Start { get; set; }

/// <summary>
/// Gets or sets the end position of the text range that this CodeLens is associated with.
/// </summary>
public ParsePosition End { get; set; }

/// <summary>
/// Gets or sets additional data associated with this CodeLens, which can be used for custom functionality.
/// </summary>
public object Data { get; set; }
}
}
31 changes: 31 additions & 0 deletions AnyText/AnyText.Core/ExecuteCommandArguments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Generic;

namespace NMF.AnyText
{
/// <summary>
/// Represents the arguments for executing a command on a document.
/// </summary>
public class ExecuteCommandArguments
{

/// <summary>
/// URI of the document.
/// </summary>
public string DocumentUri { get; set; }

/// <summary>
/// Starting position of the Range.
/// </summary>
public ParsePosition Start { get; set; }

/// <summary>
/// Ending position of the Range.
/// </summary>
public ParsePosition End { get; set; }

/// <summary>
/// Additional options for the command execution.
/// </summary>
public Dictionary<string, object> OtherOptions { get; set; }
}
}
24 changes: 24 additions & 0 deletions AnyText/AnyText.Core/Grammars/Grammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,29 @@ 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>
/// Dictionary of executable actions.
/// The key is the action identifier, and the value is the action executor.
/// </summary>
protected Dictionary<string, Func<ExecuteCommandArguments, object>> ExecutableActions { get; } = new ();

/// <summary>
/// Adds a new code action to the dictionary.
/// </summary>
/// <param name="actionIdentifier">The identifier of the action.</param>
/// <param name="executor">The action executor.</param>
protected void AddExecutableAction(string actionIdentifier, Func<ExecuteCommandArguments, object> executor)
{
ExecutableActions.Add(actionIdentifier, executor);
}
/// <summary>
/// Retrieves the dictionary of executable actions as a read-only dictionary.
/// </summary>
/// <returns>A read-only view of the dictionary.</returns>
public IReadOnlyDictionary<string, Func<ExecuteCommandArguments, object>> GetExecutableActions()
{
return ExecutableActions;
}
}
}
10 changes: 10 additions & 0 deletions AnyText/AnyText.Core/Rules/MultiRuleApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ public override void Deactivate(ParseContext context)
}
base.Deactivate(context);
}

/// <inheritdoc />
public override void AddCodeLenses(ICollection<CodeLensInfo> codeLenses)
{
foreach (var ruleApplication in Inner)
{
ruleApplication.AddCodeLenses(codeLenses);
}
base.AddCodeLenses(codeLenses);
}

internal override RuleApplication MigrateTo(MultiRuleApplication multiRule, ParseContext context)
{
Expand Down
10 changes: 10 additions & 0 deletions AnyText/AnyText.Core/Rules/Rule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,5 +200,15 @@ public uint? TokenModifierIndex
get;
internal set;
}

/// <summary>
/// Gets the list of code actions for this rule.
/// </summary>
public virtual IEnumerable<CodeActionInfo> SupportedCodeActions => new List<CodeActionInfo>();
georghinkel marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Gets the list of code lenses for this rule.
/// </summary>
public virtual IEnumerable<CodeLensInfo> SupportedCodeLenses => new List<CodeLensInfo>();
georghinkel marked this conversation as resolved.
Show resolved Hide resolved
}
}
24 changes: 24 additions & 0 deletions AnyText/AnyText.Core/Rules/RuleApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,31 @@ public virtual void Deactivate(ParseContext context)
/// </summary>
/// <returns>A collection of parse errors</returns>
public virtual IEnumerable<ParseError> CreateParseErrors() => Enumerable.Empty<ParseError>();

/// <summary>
/// Add all CodeLenses of this ruleApplication to a collection
/// </summary>
/// <param name="codeLenses">Collection of CodeLenses</param>
public virtual void AddCodeLenses(ICollection<CodeLensInfo> codeLenses)
georghinkel marked this conversation as resolved.
Show resolved Hide resolved
{
if (Rule.SupportedCodeLenses.Any())
{
var ruleCodeLenses = Rule.SupportedCodeLenses.Select(a => new CodeLensInfo()
georghinkel marked this conversation as resolved.
Show resolved Hide resolved
{
Arguments = a.Arguments,
CommandIdentifier = a.CommandIdentifier,
Data = a.Data,
Title = a.Title,
Start = CurrentPosition,
End = CurrentPosition + Length,
});
foreach (var codeLens in ruleCodeLenses)
{
codeLenses.Add(codeLens);
}

}
}
/// <summary>
/// Gets called when the newPosition of the given rule application changes
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions AnyText/AnyText.Core/Rules/SingleRuleApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ public override void Deactivate(ParseContext context)
}
base.Deactivate(context);
}
/// <inheritdoc />
public override void AddCodeLenses(ICollection<CodeLensInfo> codeLenses)
{
if (Inner != null && Inner.IsActive)
Copy link
Contributor

Choose a reason for hiding this comment

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

Der Check für IsActive ist wegen Lookaheads? Ich glaube das wäre einen Kommentar wert.

{
Inner.AddCodeLenses(codeLenses);
}
base.AddCodeLenses(codeLenses);
}

internal override RuleApplication MigrateTo(SingleRuleApplication singleRule, ParseContext context)
{
Expand Down
23 changes: 23 additions & 0 deletions AnyText/AnyText.Core/Workspace/ChangeAnnotation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace NMF.AnyText.Workspace
{
/// <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; }
}
}
28 changes: 28 additions & 0 deletions AnyText/AnyText.Core/Workspace/CreateFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace NMF.AnyText.Workspace
{
/// <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; }
}
}
28 changes: 28 additions & 0 deletions AnyText/AnyText.Core/Workspace/DeleteFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace NMF.AnyText.Workspace
{
/// <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; }
}
}
18 changes: 18 additions & 0 deletions AnyText/AnyText.Core/Workspace/DeleteFileOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace NMF.AnyText.Workspace
{
/// <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; }
}
}
28 changes: 28 additions & 0 deletions AnyText/AnyText.Core/Workspace/DocumentChange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace NMF.AnyText.Workspace
{
/// <summary>
/// Represents a change to a document, including text edits, file creation, renaming, or deletion.
/// </summary>
public class DocumentChange
{
/// <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; }
}
}
Loading