> ## 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.

# Plugin API Overview

> Getting started with the Fresh editor Plugin API

The Fresh editor provides a powerful plugin API that enables you to extend the editor's functionality using TypeScript. Plugins can create custom commands, respond to events, manipulate buffers, and create rich UI elements.

## Core Concepts

### Buffers

A buffer holds text content and may or may not be associated with a file. Each buffer has a unique numeric ID that persists for the editor session. Buffers track their content, modification state, cursor positions, and path. All text operations (insert, delete, read) use byte offsets, not character indices.

### Splits

A split is a viewport pane that displays a buffer. The editor can have multiple splits arranged in a tree layout. Each split shows exactly one buffer, but the same buffer can be displayed in multiple splits. Use split IDs to control which pane displays which buffer.

### Virtual Buffers

Special buffers created by plugins to display structured data like search results, diagnostics, or git logs. Virtual buffers support text properties (metadata attached to text ranges) that plugins can query when the user selects a line. Unlike normal buffers, virtual buffers are typically read-only and not backed by files.

### Text Properties

Metadata attached to text ranges in virtual buffers. Each entry has text content and a properties object with arbitrary key-value pairs. Use `getTextPropertiesAtCursor` to retrieve properties at the cursor position (e.g., to get file/line info for "go to").

### Overlays

Visual decorations applied to buffer text without modifying content. Overlays can change text color and add underlines. Use overlay IDs to manage them; prefix IDs enable batch removal (e.g., "lint:" prefix for all linter highlights).

### Modes

Keybinding contexts that determine how keypresses are interpreted. Each buffer has a mode (e.g., "normal", "insert", "special"). Custom modes can inherit from parents and define buffer-local keybindings. Virtual buffers typically use custom modes.

## Quick Start

### Creating Your First Plugin

Plugins are TypeScript files that interact with the editor through the global `editor` object:

```typescript theme={null}
// my-plugin.ts

// Register a command
editor.registerCommand(
  "My Plugin: Hello",
  "Say hello from my plugin",
  "my_hello",
  "normal",
  "plugin"
);

// Define the command handler
globalThis.my_hello = () => {
  editor.setStatus("Hello from my plugin!");
};
```

### Responding to Events

Plugins can subscribe to editor events using the `on` method:

```typescript theme={null}
globalThis.onBufferSave = (data) => {
  editor.setStatus(`Saved: ${data.path}`);
};

editor.on("buffer_save", "onBufferSave");
```

### Creating a Virtual Buffer

Virtual buffers are useful for displaying structured data:

```typescript theme={null}
// First define the mode with keybindings
editor.defineMode("search-results", "special", [
  ["Return", "search_goto"],
  ["q", "close_buffer"]
], true);

// Then create the buffer
const result = await editor.createVirtualBufferInSplit({
  name: "*Search*",
  mode: "search-results",
  read_only: true,
  entries: [
    { text: "src/main.rs:42: match\n", properties: { file: "src/main.rs", line: 42 } }
  ],
  ratio: 0.3,
  panel_id: "search"
});
```

## API Categories

The Fresh Plugin API is organized into several categories:

<CardGroup cols={2}>
  <Card title="Buffer API" icon="file-lines" href="/api/buffer">
    Query and manipulate buffer content, cursors, and metadata
  </Card>

  <Card title="Events API" icon="bolt" href="/api/events">
    Subscribe to editor events and hooks
  </Card>

  <Card title="Filesystem API" icon="folder" href="/api/filesystem">
    Read, write, and manipulate files and directories
  </Card>

  <Card title="Overlays API" icon="highlighter" href="/api/overlays">
    Add visual decorations to buffer text
  </Card>

  <Card title="Virtual Buffers" icon="window-restore" href="/api/virtual-buffers">
    Create and manage virtual buffers for structured data
  </Card>

  <Card title="Status & Logging" icon="message" href="/api/status-logging">
    Display status messages and log plugin activity
  </Card>

  <Card title="Internationalization" icon="globe" href="/api/i18n">
    Add multi-language support to your plugin
  </Card>

  <Card title="Utilities" icon="wrench" href="/api/utilities">
    Reusable utilities for common plugin patterns
  </Card>
</CardGroup>

## Common Types

The API uses several TypeScript types that are shared across methods:

### BufferInfo

```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
}
```

### CursorInfo

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

### TextPropertyEntry

```typescript theme={null}
interface TextPropertyEntry {
  text: string;                    // Text to display
  properties: Record<string, unknown>;  // Arbitrary metadata
}
```

### SpawnResult

```typescript theme={null}
interface SpawnResult {
  stdout: string;      // Complete stdout as string
  stderr: string;      // Complete stderr as string
  exit_code: number;   // Process exit code (0 = success)
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use TypeScript types">
    Reference `types/fresh.d.ts` for autocomplete and type checking in your plugin development.
  </Accordion>

  <Accordion title="Prefix overlay IDs">
    Use `"myplugin:something"` format for easy batch removal of overlays.
  </Accordion>

  <Accordion title="Handle errors">
    Wrap async operations in try/catch blocks to provide graceful error handling.
  </Accordion>

  <Accordion title="Be efficient">
    Use batched events like `lines_changed` instead of per-keystroke handlers to avoid performance issues.
  </Accordion>

  <Accordion title="Test incrementally">
    Use `editor.debug()` to log values during development and troubleshooting.
  </Accordion>

  <Accordion title="Support i18n">
    Add `.i18n.json` files to make your plugin accessible to international users.
  </Accordion>
</AccordionGroup>

## Next Steps

<Steps>
  <Step title="Explore the Buffer API">
    Learn how to query and manipulate buffer content in the [Buffer API](/api/buffer) reference.
  </Step>

  <Step title="Subscribe to Events">
    Discover available events in the [Events API](/api/events) documentation.
  </Step>

  <Step title="Create Virtual Buffers">
    Build rich UI elements with [Virtual Buffers](/api/virtual-buffers).
  </Step>

  <Step title="Add Internationalization">
    Make your plugin multilingual with [i18n support](/api/i18n).
  </Step>
</Steps>
