Skip to content

Documentation Annotations

Navi supports special comment tags that attach documentation to declarations. These annotations are used by the LSP (for hover and completions) and by the documentation generator.

Both //@tag and // @tag (with a space after //) formats are supported.

Available Tags

TagPlacementDescription
@descriptionFile header (before any declarations)Adds a top-level description for the library
@functionAbove a function declarationAdds a custom description for the function
@paramAbove a function declarationAdds a description for a parameter. Specify the parameter name, then its description
@returnsAbove a function declarationAdds a description for the return value
@typeAbove a type or newtype declarationAdds a custom description for the type
@enumAbove an enum declarationAdds a custom description for the enum
@fieldAbove a type or enum declarationAdds a description for a field or variant. Specify the field name, then its description
@variableAbove a variable declarationAdds a custom description for the variable
@exampleAbove a function or type declarationOpens a code example block (closed by @endexample)
@endexampleCloses an @example block

All tags support multi-line continuation: lines starting with // (without a @ tag) immediately after a tag line are appended to that tag's text.

Documenting Functions

Use @function, @param, and @returns to document function declarations:

navi
//@function Outputs a label with `labelText` on the bar's high.
//@param labelText (series string) The text to display on the label.
//@returns The drawn label ID.
export fn drawLabel(labelText: string) {
    label.new(bar_index, high, text:  labelText)
}

@param and @returns can appear either before or after the @function tag:

navi
//@param series Series of values to process.
//@param length Number of bars (length).
//@function Arnaud Legoux Moving Average.
//
// It uses Gaussian distribution as weights for moving average.
export fn alma(series: series float, length: simple int): series float {
    _
}
// ...

Multi-line Descriptions

Continuation lines (starting with // but without @) extend the previous tag's description:

navi
//@function Calculates the percentage difference
// from the base price to the target price.
//@param basePrice The start price
// used as the reference point.
//@param price The end price.
//@returns The signed deviation percentage.
export fn calcDeviation(basePrice: float, price: float) {
    100 * (price - basePrice) / basePrice
}

Documenting Types

Use @type and @field to document type declarations:

navi
//@type A point on a chart.
//@field index The index of the bar where the point is located, i.e., its `x`
//             coordinate.
//@field price The price where the point is located, i.e., its `y` coordinate.
struct Point {
    int index,
    float price,
}

The @type tag also works for newtype declarations:

navi
//@type Handle for a label drawing object.
export type label = int;

Documenting Enums

Use @enum and @field to document enum declarations and their variants:

navi
//@enum Represents a trading direction.
//@field Long  A long (buy) direction.
//@field Short A short (sell) direction.
//@field Both  Both directions.
export enum Direction {
    Long,
    Short,
    Both,
}

Documenting Variables

Use @variable to document variable declarations:

navi
//@variable The highest price over the last 20 bars.
let highest20: float = ta.highest(high, 20);

//@variable Tracks cumulative volume since the session started.
var cumVol: float = 0.0;

Code Examples

Use @example / @endexample pairs to attach runnable code examples to a function or type. Each line inside the block is a plain // comment; the // prefix (with the space) is stripped automatically. Multiple blocks are allowed — each becomes a separate example.

navi
//@function Calculates the percentage difference between two prices.
//@param base  The reference price.
//@param price The target price.
//@returns The signed deviation as a percentage.
//@example
// // Compare today's close to yesterday's close
// let deviation = calcDeviation(close[1], close);
// plot(deviation, title: "Deviation %");
//@endexample
export fn calcDeviation(base: float, price: float) {
    100 * (price - base) / base
}

Multiple examples are each wrapped in their own block:

navi
//@function Returns the simple moving average of `src` over `length` bars.
//@example
// // Basic 20-bar SMA
// plot(ta.sma(close, 20));
//@endexample
//@example
// // Crossover signal using two SMAs
// let fast = ta.sma(close, 9);
// let slow = ta.sma(close, 21);
// plot_shape(ta.crossover(fast, slow), style: Shape.LabelUp);
//@endexample
export fn sma(src: series float, length: simple int): series float {
    _
}

Examples are shown in the LSP hover tooltip in VS Code.

Inside any description text, you can write [`name`] to create a cross-reference link to another symbol. In the API reference dialog and the generated documentation pages, these render as clickable links that navigate to the target symbol.

navi
//@type Handle for a plot created by [`func:plot`].
export type plot = int;
//@function Fills the area between two [`func:plot`] handles.
//@param hline1 The first horizontal line handle (from [`func:hline`]).
//@returns An hline handle that can be used with [`fill`].

Syntax:

SyntaxResolves to
[`fill`]Current module's fill, or prelude's fill, or global search
[`BarmergeGaps.Off`]BarmergeGaps.Off (enum variant)
[`LineStyle.Solid`]The Solid variant of the LineStyle enum (links to the enum type)
[`variant:LineStyle.Solid`]Explicitly an enum variant (same target, clearer intent)
[`func:plot`]The plot function (excludes the plot type)
[`type:hline`]The hline type (excludes the hline function)
[`enum:LineStyle`]An enum named LineStyle

Qualifier prefixes (func, type, enum) disambiguate names that exist as both a function and a type in the same module.

For dotted references, the resolver first checks if the left side is a module with the right side as a member. If not found, it checks if the left side is an enum type with the right side as a variant name — in which case the link navigates to the enum type. This means both [`BarmergeGaps.Off`] (enum variant) and [`LineStyle.Solid`] (enum variant) work as expected.

Editor Support

When documentation annotations are present, the Navi LSP uses them to provide:

  • Hover information — shows the description, parameters, return value, and field docs when hovering over a symbol
  • Completion details — shows the summary in autocomplete suggestions
  • Document symbols — includes the summary in the outline view

Library Documentation

For exported libraries, documentation annotations are especially important. The documentation generator (navi-docgen) extracts these annotations to produce API reference pages.

Use @description in the file header to add a top-level description for the library itself. It must appear before any declarations:

navi
//@description Provides utilities for calculating volatility bands.
//
// Includes customizable Bollinger Bands and Keltner Channels.
library("MyLib")

Full example:

navi
library("MyLib");

//@type Configuration for a custom indicator.
//@field length     The lookback period.
//@field multiplier The standard deviation multiplier.
export struct Config {
    int length = 14,
    float multiplier = 2.0,
}

//@function Calculates a custom band around a moving average.
//@param src    The source series.
//@param config The indicator configuration.
//@returns The upper band value.
export fn upperBand(src: series float, config: Config) {
    let basis = ta.sma(src, config.length);
    basis + config.multiplier * ta.stdev(src, config.length)
}

Released under the MIT License.