Finished hacker theme mostly and added some other configs

This commit is contained in:
ManOfGoldForever 2026-04-03 10:57:53 -04:00
parent 0c499ecbd6
commit ad06f5284e
91 changed files with 1928 additions and 3 deletions

View file

@ -0,0 +1,14 @@
# This file was created by fish when upgrading to version 4.3, to migrate
# the 'fish_key_bindings' variable from its old default scope (universal)
# to its new default scope (global). We recommend you delete this file
# and configure key bindings in ~/.config/fish/config.fish if needed.
# set --global fish_key_bindings fish_default_key_bindings
# Prior to version 4.3, fish shipped an event handler that runs
# `set --universal fish_key_bindings fish_default_key_bindings`
# whenever the fish_key_bindings variable is erased.
# This means that as long as any fish < 4.3 is still running on this system,
# we cannot complete the migration.
# As a workaround, erase the universal variable at every shell startup.
set --erase --universal fish_key_bindings

View file

@ -0,0 +1 @@
source "$HOME/.cargo/env.fish"

View file

@ -0,0 +1,34 @@
source /usr/share/cachyos-fish-config/cachyos-config.fish
fish_config theme choose "Dracula Official"
oh-my-posh init fish --config ~/.cache/oh-my-posh/themes/dracula.omp.json | source
alias mntnas="sudo mount -a"
# Set Zed as the default editor
set -gx EDITOR /usr/local/bin/zed_sudo_wrapper
set -gx VISUAL "zeditor --wait"
set -gx SUDO_EDITOR "zeditor --wait"
# Start SSH agent if not already running
if not set -q SSH_AGENT_PID
eval (ssh-agent -c)
end
function update
sudo pacman -Syu --noconfirm
paru -Syu --noconfirm
sudo pacman -Sc --noconfirm
paru -Sc --noconfirm
end
function helium
exec /usr/bin/helium-0.6.9.1-x86_64.AppImage
end
function add_ssh_key
set -l ssh_key ~/.ssh/github-ssh
echo "Adding SSH key..."
ssh-add $ssh_key
end

View file

@ -0,0 +1,81 @@
# This file contains fish universal variable definitions.
# VERSION: 3.0
SETUVAR --export BAT_THEME:Dracula
SETUVAR --export YAZI_FILE_ONE:/usr/bin/file
SETUVAR __done_min_cmd_duration:10000
SETUVAR __done_notification_urgency_level:low
SETUVAR __fish_initialized:4300
SETUVAR fish_greeting:\x1d
SETUVAR --export fish_user_paths:/home/henry/\x2enpm\x2dglobal/bin
SETUVAR pure_begin_prompt_with_current_directory:true
SETUVAR pure_check_for_new_release:false
SETUVAR pure_color_at_sign:pure_color_mute
SETUVAR pure_color_aws_profile:pure_color_warning
SETUVAR pure_color_command_duration:pure_color_warning
SETUVAR pure_color_current_directory:pure_color_primary
SETUVAR pure_color_danger:red
SETUVAR pure_color_dark:black
SETUVAR pure_color_exit_status:pure_color_danger
SETUVAR pure_color_git_branch:pure_color_mute
SETUVAR pure_color_git_dirty:pure_color_mute
SETUVAR pure_color_git_stash:pure_color_info
SETUVAR pure_color_git_unpulled_commits:pure_color_info
SETUVAR pure_color_git_unpushed_commits:pure_color_info
SETUVAR pure_color_hostname:pure_color_mute
SETUVAR pure_color_info:cyan
SETUVAR pure_color_jobs:pure_color_normal
SETUVAR pure_color_k8s_context:pure_color_success
SETUVAR pure_color_k8s_namespace:pure_color_primary
SETUVAR pure_color_k8s_prefix:pure_color_info
SETUVAR pure_color_light:white
SETUVAR pure_color_mute:brblack
SETUVAR pure_color_nixdevshell_prefix:pure_color_info
SETUVAR pure_color_nixdevshell_symbol:pure_color_mute
SETUVAR pure_color_normal:normal
SETUVAR pure_color_prefix_root_prompt:pure_color_danger
SETUVAR pure_color_primary:blue
SETUVAR pure_color_prompt_on_error:pure_color_danger
SETUVAR pure_color_prompt_on_success:pure_color_success
SETUVAR pure_color_success:magenta
SETUVAR pure_color_system_time:pure_color_mute
SETUVAR pure_color_username_normal:pure_color_mute
SETUVAR pure_color_username_root:pure_color_light
SETUVAR pure_color_virtualenv:pure_color_mute
SETUVAR pure_color_warning:yellow
SETUVAR pure_convert_exit_status_to_signal:false
SETUVAR pure_enable_aws_profile:true
SETUVAR pure_enable_container_detection:true
SETUVAR pure_enable_git:true
SETUVAR pure_enable_k8s:false
SETUVAR pure_enable_nixdevshell:false
SETUVAR pure_enable_single_line_prompt:false
SETUVAR pure_enable_virtualenv:true
SETUVAR pure_reverse_prompt_symbol_in_vimode:true
SETUVAR pure_separate_prompt_on_error:false
SETUVAR pure_shorten_prompt_current_directory_length:0
SETUVAR pure_shorten_window_title_current_directory_length:0
SETUVAR pure_show_exit_status:false
SETUVAR pure_show_jobs:false
SETUVAR pure_show_numbered_git_indicator:false
SETUVAR pure_show_prefix_root_prompt:false
SETUVAR pure_show_subsecond_command_duration:false
SETUVAR pure_show_system_time:false
SETUVAR pure_symbol_aws_profile_prefix:
SETUVAR pure_symbol_container_prefix:
SETUVAR pure_symbol_exit_status_prefix:\x7c
SETUVAR pure_symbol_exit_status_separator:\x7c
SETUVAR pure_symbol_git_dirty:\x2a
SETUVAR pure_symbol_git_stash:\u2261
SETUVAR pure_symbol_git_unpulled_commits:\u21e3
SETUVAR pure_symbol_git_unpushed_commits:\u21e1
SETUVAR pure_symbol_k8s_prefix:\u2638
SETUVAR pure_symbol_nixdevshell_prefix:\u2744\ufe0f
SETUVAR pure_symbol_prefix_root_prompt:\x23
SETUVAR pure_symbol_prompt:\u276f
SETUVAR pure_symbol_reverse_prompt:\u276e
SETUVAR pure_symbol_ssh_prefix:
SETUVAR pure_symbol_title_bar_separator:\x2d
SETUVAR pure_symbol_virtualenv_prefix:
SETUVAR pure_threshold_command_duration:5
SETUVAR pure_truncate_prompt_current_directory_keeps:\x2d1
SETUVAR pure_truncate_window_title_current_directory_keeps:\x2d1

View file

@ -0,0 +1,13 @@
function awww_set_wallpaper
set wallpaper $argv[1]
# Start swww daemon if not running
if not pgrep awww-daemon > /dev/null
awww-daemon &
sleep 1
end
# Set wallpaper with animation
awww img "$wallpaper" \
--transition-type wipe
end

View file

@ -0,0 +1,8 @@
function yazi-cd
set tmpfile (mktemp)
yazi --cwd-file="$tmpfile"
if test -s "$tmpfile"
cd (cat "$tmpfile")
end
rm -f "$tmpfile"
end

View file

@ -0,0 +1,2 @@
file:///mnt/games games
file:///mnt/data data

View file

@ -0,0 +1,10 @@
# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
# ┃ Enviroment Configuration ┃
# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
envd = HYPRCURSOR_THEME, Dracula
envd = HYPRCURSOR_SIZE,24
envd = XCURSOR_THEME, Dracula
envd = XCURSOR_SIZE,24
envd = QT_CURSOR_THEME, Dracula
envd = QT_CURSOR_SIZE,24

View file

@ -0,0 +1,21 @@
#!/usr/bin/env sh
HYPRGAMEMODE=$(hyprctl getoption animations:enabled | awk 'NR==1{print $2}')
if [ "$HYPRGAMEMODE" = 1 ] ; then
hyprctl --batch "\
keyword animations:enabled 0;\
keyword animation borderangle,0; \
keyword decoration:shadow:enabled 0;\
keyword decoration:blur:enabled 0;\
keyword decoration:fullscreen_opacity 1;\
keyword general:gaps_in 0;\
keyword general:gaps_out 0;\
keyword general:border_size 1;\
keyword decoration:rounding 0"
hyprctl notify 1 5000 "rgb(40a02b)" "Gamemode [ON]"
exit
else
hyprctl notify 1 5000 "rgb(d20f39)" "Gamemode [OFF]"
hyprctl reload
exit 0
fi
exit 1

View file

@ -0,0 +1,94 @@
{
"name": "Laptop",
"created_at": "2026-04-01T04:29:51.207188499Z",
"updated_at": "2026-04-01T04:31:06.822573866Z",
"outputs": [
{
"key": "boe|0x0a6d",
"name": "eDP-2",
"make": "BOE",
"model": "0x0A6D",
"enabled": true,
"mode": "1920x1200@165.00Hz",
"width": 1920,
"height": 1200,
"refresh": 165,
"x": -1,
"y": -1,
"scale": 1,
"transform": 0
},
{
"key": "dell inc.|dell s2721dgf|h13jy83",
"name": "DP-1",
"make": "Dell Inc.",
"model": "DELL S2721DGF",
"serial": "H13JY83",
"enabled": false,
"mode": "2560x1440@59.95Hz",
"width": 2560,
"height": 1440,
"refresh": 59.95,
"x": 1920,
"y": 0,
"scale": 1,
"transform": 1
},
{
"key": "samsung electric company|odyssey g40b|hcjxa14774",
"name": "HDMI-A-1",
"make": "Samsung Electric Company",
"model": "Odyssey G40B",
"serial": "HCJXA14774",
"enabled": false,
"mode": "1920x1080@239.76Hz",
"width": 1920,
"height": 1080,
"refresh": 239.76,
"x": 0,
"y": 0,
"scale": 1,
"transform": 0
}
],
"workspaces": {
"enabled": true,
"strategy": "sequential",
"max_workspaces": 9,
"group_size": 3,
"monitor_order": [
"boe|0x0a6d",
"samsung electric company|odyssey g40b|hcjxa14774",
"dell inc.|dell s2721dgf|h13jy83"
],
"rules": [
{
"workspace": "1",
"output_key": "samsung electric company|odyssey g40b|hcjxa14774",
"output_name": "HDMI-A-1",
"default": true
},
{
"workspace": "2",
"output_key": "samsung electric company|odyssey g40b|hcjxa14774",
"output_name": "HDMI-A-1"
},
{
"workspace": "3",
"output_key": "dell inc.|dell s2721dgf|h13jy83",
"output_name": "DP-1",
"default": true
},
{
"workspace": "4",
"output_key": "dell inc.|dell s2721dgf|h13jy83",
"output_name": "DP-1"
},
{
"workspace": "5",
"output_key": "dell inc.|dell s2721dgf|h13jy83",
"output_name": "DP-1"
}
]
}
}

