Open george-grec opened 3 months ago
Good idea! Thank you. We'll need to decide the precise syntax. I think it would be nice if the syntax could be valid markdown too. For example:
/// Construct a request from a URL string. The returned `gleam/http/request.Request` will have the same defaults
/// as `gleam/http/request.from_uri` as that is used under the hood.
///
pub fn to(url: String) -> Result(Request(String), Nil)
One tricky thing is when a type and a value have the same name. Which should we link to? I guess the syntax would need to be able specify one or the other? Could get annoying
@lpil Good points!
I think it would be nice if the syntax could be valid markdown too
Strictly speaking using brackets around some text is not invalid markdown but I see where you are coming from. Still, I think it is fine if the code links would just look like regular text with visible brackets in a regular markdown editor. We can expect most gleam code to be open in editors with gleam support where that should not be an issue. Then we could keep backticks as they are for just providing code examples without also being links which I would suggest is a common use case. You could also argue that the functionality that we want (linking to code) is closer to markdown links which also utilize brackets.
One tricky thing is when a type and a value have the same name. Which should we link to?
I am not sure what you mean by "value" in this context but if you mean something like this:
pub type Foo {
Foo
}
then [request.Foo]
should link to the type and [request.Foo.Foo]
should link to the variant / constructor.
In any case, I think it would be best to always require the name of the module for every code link. However, if the type is already imported I don't think a full module path (like gleam/http/request.Request
from your example) is required.
For example:
/// see [request.from_uri] // Good
/// see [from_uri] // Bad, even if the function is defined in the same module
///
pub fn to(url: String) -> Result(Request(String), Nil)
An exception should be made when referencing an argument in the function that is being documented.
/// returns `Nil` if [url] is invalid // Still good, because url is an argument for this function
///
pub fn to(url: String) -> Result(Request(String), Nil)
You will notice that I used backticks instead of a link for Nil
as it is not something that can be linked to ;)
Would this cover all ambiguities?
I would want it to ideally be markdown formatting that still makes sense when there's regular markdown rendering or no rendering, so possibly backticks. We can look at what other tools do.
Value constructors are not namespaced by their type so I'm not a huge fan of having them be so in this context. We try and make everything as consistent or explicit as possible.
How would it know that "request" means the "gleam/http/request" module?
How would it know that "request" means the "gleam/http/request" module?
By being aware of the imports in the current file. Of course, if you reference something from a module that is not imported you would still need to use the full path. That is at least how it works in KDoc.
How do we avoid links breaking when imports are changed? To we have to parse the comments and check them on each compile run?
I would want it to ideally be markdown formatting that still makes sense when there's regular markdown rendering or no rendering, so possibly backticks. We can look at what other tools do.
Sure, I am biased because the tools I use use brackets for this but I'd be happy if other people could make the case for other options so we explore all possibilities.
Value constructors are not namespaced by their type so I'm not a huge fan of having them be so in this context. We try and make everything as consistent or explicit as possible.
Here is an idea off the top of my head:
// in file example.gleam
pub type Foo {
Foo
}
/// see `example.{type Foo}`
references the type and /// see `example.Foo`
references the variant
How do we avoid links breaking when imports are changed? To we have to parse the comments and check them on each compile run?
When writing Kotlin in IntelliJ (and Android Studio I guess) the refactoring tools change references in documentation comments too. If you reference something that is not recognized, the code link in the comment section is highlighted like an error in the editor. To me that sounds like a feature for the LSP and not the compiler but I am not familiar how those things work under the hood - I am just a user of those features.
Given the LSP is an optional extra rather than a required tool for writing Gleam any feature needs to work just as well when not using it. We could have the compiler or build tool do something to cover all users, but not the language server.
Sometimes you want to refer to another specific piece of code when documenting something. You can currently just write the name of the code segment in ticks and the reader can search for that manually but it would be much more useful if there was a standard way to link somewhere and have it be a clickable link in an IDE or on the generated docs page.
Possible inspirations:
Personally, I would love to able to link to functions, types, variants or record accessors.
Example Take the function
fn from_uri(uri: Uri)
from thegleam_http
package which creates a request from a Uri that you can pass to an http client. Now there is also the functionfn to(url: String)
that does the exact same thing but you can just give it a String which will be parsed into a Uri and passed on tofrom_uri(uri: Uri)
. A user of this API might wonder what http method the returned request might have. If the documentation forfrom_uri
already specifies that it defaults toGET
then you could write the documentation forfn to(url: String)
this way:When hovering over
to()
somewhere in your code or when looking at the hexdocs of that function the discoverability would then be much better if you could instantly jump to the referenced functionfrom_uri()
to read up on it.