[ANN] Small VS Code extension to help creating docstrings

Hi!

I am moving from Neovim to VS Code for my development workflow. In Neovim, I had a lua function to extract information from the function declaration and help me creating docstrings. Hence, I released a small extension to VS Code to do the same:

Basically, you select the text with the function declaration, like:

function my_function(x::Int, y::Int, z::Int = 3; verbose::Bool = false)

and call a command to insert the following snippet:

"""
    my_function(x::Int, y::Int, z::Int = 3; kwargs...) -> <Return type>

<Description of the function>

# Arguments

- `x::Int`: <Argument description>
- `y::Int`: <Argument description>
- `z::Int`: <Argument description>
    (**Default**: `3`)
# Keywords

- `verbose::Bool`: <Keyword description>
    (**Default**: `false`)
"""

Where everything between <> are placeholders that you can navigate using TAB. It fits for my development strategy by writing the most annoying part of the documentation following the template I like. Currently, the extension supports only macros and functions but I am planning to support structures as well.

20 Likes

Why oh why do we have to manually repeat method signatures in docstrings… https://discourse.julialang.org/t/why-is-it-convention-to-repeat-function-signatures-in-docstrings/. Seems like the compiler is in perfect position to automatically prepend the correct signature to each docstring

3 Likes

Looks very cool!
DocStringExtensions.jl does a bit of that parsing but I am not a fan of some design choices / limitations there (like not showing default values for keyword arguments if memory serves) so this extension might be useful

3 Likes

Well, I have no idea :smiley: I am just used to this pattern when documenting all my functions.

If there isn’t already an issue in the Julia repo about doing this, maybe I should make one…

I can’t see any downside to automatically prepending a signature to docstrings that don’t start with a code block.

3 Likes

This will be awesome! Because 95% of time, I really do not need this kind of configurability. Can the system take all the information, including the variable’s name, or only the variable’s type?

Docstrings are lowered to macro calls and should therefore have access to all required info to reproduce the function signature.

Btw, this functionality is also available via LanguageServer.jl, just in a much worse form:

AFAICT it’s not possible to reproduce the nice snippet/tab stuff with TextDocumentEdits directly :frowning:

I see! The snippet/tab is not the most useful thing in my workflow, it is the argument / keyword listing with their default values. It is very annoying to add this information following the template in Blue style / Julia official docs.

…or maybe a PR? :thinking:

3 Likes

Yes! Some ideas:

  1. As you say, if a doctoring begins with a code block, leave it alone.
  2. If a function/method has no docstring, don’t add a docstring. Otherwise the documentation for functions with multiple methods will be extremely long, listing every single method.
  3. If the function is defined as literally function func_name end (no function body), insert its docstring (call it “general docstring”) into other auto-generated docstrings as follows: "$signature\n$general_docstring\n$specific_docstring". The general docstring is supposed to describe the overall purpose of the function ModuleName.function_name.
  4. The function signature should be copied verbatim from the method it belongs to, including keyword arguments, types (possibly auto-minified) and default arguments.

Example “specific docstring”:

# ===== In Distributions.jl =====
"""
Fit a probability distribution via maximum likelihood.
"""
function fit_mle end

# ===== Elsewhere =====
"""
Fits the Student's t distribution using the EM algorithm.
"""
function Distributions.fit_mle(d::TDist, xs::AbstractVector{<:Real})
    # code here
end

Example output:

help?> fit_mle(TDist(1.5), [1,2,3])
   fit_mle(d::TDist, xs::AbstractVector{<:Real})

   Fit a probability distribution via maximum likelihood.
   Fits the Student's t distribution using the EM algorithm.

But perhaps such docstrings will be too cluttered. After all, one could just ask for ?fit_mle and get docstrings for all methods, including the one without the body.