# Configuration

IWE projects are configured through a `.iwe/config.toml` file in your project root. Below are all available configuration options.

## Basic Configuration

``` toml
[markdown]
refs_extension = ""
date_format = "%b %d, %Y"
time_format = "%b %d, %Y %H:%M"
locale = "de_DE"
wiki_link_path = "preserve"

[markdown.formatting]
emphasis_token = "_"
strong_token = "__"
list_token = "-"
ordered_list_token = "."
code_block_token = "`"
code_block_token_count = 3
increment_ordered_list_bullets = true
ordered_list_content_indent = 4
bullet_list_content_indent = 4
rule_token = "-"
rule_token_count = 72

[library]
path = ""
date_format = "%Y-%m-%d"
time_format = "%Y-%m-%d %H:%M"
locale = "en_US"
frontmatter_document_title = "title"

[completion]
link_format = "markdown"
min_prefix_length = 0
trigger_characters = ["["]
```

### Markdown Settings

- `refs_extension`: File extension for markdown references (default: empty, uses `.md`)
- `date_format`: Date format for markdown content display and the `{{today}}` variable (default: `"%b %d, %Y"`, e.g., "Jan 15, 2024")
- `time_format`: Format for the `{{now}}` variable in document content (default: falls back to `date_format`). Use this to include time components like `%H`, `%M`, `%S` in `{{now}}` while keeping `{{today}}` date-only.
- `locale`: Locale for date formatting in document content (default: system locale). Allows different localization for content than for file keys.
- `wiki_link_path`: How the path inside a wiki link (`[[…]]`) is written when documents are written (default: `"preserve"`). One of `"preserve"`, `"full"`, or `"short"`: `"preserve"` keeps each link exactly as typed, `"full"` rewrites every link to its full key path, and `"short"` rewrites every link to its shortest unambiguous path suffix. Affects normalization, completion, and link actions; resolution of existing links is unaffected. See [Keys and Cross-References](keys.md) for details.

### Formatting Settings

Control how IWE renders markdown when normalizing or formatting documents. All fields are optional and use sensible defaults. Invalid values fall back to defaults.

``` toml
[markdown.formatting]
emphasis_token = "_"
strong_token = "__"
list_token = "-"
```

- `emphasis_token`: Character for italic text (default: `"*"`). Options: `"*"` or `"_"`
- `strong_token`: Characters for bold text (default: `"**"`). Options: `"**"` or `"__"`
- `list_token`: Character for unordered list items (default: `"-"`). Options: `"-"`, `"*"`, or `"+"`
- `ordered_list_token`: Character after numbers in ordered lists (default: `"."`). Options: `"."` (`1. item`) or `")"` (`1) item`)
- `code_block_token`: Character for code block fences (default: `` "`" ``). Options: `` "`" `` or `"~"`
- `code_block_token_count`: Minimum number of fence characters (default: `3`)
- `increment_ordered_list_bullets`: Whether to increment ordered list numbers (default: `true`). When `true`, items use `1.`, `2.`, `3.`; when `false`, all items use `1.`
- `ordered_list_content_indent`: Minimum column where ordered list item content and continuation lines start (default: unset, content aligns one space after the marker, e.g. `1. item` with 3-space continuation). Accepts `2`–`4`; values outside the range are ignored. Set to `4` for MkDocs-style alignment (`1.  item` with 4-space continuation). The marker width is always respected, so wider markers (e.g. `10.`) use their natural width when it exceeds the configured value.
- `bullet_list_content_indent`: Minimum column where unordered list item content and continuation lines start (default: unset, content aligns one space after the marker, e.g. `- item` with 2-space continuation). Accepts `2`–`4`; values outside the range are ignored. Set to `4` for MkDocs-style alignment (`-   item` with 4-space continuation).
- `rule_token`: Character for horizontal rules (default: `"-"`). Options: `"-"`, `"*"`, or `"_"`
- `rule_token_count`: Number of characters in horizontal rules (default: `72`)
- `wrap_column`: Wrap paragraphs at this column (default: unset, no wrapping). Minimum effective value is `20`; lower values are ignored. Wrapping splits at word boundaries; inline code, wiki links, math, and link/image URLs stay atomic; inline-link and image text wraps at spaces with the closing `](url)` glued to the last word. List and blockquote indents are subtracted from the effective width so wrapped lines inside `- ` items respect `wrap_column`. Tokens longer than the limit sit on their own line.
- `preserve_line_breaks`: Keep hard line breaks instead of dropping them (default: `false`). Recognizes two trailing spaces (`  \n`) and backslash (`\\\n`) in the source and emits them in the configured `line_break_style` on output.
- `line_break_style`: How preserved hard breaks are emitted (default: `"backslash"`). Options: `"backslash"` (`\\\n`, visible and survives whitespace-trimming editors), `"spaces"` (`  \n`, invisible CommonMark default). Only takes effect when `preserve_line_breaks = true`.
- `preserve_newlines`: Keep soft line breaks inside a paragraph instead of joining the lines (default: `false`). With this on, a paragraph written one sentence per line ([semantic line breaks](https://sembr.org/)) keeps its line layout through normalization instead of being reflowed onto a single line. Independent of `wrap_column`, which reflows and re-wraps paragraph text.

### Library Settings

- `path`: Subdirectory for markdown files relative to project root (default: empty, uses root)
- `date_format`: Date format for file key generation and the `{{today}}` variable (default: `"%Y-%m-%d"`, e.g., "2024-01-15")
- `time_format`: Format for the `{{now}}` variable in file key generation (default: falls back to `date_format`). Use this to include time components in keys, e.g., `"%Y-%m-%d-%H%M"` for sortable keys with time.
- `locale`: Locale for date formatting (default: auto-detected from system). Affects day and month names when using `%A`, `%B`, etc.
- `frontmatter_document_title`: YAML frontmatter field to use as document title (default: none, uses first header)

### Completion Settings

- `link_format`: Format for auto-completed links (default: `"markdown"`). Overridden by a typed `[` or `[[` prefix at the cursor.
  - `"markdown"`: Creates `[title](key)` style links
  - `"wiki"`: Creates `[[key]]` style WikiLinks
- `min_prefix_length`: Minimum number of characters typed before completions appear (default: `0`). Measured against the search query after any leading `[` or `[[` is stripped. Raise to `3` (or higher) to suppress the popup until the user has typed a few characters.
- `trigger_characters`: Characters that open the completion popup (default: `["["]`). Typing any listed character makes the editor request completions from the LSP server. Word characters trigger completion via editor heuristics regardless of this list.

### Date Format Patterns

Date formats use [chrono format specifiers](https://docs.rs/chrono/latest/chrono/format/strftime/index.html):

**Date specifiers:**

- `%Y`: 4-digit year (2024)
- `%y`: 2-digit year (24)
- `%m`: Month as number (01-12)
- `%b`: Abbreviated month name (Jan)
- `%B`: Full month name (January)
- `%d`: Day of month (01-31)
- `%A`: Full weekday name (Monday)
- `%a`: Abbreviated weekday name (Mon)

**Time specifiers:**

- `%H`: Hour in 24-hour format (00-23)
- `%M`: Minute (00-59)
- `%S`: Second (00-59)

**Combined examples:**

- `"%Y-%m-%d %H:%M"` → "2024-01-15 14:30"
- `"%b %d, %Y %H:%M:%S"` → "Jan 15, 2024 14:30:45"
- `"%Y%m%d%H%M"` → "202401151430" (useful for sortable file keys)

Textual specifiers (`%A`, `%a`, `%B`, `%b`) are localized based on the `locale` setting. For example, with `locale = "de_DE"` and `date_format = "%A, %d. %B %Y"`, dates display as "Freitag, 27. März 2026".

### Locale Settings

IWE supports separate locales for file keys and document content. By default, both use your system locale independently.

- **`library.locale`**: Controls the language for file key generation (e.g., `journal/Friday-March-27`)
- **`markdown.locale`**: Controls the language for document content (e.g., `# Freitag, 27. März 2026`)

``` toml
[library]
date_format = "%A-%B-%d"
locale = "en_US"

[markdown]
date_format = "%A, %d. %B %Y"
locale = "de_DE"
```

With this configuration:

- File keys use English day/month names: `journal/Friday-March-27`
- Document content uses German: `# Freitag, 27. März 2026`

The locale accepts both POSIX format (`de_DE`) and BCP47 format (`de-DE`). Encoding suffixes like `.UTF-8` are automatically stripped.

### Frontmatter Document Title

By default, IWE uses the first header in a document as its title for links, autocomplete suggestions, and search results. You can override this behavior by specifying a YAML frontmatter field to use instead:

``` toml
[library]
frontmatter_document_title = "title"
```

With this configuration, a document like:

``` markdown
---
title: My Custom Title
---

# Header (ignored for title)

Document content...
```

Will use "My Custom Title" as the document title instead of "Header (ignored for title)". This affects:

- Link text in auto-completed links: `[My Custom Title](document-key)`
- Link text normalization when references are updated
- Document titles in search results and workspace symbols

If the configured frontmatter field is missing or the document has no frontmatter, IWE falls back to using the first header as the title.

## Commands

Define CLI commands for text transformation actions. Commands receive input via stdin and output transformed content to stdout:

``` toml
[commands.claude]
run = "claude -p"
timeout_seconds = 120

[commands.uppercase]
run = "tr '[:lower:]' '[:upper:]'"
timeout_seconds = 5

[commands.custom_script]
run = "/path/to/my-script.sh"
timeout_seconds = 60
```

Each command requires:

- `run`: Command to execute (by default runs via `sh -c`)

Optional parameters:

- `args`: Array of arguments when using direct execution (only used when `shell = false`)
- `cwd`: Working directory for command execution
- `env`: Environment variables as key-value pairs (supports `$VAR` or `${VAR}` expansion from parent environment)
- `shell`: Execute via shell (`true`, default) or directly (`false`)
- `timeout_seconds`: Maximum execution time in seconds (default: 120)

Commands are executed with the processed input template piped to stdin. The command's stdout becomes the replacement content.

### Example Commands

**Using Claude CLI:**

``` toml
[commands.claude]
run = "claude -p"
timeout_seconds = 120
```

**Using a custom script:**

``` toml
[commands.rewriter]
run = "python ~/scripts/rewrite.py"
timeout_seconds = 30
```

**Simple text transformation:**

``` toml
[commands.uppercase]
run = "tr '[:lower:]' '[:upper:]'"
timeout_seconds = 5
```

**Direct execution with arguments (no shell):**

``` toml
[commands.claude_direct]
run = "claude"
args = ["-p", "--model", "sonnet"]
shell = false
timeout_seconds = 120
```

**With environment variables:**

``` toml
[commands.custom_api]
run = "my-api-tool"
env = { API_KEY = "$MY_API_KEY", DEBUG = "true" }
timeout_seconds = 60
```

**With custom working directory:**

``` toml
[commands.project_script]
run = "./scripts/process.sh"
cwd = "/path/to/project"
timeout_seconds = 30
```

## Transform Actions

Transform actions modify text content in-place using configured commands:

``` toml
[actions.rewrite]
type = "transform"
title = "Rewrite"
command = "claude"
input_template = """
Here's a text that I'm going to ask you to edit. The text is marked with {{context_start}}{{context_end}} tag.

The part you'll need to update is marked with {{update_start}}{{update_end}}.

{{context_start}}
{{context}}
{{context_end}}

Rewrite the given text to improve clarity and readability.
"""
```

Transform action parameters:

- `type`: Must be `"transform"`
- `title`: Display name in editor
- `command`: Reference to command configuration
- `input_template`: Template for preparing stdin input

### Attach Actions

Link content under cursor to another file, creating daily notes or collections:

``` toml
[actions.today]
type = "attach"
title = "Add to Today"
key_template = "{{today}}"
document_template = "# {{today}}\n\n{{content}}\n"

[actions.weekly_review]
type = "attach"
title = "Add to Weekly Review"
key_template = "weekly-{{today}}"
document_template = "# Weekly Review - {{today}}\n\n## Notes\n\n{{content}}\n\n## Action Items\n\n- [ ] \n"
```

Attach action parameters:

- `type`: Must be `"attach"`
- `title`: Display name in editor code actions
- `key_template`: Template for target file key (supports `{{today}}` variable)
- `document_template`: Template for new document content (supports `{{today}}` and `{{content}}` variables)

### Template Variables

**Attach Actions** support:

- `{{today}}`: Current date formatted using `library.date_format` (for keys) or `markdown.date_format` (for content). Intended for date-only formatting.
- `{{now}}`: Current date/time formatted using `library.time_format` (for keys) or `markdown.time_format` (for content). Falls back to `date_format` if `time_format` is not set. Intended for date+time formatting.
- `{{content}}`: The content being attached

**Transform Actions** support:

- `{{context}}`: Document context with the target block marked
- `{{context_start}}`, `{{context_end}}`: Context delimiters
- `{{update_start}}`, `{{update_end}}`: Update region delimiters

### Examples

**Daily Note Creation**

``` toml
[actions.daily]
type = "attach"
title = "Add to Daily Note"
key_template = "daily/{{today}}"
document_template = """# Daily Note - {{today}}

## Today's Focus

{{content}}

## Tasks
- [ ]

## Notes

"""
```

**Project Collection**

``` toml
[actions.project_ideas]
type = "attach"
title = "Add to Project Ideas"
key_template = "projects/ideas"
document_template = "# Project Ideas\n\n{{content}}\n"
```

**Text Transformation with Claude CLI**

``` toml
[commands.claude]
run = "claude -p"
timeout_seconds = 120

[actions.expand]
type = "transform"
title = "Expand"
command = "claude"
input_template = """
Here's a text that I'm going to ask you to edit. The text is marked with {{context_start}}{{context_end}} tag.

The part you'll need to update is marked with {{update_start}}{{update_end}}.

{{context_start}}
{{context}}
{{context_end}}

Expand the text you need to update, generate a couple paragraphs.
"""
```

**Simple Text Transformation**

``` toml
[commands.uppercase]
run = "tr '[:lower:]' '[:upper:]'"
timeout_seconds = 5

[actions.uppercase]
type = "transform"
title = "UPPERCASE"
command = "uppercase"
input_template = "{{context}}"
```

## Migration from Version 2

If you're upgrading from a configuration using the old `[models]` section, IWE will automatically migrate your configuration to version 3. The migration:

1.  Renames `[models]` section to `[commands]` with empty `run` values
2.  Renames `model` field to `command` in transform actions
3.  Renames `prompt_template` field to `input_template` in transform actions
4.  Removes the `context` field from transform actions

After migration, you'll need to manually update the `run` field in each command to specify the actual CLI command to execute.

**Before (version 2):**

``` toml
version = 2

[models.default]
api_key_env = "OPENAI_API_KEY"
base_url = "https://api.openai.com"
name = "gpt-4o"

[actions.rewrite]
type = "transform"
title = "Rewrite"
model = "default"
prompt_template = "..."
context = "Document"
```

**After (version 3):**

``` toml
version = 3

[commands.default]
run = "claude -p"  # Update this to your preferred CLI command
timeout_seconds = 120

[actions.rewrite]
type = "transform"
title = "Rewrite"
command = "default"
input_template = "..."
```
