This commit is contained in:
2026-02-07 14:53:38 -08:00
parent d4cd0d51c7
commit 1d8e65d4e2
10 changed files with 37 additions and 533 deletions

View File

@@ -4,9 +4,22 @@
"pr": "" "pr": ""
}, },
"permissions": { "permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Read(~/.zshrc)",
"Bash(git * main)",
"Bash(ls *)",
"Bash(pnpm build *)"
],
"deny": [ "deny": [
"Read(.env)", "Bash(curl *)",
"Read(~/.aws/**)" "Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Read(~/.aws/**)",
"Bash(git push *)",
"Bash(yadm push *)"
] ]
}, },
"hooks": { "hooks": {
@@ -25,19 +38,20 @@
"enabledPlugins": { "enabledPlugins": {
"pyright-lsp@claude-plugins-official": true, "pyright-lsp@claude-plugins-official": true,
"typescript-lsp@claude-plugins-official": true, "typescript-lsp@claude-plugins-official": true,
"clangd-lsp@claude-plugins-official": true "clangd-lsp@claude-plugins-official": true,
"claude-mem@thedotmack": true,
"frontend-design@claude-plugins-official": true,
"code-review@claude-plugins-official": true,
"code-simplifier@claude-plugins-official": true,
"playwright@claude-plugins-official": true
}, },
"sandbox": { "sandbox": {
"enabled": false, "enabled": false,
"autoAllowBashIfSandboxed": true, "autoAllowBashIfSandboxed": true,
"network": { "network": {
"allowUnixSockets": [ "allowUnixSockets": ["/var/run/docker.sock"],
"/var/run/docker.sock"
],
"allowLocalBinding": true "allowLocalBinding": true
}, },
"excludedCommands": [ "excludedCommands": ["docker"]
"docker"
]
} }
} }

View File

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

View File

@@ -271,3 +271,10 @@ debug {
disable_logs = true disable_logs = true
enable_stdout_logs = false enable_stdout_logs = false
} }
layerrule {
name = fix-rofi
match:namespace = rofi
no_anim = true
}

View File

@@ -152,4 +152,3 @@ bind = $mainMod, a, exec, ~/.config/rofi/scripts/rofi-anki-script.sh
bindl = , mouse:275, exec, xdotool key alt+w # top mouse to texthooker bindl = , mouse:275, exec, xdotool key alt+w # top mouse to texthooker
bindl = , mouse:276, exec, xdotool key alt+grave # bottom mouse to overlay 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, g, exec, /opt/mpv-yomitan/mpv-yomitan.AppImage --toggle
# bind = ALT SHIFT, Y, exec, "$HOME/.config/rofi/scripts/rofi-mpv-yomitan.sh"

View File

@@ -1 +0,0 @@
../submodules/animecards/animecards

View File

