Robot Companion.
Sections

    Robot Companion.

    Your test files already explain themselves. This one renders it.

    A VS Code extension for Robot Framework. It turns the explanations already sitting in your .robot files — [Documentation] blocks and ordinary comments — into rendered prose in a side panel that follows your cursor. And because a test is only half prose, it also reads your Python keyword libraries and tells you what a keyword actually returns, right where you are about to use it.

    It adds no formatter, no diagnostics, no language server. It sits beside whatever Robot Framework tooling you already run.

    This page makes the case. The reference is the inventory: every capability, every limit, and what each part needs from your project.

    01The idea

    Two characters turn a comment into a document

    Robot Framework gives you [Documentation] — one block, at the top, away from the steps it describes. So the real explanation ends up where explanations always end up: in comments, next to the line they are about, where nothing renders them and nobody outside the editor ever sees them.

    Robot Companion reads two comment markers. #> is a documentation line; #>> is a nested one under it. That is the whole syntax. Everything else — headings, bullets, numbered lists, arrow notes for expected results — is ordinary Markdown inside those markers. The file stays a perfectly normal Robot file: strip the extension and you are left with comments.

    suites/checkout.robotwhat you write
    *** Test Cases ***
    Express Checkout Delivers On The Promised Date
        [Documentation]
        ...    Covers the express lane end to end: a
        ...    basket is built, the order is placed with
        ...    express shipping, and then checked.
        ...
        ...    - Express orders must quote a delivery
        ...        date; standard orders need not.
        ...        -> The date shows on the receipt.
        [Tags]    Checkout    Checkout-Express    Smoke
    
        #> ## Prepare the basket
        #> - Start from a clean basket so the totals
        #>   stay predictable.
        ${sku}=       Set Variable    DESK-LAMP-002
        ${basket}=    Add Item To Basket    sku=${sku}
        #>> -> The basket id is reused by later steps.
    
        #> ## Place the order
        #> - Express shipping is the case under test.
        ${order}=    Place Order    basket_id=${basket}
        ...          shipping=EXPRESS
        #>> -> <success>Confirmation returned.</success>
    
        #> ### What we then assert
        #> 1. The payment was at least authorised.
        #> 2. A tracking id exists.
        #> 3. The delivery date is a real date.
        #>> -> <note>Demo fixtures, not real data.</note>
        Should Be Equal    ${order.payment_state}
        ...                AUTHORISED
    the file. Still a normal Robot suite.
    The Documentation Preview panel showing the file name, a fold and export
                    action bar, a list of the three test cases in the file with the first one
                    selected, and below it the rendered documentation: a lead paragraph, a bullet
                    with an indented arrow note, the headings Prepare the basket, Place the order
                    and What we then assert, a green-highlighted success note, a blue-highlighted
                    note, and Variables and Returned Variables sections listing the local variable
                    sku with its value and the two variables assigned from keyword calls.
    the panel. Rendered from that file, synced to the cursor.

    About that image. It is the extension's real Documentation Preview markup, produced by running its own renderer over the file on the left and painting it with VS Code's Dark Modern colour values. It is genuine output, not a mock-up — but it is not a photograph of a running editor window, so the surrounding VS Code chrome is absent.

    02Rendering

    Prose that survives the source

    Source lines are short because editors are narrow; sentences are not. So consecutive documentation comments are joined into one flowing rendered line, and a continuation indented under a bullet or an arrow stays part of that item instead of breaking it in half. When you genuinely want a break, an explicit <br> gives you one. The same rule applies to wrapped [Documentation] continuation rows.

    Every rendered line remembers where it came from. Click a paragraph, a bullet, an arrow note or a heading in the panel and the editor jumps to the exact source line behind it — including later lines in blocks that mix a [Documentation] header with inline markers further down.

    Colour that means something

    Five semantic tags and eight plain colour tags are recognised inside documentation text. They render in the panel and in the printable export, and they survive a Markdown export as the tags you wrote. Anything else — unknown tags, attributes, arbitrary HTML — is rendered as plain text rather than executed.

    Plus <red>, <orange>, <yellow>, <green>, <blue>, <pink>, <purple>, <gray>, and <color value="#0f766e"> for the rare custom one.

    03Types

    What does this keyword actually give me back?

    The question you ask a hundred times a day when a Robot test drives a Python library. The answer is in the library's type annotations, three files away. Robot Companion indexes your workspace's Python sources — statically, by reading them; nothing is imported or executed — and keeps the answer one hover away.

    It finds the library methods you decorate with @keyword, takes their parameter annotations, return annotation and docstring, then walks the returned type: dataclasses, plain annotated classes, @property members, and the element type inside a list[…] or similar container.

    resources/ShopLibrary.pyyour library
    @keyword("Place Order")
    def place_order(
        self,
        basket_id: str,
        shipping: ShippingMethod = ShippingMethod.STANDARD,
        gift_wrap: bool = False,
    ) -> OrderConfirmation:
        """Place the prepared basket and return the
        shop's confirmation.
    
        Args:
            basket_id: Identifier of a basket built by
                `Add Item To Basket`.
            shipping: Which shipping method was picked.
    
        Returns:
            The confirmation object.
        """
    indexed. Read as source, never imported.
    ${order}resolved access paths
    ${order.order_id}
    ${order.total_cents}
    ${order.currency}
    ${order.payment_state}
    ${order.ship_to}
    ${order.parcels}
    ${order.total}
    
    # second level
    ${order.ship_to.street}
    ${order.ship_to.postcode}
    ${order.ship_to.city}
    ${order.ship_to.country}
    ${order.parcels[0].tracking_id}
    ${order.parcels[0].method}
    ${order.parcels[0].delivers_on}
    the answer. The resolver's own first- and second-level output for that keyword's return value; only the divider is ours.

    Notice what those paths are: not a diagram of a type, but the exact strings you would type next — including the index into the list. That is what the Robot Return Explorer side view offers for the variable under your cursor, and a shallower version of it is what you get on hover over any variable assigned from a keyword call.

    Under it sits a technical section for when you want the shape rather than the paths — the resolved type graph, annotated with what each node was recognised as:

    technical detaildefault depth 5
    OrderConfirmation (dataclass)
      .order_id
      .total_cents
      .currency
      .payment_state
      PaymentState (typed class)
      .ship_to
      Address (dataclass)
        .street
        .postcode
        .city
        .country
      .parcels
      Parcel (dataclass)
        .tracking_id
        .method
        ShippingMethod (typed class)
        .delivers_on
      .total

    The same index powers three completions, all of them scoped to named-argument value positions — the place after argument= where a wrong guess costs you a run:

    Hover also resolves plain local values: put the cursor on a variable that a Set Variable or VAR earlier in the same test assigned, and you see what it holds — including the ambiguous case, where a conditional gave it two possible values and the hover says so instead of picking one.

    Honest limits. This is static analysis of Python source, not runtime introspection. It resolves what annotations state. Keywords without a @keyword decorator, dynamic libraries, and unannotated returns are outside what it can see, and the keyword-doc view says so rather than guessing when a match is ambiguous.

    04Reading a long test

    Fold to the shape of the argument

    A five-hundred-line test case is unreadable at full expansion and useless fully collapsed. Because the extension already knows which lines are headings, which are documentation steps and which are the Robot steps underneath them, it can fold to those tiers instead of to brackets: Headlines leaves the #> ## section titles, Steps leaves the documentation lines, Unfold puts it all back.

    Folding is contributed as a normal VS Code folding-range provider, so it composes with the editor you already have; a command is provided to make it the default provider for Robot files if you want the tiers on the standard fold shortcuts.

    A CodeLens above each documentation block — Open rendered documentation preview — opens the block in the panel, and the panel's own list of every documented test case and keyword in the file doubles as a table of contents, with a jump link per entry.

    05Getting it out

    The documentation was always shareable

    Someone will eventually ask what a test does, and they will not have VS Code open. Four export commands take the current block or a multi-select of blocks and produce either a Markdown file — written where you choose, colour tags preserved as written — or a print-styled page with a Print / Save as PDF button on it.

    Export as Markdownreal output, wrapped to fit
    # Express Checkout Delivers On The Promised Date
    
    Covers the express lane end to end: a basket is built,
    the order is placed with express shipping, and then
    checked.
    
    - Express orders must quote a delivery date; standard
      orders need not.
        -> The date shows on the receipt.
    ## Prepare the basket
    - Start from a clean basket so the totals stay
      predictable.
      -> The basket id is reused by later steps.
    ## Place the order
    - Express shipping is the case under test.
      -> <success>Confirmation returned.</success>
    ### What we then assert
    1. The payment was at least authorised.
    2. A tracking id exists.
    3. The delivery date is a real date.
      -> <note>Demo fixtures, not real data.</note>
    
    ## Variables
    
    - `${sku}`: DESK-LAMP-002
    markdown. Wrapped source lines, joined.
    The printable export page: a toolbar reading Print / Save as PDF with the hint
                   to use the print dialog and choose Save as PDF, then the file path, the test case
                   title as a heading, and the same documentation typeset for print with its
                   headings, bullets, arrow notes, coloured semantic spans, and the Variables and
                   Returned Variables sections.
    print. The same block, typeset for paper.

    Both exports carry the block's Variables and Returned Variables sections — the local values the extension resolved, and which keyword each returned variable came from — so the exported document explains the test's data as well as its steps.

    06Restraint

    What it deliberately does not do

    Robot Framework tooling in VS Code is a crowded shelf, and most of it wants to own the editor. This extension contributes two webview views, a CodeLens provider, a folding-range provider, a hover provider and one completion provider. That is the entire surface it claims.

    Where it does cost something, it says so: indexing a workspace is real work, so the index and the resolved return types are cached in memory and optionally on disk per workspace, the roots it scans are configurable, and an Invalidate All Caches command exists for when you want to be sure.

    07Surface

    Everything it contributes

    ContributionWhat it is
    Documentation Preview Sidebar webview. Rendered documentation for the block at the cursor, a table of contents for the file, per-line source jumps, fold and export actions.
    Robot Return Explorer Sidebar webview. Resolved return structure, argument context, and the indexed Python @keyword docstring for the keyword under the cursor, with jump links to the Python definition.
    Hover Local Set Variable / VAR values, Enum members behind a named argument, and the structure of a keyword's return value.
    Completion In named-argument value positions only: Enum members, type-matched local variables, and ${var.} return members.
    CodeLens One lens per documentation block, opening it in the preview.
    Folding Documentation-aware ranges, plus fold-to-headlines / fold-to-steps / unfold commands.
    12 commands Focus, open current block, four exports, four folding commands, show output, invalidate caches.
    35 settings Each hover, completion and the CodeLens has its own on/off switch; depths, limits, index roots, exclusions, cache size and log level are all configurable.

    Every one of them is described, with its real limits and the prerequisites it depends on, in the reference — including the parts of this extension that quietly do nothing unless your Python keywords are shaped a particular way. The README's settings table and the Marketplace listing carry the same list with every default.

    08Installing

    Open a .robot file

    It is on the Visual Studio Code Marketplace under the identifier StochasticEntropy.robot-markdown-companion. Search the Extensions view for Robot Companion, or paste one line:

    from the Marketplacethe published build
    # in VS Code's Quick Open bar — Ctrl/Cmd + P
    ext install StochasticEntropy.robot-markdown-companion
    
    # or from a shell, with the code CLI on your PATH
    code --install-extension StochasticEntropy.robot-markdown-companion

    If you would rather build it than trust a listing, the repository packages its own .vsix. The package script is the same one the published build comes from, and it writes robot-markdown-companion-<version>.vsix into the clone.

    from sourceNode 20+, VS Code 1.85+
    git clone https://github.com/StochasticEntropy/robot-companion
    cd robot-companion
    npm install
    npm run package
    code --install-extension robot-markdown-companion-*.vsix

    Either way, that is the setup. The extension activates on Robot files, indexes the workspace in the background, and the panels appear under its icon in the activity bar. Nothing to configure before it is useful; the 35 settings exist for after you know what you want to change.

    It works on any .robot or .resource file, whether or not another extension has claimed the Robot Framework language id — the providers match the file pattern as well as the language.

    09Elsewhere

    The listing, the source, the inbox

    Nothing on this page is the canonical copy of anything. These are.