View file

@ -0,0 +1,94 @@
{
"name": "Normal",
"created_at": "2026-04-01T04:23:11.482056896Z",
"updated_at": "2026-04-01T04:23:11.482145433Z",
"outputs": [
{
"key": "dell inc.|dell s2721dgf|h13jy83",
"name": "DP-1",
"make": "Dell Inc.",
"model": "DELL S2721DGF",
"serial": "H13JY83",
"enabled": true,
"mode": "2560x1440@59.95Hz",
"width": 2560,
"height": 1440,
"refresh": 59.95,
"x": 1920,
"y": 0,
"scale": 1,
"transform": 1
},
{
"key": "samsung electric company|odyssey g40b|hcjxa14774",
"name": "HDMI-A-1",
"make": "Samsung Electric Company",
"model": "Odyssey G40B",
"serial": "HCJXA14774",
"enabled": true,
"mode": "1920x1080@239.76Hz",
"width": 1920,
"height": 1080,
"refresh": 239.76,
"x": 0,
"y": 0,
"scale": 1,
"transform": 0
},
{
"key": "boe|0x0a6d",
"name": "eDP-2",
"make": "BOE",
"model": "0x0A6D",
"enabled": false,
"mode": "preferred",
"width": 0,
"height": 0,
"refresh": 60,
"x": -1,
"y": -1,
"scale": 1,
"transform": 0
}
],
"workspaces": {
"enabled": true,
"strategy": "manual",
"max_workspaces": 9,
"group_size": 3,
"monitor_order": [
"boe|0x0a6d",
"samsung electric company|odyssey g40b|hcjxa14774",
"dell inc.|dell s2721dgf|h13jy83"
],
"rules": [
{
"workspace": "1",
"output_key": "samsung electric company|odyssey g40b|hcjxa14774",
"output_name": "HDMI-A-1",
"default": true
},
{
"workspace": "2",
"output_key": "samsung electric company|odyssey g40b|hcjxa14774",
"output_name": "HDMI-A-1"
},
{
"workspace": "3",
"output_key": "dell inc.|dell s2721dgf|h13jy83",
"output_name": "DP-1",
"default": true
},
{
"workspace": "4",
"output_key": "dell inc.|dell s2721dgf|h13jy83",
"output_name": "DP-1"
},
{
"workspace": "5",
"output_key": "dell inc.|dell s2721dgf|h13jy83",
"output_name": "DP-1"
}
]
}
}

View file

@ -0,0 +1,19 @@
foreground #f8f8f2
background #282a36
title_fg #f8f8f2
title_bg #282a36
margin_bg #6272a4
margin_fg #44475a
removed_bg #ff5555
highlight_removed_bg #ff5555
removed_margin_bg #ff5555
added_bg #50fa7b
highlight_added_bg #50fa7b
added_margin_bg #50fa7b
filler_bg #44475a
hunk_margin_bg #44475a
hunk_bg #bd93f9
search_bg #8be9fd
search_fg #282a36
select_bg #f1fa8c
select_fg #282a36

View file

@ -0,0 +1,2 @@
script-opts=ytdl_hook-ytdl_path=/usr/bin/yt-dlp
ytdl-raw-options=concurrent-fragments=5

View file

@ -0,0 +1,11 @@
#!/bin/bash
WALLPAPER_DIR="/mnt/data/Wallpapers"
WALLPAPERS=$(find "$WALLPAPER_DIR" -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.jpeg" \))
SELECTED_WALLPAPER=$(echo "$WALLPAPERS" | rofi -dmenu -i -p "Select Wallpaper:")
if [ -n "$SELECTED_WALLPAPER" ]; then
fish -c "awww_set_wallpaper '$SELECTED_WALLPAPER'"
fi

View file

@ -0,0 +1,34 @@
[[keymaps]]
command = "NextTrack"
key_sequence = "g n"
[[keymaps]]
command = "PreviousTrack"
key_sequence = "g p"
[[keymaps]]
command = "Search"
key_sequence = "C-c C-x /"
[[keymaps]]
command = "ResumePause"
key_sequence = "M-enter"
[[keymaps]]
command = "None"
key_sequence = "q"
[[keymaps]]
command = { VolumeChange = { offset = 1 } }
key_sequence = "-"
[[keymaps]]
command = { SeekForward = { duration = 10 } }
key_sequence = "E"
[[keymaps]]
command = { SeekBackward = { } }
key_sequence = "Q"
[[actions]]
action = "GoToArtist"
key_sequence = "g A"
[[actions]]
action = "GoToAlbum"
key_sequence = "g B"
target = "PlayingTrack"
[[actions]]
action="ToggleLiked"
key_sequence="C-l"

View file

@ -0,0 +1,16 @@
# sway does not set DISPLAY/WAYLAND_DISPLAY in the systemd user environment
# See FS#63021
# Adapted from xorg's 50-systemd-user.sh, which achieves a similar goal.
# Upstream refuses to set XDG_CURRENT_DESKTOP so we have to.
exec systemctl --user set-environment XDG_CURRENT_DESKTOP=sway
exec systemctl --user import-environment DISPLAY \
SWAYSOCK \
WAYLAND_DISPLAY \
XDG_CURRENT_DESKTOP
exec hash dbus-update-activation-environment 2>/dev/null && \
dbus-update-activation-environment --systemd DISPLAY \
SWAYSOCK \
XDG_CURRENT_DESKTOP=sway \
WAYLAND_DISPLAY

View file

@ -0,0 +1,6 @@
#!/bin/bash
export WLR_NO_HARDWARE_CURSORS=1
export GBM_BACKEND=nvidia-drm
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export WLR_RENDERER=vulkan
exec sway --unsupported-gpu

View file

@ -0,0 +1,9 @@
# Wallpaper
output * bg /mnt/data/Wallpapers/solid_background_dark.png fill
# My monitors (change to work for yours):
output HDMI-A-1 res 1920x1080@239.76Hz pos 0,0 transform 0
output DP-1 res 2560x1440@59.95Hz pos 1920,0 transform 270
output eDP-2 disable
# You can get the names of your outputs by running: swaymsg -t get_outputs

View file

@ -0,0 +1,127 @@
#!/usr/bin/env python3
import argparse
import logging
import sys
import signal
import gi
import json
gi.require_version('Playerctl', '2.0')
from gi.repository import Playerctl, GLib
logger = logging.getLogger(__name__)
def write_output(text, player):
logger.info('Writing output')
output = {'text': text,
'class': 'custom-' + player.props.player_name,
'alt': player.props.player_name}
sys.stdout.write(json.dumps(output) + '\n')
sys.stdout.flush()
def on_play(player, status, manager):
logger.info('Received new playback status')
on_metadata(player, player.props.metadata, manager)
def on_metadata(player, metadata, manager):
logger.info('Received new metadata')
track_info = ''
if player.props.player_name == 'spotify' and \
'mpris:trackid' in metadata.keys() and \
':ad:' in player.props.metadata['mpris:trackid']:
track_info = 'AD PLAYING'
elif player.get_artist() != '' and player.get_title() != '':
track_info = '{artist} - {title}'.format(artist=player.get_artist(),
title=player.get_title())
else:
track_info = player.get_title()
if player.props.status != 'Playing' and track_info:
track_info = '' + track_info
write_output(track_info, player)
def on_player_appeared(manager, player, selected_player=None):
if player is not None and (selected_player is None or player.name == selected_player):
init_player(manager, player)
else:
logger.debug("New player appeared, but it's not the selected player, skipping")
def on_player_vanished(manager, player):
logger.info('Player has vanished')
sys.stdout.write('\n')
sys.stdout.flush()
def init_player(manager, name):
logger.debug('Initialize player: {player}'.format(player=name.name))
player = Playerctl.Player.new_from_name(name)
player.connect('playback-status', on_play, manager)
player.connect('metadata', on_metadata, manager)
manager.manage_player(player)
on_metadata(player, player.props.metadata, manager)
def signal_handler(sig, frame):
logger.debug('Received signal to stop, exiting')
sys.stdout.write('\n')
sys.stdout.flush()
# loop.quit()
sys.exit(0)
def parse_arguments():
parser = argparse.ArgumentParser()
# Increase verbosity with every occurance of -v
parser.add_argument('-v', '--verbose', action='count', default=0)
# Define for which player we're listening
parser.add_argument('--player')
return parser.parse_args()
def main():
arguments = parse_arguments()
# Initialize logging
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG,
format='%(name)s %(levelname)s %(message)s')
# Logging is set by default to WARN and higher.
# With every occurrence of -v it's lowered by one
logger.setLevel(max((3 - arguments.verbose) * 10, 0))
# Log the sent command line arguments
logger.debug('Arguments received {}'.format(vars(arguments)))
manager = Playerctl.PlayerManager()
loop = GLib.MainLoop()
manager.connect('name-appeared', lambda *args: on_player_appeared(*args, arguments.player))
manager.connect('player-vanished', on_player_vanished)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
for player in manager.props.player_names:
if arguments.player is not None and arguments.player != player.name:
logger.debug('{player} is not the filtered player, skipping it'
.format(player=player.name)
)
continue
init_player(manager, player)
loop.run()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,42 @@
#!/usr/bin/python
import os
import imaplib
import mailsecrets
def getmails(username, password, server):
imap = imaplib.IMAP4_SSL(server, 993)
imap.login(username, password)
imap.select('INBOX')
ustatus, uresponse = imap.uid('search', None, 'UNSEEN')
if ustatus == 'OK':
unread_msg_nums = uresponse[0].split()
else:
unread_msg_nums = []
fstatus, fresponse = imap.uid('search', None, 'FLAGGED')
if fstatus == 'OK':
flagged_msg_nums = fresponse[0].split()
else:
flagged_msg_nums = []
return [len(unread_msg_nums), len(flagged_msg_nums)]
ping = os.system("ping " + mailsecrets.server + " -c1 > /dev/null 2>&1")
if ping == 0:
mails = getmails(mailsecrets.username, mailsecrets.password, mailsecrets.server)
text = ''
alt = ''
if mails[0] > 0:
text = alt = str(mails[0])
if mails[1] > 0:
alt = str(mails[1]) + "" + alt
else:
exit(1)
print('{"text":"' + text + '", "alt": "' + alt + '"}')
else:
exit(1)

View file