@@ -1,388 +0,0 @@
// Go to https://jimaku.cc/login and create a new account.
// Then go to https://jimaku.cc/account and click the `Generate` button to create a new API key
// Click the `Copy` button and paste it below
var API_KEY = "";
// Configuration options
var CONFIG = {
// Filter the response to only have the specified episode
prompt_episode: true,
// Subtitle suffix (e.g., ".JA" for Japanese subtitles)
subtitle_suffix: ".JA",
// Preferred subtitle format (order matters, first is most preferred)
preferred_formats: ["ass", "srt", "vtt"],
// Automatically load the subtitle after download
auto_load: true,
// Default subtitle delay in seconds (can be positive or negative)
default_delay: 0,
// Default subtitle font size
default_font_size: 16,
// Automatically rename the subtitle file after download
auto_rename: true,
// Automatically run autosubsync-mpv after downloading the subtitle
run_auto_subsync: true
};
// Keybindings
// var MANUAL_SEARCH_KEY = "g";
var FILENAME_AUTO_SEARCH_KEY = "ctrl+J";
var PARENT_FOLDER_AUTO_SEARCH_KEY = "n";
function api(url, extraArgs) {
var baseArgs = [
"curl",
"-s",
"--url",
url,
"--header",
"Authorization: " + API_KEY
];
var args = Array.prototype.concat.apply(baseArgs, extraArgs);
var res = mp.command_native({
name: "subprocess",
playback_only: false,
capture_stdout: true,
capture_stderr: true,
args: args
});
if (res.stdout) return JSON.parse(res.stdout);
}
function downloadSub(sub) {
return api(sub.url, ["--output", sub.name]);
}
function showMessage(message, persist) {
var ass_start = mp.get_property_osd("osd-ass-cc/0");
var ass_stop = mp.get_property_osd("osd-ass-cc/1");
mp.osd_message(
ass_start + "{\\fs16}" + message + ass_stop,
persist ? 999 : 2
);
}
// The timeout is neccessary due to a weird bug in mpv
function inputGet(args) {
mp.input.terminate();
setTimeout(function () {
mp.input.get(args);
}, 1);
}
// The timeout is neccessary due to a weird bug in mpv
function inputSelect(args) {
mp.input.terminate();
setTimeout(function () {
mp.input.select(args);
}, 1);
}
// Taken from mpv-subversive
// https://github.com/nairyosangha/mpv-subversive/blob/master/backend/backend.lua#L146
function sanitize(text) {
var subPatterns = [
/\.[a-zA-Z]+$/, // extension
/\./g,
/-/g,
/_/g,
/\[[^\]]+\]/g, // [] bracket
/\([^\)]+\)/g, // () bracket
/720[pP]/g,
/480[pP]/g,
/1080[pP]/g,
/[xX]26[45]/g,
/[bB]lu[-]?[rR]ay/g,
/^[\s]*/,
/[\s]*$/,
/1920x1080/g,
/1920X1080/g,
/Hi10P/g,
/FLAC/g,
/AAC/g
];
var result = text;
subPatterns.forEach(function (subPattern) {
var newResult = result.replace(subPattern, " ");
if (newResult.length > 0) {
result = newResult;
}
});
return result;
}
// Adapted from mpv-subversive
// https://github.com/nairyosangha/mpv-subversive/blob/master/backend/backend.lua#L164
function extractTitle(text) {
var matchers = [
{ regex: /^([\w\s\d]+)[Ss]\d+[Ee]?\d+/, group: 1 },
{ regex: /^([\w\s\d]+)-[\s]*\d+[\s]*[^\w]*$/, group: 1 },
{ regex: /^([\w\s\d]+)[Ee]?[Pp]?[\s]+\d+$/, group: 1 },
{ regex: /^([\w\s\d]+)[\s]\d+.*$/, group: 1 },
{ regex: /^\d+[\s]*(.+)$/, group: 1 }
];
for (var i = 0; i < matchers.length; i++) {
var matcher = matchers[i];
var match = text.match(matcher.regex);
if (match) {
return match[matcher.group].trim();
}
}
return text;
}
function getNames(results) {
return results.map(function (item) {
return item.name;
});
}
function runAutoSubSyncMPV() {
try {
mp.command_native(["script-binding", "autosubsync-menu"]);
} catch (e) {
showMessage("autosubsync-mpv not installed");
return;
}
}
function selectSub(selectedSub) {
showMessage("Downloading: " + selectedSub.name);
try {
downloadSub(selectedSub);
// Get current video filename without extension
var videoPath = mp.get_property("path");
if (!videoPath) {
throw new Error("No video file is currently playing");
}
var videoName = videoPath.substring(0, videoPath.lastIndexOf("."));
// Get subtitle extension
var subExt = selectedSub.name.substring(selectedSub.name.lastIndexOf("."));
var newSubName = selectedSub.name;
if (CONFIG.auto_rename) {
// Create new subtitle filename
newSubName = videoName + CONFIG.subtitle_suffix + subExt;
// Rename the downloaded subtitle file
var renameResult = mp.command_native({
name: "subprocess",
playback_only: false,
args: ["mv", selectedSub.name, newSubName]
});
if (renameResult.error) {
throw new Error(
"Failed to rename subtitle file: " + renameResult.error
);
}
showMessage(newSubName + " downloaded and renamed");
} else {
showMessage(newSubName + " downloaded");
}
if (CONFIG.auto_load) {
mp.commandv("sub_add", newSubName);
showMessage(newSubName + " added");
// Apply subtitle settings if configured
if (CONFIG.default_delay !== 0) {
mp.commandv("sub_delay", CONFIG.default_delay);
}
if (CONFIG.default_font_size !== 16) {
mp.commandv("sub_font_size", CONFIG.default_font_size);
}
}
if (CONFIG.run_auto_subsync) {
runAutoSubSyncMPV();
}
mp.set_property("pause", "no");
} catch (error) {
showMessage("Error: " + error.message, true);
mp.set_property("pause", "no");
}
}
function sortByPreferredFormat(files) {
return files.sort(function (a, b) {
var extA = a.name.substring(a.name.lastIndexOf(".") + 1).toLowerCase();
var extB = b.name.substring(b.name.lastIndexOf(".") + 1).toLowerCase();
var indexA = CONFIG.preferred_formats.indexOf(extA);
var indexB = CONFIG.preferred_formats.indexOf(extB);
if (indexA === -1) return 1;
if (indexB === -1) return -1;
return indexA - indexB;
});
}
function selectEpisode(anime, episode) {
mp.input.terminate();
var episodeResults;
if (episode) {
showMessage("Fetching subs for: " + anime.name + " episode " + episode);
episodeResults = api(
"https://jimaku.cc/api/entries/" + anime.id + "/files?episode=" + episode
);
} else {
showMessage("Fetching all subs for: " + anime.name);
episodeResults = api(
"https://jimaku.cc/api/entries/" + anime.id + "/files"
);
}
if (episodeResults.error) {
showMessage("Error: " + animeResults.error);
return;
}
if (episodeResults.length === 0) {
showMessage("No results found");
return;
}
// Sort results by preferred format
episodeResults = sortByPreferredFormat(episodeResults);
if (episodeResults.length === 1) {
var selectedEpisode = episodeResults[0];
selectSub(selectedEpisode);
return;
}
var items = getNames(episodeResults);
inputSelect({
prompt: "Select episode: ",
items: items,
submit: function (id) {
var selectedEpisode = episodeResults[id - 1];
selectSub(selectedEpisode);
}
});
}
function onAnimeSelected(anime) {
if (CONFIG.prompt_episode) {
inputGet({
prompt: "Episode (leave blank for all): ",
submit: function (episode) {
selectEpisode(anime, episode);
}
});
} else {
selectEpisode(anime);
}
}
function search(searchTerm, isAuto) {
mp.input.terminate();
showMessage('Searching for: "' + searchTerm + '"');
var animeResults = api(
encodeURI(
"https://jimaku.cc/api/entries/search?anime=true&query=" + searchTerm
)
);
if (animeResults.error) {
showMessage("Error: " + animeResults.error);
return;
}
if (animeResults.length === 0) {
showMessage("No results found");
if (isAuto) {
manualSearch(searchTerm);
}
return;
}
if (animeResults.length === 1) {
var selectedAnime = animeResults[0];
onAnimeSelected(selectedAnime);
return;
}
var items = getNames(animeResults);
inputSelect({
prompt: "Select anime: ",
items: items,
submit: function (id) {
var selectedAnime = animeResults[id - 1];
showMessage(selectedAnime.name, true);
onAnimeSelected(selectedAnime);
}
});
}
function manualSearch(defaultText) {
inputGet({
prompt: "Search term: ",
submit: search,
default_text: defaultText
});
mp.set_property("pause", "yes");
showMessage("Manual Jimaku Search", true);
}
function autoSearch() {
var filename = mp.get_property("filename");
var sanitizedFilename = sanitize(filename);
var currentAnime = extractTitle(sanitizedFilename);
mp.set_property("pause", "yes");
search(currentAnime, true);
}
function autoSearchParentFolder() {
var path = mp.get_property("stream-open-filename");
var pathSplit = path.split(path.indexOf("/") >= 0 ? "/" : "\\");
var filename =
pathSplit.length === 1 ? pathSplit[0] : pathSplit[pathSplit.length - 2];
var sanitizedFilename = sanitize(filename);
var currentAnime = extractTitle(sanitizedFilename);
mp.set_property("pause", "yes");
search(currentAnime, true);
}
// mp.add_key_binding(MANUAL_SEARCH_KEY, "jimaku-manual-search", manualSearch);
mp.add_key_binding(
FILENAME_AUTO_SEARCH_KEY,
"jimaku-filename-auto-search",
autoSearch
);
mp.add_key_binding(
PARENT_FOLDER_AUTO_SEARCH_KEY,
"jimaku-parent-folder-auto-search",
autoSearchParentFolder
);

