Compare commits

...

29 Commits

Author SHA1 Message Date
3218ceada1 move config 2026-02-04 02:35:42 -08:00
dca8f0df32 update 2026-02-04 02:14:03 -08:00
da80481d63 update symlink 2026-02-03 17:19:03 -08:00
e6c89cf38b update 2026-02-03 17:13:42 -08:00
35357f1674 update scripts 2026-02-03 17:13:21 -08:00
bd6eefe084 change to jsonc 2026-02-03 17:13:20 -08:00
4eda790932 update 2026-02-03 15:14:29 -08:00
d57275597d update 2026-02-03 10:29:34 -08:00
75a9cc360c update 2026-02-03 10:23:20 -08:00
5b9cbbba99 add config 2026-02-03 03:09:03 -08:00
c867434c8d update 2026-02-02 23:07:36 -08:00
63cd7242b6 update 2026-02-02 18:35:52 -08:00
7f28515e8d update 2026-02-02 18:35:24 -08:00
suda@sudacode.com
88f0d9938c update 2026-02-02 08:40:51 -08:00
suda@sudacode.com
7957d0b57c split version 2026-02-02 08:40:26 -08:00
7d47044e5c update 2026-02-02 02:57:29 -08:00
baa897573e udpate 2026-02-02 02:56:45 -08:00
6ce0155364 remove immersion tracker 2026-02-02 01:38:25 -08:00
d32f79f406 update 2026-02-01 23:09:36 -08:00
f301f16949 update 2026-02-01 23:09:20 -08:00
cf14d30091 add mpv-yomitan config 2026-02-01 23:07:49 -08:00
b238daee8c add linux websocket 2026-02-01 20:36:14 -08:00
61c4425c6e remove linux websocket 2026-02-01 16:37:48 -08:00
15d55786f3 update mpv config 2026-02-01 15:06:45 -08:00
e9e6dfa2d3 update 2026-02-01 12:20:52 -08:00
fb7b605e55 add windows version 2026-01-29 23:59:06 -08:00
84185b8dc6 update 2026-01-29 23:52:14 -08:00
063a3aaf9b add windows version 2026-01-29 23:51:34 -08:00
2b53dd6ee1 add windows version? 2026-01-29 23:44:18 -08:00
42 changed files with 804 additions and 192 deletions

View File

@@ -16,7 +16,7 @@
"hooks": [
{
"type": "command",
"command": "powershell.exe -WindowStyle Hidden -Command \"& { Add-Type -AssemblyName System.Windows.Forms; $balloon = New-Object System.Windows.Forms.NotifyIcon; $balloon.Icon = [System.Drawing.SystemIcons]::Information; $balloon.BalloonTipIcon = 'Info'; $balloon.BalloonTipTitle = 'Claude Code'; $balloon.BalloonTipText = 'Awaiting your input'; $balloon.Visible = $true; $balloon.ShowBalloonTip(5000); Start-Sleep -Seconds 5; $balloon.Dispose() }\""
"command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
}
]
}
@@ -28,7 +28,7 @@
"clangd-lsp@claude-plugins-official": true
},
"sandbox": {
"enabled": true,
"enabled": false,
"autoAllowBashIfSandboxed": true,
"network": {
"allowUnixSockets": [

View File

@@ -0,0 +1,43 @@
{
"attribution": {
"commit": "",
"pr": ""
},
"permissions": {
"deny": [
"Read(.env)",
"Read(~/.aws/**)"
]
},
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
}
]
}
]
},
"enabledPlugins": {
"pyright-lsp@claude-plugins-official": true,
"typescript-lsp@claude-plugins-official": true,
"clangd-lsp@claude-plugins-official": true
},
"sandbox": {
"enabled": false,
"autoAllowBashIfSandboxed": true,
"network": {
"allowUnixSockets": [
"/var/run/docker.sock"
],
"allowLocalBinding": true
},
"excludedCommands": [
"docker"
]
}
}

View File

@@ -0,0 +1,44 @@
{
"attribution": {
"commit": "",
"pr": ""
},
"permissions": {
"deny": [
"Read(.env)",
"Read(~/.aws/**)"
]
},
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
}
]
}
]
},
"enabledPlugins": {
"pyright-lsp@claude-plugins-official": true,
"typescript-lsp@claude-plugins-official": true,
"clangd-lsp@claude-plugins-official": true
},
"sandbox": {
"enabled": false,
"autoAllowBashIfSandboxed": true,
"network": {
"allowUnixSockets": [
"/var/run/docker.sock"
],
"allowLocalBinding": true
},
"excludedCommands": [
"docker"
]
},
"model": "haiku"
}

View File

@@ -2,7 +2,7 @@
#* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes.
#* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes"
color_theme = "/home/kyasuda/.config/btop/themes/catppuccin_macchiato.theme"
color_theme = "TTY"
#* If the theme set background should be shown, set to False if you want terminal background transparency.
theme_background = true

View File

@@ -17,7 +17,10 @@ app-notifications = no-clipboard-copy
shell-integration = zsh
shell-integration-features = title,sudo
desktop-notifications = true
term=ghostty
term=xterm-ghostty
link-url = true
link-previews = true
bell-features=system,attention,no-audio
keybind = all:ctrl+enter=unbind
keybind = all:ctrl+shift+j=next_tab
keybind = all:ctrl+shift+k=last_tab

View File

