LSP-based IDE support plan #1077
Replies: 21 comments 62 replies
-
|
This is a well thought out plan. A few thoughts : To my understanding, there is no support in the LSP for commenting/uncommenting. Please also document when we should tackle the creation of a hybrid VS extension so that we can include the templates. Should we also include an aspirational statement about whether extension code not related to the LSP should be ported out of VSSDK to VS.Extensibility? What appetite is there to include changes/improvements to the binding discovery process (such as code-gen bindings)? |
Beta Was this translation helpful? Give feedback.
-
|
Sounds like a good plan. Does that mean that the community has decided that this approach provides a good enough interaction/support as a reqnroll plugin in order to go ahead with this? Or should we still evaluate per feature how well it scores and whether it passes as good, good enough, or sub par and look for ways to mitigate any sub par user experiences? A couple of remarks:
Phase 3:
For now the uncommented routine just relies on ctrl+z but I can of course also toggle when a |
Beta Was this translation helpful? Give feedback.
-
|
Any thoughts or preferences on how the server should be packaged/distributed? Would we publish this as a nuget package or kept interna as a git submodule? |
Beta Was this translation helpful? Give feedback.
-
|
I've noticed that the POC is declaring server capabilities globally (during init) and those would (?) apply for both .feature and .cs files. I fear a risk that our LSP would not play well with other LSPs and/or native C# support provided by the IDEs. Let's take care to include some form of experience testing to confirm proper cooperative behaviors. |
Beta Was this translation helpful? Give feedback.
-
|
I will grant that the following is not a high priority item for the first implementation, but I am intrigued by the idea that we precompute the mapping between pickle steps and bindings during the compilation phase. The result would be an artifact that could be used by the LSP to provide Definition and References (especially to external assemblies). But such an artifact could also be used by other tooling such as reports on binding usage (or non-usage). |
Beta Was this translation helpful? Give feedback.
-
|
Another idea to consider is to refactor the code within Reqnroll so that the |
Beta Was this translation helpful? Give feedback.
-
|
We will need to give some thought on telemetry. Do we need to plan a step to normalize the set of monitored events (and data structures) from all three clients that will consume the LSP server? The LSP standard includes a |
Beta Was this translation helpful? Give feedback.
-
|
Here is a proposed structure for the projects that will make up the Visual Studio extension. graph TD
CT["Analytics<br/>(harvested from existing VS Extension)<br/>netstandard2.0"]
subgraph Common ["Common"]
Config[Reqnroll Configuration<br/>netstandard2.0]
end
subgraph LSPHost ["Reqnroll Language Server"]
LSP[LspServerProject<br/>net8<br/>LSP server logic]
Connector["Binding Engine<br/>Reqnroll.dll<br/>run-time varies"]
LSP -.->|"Out-of-proc"| Connector
end
subgraph VisualStudioExtension["Solution: Reqnroll.Plugin.VisualStudio.sln"]
EP["ExtensionProject<br/>VSIX manifest<br/>VSSDK+Extensibility<br/>(net481)"]
subgraph Classic ["Classic VSSDK"]
PTP["ProjectTemplate Project<br/>net481<br/>.vstemplate"]
ITP["ItemTemplate Project<br/>net481<br/>.vstemplate"]
WP[WizardsProject<br/>net481<br/>IWizard impl]
end
subgraph Modern ["VisualStudio.Extensibility"]
Editing["EditingProject<br/>(net8-windows)<br/>LanguageServerProvider<br/>CodeLensProvider"]
end
EP -.->|"Assets"| PTP
EP -.->|"Assets"| ITP
EP -.->|"Assets"| WP
EP -.->|"Out-of-proc"| Editing
end
EP -.->|consumes shared lib| CT
WP -.->|consumes shared lib| CT
Editing -.->|consumes shared lib| CT
Editing -.->|"Out-of-proc"| LSP
VisualStudioExtension-.->|"consumes shared lib"|Common
classDef shared fill:#e1f5fe
classDef classic fill:#fff3e0
classDef modern fill:#f3e5f5
classDef vsix fill:#e8f5e8
classDef hostedreqnroll fill:#e8eaf6
class Common,CT,Config shared
class EP,PTP,ITP,WP classic
class Editing,LSP modern
class VSIX vsix
class Connector hostedreqnroll
|
Beta Was this translation helpful? Give feedback.
-
|
Regarding gherkin document formatting, the existing VisualStudio extension supports two ways of configuring a few settings - in the reqnroll.config file and in the .editorconfig file. The extension merges these settings together (the former provides a global set, the .editorconfig provide overrides at a folder level). Do we want to support these in the new extensions? (We might consider dropping the support for reqnroll.config settings in favor of the .editorconfig approach) What approach should be taken to feed these settings to the formatting service that will run inside the LSP? Is reading these settings a responsibility of the LSP or of the IDE Extension? The LSP message |
Beta Was this translation helpful? Give feedback.
-
|
Scope questions for you @gasparnagy:
|
Beta Was this translation helpful? Give feedback.
-
|
User experience question related to binding discovery - With the LSP we have the opportunity to use the Roslyn parser to discover bindings in project c# source without requiring a compilation cycle. But we also will continue to rely on Reqnroll to perform reflection-based discovery of external assemblies not in the current project. Do we want to attempt this? |
Beta Was this translation helpful? Give feedback.
-
|
I'm experimenting with extracting the Feature file parsing and tagging out of the existing VS Extension. |
Beta Was this translation helpful? Give feedback.
-
|
Re: The VisualStudio extension - would you like this release to behave as an upgrade of the existing VS Extension? (Use the same identifying GUID, name, etc) or be an entirely different product? |
Beta Was this translation helpful? Give feedback.
-
|
Cucumber has an LSP implementation. How closely would we like to match their handling of semantic tagging? In their handling of semantic tag mapping they place a semantic tag on the mediaType assigned to a docString (if it exists) (such as ```xml) Secondly, should we match their pre-existing tag mapping? Their mapping is: export const semanticTokenTypes: SemanticTokenTypes[] = [
SemanticTokenTypes.keyword, // Feature, Scenario, Given etc
SemanticTokenTypes.parameter, // step parameters
SemanticTokenTypes.string, // DocString content and ``` delimiter, table cells (except example table header rows)
SemanticTokenTypes.type, // @tags and DocString ```type
SemanticTokenTypes.variable, // step <placeholder>
SemanticTokenTypes.property, // examples table header row
SemanticTokenTypes.comment, // # commentsFrom the comments in the code, this seems mostly driven by what VSCode easily supports. |
Beta Was this translation helpful? Give feedback.
-
|
I would like to suggest a few new/changed features that should be possible with Diagnostics and CodeLens:
|
Beta Was this translation helpful? Give feedback.
-
|
I'm noticing in the Reqnroll.VisualStudio projects the use of C# attributes such as Do we wish to continue to use them? Is there an update/upgrade that we should consider using? |
Beta Was this translation helpful? Give feedback.
-
|
After some experimentation on my own and reading through @ThomasHeijtink's POC, I've drafted the attached design document. My intent is to confirm the scope, approach, non-functional requirements, and open issues. I apologize in advance for the length. But please review and provide any feedback you have. |
Beta Was this translation helpful? Give feedback.
-
|
I have a working prototype, with tests, for Visual Studio, that implements Features F1, F2, F3, and F4 of the design plan (updated) I previously posted. The prototype:
I will keep working through the plan and documenting findings by updating the plan. The handling of semantic tokens for VisualStudio was quite challenging as the support for it within its built-in LSP client and VS.Extensibility is just not mature. Comments of course are welcome. |
Beta Was this translation helpful? Give feedback.
-
|
While attempting to implement Presume you have a feature file: Feat.feature in Project A. Project A also has a set of step bindings that map to that feature and it binds without error. You create Project B and link in the feature file Feat.feature from Project A. Project B has its own set of bindings. If those bindings in B differ from those in A it will not be obvious in the editor. When the IDE opens a file it provides the LSP server with the file-path. It does not indicate which project context this editing operation is within. Both Projects A and B will see the file as having a file-path from within's Project A's folder structure. This differs from our current VS extension as the display of binding coloring is sensitive to the project from which the feature file has been opened. My apologies if that description is convoluted and hard to follow. |
Beta Was this translation helpful? Give feedback.
-
|
Per feedback from @Code-Grump the design doc has been restructured into 4 separate documents: |
Beta Was this translation helpful? Give feedback.
-
|
I made good progress this week on the experimental VS implementation here The following features are implemented:
With the following yet to be implemented:
The largest hurdle to overcome has been the mismatch between the .net project system and the LSP server's limited concept of file ownership. To overcome that, I've defined several custom request methods and notifications which are used by the VS extension code to send information to the LSP server about which documents belong to a project (and changes in that status). I have one undiagnosed issue that occurs at startup in that when opening an existing solution, if that solution had open files in the editor during its last session those will be reopened. The reopening occurs before the LSP gets spun up so those editors don't get LSP support. Closing and reopening them fix that. (for now). Also, the LSP is spun up lazily by VS and so if there are binding classes open for editing they don't get LSP support until a feature file is opened. I also have a TODO to build out the performance validation tests. |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
This discussion board can be used to have a plan to an LSP-based IDE support based on the proof of concept (PoC) of @ThomasHeijtink: https://github.com/ThomasHeijtink/Reqnroll.Plugin
All of the below is just suggestions, feel free to comment or suggest changes.
Overall goals
Implementation plan
I suggest making the implementation in phases: once we are done with a phase, we can make a review and move on to the next phase only after we are happy with the approach. With this we can avoid to produce a massive amount of code that gets stuck in review for forever.
The suggested phase arrangement could be:
Phase 1: Basic syntax coloring
We should start with an "empty" LSP server and the shells for VS, VSCode and Rider, that provides syntax coloring for Gherkin files using the Gherkin parser. The default language configuration should be read from
reqnroll.json.Related specs:
Related codes (consider to reuse):
With this phase we can verify:
Phase 2: Binding discovery
Import existing binding discovery method from VS ext (processing compiled test assemblies with connectors after build), extend it with a code-based discovery approach and integrate it with core features like: showing undefined steps, define step and go to step definition
Related specs:
Related codes (consider to reuse):
With this phase we can verify:
Phase 3: Editor improvements
Extend editor support with additional missing features:
Phase 4: Navigation improvements
Extend with additional missing features:
Beta Was this translation helpful? Give feedback.
All reactions