Navigation Menu

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

Re-enable stdio clients by fixing initialization sequence #1801

Merged
merged 5 commits into from May 17, 2022

Conversation

andyleejordan
Copy link
Member

In addition to a few clean-ups, the primary fix here is to start the PowerShell host in the initialize request handler, instead of the onDidChangeConfiguration handler, which only worked as it relied on a quirk of the VS Code client. In order to do this, we now expect to receive the settings EnableProfileLoading: bool and InitialWorkingDirectory: string as initialization parameters.

Fixes #1695.

@andyleejordan andyleejordan requested a review from a team as a code owner May 17, 2022 15:58
@ghost ghost added Area-Language Server Issue-Bug A bug to squash. labels May 17, 2022
This fixes a whole confusing mess of problems. Previously our initialize
delegate just set some options, but didn’t actually initialize the
host (which is required for the server to work). Instead, we relied on a
particular behavior of VS Code’s client to immediately send us an
`OnDidChangeConfiguration` request, where we then actually started the
host’s command loop. The logic was there because that’s where we
received the client’s configuration on loading profiles and initial
working directory. However, not all clients immediately sent this
request, resulting in PSES v3 not working in Vim or Emacs etc. This
behavior was also confusing! Instead, we now request that the client
send initialization configuration via the initialize request’s
parameters (in fact, the spec has an `initializationOptions` field just
for this). Based on these settings, we can now start the host at the
correct time. We also no longer respect `rootUri` as it has been
long-since deprecated. Note that we can “no longer” (but we weren’t
currently) respect a change to `EnableProfileLoading` nor
`InitialWorkingDirectory` after the server has initialized. But this
makes sense, you must restart it if you want to disable/enable profile
loading or change the initial working directory.
We could set the `Label` to `CompletionText` as the fallback, but that
then makes the list of completions in fancier clients not as
accurate (since PowerShell explicitly provides `ListItemText` for this
purpose). Instead, we set usually unused field `InsertText` with the
same information we provided for more advanced clients in `TextEdit`.
Copy link
Collaborator

@SeeminglyScience SeeminglyScience left a comment

Choose a reason for hiding this comment

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

LGTM! ❤️

One non-blocking question

@@ -98,7 +98,7 @@ public sealed class EditorServicesLoader : IDisposable

AssemblyLoadContext.Default.Resolving += (AssemblyLoadContext _, AssemblyName asmName) =>
{
#if DEBUG
#if ASSEMBLY_LOAD_STACKTRACE
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yesssssssssss

Copy link
Member Author

Choose a reason for hiding this comment

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

Was really bugging me, but didn't want to throw this away either.

@@ -184,7 +185,10 @@ public override async Task<CompletionItem> Handle(CompletionItem request, Cancel
// Retain PowerShell's sort order with the given index.
SortText = $"{sortIndex:D4}{result.ListItemText}",
FilterText = result.CompletionText,
TextEdit = textEdit // Used instead of InsertText.
// Used instead of Label when TextEdit is unsupported
InsertText = result.CompletionText,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah so it just falls back then? That's handy!

How does InsertText work with things like type names where the completion text can be the whole type name? e.g. [System.Management.Automation.<tab>. Though even if that explodes it's better than not working at all so I'm cool with rollin' with it.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it works. Just tested [System.Management.Automation.<tab> using eglot in Emacs and got [System.Management.Automation.Job, but also as I was tabbing through SMA it erroneously at some point doubled up the SM part, which IDK, this also isn't rebased on top of your branch, and dealing with other client's idiosyncrasies is hard. I want to get this out the door and then see what happens in the real world.

Copy link
Collaborator

Choose a reason for hiding this comment

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

but also as I was tabbing through SMA it erroneously at some point doubled up the SM part

That's what I was expecting. My PR won't fix that, I'm even not 100% sure we can fix it if the client doesn't support edits. Either way I'm cool with it just to get those clients at least working and we can take a pass at figuring something out later

@andyleejordan andyleejordan merged commit afc9fd1 into master May 17, 2022
@andyleejordan andyleejordan deleted the andschwa/stdio branch May 17, 2022 16:50
@dkattan
Copy link
Contributor

dkattan commented May 18, 2022

YES, I can finally remove my hacky onDidChnageConfiguration workaround to get PSES to initialize!

@andyleejordan
Copy link
Member Author

@dkattan I saw that and just cringed. Don't ask me how it happened!

@dkattan
Copy link
Contributor

dkattan commented May 18, 2022

@dkattan I saw that and just cringed. Don't ask me how it happened!

I'm pretty sure it's been like this since before the re-write. I first encountered the issue on 2021-06-03 and I stared at TypeFox/monaco-languageclient#201 forever trying to figure out how to make it work.

This was what I had to do:

const monacoLanguageClient = new MonacoLanguageClient({
            name: "Monaco PowerShell",
            clientOptions: {
              // use a language id as a document selector
              documentSelector: ["powershell"],
              middleware: {
                workspace: {
                  didChangeConfiguration: sections => {
                    console.debug(
                      this.$options.name,
                      "Language Server: Overriding workspace/didChangeConfiguration response; Sections: ",
                      sections
                    );
                    monacoLanguageClient.sendNotification(
                      "workspace/didChangeConfiguration",
                      sections
                    );
                  },
                },
              },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Stdio mode broken since v3.0.0
3 participants