@@ -191,13 +191,15 @@ animations {
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
dwindle {
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true # You probably want this
pseudotile = false # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = true
split_width_multiplier = 1.69
}
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
master {
new_status = master
new_status = slave
allow_small_split = false
}
# https://wiki.hyprland.org/Configuring/Variables/#misc

View File

@@ -32,7 +32,7 @@ bind = $mainMod SHIFT, j, movewindow, d
bind = $mainMod SHIFT, k, movewindow, u
bind = $mainMod SHIFT, h, movewindow, l
bind = $mainMod SHIFT, l, movewindow, r
bind = CTRL+SHIFT, c, centerwindow
bind = $mainMod+SHIFT, c, centerwindow
# Move focus to next monitor
@@ -92,7 +92,7 @@ bindl = , XF86AudioPrev, exec, mpc prev
# rofi
bind = $mainMod SHIFT, v, exec, uwsm app -sb -- rofi-rbw
bind = $mainMod, w, exec, rofi -show window -theme $HOME/.config/rofi/launchers/type-2/style-2.rasi -dpi 96 -theme-str 'window {width: 35%;}'
# bind = $mainMod, w, exec, rofi -show window -theme $HOME/.config/rofi/launchers/type-2/style-2.rasi -dpi 96 -theme-str 'window {width: 35%;}'
bind = $mainMod SHIFT, w, exec, "$HOME/.config/rofi/scripts/rofi-wallpaper.sh"
bind = $mainMod SHIFT, d, exec, "$HOME/.config/rofi/scripts/rofi-docs.sh"
bind = SUPER, j, exec, "$HOME/.config/rofi/scripts/rofi-jellyfin-dir.sh"
@@ -146,4 +146,10 @@ bind = SUPER, l, exec, hyprlock
# ANKI
bind = $mainMod, a, exec, ~/.config/rofi/scripts/rofi-anki-script.sh
bind = $mainMod SHIFT, a, exec, ~/projects/scripts/screenshot-anki.sh -cdMinecraft
# bind = $mainMod SHIFT, a, exec, ~/projects/scripts/screenshot-anki.sh -cdMinecraft
# GSM
bindl = , mouse:275, exec, xdotool key alt+w # top mouse to texthooker
bindl = , mouse:276, exec, xdotool key alt+grave # bottom mouse to overlay
bind = ALT, g, exec, /opt/mpv-yomitan/mpv-yomitan.AppImage --toggle
# bind = ALT SHIFT, Y, exec, "$HOME/.config/rofi/scripts/rofi-mpv-yomitan.sh"

View File

@@ -225,7 +225,8 @@ ctrl+B ignore # script-binding mpvacious-overwrite-selected-note
ctrl+m ignore # script-binding mpvacious-update-last-note
ctrl+M ignore # script-binding mpvacious-overwrite-last-note
G script-binding mpvacious-quick-card-menu-open
alt+g script-binding mpvacious-quick-card-sel-menu-open
alt+g ignore
alt+G script-binding mpvacious-quick-card-sel-menu-open
ctrl+c script-binding mpvacious-copy-primary-sub-to-clipboard
ctrl+C script-binding mpvacious-copy-secondary-sub-to-clipboard
ctrl+= script-binding mpvacious-autocopy-toggle

View File

@@ -25,7 +25,7 @@ sub-fix-timing=yes
sub-ass-override=scale
sub-gauss=1.0
sub-gray=yes
sub-pos=100
sub-pos=95
# --- Audio chain ---
volume=75
@@ -111,6 +111,8 @@ demuxer-max-back-bytes=200MiB # Keep recent data handy for quick reverse seeks
cache-secs=30
demuxer-readahead-secs=30
msg-level=subs2srs,animecards,mpvacious=error
[anime]
profile-desc="Anime upscaling with ArtCNN"
glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
@@ -163,6 +165,7 @@ glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
scale=ewa_lanczossharp
dither=error-diffusion
deband=yes # Crucial for anime gradients
input-ipc-server=/tmp/mpv-yomitan-socket
[anime-subs]
profile-cond=p["slang"] == "ja" or p["slang"] == "ja.hi"

View File

@@ -8,7 +8,7 @@ dither=fruit # Lightweight dithering
ontop=yes
border=no
no-border
autofit=50% # Reasonable default size
autofit=69% # Reasonable default size
# Audio (macOS-specific)
volume=75
@@ -129,6 +129,9 @@ cache-pause=no
cache-secs=30
demuxer-readahead-secs=30
msg-level=subs2srs,animecards,mpvacious=error
############
# Profiles #
############
@@ -152,7 +155,7 @@ profile-cond=width >= 1920 and filename:match("mkv$|mp4$")
glsl-shaders=""
scale=ewa_lanczos
target-peak=800
hdr-tone-mapping=bt.2390
# hdr-tone-mapping=bt.2390
# HDR profile
[hdr]
@@ -195,6 +198,7 @@ glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
scale=ewa_lanczossharp
dither=error-diffusion
deband=yes # Crucial for anime gradients
input-ipc-server=/tmp/mpv-yomitan-socket
# Anime subtitles profile
[anime-subs]

View File

@@ -0,0 +1,176 @@
profile=high-quality
user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
# --- Shaders ---
glsl-shaders=""
# glsl-shaders="~~/shaders/ArtCNN_C4F32_DS.glsl"
# glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
# --- Scaling & dithering ---
scale=spline36
dither=fruit
# --- Window & interface ---
ontop=yes
border=no
no-border
autofit=50%
osc=no
blend-subtitles=video
opengl-early-flush=no
# --- Subtitle defaults ---
sub-font="JetBrainsMono Nerd Font"
sub-font-size=45
sub-auto=fuzzy
slang=en,eng
subs-with-matching-audio=no
sub-fix-timing=yes
sub-ass-override=scale
sub-gauss=1.0
sub-gray=yes
sub-pos=100
# --- Audio (Windows) ---
volume=75
ao=wasapi
audio-spdif=ac3,dts-hd,truehd
audio-stream-silence=yes
audio-wait-open=0.1
# --- Networking ---
ytdl-format=bestvideo+bestaudio/best
ytdl-raw-options=sub-langs=en.*,write-auto-subs=
ytdl-raw-options-append=sponsorblock-mark=all
ytdl-raw-options-append=sponsorblock-remove=sponsor,selfpromo,interaction
# --- Video output & decoding ---
vo=gpu-next
hwdec=nvdec
hwdec-codecs=all
gpu-api=vulkan
gpu-context=winvk
vulkan-queue-count=2
vulkan-async-compute=yes
vulkan-async-transfer=yes
vd-lavc-dr=yes
vd-lavc-threads=0
video-sync=display-resample
# --- Scaling, interpolation, dithering ---
scale=ewa_lanczossharp
dscale=catmull_rom
cscale=ewa_lanczos
tscale=oversample
interpolation=yes
interpolation-preserve=no
interpolation-threshold=0.5
sigmoid-upscaling=yes
temporal-dither=yes
dither=error-diffusion
dither-depth=auto
error-diffusion=sierra-lite
# --- Antiring ---
scale-antiring=0.5
dscale-antiring=0.5
cscale-antiring=0.5
# --- Debanding ---
deband=yes
deband-iterations=2
deband-threshold=24
deband-range=16
deband-grain=4
# --- IPC (Windows named pipe) ---
input-ipc-server=\\.\pipe\mpv-socket
# --- Screenshots ---
screenshot-format=webp
screenshot-webp-lossless=yes
screenshot-high-bit-depth=yes
screenshot-sw=no
screenshot-directory="Z:/sudacode/pictures/mpv"
screenshot-template="%f-%wH.%wM.%wS.%wT-#%#00n"
# --- Session persistence ---
save-position-on-quit
watch-later-dir="~~/.watch-later"
resume-playback=yes
save-watch-history
watch-history-path="~~/state/watch_history.jsonl"
# --- HDR hints ---
target-colorspace-hint=yes
# --- Cache ---
cache=yes
demuxer-max-bytes=1GiB
demuxer-max-back-bytes=200MiB
cache-secs=30
demuxer-readahead-secs=30
# =========================
# Profiles
# =========================
[anime]
profile-desc="Anime upscaling with ArtCNN"
glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
scale=ewa_lanczossharp
dither=error-diffusion
deband=yes
[movies]
profile-desc="Movies and TV shows"
profile-cond=width >= 1920 and filename:match("mkv$|mp4$")
glsl-shaders=""
scale=ewa_lanczos
target-peak=800
[hdr]
tone-mapping-param=0.5
tone-mapping-max-boost=2.0
allow-delayed-peak-detect=yes
icc-profile-auto=yes
[svp]
interpolation=no
input-ipc-server=\\.\pipe\mpv-socket
hr-seek-framedrop=no
resume-playback=no
[Idle]
profile-cond=p["idle-active"]
profile-restore=copy-equal
title=' '
keepaspect=no
[immersion]
cookies=yes
cookies-file="Z:/sudacode/japanese/cookies.Japanese.txt"
ytdl-raw-options=mark-watched=,write-auto-subs=,sub-langs=ja.*
ytdl-raw-options-append=cookies=Z:/sudacode/japanese/cookies.Japanese.txt
ytdl-raw-options-append=sponsorblock-mark=all
ytdl-raw-options-append=sponsorblock-remove=sponsor,selfpromo,interaction
sub-auto=fuzzy
alang=ja,jp,jpn,japanese,en,eng,english
slang=ja,jp,jpn,japanese,en,eng,english
vlang=ja,jpn
subs-with-matching-audio=yes
sub-font="Noto Sans CJK JP Regular"
glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
scale=ewa_lanczossharp
dither=error-diffusion
deband=yes
[anime-subs]
profile-cond=p["slang"] == "ja" or p["slang"] == "ja.hi"
sub-font="Noto Sans CJK JP Regular"
sub-font-size=42
sub-border-size=1.2
sub-shadow-color=0.0/0.0/0.0/0.6
sub-shadow-offset=3
sub-hinting=light

Binary file not shown.

View File

@@ -0,0 +1,11 @@
# Use 'yes' or 'no' for boolean options below
# Example for multiple directories (comma or semicolon separated):
# DIRECTORIES=D:/Torrents,D:/Anime
# or
# DIRECTORIES=D:/Torrents;D:/Anime
DIRECTORIES=/mnt/j/anime
UPDATE_PERCENTAGE=85
SET_COMPLETED_TO_REWATCHING_ON_FIRST_EPISODE=no
UPDATE_PROGRESS_WHEN_REWATCHING=yes
SET_TO_COMPLETED_AFTER_LAST_EPISODE_CURRENT=yes
SET_TO_COMPLETED_AFTER_LAST_EPISODE_REWATCHING=yes

View File

@@ -8,6 +8,7 @@
# Anki Field Names
# These must match the field names in your Anki note type
# =================================================
DEBUG_MODE=no
FRONT_FIELD=Expression
SENTENCE_FIELD=Sentence
IMAGE_FIELD=Picture
@@ -28,12 +29,12 @@ ASK_TO_OVERWRITE=yes
OVERWRITE_LIMIT=8
# Keep bold formatting added by yomitan? (yes/no)
HIGHLIGHT_WORD=no
HIGHLIGHT_WORD=yes
# Use MPV's built-in clipboard API (requires v0.40+)? (yes/no)
# Alternative clipboard method that may reduce latency on Windows.
# Supported on macOS and Wayland as well. Not supported on X11.
USE_MPV_CLIPBOARD_API=no
USE_MPV_CLIPBOARD_API=yes
# ==========================================================
# Audio Settings

View File

@@ -0,0 +1,33 @@
# Absolute paths to the executables, if needed:
# 1. ffmpeg
ffmpeg_path=/usr/bin/ffmpeg
# 2. ffsubsync
ffsubsync_path=/usr/bin/ffsubsync
# 3. alass
alass_path=/usr/bin/alass
# Preferred retiming tool. Allowed options: 'ffsubsync', 'alass', 'ask'.
# If set to 'ask', the add-on will ask to choose the tool every time:
# 1. Preferred tool for syncing to audio.
# audio_subsync_tool=ask
audio_subsync_tool=ffsubsync
# audio_subsync_tool=alass
# 2. Preferred tool for syncing to another subtitle.
# altsub_subsync_tool=ask
# altsub_subsync_tool=ffsubsync
altsub_subsync_tool=alass
# Unload old subs (yes,no)
# After retiming, tell mpv to forget the original subtitle track.
unload_old_sub=yes
# unload_old_sub=no
# Overwrite the original subtitle file.
# Replace the old subtitle file with the retimed file.
# overwrite_old_sub=yes
overwrite_old_sub=no

View File

@@ -1,6 +1,6 @@
start_tracking_key=ctrl+t
data_dir=/home/sudacode/.config/mpv/scripts/immersion-tracker/data
csv_file=/truenas/sudacode/japanese/immersion_tracker.csv
csv_file=/mnt/h/japanese/immersion_tracker.csv
session_file=/home/sudacode/.config/mpv/scripts/immersion-tracker/data/current_session.json
min_session_duration=30
save_interval=10

View File

@@ -0,0 +1,22 @@
start_tracking_key=ctrl+t
data_dir=/home/sudacode/.config/mpv/scripts/immersion-tracker/data
csv_file=/truenas/sudacode/japanese/immersion_tracker.csv
session_file=/home/sudacode/.config/mpv/scripts/immersion-tracker/data/current_session.json
min_session_duration=30
save_interval=10
enable_debug_logging=no
backup_sessions=no
max_backup_files=10
use_title=yes
use_filename=no
custom_prefix=[Immersion]
max_title_length = 100
export_csv=yes
export_json=no
export_html=no
backup_csv=yes
show_session_start=yes
show_session_end=yes
show_progress_milestones=no
milestone_percentages=25507590

View File

@@ -30,6 +30,6 @@ menu_timeout=5
show_errors=yes
ytdlp_file_format=mp4
ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s
use_history_db=yes
use_history_db=no
backend_host=http://localhost
backend_port=42069

View File

@@ -0,0 +1,35 @@
add_to_queue=ctrl+a
default_save_method=unwatched
download_current_video=ctrl+d
download_selected_video=ctrl+D
move_cursor_down=ctrl+j
move_cursor_up=ctrl+k
load_queue=ctrl+l
move_video=ctrl+m
play_next_in_queue=ctrl+n
open_video_in_browser=ctrl+o
open_channel_in_browser=ctrl+O
play_previous_in_queue=ctrl+p
print_current_video=ctrl+P
print_queue=ctrl+q
save_queue=ctrl+s
save_full_queue=ctrl+S
remove_from_queue=ctrl+x
play_selected_video=ctrl+ENTER
browser=zen-browser
clipboard_command=powershell -command Get-Clipboard
cursor_icon=➤
display_limit=10
download_directory=~/videos/YouTube
download_quality=1080p
downloader=curl
font_name=JetBrainsMono NF
font_size=12
marked_icon=⇅
menu_timeout=5
show_errors=yes
ytdlp_file_format=mp4
ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s
use_history_db=yes
backend_host=http://localhost
backend_port=42069

View File

@@ -46,6 +46,9 @@ menu_font_name=Noto Serif CJK JP
# Change this if you have changed webBindAddress in AnkiConnect's settings.
ankiconnect_url=127.0.0.1:8765
# AnkiConnect server api key (optional)
#ankiconnect_api_key=
##
## Toggleables.
## Possible values: `yes` or `no`.
@@ -330,3 +333,40 @@ ffmpeg_audio_args=-af loudnorm=I=-16:TP=-1.5:LRA=11:dual_mono=true
mpv_audio_args=--af-append=loudnorm=I=-16:TP=-1.5:LRA=11:dual_mono=true
#mpv_audio_args=
#mpv_audio_args=--af-append=silenceremove=1:0:-50dB
##
## Custom Sub Filter
## Place a `subs2srs_sub_filter.lua` file
## in the `~/.config/mpv/subs2srs_sub_filter` directory.
## The custom script must return a table
## that includes either of a `preprocess` or a `trim` function (or both).
##
## - `preprocess(text)`: Executes before trimming/cleaning.
## - `trim(text)`: Replaces the built-in trimming logic.
##
# Enable custom sub preprocessing by default (yes, no)
custom_sub_filter_enabled=no
# Notification prefix for toggle
custom_sub_filter_notification=Custom Sub Filter
# Use a custom trim instead of the built in one (yes, no)
use_custom_trim=no
##
## New note check timer
##
# Enable the check note timer feature.
# If set to `yes`, mpvacious will periodically check for new notes in Anki
# and automatically update them with media if they match the configured note type
# I.e., you create a note with GoldenDict, Rikaitan, etc.,
# then mpvacious updates the note and adds audio and image automatically.
enable_new_note_timer=no
# Interval in seconds for checking for new notes.
# This setting controls how often mpvacious checks for new notes in Anki.
# Only used when enable_new_note_timer is set to `yes`
new_note_timer_interval_seconds=5

View File

@@ -1 +0,0 @@
../../submodules/mpv-anilist-updater/anilistUpdater/anilistUpdater.py

View File

@@ -1 +0,0 @@
../../submodules/mpv-anilist-updater/anilistUpdater/main.lua

View File

@@ -1 +0,0 @@
../submodules/immersion-tracker

View File

@@ -1 +1 @@
../submodules/mpv-youtube-queue/mpv-youtube-queue.lua
../../mpv-modules/mpv-youtube-queue/mpv-youtube-queue.lua

View File

@@ -1,6 +1,8 @@
-- mpv_websocket
-- https://github.com/kuroahna/mpv_websocket
local use_secondary_subs = false
local utils = require("mp.utils")
local platform = mp.get_property_native("platform")
@@ -8,76 +10,101 @@ local platform = mp.get_property_native("platform")
local config_file_path = mp.find_config_file("mpv.conf")
local config_folder_path, config_file = utils.split_path(config_file_path)
local mpv_websocket_path =
utils.join_path(config_folder_path, platform == "windows" and "mpv_websocket.exe" or "mpv_websocket")
utils.join_path(config_folder_path, platform == "windows" and "mpv_websocket.exe" or "mpv_websocket")
local initialised_websocket
local _, err = utils.file_info(config_file_path)
if err then
error("failed to open mpv config file `" .. config_file_path .. "`")
error("failed to open mpv config file `" .. config_file_path .. "`")
end
local _, err = utils.file_info(mpv_websocket_path)
if err then
error("failed to open mpv_websocket")
error("failed to open mpv_websocket")
end
local function find_mpv_socket(config_file_path)
local file = io.open(config_file_path, "r")
if file == nil then
error("failed to read mpv config file `" .. config_file_path .. "`")
end
-- First, try to get from mpv properties (includes command-line options)
local mpv_socket = mp.get_property("input-ipc-server")
if mpv_socket and mpv_socket ~= "" then
return mpv_socket
end
local mpv_socket
for line in file:lines() do
mpv_socket = line:match("^input%-ipc%-server%s*=%s*(%g+)%s*")
if mpv_socket then
break
end
end
-- Fall back to reading config file
local file = io.open(config_file_path, "r")
if file == nil then
error("failed to read mpv config file `" .. config_file_path .. "`")
end
file:close()
for line in file:lines() do
mpv_socket = line:match("^input%-ipc%-server%s*=%s*(%g+)%s*")
if mpv_socket then
break
end
end
if not mpv_socket then
error("input-ipc-server option does not exist in `" .. config_file_path .. "`")
end
file:close()
return mpv_socket
if not mpv_socket then
error("input-ipc-server option does not exist in `" .. config_file_path .. "`")
end
return mpv_socket
end
local mpv_socket = find_mpv_socket(config_file_path)
if platform == "windows" then
mpv_socket = "\\\\.\\pipe" .. mpv_socket:gsub("/", "\\")
mpv_socket = "\\\\.\\pipe" .. mpv_socket:gsub("/", "\\")
end
local function start_websocket()
initialised_websocket = mp.command_native_async({
name = "subprocess",
playback_only = false,
capture_stdout = true,
capture_stderr = true,
args = {
mpv_websocket_path,
"-m",
mpv_socket,
"-w",
"6677",
},
})
local args = {
mpv_websocket_path,
"-m",
mpv_socket,
"-w",
"6677",
}
if use_secondary_subs then
table.insert(args, "-s")
end
initialised_websocket = mp.command_native_async({
name = "subprocess",
playback_only = false,
capture_stdout = true,
capture_stderr = true,
args = args,
})
end
local function end_websocket()
mp.abort_async_command(initialised_websocket)
initialised_websocket = nil
mp.abort_async_command(initialised_websocket)
initialised_websocket = nil
end
local function toggle_websocket()
local paused = mp.get_property_bool("pause")
if initialised_websocket and paused then
end_websocket()
elseif not initialised_websocket and not paused then
start_websocket()
end
local paused = mp.get_property_bool("pause")
if initialised_websocket and paused then
end_websocket()
elseif not initialised_websocket and not paused then
start_websocket()
end
end
local function toggle_subs_type()
if use_secondary_subs then
use_secondary_subs = false
else
use_secondary_subs = true
end
if initialised_websocket then
end_websocket()
start_websocket()
end
end
mp.register_script_message("togglewebsocket", toggle_websocket)
mp.register_script_message("togglesubstype", toggle_subs_type)
start_websocket()

View File

@@ -1,17 +1,17 @@
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end
vim.opt.rtp:prepend(lazypath)

View File

@@ -1,12 +1,35 @@
@import "catppuccin-macchiato.rasi"
configuration {
show-icons: true;
icon-theme: "Dracula";
dpi: 144;
}
// @import "catppuccin-latte"
// @import "catppuccin-frappe"
// @import "catppuccin-macchiato"
// @import "catppuccin-mocha"
* {
rosewater: #f4dbd6;
flamingo: #f0c6c6;
pink: #f5bde6;
mauve: #c6a0f6;
red: #ed8796;
maroon: #ee99a0;
peach: #f5a97f;
yellow: #eed49f;
green: #a6da95;
teal: #8bd5ca;
sky: #91d7e3;
sapphire: #7dc4e4;
blue: #8aadf4;
lavender: #b7bdf8;
text: #cad3f5;
subtext1: #b8c0e0;
subtext0: #a5adcb;
overlay2: #939ab7;
overlay1: #8087a2;
overlay0: #6e738d;
surface2: #5b6078;
surface1: #494d64;
surface0: #363a4f;
base: #24273a;
mantle: #1e2030;
crust: #181926;
selected-active-foreground: @background;
lightfg: @text;
separatorcolor: @foreground;
@@ -35,6 +58,11 @@ configuration {
alternate-active-foreground: @blue;
}
configuration {
show-icons: true;
icon-theme: "Dracula";
dpi: 144;
}
element {
padding: 1px ;
cursor: pointer;
@@ -90,12 +118,6 @@ element-icon {
text-color: inherit;
}
window {
border: 4;
padding: 12px;
border-radius: 12px;
anchor: center;
location: center;
padding: 5;
background-color: @background;
border: 1;
@@ -180,4 +202,3 @@ textbox-prompt-colon {
str: ":";
text-color: inherit;
}

View File

@@ -30,6 +30,7 @@ configuration {
show-icons: true;
icon-theme: "Dracula";
dpi: 144;
modes: "window,run,ssh,drun,filebrowser";
}
#window {

View File

@@ -49,7 +49,7 @@ mainbox {
border-radius: 0px 0px 0px 0px;
border-color: @selected;
background-color: transparent;
children: [ "inputbar", "listview" ];
children: [ "inputbar", "listview-split" ];
}
/*****----- Inputbar -----*****/
@@ -110,6 +110,18 @@ listview {
text-color: @foreground;
cursor: "default";
}
listview-split {
orientation: horizontal;
children: [listview, icon-current-entry];
spacing: 1em;
background-color: @background;
}
icon-current-entry {
expand: true;
size: 40%;
background-color: transparent;
border-radius: 8px;
}
scrollbar {
handle-width: 5px ;
handle-color: @selected;
@@ -173,3 +185,10 @@ textbox {
horizontal-align: 0.0;
highlight: none;
}
scrollbar {
width: 4px;
handle-color: @surface2;
handle-width: 4px;
background-color: @surface0;
}

View File

@@ -4,7 +4,7 @@ set -Eeuo pipefail
THEME="$HOME/.config/rofi/launchers/type-3/style-4.rasi"
DIR="$HOME/Pictures/wallpapers/favorites"
SELECTED_WALL=$(cd "$DIR" && for a in *.jpg *.png; do echo -en "$a\0icon\x1f$a\n"; done | rofi -dmenu -i -no-custom -theme "$THEME" -p "Select a wallpaper" -theme-str 'configuration {icon-size: 128; dpi: 96;} window {width: 45%; height: 45%;}')
SELECTED_WALL=$(cd "$DIR" && for a in *.jpg *.png; do echo -en "$a\0icon\x1f$a\n"; done | rofi -dmenu -i -no-custom -theme "$THEME" -p "Select a wallpaper" -theme-str 'configuration {icon-size: 256; dpi: 96;} window {width: 75%; height: 69%;} listview {rows: 5; lines: 7;}')
PTH="$(printf "%s" "$DIR/$SELECTED_WALL" | tr -s '/')"
hyprctl hyprpaper wallpaper "DP-1, $PTH"
notify-send -a "rofi-wallpaper" "Wallpaper set to" -i "$PTH" "$PTH"

View File

@@ -0,0 +1,129 @@
{
"subtitlePosition": {
"yPercent": 17.38459152016546
},
"keybindings": [
{
"key": "Space",
"command": [
"cycle",
"pause"
]
},
{
"key": "ArrowRight",
"command": [
"seek",
5
]
},
{
"key": "ArrowLeft",
"command": [
"seek",
-5
]
},
{
"key": "ArrowRight",
"command": [
"seek",
5
]
},
{
"key": "ArrowUp",
"command": [
"seek",
60
]
},
{
"key": "ArrowDown",
"command": [
"seek",
-60
]
},
{
"key": "KeyQ",
"command": [
"quit"
]
},
{
"key": "Ctrl+KeyW",
"command": [
"quit"
]
}
],
"texthooker": {
"openBrowser": false
},
"websocket": {
"enabled": "auto",
"port": 6677
},
"ankiConnect": {
"enabled": true,
"url": "http://127.0.0.1:8765",
"deck": "Minecraft",
"pollingRate": 200,
"audioField": "ExpressionAudio",
"imageField": "Picture",
"sentenceField": "Sentence",
"generateAudio": true,
"generateImage": true,
"imageType": "avif",
"imageFormat": "webp",
"miscInfoPattern": "[mpv-yomitan] %f (%t)",
"overwriteAudio": false,
"overwriteImage": true,
"highlightWord": true,
"showNotificationOnUpdate": true,
"notificationType": "system",
"audioPadding": 0.5,
"fallbackDuration": 3,
"animatedFps": 24,
"animatedMaxWidth": 640,
"animatedMaxHeight": null,
"animatedCrf": 35,
"autoUpdateNewCards": false,
"sentenceCardModel": "Lapis Morph",
"sentenceCardSentenceField": "Sentence",
"sentenceCardAudioField": "SentenceAudio",
"isLapis": true,
"mediaInsertMode": "append",
"auto_start_overlay": false,
"secondarySub": {
"autoLoadSecondarySub": true,
"secondarySubLanguages": [
"en",
"eng"
]
}
},
"subtitleStyle": {
"ontFamily": "Noto Sans CJK JP Regular, Noto Sans CJK JP, Arial Unicode MS, Arial, sans-serif",
"fontSize": 35,
"fontColor": "#cad3f5",
"fontWeight": "normal",
"fontStyle": "normal",
"backgroundColor": "rgb(30, 32, 48, 0.88)",
"secondary": {
"fontSize": 24,
"fontColor": "#cad3f5",
"backgroundColor": "transparent"
}
},
"shortcuts": {
"copySubtitle": "CommandOrControl+C",
"copySubtitleMultiple": "CommandOrControl+Shift+C",
"updateLastCardFromClipboard": "CommandOrControl+V",
"mineSentence": "CommandOrControl+S",
"mineSentenceMultiple": "CommandOrControl+Shift+S",
"toggleSecondarySub": "CommandOrControl+Shift+V",
"multiCopyTimeoutMs": 3000
}
}

View File

@@ -134,7 +134,8 @@ set -gq @catppuccin_pane_number_position "left" # right, left
set -gq @catppuccin_window_text_color "#{@thm_surface_0}"
set -gq @catppuccin_window_number_color "#{@thm_overlay_2}"
set -ogq @catppuccin_window_text " #T"
set -q @catppuccin_window_text " #W"
set -q @catppuccin_window_current_text " #W"
set -gq @catppuccin_window_number "#I"
set -gq @catppuccin_window_current_text_color "#{@thm_surface_1}"
set -gq @catppuccin_window_current_number_color "#{@thm_mauve}"
@@ -156,7 +157,6 @@ set -gq @catppuccin_window_flags_icon_format "##{?window_activity_flag,#{E:@catp
set -gq allow-passthrough on
set -g visual-activity off
set -g @catppuccin_window_status_style "rounded" # basic, rounded, slanted, custom, or none
run ~/.config/tmux/plugins/catppuccin/tmux/catppuccin.tmux

View File

@@ -16,6 +16,7 @@ export GTK_THEME=Dracula
export XDG_CONFIG_HOME=$HOME/.config
export COMPOSE_BAKE=true
export ANKI_WAYLAND=1
export SUDO_PROMPT=$'\a[sudo] password for %u: '
# nvidia
export NVD_BACKEND=direct

22
.gitconfig##os.Darwin Normal file
View File

@@ -0,0 +1,22 @@
[user]
name = sudacode
email = suda@sudacode.com
[init]
defaultBranch = main
[push]
default = simple
autoSetupRemote = true
[pull]
rebase = true
[rebase]
autoStash = true
[fetch]
prune = true
[diff]
algorithm = histogram
[merge]
conflictstyle = zdiff3
[color]
ui = auto
[core]
pager = less -FRX

3
.gitmodules vendored
View File

@@ -19,9 +19,6 @@
[submodule ".config/mpv-modules/autosubsync-mpv"]
path = .config/mpv-modules/autosubsync-mpv
url = git@github.com:joaquintorres/autosubsync-mpv.git
[submodule ".config/mpv-modules/immersion-tracker"]
path = .config/mpv-modules/immersion-tracker
url = git@gitea.suda.codes:sudacode/immersion-tracker.git
[submodule ".config/mpv-modules/mpvacious"]
path = .config/mpv-modules/mpvacious
url = git@github.com:ksyasuda/mpvacious.git

View File

@@ -10,9 +10,9 @@ import sys
import requests
# Configuration
OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY", "")
MODEL = os.environ.get("OPENROUTER_MODEL", "google/gemini-2.0-flash-001")
# MODEL = os.environ.get("OPENROUTER_MODEL", "google/gemini-2.0-flash-001")
MODEL = os.environ.get("OPENROUTER_MODEL", "openai/gpt-oss-120b:free")
API_URL = "https://openrouter.ai/api/v1/chat/completions"
# Try to load API key from file if not in environment

View File

@@ -1,106 +1,81 @@
#!/usr/bin/env bash
THEME="${THEME:-$HOME/.config/rofi/launchers/type-2/style-2.rasi}"
THUMBNAIL_PATH="/tmp/rmpv-thumbnail.jpg"
THEME="${THEME:-/opt/mpv-yomitan/catppuccin-macchiato.rasi}"
FONTCONFIG_FILE=$HOME/.config/mpv/mpv-fonts.conf
COMMAND=mpv
VIDEO_EXTENSIONS="mkv|mp4|avi|webm|mov|flv|wmv|m4v|ts|m2ts"
# Parse command-line options first
while getopts ":it:" opt; do
case $opt in
i)
COMMAND="$COMMAND --profile=immersion"
;;
t)
THEME="$OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
case $opt in
i)
COMMAND="$COMMAND --profile=immersion"
;;
t)
THEME="$OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
generate_thumbnail() {
local video_file="$1"
local temp_thumb="/tmp/rmpv-thumbnail-$$.jpg"
local thumbnail_file="${video_file%.*}.jpg"
# Clean up previous thumbnail
rm -f "$THUMBNAIL_PATH"
# Validate input
if [[ -z "$video_file" ]]; then
echo "Error: No video file specified" >&2
return 1
fi
if [[ ! -f "$video_file" ]]; then
echo "Error: Video file '$video_file' not found" >&2
return 1
fi
# Check if it's a video file
if ! file "$video_file" | grep -qE "(video|Video)"; then
echo "Error: '$video_file' doesn't appear to be a video file" >&2
return 1
fi
# Generate thumbnail if it doesn't exist
if [[ ! -f "$thumbnail_file" ]]; then
echo "Generating thumbnail for $(basename "$video_file")..."
# Try generating thumbnail side-by-side
if ! ffmpeg -ss 00:00:01 -i "$video_file" \
-vf "scale=320:240:force_original_aspect_ratio=decrease,pad=320:240:(ow-iw)/2:(oh-ih)/2" \
-frames:v 1 \
-q:v 4 \
"$thumbnail_file" \
-loglevel error -y 2>/dev/null; then
# Fallback to temp file if side-by-side fails (e.g. read-only fs)
echo "Warning: Failed to write to $thumbnail_file, trying temp location" >&2
thumbnail_file="$temp_thumb"
if ! ffmpeg -ss 00:00:01 -i "$video_file" \
-vf "scale=320:240:force_original_aspect_ratio=decrease,pad=320:240:(ow-iw)/2:(oh-ih)/2" \
-frames:v 1 \
-q:v 4 \
"$thumbnail_file" \
-loglevel error -y 2>/dev/null; then
echo "Error: Failed to generate thumbnail" >&2
return 1
fi
fi
fi
# Copy to consistent location for notify-send
# We use a fixed path so notify-send always finds it
if cp "$thumbnail_file" "$THUMBNAIL_PATH" 2>/dev/null; then
echo "Thumbnail ready at: $THUMBNAIL_PATH"
ls -l "$THUMBNAIL_PATH"
file "$THUMBNAIL_PATH"
else
echo "Error: Failed to copy thumbnail to $THUMBNAIL_PATH" >&2
fi
find_videos() {
find "$PWD" -maxdepth 1 -type f -regextype posix-extended \
-iregex ".*\.($VIDEO_EXTENSIONS)$" 2> /dev/null | sort -V
}
choice="$(find . -iname "*[.mkv|.mp4]" | sort -h | rofi -dmenu -i -theme "$THEME" -theme-str 'listview {columns: 1; lines: 15;} window {width: 88%;}' -p "Choose Video")"
if [[ -z "$choice" ]]; then
echo "No video selected."
exit 1
build_rofi_menu() {
while IFS= read -r video; do
[ -z "$video" ] && continue
local display_name
display_name=$(basename "$video")
printf '%s\0icon\x1fthumbnail://%s\n' "$display_name" "$video"
done < <(find_videos)
}
get_video_thumbnail() {
local video="$1"
local thumb_dir="$HOME/.cache/thumbnails/large"
local video_uri="file://$(realpath "$video")"
local thumb_hash=$(echo -n "$video_uri" | md5sum | cut -d' ' -f1)
local thumb_path="$thumb_dir/$thumb_hash.png"
if [[ -f "$thumb_path" ]]; then
echo "$thumb_path"
return 0
fi
local tmp_thumb="/tmp/rmpv-thumb-$$.jpg"
if command -v ffmpegthumbnailer &> /dev/null; then
ffmpegthumbnailer -i "$video" -o "$tmp_thumb" -s 512 -q 5 2> /dev/null && echo "$tmp_thumb"
elif command -v ffmpeg &> /dev/null; then
ffmpeg -i "$video" -ss 00:00:30 -vframes 1 -vf "scale=512:-1" "$tmp_thumb" 2> /dev/null && echo "$tmp_thumb"
fi
}
selection=$(build_rofi_menu | rofi -dmenu -i -show-icons -theme "$THEME" \
-theme-str 'configuration {font: "JetBrainsMono Nerd Font 10";} listview {columns: 1; lines: 15;} window {width: 88%;}' -p "Choose Video ")
if [[ -z "$selection" ]]; then
echo "No video selected."
exit 1
fi
generate_thumbnail "$choice"
if [[ ! -f "$THUMBNAIL_PATH" ]]; then
echo "Warning: Thumbnail not created, notification will have no icon" >&2
choice="./$selection"
THUMBNAIL_PATH=$(get_video_thumbnail "$choice")
if [[ -n "$THUMBNAIL_PATH" && -f "$THUMBNAIL_PATH" ]]; then
notify-send -i "$THUMBNAIL_PATH" "Playing Video" "$(basename "$choice")"
else
notify-send "Playing Video" "$(basename "$choice")"
fi
notify-send -i "$THUMBNAIL_PATH" "Playing Video" "$(basename "$choice")"
$COMMAND "$choice" &
# vim: ft=sh