# Channels
## Quick start
Channels are short configuration recipes that typically dictate what `tv` should search through and what's displayed on the screen along with various other options.
Any given channel consists of a single TOML file.
**Example**: the default `files` channel
```toml
[metadata]
name = "files"
description = "A channel to select files and directories"
requirements = ["fd", "bat"]
[source]
command = "fd -t f"
[preview]
command = "bat -n --color=always '{}'"
env = { BAT_THEME = "ansi" }
[keybindings]
shortcut = "f1"
```
## Default location on your system
Channels live in the `cable` directory inside your [television configuration directory](./02-configuration.md).
**Example**:
```
/home/user/.config/television
├── config.toml
└── cable
├── files.toml
├── env.toml
├── alias.toml
├── git-repos.toml
└── text.toml
```
## Community-maintained channels
The repository hosts a list of community-maintained channels which you can get and install to your cable directory using:
```sh
tv update-channels
```
## Invocation
Channels may be invoked:
1. directly from the cli:
```
tv files
```
2. using the remote control:

3. on the fly:
```
tv --source-command 'fd -t f .' --preview-command 'bat -n --color=always {}' --preview-size 70
```
## Creating your own channels
Create a new TOML file in your cable directory:
```sh
touch ~/.config/television/cable/my-awesome-channel.toml
```
Fill out the minimum required fields:
```toml
[metadata]
name = "my-awesome-channel"
[source]
command = "aws s3 ls my-bucket"
```
Launch `tv` with your new channel (or select it via the remote control):
```sh
tv my-awesome-channel
```
The complete channel format spec can be found below.
## Channel specification
### high-level sections
```toml
[metadata]
# general channel information
[source]
# this defines what we're searching through
[preview]
# for each result, maybe display a preview
[ui]
# customize the UI
[keybindings]
# customize keybindings
[actions]
# define external actions
```
### `[metadata]`
```toml
[metadata]
name = "text"
description = "A short description about what my channel does"
requirements = ["rg", "bat"] # any binary requirements my channel needs
```
### `[source]`
```toml
[source]
command = "rg . --no-heading --line-number --colors 'match:fg:white' --colors 'path:fg:blue' --color=always"
# display = "[{split:\\::..2}]\t{split:\\::2}" # what's displayed in the UI (incompatible with `ansi = true`)
output = "{strip_ansi|split:\\::..2}"
ansi = true # whether the results are ANSI formatted
```
##### Multiple Source Commands (Source Cycling)
You can specify multiple source commands in a channel, allowing users to cycle between different search variations:
```toml
[source]
command = ["fd -t f", "fd -t f -H"] # First shows normal files, second includes hidden files
```
When multiple commands are configured:
- Only the first command runs initially
- Press <kbd>Ctrl</kbd>+<kbd>S</kbd> (default keybinding for `cycle_sources`) to switch between commands
**Note**: This feature is currently only available in channel mode (not available when using `--source-command` from the CLI).
##### Sorting Options
You can control how results are sorted using two fields in the `[source]` section:
```toml
[source]
command = "cat ~/.bash_history"
no_sort = true # preserve the original order from the source command
# frecency = false # disable frecency-based ranking for this channel
```
- `no_sort` (default: `false`): When set to `true`, disables both match-quality sorting and frecency, preserving the exact order provided by the source command. This is also available as the `--no-sort` CLI flag.
- `frecency` (default: `true`): When set to `false`, disables frecency ranking for this channel while keeping match-quality sorting. This is useful for channels where the source order is meaningful (e.g., shell history, git log). See [Frecency Sorting](../advanced/02-tips-and-tricks.md#frecency-sorting) for details on how frecency works.
### `[preview]`
```toml
[preview]
command = 'bat -n --color=always {split:\::0}'
env = { BAT_THEME = "ansi" } # extra envs to use when generating preview
offset = '{split:\::1}' # extracts preview offset information from the entry
```
### `[ui]`
```toml
[ui]
ui_scale = 80 # use 80% of available screen
layout = "portrait"
input_bar_position = "bottom"
input_header = "Search:"
[ui.preview_panel]
size = 40 # 40%
header = "{}" # show the currently selected entry
footer = "my awesome footer"
scrollbar = false
[ui.status_bar]
separator_open = "<"
separator_close = ">"
[ui.help_panel]
show_categories = true
[ui.remote_control]
show_channel_descriptions = true
sort_alphabetically = true
# UI panel visibility (individual control)
[ui.preview_panel]
hidden = false
[ui.status_bar]
hidden = false
[ui.help_panel]
hidden = true
[ui.remote_control]
# disabled = false # uncomment to disable remote control for this channel
```
### `[keybindings]`
```toml
[keybindings]
shortcut = "f1" # `f1` will automatically switch to this channel
quit = ["esc", "ctrl-c"]
select_next_entry = ["down", "ctrl-j"]
select_prev_entry = ["up", "ctrl-k"]
confirm_selection = "enter"
```
See the [Actions Reference](../reference/02-actions.md) for a list of available actions.
### `[actions]`
External actions allow you to define custom commands that can be executed on
selected entries. Actions are triggered via keybindings using the
`actions:<action_name>` syntax.
#### Action specification:
| `description` | Optional description of what the action does |
| `command` | Command template to execute (supports [templating syntax](#templating-syntax)) |
| `mode` | Execution mode: `fork` runs command in a subprocess, allowing you to return to tv upon completion (default); `execute` runs command and becomes the new process |
| `separator` | Character(s) to use when joining **multiple selected entries** when using complex template processing; depending on the entries content it might be beneficial to change to another one (default: `" "` - space) |
#### Example:
```toml
[actions.edit]
description = "Open selected files in editor"
command = "nvim {}"
# Single file: nvim 'file1.txt'
# Multiple files: nvim 'file1.txt' 'file2.txt'
# Files with quotes: nvim 'file\'s name.txt'
```
#### Advanced Template Processing:
For complex formatting needs, use the full [templating syntax](#templating-syntax):
```toml
[keybindings]
ctrl-e = "actions:edit"
f2 = "actions:view"
[actions.edit]
description = "Open selected files in editor"
separator = "\n"
# example: inputs "file1" and "file 2" will generate the command
# nvim 'file1' 'file 2'
# Note: we added quotes at command level to avoid shell artifacts
[actions.view]
description = "View files with less"
command = "less {}"
mode = "fork"
separator = " "
# example: inputs "file1" and "file 2" will generate the command
# less file1 file 2
# Note: 3 args here, instead of 2
```
## Templating syntax
Several channel fields can be formatted dynamically using the syntax described in the [string-pipeline](https://docs.rs/string_pipeline/0.12.0/string_pipeline/) crate.
Here's a quick TLDR if you're feeling lazy:
**Basic transformations:**
```bash
# Extract middle items: "a,b,c,d,e"
"{split:,:1..3}"
# Output: "b,c"
# Clean and format names: " john , jane , bob "
# Extract numbers and pad with zeros: "item1,thing22,stuff333"
```
**More niche use-cases:**
```bash
# Filter files, format as list: "app.py,readme.md,test.py,data.json"
# Extract domains from URLs: "https://github.com,https://google.com"
# Debug complex processing: "apple Banana cherry Date"
```