@ -0,0 +1,18 @@
#!/bin/sh
class=$(playerctl metadata --player=spotify_player --format '{{lc(status)}}')
icon=""
if [[ $class == "playing" ]]; then
info=$(playerctl metadata --player=spotify_player --format '{{artist}} - {{title}}')
if [[ ${#info} > 40 ]]; then
info=$(echo $info | cut -c1-40)"..."
fi
text=$info" "$icon
elif [[ $class == "paused" ]]; then
text=$icon
elif [[ $class == "stopped" ]]; then
text=""
fi
echo -e "{\"text\":\""$text"\", \"class\":\""$class"\"}"

View file

@ -0,0 +1,24 @@
#!/bin/sh
mount="/"
warning=20
critical=10
df -h -P -l "$mount" | awk -v warning=$warning -v critical=$critical '
/\/.*/ {
text=$5
tooltip="Filesystem: "$1"\rSize: "$2"\rUsed: "$3"\rAvail: "$4"\rUse%: "$5"\rMounted on: "$6
use=$5
exit 0
}
END {
class=""
gsub(/%$/,"",use)
if ((100 - use) < critical) {
class="critical"
} else if ((100 - use) < warning) {
class="warning"
}
print "{\"text\":\""text"\", \"percentage\":"use",\"tooltip\":\""tooltip"\", \"class\":\""class"\"}"
}
'

View file

@ -0,0 +1,8 @@
#!/bin/bash
updates=$(($(checkupdates 2>/dev/null | wc -l) + $(paru -Qum 2>/dev/null | wc -l)))
if [ "$updates" -gt 0 ]; then
echo '{"text":"⟳","class":"updates-available"}'
else
echo '{"text":"⟳","class":"no-updates"}'
fi

View file

@ -0,0 +1,79 @@
#!/bin/bash
cachedir=~/.cache/rbn
cachefile=${0##*/}-$1
if [ ! -d $cachedir ]; then
mkdir -p $cachedir
fi
if [ ! -f $cachedir/$cachefile ]; then
touch $cachedir/$cachefile
fi
# Save current IFS
SAVEIFS=$IFS
# Change IFS to new line.
IFS=$'\n'
cacheage=$(($(date +%s) - $(stat -c '%Y' "$cachedir/$cachefile")))
if [ $cacheage -gt 1740 ] || [ ! -s $cachedir/$cachefile ]; then
data=($(curl -s https://en.wttr.in/$1\?0qnT 2>&1))
echo ${data[0]} | cut -f1 -d, > $cachedir/$cachefile
echo ${data[1]} | sed -E 's/^.{15}//' >> $cachedir/$cachefile
echo ${data[2]} | sed -E 's/^.{15}//' >> $cachedir/$cachefile
fi
weather=($(cat $cachedir/$cachefile))
# Restore IFSClear
IFS=$SAVEIFS
temperature=$(echo ${weather[2]} | sed -E 's/([[:digit:]])+\.\./\1 to /g')
#echo ${weather[1]##*,}
# https://fontawesome.com/icons?s=solid&c=weather
case $(echo ${weather[1]##*,} | tr '[:upper:]' '[:lower:]') in
"clear" | "sunny")
condition=""
;;
"partly cloudy")
condition="杖"
;;
"cloudy")
condition=""
;;
"overcast")
condition=""
;;
"mist" | "fog" | "freezing fog")
condition=""
;;
"patchy rain possible" | "patchy light drizzle" | "light drizzle" | "patchy light rain" | "light rain" | "light rain shower" | "rain")
condition=""
;;
"moderate rain at times" | "moderate rain" | "heavy rain at times" | "heavy rain" | "moderate or heavy rain shower" | "torrential rain shower" | "rain shower")
condition=""
;;
"patchy snow possible" | "patchy sleet possible" | "patchy freezing drizzle possible" | "freezing drizzle" | "heavy freezing drizzle" | "light freezing rain" | "moderate or heavy freezing rain" | "light sleet" | "ice pellets" | "light sleet showers" | "moderate or heavy sleet showers")
condition="ﭽ"
;;
"blowing snow" | "moderate or heavy sleet" | "patchy light snow" | "light snow" | "light snow showers")
condition="流"
;;
"blizzard" | "patchy moderate snow" | "moderate snow" | "patchy heavy snow" | "heavy snow" | "moderate or heavy snow with thunder" | "moderate or heavy snow showers")
condition="ﰕ"
;;
"thundery outbreaks possible" | "patchy light rain with thunder" | "moderate or heavy rain with thunder" | "patchy light snow with thunder")
condition=""
;;
*)
condition=""
echo -e "{\"text\":\""$condition"\", \"alt\":\""${weather[0]}"\", \"tooltip\":\""${weather[0]}: $temperature ${weather[1]}"\"}"
;;
esac
#echo $temp $condition
echo -e "{\"text\":\""$temperature $condition"\", \"alt\":\""${weather[0]}"\", \"tooltip\":\""${weather[0]}: $temperature ${weather[1]}"\"}"

View file

@ -0,0 +1,10 @@
#!/usr/bin/env sh
# Terminate already running bar instances
killall -q waybar
# Wait until the processes have been shut down
while pgrep -x waybar >/dev/null; do sleep 1; done
# Launch main
waybar &

View file

@ -0,0 +1,5 @@
#!/usr/bin/sh
req=$(curl -s wttr.in/CITY?format="%t|%l+(%c%f)+%h,+%C")
bar=$(echo $req | awk -F "|" '{print $1}')
tooltip=$(echo $req | awk -F "|" '{print $2}')
echo "{\"text\":\"$bar\", \"tooltip\":\"$tooltip\"}"

View file

@ -0,0 +1,11 @@
[filechooser]
cmd=yazi-wrapper.sh
default_dir=$HOME
; Uncomment to skip creating destination save files with instructions in them
; create_help_file=0
; Uncomment and edit the line below to change the terminal emulator command
env=TERMCMD=kitty -e
; Mode must be one of 'suggested', 'default', or 'last'.
open_mode=suggested
save_mode=suggested

View file

@ -0,0 +1,43 @@
#!/usr/bin/env sh
# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
#
# For more information about input/output arguments read `xdg-desktop-portal-termfilechooser(5)`
set -e
if [ "$6" -ge 4 ]; then
set -x
fi
multiple="$1"
directory="$2"
save="$3"
path="$4"
out="$5"
cmd="lf"
termcmd="${TERMCMD:-kitty --title 'termfilechooser'}"
if [ "$save" = "1" ]; then
# save a file
set -- -selection-path "$out" "$path"
elif [ "$directory" = "1" ]; then
# upload files from a directory
set -- -last-dir-path "$out" "$path"
elif [ "$multiple" = "1" ]; then
# upload multiple files
set -- -selection-path "$out" "$path"
else
# upload only 1 file
set -- -selection-path "$out" "$path"
fi
command="$termcmd $cmd"
for arg in "$@"; do
# escape double quotes
escaped=$(printf "%s" "$arg" | sed 's/"/\\"/g')
# escape special
command="$command \"$escaped\""
done
sh -c "$command"

View file

@ -0,0 +1,54 @@
#!/usr/bin/env sh
# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
#
# For more information about input/output arguments read `xdg-desktop-portal-termfilechooser(5)`
set -e
if [ "$6" -ge 4 ]; then
set -x
fi
multiple="$1"
directory="$2"
save="$3"
path="$4"
out="$5"
cmd="nnn"
termcmd="${TERMCMD:-kitty --title 'termfilechooser'}"
if [ "$save" = "1" ]; then
# save a file
set -- -p "$out" "$path"
elif [ "$directory" = "1" ]; then
# upload files from a directory
set -- -p "$out" "$path"
elif [ "$multiple" = "1" ]; then
# upload multiple files
set -- -p "$out" "$path"
else
# upload only 1 file
set -- -p "$out" "$path"
fi
command="$termcmd $cmd"
for arg in "$@"; do
# escape double quotes
escaped=$(printf "%s" "$arg" | sed 's/"/\\"/g')
# escape special
command="$command \"$escaped\""
done
if [ "$directory" = "1" ]; then
sh -c "env NNN_TMPFILE=\"$out\" $command"
else
sh -c "$command"
fi
if [ "$directory" = "1" ] && [ -s "$out" ]; then
# select on quit; file data will be `cd '/dir/path'`
if [ "$(cut -c -2 "$out")" = "cd" ]; then
sed -i "s/^cd '\(.*\)'/\1/" "$out"
fi
fi

View file

@ -0,0 +1,43 @@
#!/usr/bin/env sh
# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
#
# For more information about input/output arguments read `xdg-desktop-portal-termfilechooser(5)`
set -e
if [ "$6" -ge 4 ]; then
set -x
fi
multiple="$1"
directory="$2"
save="$3"
path="$4"
out="$5"
cmd="ranger"
termcmd="${TERMCMD:-kitty --title 'termfilechooser'}"
if [ "$save" = "1" ]; then
# save a file
set -- --choosefile="$out" --cmd="echo Select save path (see tutorial in preview pane; try pressing zv or zp if no preview)" --selectfile="$path"
elif [ "$directory" = "1" ]; then
# upload files from a directory
set -- --choosedir="$out" --show-only-dirs --cmd="echo Select directory (quit in dir to select it)" "$path"
elif [ "$multiple" = "1" ]; then
# upload multiple files
set -- --choosefiles="$out" --cmd="echo Select file(s) (open file to select it; <Space> to select multiple)" "$path"
else
# upload only 1 file
set -- --choosefile="$out" --cmd="echo Select file (open file to select it)" "$path"
fi
command="$termcmd $cmd"
for arg in "$@"; do
# escape double quotes
escaped=$(printf "%s" "$arg" | sed 's/"/\\"/g')
# escape special
command="$command \"$escaped\""
done
sh -c "$command"

View file

@ -0,0 +1,11 @@
[Unit]
Description=Portal service (terminal file chooser implementation)
PartOf=graphical-session.target
After=graphical-session.target
[Service]
Type=dbus
BusName=org.freedesktop.impl.portal.desktop.termfilechooser
ExecStart=@libexecdir@/xdg-desktop-portal-termfilechooser
Restart=on-failure
Slice=session.slice

View file

@ -0,0 +1,45 @@
#!/usr/bin/env sh
# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
#
# For more information about input/output arguments read `xdg-desktop-portal-termfilechooser(5)`
set -e
if [ "$6" -ge 4 ]; then
set -x
fi
multiple="$1"
directory="$2"
save="$3"
path="$4"
out="$5"
cmd="vifm"
termcmd="${TERMCMD:-kitty --title 'termfilechooser'}"
if [ "$save" = "1" ]; then
# save a file
set -- --choose-files "$out" -c "only" -c "map <esc> :cquit<cr>" \
-c "set statusline='Save file (press <Enter> to select or <Esc> to cancel)%NCursorfile is the recommended choice, you can rename/move it%NIf you select another file, it will be overwritten by the save'" \
--select "$path" >"$path"
elif [ "$directory" = "1" ]; then
# upload files from a directory
set -- --choose-files "$out" --choose-dir "$out" -c "only" -c "map <esc> :cquit<cr>" -c "set statusline='Select directory (:quit in dir or select and open it, press <Esc> to cancel)'"
elif [ "$multiple" = "1" ]; then
# upload multiple files
set -- --choose-files "$out" -c "only" -c "map <esc> :cquit<cr>" -c "set statusline='Select file(s) (press <t> key to select multiple, press <Esc> to cancel)'"
else
# upload only 1 file
set -- --choose-files "$out" -c "only" -c "map <esc> :cquit<cr>" -c "set statusline='Select file (open file to select it, press <Esc> to cancel)'"
fi
command="$termcmd $cmd"
for arg in "$@"; do
# escape double quotes
escaped=$(printf "%s" "$arg" | sed 's/"/\\"/g')
# escape special
command="$command \"$escaped\""
done
sh -c "$command"

View file

@ -0,0 +1,52 @@
#!/usr/bin/env sh
# This wrapper script is invoked by xdg-desktop-portal-termfilechooser.
#
# For more information about input/output arguments read `xdg-desktop-portal-termfilechooser(5)`
set -e
if [ "$6" -ge 4 ]; then
set -x
fi
multiple="$1"
directory="$2"
save="$3"
path="$4"
out="$5"
cmd="yazi"
termcmd="${TERMCMD:-kitty --title 'termfilechooser'}"
if [ "$save" = "1" ]; then
# save a file
set -- --chooser-file="$out" "$path"
elif [ "$directory" = "1" ]; then
# upload files from a directory
set -- --chooser-file="$out" --cwd-file="$out"".1" "$path"
elif [ "$multiple" = "1" ]; then
# upload multiple files
set -- --chooser-file="$out" "$path"
else
# upload only 1 file
set -- --chooser-file="$out" "$path"
fi
command="$termcmd $cmd"
for arg in "$@"; do
# escape double quotes
escaped=$(printf "%s" "$arg" | sed 's/"/\\"/g')
# escape special
command="$command \"$escaped\""
done
sh -c "$command"
if [ "$directory" = "1" ]; then
if [ ! -s "$out" ] && [ -s "$out"".1" ]; then
cat "$out"".1" > "$out"
rm "$out"".1"
else
rm "$out"".1"
fi
fi

View file

@ -0,0 +1,3 @@
[preferred]
default=hyprland;gtk;
org.freedesktop.impl.portal.FileChooser=termfilechooser;

View file

@ -0,0 +1,4 @@
require("recycle-bin"):setup({
-- Optional: Override automatic trash directory discovery
-- trash_dir = "~/.local/share/Trash/", -- Uncomment to use specific directory
})

View file

