# mojolint.lsp

> A module of lint's API.

A batch client for `mojo-lsp-server`.

The server's `--mojo-test` mode reads `// -----`-delimited JSON-RPC messages
from stdin, answers every request before it honours `shutdown`, and runs
single-threaded — a design for scripted use. So the client is a batch: queue
`initialize`, `didOpen`, any number of `hover`/`references` queries, then
`shutdown`/`exit`; write the lot to a file; run the server once with stdin
redirected; parse the `Content-Length`-framed replies and index them by id.
No pipes, no threads, one process per file, well under a second with `std`
loaded.

Positions are LSP positions: 0-based line, 0-based UTF-16 column. The linter
works in bytes and 1-based lines; `Pos` converts at the boundary and the
column difference only matters after a non-ASCII character on the same line.

## Structs

### `Pos`

```mojo
struct Pos
```

A 1-based line and 0-based byte column, as the linter counts.

Implements: `Copyable`, `Equatable`, `ImplicitlyCopyable`, `Movable`, `Writable`

Fields:

- `line: Int`
- `col: Int`

#### `__lt__`

```mojo
def __lt__(self, other: Self) -> Bool
```

#### `__eq__`

```mojo
def __eq__(self, other: Self) -> Bool
```

#### `write_to`

```mojo
def write_to(self, mut writer: T)
```

### `LspBatch`

```mojo
struct LspBatch
```

The requests for one document, in order.

Implements: `Movable`

Fields:

- `uri: String`
- `text: String`
- `next_id: Int`
- `body: String`: The delimited request stream, without the closing shutdown/exit.

#### `__init__`

```mojo
def __init__(out self, path: String, source: String)
```

#### `hover`

```mojo
def hover(mut self, at: Pos) -> Int
```

Queue a hover at `at`; returns the request id.

#### `references`

```mojo
def references(mut self, at: Pos) -> Int
```

Queue a references query (declaration included) at `at`.

#### `run`

```mojo
def run(self, include: List[String]) -> LspReplies
```

Run the server over the queued requests and collect its replies.

The server is `mojo-lsp-server` on `PATH`, or `$MOJO_LSP_SERVER`.

### `LspReplies`

```mojo
struct LspReplies
```

Every message the server sent, parsed, with requests indexed by id.

Implements: `Movable`

Fields:

- `docs: List[JsonDoc]`
- `ids: List[Int]`: `ids[k]` is the id of `docs[k]`, or -1 for a notification.
- `errors: Int`: Diagnostics of severity 1 (error) the server published.
- `raw: String`

#### `__init__`

```mojo
def __init__(out self, var stream: String)
```

#### `hover_text`

```mojo
def hover_text(self, id: Int) -> String
```

The first line of the hover's code block: `(variable) var t: T`, `(argument) p: T`, `(field) var cell: T`, `(function) def f(...)`. Empty when the server had nothing to say.

#### `positions`

```mojo
def positions(self, id: Int) -> List[Pos]
```

The start of every location in a references reply, sorted.

## Functions

### `split_frames`

```mojo
def split_frames(stream: String) -> List[String]
```

The bodies of the `Content-Length:`-framed messages in `stream`.

### `hover_type`

```mojo
def hover_type(text: String) -> String
```

The type in a hover line: everything after the first `: ` of `(variable) var t: Pointer[T, MutUntrackedOrigin]`; empty if none.

### `hover_signature`

```mojo
def hover_signature(text: String) -> String
```

The `def ...` of a `(function) def f(...)` hover line; empty if none.