View File

@@ -1 +0,0 @@
../submodules/mpvacious

View File

@@ -37,7 +37,8 @@ window {
location: center; location: center;
anchor: center; anchor: center;
fullscreen: false; fullscreen: false;
width: 37%; width: 46.65%;
height: 44%;
x-offset: 0px; x-offset: 0px;
y-offset: 0px; y-offset: 0px;
@@ -58,9 +59,9 @@ mainbox {
} }
imagebox { imagebox {
padding: 20px; padding: 24px;
background-color: transparent; background-color: transparent;
background-image: url("~/.config/rofi/images/oshinoko.png", height); background-image: url("~/.config/rofi/images/oshinoko.png", both);
orientation: vertical; orientation: vertical;
children: [ "inputbar", "dummy", "mode-switcher" ]; children: [ "inputbar", "dummy", "mode-switcher" ];
} }

View File

@@ -1,129 +0,0 @@
{
"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

@@ -73,3 +73,5 @@ zstyle ':url-quote-magic:*' url-quotes ''
# bind it to both typing and pasting # bind it to both typing and pasting
zle -N self-insert url-quote-magic zle -N self-insert url-quote-magic
zle -N bracketed-paste bracketed-paste-magic zle -N bracketed-paste bracketed-paste-magic
alias claude-mem='bun "/home/sudacode/.claude/plugins/marketplaces/thedotmack/plugin/scripts/worker-service.cjs"'