diff --git a/television/cable/.keep b/television/cable/.keep new file mode 100644 index 0000000..e69de29 diff --git a/television/cable/alias.toml b/television/cable/alias.toml new file mode 100644 index 0000000..68be046 --- /dev/null +++ b/television/cable/alias.toml @@ -0,0 +1,14 @@ +[metadata] +name = "alias" +description = "A channel to select from shell aliases" + +[source] +# you may need to adjust the command depending on your shell +command = "$SHELL -ic 'alias'" +output = "{split:=:0}" + +[preview] +command = "$SHELL -ic 'alias' | grep -E '^(alias )?{split:=:0}='" + +[ui.preview_panel] +size = 30 diff --git a/television/cable/bash-history.toml b/television/cable/bash-history.toml new file mode 100644 index 0000000..8dc8d58 --- /dev/null +++ b/television/cable/bash-history.toml @@ -0,0 +1,9 @@ +[metadata] +name = "bash-history" +description = "A channel to select from your bash history" +requirements = ["bash"] + +[source] +command = "sed '1!G;h;$!d' ${HISTFILE:-${HOME}/.bash_history} | awk '!seen[$0]++'" +no_sort = true +frecency = false diff --git a/television/cable/brew-packages.toml b/television/cable/brew-packages.toml new file mode 100644 index 0000000..548f5f4 --- /dev/null +++ b/television/cable/brew-packages.toml @@ -0,0 +1,30 @@ +[metadata] +name = "brew-packages" +description = "List and manage Homebrew packages" +requirements = ["brew"] + +[source] +command = [ + { name = "Formulae", run = "brew list --formula" }, + { name = "Casks", run = "brew list --cask" }, +] + +[preview] +command = "brew info '{}'" + +[ui] +layout = "portrait" + +[keybindings] +ctrl-u = "actions:upgrade" +ctrl-d = "actions:uninstall" + +[actions.upgrade] +description = "Upgrade the selected package" +command = "brew upgrade {}" +mode = "execute" + +[actions.uninstall] +description = "Uninstall the selected package" +command = "brew uninstall {}" +mode = "execute" diff --git a/television/cable/cargo-commands.toml b/television/cable/cargo-commands.toml new file mode 100644 index 0000000..a1ce78a --- /dev/null +++ b/television/cable/cargo-commands.toml @@ -0,0 +1,22 @@ +[metadata] +name = "cargo-commands" +description = "List available cargo commands and extensions" +requirements = ["cargo"] + +[source] +command = "cargo --list 2>/dev/null | tail -n +2 | awk '{print $1}'" + +[preview] +command = "cargo {} --help 2>/dev/null | head -50" + +[ui] +layout = "portrait" +preview_panel = { size = 60 } + +[keybindings] +enter = "actions:run" + +[actions.run] +description = "Run the selected cargo command" +command = "cargo {}" +mode = "execute" diff --git a/television/cable/cargo-crates.toml b/television/cable/cargo-crates.toml new file mode 100644 index 0000000..99302d6 --- /dev/null +++ b/television/cable/cargo-crates.toml @@ -0,0 +1,17 @@ +[metadata] +name = "cargo-crates" +description = "List installed cargo crates" +requirements = ["cargo"] + +[source] +command = "cargo install --list 2>/dev/null | grep -v '^ ' | sed 's/:$//'" +display = "{split: :0} {split: :1}" +output = "{split: :0}" + +[preview] +command = "cargo install --list 2>/dev/null | sed -n '/^{split: :0} /,/^[^ ]/p' | head -20" + +[actions.uninstall] +description = "Uninstall the selected crate" +command = "cargo uninstall '{split: :0}'" +mode = "execute" diff --git a/television/cable/channels.toml b/television/cable/channels.toml new file mode 100644 index 0000000..9c8b922 --- /dev/null +++ b/television/cable/channels.toml @@ -0,0 +1,19 @@ +[metadata] +name = "channels" +description = "Select a television channel" +requirements = ["tv", "bat"] + +[source] +command = ["tv list-channels"] + +[preview] +command = "bat -pn --color always ${TELEVISION_CONFIG:-${XDG_CONFIG_HOME:-$HOME/.config}/television}/cable/{}.toml" +shell = "bash" + +[keybindings] +enter = "actions:channel-enter" + +[actions.channel-enter] +description = "Enter a television channel" +command = "tv {}" +mode = "execute" diff --git a/television/cable/crontab.toml b/television/cable/crontab.toml new file mode 100644 index 0000000..c30f989 --- /dev/null +++ b/television/cable/crontab.toml @@ -0,0 +1,20 @@ +[metadata] +name = "crontab" +description = "List and manage crontab entries" + +[source] +command = "crontab -l 2>/dev/null | grep -v '^#' | grep -v '^$'" +no_sort = true +frecency = false + +[preview] +command = '''echo 'Schedule: {split: :..5}' && echo '' && echo 'Command:' && echo '{split: :5..}' ''' + +[ui] +layout = "portrait" +preview_panel = { size = 30 } + +[actions.edit] +description = "Open crontab for editing" +command = "crontab -e" +mode = "execute" diff --git a/television/cable/dirs.toml b/television/cable/dirs.toml new file mode 100644 index 0000000..4dcc5a7 --- /dev/null +++ b/television/cable/dirs.toml @@ -0,0 +1,26 @@ +[metadata] +name = "dirs" +description = "A channel to select from directories" +requirements = ["fd"] + +[source] +command = [ + { name = "Default", run = "fd -t d" }, + { name = "Hidden", run = "fd -t d --hidden" }, +] + +[preview] +command = "ls -la --color=always '{}'" + +[keybindings] +shortcut = "f2" + +[actions.cd] +description = "Open a shell in the selected directory" +command = "cd {} && $SHELL" +mode = "execute" + +[actions.goto_parent_dir] +description = "Re-opens tv in the parent directory" +command = "tv dirs .." +mode = "execute" diff --git a/television/cable/docker-compose.toml b/television/cable/docker-compose.toml new file mode 100644 index 0000000..2379dcc --- /dev/null +++ b/television/cable/docker-compose.toml @@ -0,0 +1,32 @@ +[metadata] +name = "docker-compose" +description = "Manage Docker Compose services" +requirements = ["docker"] + +[source] +command = "docker compose ps --format '{{.Name}}\t{{.Service}}\t{{.Status}}'" +display = "{split:\t:1} ({split:\t:2})" +output = "{split:\t:1}" + +[preview] +command = "docker compose logs --tail=30 --no-log-prefix '{split:\t:1}'" + +[actions.up] +description = "Start the selected service" +command = "docker compose up -d '{split:\t:1}'" +mode = "fork" + +[actions.down] +description = "Stop and remove the selected service" +command = "docker compose down '{split:\t:1}'" +mode = "fork" + +[actions.restart] +description = "Restart the selected service" +command = "docker compose restart '{split:\t:1}'" +mode = "fork" + +[actions.logs] +description = "Follow logs of the selected service" +command = "docker compose logs -f '{split:\t:1}'" +mode = "execute" diff --git a/television/cable/docker-containers.toml b/television/cable/docker-containers.toml new file mode 100644 index 0000000..a5f2953 --- /dev/null +++ b/television/cable/docker-containers.toml @@ -0,0 +1,56 @@ +[metadata] +name = "docker-containers" +description = "List and manage Docker containers" +requirements = ["docker", "jq"] + +[source] +command = [ + { name = "Running", run = "docker ps --format '{{.Names}}\\t{{.Image}}\\t{{.Status}}'" }, + { name = "All", run = "docker ps -a --format '{{.Names}}\\t{{.Image}}\\t{{.Status}}'" }, +] +display = "{split:\\t:0} ({split:\\t:2})" +output = "{split:\\t:0}" + +[preview] +command = "docker inspect '{split:\\t:0}' | jq -C '.[0] | {Name, State, Config: {Image: .Config.Image, Cmd: .Config.Cmd}, NetworkSettings: {IPAddress: .NetworkSettings.IPAddress}}'" + +[ui] +layout = "portrait" + +[keybindings] +ctrl-s = "actions:start" +f2 = "actions:stop" +ctrl-r = "actions:restart" +ctrl-l = "actions:logs" +ctrl-e = "actions:exec" +ctrl-d = "actions:remove" + +[actions.start] +description = "Start the selected container" +command = "docker start '{split:\\t:0}'" +mode = "fork" + +[actions.stop] +description = "Stop the selected container" +command = "docker stop '{split:\\t:0}'" +mode = "fork" + +[actions.restart] +description = "Restart the selected container" +command = "docker restart '{split:\\t:0}'" +mode = "fork" + +[actions.logs] +description = "Follow logs of the selected container" +command = "docker logs -f '{split:\\t:0}'" +mode = "execute" + +[actions.exec] +description = "Execute shell in the selected container" +command = "docker exec -it '{split:\\t:0}' /bin/sh" +mode = "execute" + +[actions.remove] +description = "Remove the selected container" +command = "docker rm '{split:\\t:0}'" +mode = "execute" diff --git a/television/cable/docker-images.toml b/television/cable/docker-images.toml new file mode 100644 index 0000000..a7948ab --- /dev/null +++ b/television/cable/docker-images.toml @@ -0,0 +1,34 @@ +[metadata] +name = "docker-images" +description = "A channel to select from Docker images" +requirements = ["docker", "jq"] + +[source] +command = "docker images --format '{{.Repository}}:{{.Tag}} {{.ID}}'" +output = "{split: :-1}" + +[preview] +command = "docker image inspect '{split: :-1}' | jq -C" + +[ui] +layout = "portrait" + +[keybindings] +ctrl-r = "actions:run" +ctrl-d = "actions:remove" +ctrl-s = "actions:shell" + +[actions.run] +description = "Run a container from the selected image" +command = "docker run -it '{split: :-1}'" +mode = "execute" + +[actions.shell] +description = "Run a shell in the selected image" +command = "docker run -it '{split: :-1}' /bin/sh" +mode = "execute" + +[actions.remove] +description = "Remove the selected image" +command = "docker rmi '{split: :-1}'" +mode = "execute" diff --git a/television/cable/docker-networks.toml b/television/cable/docker-networks.toml new file mode 100644 index 0000000..b57b2c5 --- /dev/null +++ b/television/cable/docker-networks.toml @@ -0,0 +1,20 @@ +[metadata] +name = "docker-networks" +description = "List and manage Docker networks" +requirements = ["docker", "jq"] + +[source] +command = "docker network ls --format '{{.Name}}\t{{.Driver}}\t{{.Scope}}'" +display = "{split:\t:0} ({split:\t:1}, {split:\t:2})" +output = "{split:\t:0}" + +[preview] +command = "docker network inspect '{split:\t:0}' | jq -C '.[0] | {Name, Driver, Scope, IPAM, Containers: (.Containers // {} | to_entries | map({name: .value.Name, ipv4: .value.IPv4Address}))}'" + +[ui] +layout = "portrait" + +[actions.remove] +description = "Remove the selected network" +command = "docker network rm '{split:\t:0}'" +mode = "execute" diff --git a/television/cable/docker-volumes.toml b/television/cable/docker-volumes.toml new file mode 100644 index 0000000..03b8e6f --- /dev/null +++ b/television/cable/docker-volumes.toml @@ -0,0 +1,25 @@ +[metadata] +name = "docker-volumes" +description = "List and manage Docker volumes" +requirements = ["docker", "jq"] + +[source] +command = "docker volume ls --format '{{.Name}}\t{{.Driver}}'" +display = "{split:\t:0} ({split:\t:1})" +output = "{split:\t:0}" + +[preview] +command = "docker volume inspect '{split:\t:0}' | jq -C '.[0]'" + +[ui] +layout = "portrait" + +[actions.remove] +description = "Remove the selected volume" +command = "docker volume rm '{split:\t:0}'" +mode = "execute" + +[actions.inspect] +description = "Inspect the selected volume in a pager" +command = "docker volume inspect '{split:\t:0}' | jq -C '.[0]' | less -R" +mode = "execute" diff --git a/television/cable/dotfiles.toml b/television/cable/dotfiles.toml new file mode 100644 index 0000000..10d21de --- /dev/null +++ b/television/cable/dotfiles.toml @@ -0,0 +1,19 @@ +[metadata] +name = "dotfiles" +description = "A channel to select from your user's dotfiles" +requirements = ["fd", "bat"] + +[source] +command = "fd -t f . $HOME/.config" + +[preview] +command = "bat -n --color=always '{}'" + +[keybindings] +enter = "actions:edit" + +[actions.edit] +description = "Edit the selected dotfile" +command = "${EDITOR:-vim} {}" +shell = "bash" +mode = "execute" diff --git a/television/cable/downloads.toml b/television/cable/downloads.toml new file mode 100644 index 0000000..939e218 --- /dev/null +++ b/television/cable/downloads.toml @@ -0,0 +1,31 @@ +[metadata] +name = "downloads" +description = "Browse recent files in Downloads folder" +requirements = ["fd", "bat"] + +[source] +command = "fd -t f . ~/Downloads 2>/dev/null | head -200" + +[preview] +command = "bat -n --color=always '{}' 2>/dev/null || file '{}'" +env = { BAT_THEME = "ansi" } + +[keybindings] +enter = "actions:open" +ctrl-d = "actions:delete" +ctrl-m = "actions:move" + +[actions.open] +description = "Open the selected file with default application" +command = "xdg-open {} 2>/dev/null || open {}" +mode = "fork" + +[actions.delete] +description = "Delete the selected file" +command = "rm -i {}" +mode = "execute" + +[actions.move] +description = "Move the selected file to current directory" +command = "mv {} ." +mode = "fork" diff --git a/television/cable/env.toml b/television/cable/env.toml new file mode 100644 index 0000000..190144b --- /dev/null +++ b/television/cable/env.toml @@ -0,0 +1,22 @@ +[metadata] +name = "env" +description = "A channel to select from environment variables" + +[source] +command = "printenv" +output = "{split:=:1..}" # output the value + +[preview] +command = "echo '{split:=:1..}'" + +[ui] +layout = "portrait" +preview_panel = { size = 20, header = "{split:=:0}" } + +[keybindings] +shortcut = "f3" + +[actions.name] +description = "Output the variable name instead of the value" +command = "echo '{split:=:0}'" +mode = "execute" diff --git a/television/cable/files.toml b/television/cable/files.toml new file mode 100644 index 0000000..b82b502 --- /dev/null +++ b/television/cable/files.toml @@ -0,0 +1,33 @@ +[metadata] +name = "files" +description = "A channel to select files and directories" +requirements = ["fd", "bat", "mtime-sort"] + +# Most recently modified first; tv ranks matches and frecency on top. +[source] +command = [ + { name = "Default", run = "fd -t f | mtime-sort" }, + { name = "Hidden", run = "fd -t f -H | mtime-sort" }, +] +shell = "bash" + +[preview] +command = "bat -n --color=always '{}'" +env = { BAT_THEME = "ansi" } + +# ctrl-e (edit) and ctrl-h (goto_parent_dir) are bound in config.toml. +[keybindings] +shortcut = "f1" +[actions.edit] +description = "Opens the selected entries in nvim" +# Redirect to the tty: the fish ctrl-t binding runs tv inside a command +# substitution, so stdout is a pipe there. +command = "nvim {} /dev/tty" +shell = "bash" +# use `mode = "fork"` if you want to return to tv afterwards +mode = "execute" + +[actions.goto_parent_dir] +description = "Re-opens tv in the parent directory" +command = "tv files .." +mode = "execute" diff --git a/television/cable/fish-history.toml b/television/cable/fish-history.toml new file mode 100644 index 0000000..792ee02 --- /dev/null +++ b/television/cable/fish-history.toml @@ -0,0 +1,9 @@ +[metadata] +name = "fish-history" +description = "A channel to select from your fish history" +requirements = ["fish"] + +[source] +command = "fish -c 'history'" +no_sort = true +frecency = false diff --git a/television/cable/fonts.toml b/television/cable/fonts.toml new file mode 100644 index 0000000..5eec6e8 --- /dev/null +++ b/television/cable/fonts.toml @@ -0,0 +1,13 @@ +[metadata] +name = "fonts" +description = "List installed system fonts" +requirements = ["fc-list"] + +[source] +command = "fc-list --format='%{family}\n' | sort -uf" + +[preview] +command = "fc-list '{}' --format='%{file}\n%{style}\n%{family}\n' | head -20" + +[ui.preview_panel] +size = 70 diff --git a/television/cable/gh-issues.toml b/television/cable/gh-issues.toml new file mode 100644 index 0000000..07df877 --- /dev/null +++ b/television/cable/gh-issues.toml @@ -0,0 +1,47 @@ +[metadata] +name = "gh-issues" +description = "List GitHub issues for the current repo" +requirements = ["gh", "jq"] + +[source] +command = '''gh issue list --state open --limit 100 --json number,title,createdAt,author,labels | jq -r 'sort_by(.createdAt) | reverse | .[] | " \u001b[32m#\(.number)\u001b[39m \(.title) \u001b[33m@\(.author.login)\u001b[39m" + (if (.labels | length) > 0 then " " + ([.labels[] | "\u001b[35m" + .name + "\u001b[39m"] | join(" ")) else "" end)' +''' +ansi = true +output = "{strip_ansi|split:#:1|split: :0}" + +[ui] +layout = "portrait" +preview_panel = { header = '{strip_ansi|split:#:1|split: :0}' } + +[preview] +command = '''gh issue view '{strip_ansi|split:#:1|split: :0}' --json number,title,body,state,author,createdAt,updatedAt,labels,assignees | jq -r ' +" " + .title, +" #" + (.number | tostring), +"", +" \u001b[36mStatus:\u001b[39m \u001b[32m" + .state + "\u001b[39m", +" \u001b[36mAuthor:\u001b[39m \u001b[33m" + .author.login + "\u001b[39m", +" \u001b[36mCreated:\u001b[39m " + (.createdAt | fromdateiso8601 | (now - .) | if . < 3600 then (./60|floor|tostring) + " minutes ago" elif . < 86400 then (./3600|floor|tostring) + " hours ago" else (./86400|floor|tostring) + " days ago" end), +" \u001b[36mUpdated:\u001b[39m " + (.updatedAt | fromdateiso8601 | (now - .) | if . < 3600 then (./60|floor|tostring) + " minutes ago" elif . < 86400 then (./3600|floor|tostring) + " hours ago" else (./86400|floor|tostring) + " days ago" end), +(if (.labels | length) > 0 then " \u001b[36mLabels:\u001b[39m " + ([.labels[] | "\u001b[35m" + .name + "\u001b[39m"] | join(" ")) else "" end), +(if (.assignees | length) > 0 then " \u001b[36mAssignees:\u001b[39m " + ([.assignees[].login] | join(", ")) else "" end), +"", +" \u001b[90m────────────────────────────────────────────────────────────\u001b[39m", +"", +(.body // "")' +''' + +[actions.open] +description = "Open the issue in the browser" +command = "gh issue view {strip_ansi|split:#:1|split: :0} --web" +mode = "fork" + +[actions.close] +description = "Close the selected issue" +command = "gh issue close {strip_ansi|split:#:1|split: :0}" +mode = "fork" + +[actions.comment] +description = "Add a comment to the selected issue" +command = "gh issue comment {strip_ansi|split:#:1|split: :0}" +mode = "execute" + diff --git a/television/cable/gh-prs.toml b/television/cable/gh-prs.toml new file mode 100644 index 0000000..2ac73c5 --- /dev/null +++ b/television/cable/gh-prs.toml @@ -0,0 +1,52 @@ +[metadata] +name = "gh-prs" +description = "List GitHub PRs for the current repo" +requirements = ["gh", "jq"] + +[source] +command = '''gh pr list --state open --limit 100 --json number,title,createdAt,author,labels | jq -r 'sort_by(.createdAt) | reverse | .[] | " \u001b[32m#\(.number)\u001b[39m \(.title) \u001b[33m@\(.author.login)\u001b[39m" + (if (.labels | length) > 0 then " " + ([.labels[] | "\u001b[35m" + .name + "\u001b[39m"] | join(" ")) else "" end)' +''' +output = '{strip_ansi|split:#:1|split: :0}' +ansi = true + +[ui] +layout = "portrait" + +[preview] +command = '''gh pr view '{strip_ansi|split:#:1|split: :0}' --json number,title,body,state,headRefName,baseRefName,author,createdAt,updatedAt,mergeable,changedFiles,additions,deletions,labels,assignees,reviewDecision,headRepository,headRepositoryOwner | jq -r ' +" " + .title, +" #" + (.number | tostring), +"", +" \u001b[36mStatus:\u001b[39m \u001b[32m" + .state + "\u001b[39m " + .baseRefName + " ← " + .headRefName, +" \u001b[36mRepo:\u001b[39m \u001b[34m" + (.headRepositoryOwner.login) + "/" + (.headRepository.name) + "\u001b[39m", +" \u001b[36mAuthor:\u001b[39m \u001b[33m" + .author.login + "\u001b[39m", +" \u001b[36mCreated:\u001b[39m " + (.createdAt | fromdateiso8601 | (now - .) | if . < 3600 then (./60|floor|tostring) + " minutes ago" elif . < 86400 then (./3600|floor|tostring) + " hours ago" else (./86400|floor|tostring) + " days ago" end), +" \u001b[36mUpdated:\u001b[39m " + (.updatedAt | fromdateiso8601 | (now - .) | if . < 3600 then (./60|floor|tostring) + " minutes ago" elif . < 86400 then (./3600|floor|tostring) + " hours ago" else (./86400|floor|tostring) + " days ago" end), +(if (.labels | length) > 0 then " \u001b[36mLabels:\u001b[39m " + ([.labels[] | "\u001b[35m" + .name + "\u001b[39m"] | join(" ")) else "" end), +" \u001b[36mMerge Status:\u001b[39m " + (if .mergeable == "MERGEABLE" then "\u001b[32m✓ Clean\u001b[39m" elif .mergeable == "CONFLICTING" then "\u001b[31m✗ Dirty\u001b[39m" else "\u001b[33m? Unknown\u001b[39m" end), +" \u001b[36mChanges:\u001b[39m " + (.changedFiles | tostring) + " files \u001b[32m+" + (.additions | tostring) + "\u001b[39m \u001b[31m-" + (.deletions | tostring) + "\u001b[39m", +"", +" \u001b[90m────────────────────────────────────────────────────────────\u001b[39m", +"", +(.body // "")' +''' + +[actions.open] +description = "Open the PR in the browser" +command = "gh pr view {strip_ansi|split:#:1|split: :0} --web" +mode = "execute" + +[actions.checkout] +description = "Checkout the PR branch locally" +command = "gh pr checkout {strip_ansi|split:#:1|split: :0}" +mode = "execute" + +[actions.merge] +description = "Merge the selected PR" +command = "gh pr merge {strip_ansi|split:#:1|split: :0}" +mode = "execute" + +[actions.diff] +description = "View the PR diff" +command = "gh pr diff {strip_ansi|split:#:1|split: :0} | less" +mode = "execute" diff --git a/television/cable/ghq-repos.toml b/television/cable/ghq-repos.toml new file mode 100644 index 0000000..5edffd5 --- /dev/null +++ b/television/cable/ghq-repos.toml @@ -0,0 +1,60 @@ +[metadata] +name = "ghq-repos" +description = """ +ghq repositories (plus the chezmoi source tree) and Obsidian vaults, newest +git activity first. Enter prints the directory; the gho shell function (ctrl-o +in fish, zsh and bash) cds into it. +""" +requirements = ["ghq", "fd", "onefetch", "mtime-sort"] + +# Entries are "\t": the name is what you fuzzy-match, the +# path is what enter prints. ctrl-s cycles repos → vaults. +[source] +command = [ + { name = "Repos", run = ''' +root=$(ghq root) +{ + ghq list | awk -v r="$root" '{ print $0 "\t" r "/" $0 }' + # chezmoi's source is a github.com/prdlk/dotfiles checkout outside ghq root. + c=$HOME/.local/share/chezmoi + [ -d "$c/.git" ] && printf 'github.com/prdlk/dotfiles\t%s\n' "$c" +} | mtime-sort --repo +''' }, + { name = "Vaults", run = ''' +v=$HOME/Documents/Obsidian +fd -H -t d -d 3 '^\.obsidian$' "$v" -x dirname | + awk -v r="$v/" '{ print substr($0, length(r) + 1) "\t" $0 }' | + mtime-sort +''' }, +] +shell = "bash" +display = "{split:\\t:0}" +output = "{split:\\t:1}" + +[preview] +command = ''' +d='{split:\t:1}' +if [ -e "$d/.git" ]; then + onefetch --no-art "$d" 2>&1 +else + eza --tree --level 2 --color=always "$d" 2>/dev/null || ls -la "$d" +fi +''' +shell = "bash" + +# ctrl-e (edit) is bound globally in config.toml. +[keybindings] +ctrl-b = "actions:browse" + +[actions.edit] +description = "Open the repository in nvim" +# /dev/tty: the gho wrapper captures tv's stdout to read the picked path. +command = "cd '{split:\\t:1}' && nvim . /dev/tty" +shell = "bash" +mode = "execute" + +[actions.browse] +description = "Open the repository's web page (gop)" +command = "cd '{split:\\t:1}' && gop >/dev/null 2>&1" +shell = "bash" +mode = "fork" diff --git a/television/cable/git-branch.toml b/television/cable/git-branch.toml new file mode 100644 index 0000000..d1e2032 --- /dev/null +++ b/television/cable/git-branch.toml @@ -0,0 +1,37 @@ +[metadata] +name = "git-branch" +description = "A channel to select from git branches" +requirements = ["git"] + +[source] +command = "git --no-pager branch --all --format=\"%(refname:short)\"" +output = "{split: :0}" + +[preview] +command = "git show -p --stat --pretty=fuller --color=always '{0}'" + +[keybindings] +enter = "actions:checkout" +ctrl-d = "actions:delete" +ctrl-m = "actions:merge" +ctrl-r = "actions:rebase" + +[actions.checkout] +description = "Checkout the selected branch" +command = "git checkout '{0}'" +mode = "execute" + +[actions.delete] +description = "Delete the selected branch" +command = "git branch -d '{0}'" +mode = "execute" + +[actions.merge] +description = "Merge the selected branch into current branch" +command = "git merge '{0}'" +mode = "execute" + +[actions.rebase] +description = "Rebase current branch onto the selected branch" +command = "git rebase '{0}'" +mode = "execute" diff --git a/television/cable/git-deletions.toml b/television/cable/git-deletions.toml new file mode 100644 index 0000000..bb047c9 --- /dev/null +++ b/television/cable/git-deletions.toml @@ -0,0 +1,24 @@ +[metadata] +name = "git-deletions" +description = "A channel to list files which were deleted from the Git repository" +requirements = ["git", "rg", "bat"] + +[source] +command = "git log --diff-filter=D --summary | rg 'delete mode \\d+' -r '' --trim" + +[preview] +command = ["git show \"$(git rev-list -n1 HEAD -- '{}')^:{}\" | bat -n --color always --file-name '{}'", "git show --summary \"$(git rev-list -n1 HEAD -- '{}')\""] + +[keybindings] +enter = "actions:print_commit" +ctrl-r = "actions:restore_file" + +[actions.print_commit] +description = "Print the latest commit where file was deleted" +command = "echo \"$(git rev-list -n1 HEAD -- {})\"" +mode = "execute" + +[actions.restore_file] +description = "Restore the selected file" +command = "git checkout \"$(git rev-list -n1 HEAD -- {})^\" -- {}" + diff --git a/television/cable/git-diff.toml b/television/cable/git-diff.toml new file mode 100644 index 0000000..fd44677 --- /dev/null +++ b/television/cable/git-diff.toml @@ -0,0 +1,34 @@ +[metadata] +name = "git-diff" +description = "A channel to select files from git diff commands" +requirements = ["git"] + +[source] +command = "git diff --name-only HEAD" + +[preview] +command = "git diff HEAD --color=always -- '{}'" + +[ui] +layout = "portrait" + +[keybindings] +ctrl-s = "actions:stage" +ctrl-r = "actions:restore" +ctrl-e = "actions:edit" + +[actions.stage] +description = "Stage the selected file" +command = "git add {}" +mode = "fork" + +[actions.restore] +description = "Discard changes in the selected file" +command = "git restore {}" +mode = "fork" + +[actions.edit] +description = "Open the selected file in editor" +command = "${EDITOR:-vim} {}" +shell = "bash" +mode = "execute" diff --git a/television/cable/git-files.toml b/television/cable/git-files.toml new file mode 100644 index 0000000..e51a20f --- /dev/null +++ b/television/cable/git-files.toml @@ -0,0 +1,35 @@ +[metadata] +name = "git-files" +description = """ +Files tracked in the current git repository, most recently modified first +(all files under the cwd outside a repo). Enter opens the selection in nvim; +bound to ctrl-e in fish, zsh and bash. +""" +requirements = ["git", "fd", "bat", "mtime-sort"] + +[source] +command = [ + { name = "Tracked", run = ''' +if top=$(git rev-parse --show-toplevel 2>/dev/null); then + git -c core.quotePath=false ls-files -- "$top" +else + fd -t f +fi | mtime-sort +''' }, + { name = "All", run = "fd -t f -H -E .git | mtime-sort" }, +] +shell = "bash" + +[preview] +command = "bat -n --color=always '{}'" +env = { BAT_THEME = "ansi" } + +# ctrl-e (edit) is bound globally in config.toml. +[keybindings] +enter = "actions:edit" + +[actions.edit] +description = "Opens the selected entries in nvim" +command = "nvim {} /dev/tty" +shell = "bash" +mode = "execute" diff --git a/television/cable/git-log.toml b/television/cable/git-log.toml new file mode 100644 index 0000000..9f80a9f --- /dev/null +++ b/television/cable/git-log.toml @@ -0,0 +1,34 @@ +[metadata] +name = "git-log" +description = "A channel to select from git log entries" +requirements = ["git"] + +[source] +command = "git log --graph --pretty=format:'%C(yellow)%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --color=always" +output = "{strip_ansi|split: :1}" +ansi = true +no_sort = true +frecency = false + +[preview] +command = "git show -p --stat --pretty=fuller --color=always '{strip_ansi|split: :1}' | head -n 1000" + +[keybindings] +ctrl-y = "actions:cherry-pick" +ctrl-r = "actions:revert" +ctrl-o = "actions:checkout" + +[actions.cherry-pick] +description = "Cherry-pick the selected commit" +command = "git cherry-pick '{strip_ansi|split: :1}'" +mode = "execute" + +[actions.revert] +description = "Revert the selected commit" +command = "git revert '{strip_ansi|split: :1}'" +mode = "execute" + +[actions.checkout] +description = "Checkout the selected commit" +command = "git checkout '{strip_ansi|split: :1}'" +mode = "execute" diff --git a/television/cable/git-reflog.toml b/television/cable/git-reflog.toml new file mode 100644 index 0000000..e16dff1 --- /dev/null +++ b/television/cable/git-reflog.toml @@ -0,0 +1,28 @@ +[metadata] +name = "git-reflog" +description = "A channel to select from git reflog entries" +requirements = ["git"] + +[source] +command = "git reflog --decorate --color=always" +output = "{0|strip_ansi}" +ansi = true +no_sort = true +frecency = false + +[preview] +command = "git show -p --stat --pretty=fuller --color=always '{0|strip_ansi}'" + +[keybindings] +ctrl-o = "actions:checkout" +ctrl-r = "actions:reset" + +[actions.checkout] +description = "Checkout the selected reflog entry" +command = "git checkout '{0|strip_ansi}'" +mode = "execute" + +[actions.reset] +description = "Reset --hard to the selected reflog entry" +command = "git reset --hard '{0|strip_ansi}'" +mode = "execute" diff --git a/television/cable/git-remotes.toml b/television/cable/git-remotes.toml new file mode 100644 index 0000000..08ce83e --- /dev/null +++ b/television/cable/git-remotes.toml @@ -0,0 +1,20 @@ +[metadata] +name = "git-remotes" +description = "List and manage git remotes" +requirements = ["git"] + +[source] +command = "git remote" + +[preview] +command = "git remote show '{}'" + +[actions.fetch] +description = "Fetch from the selected remote" +command = "git fetch {}" +mode = "execute" + +[actions.remove] +description = "Remove the selected remote" +command = "git remote remove {}" +mode = "execute" diff --git a/television/cable/git-repos.toml b/television/cable/git-repos.toml new file mode 100644 index 0000000..a67421a --- /dev/null +++ b/television/cable/git-repos.toml @@ -0,0 +1,31 @@ +[metadata] +name = "git-repos" +requirements = ["fd", "git"] +description = """ +A channel to select from git repositories on your local machine. + +This channel uses `fd` to find directories that contain a `.git` subdirectory, and then allows you to preview the git log of the selected repository. +""" + +[source] +# this is a macos version of the command. While perfectly usable on linux, you may want to tweak it a bit. +command = "fd -g .git -HL -t d -d 10 --prune ~ -E 'Library' -E 'Application Support' --exec dirname '{}'" +display = "{split:/:-1}" + +[preview] +command = "cd '{}'; git log -n 200 --pretty=medium --all --graph --color" + +[keybindings] +enter = "actions:cd" +ctrl-e = "actions:edit" + +[actions.cd] +description = "Open a new shell in the selected repository" +command = "cd {} && $SHELL" +mode = "execute" + +[actions.edit] +description = "Open the repository in editor" +command = "${EDITOR:-vim} {}" +shell = "bash" +mode = "execute" diff --git a/television/cable/git-stash.toml b/television/cable/git-stash.toml new file mode 100644 index 0000000..bcd6719 --- /dev/null +++ b/television/cable/git-stash.toml @@ -0,0 +1,37 @@ +[metadata] +name = "git-stash" +description = "Browse and manage git stash entries" +requirements = ["git"] + +[source] +command = "git stash list --color=always" +ansi = true +output = "{strip_ansi|split:\\::0}" +no_sort = true +frecency = false + +[preview] +command = "git stash show -p --color=always '{strip_ansi|split:\\::0}'" + +[ui] +layout = "portrait" + +[keybindings] +enter = "actions:apply" +ctrl-p = "actions:pop" +ctrl-d = "actions:drop" + +[actions.apply] +description = "Apply the selected stash" +command = "git stash apply '{strip_ansi|split:\\::0}'" +mode = "execute" + +[actions.pop] +description = "Pop the selected stash (apply and remove)" +command = "git stash pop '{strip_ansi|split:\\::0}'" +mode = "execute" + +[actions.drop] +description = "Drop the selected stash" +command = "git stash drop '{strip_ansi|split:\\::0}'" +mode = "execute" diff --git a/television/cable/git-submodules.toml b/television/cable/git-submodules.toml new file mode 100644 index 0000000..1680b71 --- /dev/null +++ b/television/cable/git-submodules.toml @@ -0,0 +1,20 @@ +[metadata] +name = "git-submodules" +description = "List and manage git submodules" +requirements = ["git"] + +[source] +command = "git submodule status | awk '{print $2}'" + +[preview] +command = "git -C '{}' log --oneline -10 --color=always" + +[actions.update] +description = "Update the selected submodule" +command = "git submodule update --init --recursive {}" +mode = "execute" + +[actions.sync] +description = "Sync the selected submodule URL" +command = "git submodule sync {}" +mode = "execute" diff --git a/television/cable/git-tags.toml b/television/cable/git-tags.toml new file mode 100644 index 0000000..8230fa3 --- /dev/null +++ b/television/cable/git-tags.toml @@ -0,0 +1,26 @@ +[metadata] +name = "git-tags" +description = "Browse and checkout git tags" +requirements = ["git"] + +[source] +command = "git tag --sort=-creatordate" +no_sort = true +frecency = false + +[preview] +command = "git show --color=always '{}'" + +[keybindings] +enter = "actions:checkout" +ctrl-d = "actions:delete" + +[actions.checkout] +description = "Checkout the selected tag" +command = "git checkout {}" +mode = "execute" + +[actions.delete] +description = "Delete the selected tag" +command = "git tag -d {}" +mode = "execute" diff --git a/television/cable/git-worktrees.toml b/television/cable/git-worktrees.toml new file mode 100644 index 0000000..4d8010c --- /dev/null +++ b/television/cable/git-worktrees.toml @@ -0,0 +1,24 @@ +[metadata] +name = "git-worktrees" +description = "List and switch between git worktrees" +requirements = ["git"] + +[source] +command = "git worktree list --porcelain | grep '^worktree' | cut -d' ' -f2-" + +[preview] +command = "cd '{}' && git log --oneline -10 --color=always && echo && git status --short" + +[keybindings] +enter = "actions:cd" +ctrl-d = "actions:remove" + +[actions.cd] +description = "Change to the selected worktree" +command = "cd {} && $SHELL" +mode = "execute" + +[actions.remove] +description = "Remove the selected worktree" +command = "git worktree remove {}" +mode = "execute" diff --git a/television/cable/images.toml b/television/cable/images.toml new file mode 100644 index 0000000..53d5b1c --- /dev/null +++ b/television/cable/images.toml @@ -0,0 +1,21 @@ +[metadata] +name = "images" +description = "Browse image files with preview" +requirements = ["fd", "chafa"] + +[source] +command = [ + { name = "Default", run = "fd -t f -e png -e jpg -e jpeg -e gif -e webp -e bmp -e svg ." }, + { name = "Hidden", run = "fd -t f -e png -e jpg -e jpeg -e gif -e webp -e bmp -e svg -H ." }, +] + +[preview] +command = "chafa -s 80x40 '{}' 2>/dev/null || file '{}'" + +[keybindings] +enter = "actions:open" + +[actions.open] +description = "Open the selected image with default viewer" +command = "xdg-open {} 2>/dev/null || open {}" +mode = "fork" diff --git a/television/cable/journal.toml b/television/cable/journal.toml new file mode 100644 index 0000000..5ef0ed8 --- /dev/null +++ b/television/cable/journal.toml @@ -0,0 +1,24 @@ +[metadata] +name = "journal" +description = "Browse systemd journal log identifiers and their logs" +requirements = ["journalctl"] + +[source] +command = "journalctl --field SYSLOG_IDENTIFIER 2>/dev/null | sort -f" + +[preview] +command = "journalctl -b --no-pager -o short-iso -n 50 SYSLOG_IDENTIFIER='{}' 2>/dev/null" + +[ui] +layout = "portrait" +preview_panel = { size = 70 } + +[actions.logs] +description = "Follow live logs for the selected identifier" +command = "journalctl -f SYSLOG_IDENTIFIER={}" +mode = "execute" + +[actions.full] +description = "View all logs for the selected identifier in a pager" +command = "journalctl -b --no-pager -o short-iso SYSLOG_IDENTIFIER={} | less" +mode = "fork" diff --git a/television/cable/just-recipes.toml b/television/cable/just-recipes.toml new file mode 100644 index 0000000..69b2fd2 --- /dev/null +++ b/television/cable/just-recipes.toml @@ -0,0 +1,18 @@ +[metadata] +name = "just-recipes" +description = "A channel to select recipes from Justfiles" +requirements = ["just"] + +[source] +command = ["just --summary | tr '[:blank:]' '\n'"] + +[preview] +command = "just -s {}" + +[keybindings] +f5 = "actions:execute-recipe" + +[actions.execute-recipe] +description = "Execute a justfile recipe" +command = "just {}" +mode = "execute" diff --git a/television/cable/make-targets.toml b/television/cable/make-targets.toml new file mode 100644 index 0000000..dbf78aa --- /dev/null +++ b/television/cable/make-targets.toml @@ -0,0 +1,18 @@ +[metadata] +name = "make-targets" +description = "List and run Makefile targets" +requirements = ["make", "awk"] + +[source] +command = "make -pRrq 2>/dev/null | awk -F: '/^[a-zA-Z0-9][^$#\\/\\t=]*:([^=]|$)/ {split($1,a,\" \"); print a[1]}' | sort -u | grep -v '^Makefile$'" + +[preview] +command = "awk '/^{}[[:space:]]*:/{found=1} found{print; if(/^[^\\t]/ && NR>1 && !/^{}[[:space:]]*:/) exit}' Makefile" + +[keybindings] +enter = "actions:run" + +[actions.run] +description = "Run the selected make target" +command = "make {}" +mode = "execute" diff --git a/television/cable/man-pages.toml b/television/cable/man-pages.toml new file mode 100644 index 0000000..ede3aba --- /dev/null +++ b/television/cable/man-pages.toml @@ -0,0 +1,25 @@ +[metadata] +name = "man-pages" +description = "Browse and preview system manual pages" +requirements = ["apropos", "man"] + +[source] +# List all man pages using apropos +command = "apropos ." + +[preview] +# Show the man page for the selected entry +command = "man '{0}'" +env = { "MANWIDTH" = "80" } + +[keybindings] +enter = "actions:open" + +[actions.open] +description = "Open the selected man page in the system pager" +command = "man '{0}'" +mode = "execute" + +[ui] +layout = "portrait" +preview_panel = { header = "{0}" } diff --git a/television/cable/mounts.toml b/television/cable/mounts.toml new file mode 100644 index 0000000..531aa70 --- /dev/null +++ b/television/cable/mounts.toml @@ -0,0 +1,19 @@ +[metadata] +name = "mounts" +description = "List mounted filesystems" +requirements = ["df", "awk"] + +[source] +command = "df -h --output=target,fstype,size,used,avail,pcent 2>/dev/null | tail -n +2" +display = "{split: :0}" + +[preview] +command = "df -h '{}' && echo && ls -la '{}' 2>/dev/null | head -20" + +[keybindings] +enter = "actions:cd" + +[actions.cd] +description = "Open a shell in the selected mount point" +command = "cd {} && $SHELL" +mode = "execute" diff --git a/television/cable/node-packages.toml b/television/cable/node-packages.toml new file mode 100644 index 0000000..89cee7a --- /dev/null +++ b/television/cable/node-packages.toml @@ -0,0 +1,21 @@ +[metadata] +name = "node-packages" +description = "Browse local node_modules dependencies" +requirements = ["node"] + +[source] +command = "ls -d node_modules/*/ 2>/dev/null | sed 's|node_modules/||;s|/$||' | grep -v '^\\.'" +output = "{}" + +[preview] +command = "cat 'node_modules/{}/package.json' 2>/dev/null | jq -C '{name, version, description, license, homepage, main}'" + +[actions.readme] +description = "View the package README" +command = "cat node_modules/{}/README.md 2>/dev/null | less" +mode = "execute" + +[actions.homepage] +description = "Open the package homepage" +command = "node -e \"const p=require('./node_modules/{}/package.json'); const u=p.homepage||'https://www.npmjs.com/package/'+p.name; require('child_process').exec('xdg-open '+u)\"" +mode = "fork" diff --git a/television/cable/npm-packages.toml b/television/cable/npm-packages.toml new file mode 100644 index 0000000..6d26a9e --- /dev/null +++ b/television/cable/npm-packages.toml @@ -0,0 +1,20 @@ +[metadata] +name = "npm-packages" +description = "List globally installed npm packages" +requirements = ["npm"] + +[source] +command = "npm list -g --depth=0 --parseable 2>/dev/null | tail -n +2 | xargs -I{} basename {}" + +[preview] +command = "npm info '{}' 2>/dev/null | head -30" + +[actions.uninstall] +description = "Uninstall the selected global package" +command = "npm uninstall -g {}" +mode = "execute" + +[actions.update] +description = "Update the selected global package" +command = "npm update -g {}" +mode = "execute" diff --git a/television/cable/npm-scripts.toml b/television/cable/npm-scripts.toml new file mode 100644 index 0000000..8c966c2 --- /dev/null +++ b/television/cable/npm-scripts.toml @@ -0,0 +1,22 @@ +[metadata] +name = "npm-scripts" +description = "List and run npm scripts from package.json" +requirements = ["jq"] + +[source] +command = "jq -r '.scripts | to_entries[] | \"\\(.key)\\t\\(.value)\"' package.json 2>/dev/null" +display = "{split:\\t:0}" + +[preview] +command = "jq -r '.scripts[\"{split:\\t:0}\"]' package.json" + +[ui.preview_panel] +size = 30 + +[keybindings] +enter = "actions:run" + +[actions.run] +description = "Run the selected npm script" +command = "npm run '{split:\\t:0}'" +mode = "execute" diff --git a/television/cable/nu-history.toml b/television/cable/nu-history.toml new file mode 100644 index 0000000..f6d9899 --- /dev/null +++ b/television/cable/nu-history.toml @@ -0,0 +1,9 @@ + +[metadata] +name = "nu-history" +description = "A channel to select from your nu history" + +[source] +command = "nu -c 'open $nu.history-path | lines | uniq | reverse | to text'" +no_sort = true +frecency = false diff --git a/television/cable/opencode-sessions.toml b/television/cable/opencode-sessions.toml new file mode 100644 index 0000000..d8324a4 --- /dev/null +++ b/television/cable/opencode-sessions.toml @@ -0,0 +1,36 @@ +[metadata] +name = "opencode-sessions" +description = "Browse and resume OpenCode sessions" +requirements = ["opencode", "jq"] + +[source] +# Use literal strings (''') to avoid escape sequence errors +command = '''opencode session list --format json | jq -r '.[] | "\(.id)\t\(.title)\t\(.directory)"' ''' +display = "{split:\t:1} ({split:\t:2})" +output = "{split:\t:0}" + +[preview] +# We use triple single quotes so we don't have to escape the backslashes for jq or the template engine +command = '''opencode session list --format json | jq -r '.[] | select(.id == "{split:\t:0}") | "TITLE: \(.title)\nID: \(.id)\nPROJECT: \(.projectId)\nDIRECTORY: \(.directory)\nUPDATED: \((.updated / 1000) | strftime("%Y-%m-%d %H:%M:%S"))"' ''' + +[ui] +layout = "landscape" +[ui.preview_panel] +size = 60 +header = "Session: {split:\t:1}" +border_type = "rounded" + +[keybindings] +shortcut = "f4" +enter = "actions:resume" +ctrl-d = "actions:delete" + +[actions.resume] +description = "Resume session" +command = "opencode -s {split:\t:0}" +mode = "execute" + +[actions.delete] +description = "Delete session" +command = '''bash -c 'echo "Delete {split:\t:1}?" && read -p "[y/N]: " conf && [[ $conf == "y" ]] && opencode session delete {split:\t:0} ' ''' +mode = "execute" diff --git a/television/cable/pacman-packages.toml b/television/cable/pacman-packages.toml new file mode 100644 index 0000000..c53a7e4 --- /dev/null +++ b/television/cable/pacman-packages.toml @@ -0,0 +1,21 @@ +[metadata] +name = "pacman-packages" +description = "List and manage installed pacman packages" +requirements = ["pacman"] + +[source] +command = "pacman -Q" +output = "{split: :0}" + +[preview] +command = "pacman -Qi '{split: :0}' 2>/dev/null" + +[actions.remove] +description = "Remove the selected package" +command = "sudo pacman -R '{split: :0}'" +mode = "execute" + +[actions.files] +description = "List files owned by the selected package" +command = "pacman -Ql '{split: :0}' | less" +mode = "execute" diff --git a/television/cable/path.toml b/television/cable/path.toml new file mode 100644 index 0000000..ec4bec2 --- /dev/null +++ b/television/cable/path.toml @@ -0,0 +1,15 @@ +[metadata] +name = "path" +description = "Investigate PATH contents" +requirements = ["fd", "bat"] + +[source] +command = "printf '%s\n' \"$PATH\" | tr ':' '\n'" + +[preview] +command = "fd -tx -d1 . \"{}\" -X printf \"%s\n\" \"{/}\" | sort -f | bat -n --color=always" + +[actions.cd] +description = "Open a shell in the selected PATH directory" +command = "cd {} && $SHELL" +mode = "execute" diff --git a/television/cable/pdf-files.toml b/television/cable/pdf-files.toml new file mode 100644 index 0000000..b41b01a --- /dev/null +++ b/television/cable/pdf-files.toml @@ -0,0 +1,24 @@ +[metadata] +name = "pdf-files" +description = "Browse PDF files" +requirements = ["fd", "pdftotext"] + +[source] +command = [ + { name = "Default", run = "fd -t f -e pdf ." }, + { name = "Hidden", run = "fd -t f -e pdf -H ." }, +] + +[preview] +command = "pdftotext -l 2 -layout '{}' - 2>/dev/null | head -100 || file '{}'" + +[ui] +layout = "portrait" + +[keybindings] +enter = "actions:open" + +[actions.open] +description = "Open the selected PDF with default viewer" +command = "xdg-open {} 2>/dev/null || open {}" +mode = "fork" diff --git a/television/cable/pip-packages.toml b/television/cable/pip-packages.toml new file mode 100644 index 0000000..8dd88b8 --- /dev/null +++ b/television/cable/pip-packages.toml @@ -0,0 +1,27 @@ +[metadata] +name = "pip-packages" +description = "List installed Python packages" +requirements = ["pip"] + +[source] +command = "pip list --format=freeze 2>/dev/null | cut -d= -f1" + +[preview] +command = "pip show '{}'" + +[ui] +layout = "portrait" + +[keybindings] +ctrl-u = "actions:upgrade" +ctrl-d = "actions:uninstall" + +[actions.upgrade] +description = "Upgrade the selected package" +command = "pip install --upgrade {}" +mode = "execute" + +[actions.uninstall] +description = "Uninstall the selected package" +command = "pip uninstall {}" +mode = "execute" diff --git a/television/cable/pj.toml b/television/cable/pj.toml new file mode 100644 index 0000000..754947e --- /dev/null +++ b/television/cable/pj.toml @@ -0,0 +1,32 @@ +[metadata] +name = "pj" +description = """ +Project tasks from every task source between the cwd and the git toplevel +(package.json, Makefile, justfile, mise, devbox, pyproject), tasks of the most +recently modified manifest first. Enter runs the task. Discovery, preview and +run live in ~/.local/bin/pj; `pj` (ctrl-p, and down on an empty prompt in fish, +zsh and bash) opens this cable with its own scan. +""" +requirements = ["pj", "mtime-sort"] + +# Record: display, kind, target, root, runner, manifest (tab separated). +[source] +command = "pj --list 2>/dev/null" +shell = "bash" +display = "{split:\\t:0}" + +[preview] +command = "pj --preview '{split:\\t:1}' '{split:\\t:2}' '{split:\\t:3}' '{split:\\t:5}'" +shell = "bash" + +[ui.preview_panel] +size = 40 + +[keybindings] +enter = "actions:run" + +[actions.run] +description = "Run the selected task" +command = "pj --run '{split:\\t:1}' '{split:\\t:2}' '{split:\\t:3}' '{split:\\t:4}'" +shell = "bash" +mode = "execute" diff --git a/television/cable/ports.toml b/television/cable/ports.toml new file mode 100644 index 0000000..9bd7333 --- /dev/null +++ b/television/cable/ports.toml @@ -0,0 +1,19 @@ +[metadata] +name = "ports" +description = "List listening ports and associated processes" +requirements = ["ss", "awk"] + +[source] +command = "ss -tlnp 2>/dev/null | tail -n +2 | awk '{gsub(/.*:/,\"\",$4); print $4, $1, $6}' | sed 's/users:((\"//; s/\".*//'" +display = "{split: :0} ({split: :2})" + +[preview] +command = "ss -tlnp 2>/dev/null | grep ':{split: :0} ' | head -20" + +[ui.preview_panel] +size = 40 + +[actions.kill] +description = "Kill the process listening on the selected port" +command = "fuser -k {split: :0}/tcp" +mode = "execute" diff --git a/television/cable/procs.toml b/television/cable/procs.toml new file mode 100644 index 0000000..de87ff7 --- /dev/null +++ b/television/cable/procs.toml @@ -0,0 +1,38 @@ +[metadata] +name = "procs" +description = "A channel to find and manage running processes" +requirements = ["ps", "awk"] + +[source] +command = "ps -e -o pid=,ucomm= | awk '{print $1, $2}'" +display = "{split: :1}" +output = "{split: :0}" + +[preview] +command = "ps -p '{split: :0}' -o user,pid,ppid,state,%cpu,%mem,command | fold" + +[keybindings] +ctrl-k = "actions:kill" +f2 = "actions:term" +ctrl-s = "actions:stop" +ctrl-c = "actions:cont" + +[actions.kill] +description = "Kill the selected process (SIGKILL)" +command = "kill -9 {split: :0}" +mode = "execute" + +[actions.term] +description = "Terminate the selected process (SIGTERM)" +command = "kill -15 {split: :0}" +mode = "execute" + +[actions.stop] +description = "Stop/pause the selected process (SIGSTOP)" +command = "kill -STOP {split: :0}" +mode = "fork" + +[actions.cont] +description = "Continue/resume the selected process (SIGCONT)" +command = "kill -CONT {split: :0}" +mode = "fork" diff --git a/television/cable/python-venvs.toml b/television/cable/python-venvs.toml new file mode 100644 index 0000000..e1bc12b --- /dev/null +++ b/television/cable/python-venvs.toml @@ -0,0 +1,20 @@ +[metadata] +name = "python-venvs" +description = "Find Python virtual environments" +requirements = ["find"] + +[source] +command = "find ~ -maxdepth 5 -type f -name 'pyvenv.cfg' 2>/dev/null | xargs -I{} dirname {}" + +[preview] +command = "cat '{}/pyvenv.cfg' 2>/dev/null && echo '' && echo 'Packages:' && '{}/bin/pip' list --format=columns 2>/dev/null | head -20" + +[actions.activate] +description = "Open a shell with the selected venv activated" +command = "source '{}/bin/activate' && $SHELL" +mode = "execute" + +[actions.packages] +description = "List all packages in the selected venv" +command = "'{}/bin/pip' list | less" +mode = "execute" diff --git a/television/cable/recent-files.toml b/television/cable/recent-files.toml new file mode 100644 index 0000000..e044bf7 --- /dev/null +++ b/television/cable/recent-files.toml @@ -0,0 +1,23 @@ +[metadata] +name = "recent-files" +description = "List recently modified files (via git or filesystem)" +requirements = ["git", "bat"] + +[source] +command = [ + { name = "Recent", run = "git diff --name-only HEAD~10 HEAD 2>/dev/null || find . -type f -mtime -7 -not -path '*/.*' 2>/dev/null | head -100" }, + { name = "Last hour", run = "find . -type f -mmin -60 -not -path '*/.*' 2>/dev/null | head -100" }, +] + +[preview] +command = "bat -n --color=always '{}'" +env = { BAT_THEME = "ansi" } + +[keybindings] +enter = "actions:edit" + +[actions.edit] +description = "Open the selected file in editor" +command = "${EDITOR:-vim} {}" +shell = "bash" +mode = "execute" diff --git a/television/cable/rustup.toml b/television/cable/rustup.toml new file mode 100644 index 0000000..11bb7cd --- /dev/null +++ b/television/cable/rustup.toml @@ -0,0 +1,20 @@ +[metadata] +name = "rustup" +description = "Manage Rust toolchains" +requirements = ["rustup"] + +[source] +command = "rustup toolchain list" + +[preview] +command = "rustup run '{split: :0}' rustc --version --verbose 2>/dev/null" + +[actions.default] +description = "Set the selected toolchain as default" +command = "rustup default '{split: :0}'" +mode = "execute" + +[actions.uninstall] +description = "Uninstall the selected toolchain" +command = "rustup toolchain uninstall '{split: :0}'" +mode = "execute" diff --git a/television/cable/ssh-hosts.toml b/television/cable/ssh-hosts.toml new file mode 100644 index 0000000..9604571 --- /dev/null +++ b/television/cable/ssh-hosts.toml @@ -0,0 +1,18 @@ +[metadata] +name = "ssh-hosts" +description = "A channel to select hosts from your SSH config" +requirements = ["grep", "tr", "cut", "awk"] + +[source] +command = "grep -E '^Host(name)? ' $HOME/.ssh/config | tr -s ' ' | cut -d' ' -f2- | tr ' ' '\n' | grep -v '^$'" + +[preview] +command = "awk '/^Host / { found=0 } /^Host (.*[[:space:]])?'{}'([[:space:]].*)?$/ { found=1 } found' $HOME/.ssh/config" + +[keybindings] +enter = "actions:connect" + +[actions.connect] +description = "SSH into the selected host" +command = "ssh {}" +mode = "execute" diff --git a/television/cable/systemd-units.toml b/television/cable/systemd-units.toml new file mode 100644 index 0000000..fe8c6c2 --- /dev/null +++ b/television/cable/systemd-units.toml @@ -0,0 +1,49 @@ +[metadata] +name = "systemd-units" +description = "List and manage systemd services" +requirements = ["systemctl"] + +[source] +command = [ + { name = "Active", run = "systemctl list-units --type=service --no-pager --no-legend --plain" }, + { name = "All", run = "systemctl list-units --type=service --all --no-pager --no-legend --plain" }, +] +display = "{split: :0}" + +[preview] +command = "systemctl status '{split: :0}' --no-pager" + +[ui] +layout = "portrait" + +[keybindings] +ctrl-s = "actions:start" +f2 = "actions:stop" +ctrl-r = "actions:restart" +ctrl-e = "actions:enable" +ctrl-d = "actions:disable" + +[actions.start] +description = "Start the selected service" +command = "sudo systemctl start '{split: :0}'" +mode = "execute" + +[actions.stop] +description = "Stop the selected service" +command = "sudo systemctl stop '{split: :0}'" +mode = "execute" + +[actions.restart] +description = "Restart the selected service" +command = "sudo systemctl restart '{split: :0}'" +mode = "execute" + +[actions.enable] +description = "Enable the selected service" +command = "sudo systemctl enable '{split: :0}'" +mode = "execute" + +[actions.disable] +description = "Disable the selected service" +command = "sudo systemctl disable '{split: :0}'" +mode = "execute" diff --git a/television/cable/tailscale-exit-node.toml b/television/cable/tailscale-exit-node.toml new file mode 100644 index 0000000..099b8ac --- /dev/null +++ b/television/cable/tailscale-exit-node.toml @@ -0,0 +1,18 @@ +[metadata] +name = "tailscale-exit-node" +description = "A channel to select a tailscale exit node" +requirements = ["tailscale", "awk"] + +[source] +command = "tailscale exit-node list | awk '/^[[:space:]]*[0-9]+\\./ {gsub(/^[[:space:]]+/, \"\"); print $1}'" + +[preview] +command = "tailscale whois {}" + +[keybindings] +enter = "actions:connect" + +[actions.connect] +description = "Set selected host as exit node" +command = "tailscale set --exit-node={}" +mode = "execute" diff --git a/television/cable/tea-issues.toml b/television/cable/tea-issues.toml new file mode 100644 index 0000000..5918de4 --- /dev/null +++ b/television/cable/tea-issues.toml @@ -0,0 +1,36 @@ +[metadata] +name = "tea-issues" +description = "List Gitea issues for the current repo" +requirements = ["tea", "jq"] + +[source] +command = '''tea issues list --output json --state open 0 then "\u001b[36mLabels:\u001b[39m " + ([.labels[] | "\u001b[35m" + .name + "\u001b[39m"] +| join(" ")) else empty end), +"", +"\u001b[90m────────────────────────────────────────────────────────────\u001b[39m", +"", +(.body // "") +' +''' + +[actions.close] +description = "Close the selected issue" +command = "tea issues close {strip_ansi|split:#:1|split:\t:0}" +mode = "fork" diff --git a/television/cable/tea-prs.toml b/television/cable/tea-prs.toml new file mode 100644 index 0000000..23b837e --- /dev/null +++ b/television/cable/tea-prs.toml @@ -0,0 +1,42 @@ +[metadata] +name = "tea-prs" +description = "List Gitea PRs for the current repo" +requirements = ["tea", "jq"] + +[source] +command = '''tea pulls list --output json --state open 0 then "\u001b[36mLabels:\u001b[39m " + ([.labels[] | "\u001b[35m" + .name + "\u001b[39m"] | join(" ")) else empty end), +"\u001b[36mMergeable:\u001b[39m " + (if .mergeable then "\u001b[32m✓ Clean\u001b[39m" else "\u001b[31m✗ Dirty\u001b[39m" end), +"", +"\u001b[90m────────────────────────────────────────────────────────────\u001b[39m", +"", +(.body // "") +' +''' + +[actions.checkout] +description = "Checkout the PR branch locally" +command = "tea pulls checkout {strip_ansi|split:#:1|split:\t:0}" +mode = "execute" + +[actions.merge] +description = "Merge the selected PR" +command = "tea pulls merge {strip_ansi|split:#:1|split:\t:0}" +mode = "execute" diff --git a/television/cable/text.toml b/television/cable/text.toml new file mode 100644 index 0000000..6be730d --- /dev/null +++ b/television/cable/text.toml @@ -0,0 +1,29 @@ +[metadata] +name = "text" +description = "A channel to find and select text from files" +requirements = ["rg", "bat"] + +[source] +command = [ + { name = "Default", run = "rg . --no-heading --line-number --colors 'match:fg:white' --colors 'path:fg:blue' --color=always" }, + { name = "Hidden", run = "rg . --no-heading --line-number --hidden --colors 'match:fg:white' --colors 'path:fg:blue' --color=always" }, +] +ansi = true +output = "{strip_ansi|split:\\::..2}" + +[preview] +command = "bat -n --color=always '{strip_ansi|split:\\::0}'" +env = { BAT_THEME = "ansi" } +offset = '{strip_ansi|split:\::1}' + +[ui] +preview_panel = { header = '{strip_ansi|split:\::..2}' } + +[keybindings] +enter = "actions:edit" + +[actions.edit] +description = "Open file in editor at line" +command = "${EDITOR:-vim} '+{strip_ansi|split:\\::1}' '{strip_ansi|split:\\::0}'" +shell = "bash" +mode = "execute" diff --git a/television/cable/tldr.toml b/television/cable/tldr.toml new file mode 100644 index 0000000..884b453 --- /dev/null +++ b/television/cable/tldr.toml @@ -0,0 +1,21 @@ +[metadata] +name = "tldr" +description = "Browse and preview TLDR help pages for command-line tools" +requirements = ["tldr"] + +[source] +command = "tldr --list" + +[preview] +command = "tldr '{0}' --color always" + +[ui] +layout = "portrait" + +[keybindings] +ctrl-e = "actions:open" + +[actions.open] +description = "Open the selected TLDR page" +command = "tldr '{0}'" +mode = "execute" diff --git a/television/cable/tmux-sessions.toml b/television/cable/tmux-sessions.toml new file mode 100644 index 0000000..6e77d24 --- /dev/null +++ b/television/cable/tmux-sessions.toml @@ -0,0 +1,22 @@ +[metadata] +name = "tmux-sessions" +description = "List and manage tmux sessions" +requirements = ["tmux"] + +[source] +command = "tmux list-sessions -F '#{session_name}\t#{session_windows} windows\t#{session_created_string}'" +display = "{split:\t:0} ({split:\t:1})" +output = "{split:\t:0}" + +[preview] +command = "tmux capture-pane -t '{split:\t:0}' -p 2>/dev/null || echo 'No preview available'" + +[actions.attach] +description = "Attach to the selected session" +command = "tmux attach-session -t '{split:\t:0}'" +mode = "execute" + +[actions.kill] +description = "Kill the selected session" +command = "tmux kill-session -t '{split:\t:0}'" +mode = "fork" diff --git a/television/cable/tmux-windows.toml b/television/cable/tmux-windows.toml new file mode 100644 index 0000000..557e259 --- /dev/null +++ b/television/cable/tmux-windows.toml @@ -0,0 +1,22 @@ +[metadata] +name = "tmux-windows" +description = "List and switch between tmux windows" +requirements = ["tmux"] + +[source] +command = "tmux list-windows -a -F '#{session_name}:#{window_index}\t#{window_name}\t#{pane_current_command}'" +display = "{split:\t:0} - {split:\t:1} ({split:\t:2})" +output = "{split:\t:0}" + +[preview] +command = "tmux capture-pane -t '{split:\t:0}' -p 2>/dev/null || echo 'No preview available'" + +[actions.select] +description = "Switch to the selected window" +command = "tmux select-window -t '{split:\t:0}'" +mode = "execute" + +[actions.kill] +description = "Kill the selected window" +command = "tmux kill-window -t '{split:\t:0}'" +mode = "fork" diff --git a/television/cable/todo-comments.toml b/television/cable/todo-comments.toml new file mode 100644 index 0000000..ceda02c --- /dev/null +++ b/television/cable/todo-comments.toml @@ -0,0 +1,26 @@ +[metadata] +name = "todo-comments" +description = "Find TODO, FIXME, HACK, and XXX comments in codebase" +requirements = ["rg", "bat"] + +[source] +command = "rg -n --color=always '(TODO|FIXME|HACK|XXX|BUG|WARN):?'" +ansi = true +output = "{strip_ansi|split:\\::..2}" + +[preview] +command = "bat -n --color=always --highlight-line '{strip_ansi|split:\\::1}' '{strip_ansi|split:\\::0}'" +env = { BAT_THEME = "ansi" } +offset = "{strip_ansi|split:\\::1}" + +[ui] +preview_panel = { header = "{strip_ansi|split:\\::..2}" } + +[keybindings] +enter = "actions:edit" + +[actions.edit] +description = "Open file in editor at the comment" +command = "${EDITOR:-vim} '+{strip_ansi|split:\\::1}' '{strip_ansi|split:\\::0}'" +shell = "bash" +mode = "execute" diff --git a/television/cable/unicode.toml b/television/cable/unicode.toml new file mode 100644 index 0000000..c96a6cf --- /dev/null +++ b/television/cable/unicode.toml @@ -0,0 +1,43 @@ +[metadata] +name = "unicode" +description = '''Search and insert unicode characters + +The UnicodeData.txt file is included by many packages. + +In addition to: + +Alpine Linux: unicode-character-database +Arch: unicode-character-database +Debian/Ubuntu: unicode-data +Fedora / RHEL / CentOS unicode-ucd +Gentoo: app-i18n/unicode-data +NixOS: unicode/unicode-data +openSUSE: unicode-ucd + +UnicodData.txt may also aleady be provided by: + +1) Many java packages +2) Latex packages +3) Still others + +It may in some cases be necessary to alter UNICODE_FILE below. + +''' +requirements = ["awk", "perl"] + +[source] +command = ''' +UNICODE_FILE="/usr/share/unicode/ucd/UnicodeData.txt" +awk -F';' ' + $2 !~ /^/dev/null | grep -v '^:' | sort -t: -k2 -rn" +display = "{split:\\::0} ({split:\\::1}% {split:\\::2})" +output = "{split:\\::0}" + +[preview] +command = "nmcli -t -f SSID,BSSID,MODE,FREQ,SIGNAL,SECURITY,ACTIVE device wifi list 2>/dev/null | grep '^{split:\\::0}:'" + +[actions.connect] +description = "Connect to the selected network" +command = "nmcli device wifi connect '{split:\\::0}'" +mode = "execute" diff --git a/television/cable/zoxide.toml b/television/cable/zoxide.toml new file mode 100644 index 0000000..aa69084 --- /dev/null +++ b/television/cable/zoxide.toml @@ -0,0 +1,26 @@ +[metadata] +name = "zoxide" +description = "Browse zoxide directory history" +requirements = ["zoxide"] + +[source] +command = "zoxide query -l" +no_sort = true +frecency = false + +[preview] +command = "ls -la --color=always '{}'" + +[keybindings] +enter = "actions:cd" +ctrl-d = "actions:remove" + +[actions.cd] +description = "Change to the selected directory" +command = "cd {} && $SHELL" +mode = "execute" + +[actions.remove] +description = "Remove the selected directory from zoxide" +command = "zoxide remove {}" +mode = "fork" diff --git a/television/cable/zsh-history.toml b/television/cable/zsh-history.toml new file mode 100644 index 0000000..6bc8f90 --- /dev/null +++ b/television/cable/zsh-history.toml @@ -0,0 +1,16 @@ +[metadata] +name = "zsh-history" +description = "A channel to select from your zsh history" +requirements = ["zsh"] + +[source] +command = "sed '1!G;h;$!d' ${HISTFILE:-${HOME}/.zsh_history}" +display = "{split:;:1..}" +output = "{split:;:1..}" +no_sort = true +frecency = false + +[actions.execute] +description = "Execute the selected command" +command = "zsh -c '{split:;:1..}'" +mode = "execute" diff --git a/television/config.toml b/television/config.toml new file mode 100644 index 0000000..d9d9c42 --- /dev/null +++ b/television/config.toml @@ -0,0 +1,255 @@ +# CONFIGURATION FILE LOCATION ON YOUR SYSTEM: +# ------------------------------------------- +# Defaults: +# --------- +# Linux: `$HOME/.config/television/config.toml` +# macOS: `$HOME/.config/television/config.toml` +# Windows: `%LocalAppData%\television\config\config.toml` +# +# XDG dirs: +# --------- +# You may use XDG_CONFIG_HOME if set on your system. +# In that case, television will expect the configuration file to be in: +# `$XDG_CONFIG_HOME/television/config.toml` +# + +# General settings +# ---------------------------------------------------------------------------- +tick_rate = 50 +default_channel = "files" +# Shell settings +# -------------- +# Default shell used for executing commands (source, preview, actions). +# Options: bash, zsh, fish, powershell, cmd, nu +# If not specified, the shell is detected from the environment ($SHELL on Unix). +# Channel-specific shell settings override this global setting. +# shell = "bash" +# History settings +# --------------- +# Maximum number of entries to keep in the global history (default: 100) +# The history tracks search queries across all channels and sessions +# Set to 0 to disable history functionality entirely +history_size = 200 +# Whether to use global history (default: false) +# When true: history navigation shows entries from all channels +# When false: history navigation is scoped to the current channel +global_history = false + +[ui] +# How much space to allocate for the UI (in percentage of the screen) +# ┌─────────────────────────┐ +# │ Terminal screen │ +# │ ┌───────────────────┐ │ +# │ │ │ │ +# │ │ Television UI │ │ +# │ │ │ │ +# │ └───────────────────┘ │ +# │ │ +# └─────────────────────────┘ +ui_scale = 100 +# What orientation should tv be (landscape or portrait) +orientation = "landscape" +# The theme to use for the UI: themes/cyberdream-transparent.toml in this +# config dir (a builtin theme shadows a user theme of the same name). +theme = "cyberdream-transparent" + +# Feature-specific configurations +# Each feature can have its own configuration section +[ui.input_bar] +# Where to place the input bar in the UI (top or bottom) +position = "top" +# The input prompt string (defaults to ">" if not specified) +prompt = ">" +# header = "{}" +# padding = {"left": 0, "right": 0, "top": 0, "bottom": 0} +border_type = "rounded" # https://docs.rs/ratatui/latest/ratatui/widgets/block/enum.BorderType.html#variants + +[ui.status_bar] +# Status bar separators (bubble): +#separator_open = "" +#separator_close = "" +# Status bar separators (box): +separator_open = "" +separator_close = "" +hidden = false + +[ui.results_panel] +border_type = "rounded" +# padding = {"left": 0, "right": 0, "top": 0, "bottom": 0} + +[ui.preview_panel] +# Preview panel size (percentage of screen width/height) +size = 50 +#header = "" +#footer = "" +scrollbar = true +border_type = "rounded" +# padding = {"left": 0, "right": 0, "top": 0, "bottom": 0} +hidden = false + +[ui.help_panel] +# Whether to split the help panel by categories +show_categories = true +hidden = true + +[ui.remote_control] +# Whether to show channel descriptions in remote control mode +show_channel_descriptions = true +# Whether to sort channels alphabetically +sort_alphabetically = true +# disabled = false + +# Theme color overrides +# --------------------- +# You can override specific colors from the selected theme by adding them here. +# This allows you to customize the appearance without creating a full theme file. +# Colors can be specified as ANSI color names (e.g., "red", "bright-blue") or +# as hex values (e.g., "#ff0000", "#1e1e2e"). +# +# Example overrides: +# [ui.theme_overrides] +# background = "#000000" +# text_fg = "#ffffff" +# selection_bg = "#444444" +# match_fg = "#ff0000" + +# Keybindings and Events +# ---------------------------------------------------------------------------- +# +[keybindings] +# Application control +# ------------------ +esc = "quit" +ctrl-c = "quit" + +# Navigation and selection +# ----------------------- +down = "select_next_entry" +ctrl-n = "select_next_entry" +ctrl-j = "select_next_entry" +up = "select_prev_entry" +ctrl-p = "select_prev_entry" +ctrl-k = "select_prev_entry" + +# History navigation +# ----------------- +ctrl-up = "select_prev_history" +ctrl-down = "select_next_history" + +# Multi-selection +# -------------- +tab = "toggle_selection_down" +backtab = "toggle_selection_up" +enter = "confirm_selection" + +# Preview panel control +# -------------------- +pagedown = "scroll_preview_half_page_down" +pageup = "scroll_preview_half_page_up" +ctrl-f = "cycle_previews" + +# Data operations +# -------------- +ctrl-y = "copy_entry_to_clipboard" +ctrl-r = "reload_source" +ctrl-s = "cycle_sources" + +# UI Features +# ---------- +ctrl-t = "toggle_remote_control" +ctrl-x = "toggle_action_picker" +ctrl-o = "toggle_preview" +# ctrl-h/ctrl-e run the current channel's actions (files: goto_parent_dir, +# edit in nvim — see cable/files.toml); `end` still jumps to input end. +ctrl-h = "actions:goto_parent_dir" +f12 = "toggle_status_bar" +ctrl-l = "toggle_layout" + +# Input field actions +# ---------------------------------------- +backspace = "delete_prev_char" +ctrl-w = "delete_prev_word" +ctrl-u = "delete_line" +delete = "delete_next_char" +left = "go_to_prev_char" +right = "go_to_next_char" +home = "go_to_input_start" +ctrl-a = "go_to_input_start" +end = "go_to_input_end" +ctrl-e = "actions:edit" + +# Shell integration +# ---------------------------------------------------------------------------- +# +# The shell integration feature allows you to use television as a picker for +# your shell commands (as well as your shell history with ). +# E.g. typing `git checkout ` will open television with a list of +# branches to choose from. + +[shell_integration] +# This specifies the default fallback channel if no other channel is matched. +fallback_channel = "files" + +[shell_integration.channel_triggers] +# Add your channel triggers here. Each key is a channel that will be triggered +# by the corresponding commands. +# Example: say you want the following commands to trigger the following channels +# when pressing : +# `git checkout` should trigger the `git-branches` channel +# `ls` should trigger the `dirs` channel +# `cat` and `cp` should trigger the `files` channel +# +# You would add the following to your configuration file: +# ``` +# [shell_integration.channel_triggers] +# "git-branches" = ["git checkout"] +# "dirs" = ["ls"] +# "files" = ["cat", "cp"] +# ``` +"alias" = ["alias", "unalias"] +"env" = ["export", "unset"] +"dirs" = ["cd", "ls", "rmdir", "z"] +"files" = [ + "cat", + "less", + "head", + "tail", + "vim", + "nano", + "bat", + "cp", + "mv", + "rm", + "touch", + "chmod", + "chown", + "ln", + "tar", + "zip", + "unzip", + "gzip", + "gunzip", + "xz", +] +"git-diff" = ["git add", "git restore"] +"git-branch" = [ + "git checkout", + "git switch", + "git branch", + "git merge", + "git rebase", + "git pull", + "git push", +] +"git-log" = ["git log", "git show"] +"docker-images" = ["docker run"] +"git-repos" = ["nvim", "code", "hx", "git clone"] + + +[shell_integration.keybindings] +# controls which key binding should trigger tv +# for shell autocomplete +"smart_autocomplete" = "ctrl-t" +# controls which keybinding should trigger tv +# for command history +"command_history" = "ctrl-r" diff --git a/television/themes/cyberdream-transparent.toml b/television/themes/cyberdream-transparent.toml new file mode 100644 index 0000000..ef61c8d --- /dev/null +++ b/television/themes/cyberdream-transparent.toml @@ -0,0 +1,29 @@ +# cyberdream-transparent — https://github.com/scottmckendry/cyberdream.nvim +# Same palette as the kitty, fish, atuin, bat and yazi cyberdream themes. +# Differs from tv's builtin `cyberdream` (which shadows a user theme of that +# name): no `background`, so tv draws on kitty's own translucent #16181a +# (tv 0.15 rejects `background = 'none'` and falls back to the default theme). + +# general +border_fg = '#3c4048' +text_fg = '#ffffff' +dimmed_text_fg = '#7b8496' +# input +input_text_fg = '#ffffff' +result_count_fg = '#ffbd5e' +# results +result_name_fg = '#5ea1ff' +result_line_number_fg = '#f1ff5e' +result_value_fg = '#ffffff' +selection_fg = '#5eff6c' +selection_bg = '#3c4048' +match_fg = '#5ef1ff' +# preview +preview_title_fg = '#ffaecf' +# modes +channel_mode_fg = '#16181a' +channel_mode_bg = '#5ef1ff' +remote_control_mode_fg = '#16181a' +remote_control_mode_bg = '#5eff6c' +action_picker_mode_fg = '#16181a' +action_picker_mode_bg = '#bd5eff'