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: Proposal for module registry information v2 #10051

Closed
kitsonk opened this issue Apr 7, 2021 · 3 comments · Fixed by #13023
Closed

lsp: Proposal for module registry information v2 #10051

kitsonk opened this issue Apr 7, 2021 · 3 comments · Fixed by #13023
Assignees
Labels
lsp related to the language server suggestion suggestions for new features (yet to be agreed)
Milestone

Comments

@kitsonk
Copy link
Contributor

kitsonk commented Apr 7, 2021

Having re-implemented what we had for module registries completion from vscode_deno v2 branch into the lsp, it made me think that there are potentially a few other features that we could benefit from.

Import Details

Completion Items support a documentation field, which can be displayed in the editor. This could be used to provide information about a package or module in the IDE.

In addition, we do not currently have "intelligent" hover support for imports that could be used to provide information about a package or a module.

It is proposed that we extend the /.well-known/deno-import-intellisense.json schema so that a "variables" item can contain an optional property of "details" which will take a URL like "url" pointing to an endpoint which can provide additional details.

For example it might look something like this:

{
  "registries": [
    {
      "schema": "/:module([a-z0-9_]*)@:version?/:path*",
      "variables": [
        {
          "key": "path",
          "url": "https://example.com/api/modules/${module}/v/${{version}}/",
          "details": "https://example.com/api/modules/${module}/v/${{version}}/details/${path}"
        }
      ]
    }
  ]
}

The response payload would be an LSP MarkupContent item, for example:

{
  "kind": "markdown",
  "value": "Some sort of _description_ here."
}

For completions, the protocol supports lazily resolving the completion data, which means we would only query the endpoint when requested by the client, and hover requests only occur when an import is hovered.

Path Navigation of a schema

Currently, there is no way for Deno to incrementally query a "path" from a module registry, basically a module registry has to return all potential values, even if it trying to represent something like a file system. The Express-like path syntax we use though allows a repeating modifier (* or + for a parameter).

Currently we take that parameter as whole and query that for completions. So for example from above, the path parameter is optional and allowed to repeat. So we can have things like:

But when we query the server we expected to get back all the completions possible, which we return to the client. This prevents a user from navigating a "folder" structure.

The proposal in this case is that we would add a key named "parts" to a variable, which specifies the variable in the URL, which will be used for generating the repeating pattern and incrementally querying each one. The response would need to be more intelligent to indicate whether there are more "subparts" that can be queried. (We would also validate that the schema contains a repeat modifier for that parameter too).

An example might look like this:

{
  "registries": [
    {
      "schema": "/:module([a-z0-9_]*)@:version?/:path*",
      "variables": [
        {
          "key": "path",
          "url": "https://example.com/api/modules/${module}/v/${{version}}/",
          "parts": "https://example.com/api/modules/${module}/v/${{version}}/${path}"
        }
      ]
    }
  ]
}

The response for https://example.com/api/modules/example/v/v1.0.0/ would look like this:

[
  {
    "kind": "file",
    "value": "a.ts"
  },
  {
    "kind": "folder",
    "value": "b"
  },
  {
    "kind": "folder",
    "value": "d"
  }
]

And a response for https://example.com/api/modules/example/v/v1.0.0/b would look like:

[
  {
    "kind": "file",
    "value": "c.ts"
  }
]

When the "parts" URL is absent, individual parts would not be queried, and the current behaviour of providing all the completions would occur.

@stale
Copy link

stale bot commented Jun 6, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 6, 2021
@kitsonk kitsonk added lsp related to the language server suggestion suggestions for new features (yet to be agreed) labels Jun 6, 2021
@stale stale bot removed the stale label Jun 6, 2021
@kitsonk kitsonk self-assigned this Jun 6, 2021
@kitsonk
Copy link
Contributor Author

kitsonk commented Jun 24, 2021

Part of the proposal needs to address preferred modules.

@kitsonk kitsonk mentioned this issue Jun 29, 2021
23 tasks
@kitsonk
Copy link
Contributor Author

kitsonk commented Dec 6, 2021

I have started working on this again, and have created a prototype registry to experiment, and a few changes:

Support incremental searching on endpoints

All URLs to specify the variable in the "url" field, which indicates that the registry is capable of incremental matching. So for given a "url" of https://example.com/api/mods/${module}, when starting to type a module, a request would be made of https://example.com/api/mods/ and the list is not "complete" (see below), then as they were to type, additional requests. For example they typed something like https://example.com/registry/de then a request would be made to https://example.com/api/mods/de.

I believe this "replaces" the need for the "parts" URL mentioned above.

Modify the return types

A registry can either return an array of items (just a string[]) or an ItemList, which would look like this:

interface ItemList {
  items: string[];
  isIncomplete: boolean;
  preselect?: string;
}

Where the items would just be an array of items like before. The isIncomplete flag indicates if the list is compete or not. A registry can indicate by setting isIncomplete to true that additional queries will narrow down the list of results, and additional queries will be made to the endpoint to filter out the list. Also, if there is a specific item that should be preselected, then the preselect property can be set to that string in the items list. This will inform the UI that that item should be preselected.

We will probably support both the old and new formats for a period of time.

Response to a details enpoint

The "details" endpoint should either return a 404 or a documentation response:

interface Documentation {
  kind: "markdown" | "plaintext";
  value: string
}

@kitsonk kitsonk added this to the 1.17.0 milestone Dec 6, 2021
kitsonk added a commit to kitsonk/deno that referenced this issue Dec 8, 2021
kitsonk added a commit to kitsonk/deno that referenced this issue Dec 8, 2021
kitsonk added a commit to kitsonk/deno that referenced this issue Dec 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lsp related to the language server suggestion suggestions for new features (yet to be agreed)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant