> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/sinelaw/fresh/llms.txt
> Use this file to discover all available pages before exploring further.

# Buffer API

> Query and manipulate buffer content, cursors, and metadata

The Buffer API provides methods for working with editor buffers - the in-memory representation of text files and virtual content.

## Buffer Queries

### getActiveBufferId

Get the buffer ID of the focused editor pane.

```typescript theme={null}
getActiveBufferId(): number
```

<ResponseField name="returns" type="number">
  The active buffer ID, or 0 if no buffer is active (rare edge case)
</ResponseField>

**Example:**

```typescript theme={null}
const bufferId = editor.getActiveBufferId();
editor.info(`Active buffer: ${bufferId}`);
```

### getBufferPath

Get the absolute file path for a buffer.

```typescript theme={null}
getBufferPath(buffer_id: number): string
```

<ParamField path="buffer_id" type="number" required>
  Target buffer ID
</ParamField>

<ResponseField name="returns" type="string">
  Absolute file path, or empty string for unsaved buffers or virtual buffers
</ResponseField>

**Example:**

```typescript theme={null}
const path = editor.getBufferPath(bufferId);
if (path) {
  editor.info(`Buffer path: ${path}`);
}
```

### getBufferLength

Get the total byte length of a buffer's content.

```typescript theme={null}
getBufferLength(buffer_id: number): number
```

<ParamField path="buffer_id" type="number" required>
  Target buffer ID
</ParamField>

<ResponseField name="returns" type="number">
  Buffer length in bytes, or 0 if buffer doesn't exist
</ResponseField>

### isBufferModified

Check if a buffer has been modified since last save.

```typescript theme={null}
isBufferModified(buffer_id: number): boolean
```

<ParamField path="buffer_id" type="number" required>
  Target buffer ID
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if buffer has unsaved changes, `false` otherwise. Virtual buffers are never considered modified.
</ResponseField>

### getBufferInfo

Get full information about a buffer.

```typescript theme={null}
getBufferInfo(buffer_id: number): BufferInfo | null
```

<ParamField path="buffer_id" type="number" required>
  Buffer ID to query
</ParamField>

<ResponseField name="returns" type="BufferInfo | null">
  Buffer information object, or `null` if buffer doesn't exist
</ResponseField>

**BufferInfo Type:**

```typescript theme={null}
interface BufferInfo {
  id: number;           // Unique buffer ID
  path: string;         // File path (empty string if no path)
  modified: boolean;    // Whether buffer has unsaved changes
  length: number;       // Buffer length in bytes
}
```

### listBuffers

List all open buffers.

```typescript theme={null}
listBuffers(): BufferInfo[]
```

<ResponseField name="returns" type="BufferInfo[]">
  Array of all open buffers
</ResponseField>

**Example:**

```typescript theme={null}
const buffers = editor.listBuffers();
editor.info(`Open buffers: ${buffers.length}`);
for (const buf of buffers) {
  editor.debug(`Buffer ${buf.id}: ${buf.path}`);
}
```

### getBufferText

Get text from a buffer range.

```typescript theme={null}
getBufferText(buffer_id: number, start: number, end: number): Promise<string>
```

<ParamField path="buffer_id" type="number" required>
  Buffer ID
</ParamField>

<ParamField path="start" type="number" required>
  Start byte offset
</ParamField>

<ParamField path="end" type="number" required>
  End byte offset
</ParamField>

<ResponseField name="returns" type="Promise<string>">
  Text content from the specified range
</ResponseField>

**Example:**

```typescript theme={null}
// Get first 100 bytes of buffer
const text = await editor.getBufferText(bufferId, 0, 100);
editor.debug(`First 100 bytes: ${text}`);
```

### findBufferByPath

Find a buffer ID by its file path.

```typescript theme={null}
findBufferByPath(path: string): number
```

<ParamField path="path" type="string" required>
  File path to search for
</ParamField>

<ResponseField name="returns" type="number">
  Buffer ID if found, or 0 if not found
</ResponseField>

## Cursor Operations

### getCursorPosition

Get the byte offset of the primary cursor.

```typescript theme={null}
getCursorPosition(): number
```

<ResponseField name="returns" type="number">
  Byte offset of cursor, or 0 if no cursor. For multi-cursor, use `getAllCursors`.
</ResponseField>

<Note>
  This returns a byte offset, not a character index. Use this with `insertText` and `deleteRange`.
</Note>

### getCursorLine

Get the line number of the primary cursor (1-indexed).

```typescript theme={null}
getCursorLine(): number
```

<ResponseField name="returns" type="number">
  Line number starting at 1. Returns 1 if no cursor exists.
</ResponseField>

### getPrimaryCursor

Get primary cursor with selection info.

```typescript theme={null}
getPrimaryCursor(): CursorInfo | null
```

<ResponseField name="returns" type="CursorInfo | null">
  Cursor information including position and selection, or `null` if no cursor
</ResponseField>

**CursorInfo Type:**

```typescript theme={null}
interface CursorInfo {
  position: number;                           // Byte position of the cursor
  selection: { start: number; end: number } | null;  // Selection range if text is selected
}
```

### getAllCursors

Get all cursors (for multi-cursor support).

```typescript theme={null}
getAllCursors(): CursorInfo[]
```

<ResponseField name="returns" type="CursorInfo[]">
  Array of all cursors with position and selection info
</ResponseField>

### getAllCursorPositions

Get byte offsets of all cursors.

```typescript theme={null}
getAllCursorPositions(): number[]
```

<ResponseField name="returns" type="number[]">
  Array of cursor positions. Empty if no cursors. Primary cursor is typically first.
</ResponseField>

### setBufferCursor

Set cursor position in a buffer (also scrolls viewport to show cursor).

```typescript theme={null}
setBufferCursor(buffer_id: number, position: number): boolean
```

<ParamField path="buffer_id" type="number" required>
  ID of the buffer
</ParamField>

<ParamField path="position" type="number" required>
  Byte offset position for the cursor
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

## Buffer Mutations

### insertText

Insert text at a byte position in a buffer.

```typescript theme={null}
insertText(buffer_id: number, position: number, text: string): boolean
```

<ParamField path="buffer_id" type="number" required>
  Target buffer ID
</ParamField>

<ParamField path="position" type="number" required>
  Byte offset where text will be inserted (must be at char boundary)
</ParamField>

<ParamField path="text" type="string" required>
  UTF-8 text to insert
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if command was sent successfully. Operation is asynchronous.
</ResponseField>

<Warning>
  Text is inserted before the byte at position. Position must be valid (0 to buffer length). Insertion shifts all text after position.
</Warning>

**Example:**

```typescript theme={null}
const bufferId = editor.getActiveBufferId();
const pos = editor.getCursorPosition();
editor.insertText(bufferId, pos, "Hello, world!");
```

### insertAtCursor

Insert text at the current cursor position in the active buffer.

```typescript theme={null}
insertAtCursor(text: string): boolean
```

<ParamField path="text" type="string" required>
  The text to insert
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

**Example:**

```typescript theme={null}
editor.insertAtCursor("// TODO: Implement this");
```

### deleteRange

Delete a byte range from a buffer.

```typescript theme={null}
deleteRange(buffer_id: number, start: number, end: number): boolean
```

<ParamField path="buffer_id" type="number" required>
  Target buffer ID
</ParamField>

<ParamField path="start" type="number" required>
  Start byte offset (inclusive)
</ParamField>

<ParamField path="end" type="number" required>
  End byte offset (exclusive)
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if command was sent successfully. Operation is asynchronous.
</ResponseField>

<Warning>
  Deletes bytes from start (inclusive) to end (exclusive). Both positions must be at valid UTF-8 char boundaries.
</Warning>

## Buffer Display

### showBuffer

Switch the current split to display a buffer.

```typescript theme={null}
showBuffer(buffer_id: number): boolean
```

<ParamField path="buffer_id" type="number" required>
  ID of the buffer to show
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

### closeBuffer

Close a buffer and remove it from all splits.

```typescript theme={null}
closeBuffer(buffer_id: number): boolean
```

<ParamField path="buffer_id" type="number" required>
  ID of the buffer to close
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

### openFile

Open a file in the editor, optionally at a specific location.

```typescript theme={null}
openFile(path: string, line: number, column: number): boolean
```

<ParamField path="path" type="string" required>
  File path to open
</ParamField>

<ParamField path="line" type="number" required>
  Line number to jump to (0 for no jump)
</ParamField>

<ParamField path="column" type="number" required>
  Column number to jump to (0 for no jump)
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

**Example:**

```typescript theme={null}
// Open file at specific line
editor.openFile("/path/to/file.rs", 42, 0);

// Just open file without jumping
editor.openFile("/path/to/file.rs", 0, 0);
```

### openFileInSplit

Open a file in a specific split pane.

```typescript theme={null}
openFileInSplit(split_id: number, path: string, line: number, column: number): boolean
```

<ParamField path="split_id" type="number" required>
  The split ID to open the file in
</ParamField>

<ParamField path="path" type="string" required>
  File path to open
</ParamField>

<ParamField path="line" type="number" required>
  Line number to jump to (0 for no jump)
</ParamField>

<ParamField path="column" type="number" required>
  Column number to jump to (0 for no jump)
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

## Configuration

### getConfig

Get the current editor configuration.

```typescript theme={null}
getConfig(): unknown
```

<ResponseField name="returns" type="unknown">
  Merged configuration (user config file + compiled-in defaults). This is the runtime config that the editor is actually using.
</ResponseField>

### getUserConfig

Get the user's configuration (only explicitly set values).

```typescript theme={null}
getUserConfig(): unknown
```

<ResponseField name="returns" type="unknown">
  Configuration from the user's config file only. Fields not present here are using default values.
</ResponseField>

### getConfigDir

Get the absolute path to the user config directory.

```typescript theme={null}
getConfigDir(): string
```

<ResponseField name="returns" type="string">
  Absolute path to config directory (e.g., `~/.config/fresh/` on Linux)
</ResponseField>

### reloadConfig

Reload configuration from file.

```typescript theme={null}
reloadConfig(): void
```

After a plugin saves config changes to the config file, call this to reload the editor's in-memory configuration.

## Diagnostics

### getAllDiagnostics

Get all LSP diagnostics across all files.

```typescript theme={null}
getAllDiagnostics(): TsDiagnostic[]
```

<ResponseField name="returns" type="TsDiagnostic[]">
  Array of all LSP diagnostics
</ResponseField>

**TsDiagnostic Type:**

```typescript theme={null}
interface TsDiagnostic {
  uri: string;          // File URI (e.g., "file:///path/to/file.rs")
  severity: number;     // 1=Error, 2=Warning, 3=Info, 4=Hint
  message: string;      // Diagnostic message
  source?: string | null;  // Source (e.g., "rust-analyzer")
  range: TsDiagnosticRange;  // Location range
}
```

## Actions

### executeAction

Execute a built-in editor action by name.

```typescript theme={null}
executeAction(action_name: string): boolean
```

<ParamField path="action_name" type="string" required>
  Action name (e.g., "move\_word\_right", "move\_line\_end")
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

**Example:**

```typescript theme={null}
// Move cursor to end of word
editor.executeAction("move_word_right");
```

### executeActions

Execute multiple actions in sequence, each with an optional repeat count.

```typescript theme={null}
executeActions(actions: ActionSpecJs[]): boolean
```

<ParamField path="actions" type="ActionSpecJs[]" required>
  Array of action specifications
</ParamField>

<ResponseField name="returns" type="boolean">
  `true` if successful
</ResponseField>

**ActionSpecJs Type:**

```typescript theme={null}
interface ActionSpecJs {
  action: string;
  count?: number | null;
}
```

**Example:**

```typescript theme={null}
// Delete 3 words
editor.executeActions([
  { action: "move_word_right", count: 3 },
  { action: "delete_selection" }
]);
```

## Clipboard

### setClipboard

Copy text to the system clipboard.

```typescript theme={null}
setClipboard(text: string): void
```

<ParamField path="text" type="string" required>
  Text to copy to clipboard
</ParamField>

Copies the provided text to both the internal and system clipboard. Uses OSC 52 and arboard for cross-platform compatibility.

**Example:**

```typescript theme={null}
const text = await editor.getBufferText(bufferId, start, end);
editor.setClipboard(text);
editor.setStatus("Copied to clipboard");
```
