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

# Status and Logging

> Display status messages and log plugin activity

The Status and Logging API provides methods for communicating with users through status messages and logging plugin activity for debugging and monitoring.

## Status Messages

### setStatus

Display a transient message in the editor's status bar.

```typescript theme={null}
setStatus(message: string): void
```

<ParamField path="message" type="string" required>
  Text to display (keep short - status bar has limited width)
</ParamField>

<Note>
  The message will be shown until the next status update or user action. Use for feedback on completed operations (e.g., "File saved", "2 matches found").
</Note>

**Example:**

```typescript theme={null}
// Simple status message
editor.setStatus("File saved successfully");

// Status with dynamic content
const count = results.length;
editor.setStatus(`Found ${count} matches`);

// Status after operation
await editor.spawnProcess("git", ["pull"]);
editor.setStatus("Git pull completed");
```

## Logging Functions

Fresh provides four log levels for plugin messages. Messages appear in the log file when running with appropriate `RUST_LOG` environment variable settings.

### debug

Log a debug message from a plugin.

```typescript theme={null}
debug(message: string): void
```

<ParamField path="message" type="string" required>
  Debug message - include context like function name and relevant values
</ParamField>

<Note>
  Messages appear in log file when running with `RUST_LOG=debug`. Useful for plugin development and troubleshooting.
</Note>

**Example:**

```typescript theme={null}
editor.debug(`Search query: "${query}", found ${results.length} results`);
editor.debug(`Buffer ID: ${bufferId}, cursor at ${position}`);
```

### info

Log an info message from a plugin.

```typescript theme={null}
info(message: string): void
```

<ParamField path="message" type="string" required>
  Info message
</ParamField>

<Note>
  Messages appear in log file when running with `RUST_LOG=info`. Use for important operational messages.
</Note>

**Example:**

```typescript theme={null}
editor.info("Plugin initialized successfully");
editor.info(`Loaded configuration from ${configPath}`);
```

### warn

Log a warning message from a plugin.

```typescript theme={null}
warn(message: string): void
```

<ParamField path="message" type="string" required>
  Warning message
</ParamField>

<Note>
  Messages appear in log file when running with `RUST_LOG=warn`. Use for warnings that don't prevent operation but indicate issues.
</Note>

**Example:**

```typescript theme={null}
editor.warn("Config file not found, using defaults");
editor.warn(`Git command failed: ${stderr}`);
```

### error

Log an error message from a plugin.

```typescript theme={null}
error(message: string): void
```

<ParamField path="message" type="string" required>
  Error message
</ParamField>

<Note>
  Messages appear in log file when running with `RUST_LOG=error`. Use for critical errors that need attention.
</Note>

**Example:**

```typescript theme={null}
editor.error("Failed to initialize LSP server");
editor.error(`Unable to read file: ${error}`);
```

## Log Levels

Control which messages appear in the log by setting the `RUST_LOG` environment variable:

<CodeGroup>
  ```bash Debug Level theme={null}
  # Show all messages (debug, info, warn, error)
  RUST_LOG=debug fresh
  ```

  ```bash Info Level theme={null}
  # Show info, warn, and error messages
  RUST_LOG=info fresh
  ```

  ```bash Warn Level theme={null}
  # Show only warn and error messages
  RUST_LOG=warn fresh
  ```

  ```bash Error Level theme={null}
  # Show only error messages
  RUST_LOG=error fresh
  ```
</CodeGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Use appropriate log levels">
    * `debug()`: Development info, variable values, function entry/exit
    * `info()`: Important milestones, configuration loaded, plugin initialized
    * `warn()`: Recoverable issues, missing config, deprecated features
    * `error()`: Critical failures, exceptions, data corruption
  </Accordion>

  <Accordion title="Include context in messages">
    Make log messages self-explanatory by including relevant context:

    ```typescript theme={null}
    // Bad
    editor.debug("Processing");

    // Good
    editor.debug(`Processing ${files.length} files from ${directory}`);
    ```
  </Accordion>

  <Accordion title="Use setStatus for user feedback">
    Status messages are for users, log messages are for developers:

    ```typescript theme={null}
    // User sees this
    editor.setStatus("Search completed");

    // Developer sees this in logs
    editor.info(`Search found ${results.length} matches in ${elapsed}ms`);
    ```
  </Accordion>

  <Accordion title="Keep status messages concise">
    The status bar has limited width. Keep messages short and clear:

    ```typescript theme={null}
    // Good
    editor.setStatus("Saved");
    editor.setStatus("3 errors, 2 warnings");

    // Too long
    editor.setStatus("File has been successfully saved to disk at /very/long/path/...");
    ```
  </Accordion>
</AccordionGroup>

## Examples

### Progress indication

```typescript theme={null}
async function processFiles(files: string[]) {
  editor.info(`Processing ${files.length} files`);
  
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    editor.setStatus(`Processing ${i + 1}/${files.length}: ${file}`);
    editor.debug(`Processing file: ${file}`);
    
    try {
      await processFile(file);
    } catch (error) {
      editor.error(`Failed to process ${file}: ${error}`);
    }
  }
  
  editor.setStatus(`Processed ${files.length} files`);
  editor.info("Processing complete");
}
```

### Error handling with logging

```typescript theme={null}
async function loadConfig() {
  const configPath = editor.pathJoin([editor.getConfigDir(), "my-plugin.json"]);
  
  if (!editor.fileExists(configPath)) {
    editor.warn(`Config file not found at ${configPath}, using defaults`);
    return getDefaultConfig();
  }
  
  try {
    const content = await editor.readFile(configPath);
    const config = JSON.parse(content);
    editor.info(`Loaded config from ${configPath}`);
    return config;
  } catch (error) {
    editor.error(`Failed to load config: ${error}`);
    editor.setStatus("Failed to load config, using defaults");
    return getDefaultConfig();
  }
}
```

### Debug logging for troubleshooting

```typescript theme={null}
function findReferences(symbol: string) {
  editor.debug(`findReferences called with symbol: "${symbol}"`);
  
  const bufferId = editor.getActiveBufferId();
  const path = editor.getBufferPath(bufferId);
  editor.debug(`Current buffer: ${bufferId}, path: ${path}`);
  
  const cursor = editor.getPrimaryCursor();
  editor.debug(`Cursor position: ${cursor?.position}, selection: ${JSON.stringify(cursor?.selection)}`);
  
  // ... find references logic ...
  
  editor.debug(`Found ${references.length} references`);
  return references;
}
```

### Combining status and logging

```typescript theme={null}
async function runLinter() {
  editor.info("Starting linter");
  editor.setStatus("Running linter...");
  
  try {
    const result = await editor.spawnProcess("eslint", ["."]);
    
    if (result.exit_code === 0) {
      editor.info("Linter completed with no errors");
      editor.setStatus("No lint errors");
    } else {
      const errorCount = result.stdout.split("\n").length;
      editor.warn(`Linter found ${errorCount} issues`);
      editor.setStatus(`${errorCount} lint errors`);
    }
  } catch (error) {
    editor.error(`Linter failed: ${error}`);
    editor.setStatus("Linter failed");
  }
}
```