@ -0,0 +1,370 @@
# A TOML linter such as https://taplo.tamasfe.dev/ can use this schema to validate your config.
# If you encounter any issues, please make an issue at https://github.com/yazi-rs/schemas.
"$schema" = "https://yazi-rs.github.io/schemas/keymap.json"
[mgr]
keymap = [
{ on = ["R","b"], run = "plugin recycle-bin", desc = "Open Recycle Bin menu" },
{ on = "<Esc>", run = "escape", desc = "Exit visual mode, clear selection, or cancel search" },
{ on = "<C-[>", run = "escape", desc = "Exit visual mode, clear selection, or cancel search" },
{ on = "q", run = "quit", desc = "Quit the process" },
{ on = "Q", run = "quit --no-cwd-file", desc = "Quit without outputting cwd-file" },
{ on = "<C-c>", run = "close", desc = "Close the current tab, or quit if it's last" },
{ on = "<C-z>", run = "suspend", desc = "Suspend the process" },
# Hopping
{ on = "k", run = "arrow prev", desc = "Previous file" },
{ on = "j", run = "arrow next", desc = "Next file" },
{ on = "<Up>", run = "arrow prev", desc = "Previous file" },
{ on = "<Down>", run = "arrow next", desc = "Next file" },
{ on = "<C-u>", run = "arrow -50%", desc = "Move cursor up half page" },
{ on = "<C-d>", run = "arrow 50%", desc = "Move cursor down half page" },
{ on = "<C-b>", run = "arrow -100%", desc = "Move cursor up one page" },
{ on = "<C-f>", run = "arrow 100%", desc = "Move cursor down one page" },
{ on = "<S-PageUp>", run = "arrow -50%", desc = "Move cursor up half page" },
{ on = "<S-PageDown>", run = "arrow 50%", desc = "Move cursor down half page" },
{ on = "<PageUp>", run = "arrow -100%", desc = "Move cursor up one page" },
{ on = "<PageDown>", run = "arrow 100%", desc = "Move cursor down one page" },
{ on = [ "g", "g" ], run = "arrow top", desc = "Go to top" },
{ on = "G", run = "arrow bot", desc = "Go to bottom" },
# Navigation
{ on = "h", run = "leave", desc = "Back to the parent directory" },
{ on = "l", run = "enter", desc = "Enter the child directory" },
{ on = "<Left>", run = "leave", desc = "Back to the parent directory" },
{ on = "<Right>", run = "enter", desc = "Enter the child directory" },
{ on = "H", run = "back", desc = "Back to previous directory" },
{ on = "L", run = "forward", desc = "Forward to next directory" },
# Toggle
{ on = "<Space>", run = [ "toggle", "arrow next" ], desc = "Toggle the current selection state" },
{ on = "<C-a>", run = "toggle_all --state=on", desc = "Select all files" },
{ on = "<C-r>", run = "toggle_all", desc = "Invert selection of all files" },
# Visual mode
{ on = "v", run = "visual_mode", desc = "Enter visual mode (selection mode)" },
{ on = "V", run = "visual_mode --unset", desc = "Enter visual mode (unset mode)" },
# Seeking
{ on = "K", run = "seek -5", desc = "Seek up 5 units in the preview" },
{ on = "J", run = "seek 5", desc = "Seek down 5 units in the preview" },
# Spotting
{ on = "<Tab>", run = "spot", desc = "Spot hovered file" },
# Operation
{ on = "o", run = "open", desc = "Open selected files" },
{ on = "O", run = "open --interactive", desc = "Open selected files interactively" },
{ on = "<Enter>", run = "open", desc = "Open selected files" },
{ on = "<S-Enter>", run = "open --interactive", desc = "Open selected files interactively" },
{ on = "y", run = "yank", desc = "Yank selected files (copy)" },
{ on = "x", run = "yank --cut", desc = "Yank selected files (cut)" },
{ on = "p", run = "paste", desc = "Paste yanked files" },
{ on = "P", run = "paste --force", desc = "Paste yanked files (overwrite if the destination exists)" },
{ on = "-", run = "link", desc = "Symlink the absolute path of yanked files" },
{ on = "_", run = "link --relative", desc = "Symlink the relative path of yanked files" },
{ on = "<C-->", run = "hardlink", desc = "Hardlink yanked files" },
{ on = "Y", run = "unyank", desc = "Cancel the yank status" },
{ on = "X", run = "unyank", desc = "Cancel the yank status" },
{ on = "d", run = "remove", desc = "Trash selected files" },
{ on = "D", run = "remove --permanently", desc = "Permanently delete selected files" },
{ on = "a", run = "create", desc = "Create a file (ends with / for directories)" },
{ on = "r", run = "rename --cursor=before_ext", desc = "Rename selected file(s)" },
{ on = ";", run = "shell --interactive", desc = "Run a shell command" },
{ on = ":", run = "shell --block --interactive", desc = "Run a shell command (block until finishes)" },
{ on = ".", run = "hidden toggle", desc = "Toggle the visibility of hidden files" },
{ on = "s", run = "search --via=fd", desc = "Search files by name via fd" },
{ on = "S", run = "search --via=rg", desc = "Search files by content via ripgrep" },
{ on = "<C-s>", run = "escape --search", desc = "Cancel the ongoing search" },
{ on = "z", run = "plugin fzf", desc = "Jump to a file/directory via fzf" },
{ on = "Z", run = "plugin zoxide", desc = "Jump to a directory via zoxide" },
# Linemode
{ on = [ "m", "s" ], run = "linemode size", desc = "Linemode: size" },
{ on = [ "m", "p" ], run = "linemode permissions", desc = "Linemode: permissions" },
{ on = [ "m", "b" ], run = "linemode btime", desc = "Linemode: btime" },
{ on = [ "m", "m" ], run = "linemode mtime", desc = "Linemode: mtime" },
{ on = [ "m", "o" ], run = "linemode owner", desc = "Linemode: owner" },
{ on = [ "m", "n" ], run = "linemode none", desc = "Linemode: none" },
# Copy
{ on = [ "c", "c" ], run = "copy path", desc = "Copy the file path" },
{ on = [ "c", "d" ], run = "copy dirname", desc = "Copy the directory path" },
{ on = [ "c", "f" ], run = "copy filename", desc = "Copy the filename" },
{ on = [ "c", "n" ], run = "copy name_without_ext", desc = "Copy the filename without extension" },
# Filter
{ on = "f", run = "filter --smart", desc = "Filter files" },
# Find
{ on = "/", run = "find --smart", desc = "Find next file" },
{ on = "?", run = "find --previous --smart", desc = "Find previous file" },
{ on = "n", run = "find_arrow", desc = "Next found" },
{ on = "N", run = "find_arrow --previous", desc = "Previous found" },
# Sorting
{ on = [ ",", "m" ], run = [ "sort mtime --reverse=no", "linemode mtime" ], desc = "Sort by modified time" },
{ on = [ ",", "M" ], run = [ "sort mtime --reverse", "linemode mtime" ], desc = "Sort by modified time (reverse)" },
{ on = [ ",", "b" ], run = [ "sort btime --reverse=no", "linemode btime" ], desc = "Sort by birth time" },
{ on = [ ",", "B" ], run = [ "sort btime --reverse", "linemode btime" ], desc = "Sort by birth time (reverse)" },
{ on = [ ",", "e" ], run = "sort extension --reverse=no", desc = "Sort by extension" },
{ on = [ ",", "E" ], run = "sort extension --reverse", desc = "Sort by extension (reverse)" },
{ on = [ ",", "a" ], run = "sort alphabetical --reverse=no", desc = "Sort alphabetically" },
{ on = [ ",", "A" ], run = "sort alphabetical --reverse", desc = "Sort alphabetically (reverse)" },
{ on = [ ",", "n" ], run = "sort natural --reverse=no", desc = "Sort naturally" },
{ on = [ ",", "N" ], run = "sort natural --reverse", desc = "Sort naturally (reverse)" },
{ on = [ ",", "s" ], run = [ "sort size --reverse=no", "linemode size" ], desc = "Sort by size" },
{ on = [ ",", "S" ], run = [ "sort size --reverse", "linemode size" ], desc = "Sort by size (reverse)" },
{ on = [ ",", "r" ], run = "sort random --reverse=no", desc = "Sort randomly" },
# Goto
{ on = [ "g", "e" ], run = "cd /mnt/data", desc = "Go /mnt/data" },
{ on = [ "g", "h" ], run = "cd ~", desc = "Go home" },
{ on = [ "g", "c" ], run = "cd ~/.config", desc = "Go ~/.config" },
{ on = [ "g", "d" ], run = "cd ~/Downloads", desc = "Go ~/Downloads" },
{ on = [ "g", "<Space>" ], run = "cd --interactive", desc = "Jump interactively" },
{ on = [ "g", "f" ], run = "follow", desc = "Follow hovered symlink" },
# Tabs
{ on = "t", run = "tab_create --current", desc = "Create a new tab with CWD" },
{ on = "1", run = "tab_switch 0", desc = "Switch to first tab" },
{ on = "2", run = "tab_switch 1", desc = "Switch to second tab" },
{ on = "3", run = "tab_switch 2", desc = "Switch to third tab" },
{ on = "4", run = "tab_switch 3", desc = "Switch to fourth tab" },
{ on = "5", run = "tab_switch 4", desc = "Switch to fifth tab" },
{ on = "6", run = "tab_switch 5", desc = "Switch to sixth tab" },
{ on = "7", run = "tab_switch 6", desc = "Switch to seventh tab" },
{ on = "8", run = "tab_switch 7", desc = "Switch to eighth tab" },
{ on = "9", run = "tab_switch 8", desc = "Switch to ninth tab" },
{ on = "[", run = "tab_switch -1 --relative", desc = "Switch to previous tab" },
{ on = "]", run = "tab_switch 1 --relative", desc = "Switch to next tab" },
{ on = "{", run = "tab_swap -1", desc = "Swap current tab with previous tab" },
{ on = "}", run = "tab_swap 1", desc = "Swap current tab with next tab" },
# Tasks
{ on = "w", run = "tasks:show", desc = "Show task manager" },
# Help
{ on = "~", run = "help", desc = "Open help" },
{ on = "<F1>", run = "help", desc = "Open help" },
]
[tasks]
keymap = [
{ on = "<Esc>", run = "close", desc = "Close task manager" },
{ on = "<C-[>", run = "close", desc = "Close task manager" },
{ on = "<C-c>", run = "close", desc = "Close task manager" },
{ on = "w", run = "close", desc = "Close task manager" },
{ on = "k", run = "arrow prev", desc = "Previous task" },
{ on = "j", run = "arrow next", desc = "Next task" },
{ on = "<Up>", run = "arrow prev", desc = "Previous task" },
{ on = "<Down>", run = "arrow next", desc = "Next task" },
{ on = "<Enter>", run = "inspect", desc = "Inspect the task" },
{ on = "x", run = "cancel", desc = "Cancel the task" },
# Help
{ on = "~", run = "help", desc = "Open help" },
{ on = "<F1>", run = "help", desc = "Open help" },
]
[spot]
keymap = [
{ on = "<Esc>", run = "close", desc = "Close the spot" },
{ on = "<C-[>", run = "close", desc = "Close the spot" },
{ on = "<C-c>", run = "close", desc = "Close the spot" },
{ on = "<Tab>", run = "close", desc = "Close the spot" },
{ on = "k", run = "arrow prev", desc = "Previous line" },
{ on = "j", run = "arrow next", desc = "Next line" },
{ on = "h", run = "swipe prev", desc = "Swipe to previous file" },
{ on = "l", run = "swipe next", desc = "Swipe to next file" },
{ on = "<Up>", run = "arrow prev", desc = "Previous line" },
{ on = "<Down>", run = "arrow next", desc = "Next line" },
{ on = "<Left>", run = "swipe prev", desc = "Swipe to previous file" },
{ on = "<Right>", run = "swipe next", desc = "Swipe to next file" },
# Copy
{ on = [ "c", "c" ], run = "copy cell", desc = "Copy selected cell" },
# Help
{ on = "~", run = "help", desc = "Open help" },
{ on = "<F1>", run = "help", desc = "Open help" },
]
[pick]
keymap = [
{ on = "<Esc>", run = "close", desc = "Cancel pick" },
{ on = "<C-[>", run = "close", desc = "Cancel pick" },
{ on = "<C-c>", run = "close", desc = "Cancel pick" },
{ on = "<Enter>", run = "close --submit", desc = "Submit the pick" },
{ on = "k", run = "arrow prev", desc = "Previous option" },
{ on = "j", run = "arrow next", desc = "Next option" },
{ on = "<Up>", run = "arrow prev", desc = "Previous option" },
{ on = "<Down>", run = "arrow next", desc = "Next option" },
# Help
{ on = "~", run = "help", desc = "Open help" },
{ on = "<F1>", run = "help", desc = "Open help" },
]
[input]
keymap = [
{ on = "<C-c>", run = "close", desc = "Cancel input" },
{ on = "<Enter>", run = "close --submit", desc = "Submit input" },
{ on = "<Esc>", run = "escape", desc = "Back to normal mode, or cancel input" },
{ on = "<C-[>", run = "escape", desc = "Back to normal mode, or cancel input" },
# Mode
{ on = "i", run = "insert", desc = "Enter insert mode" },
{ on = "I", run = [ "move first-char", "insert" ], desc = "Move to the BOL, and enter insert mode" },
{ on = "a", run = "insert --append", desc = "Enter append mode" },
{ on = "A", run = [ "move eol", "insert --append" ], desc = "Move to the EOL, and enter append mode" },
{ on = "v", run = "visual", desc = "Enter visual mode" },
{ on = "r", run = "replace", desc = "Replace a single character" },
# Selection
{ on = "V", run = [ "move bol", "visual", "move eol" ], desc = "Select from BOL to EOL" },
{ on = "<C-A>", run = [ "move eol", "visual", "move bol" ], desc = "Select from EOL to BOL" },
{ on = "<C-E>", run = [ "move bol", "visual", "move eol" ], desc = "Select from BOL to EOL" },
# Character-wise movement
{ on = "h", run = "move -1", desc = "Move back a character" },
{ on = "l", run = "move 1", desc = "Move forward a character" },
{ on = "<Left>", run = "move -1", desc = "Move back a character" },
{ on = "<Right>", run = "move 1", desc = "Move forward a character" },
{ on = "<C-b>", run = "move -1", desc = "Move back a character" },
{ on = "<C-f>", run = "move 1", desc = "Move forward a character" },
# Word-wise movement
{ on = "b", run = "backward", desc = "Move back to the start of the current or previous word" },
{ on = "B", run = "backward --far", desc = "Move back to the start of the current or previous WORD" },
{ on = "w", run = "forward", desc = "Move forward to the start of the next word" },
{ on = "W", run = "forward --far", desc = "Move forward to the start of the next WORD" },
{ on = "e", run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" },
{ on = "E", run = "forward --far --end-of-word", desc = "Move forward to the end of the current or next WORD" },
{ on = "<A-b>", run = "backward", desc = "Move back to the start of the current or previous word" },
{ on = "<A-f>", run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" },
# Line-wise movement
{ on = "0", run = "move bol", desc = "Move to the BOL" },
{ on = "$", run = "move eol", desc = "Move to the EOL" },
{ on = "_", run = "move first-char", desc = "Move to the first non-whitespace character" },
{ on = "^", run = "move first-char", desc = "Move to the first non-whitespace character" },
{ on = "<C-a>", run = "move bol", desc = "Move to the BOL" },
{ on = "<C-e>", run = "move eol", desc = "Move to the EOL" },
{ on = "<Home>", run = "move bol", desc = "Move to the BOL" },
{ on = "<End>", run = "move eol", desc = "Move to the EOL" },
# Delete
{ on = "<Backspace>", run = "backspace", desc = "Delete the character before the cursor" },
{ on = "<Delete>", run = "backspace --under", desc = "Delete the character under the cursor" },
{ on = "<C-h>", run = "backspace", desc = "Delete the character before the cursor" },
{ on = "<C-d>", run = "backspace --under", desc = "Delete the character under the cursor" },
# Kill
{ on = "<C-u>", run = "kill bol", desc = "Kill backwards to the BOL" },
{ on = "<C-k>", run = "kill eol", desc = "Kill forwards to the EOL" },
{ on = "<C-w>", run = "kill backward", desc = "Kill backwards to the start of the current word" },
{ on = "<A-d>", run = "kill forward", desc = "Kill forwards to the end of the current word" },
# Cut/Yank/Paste
{ on = "d", run = "delete --cut", desc = "Cut selected characters" },
{ on = "D", run = [ "delete --cut", "move eol" ], desc = "Cut until EOL" },
{ on = "c", run = "delete --cut --insert", desc = "Cut selected characters, and enter insert mode" },
{ on = "C", run = [ "delete --cut --insert", "move eol" ], desc = "Cut until EOL, and enter insert mode" },
{ on = "s", run = [ "delete --cut --insert", "move 1" ], desc = "Cut current character, and enter insert mode" },
{ on = "S", run = [ "move bol", "delete --cut --insert", "move eol" ], desc = "Cut from BOL until EOL, and enter insert mode" },
{ on = "x", run = [ "delete --cut", "move 1 --in-operating" ], desc = "Cut current character" },
{ on = "y", run = "yank", desc = "Copy selected characters" },
{ on = "p", run = "paste", desc = "Paste copied characters after the cursor" },
{ on = "P", run = "paste --before", desc = "Paste copied characters before the cursor" },
# Undo/Redo
{ on = "u", run = "undo", desc = "Undo the last operation" },
{ on = "<C-r>", run = "redo", desc = "Redo the last operation" },
# Help
{ on = "~", run = "help", desc = "Open help" },
{ on = "<F1>", run = "help", desc = "Open help" },
]
[confirm]
keymap = [
{ on = "<Esc>", run = "close", desc = "Cancel the confirm" },
{ on = "<C-[>", run = "close", desc = "Cancel the confirm" },
{ on = "<C-c>", run = "close", desc = "Cancel the confirm" },
{ on = "<Enter>", run = "close --submit", desc = "Submit the confirm" },
{ on = "n", run = "close", desc = "Cancel the confirm" },
{ on = "y", run = "close --submit", desc = "Submit the confirm" },
{ on = "k", run = "arrow prev", desc = "Previous line" },
{ on = "j", run = "arrow next", desc = "Next line" },
{ on = "<Up>", run = "arrow prev", desc = "Previous line" },
{ on = "<Down>", run = "arrow next", desc = "Next line" },
# Help
{ on = "~", run = "help", desc = "Open help" },
{ on = "<F1>", run = "help", desc = "Open help" },
]
[cmp]
keymap = [
{ on = "<C-c>", run = "close", desc = "Cancel completion" },
{ on = "<Tab>", run = "close --submit", desc = "Submit the completion" },
{ on = "<Enter>", run = [ "close --submit", "input:close --submit" ], desc = "Complete and submit the input" },
{ on = "<A-k>", run = "arrow prev", desc = "Previous item" },
{ on = "<A-j>", run = "arrow next", desc = "Next item" },
{ on = "<Up>", run = "arrow prev", desc = "Previous item" },
{ on = "<Down>", run = "arrow next", desc = "Next item" },
{ on = "<C-p>", run = "arrow prev", desc = "Previous item" },
{ on = "<C-n>", run = "arrow next", desc = "Next item" },
# Help
{ on = "~", run = "help", desc = "Open help" },
{ on = "<F1>", run = "help", desc = "Open help" },
]
[help]
keymap = [
{ on = "<Esc>", run = "escape", desc = "Clear the filter, or hide the help" },
{ on = "<C-[>", run = "escape", desc = "Clear the filter, or hide the help" },
{ on = "<C-c>", run = "close", desc = "Hide the help" },
# Navigation
{ on = "k", run = "arrow prev", desc = "Previous line" },
{ on = "j", run = "arrow next", desc = "Next line" },
{ on = "<Up>", run = "arrow prev", desc = "Previous line" },
{ on = "<Down>", run = "arrow next", desc = "Next line" },
# Filtering
{ on = "f", run = "filter", desc = "Filter help items" },
]

View file

@ -0,0 +1,7 @@
[[plugin.deps]]
use = "uhs-robert/recycle-bin"
rev = "1762676"
hash = "c77042b4296544a9edb4849338056039"
[flavor]
deps = []

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Robert
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,183 @@
<p align="center">
<img
src="https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/svg/1f5d1.svg"
width="128" height="128" alt="Trash emoji" />
</p>
<h1 align="center">recycle-bin.yazi</h1>
<p align="center">
<a href="https://github.com/uhs-robert/recycle-bin.yazi/stargazers"><img src="https://img.shields.io/github/stars/uhs-robert/recycle-bin.yazi?colorA=192330&colorB=skyblue&style=for-the-badge&cacheSeconds=4300"></a>
<a href="https://github.com/sxyazi/yazi" target="_blank" rel="noopener noreferrer"><img alt="Yazi 0.25+" src="https://img.shields.io/badge/Yazi-0.25%2B-blue?style=for-the-badge&cacheSeconds=4300&labelColor=192330" /></a>
<a href="https://github.com/uhs-robert/recycle-bin.yazi/issues"><img src="https://img.shields.io/github/issues/uhs-robert/recycle-bin.yazi?colorA=192330&colorB=khaki&style=for-the-badge&cacheSeconds=4300"></a>
<a href="https://github.com/uhs-robert/recycle-bin.yazi/contributors"><img src="https://img.shields.io/github/contributors/uhs-robert/recycle-bin.yazi?colorA=192330&colorB=8FD1C7&style=for-the-badge&cacheSeconds=4300"></a>
<a href="https://github.com/uhs-robert/recycle-bin.yazi/network/members"><img src="https://img.shields.io/github/forks/uhs-robert/recycle-bin.yazi?colorA=192330&colorB=CFA7FF&style=for-the-badge&cacheSeconds=4300"></a>
</p>
<p align="center">
A blazing fast, minimal <strong>Recycle Bin</strong> for the <a target="_blank" rel="noopener noreferrer" href="https://github.com/sxyazi/yazi">Yazi</a> terminal filemanager.
</p>
## 🕶️ What does it do?
Browse, restore, or permanently delete trashed files without leaving your terminal. Includes age-based cleanup and bulk actions.
<https://github.com/user-attachments/assets/1f7ab9b2-33e3-4262-94c5-b27ad9dc142e>
> [!NOTE]
>
> **Cross-Platform Support**
>
> This plugin supports Linux and macOS systems.
## 🧠 What it does under the hood
This plugin serves as a wrapper for the [trash-cli](https://github.com/andreafrancia/trash-cli) command, integrating it seamlessly with Yazi.
## ✨ Features
- **📂 Browse trash**: Navigate to trash directory directly in Yazi
- **🔄 Restore files**: Bulk restore selected files from trash to their original locations
- **⚠️ Conflict resolution**: Intelligent handling when restored files already exist at destination
- **🛡️ Safety dialogs**: Preview conflicts with skip/overwrite options before restoration
- **🗑️ Empty trash**: Clear entire trash with detailed file previews and confirmation dialog
- **📅 Empty by days**: Remove trash items older than specified number of days with size information
- **❌ Permanent delete**: Bulk delete selected files from trash permanently
- **🔧 Configurable**: Customize trash directory
## 📋 Requirements
| Software | Minimum | Notes |
| --------- | ----------- | ----------------------------------------------------------------------------------------- |
| Yazi | `>=25.5.31` | untested on 25.6+ |
| trash-cli | any | **Linux**: `sudo dnf/apt/pacman install trash-cli`<br>**macOS**: `brew install trash-cli` |
The plugin uses the following trash-cli commands: `trash-list`, `trash-empty`, `trash-restore`, and `trash-rm`.
## 📦 Installation
Install the plugin via Yazi's package manager:
```sh
# via Yazis package manager
ya pkg add uhs-robert/recycle-bin
```
Then add the following to your `~/.config/yazi/init.lua` to enable the plugin with default settings:
```lua
require("recycle-bin"):setup()
```
## ⚙️ Configuration
The plugin automatically discovers your system's trash directories using `trash-list --trash-dirs`. If you need to customize the behavior, you can pass a config table to `setup()`:
```lua
require("recycle-bin"):setup({
-- Optional: Override automatic trash directory discovery
-- trash_dir = "~/.local/share/Trash/", -- Uncomment to use specific directory
})
```
> [!NOTE]
> The plugin supports multiple trash directories and will prompt you to choose which one to use if multiple are found.
## 🎹 Key Mapping
### 🗝️ Recommended: Preset
Add this to your `~/.config/yazi/keymap.toml` (substitute `on = ["R","b"]` with your keybind preference):
```toml
[mgr]
prepend_keymap = [
{ on = ["R","b"], run = "plugin recycle-bin", desc = "Open Recycle Bin menu" },
]
```
The `R b` menu provides access to all trash management functions:
- `o` → Open Trash
- `r` → Restore from Trash
- `d` → Delete from Trash
- `e` → Empty Trash
- `D` → Empty by Days
> [!TIP]
> `recycle-bin.yazi` uses the [array form for its keymap example](https://yazi-rs.github.io/docs/configuration/keymap).
> You must pick **only one style** per file; mixing with `[[mgr.prepend_keymap]]` will fail.
>
> **Also note:** some plugins may suggest binding a bare key like `on = "R"`,
> which blocks all `R <key>` chords (including `R b`). Change those to chords
> (e.g. `["R","r"]`) or choose a different non-conflicting prefix.
---
### 🛠️ Alternative: Custom direct keybinds
If you prefer direct keybinds, you may also set your own using our API. Here are the available options:
```toml
[mgr]
prepend_keymap = [
{ on = ["R","o"], run = "plugin recycle-bin -- open", desc = "Open Trash" },
{ on = ["R","e"], run = "plugin recycle-bin -- empty", desc = "Empty Trash" },
{ on = ["R","D"], run = "plugin recycle-bin -- emptyDays", desc = "Empty by days deleted" },
{ on = ["R","d"], run = "plugin recycle-bin -- delete", desc = "Delete from Trash" },
{ on = ["R","r"], run = "plugin recycle-bin -- restore", desc = "Restore from Trash" },
]
```
> [!IMPORTANT]
> Remember that you are the only one who is responsible for managing and resolving your keybind conflicts.
## 🚀 Usage
### 📝 Example using the recommended preset
- **Recycle Bin Menu (`R b`):** Opens an interactive menu with all trash management options
- **Open Trash (`o`):** Navigate to trash directory directly in Yazi
- **Restore from Trash (`r`):** Bulk restore selected files from trash to their original locations. The plugin automatically detects conflicts when files already exist at the original location and prompts you to skip or overwrite conflicting files with detailed information.
- **Delete from Trash (`d`):** Permanently delete selected files from trash. Shows confirmation dialog before deletion.
- **Empty Trash (`e`):** Clear entire trash with detailed file previews including names, sizes, and deletion dates before confirmation.
- **Empty by Days (`D`):** Remove trash items older than specified number of days (defaults to 30 days). Displays filtered list with file details and total size information.
> [!TIP]
> Use Yazi's visual selection (`v` or `V` followed by `ESC` to select items) or toggle select (press `Space` on individual files) to select multiple files from the Trash before restoring or deleting
>
> The plugin will show a confirmation dialog for destructive operations
## 🛠️ Troubleshooting
### Common Issues
**"trashcli not found" error:**
- Ensure trash-cli is installed: `sudo dnf/apt/pacman install trash-cli`
- Verify installation: `trash-list --version`
- Check if trash-cli commands are in your PATH
**"Trash directory not found" error:**
- The plugin automatically discovers trash directories using `trash-list --trash-dirs`
- If no directories are found, create the standard location:
- **Linux**: `mkdir -p ~/.local/share/Trash/{files,info}`
- **macOS**: `mkdir -p ~/.Trash`
- You can also specify a custom path in your configuration
**"No files selected" warning:**
- Make sure you have files selected in Yazi before running restore/delete operations
- Use `Space` to select files or `v`/`V` for visual selection mode
## 💡 Recommendations
### Companion Plugin
For an even better trash management experience, pair this plugin with:
**[restore.yazi](https://github.com/boydaihungst/restore.yazi)** - Undo your delete history by your latest deleted files/folders
This companion plugin adds an "undo" feature that lets you press `u` to instantly restore the last deleted file. You can keep hitting `u` repeatedly to step through your entire delete history, making accidental deletions a thing of the past.
**Perfect combination:** Use `restore.yazi` for quick single-file undos and `recycle-bin.yazi` for comprehensive trash management and bulk operations.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,258 @@
# A TOML linter such as https://taplo.tamasfe.dev/ can use this schema to validate your config.
# If you encounter any issues, please make an issue at https://github.com/yazi-rs/schemas.
"$schema" = "https://yazi-rs.github.io/schemas/yazi.json"
[mgr]
ratio = [ 1, 4, 3 ]
sort_by = "alphabetical"
sort_sensitive = false
sort_reverse = false
sort_dir_first = true
sort_translit = false
linemode = "none"
show_hidden = true
show_symlink = true
scrolloff = 5
mouse_events = [ "click", "scroll" ]
title_format = "Yazi: {cwd}"
[preview]
wrap = "no"
tab_size = 2
max_width = 600
max_height = 900
cache_dir = ""
image_delay = 30
image_filter = "triangle"
image_quality = 75
ueberzug_scale = 1
ueberzug_offset = [ 0, 0, 0, 0 ]
[opener]
edit = [
{ run = "/usr/local/bin/zed_sudo_wrapper %s", desc = "Zed (sudo fallback)", for = "unix", block = true },
{ run = "code %s", desc = "code", for = "windows", orphan = true },
{ run = "code -w %s", desc = "code (block)", for = "windows", block = true },
]
play = [
{ run = "xdg-open %s1", desc = "Play", for = "linux" },
{ run = "open %s", desc = "Play", for = "macos" },
{ run = 'start "" %s1', orphan = true, desc = "Play", for = "windows" },
{ run = "termux-open %s1", desc = "Play", for = "android" },
{ run = "mediainfo %s1; echo 'Press enter to exit'; read _", block = true, desc = "Show media info", for = "unix" },
{ run = "mediainfo %s1 & pause", block = true, desc = "Show media info", for = "windows" },
]
open = [
{ run = "xdg-open %s1", desc = "Open", for = "linux" },
{ run = "open %s", desc = "Open", for = "macos" },
{ run = 'start "" %s1', desc = "Open", for = "windows", orphan = true },
{ run = "termux-open %s1", desc = "Open", for = "android" },
]
reveal = [
{ run = "xdg-open %d1", desc = "Reveal", for = "linux" },
{ run = "open -R %s1", desc = "Reveal", for = "macos" },
{ run = "explorer /select,%s1", desc = "Reveal", for = "windows", orphan = true },
{ run = "termux-open %d1", desc = "Reveal", for = "android" },
{ run = "clear; exiftool %s1; echo 'Press enter to exit'; read _", desc = "Show EXIF", for = "unix", block = true },
]
extract = [
{ run = "ya pub extract --list %s", desc = "Extract here" },
]
download = [
{ run = "ya emit download --open %S", desc = "Download and open" },
{ run = "ya emit download %S", desc = "Download" },
]
pdf = [
{ run = "zathura %s", desc = "Zathura", block = true },
]
zedproj = [
{ run = "zeditor -n %s", desc = "Zed (project)", for = "unix", orphan = true, block = false },
]
[open]
rules = [
# Folder
{ url = "*/", use = [ "zedproj", "open", "reveal" ] },
# TOML (force editor regardless of mime detector differences)
{ url = "*.toml", use = [ "edit", "reveal" ] },
{ mime = "application/{toml,x-toml}", use = [ "edit", "reveal" ] },
# Common config formats (force editor)
{ url = "*.{yaml,yml,conf,ini}", use = [ "edit", "reveal" ] },
# Text
{ mime = "text/*", use = [ "edit", "reveal" ] },
# Image
{ mime = "image/*", use = [ "open", "reveal" ] },
# Media
{ mime = "{audio,video}/*", use = [ "play", "reveal" ] },
# Archive
{ mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", use = [ "extract", "reveal" ] },
# JSON
{ mime = "application/{json,ndjson}", use = [ "edit", "reveal" ] },
{ mime = "*/javascript", use = [ "edit", "reveal" ] },
# Empty file
{ mime = "inode/empty", use = [ "edit", "reveal" ] },
# Virtual file system
{ mime = "vfs/{absent,stale}", use = "download" },
# PDF
{ mime = "application/pdf", use = [ "pdf" ], desc = "Open PDF" },
# Fallback
{ url = "*", use = [ "open", "reveal" ] },
]
[tasks]
micro_workers = 10
macro_workers = 10
bizarre_retry = 3
image_alloc = 536870912 # 512MB
image_bound = [ 10000, 10000 ]
suppress_preload = false
[plugin]
fetchers = [
# Mimetype
{ id = "mime", url = "*/", run = "mime.dir", prio = "high" },
{ id = "mime", url = "local://*", run = "mime.local", prio = "high" },
{ id = "mime", url = "remote://*", run = "mime.remote", prio = "high" },
]
spotters = [
{ url = "*/", run = "folder" },
# Code
{ mime = "text/*", run = "code" },
{ mime = "application/{mbox,javascript,wine-extension-ini}", run = "code" },
# Image
{ mime = "image/{avif,hei?,jxl}", run = "magick" },
{ mime = "image/svg+xml", run = "svg" },
{ mime = "image/*", run = "image" },
# Video
{ mime = "video/*", run = "video" },
# Virtual file system
{ mime = "vfs/*", run = "vfs" },
# Error
{ mime = "null/*", run = "null" },
# Fallback
{ url = "*", run = "file" },
]
preloaders = [
# Image
{ mime = "image/{avif,hei?,jxl}", run = "magick" },
{ mime = "image/svg+xml", run = "svg" },
{ mime = "image/*", run = "image" },
# Video
{ mime = "video/*", run = "video" },
# PDF
{ mime = "application/pdf", run = "pdf" },
# Font
{ mime = "font/*", run = "font" },
{ mime = "application/ms-opentype", run = "font" },
]
previewers = [
{ url = "*/", run = "folder" },
# Code
{ mime = "text/*", run = "code" },
{ mime = "application/{mbox,javascript,wine-extension-ini}", run = "code" },
# JSON
{ mime = "application/{json,ndjson}", run = "json" },
# Image
{ mime = "image/{avif,hei?,jxl}", run = "magick" },
{ mime = "image/svg+xml", run = "svg" },
{ mime = "image/*", run = "image" },
# Video
{ mime = "video/*", run = "video" },
# PDF
{ mime = "application/pdf", run = "pdf" },
# Archive
{ mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", run = "archive" },
{ mime = "application/{debian*-package,redhat-package-manager,rpm,android.package-archive}", run = "archive" },
{ url = "*.{AppImage,appimage}", run = "archive" },
# Virtual Disk / Disk Image
{ mime = "application/{iso9660-image,qemu-disk,ms-wim,apple-diskimage}", run = "archive" },
{ mime = "application/virtualbox-{vhd,vhdx}", run = "archive" },
{ url = "*.{img,fat,ext,ext2,ext3,ext4,squashfs,ntfs,hfs,hfsx}", run = "archive" },
# Font
{ mime = "font/*", run = "font" },
{ mime = "application/ms-opentype", run = "font" },
# Empty file
{ mime = "inode/empty", run = "empty" },
# Virtual file system
{ mime = "vfs/*", run = "vfs" },
# Error
{ mime = "null/*", run = "null" },
# Fallback
{ url = "*", run = "file" },
]
[input]
cursor_blink = false
# cd
cd_title = "Change directory:"
cd_origin = "top-center"
cd_offset = [ 0, 2, 50, 3 ]
# create
create_title = [ "Create:", "Create (dir):" ]
create_origin = "top-center"
create_offset = [ 0, 2, 50, 3 ]
# rename
rename_title = "Rename:"
rename_origin = "hovered"
rename_offset = [ 0, 1, 50, 3 ]
# filter
filter_title = "Filter:"
filter_origin = "top-center"
filter_offset = [ 0, 2, 50, 3 ]
# find
find_title = [ "Find next:", "Find previous:" ]
find_origin = "top-center"
find_offset = [ 0, 2, 50, 3 ]
# search
search_title = "Search via {n}:"
search_origin = "top-center"
search_offset = [ 0, 2, 50, 3 ]
# shell
shell_title = [ "Shell:", "Shell (block):" ]
shell_origin = "top-center"
shell_offset = [ 0, 2, 50, 3 ]
[confirm]
# trash
trash_title = "Trash {n} selected file{s}?"
trash_origin = "center"
trash_offset = [ 0, 0, 70, 20 ]
# delete
delete_title = "Permanently delete {n} selected file{s}?"
delete_origin = "center"
delete_offset = [ 0, 0, 70, 20 ]
# overwrite
overwrite_title = "Overwrite file?"
overwrite_body = "Will overwrite the following file:"
overwrite_origin = "center"
overwrite_offset = [ 0, 0, 50, 15 ]
# quit
quit_title = "Quit?"
quit_body = "The following tasks are still running, are you sure you want to quit?"
quit_origin = "center"
quit_offset = [ 0, 0, 50, 15 ]
[pick]
open_title = "Open with:"
open_origin = "hovered"
open_offset = [ 0, 1, 50, 7 ]
[which]
sort_by = "none"
sort_sensitive = false
sort_reverse = false
sort_translit = false
[flavor]
dark = "dracula"
light = "dracula"

View file

@ -0,0 +1,25 @@
back: mpv playlist-previous ;; echo mpv Skipped
h: help
video: loadpage video
q: quit
watchhistory: loadpage watchhistory
resume: mpv sprop pause no ;; echo mpv Player resumed
search: loadpage search
feed: loadpage feed
x: quit
v: version
exit: quit
channel: loadpage channel
print: echo
playlist: loadpage playlist
popular: loadpage popular
next: mpv playlist-next ;; echo mpv Skipped
bookmarks: loadpage bookmarks
trending: loadpage trending
tpause: mpv tprop pause ;; echo success Toggled player pause
cp: copy
pause: mpv sprop pause yes ;; echo mpv Player paused
rc: reload configs
library: loadpage library
r: reload
sub: sync

View file

@ -0,0 +1,82 @@
global:
' ':
0: tpause ;; echo mpv Player pause toggled
Left:
3: back ;; echo mpv Unskipped
2: mpv seek -5 ;; echo mpv Rewinded 5 seconds
'f':
2: run ${browser} '${url}'
Right:
2: mpv seek 5 ;; echo mpv Fast forwarded 5 seconds
3: next ;; echo mpv Skipped
'c':
2: cp ${url}
'y':
0: cp ${url}
search:
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
'p':
2: parrun mpv '${hover-url}'
popular:
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
'p':
2: parrun mpv '${hover-url}'
trending:
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
'p':
2: parrun mpv '${hover-url}'
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
video: {}
playlist:
'p':
2: parrun mpv '${hover-url}'
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
channel_main: {}
channel_videos:
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
'p':
2: parrun mpv '${hover-url}'
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
channel_playlists:
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
'p':
2: parrun mpv '${hover-url}'
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
watchhistory:
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
'p':
2: parrun mpv '${hover-url}'
feed:
'P':
1: parrun ${terminal-emulator} mpv '${hover-channel-url}/videos' --no-video --loop-playlist=inf --shuffle
'p':
2: parrun mpv '${hover-video-url}'
'A':
1: parrun ${terminal-emulator} mpv '${hover-channel-url}/videos' --no-video --loop-playlist=inf --shuffle
'a':
2: parrun ${terminal-emulator} mpv '${hover-video-url}' --no-video
library:
'a':
2: parrun ${terminal-emulator} mpv '${hover-url}' --no-video
'A':
1: parrun ${terminal-emulator} mpv '${hover-url}' --no-video --loop-playlist=inf --shuffle
'p':
2: parrun mpv '${hover-url}'

View file

@ -0,0 +1,56 @@
launch_command: loadpage library ;; flush ;; history clear ;; key Esc 0 ;; key Up 0 ;; key Up 0 ;; key Left 0 ;; key Enter 0
video:
- Reload updated video: run rm '~/.cache/youtube-tui/info/${id}.json' ;; video ${id}
- Play video: parrun ${video-player} '${embed-url}'
- Play audio: mpv stop ;; resume ;; mpv sprop loop-file no ;; mpv loadfile '${embed-url}' ;; echo mpv Player started
- Play audio (loop): mpv stop ;; resume ;; mpv sprop loop-file inf ;; mpv loadfile '${embed-url}' ;; echo mpv Player started
- View channel: channel ${channel-id}
- Subscribe to channel: sync ${channel-id}
- Open in browser: parrun ${browser} '${url}'
- Toggle bookmark: togglemark ${id}
- Save video to library: bookmark ${id} ;; run rm -rf '${save-path}${id}.*' ;; parrun ${terminal-emulator} ${youtube-downloader} '${embed-url}' -o '${save-path}%(title)s[%(id)s].%(ext)s'
- Save audio to library: bookmark ${id} ;; parrun rm -rf '${save-path}${id}.*' ;; parrun ${terminal-emulator} ${youtube-downloader} '${embed-url}' -x -o '${save-path}%(title)s[%(id)s].%(ext)s'
- 'Mode: ${provider}': switchprovider
saved_video:
- Reload updated video: run rm '~/.cache/youtube-tui/info/${id}.json' ;; video ${id}
- '[Offline] Play saved file': parrun ${video-player} '${offline-path}' --force-window
- '[Offline] Play saved file (audio)': mpv stop ;; resume ;; mpv sprop loop-file no ;; mpv loadfile '${offline-path}' ;; echo mpv Player started
- '[Offline] Play saved file (audio loop)': mpv stop ;; resume ;; mpv sprop loop-file inf ;; mpv loadfile '${offline-path}' ;; echo mpv Player started
- View channel: channel ${channel-id}
- Subscribe to channel: sync ${channel-id}
- Open in browser: parrun ${browser} '${url}'
- Toggle bookmark: togglemark ${id}
- Redownload video to library: bookmark ${id} ;; run rm ${save-path}*${id}*.* ;; parrun ${terminal-emulator} ${youtube-downloader} ${embed-url} -o '${save-path}%(title)s[%(id)s].%(ext)s'
- Redownload audio to library: bookmark ${id} ;; run rm ${save-path}*${id}*.* ;; parrun ${terminal-emulator} ${youtube-downloader} ${embed-url} -x -o '${save-path}%(title)s[%(id)s].%(ext)s'
- Delete saved file: run rm ${save-path}*${id}*.*
playlist:
- Switch view: '%switch-view%'
- Reload updated playlist: run rm ~/.cache/youtube-tui/info/${id}.json ;; reload
- Play all (videos): parrun ${video-player} ${url}
- Play all (audio): mpv stop ;; resume ;; ${mpv-queuelist} ;; mpv sprop loop-playlist no ;; mpv playlist-play-index 0 ;; echo mpv Player started
- Shuffle play all (audio loop): mpv stop ;; resume ;; ${mpv-queuelist} ;; mpv sprop loop-playlist yes ;; mpv playlist-shuffle ;; mpv playlist-play-index 0 ;; echo mpv Player started
- View channel: channel ${channel-id}
- Subscribe to channel: sync ${channel-id}
- Open in browser: parrun ${browser} '${url}'
- Toggle bookmark: togglemark ${id}
- Save playlist videos to library: bookmark ${id} ;; run rm -rf '${save-path}*${id}*' ;; parrun ${terminal-emulator} bash -c "${youtube-downloader} ${all-videos} -o '"'${save-path}${title}[${id}]/%(title)s[%(id)s].%(ext)s'"'"
- Save playlist audio to library: bookmark ${id} ;; run rm -rf '${save-path}*${id}*' ;; parrun ${terminal-emulator} bash -c "${youtube-downloader} ${all-videos} -x -o '"'${save-path}${title}[${id}]/%(title)s[%(id)s].%(ext)s'"'"
- 'Mode: ${provider}': switchprovider
saved_playlist:
- Switch view: '%switch-view%'
- Reload updated playlist: run rm ~/.cache/youtube-tui/info/${id}.json ;; reload
- '[Offline] Play all (videos)': parrun ${video-player} ${save-path}*${id}*/* --force-window
- '[Offline] Play all (audio)': mpv stop ;; resume ;; ${offline-queuelist} ;; mpv sprop loop-playlist no ;; mpv playlist-play-index 0 ;; echo mpv Player started
- '[Offline] Shuffle play all (audio loop)': mpv stop ;; resume ;; ${offline-queuelist} ;; mpv sprop loop-playlist yes ;; mpv playlist-shuffle ;; mpv playlist-play-index 0 ;; echo mpv Player started
- View channel: channel ${channel-id}
- Subscribe to channel: sync ${channel-id}
- Open in browser: parrun ${browser} '${url}'
- Toggle bookmark: togglemark ${id}
- Redownload playlist videos to library: bookmark ${id} ;; run rm -rf ${save-path}*${id}* ;; parrun ${terminal-emulator} bash -c "${youtube-downloader} ${all-videos} -o '"'${save-path}${title}[${id}]/%(title)s[%(id)s].%(ext)s'"'"
- Redownload playlist audio to library: bookmark ${id} ;; run rm -rf ${save-path}*${id}* ;; parrun ${terminal-emulator} bash -c "${youtube-downloader} ${all-videos} -x -o '"'${save-path}${title}[${id}]/%(title)s[%(id)s].%(ext)s'"'"
- Delete saved files: run rm -rf ${save-path}*${id}*
channel:
- Subscribe to channel: sync ${id}
- Play all (videos): parrun ${video-player} ${url}
- Play all (audio): mpv stop ;; resume ;; mpv loadfile ${url} ;; mpv sprop loop-playlist no ;; mpv playlist-play-index 0 ;; echo mpv Player started
- Shuffle play all (audio loop): mpv stop ;; resume ;; mpv loadfile ${url} ;; mpv sprop loop-playlist yes ;; mpv playlist-shuffle ;; mpv playlist-play-index 0 ;; echo mpv Player started

View file

@ -0,0 +1,52 @@
Up:
0: MoveUp
2: PreviousEntry
':':
0: StartCommandCapture
Right:
0: MoveRight
2: NextWord
Enter:
0: Select
F5:
0: Reload
Esc:
0: Deselect
'j':
0: MoveDown
'r':
2: Reload
'd':
0: ClearHistory
4: RemoveWord
'u':
2: ClearLine
'e':
2: End
Left:
2: PreviousWord
0: MoveLeft
4: Back
'q':
0: Exit
Down:
0: MoveDown
2: NextEntry
'k':
0: MoveUp
'v':
2: Paste
Backspace:
0: Back
'l':
0: MoveRight
Home:
0: FirstHistory
End:
0: ClearHistory
'h':
0: MoveLeft
'w':
2: RemoveWord
'a':
2: First

View file

@ -0,0 +1,30 @@
mouse_support: true
invidious_instance: https://invidious.f5.si
write_config: Try
allow_unicode: true
message_bar_default: All good :)
images: Sixels
refresh_after_modifying_search_filters: true
syncing:
download_images: true
sync_channel_info: true
sync_channel_cooldown_secs: 86400
sync_videos_cooldown_secs: 600
limits:
watch_history: 50
search_history: 75
commands_history: 75
textbar_scroll_behaviour: History
image_index: 4
provider: YouTube
search_provider: RustyPipe
api_key: YOUR API KEY HERE
shell: sh
legacy_input_handling: false
env:
terminal-emulator: konsole -e
youtube-downloader: yt-dlp
save-path: ~/.local/share/youtube-tui/saved/
download-path: ~/Downloads/%(title)s-%(id)s.%(ext)s
video-player: mpv
browser: xdg-open

View file

@ -0,0 +1,88 @@
main_menu:
layout:
- type: NonCenteredRow
items:
- SearchBar
- SearchFilters
- type: CenteredRow
items:
- Library
- Feed
- History
- type: NonCenteredRow
items:
- ItemList
- type: NonCenteredRow
items:
- MessageBar
message: Loading main menu...
command: key Esc 0 ;; key Down 0 ;; key Down 0 ;; key Enter 0
feed:
layout:
- type: NonCenteredRow
items:
- SearchBar
- SearchFilters
- type: CenteredRow
items:
- Library
- Feed
- History
- type: NonCenteredRow
items:
- ChannelList
- type: NonCenteredRow
items:
- VideoList
- type: NonCenteredRow
items:
- MessageBar
message: Loading feed...
command: key Esc 0 ;; key Down 0 ;; key Down 0 ;; key Enter 0
search:
layout:
- type: NonCenteredRow
items:
- SearchBar
- SearchFilters
- type: NonCenteredRow
items:
- ItemList
- type: NonCenteredRow
items:
- MessageBar
message: Loading search results...
command: key Esc 0 ;; key Down 0 ;; key Enter 0
singleitem:
layout:
- type: NonCenteredRow
items:
- SearchBar
- SearchFilters
- type: NonCenteredRow
items:
- SingleItemInfo
- type: NonCenteredRow
items:
- MessageBar
message: Loading item details...
command: key Esc 0 ;; key Down 0 ;; key Enter 0
channeldisplay:
layout:
- type: NonCenteredRow
items:
- SearchBar
- SearchFilters
- type: CenteredRow
items:
- ChannelMain
- ChannelVideos
- ChannelPlaylists
- type: NonCenteredRow
items:
- ChannelDisplay
- type: NonCenteredRow
items:
- MessageBar
message: Loading channel details...
command: key Esc 0 ;; key Down 0 ;; key Enter 0 ;; key Up 0

View file

@ -0,0 +1,4 @@
'a':
5:
code: 'b'
modifiers: 5

View file

@ -0,0 +1,7 @@
query: ''
filters:
sort: Relevance
date: None
duration: None
type: All
page: 1