Compare commits

...

87 commits

Author SHA1 Message Date
Petar Kapriš
54381c1f0c hyprland: change workspace movement to silent 2025-09-29 15:29:26 +02:00
Petar Kapriš
3273da704d mpv: Don't keep-open 2025-09-29 15:29:26 +02:00
Petar Kapriš
8f83358e04 waybar: add network and battery modules 2025-09-29 15:29:24 +02:00
Petar Kapriš
2be9c73e46 git: add gitconfig 2025-09-29 15:15:55 +02:00
Petar Kapriš
2d1bc8c82f remove ludusavi and MangoHud configs 2025-09-29 15:15:55 +02:00
Petar Kapriš
29d55583ea hypr: add libinput-gestures to autostart 2025-09-29 15:15:55 +02:00
Petar Kapriš
2573d6b25c gdb: add gdb/gef config 2025-09-29 15:15:55 +02:00
Petar Kapriš
2004a01334 vim: add vim config 2025-09-29 15:15:55 +02:00
Petar Kapriš
585ff4c818 sbcl: add sbclrc 2025-09-29 15:15:55 +02:00
Petar Kapriš
ef9551757f bash: add bashrc/profile 2025-09-29 15:15:55 +02:00
Petar Kapriš
da46e9daae ranger: add ranger config 2025-09-29 15:15:55 +02:00
Petar Kapriš
7aca15a0f7 mpv: add my mpv script/conf files
mpv: move input-ipc-server line
2025-09-29 15:15:54 +02:00
Petar Kapriš
fdc982f7a1 mpv: add my mpv script/conf files 2025-09-28 18:05:22 +02:00
Petar Kapriš
aa2425c6a8 mpv: remove my input.conf 2025-09-28 18:05:22 +02:00
Petar Kapriš
ec6bf3d8c2 hypr: remove zathura center rules 2025-09-28 18:05:22 +02:00
Petar Kapriš
80a00967c7 hypr: remove mpv,qimgv special center rules 2025-09-28 18:05:22 +02:00
Petar Kapriš
4a328a3a0c waybar: add prompts for my keyboard layouts 2025-09-28 18:05:22 +02:00
Petar Kapriš
cd6f22c403 waybar: set hypr/language keyboard to match my keyboard 2025-09-28 18:05:22 +02:00
Petar Kapriš
d9c174bbd5 hypr: change default editor and file manager 2025-09-28 18:04:06 +02:00
Petar Kapriš
9155ad7740 hypr: replace nvtop with radeontop 2025-09-28 18:04:06 +02:00
Petar Kapriš
ef8c71bd93 Add pipewire autostart commands 2025-09-28 18:04:06 +02:00
Petar Kapriš
6e118abf4a Modify wallpaper change interval 2025-09-28 18:04:06 +02:00
Petar Kapriš
1fdc7d7561 Remove unnecessary github files 2025-09-28 18:04:06 +02:00
Petar Kapriš
e756858e89 Adapt hypr config to monitors 2025-09-28 18:04:04 +02:00
Petar Kapriš
6382ac1df3 Adapt hypr input config to keyboard layouts 2025-09-28 18:00:49 +02:00
Petar Kapriš
95b310ed3e Merge conflicting dotfiles 2025-09-28 18:00:45 +02:00
Petar Kapriš
2018d0b77f Fix waybar display 2025-09-28 17:52:21 +02:00
Sergio Laín
b67dda0834
chore(nvim): plugin updates 2025-09-21 17:34:42 +02:00
Sergio Laín
48af1d9bfb
feat(neomutt): add terminal mail client 2025-09-21 17:34:27 +02:00
Sergio Laín
67e0426c5f
chore(nvim): plugin updates 2025-09-20 00:13:14 +02:00
Sergio Laín
a4c1ea2216
fix(hyprland): old laptop gestures removed 2025-09-20 00:12:38 +02:00
Sergio Laín
bd7c596890
fix(ghostty): theme name 2025-09-20 00:11:57 +02:00
Sergio Laín
62a7df01e0
feat(browser): disable firefox ai stuff 2025-09-20 00:11:43 +02:00
Sergio Laín
b72d704aaa
chore(nvim): plugin updates 2025-09-18 19:13:50 +02:00
Sergio Laín
a7162e5302
refactor(waybar): used modules for the two bars 2025-09-17 23:48:44 +02:00
Sergio Laín
a1dff8f66e
feat(yazi): show hidden files by default 2025-09-17 23:47:50 +02:00
Sergio Laín
af58e10b73
feat(nvim): noice now moves the cmdline to the bottom
Just like regular nvim
2025-09-17 23:47:16 +02:00
Sergio Laín
612c6bcb9c
feat(nvim): remove vue extras
The default extra from lazyvim now works with 2 and 3 altogether
2025-09-17 23:45:26 +02:00
Sergio Laín
9d7a41a53e
fix(nvim): remove conflicting binding regarding spelling 2025-09-17 23:45:04 +02:00
Sergio Laín
802ef115de
feat(nvim): remove extras and lazyvim included defining files 2025-09-17 23:44:42 +02:00
Sergio Laín
b5e028ffd8
chore(nvim): plugin updates 2025-09-17 23:44:18 +02:00
Sergio Laín
2a3c105954
refactor(nvim): point out to new mason repo 2025-09-17 23:43:44 +02:00
Sergio Laín
60f72fbadc
feat(nvim): remove callback from obsidian extra 2025-09-17 23:43:05 +02:00
Sergio Laín
7c3160386f
feat(nvim): disable mouse by default 2025-09-17 23:42:53 +02:00
Sergio Laín
5dd4be2373
feat(nvim): keymap changes 2025-09-17 23:42:43 +02:00
Sergio Laín
161fb0a1b8
chore(fish): update variables 2025-09-02 18:22:03 +02:00
Sergio Laín
135989861d
feat(git): remove nearly every alias
i use mostly lazygit and when i have to use the git cli i tend to always use
the longer commands
2025-09-02 18:20:16 +02:00
Sergio Laín
95a882a0e5
feat(nvim): add snacks bindings for git branches 2025-09-02 18:19:50 +02:00
Sergio Laín
7a0665fd03
feat(nvim): remove a lot of keymaps i dont use 2025-09-02 18:19:28 +02:00
Sergio Laín
f9b7b1533d
chore(nvim): plugin updates 2025-09-02 18:18:35 +02:00
Sergio Laín
a10612a98b
feat(legcord): change theme 2025-08-31 23:41:08 +02:00
Sergio Laín
3c4b544b20
feat(mpv): remove gpu by default profiles 2025-08-31 19:30:34 +02:00
Sergio Laín
8ce29f35aa
feat(mise): add new tools 2025-08-31 19:29:54 +02:00
Sergio Laín
c0b50f9a09
chore(nvim): plugin updates 2025-08-31 18:03:45 +02:00
Sergio Laín
0742419fd6
feat(audio-mixer): wiremix added
This audio-mixer works as a TUI instead of Pavucontrol which is a GUI
2025-08-31 18:02:50 +02:00
Sergio Laín
4eb8a9b7b8
feat(discord-client): remove vesktop in favour of legcord 2025-08-31 17:55:39 +02:00
Sergio Laín
bc01bd54e8
chore(yazi): update plugins 2025-08-31 17:36:43 +02:00
Matt
9e27df38ec
fix a bug in the fish config (#63) 2025-08-31 14:27:57 +02:00
Petar Kapriš
05d99c60e7 Revert "hypr: add radeontop rule"
This reverts commit 4d056e0f52.
2025-08-30 23:07:02 +02:00
Sergio Laín
528adf4f88
feat(bin): tmuxp-config script 2025-08-27 14:14:13 +02:00
Sergio Laín
a4e6d0597c
refactor(bin): mise-config script now uses fd 2025-08-27 14:13:08 +02:00
Sergio Laín
0f3306c1d3
refactor(tmux): sessionizer script 2025-08-27 14:12:25 +02:00
Sergio Laín
335db8d4bd
refactor(tmux): session-switcher is now dynamic
Can pass a session name
2025-08-27 14:10:57 +02:00
Sergio Laín
259ad2106c
feat(fish): remove a lot of functions i dont use 2025-08-27 13:28:53 +02:00
Sergio Laín
8dd7e0da0c
feat(qimgv): changes to the bindings 2025-08-27 13:27:44 +02:00
Sergio Laín
d326d4328a
refactor(zathura): divide zathurarc file into different ones 2025-08-27 13:27:08 +02:00
Sergio Laín
3b5d618934
fix(tmux): italic not working 2025-08-27 13:26:03 +02:00
Sergio Laín
2695f5c1a7
feat(tmuxp): add new mail workspace file 2025-08-27 13:25:42 +02:00
Sergio Laín
c5b7baf93a
feat(nvim): disable some plugins: flash, bufferline and neotree 2025-08-27 13:23:35 +02:00
Sergio Laín
cfbbdc471b
feat(nvim): grapple marks are saved by git branch 2025-08-27 13:22:47 +02:00
Sergio Laín
8bd4110a9f
feat(nvim): remove plugins from python and markdown extended extras 2025-08-27 13:22:23 +02:00
Sergio Laín
526583d640
feat(nvim): add treesitter bindings for node selection
Using v (enter visual mode) makes more sense than the defaults that
comes with LazyVim
2025-08-27 13:21:13 +02:00
Sergio Laín
14641d063f
feat(nvim): move basedpyright options to config file instead of lsp
definition
2025-08-27 13:20:29 +02:00
Sergio Laín
3f3a617ce1
feat(nvim): go back to catppuccin theme lavender 2025-08-27 13:19:09 +02:00
Sergio Laín
5e06ef8bcf
feat(nvim): disable noice lsp progress 2025-08-27 13:18:54 +02:00
Sergio Laín
bd9319bf55
chore(nvim): update plugins 2025-08-27 13:16:39 +02:00
Sergio Laín
6558ec86c8
feat(hypr): more noticeable border for selected window 2025-08-27 13:06:41 +02:00
Sergio Laín
ca7520d1bd
feat(ghostty): less window padding 2025-08-27 13:05:06 +02:00
Sergio Laín
64a41845ab
feat(fish): set bat as default pager 2025-08-27 13:04:51 +02:00
Sergio Laín
44a34f74ac
chore(surfingkeys): update config 2025-08-27 12:31:29 +02:00
Sergio Laín
a5f37c1970
feat(browser): add some options to the user.js file 2025-08-17 01:36:26 +02:00
Sergio Laín
f369dded18
feat(fish): add fzf binding to move up and down on the list
alt+j and alt+k to move 5 entries
2025-08-17 01:33:39 +02:00
Sergio Laín
d3213296e6
feat(fish): remove trashy alias 2025-08-17 01:31:07 +02:00
Sergio Laín
62be8b15df
fix(hypr): clashing between bindings 2025-08-17 01:21:00 +02:00
Sergio Laín
1a538bfa76
feat(qimgv): some qol changes to the config 2025-08-17 01:20:07 +02:00
Sergio Laín
0ef6d6310b
refactor(monitors): changed from 3 to 2 2025-08-17 01:19:14 +02:00
Sergio Laín
2a100075d9
chore(nvim): plugin updates 2025-08-17 01:18:20 +02:00
310 changed files with 38478 additions and 3395 deletions

14
.bash_profile Normal file
View file

@ -0,0 +1,14 @@
#
# ~/.bash_profile
#
export QT_STYLE_OVERIDE=GTK+
export GDK_BACKEND=wayland
export GTK_THEME=Adwaita:dark
export GTK2_RC_FILES=/usr/share/themes/Raleigh/gtk-3.0/gtkrc
export _JAVA_AWT_WM_NONREPARENTING=1
[[ -f ~/.bashrc ]] && . ~/.bashrc
# [ -z "$DISPLAY" ] &&
[ `tty` = '/dev/tty1' ] && exec dbus-run-session Hyprland

1
.bashrc Symbolic link
View file

@ -0,0 +1 @@
/home/kappa/dotfiles/.bashrc

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View file

@ -1,358 +0,0 @@
### MangoHud configuration file
### Uncomment any options you wish to enable. Default options are left uncommented
### Use some_parameter=0 to disable a parameter (only works with on/off parameters)
### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead
################ INFORMATIONAL #################
## prints possible options on stdout
# help
################ PERFORMANCE #################
### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless VSynced)
# fps_limit=0
### early = wait before present, late = wait after present
# fps_limit_method=
### VSync [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on
# vsync=-1
### OpenGL VSync [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a FPS limiter (FPS = display refresh rate / N)
# gl_vsync=-2
### Mip-map LoD bias. Negative values will increase texture sharpness (and aliasing)
## Positive values will increase texture blurriness (-16 to 16)
# picmip=-17
### Anisotropic filtering level. Improves sharpness of textures viewed at an angle (0 to 16)
# af=-1
### Force bicubic filtering
# bicubic
### Force trilinear filtering
# trilinear
### Disable linear texture filtering. Makes textures look blocky
# retro
################### VISUAL ###################
### Legacy layout
# legacy_layout=0
### pre defined presets
# -1 = default
# 0 = no display
# 1 = fps only
# 2 = horizontal view
# 3 = extended
# 4 = high detailed information
# preset=-1
### Enable most of the toggleable parameters (currently excludes `histogram`)
# full
### Show FPS only. ***Not meant to be used with other display params***
# fps_only
### Display custom centered text, useful for a header
# custom_text_center=
### Display the current system time
# time
## removes the time label
# time_no_label
### Time formatting examples
## %H:%M
## [ %T %F ]
## %X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. Japanese)
# time_format="%T"
### Display MangoHud version
# version
### Display the current GPU information
## Note: gpu_mem_clock and gpu_mem_temp also need "vram" to be enabled
gpu_stats
gpu_temp
# gpu_junction_temp
# gpu_core_clock
# gpu_mem_temp
# gpu_mem_clock
# gpu_power
# gpu_text=
# gpu_load_change
# gpu_load_value=60,90
# gpu_load_color=39F900,FDFD09,B22222
## GPU fan in rpm on AMD, FAN in percent on NVIDIA
# gpu_fan
## gpu_voltage only works on AMD GPUs
# gpu_voltage
### Display the current CPU information
cpu_stats
cpu_temp
# cpu_power
# cpu_text=
# cpu_mhz
# cpu_load_change
# cpu_load_value=60,90
# cpu_load_color=39F900,FDFD09,B22222
### Display the current CPU load & frequency for each core
# core_load
# core_load_change
### Display IO read and write for the app (not system)
# io_read
# io_write
### Display system vram / ram / swap space usage
# vram
# ram
# swap
### Display per process memory usage
## Show resident memory and other types, if enabled
# procmem
# procmem_shared
# procmem_virt
### Display battery information
# battery
# battery_icon
# device_battery=gamepad,mouse
# device_battery_icon
# battery_watt
# battery_time
### Display FPS and frametime
fps
# fps_sampling_period=500
# fps_color_change
# fps_value=30,60
# fps_color=B22222,FDFD09,39F900
frametime
# frame_count
## fps_metrics takes a list of decimal values or the value avg
# fps_metrics=avg,0.01
### Display GPU throttling status based on Power, current, temp or "other"
## Only shows if throttling is currently happening
throttling_status
## Same as throttling_status but displays throttling on the frametime graph
#throttling_status_graph
### Display miscellaneous information
# engine_version
# engine_short_names
# gpu_name
# vulkan_driver
# wine
# exec_name
# winesync
### Display loaded MangoHud architecture
# arch
### Display the frametime line graph
frame_timing
# histogram
### Display GameMode / vkBasalt running status
# gamemode
# vkbasalt
### Gamescope related options
## Display the status of FSR (only works in gamescope)
# fsr
## Hides the sharpness info for the `fsr` option (only available in gamescope)
# hide_fsr_sharpness
## Shows the graph of gamescope app frametimes and latency (only on gamescope obviously)
# debug
## Display the status of HDR (only works in gamescope)
# hdr
## Display the current refresh rate (only works in gamescope)
# refresh_rate
### graphs displays one or more graphs that you chose
## seperated by ",", available graphs are
## gpu_load,cpu_load,gpu_core_clock,gpu_mem_clock,vram,ram,cpu_temp,gpu_temp
# graphs=
### mangoapp related options
## Enables mangoapp to be displayed above the Steam UI
# mangoapp_steam
### Steam Deck options
## Shows the Steam Deck fan rpm
# fan
### Display current FPS limit
# show_fps_limit
### Display the current resolution
# resolution
### Display custom text
# custom_text=
### Display output of Bash command in next column
# exec=
### Display media player metadata
# media_player
## for example spotify
# media_player_name=
## Format metadata, lines are delimited by ; (wip)
## example: {title};{artist};{album}
## example: Track:;{title};By:;{artist};From:;{album}
# media_player_format=title,artist,album
### Network interface throughput
# network
## Network can take arguments but it's not required.
## without arguments it shows all interfaces
## arguments set which interfaces will be displayed
# network=eth0,wlo1
### Change the hud font size
font_size=22
# font_scale=1.0
# font_size_text=24
# font_scale_media_player=0.55
# no_small_font
### Change default font (set location to TTF/OTF file)
## Set font for the whole hud
font_file=/usr/share/fonts/MapleMono-NF-unhinted/MapleMono-NF-Regular.ttf
## Set font only for text like media player metadata
# font_file_text=
## Set font glyph ranges. Defaults to Latin-only. Don't forget to set font_file/font_file_text to font that supports these
## Probably don't enable all at once because of memory usage and hardware limits concerns
## If you experience crashes or text is just squares, reduce glyph range or reduce font size
# font_glyph_ranges=korean,chinese,chinese_simplified,japanese,cyrillic,thai,vietnamese,latin_ext_a,latin_ext_b
### Outline text
text_outline
# text_outline_color = 000000
# text_outline_thickness = 1.5
### Change the hud position
position=top-right
### Change the corner roundness
round_corners=10
### Remove margins around MangoHud
# hud_no_margin
### Display compact version of MangoHud
# hud_compact
### Display MangoHud in a horizontal position
# horizontal
# horizontal_stretch
### Disable / hide the hud by default
no_display
### Hud position offset
# offset_x=0
# offset_y=0
### Hud dimensions
# width=0
# height=140
# table_columns=3
# cellpadding_y=-0.085
### Hud transparency / alpha
# background_alpha=0.5
# alpha=1.0
### FCAT overlay
### This enables an FCAT overlay to perform frametime analysis on the final image stream.
### Enable the overlay
# fcat
### Set the width of the FCAT overlay.
### 24 is a performance optimization on AMD GPUs that should not have adverse effects on nVidia GPUs.
### A minimum of 20 pixels is recommended by nVidia.
# fcat_overlay_width=24
### Set the screen edge, this can be useful for special displays that don't update from top edge to bottom. This goes from 0 (left side) to 3 (top edge), counter-clockwise.
# fcat_screen_edge=0
### Color customization
text_color=cad3f5
gpu_color=a6da95
cpu_color=8aadf4
# vram_color=AD64C1
# ram_color=C26693
engine_color=ed8796
# io_color=A491D3
frametime_color=eed49f
background_color=181926
# media_player_color=FFFFFF
# wine_color=EB5B5B
# battery_color=FF9078
### Specify GPU with PCI bus ID for AMDGPU and NVML stats
### Set to 'domain:bus:slot.function'
# pci_dev=0:0a:0.0
### Blacklist
# blacklist=
### Control over socket
### Enable and set socket name, '%p' is replaced with process id
## example: mangohud
## example: mangohud-%p
# control = -1
################ WORKAROUNDS #################
### Options starting with "gl_*" are for OpenGL
### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable
# gl_size_query=viewport
### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III
# gl_bind_framebuffer=0
### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx
# gl_dont_flip=1
################ INTERACTION #################
### Change toggle keybinds for the hud & logging
toggle_hud=Shift_L+F12
# toggle_hud_position=Shift_R+F11
# toggle_fps_limit=Shift_L+F1
# toggle_logging=Shift_L+F2
# reload_cfg=Shift_L+F4
# upload_log=Shift_L+F3
#################### LOG #####################
### Automatically start the log after X seconds
# autostart_log=
### Set amount of time in seconds that the logging will run for
# log_duration=
### Change the default log interval, 0 is default
# log_interval=0
### Set location of the output files (required for logging)
# output_folder=/home/<USERNAME>/mangologs
### Permit uploading logs directly to FlightlessMango.com
## set to 1 to enable
# permit_upload=0
### Define a '+'-separated list of percentiles shown in the benchmark results
### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1
## example: ['97', 'AVG', '1', '0.1']
# benchmark_percentiles=97,AVG
## Adds more headers and information such as versioning to the log. This format is not supported on flightlessmango.com (yet)
# log_versioning
## Enable automatic uploads of logs to flightlessmango.com
# upload_logs

View file

@ -1126,4 +1126,6 @@
],
"editor.matchBrackets": "never",
"workbench.statusBar.visible": false
"dart.flutterSdkPath": "/home/kappa/down/pkgs/flutter",
"dart.flutterCustomEmulators": []
}

View file

@ -14,7 +14,7 @@
--decorations=always
# Uncomment the following line to disable automatic paging:
--paging=never
--paging=always
# Uncomment the following line if you are using less version >= 551 and want to
# enable mouse scrolling support in `bat` when running inside tmux. This might

File diff suppressed because one or more lines are too long

View file

@ -18,6 +18,15 @@ user_pref("devtools.theme", "dark");
user_pref("font.name.serif.x-western", "Maple Mono NF");
user_pref("signon.rememberSignons", false);
user_pref("signon.autofillForms", false);
user_pref("browser.urlbar.suggest.searches", false);
user_pref("browser.tabs.fadeOutUnloadedTabs", true);
// Disable AI stuff
user_pref("browser.ml.enable", false);
user_pref("browser.ml.chat.enabled", false);
user_pref("extensions.ml.enabled", false);
user_pref("browser.ml.linkPreview.enabled ", false);
user_pref("browser.tabs.groups.smart.enabled", false);
user_pref("browser.tabs.groups.smart.userEnabled", false);
// Zen Options
user_pref("browser.urlbar.trimURLs", true);
@ -27,9 +36,9 @@ user_pref("zen.urlbar.replace-newtab", true);
user_pref("zen.tabs.vertical.right-side", true);
user_pref("zen.workspaces.open-new-tab-if-last-unpinned-tab-is-closed", false);
user_pref("zen.theme.gradient", true);
user_pref("zen.view.experimental-rounded-view", true);
user_pref("zen.view.experimental-rounded-view", false);
user_pref("zen.view.experimental-force-window-controls-left", false); // Using the sidebar at the right
user_pref("zen.widget.linux.transparency", true);
user_pref("zen.widget.linux.transparency", false);
user_pref("zen.pinned-tab-manager.restore-pinned-tabs-to-pinned-url", true);
user_pref("zen.splitView.change-on-hover", true);
user_pref("zen.tabs.show-newtab-under", false);
@ -39,3 +48,4 @@ user_pref("zen.urlbar.behavior", "float");
user_pref("zen.view.compact.hide-toolbar", true);
user_pref("zen.workspaces.force-container-workspace", true);
user_pref("zen.glance.open-essential-external-links", false);
user_pref("zen.theme.content-element-separation", 0);

View file

@ -13,8 +13,8 @@ SETUVAR --export XDG_CACHE_HOME:/home/matt/\x2ecache
SETUVAR --export XDG_CONFIG_HOME:/home/matt/\x2econfig
SETUVAR --export XDG_DATA_HOME:/home/matt/\x2elocal/share
SETUVAR --export XDG_SCRIPT_HOME:/home/matt/\x2elocal/script
SETUVAR --export __ABBR_TIPS_KEYS:g\x1ed\x1ea__bruh\x1ea__c\x1ea__cat\x1ea__catp\x1ea__cl\x1ea__clock\x1ea__codeinfo\x1ea__cv\x1ea__disks\x1ea__dots\x1ea__dsize\x1ea__ex\x1ea__f\x1ea__fetch\x1ea__gfetch\x1ea__gpt\x1ea__gr\x1ea__i\x1ea__info\x1ea__ip\x1ea__l\x1ea__ld\x1ea__ldh\x1ea__lg\x1ea__lh\x1ea__lm\x1ea__ls\x1ea__lsh\x1ea__lt\x1ea__lth\x1ea__lzd\x1ea__matrix\x1ea__mkdir\x1ea__op\x1ea__pages\x1ea__proc\x1ea__pse\x1ea__q\x1ea__r\x1ea__s\x1ea__sc\x1ea__svn\x1ea__t\x1ea__ta\x1ea__test\x2dnet\x1ea__tr\x1ea__u\x1ea__up\x1ea__upall\x1ea__v\x1ea__vcl\x1ea__vv\x1ea__vvl\x1ea__vvn\x1ea__wget\x1ea__yarn\x1ea__z\x1ea__zi
SETUVAR --export __ABBR_TIPS_VALUES:git\x1edocker\x1egenact\x20\x2ds\x204\x1ez\x1ebat\x1ebat\x20\x2d\x2dpaging\x3dalways\x1eclear\x1etty\x2dclock\x20\x2dsbc\x1escc\x20\x2e/\x1ez\x20\x26\x26\x20v\x1eduf\x1eyadm\x20enter\x20lazygit\x1edua\x20i\x1esudo\x20chmod\x20\x2bx\x1efzf\x1efastfetch\x1eonefetch\x1etgpt\x20\x2di\x1ecd\x20\x22\x24\x28git\x20rev\x2dparse\x20\x2d\x2dshow\x2dtoplevel\x29\x22\x1eyay\x20\x2dS\x20\x1etldr\x1eip\x20\x2dc\x20a\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1elazydocker\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2d\x2dicons\x20\x2dD\x20\x2d\x2dgit\x1elazygit\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1el\x3deza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dtree\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2d\x2dicons\x20\x2d\x2dtree\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1elazydocker\x1eunimatrix\x20\x2ds\x2095\x1emkdir\x20\x2dp\x1ecd\x20\x7e/Documents/Obsidian/obsidianVault\x1enavi\x1esysz\x1epacseek\x1eexit\x1emise\x20run\x1esudo\x1er\x3dsource\x20\x24XDG_CONFIG_HOME/fish/config\x2efish\x1esvn\x20\x2d\x2dconfig\x2ddir\x20\x5c\x5c\x5c\x5c\x22\x24XDG_CONFIG_HOME\x5c\x5c\x5c\x5c\x22/subversion\x1etmux\x1etmux\x20attach\x20\x2dt\x1ecommand\x20up\x1etrash\x1eyay\x20\x2dR\x20\x1eyay\x20\x2dSyu\x1etopgrade\x1envim\x1envim\x20\x2d\x2dclean\x1ebob\x1ebob\x20use\x20latest\x1ebob\x20use\x20nightly\x1ewget\x20\x2d\x2dhsts\x2dfile\x3d\x22\x24XDG_DATA_HOME/wget\x2dhsts\x22\x1eyarn\x20\x2d\x2duse\x2dyarnrc\x20\x22\x24XDG_CONFIG_HOME/yarn/config\x22\x1e__zoxide_z\x1e__zoxide_zi
SETUVAR --export __ABBR_TIPS_KEYS:g\x1ed\x1ea__c\x1ea__cat\x1ea__catp\x1ea__cl\x1ea__dots\x1ea__i\x1ea__l\x1ea__ldh\x1ea__lg\x1ea__lh\x1ea__lm\x1ea__ls\x1ea__lsh\x1ea__lt\x1ea__lth\x1ea__lzd\x1ea__mail\x1ea__notes\x1ea__svn\x1ea__u\x1ea__up\x1ea__upall\x1ea__v\x1ea__wget\x1ea__yarn\x1ea__z\x1ea__zi
SETUVAR --export __ABBR_TIPS_VALUES:git\x1edocker\x1ez\x1ebat\x1ebat\x20\x2d\x2dpaging\x3dalways\x1eclear\x1eyadm\x20enter\x20lazygit\x1eyay\x20\x2dS\x20\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2d\x2dicons\x20\x2dD\x20\x2d\x2dgit\x1elazygit\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1el\x3deza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2d\x2dicons\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2da\x20\x2d\x2dicons\x20\x2d\x2dtree\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1eeza\x20\x2d\x2dlong\x20\x2d\x2dheader\x20\x2d\x2dicons\x20\x2d\x2dtree\x20\x2d\x2dgit\x20\x2d\x2dgroup\x2ddirectories\x2dfirst\x1elazydocker\x1etmuxp\x20load\x20\x2dy\x20mail\x1etmuxp\x20load\x20\x2dy\x20notes\x2dtasks\x1esvn\x20\x2d\x2dconfig\x2ddir\x20\x5c\x5c\x5c\x5c\x22\x24XDG_CONFIG_HOME\x5c\x5c\x5c\x5c\x22/subversion\x1eyay\x20\x2dR\x20\x1eyay\x20\x2dSyu\x1etopgrade\x1envim\x1ewget\x20\x2d\x2dhsts\x2dfile\x3d\x22\x24XDG_DATA_HOME/wget\x2dhsts\x22\x1eyarn\x20\x2d\x2duse\x2dyarnrc\x20\x22\x24XDG_CONFIG_HOME/yarn/config\x22\x1e__zoxide_z\x1e__zoxide_zi
SETUVAR __fish_initialized:3800
SETUVAR _fish_abbr_d:docker
SETUVAR _fish_abbr_g:git

View file

@ -1,3 +0,0 @@
function bruh --wraps='genact -s 4' --description 'alias bruh=genact -s 4'
genact -s 4 $argv
end

View file

@ -1,3 +0,0 @@
function clock --wraps='tty-clock -sbc' --description 'alias clock=tty-clock -sbc'
tty-clock -sbc $argv
end

View file

@ -1,7 +0,0 @@
function codeinfo --wraps='scc ./' --description 'alias codeinfo=scc ./'
if type -f scc &>/dev/null
scc ./ $argv
else
missing_package scc
end
end

View file

@ -1,3 +0,0 @@
function cv --wraps=clear --wraps='z && v' --description 'alias cv=z && v'
z $argv && v
end

View file

@ -1,7 +0,0 @@
function disks --wraps=duf --description 'alias disks=duf'
if type -f duf &>/dev/null
duf $argv
else
missing_package duf
end
end

View file

@ -1,7 +0,0 @@
function dsize --wraps='dua i' --description 'alias dsize=dua i'
if type -f dua &>/dev/null
dua i $argv
else
missing_package dua-cli
end
end

View file

@ -1,3 +0,0 @@
function ex --wraps='sudo chmod +x' --description 'alias ex=sudo chmod +x'
sudo chmod +x $argv
end

View file

@ -1,7 +0,0 @@
function f --wraps=fzf --description 'alias f=fzf'
if type -f fzf &>/dev/null
fzf $argv
else
missing_package fzf
end
end

View file

@ -1,7 +0,0 @@
function fetch --wraps=fastfetch --description 'alias fetch=fastfetch'
if type -f fastfetch &>/dev/null
fastfetch $argv
else
missing_package fastfetch
end
end

View file

@ -1,7 +0,0 @@
function gfetch --wraps=onefetch --description 'alias gfetch=onefetch'
if type -f onefetch &>/dev/null
onefetch $argv
else
missing_package onefetch
end
end

View file

@ -1,7 +0,0 @@
function gpt --wraps='tgpt -i' --description 'alias gpt=tgpt -i'
if type -f tgpt &>/dev/null
tgpt $argv
else
missing_package tgpt
end
end

View file

@ -1,3 +0,0 @@
function gr --wraps='cd "$(git rev-parse --show-toplevel)"' --description 'alias gr=cd "$(git rev-parse --show-toplevel)"'
cd "$(git rev-parse --show-toplevel)" $argv
end

View file

@ -1,7 +0,0 @@
function info --wraps=tldr --description 'alias info=tldr'
if type -f tldr &>/dev/null
tldr $argv
else
missing_package tldr
end
end

View file

@ -1,3 +0,0 @@
function ip --description 'alias ip=ip -c a'
command ip -c a $argv
end

View file

@ -1,7 +0,0 @@
function ld --wraps=lazydocker --description 'alias ld=lazydocker'
if type -f lazydocker &>/dev/null
lazydocker $argv
else
missing_package lazydocker
end
end

View file

@ -0,0 +1,3 @@
function mail --description 'alias mail=tmuxp load -y mail'
tmuxp load -y mail $argv
end

View file

@ -1,3 +0,0 @@
function matrix --wraps='unimatrix -s 95' --description 'alias matrix=unimatrix -s 95'
unimatrix -s 95 $argv
end

View file

@ -1,4 +0,0 @@
function mkdir-cd --argument dir
mkdir -p -- $dir
and cd -- $dir
end

View file

@ -1,3 +0,0 @@
function mkdir --description 'alias mkdir=mkdir -p'
command mkdir -p $argv
end

View file

@ -0,0 +1,3 @@
function notes --wraps='tmuxp load -y notes-tasks' --description 'alias notes=tmuxp load -y notes-tasks'
tmuxp load -y notes-tasks $argv
end

View file

@ -1,3 +0,0 @@
function op --wraps='cd ~/Documents/Obsidian/obsidianVault' --description 'alias op=cd ~/Documents/Obsidian/obsidianVault'
tmuxp load -y notes-tasks
end

View file

@ -1,7 +0,0 @@
function pages --wraps=navi --description 'alias pages=navi'
if type -f navi &>/dev/null
navi $argv
else
missing_package navi
end
end

View file

@ -1,7 +0,0 @@
function proc --wraps=sysz --description 'alias proc=sysz'
if type -f sysz &>/dev/null
sysz $argv
else
missing_package sysz
end
end

View file

@ -1,8 +0,0 @@
function pse --wraps=pacseek --description 'alias pse=pacseek'
if type -f pacseek &>/dev/null
pacseek $argv
else
missing_package pacseek
end
end

View file

@ -1,3 +0,0 @@
function q --wraps=exit --description 'alias q=exit'
exit $argv
end

View file

@ -1,8 +0,0 @@
function r --wraps='mise run' --description 'alias r=mise run'
if type -f mise &>/dev/null
mise run $argv
else
missing_package mise
end
end

View file

@ -1,3 +0,0 @@
function s --wraps=sudo --description 'alias s=sudo'
sudo $argv
end

View file

@ -1,3 +0,0 @@
function sc --wraps='source $XDG_CONFIG_HOME/fish/config.fish' --description 'alias r=source $XDG_CONFIG_HOME/fish/config.fish'
source $XDG_CONFIG_HOME/fish/config.fish $argv
end

View file

@ -1,7 +0,0 @@
function t --wraps=tmux --description 'alias t=tmux'
if type -f tmux &>/dev/null
tmux new-session $argv
else
missing_package tmux
end
end

View file

@ -1,7 +0,0 @@
function ta --wraps='tmux attach -t' --description 'alias ta=tmux attach -t'
if type -f tmux &>/dev/null
tmux attach
else
missing_package tmux
end
end

View file

@ -1,3 +0,0 @@
function test-net --wraps='command up' --description 'alias test-net=command up'
command up $argv
end

View file

@ -1,3 +0,0 @@
function tr --wraps=trash --description 'alias tr=trash'
trash $argv
end

View file

@ -1,7 +0,0 @@
function vcl --wraps='nvim --clean' --description 'alias vcl=nvim --clean'
if type -f nvim &>/dev/null
nvim --clean $argv
else
missing_package nvim
end
end

View file

@ -1,3 +0,0 @@
function vv --wraps=bob --description 'alias vv=bob'
bob $argv
end

View file

@ -1,3 +0,0 @@
function vvl --wraps='bob use latest' --description 'alias vvl=bob use latest'
bob use latest $argv
end

View file

@ -1,3 +0,0 @@
function vvn --wraps='bob use nightly' --description 'alias vvn=bob use nightly'
bob use nightly $argv
end

View file

@ -63,6 +63,7 @@ fish_add_path $XDG_DATA_HOME/pnpm
set -xg EDITOR nvim
set -xg VISUAL $EDITOR
set -xg SUDO_EDITOR $EDITOR
set -xg PAGER bat
# GPG/LANG
set -xg GPG_TTY (tty)
@ -77,7 +78,8 @@ set -xg FZF_DEFAULT_OPTS "--height=90% --layout=reverse --info=inline --border r
--color=border:#6E738D,label:#CAD3F5 \
--bind 'ctrl-u:preview-half-page-up'
--bind 'ctrl-d:preview-half-page-down'
--bind 'ctrl-y:execute-silent(printf {} | cut -f 2- | wl-copy --trim-newline)'"
--bind 'ctrl-y:execute-silent(printf {} | cut -f 2- | wl-copy --trim-newline)'
--bind 'alt-j:down+down+down+down+down' --bind 'alt-k:up+up+up+up+up'"
set -xg fzf_preview_dir_cmd eza --long --header --icons --all --color=always --group-directories-first --hyperlink
set -xg fzf_fd_opts --hidden --color=always
set -xg _ZO_FZF_OPTS $FZF_DEFAULT_OPTS '--preview "{$fzf_preview_dir_cmd} {2}"'

View file

@ -1,4 +1,4 @@
theme = catppuccin-macchiato
theme = Catppuccin Macchiato
background-blur-radius = 20
font-family = Maple Mono NF
@ -17,16 +17,15 @@ gtk-single-instance = true
window-theme = system
gtk-titlebar = false
gtk-wide-tabs = false
gtk-adwaita = false
macos-titlebar-style = hidden
macos-option-as-alt = true
mouse-hide-while-typing = true
confirm-close-surface = false
window-padding-x = 6
window-padding-y = 5,5
window-padding-balance = false
window-padding-x = 4,5
window-padding-y = 4,5
window-padding-balance = true
auto-update = check
auto-update-channel = stable

View file

@ -61,203 +61,4 @@
[alias]
aliases = config --get-regexp alias
a = add --all
ai = add -i
ap = apply
as = apply --stat
ac = apply --check
ama = am --abort
amr = am --resolved
ams = am --skip
b = branch
ba = branch -a
bd = branch -d
bdd = branch -D
br = branch -r
bc = rev-parse --abbrev-ref HEAD
bu = !git rev-parse --abbrev-ref --symbolic-full-name "@{u}"
bs = !git-branch-status
c = commit
ca = commit -a
cm = commit -m
cam = commit -am
cem = commit --allow-empty -m
cd = commit --amend
cad = commit -a --amend
ced = commit --allow-empty --amend
cl = clone
cld = clone --depth 1
clg = !sh -c 'git clone https://github.com/$1 $(basename $1)' -
clgp = !sh -c 'git clone git@github.com:$1 $(basename $1)' -
clgu = !sh -c 'git clone git@github.com:$(git config --get user.username)/$1 $1' -
cp = cherry-pick
cpa = cherry-pick --abort
cpc = cherry-pick --continue
d = diff
dp = diff --patience
dc = diff --cached
dk = diff --check
dck = diff --cached --check
dt = difftool
dct = difftool --cached
f = fetch
fo = fetch origin
fu = fetch upstream
fp = format-patch
fk = fsck
g = grep -p
l = log --oneline --graph --decorate
lg = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
ls = ls-files
lsf = !git ls-files | grep -i
m = merge
mm = merge --no-ff -m "🔀 merge: Merge branch '$(git symbolic-ref --short HEAD)' into '$(git branch --show-current)'"
ma = merge --abort
mc = merge --continue
ms = merge --skip
o = checkout
om = checkout master
ob = checkout -b
opr = !sh -c 'git fo pull/$1/head:pr-$1 && git o pr-$1'
pr = prune -v
ps = push
psf = push -f
psu = push -u
pst = push --tags
pso = push origin
psao = push --all origin
psfo = push -f origin
psuo = push -u origin
psom = push origin master
psaom = push --all origin master
psfom = push -f origin master
psuom = push -u origin master
psoc = !git push origin $(git bc)
psaoc = !git push --all origin $(git bc)
psfoc = !git push -f origin $(git bc)
psuoc = !git push -u origin $(git bc)
psdc = !git push origin :$(git bc)
pl = pull
pb = pull --rebase
plo = pull origin
pbo = pull --rebase origin
plom = pull origin master
ploc = !git pull origin $(git bc)
pbom = pull --rebase origin master
pboc = !git pull --rebase origin $(git bc)
plu = pull upstream
plum = pull upstream master
pluc = !git pull upstream $(git bc)
pbum = pull --rebase upstream master
pbuc = !git pull --rebase upstream $(git bc)
rb = rebase
rba = rebase --abort
rbc = rebase --continue
rbi = rebase --interactive
rbs = rebase --skip
re = reset
rh = reset HEAD
reh = reset --hard
rem = reset --mixed
res = reset --soft
rehh = reset --hard HEAD
remh = reset --mixed HEAD
resh = reset --soft HEAD
rehom = reset --hard origin/master
r = remote
ra = remote add
rr = remote rm
rv = remote -v
rn = remote rename
rp = remote prune
rs = remote show
rao = remote add origin
rau = remote add upstream
rro = remote remove origin
rru = remote remove upstream
rso = remote show origin
rsu = remote show upstream
rpo = remote prune origin
rpu = remote prune upstream
rmf = rm -f
rmrf = rm -r -f
s = status
sb = status -s -b
sa = stash apply
sc = stash clear
sd = stash drop
sl = stash list
sp = stash pop
ss = stash save
ssk = stash save -k
sw = stash show
st = !git stash list | wc -l 2>/dev/null | grep -oEi '[0-9][0-9]*'
t = tag
td = tag -d
w = show
wp = show -p
wr = show -p --no-color
svnr = svn rebase
svnd = svn dcommit
svnl = svn log --oneline --show-commit
subadd = !sh -c 'git submodule add git://github.com/$1 $2/$(basename $1)' -
subrm = !sh -c 'git submodule deinit -f -- $1 && rm -rf .git/modules/$1 && git rm -f $1' -
subup = submodule update --init --recursive
subpull = submodule foreach 'git pull --tags -f origin master || git pull --tags -f origin main'
assume = update-index --assume-unchanged
unassume = update-index --no-assume-unchanged
assumed = !git ls -v | grep ^h | cut -c 3-
unassumeall = !git assumed | xargs git unassume
assumeall = !git status -s | awk {'print $2'} | xargs git assume
bump = !sh -c 'git commit -am \"Version bump v$1\" && git psuoc && git release $1' -
release = !sh -c 'git tag v$1 && git pst' -
unrelease = !sh -c 'git tag -d v$1 && git pso :v$1' -
merged = !sh -c 'git o master && git plom && git bd $1 && git rpo' -
aliases = !git config -l | grep alias | cut -c 7-
snap = !git stash save 'snapshot: $(date)' && git stash apply 'stash@{0}'
bare = !sh -c 'git symbolic-ref HEAD refs/heads/$1 && git rm --cached -r . && git clean -xfd' -
whois = !sh -c 'git log -i -1 --author=\"$1\" --pretty=\"format:%an <%ae>\"' -
serve = daemon --reuseaddr --verbose --base-path=. --export-all ./.git
behind = !git rev-list --left-only --count $(git bu)...HEAD
ahead = !git rev-list --right-only --count $(git bu)...HEAD
ours = "!f() { git checkout --ours $@ && git add $@; }; f"
theirs = "!f() { git checkout --theirs $@ && git add $@; }; f"
subrepo = !sh -c 'git filter-branch --prune-empty --subdirectory-filter $1 master' -
human = name-rev --name-only --refs=refs/heads/*
ig = "!f() { gitignore \"$@\"; }; f"

View file

@ -18,7 +18,7 @@ bind = $mainMod SHIFT, N, exec, $notifications-menu-read
bind = $mainMod CTRL, N, exec, $notifications-menu-disturb
## Bar
bind = $mainMod, R, exec, $bar-reload
bind = $mainMod CTRL, R, exec, $bar-reload
bind = $mainMod, T, exec, $bar-toggle
# Pickers/Launchers
@ -118,26 +118,26 @@ bind = $mainMod, 8, workspace, r~8
bind = $mainMod, 9, workspace, r~9
## Moving Windows to other Workspaces
bind = $mainMod SHIFT, 1, movetoworkspace, r~1
bind = $mainMod SHIFT, 2, movetoworkspace, r~2
bind = $mainMod SHIFT, 3, movetoworkspace, r~3
bind = $mainMod SHIFT, 4, movetoworkspace, r~4
bind = $mainMod SHIFT, 5, movetoworkspace, r~5
bind = $mainMod SHIFT, 6, movetoworkspace, r~6
bind = $mainMod SHIFT, 7, movetoworkspace, r~7
bind = $mainMod SHIFT, 8, movetoworkspace, r~8
bind = $mainMod SHIFT, 9, movetoworkspace, r~9
bind = $mainMod SHIFT, 1, movetoworkspacesilent, r~1
bind = $mainMod SHIFT, 2, movetoworkspacesilent, r~2
bind = $mainMod SHIFT, 3, movetoworkspacesilent, r~3
bind = $mainMod SHIFT, 4, movetoworkspacesilent, r~4
bind = $mainMod SHIFT, 5, movetoworkspacesilent, r~5
bind = $mainMod SHIFT, 6, movetoworkspacesilent, r~6
bind = $mainMod SHIFT, 7, movetoworkspacesilent, r~7
bind = $mainMod SHIFT, 8, movetoworkspacesilent, r~8
bind = $mainMod SHIFT, 9, movetoworkspacesilent, r~9
## Moving Windows to other Workspaces (Silent)
bind = $mainMod ALT, 1, movetoworkspacesilent, r~1
bind = $mainMod ALT, 2, movetoworkspacesilent, r~2
bind = $mainMod ALT, 3, movetoworkspacesilent, r~3
bind = $mainMod ALT, 4, movetoworkspacesilent, r~4
bind = $mainMod ALT, 5, movetoworkspacesilent, r~5
bind = $mainMod ALT, 6, movetoworkspacesilent, r~6
bind = $mainMod ALT, 7, movetoworkspacesilent, r~7
bind = $mainMod ALT, 8, movetoworkspacesilent, r~8
bind = $mainMod ALT, 9, movetoworkspacesilent, r~9
bind = $mainMod ALT, 1, movetoworkspace, r~1
bind = $mainMod ALT, 2, movetoworkspace, r~2
bind = $mainMod ALT, 3, movetoworkspace, r~3
bind = $mainMod ALT, 4, movetoworkspace, r~4
bind = $mainMod ALT, 5, movetoworkspace, r~5
bind = $mainMod ALT, 6, movetoworkspace, r~6
bind = $mainMod ALT, 7, movetoworkspace, r~7
bind = $mainMod ALT, 8, movetoworkspace, r~8
bind = $mainMod ALT, 9, movetoworkspace, r~9
## Moving to other Workspace with Mouse Control
bind = $mainMod, mouse_down, workspace, m-1

View file

@ -12,11 +12,11 @@ $notifications-menu-toggle = $notifications-menu -t
$notifications-menu-disturb = $notifications-menu -d
$notifications-menu-reload = $notifications-menu -R && $notifications-menu -rs
$browser = zen-browser
$browser = librewolf
$notetaking-app = obsidian
$terminal = ghostty --gtk-single-instance=true
$office-suite = libreoffice
$editor = $terminal nvim
$editor = $terminal vim
$alter-editor = vscodium
$file-manager = yazi
$file-manager = ranger
$alter-file-manager = nemo

View file

@ -1,10 +1,12 @@
input {
kb_layout = us, es
# kb_variant = colemak_dh
kb_options = compose:rctrl, level3:ralt_switch, grp:win_space_toggle, caps:escape
kb_layout=us,rs,rs,de
kb_variant=,latinyz,yz,qwerty
kb_options=caps:swapescape,grp:alt_shift_toggle
follow_mouse = 1
numlock_by_default = true
repeat_rate=50
repeat_delay=300
touchpad {
natural_scroll = yes

View file

@ -27,8 +27,3 @@ dwindle {
force_split = 0
preserve_split = true
}
gestures {
workspace_swipe = yes
workspace_swipe_fingers = 4
}

View file

@ -1,9 +1,5 @@
# Main Monitor
monitor=DP-1, 2560x1080@74.99, 0x1080,1.0
monitor=eDP-1, preferred, auto, 1
# Second Monitor
monitor=DP-3, 2560x1080@74.99, 0x0,1.0
# Third Monitor
monitor=HDMI-A-1, 1920x1080@74.97, 2560x300,1.0
monitor=HDMI-A-1, transform, 3

View file

@ -1,32 +1,22 @@
# Main Monitor
workspace = 1, monitor:DP-1, default:true
workspace = 2, monitor:DP-1
workspace = 3, monitor:DP-1
workspace = 4, monitor:DP-1
workspace = 5, monitor:DP-1
workspace = 6, monitor:DP-1
workspace = 7, monitor:DP-1, rounding:false, decorate:false, gapsin:0, gapsout:0, border:false, decorate:false # Gaming Workspace
workspace = 8, monitor:DP-1
workspace = 9, monitor:DP-1
workspace = 1, monitor:eDP-1, default:true
workspace = 2, monitor:eDP-1
workspace = 3, monitor:eDP-1
workspace = 4, monitor:eDP-1
workspace = 5, monitor:eDP-1
workspace = 6, monitor:eDP-1
workspace = 7, monitor:eDP-1,
workspace = 8, monitor:eDP-1
workspace = 9, monitor:eDP-1
# Second Monitor
workspace = 10, monitor:DP-3, default:true
workspace = 11, monitor:DP-3
workspace = 12, monitor:DP-3
workspace = 13, monitor:DP-3
workspace = 14, monitor:DP-3
workspace = 15, monitor:DP-3
workspace = 16, monitor:DP-3
workspace = 17, monitor:DP-3
workspace = 18, monitor:DP-3
# Third Monitor
workspace = 19, monitor:HDMI-A-1, default:true
workspace = 20, monitor:HDMI-A-1
workspace = 21, monitor:HDMI-A-1
workspace = 22, monitor:HDMI-A-1
workspace = 23, monitor:HDMI-A-1
workspace = 24, monitor:HDMI-A-1
workspace = 25, monitor:HDMI-A-1
workspace = 26, monitor:HDMI-A-1
workspace = 27, monitor:HDMI-A-1
workspace = 10, monitor:HDMI-A-1, default:true
workspace = 11, monitor:HDMI-A-1
workspace = 12, monitor:HDMI-A-1
workspace = 13, monitor:HDMI-A-1
workspace = 14, monitor:HDMI-A-1
workspace = 15, monitor:HDMI-A-1
workspace = 16, monitor:HDMI-A-1
workspace = 17, monitor:HDMI-A-1
workspace = 18, monitor:HDMI-A-1

View file

@ -24,3 +24,10 @@ command = "nm-connection-editor"
animation = "fromRight"
margin = 20
lazy = true
[wallpapers]
path = "~/.config/hypr/theme/walls/"
interval = 1440 # change every day
command = "swww img --transition-bezier 0.5,1.19,.8,.4 --transition-type wipe --transition-duration 2 --transition-fps 75 \"[file]\" && notify-send 'Wallpaper Changed' -i \"[file]\" --app-name=Wallpaper"
clear_command = "swww clear"
extensions = ["jpg", "png", "gif", "jpeg"]

View file

@ -4,6 +4,6 @@
feishin &
# Terminal Apps
# kitty --class btop btop &
# kitty --class nvtop nvtop &
kitty --class btop btop &
kitty --class radeontop radeontop &
ghostty --gtk-single-instance=true --quit-after-last-window-closed=false --initial-window=false &

View file

@ -29,8 +29,13 @@ wl-paste --watch cliphist store &
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &
# Audio
pipewire &
wireplumber &
pipewire-pulse &
easyeffects --gapplication-service &
libinput-gestures &
# Random Wallpaper
"$HOME"/.config/hypr/scripts/random_wallpaper &

View file

@ -2,7 +2,7 @@ source = ./colors.conf
general {
border_size = 2
col.active_border = rgba($lavenderAlpha80)
col.active_border = rgba($lavenderAlphaB0)
col.inactive_border = rgba($textAlpha40)
gaps_in = 5

View file

@ -1,9 +1,4 @@
# Base Rules
$center-float-large = class:^(center-float-large)$|^(.*qimgv.*)$|^(.*mpv.*)$
windowrule = float, $center-float-large
windowrule = size 70% 70%, $center-float-large
windowrule = center 1, $center-float-large
$center-float = class:^(center-float)$
$center-float-title = title:^(.*Open Folder.*)$|^(.*Open File.*)$|^(.*Save File.*)$|^(.*Save Folder.*)$|^(.*Save Image.*)$|^(.*Save As.*)$|^(.*Open As.*)$
windowrule = float, $center-float
@ -36,30 +31,25 @@ windowrule = float, xfce-polkit|wleave|title:branchdialog|nwg-look|nm-connection
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
## System
windowrule = workspace 8, class:^(.*virt-manager.*)$|(.*PikaBackup.*)$|(.*VirtualBox Manager.*)$|(.*Vmware*)$
windowrule = workspace 17, class:^(.*GParted.*)$|(.*clamtk.*)$|(.*gnome.Logs.*)$
windowrule = workspace 5, class:^(.*virt-manager.*)$|(.*PikaBackup.*)$|(.*VirtualBox Manager.*)$|(.*Vmware*)$
windowrule = workspace 5, class:^(.*GParted.*)$|(.*clamtk.*)$|(.*gnome.Logs.*)$
## Gaming
windowrule = workspace 7, class:^(.*steam_app.*)$|(.*gamescope.*)$|(.*atlauncher.*)$|(.*Minecraft.*)$
windowrule = workspace 16 silent, class:^([Ss]team)$|(.*heroic.*)$
windowrule = workspace 7, class:^(.*Ryujinx.*)$|(.*cemu.*)$|(.*dolphin.*)$|(.*RetroArch.*)$|(.*xemu.*)$|(.*duckstation.*)$|(.*rpcs3.*)$
windowrule = workspace 6, class:^(.*steam_app.*)$|(.*gamescope.*)$|(.*atlauncher.*)$|(.*Minecraft.*)$
windowrule = workspace 15 silent, class:^([Ss]team)$|(.*heroic.*)$
windowrule = workspace 15, class:^(.*Ryujinx.*)$|(.*cemu.*)$|(.*dolphin.*)$|(.*RetroArch.*)$|(.*xemu.*)$|(.*duckstation.*)$|(.*rpcs3.*)$
## Media
windowrule = workspace 6, class:^(.*kdenlive.*)$
windowrule = workspace 21 silent, class:^(.*thunderbird.*)$
windowrule = workspace 22 silent, class:^(.*btop.*)$
windowrule = workspace 22 silent, class:^(.*nvtop.*)$
windowrule = workspace 22 silent, class:^(.*radeontop.*)$
windowrule = workspace 19 silent, class:^(.*[Ss]potify.*)$|(.*tidal-hifi.*)$|(.*You[Tt]ube Music.*)$|^(.*feishin.*)$
windowrule = workspace 20 silent, class:^(.*discord.*)$|(.*vesktop.*)$|(.*WebCord.*)$|(.*legcord.*)$
windowrule = workspace 15, class:^(.*obsproject.*)$
windowrule = workspace 14, class:^(.*easyeffects.*)$|^(.*qpwgraph.*)$|(.*Helvum.*)$|(.*nicotine_plus.*)$|(.*Picard*)$
windowrule = workspace 5, class:^(.*vital.*)$|(.*fl64.*)$
windowrule = workspace 5, title:^(.*FL Studio.*)$
windowrule = workspace 4, class:^(.*kdenlive.*)$
windowrule = workspace 12 silent, class:^(.*[Ss]potify.*)$|(.*tidal-hifi.*)$|(.*You[Tt]ube Music.*)$|^(.*feishin.*)$
windowrule = workspace 7 silent, class:^(.*discord.*)$|(.*vesktop.*)$|(.*WebCord.*)$|(.*legcord.*)$
windowrule = workspace 4, class:^(.*obsproject.*)$
windowrule = workspace 12, class:^(.*easyeffects.*)$|^(.*qpwgraph.*)$|(.*Helvum.*)$|(.*nicotine_plus.*)$|(.*Picard*)$
windowrule = workspace 3, class:^(.*vital.*)$|(.*fl64.*)$
windowrule = workspace 3, title:^(.*FL Studio.*)$
windowrule = workspace 4, class:^(.*pinta.*)$|(.*krita.*)$|(.*blender.*)$|(.*Upscayl.*)$
## Productivity/Dev
windowrule = workspace 9 silent, class:^(.*obsidian.*)$|(.*Zotero.*)$
windowrule = workspace 2, class:^(.*Code.*)$|(.*codium.*)$|(.*VSCodium.*)$|(.*neovide.*)$
@ -105,11 +95,6 @@ windowrule = noblur, $videobridge
windowrule = noinitialfocus, $videobridge
windowrule = maxsize 1 1, $videobridge
$zathura = class:^(.*zathura.*)$
windowrule = float, $zathura
windowrule = size 35% 90%, $zathura
windowrule = center 1, $zathura
$scrcpy = class:^(.*scrcpy.*)$
windowrule = center 1, $scrcpy
windowrule = float, $scrcpy

22
.config/isyncrc Normal file
View file

@ -0,0 +1,22 @@
# Remote Vault
IMAPStore proton-remote
Account proton
# Local Vault
MaildirStore proton-local
Path ~/.mail/proton/
Inbox ~/.mail/proton/INBOX
Subfolders Verbatim
# Sync Channel
Channel proton-default
Far :proton-remote:
Near :proton-local:
Patterns * !"All Mail"
Create Both
Expunge Both
SyncState *
# Sync Inbox
Group proton
Channel proton-default

BIN
.config/legcord/.github/title.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,57 @@
{
"windowStyle": "native",
"channel": "stable",
"bounceOnPing": false,
"legcordCSP": true,
"minimizeToTray": true,
"keybinds": [],
"audio": {
"workaround": true,
"deviceSelect": true,
"granularSelect": true,
"ignoreVirtual": false,
"ignoreDevices": false,
"ignoreInputMedia": false,
"onlySpeakers": false,
"onlyDefaultSpeakers": true,
"loopbackType": "loopback"
},
"multiInstance": false,
"mods": [
"equicord"
],
"transparency": "universal",
"spellcheck": true,
"hardwareAcceleration": true,
"performanceMode": "dynamic",
"skipSplash": true,
"inviteWebsocket": true,
"startMinimized": false,
"disableHttpCache": false,
"customJsBundle": "https://legcord.app/placeholder.js",
"customCssBundle": "https://legcord.app/placeholder.css",
"disableAutogain": false,
"autoHideMenuBar": true,
"blockPowerSavingInVoiceChat": false,
"useMacSystemPicker": true,
"mobileMode": false,
"tray": "ac_plug_colored",
"doneSetup": true,
"popoutPiP": false,
"spellcheckLanguage": [
"en-US"
],
"sleepInBackground": false,
"noBundleUpdates": false,
"additionalArguments": "",
"customIcon": "/usr/lib/legcord/resources/app.asar/assets/desktop.png",
"smoothScroll": true,
"autoScroll": false,
"useSystemCssEditor": false,
"modCache": {
"shelter": "1b35b8802a85809742af99f454bb941f56f759a3",
"vencord": "cf78ddcfe27e48d3c49e6a12a4bf1834ae6ea29c",
"equicord": "01246da078d89a49ce580b80c5ae108526b3b457"
},
"overlayButtonColor": "#121214"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View file

@ -1,80 +0,0 @@
---
runtime:
threads: ~
release:
check: true
manifest:
enable: false
secondary:
- url: "https://cdn.losbroxas.org/manifest.yaml"
enable: true
language: en-US
theme: dark
roots:
- store: steam
path: ~/.local/share/Steam
- store: heroic
path: ~/.config/heroic
- store: steam
path: ~/games/SteamLibrary
- store: other
path: ~/.local/share/dolphin-emu
- store: other
path: ~/.config/Ryujinx
redirects: []
backup:
path: ~/games/gamesaves
ignoredGames: []
filter:
excludeStoreScreenshots: false
cloud:
exclude: false
epic: false
gog: false
origin: false
steam: false
uplay: false
ignoredPaths: []
ignoredRegistry: []
toggledPaths: {}
toggledRegistry: {}
sort:
key: status
reversed: false
retention:
full: 1
differential: 0
format:
chosen: zip
zip:
compression: deflate
compression:
deflate:
level: 6
bzip2:
level: 6
zstd:
level: 10
onlyConstructive: false
restore:
path: ~/games/gamesaves
ignoredGames: []
toggledPaths: {}
toggledRegistry: {}
sort:
key: status
reversed: false
reverseRedirects: false
scan:
showDeselectedGames: true
showUnchangedGames: true
showUnscannedGames: true
cloud:
remote: ~
path: ludusavi-backup
synchronize: true
apps:
rclone:
path: /usr/bin/rclone
arguments: "--fast-list --ignore-checksum"
customGames: []

View file

@ -14,12 +14,17 @@ watchexec = "latest"
"cargo:cargo-cache" = "latest"
"cargo:kanata" = "latest"
"cargo:atac" = "latest"
"cargo:youtube-tui" = "latest"
"cargo:dedoc" = "latest"
"cargo:https://github.com/fioncat/otree" = "latest"
# Go Tools
"go:github.com/stefanlogue/meteor" = "latest"
# "go:github.com/rszyma/kanata-tray" = "latest"
"go:github.com/crumbyte/noxdir" = "latest"
"go:github.com/sahaj-b/wakafetch" = "latest"
"go:github.com/jbensmann/mouseless" = "latest"
"go:github.com/jorgerojas26/lazysql" = "latest"
# "go:github.com/guyfedwards/nom" = "latest"
"go:github.com/boyter/scc/v3" = "latest"
# Python Tools
"pipx:darrenburns/posting" = "latest"

View file

@ -1,66 +0,0 @@
# Progress
# 60 seconds
CTRL+SHIFT+l seek 60
CTRL+SHIFT+l seek -60
CTRL+SHIFT+RIGHT seek 60
CTRL+SHIFT+LEFT seek -60
# 30 seconds
SHIFT+l seek 30
SHIFT+h seek -30
SHIFT+RIGHT seek 30
SHIFT+LEFT seek -30
# 10 seconds
CTRL+l seek 10
CTRL+h seek -10
CTRL+RIGHT seek 10
CTRL+LEFT seek -10
# 5 seconds
l seek 5
h seek -5
RIGHT seek 5
LEFT seek -5
# 2 seconds
ALT+l seek 2
ALT+h seek -2
ALT+RIGHT seek 2
ALT+LEFT seek -2
# Disables all normal mouse scrolls
WHEEL_LEFT ignore
WHEEL_RIGHT ignore
# Audio
# 100%
CTRL+SHIFT+k add volume 100
CTRL+SHIFT+j add volume -100
CTRL+SHIFT+UP add volume 100
CTRL+SHIFT+DOWN add volume -100
# 50%
SHIFT+k add volume 50
SHIFT+j add volume -50
SHIFT+UP add volume 50
SHIFT+DOWN add volume -50
# 25%
CTRL+k add volume 25
CTRL+j add volume -25
CTRL+UP add volume 25
CTRL+DOWN add volume -25
# 10%
k add volume 10
j add volume -10
UP add volume 10
DOWN add volume -10
# 5%
ALT+k add volume 5
ALT+j add volume -5
ALT+UP add volume 5
ALT+DOWN add volume -5

View file

@ -1,15 +1,4 @@
# Uses GPU-accelerated video output by default.
#vo=gpu
# Can cause performance problems with some GPU drivers and GPUs.
#profile=gpu-hq
# ===== REMOVE THE ABOVE FOUR LINES AND RESAVE IF YOU ENCOUNTER PLAYBACK ISSUES AFTER =====
# Source: https://github.com/hl2guide/better-mpv-config
# External Sources:
# * https://raw.githubusercontent.com/classicjazz/mpv-config/master/mpv.conf
gpu-context=wayland
# Theme
background-color='#24273a'
@ -19,14 +8,17 @@ osd-color='#cad3f5'
osd-shadow-color='#24273a'
# Screenshots
screenshot-directory='~/Imagenes/Capturas/PC'
screenshot-directory='~'
screenshot-template='mpv-%f-%p'
# Enables best HW decoder; turn off for software decoding
hwdec=auto
# IPC
input-ipc-server=/tmp/mpv-socket
# Keeps open the window after a video is finished
keep-open
# keep-open
border=no # hides the window title bar
msg-color=yes # color log messages on terminal
@ -41,13 +33,6 @@ osd-font-size=35
# Saves the seekbar position on exit
save-position-on-quit=yes
# Uses a large seekable RAM cache even for local input.
cache=yes
# cache-secs=300
# Uses extra large RAM cache (needs cache=yes to make it useful).
demuxer-max-bytes=1800M
demuxer-max-back-bytes=1200M
# Sets the profile restore method to "copy if equal"
profile-restore=copy-equal
@ -56,204 +41,15 @@ profile-restore=copy-equal
# Sets volume to 100%.
volume=100
# Normalizes audio
# af-add='dynaudnorm=g=5:f=250:r=0.9:p=0.5'
# ===== Color Space =====
target-trc=auto
gamma-auto
vf=format=colorlevels=full:colormatrix=auto
video-output-levels=full
# ===== Dithering =====
dither-depth=auto
temporal-dither=yes
dither=fruit
# ===== Debanding =====
deband=yes # enabled by default
deband-iterations=4 # deband steps
deband-threshold=48 # deband strength
deband-range=16 # deband range
deband-grain=48 # dynamic grain: set to "0" if using the static grain shader
# Sets maximum volume to 200%.
volume-max=200
# Audio language: German
alang=ger
# ===== Subtitles =====
blend-subtitles=yes
# ===== Motion Interpolation =====
override-display-fps=75
video-sync=display-resample
interpolation=yes
tscale=oversample # smoothmotion
# ===== Anti-Ringing =====
scale-antiring=0.7 # luma upscale deringing
dscale-antiring=0.7 # luma downscale deringing
cscale-antiring=0.7 # chroma upscale deringing
# ===== Upscaling & Processing =====
glsl-shaders-clr
# luma upscaling
# note: any FSRCNNX above FSRCNNX_x2_8-0-4-1 is not worth the additional computional overhead
glsl-shaders="~/.config/mpv/shaders/FSRCNNX_x2_8-0-4-1.glsl"
scale=ewa_lanczos
# luma downscaling
# note: ssimdownscaler is tuned for mitchell and downscaling=no
glsl-shaders-append="~/.config/mpv/shaders/SSimDownscaler.glsl"
dscale=mitchell
linear-downscaling=no
# chroma upscaling and downscaling
glsl-shaders-append="~/.config/mpv/shaders/KrigBilateral.glsl"
cscale=mitchell
sigmoid-upscaling=yes
# ===== Custom Profiles =====
# Uses specific naming convensions for shorter easier typing.
# Naming Convensions:
# V = Very Low, L = Low, M = Medium, H = High, U = Ultra, S = Supreme
# Very Low = 480p, Low = 720p, Medium = 1080p, High = 1440p, Ultra = 2160p (4K), Supreme = 4320p (8K)
# 30 = 30 frames per second, 60 = 60 frames per second
# Use the switch e.g: --profile=H60
# 4320p (8K) 60 FPS
[S60]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Supereme - 4320p (8K) - 60 FPS"
ytdl-format=bestvideo[height<=?4320][fps<=?60][vcodec!=?vp9]+bestaudio/best
# 4320p (8K) 30 FPS
[S30]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Supereme - 4320p (8K) - 30 FPS"
ytdl-format=bestvideo[height<=?4320][fps<=?30][vcodec!=?vp9]+bestaudio/best
# 2160p (4K) 60 FPS
[U60]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Ultra - 2160p (4K) - 60 FPS"
ytdl-format=bestvideo[height<=?2160][fps<=?60][vcodec!=?vp9]+bestaudio/best
# 2160p (4K) 30 FPS
[U30]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Ultra - 2160p (4K) - 30 FPS"
ytdl-format=bestvideo[height<=?2160][fps<=?30][vcodec!=?vp9]+bestaudio/best
# 1440p 60 FPS
[H60]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="High - 1440p - 60 FPS"
ytdl-format=bestvideo[height<=?1440][fps<=?60][vcodec!=?vp9]+bestaudio/best
# 1440p 30 FPS
[H30]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="High - 1440p - 30 FPS"
ytdl-format=bestvideo[height<=?1440][fps<=?30][vcodec!=?vp9]+bestaudio/best
# 1080p 60 FPS
[M60]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Medium - 1080p - 60 FPS"
ytdl-format=bestvideo[height<=?1080][fps<=?60][vcodec!=?vp9]+bestaudio/best
# 1080p 30 FPS
[M30]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Medium - 1080p - 30 FPS"
ytdl-format=bestvideo[height<=?1080][fps<=?30][vcodec!=?vp9]+bestaudio/best
# 720p 60 FPS
[L60]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Low - 720p - 60 FPS"
ytdl-format=bestvideo[height<=?720][fps<=?60][vcodec!=?vp9]+bestaudio/best
# 720p 30 FPS
[L30]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Low - 720p - 30 FPS"
ytdl-format=bestvideo[height<=?720][fps<=?30][vcodec!=?vp9]+bestaudio/best
# 480p 60 FPS
[V60]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Very Low - 480p - 60 FPS"
ytdl-format=bestvideo[height<=?480][fps<=?60][vcodec!=?vp9]+bestaudio/best
# 480p 30 FPS
[V30]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc="Very Low - 480p - 30 FPS"
ytdl-format=bestvideo[height<=?480][fps<=?30][vcodec!=?vp9]+bestaudio/best
# Other Profiles
[4k60] # 2160p @ 60fps (3840x2160 UHDTV)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=4k60
profile-cond=((width ==3840 and height ==2160) and p["estimated-vf-fps"]>=31)
# deband=yes # necessary to avoid blue screen with KrigBilateral.glsl
deband=no # turn off debanding because presume wide color gamut
interpolation=no # turn off interpolation because presume 60fps
# UHD videos are already 4K so no luma upscaling is needed
# UHD videos are YUV420 so chroma upscaling is still needed
glsl-shaders-clr
# glsl-shaders="~/.config/mpv/shaders/KrigBilateral.glsl" # enable if your hardware can support it
interpolation=no # no motion interpolation required because 60fps is hardware ceiling
# no deinterlacer required because progressive
[4k30] # 2160p @ 24-30fps (3840x2160 UHDTV)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=4k30
profile-cond=((width ==3840 and height ==2160) and p["estimated-vf-fps"]<31)
# deband=yes # necessary to avoid blue screen with KrigBilateral.glsl
deband=no # turn off debanding because presume wide color gamut
# UHD videos are already 4K so no luma upscaling is needed
# UHD videos are YUV420 so chroma upscaling is still needed
glsl-shaders-clr
# glsl-shaders="~/.config/mpv/shaders/KrigBilateral.glsl" # enable if your hardware can support it
# apply motion interpolation
# no deinterlacer required because progressive
[full-hd60] # 1080p @ 60fps (progressive ATSC)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=full-hd60
profile-cond=((width ==1920 and height ==1080) and not p["video-frame-info/interlaced"] and p["estimated-vf-fps"]>=31)
# apply all luma and chroma upscaling and downscaling settings
interpolation=no # no motion interpolation required because 60fps is hardware ceiling
# no deinterlacer required because progressive
[full-hd30] # 1080p @ 24-30fps (NextGen TV/ATSC 3.0, progressive Blu-ray)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=full-hd30
profile-cond=((width ==1920 and height ==1080) and not p["video-frame-info/interlaced"] and p["estimated-vf-fps"]<31)
# apply all luma and chroma upscaling and downscaling settings
# apply motion interpolation
# no deinterlacer required because progressive
[full-hd-interlaced] # 1080i @ 24-30fps (HDTV, interlaced Blu-rays)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=full-hd-interlaced
profile-cond=((width ==1920 and height ==1080) and p["video-frame-info/interlaced"] and p["estimated-vf-fps"]<31)
# apply all luma and chroma upscaling and downscaling settings
# apply motion interpolation
vf=bwdif # apply FFMPEG's bwdif deinterlacer
[hd] # 720p @ 60 fps (HDTV, Blu-ray - progressive)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=hd
profile-cond=(width ==1280 and height ==720)
# apply all luma and chroma upscaling and downscaling settings
interpolation=no # no motion interpolation required because 60fps is hardware ceiling
# no deinterlacer required because progressive
[sdtv-ntsc] # 640x480, 704x480, 720x480 @ 30fps (NTSC DVD - interlaced)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=sdtv-ntsc
profile-cond=((width ==640 and height ==480) or (width ==704 and height ==480) or (width ==720 and height ==480))
# apply all luma and chroma upscaling and downscaling settings
# apply motion interpolation
vf=bwdif # apply FFMPEG's bwdif deinterlacer
[sdtv-pal] # 352x576, 480x576, 544x576, 720x576 @ 30fps (PAL broadcast or DVD - interlaced)
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=sdtv-pal
profile-cond=((width ==352 and height ==576) or (width ==480 and height ==576) or (width ==544 and height ==576) or (width ==720 and height ==576))
# apply all luma and chroma upscaling and downscaling settings
# apply motion interpolation
vf=bwdif # apply FFMPEG's bwdif deinterlacer
[default]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
sub-auto=fuzzy
slang=ger
# ===== File Type Profiles =====
# GIF Files
@ -270,21 +66,7 @@ profile-desc=webm
no-pause
loop-file=yes
# ===== Protocol Specific Configuration =====
[protocol.http]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=http
hls-bitrate=max # use max quality for HLS streams
cache=yes
no-cache-pause # don't pause when the cache runs low
[protocol.https]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=https
profile=protocol.http
[protocol.ytdl]
profile-restore=copy-equal # Sets the profile restore method to "copy if equal"
profile-desc=ytdl
profile=protocol.http
ytdl-raw-options=ignore-config=,sub-format=de,write-sub=

BIN
.config/mpv/mpv_websocket Executable file

Binary file not shown.

View file

@ -0,0 +1,2 @@
font_size=38
scale=3

View file

@ -0,0 +1,455 @@
------------- Instructions -------------
-- -- Video Demonstration: https://www.youtube.com/watch?v=M4t7HYS73ZQ
-- IF USING WEBSOCKET (RECOMMENDED)
-- -- Install the mpv_webscoket extension: https://github.com/kuroahna/mpv_websocket
-- -- Open a LOCAL copy of https://github.com/Renji-XD/texthooker-ui
-- -- Configure the script (if you're not using the Lapis note format)
-- IF USING CLIPBOARD INSERTER (NOT RECOMMENDED)
-- -- Install the clipboard inserter plugin: https://github.com/laplus-sadness/lap-clipboard-inserter
-- -- Open the texthooker UI, enable the plugin and enable clipboard pasting: https://github.com/Renji-XD/texthooker-ui
-- BOTH
-- -- Wait for an unknown word and create the card with Yomichan.
-- -- Select all the subtitle lines you wish to add to the card and copy with Ctrl + c.
-- -- Press Ctrl + v in MPV to add the lines, their Audio and the currently paused image to the back of the card.
---------------------------------------
------------- Credits -------------
-- Credits and copyright go to Anacreon DJT: https://anacreondjt.gitlab.io/
------------------------------------
------------- Original Credits (Outdated) -------------
-- This script was made by users of 4chan's Daily Japanese Thread (DJT) on /jp/
-- More information can be found here http://animecards.site/
-- Message @Anacreon with bug reports and feature requests on Discord (https://animecards.site/discord/) or 4chan (https://boards.4channel.org/jp/#s=djt)
--
-- If you like this work please consider subscribing on Patreon!
-- https://www.patreon.com/Quizmaster
------------------------------------
local utils = require 'mp.utils'
local msg = require 'mp.msg'
------------- User Config -------------
-- Set these to match your field names in Anki
local FRONT_FIELD = "Vocab"
local SENTENCE_AUDIO_FIELD = "SentAudio"
local SENTENCE_FIELD = "INVALID" -- the sentence is better taken care of by yomitan itself.
local IMAGE_FIELD = "Image"
-- Optional padding and fade settings in seconds.
-- Padding grabs extra audio around your selected subs.
-- Fade does a volume fade effect at the beginning and end of the resulting audio.
local AUDIO_CLIP_FADE = 0.2
local AUDIO_CLIP_PADDING = 0.75
-- Optional play sentence audio automatically after card update
local AUTOPLAY_AUDIO = false
-- Optional screenshot image format. Valid options: "webp" or "png"
-- Change to "png" if you plan to view cards on iOS or Mac.
local IMAGE_FORMAT = "png"
-- Optional set to true if you want your volume in mpv to affect Anki card volume.
local USE_MPV_VOLUME = false
-- Set to true if you want writing to clipboard to be enabled by default.
-- The more modern and recommended alternative is to use the websocket.
local ENABLE_SUBS_TO_CLIP = false
---------------------------------------
------------- Internal Variables -------------
local subs = {}
local debug_mode = true
local use_powershell_clipboard = nil
local prefix = ""
---------------------------------------
------------- Setup -------------
if unpack ~= nil then table.unpack = unpack end
local o = {}
-- Possible platforms: windows, linux, macos
local platform = mp.get_property_native("platform")
if platform == "darwin" then
platform = "macos"
end
local display_server
if os.getenv("WAYLAND_DISPLAY") then
display_server = 'wayland'
elseif platform == 'linux' then
display_server = 'xorg'
else
display_server = ""
end
local function dlog(...)
if debug_mode then
print(...)
end
end
local function verfiy_libmp3lame()
local encoderlist = mp.get_property("encoder-list")
if not encoderlist or not string.find(encoderlist, "libmp3lame") then
mp.osd_message("Error: libmp3lame encoder not found. Audio export will not work.\nPlease use a build of mpv with libmp3lame support.", 10)
msg.error("Error: libmp3lame encoder not found. MP3 audio export will not work.")
else
dlog("libmp3lame encoder found.")
end
end
mp.register_event("file-loaded", verfiy_libmp3lame)
dlog("Detected Platform: " .. platform)
dlog("Detected display server: " .. display_server)
---------------------------------------
-- Handle requests to AnkiConnect
local function anki_connect(action, params)
local request = utils.format_json({action=action, params=params, version=6})
local args = {'curl', '-s', 'localhost:8765', '-X', 'POST', '-d', request}
dlog("AnkiConnect request: " .. request)
local result = utils.subprocess({ args = args, cancellable = false, capture_stderr = true })
if result.status ~= 0 then
msg.error("Curl command failed with status: " .. tostring(result.status))
msg.error("Stderr: " .. (result.stderr or "none"))
return nil
end
if not result.stdout or result.stdout == "" then
msg.error("Empty response from AnkiConnect")
return nil
end
dlog("AnkiConnect response: " .. result.stdout)
local success, parsed_result = pcall(function() return utils.parse_json(result.stdout) end)
if not success or not parsed_result then
msg.error("Failed to parse JSON response: " .. (result.stdout or "empty"))
return nil
end
return parsed_result
end
-- Get media directory path from AnkiConnect
local function set_media_dir()
local media_dir_response = anki_connect('getMediaDirPath')
if not media_dir_response then
msg.error("Failed to communicate with AnkiConnect. Is Anki running and do you have AnkiConnect installed?")
mp.osd_message("Error: Failed to communicate with AnkiConnect. Is Anki running and do you have AnkiConnect installed?", 5)
return
elseif media_dir_response["error"] then
msg.error("AnkiConnect error: " .. tostring(media_dir_response["error"]))
mp.osd_message("AnkiConnect error: " .. tostring(media_dir_response["error"]), 5)
return
elseif media_dir_response["result"] then
prefix = media_dir_response["result"]
dlog("Got media directory path from AnkiConnect: " .. prefix)
else
msg.error("Unexpected response format from AnkiConnect")
mp.osd_message("Error: Unexpected response from AnkiConnect", 5)
return
end
end
local function clean(s)
for _, ws in ipairs({'%s', ' ', '', ' ', '', '', '', '', '', '', '', '', '', '', '', '', '', ' ', '', ''}) do
s = s:gsub(ws..'+', "")
end
return s
end
local function get_name(s, e)
return mp.get_property("filename"):gsub('%W','').. tostring(s) .. tostring(e)
end
local function get_clipboard()
local res
if platform == 'windows' then
res = utils.subprocess({ args = {
'powershell', '-NoProfile', '-Command', [[& {
Trap {
Write-Error -ErrorRecord $_
Exit 1
}
$clip = ""
if (Get-Command "Get-Clipboard" -errorAction SilentlyContinue) {
$clip = Get-Clipboard -Raw -Format Text -TextFormatType UnicodeText
} else {
Add-Type -AssemblyName PresentationCore
$clip = [Windows.Clipboard]::GetText()
}
$clip = $clip -Replace "`r",""
$u8clip = [System.Text.Encoding]::UTF8.GetBytes($clip)
[Console]::OpenStandardOutput().Write($u8clip, 0, $u8clip.Length)
}]]
} })
elseif platform == 'macos' then
return io.popen('LANG=en_US.UTF-8 pbpaste'):read("*a")
else -- platform == 'linux'
if display_server == 'wayland' then
res = utils.subprocess({ args = {
'wl-paste'
} })
else -- display_server == 'xorg'
res = utils.subprocess({ args = {
'xclip', '-selection', 'clipboard', '-out'
} })
end
end
if not res.error then
return res.stdout
end
end
local function powershell_set_clipboard(text)
utils.subprocess({ args = {
'powershell', '-NoProfile', '-Command', [[Set-Clipboard -Value @"]] .. "\n" .. text .. "\n" .. [["@]]
}})
end
local function cmd_set_clipboard(text)
local cmd = 'echo ' .. text .. ' | clip';
mp.command("run cmd /D /C " .. cmd);
end
local function determine_clip_type()
powershell_set_clipboard([[Anacreon様]])
use_powershell_clipboard = get_clipboard() == [[Anacreon様]]
end
local function linux_set_clipboard(text)
if display_server == 'wayland' then
os.execute('wl-copy <<EOF\n' .. text .. '\nEOF\n')
else -- display_server == 'xorg'
os.execute('xclip -selection clipboard <<EOF\n' .. text .. '\nEOF\n')
end
end
local function macos_set_clipboard(text)
os.execute('export LANG=en_US.UTF-8; cat <<EOF | pbcopy\n' .. text .. '\nEOF\n')
end
local function record_sub(_, text)
if text and mp.get_property_number('sub-start') and mp.get_property_number('sub-end') then
local sub_delay = mp.get_property_native("sub-delay")
local audio_delay = mp.get_property_native("audio-delay")
local newtext = clean(text)
if newtext == '' then
return
end
subs[newtext] = { mp.get_property_number('sub-start') + sub_delay - audio_delay, mp.get_property_number('sub-end') + sub_delay - audio_delay }
dlog(string.format("%s -> %s : %s", subs[newtext][1], subs[newtext][2], newtext))
if ENABLE_SUBS_TO_CLIP then
-- Remove newlines from text before sending it to clipboard.
-- This way pressing control+v without copying from texthooker page
-- will always give last line.
text = string.gsub(text, "[\n\r]+", " ")
if platform == 'windows' then
if use_powershell_clipboard == nil then
determine_clip_type()
end
if use_powershell_clipboard then
powershell_set_clipboard(text)
else
cmd_set_clipboard(text)
end
elseif platform == 'macos' then
macos_set_clipboard(text)
else
linux_set_clipboard(text)
end
end
end
end
local function create_audio(s, e)
if s == nil or e == nil then
return
end
local name = get_name(s, e)
local destination = utils.join_path(prefix, name .. '.mp3')
s = s - AUDIO_CLIP_PADDING
local t = e - s + AUDIO_CLIP_PADDING
local source = mp.get_property("path")
local aid = mp.get_property("aid")
local tracks_count = mp.get_property_number("track-list/count")
for i = 1, tracks_count do
local track_type = mp.get_property(string.format("track-list/%d/type", i))
local track_selected = mp.get_property(string.format("track-list/%d/selected", i))
if track_type == "audio" and track_selected == "yes" then
if mp.get_property(string.format("track-list/%d/external-filename", i), o) ~= o then
source = mp.get_property(string.format("track-list/%d/external-filename", i))
aid = 'auto'
end
break
end
end
local cmd = {
'run',
'mpv',
source,
'--loop-file=no',
'--video=no',
'--no-ocopy-metadata',
'--no-sub',
'--audio-channels=1',
string.format('--start=%.3f', s),
string.format('--length=%.3f', t),
string.format('--aid=%s', aid),
string.format('--volume=%s', USE_MPV_VOLUME and mp.get_property('volume') or '100'),
string.format("--af-append=afade=t=in:curve=ipar:st=%.3f:d=%.3f", s, AUDIO_CLIP_FADE),
string.format("--af-append=afade=t=out:curve=ipar:st=%.3f:d=%.3f", s + t - AUDIO_CLIP_FADE, AUDIO_CLIP_FADE),
string.format('-o=%s', destination)
}
mp.commandv(table.unpack(cmd))
dlog(utils.to_string(cmd))
end
local function create_screenshot(s, e)
local source = mp.get_property("path")
local img = utils.join_path(prefix, get_name(s,e) .. '.' .. IMAGE_FORMAT)
local cmd = {
'run',
'mpv',
source,
'--loop-file=no',
'--audio=no',
'--no-ocopy-metadata',
'--no-sub',
'--frames=1',
}
if IMAGE_FORMAT == 'webp' then
table.insert(cmd, '--ovc=libwebp')
table.insert(cmd, '--ovcopts-add=lossless=0')
table.insert(cmd, '--ovcopts-add=compression_level=6')
table.insert(cmd, '--ovcopts-add=preset=drawing')
elseif IMAGE_FORMAT == 'png' then
table.insert(cmd, '--vf-add=format=rgb24')
end
table.insert(cmd, '--vf-add=scale=480*iw*sar/ih:480')
table.insert(cmd, string.format('--start=%.3f', mp.get_property_number("time-pos")))
table.insert(cmd, string.format('-o=%s', img))
mp.commandv(table.unpack(cmd))
dlog(utils.to_string(cmd))
end
local function add_to_last_added(ifield, afield, tfield)
local added_notes = anki_connect('findNotes', {query='added:1'})["result"]
table.sort(added_notes)
local noteid = added_notes[#added_notes]
local note = anki_connect('notesInfo', {notes={noteid}})
if note ~= nil then
local word = note["result"][1]["fields"][FRONT_FIELD]["value"]
local new_fields = {
[SENTENCE_AUDIO_FIELD]=afield,
[SENTENCE_FIELD]=tfield,
[IMAGE_FIELD]=ifield
}
anki_connect('updateNoteFields', {
note={
id=noteid,
fields=new_fields
}
})
mp.osd_message("Updated note: " .. word, 3)
msg.info("Updated note: " .. word)
end
end
local function get_extract()
local lines = get_clipboard()
local e = 0
local s = 0
for line in lines:gmatch("[^\r\n]+") do
line = clean(line)
dlog(line)
if subs[line]~= nil then
if subs[line][1] ~= nil and subs[line][2] ~= nil then
if s == 0 then
s = subs[line][1]
else
s = math.min(s, subs[line][1])
end
e = math.max(e, subs[line][2])
end
else
mp.osd_message("ERR! Line not found: " .. line, 3)
return
end
end
dlog(string.format('s=%d, e=%d', s, e))
if e ~= 0 then
create_screenshot(s, e)
create_audio(s, e)
local ifield = '<img src='.. get_name(s,e) ..'.' .. IMAGE_FORMAT .. '>'
local afield = "[sound:".. get_name(s,e) .. ".mp3]"
local tfield = string.gsub(string.gsub(lines,"\n+", "<br />"), "\r", "")
add_to_last_added(ifield, afield, tfield)
if AUTOPLAY_AUDIO then
local name = get_name(s, e)
local audio = utils.join_path(prefix, name .. '.mp3')
local cmd = {'run', 'mpv', audio, '--loop-file=no', '--load-scripts=no'}
mp.commandv(table.unpack(cmd))
end
end
end
local function ex()
if not prefix or prefix == "" then
set_media_dir()
end
if debug_mode then
get_extract()
else
pcall(get_extract)
end
end
local function rec(...)
if debug_mode then
record_sub(...)
else
pcall(record_sub, ...)
end
end
local function toggle_sub_to_clipboard()
ENABLE_SUBS_TO_CLIP = not ENABLE_SUBS_TO_CLIP
mp.osd_message("Clipboard inserter " .. (ENABLE_SUBS_TO_CLIP and "activated" or "deactived"), 3)
end
local function toggle_debug_mode()
debug_mode = not debug_mode
mp.osd_message("Debug mode " .. (debug_mode and "activated" or "deactived"), 3)
end
local function clear_subs(_)
subs = {}
end
mp.observe_property("sub-text", 'string', rec)
mp.observe_property("filename", "string", clear_subs)
mp.add_key_binding("ctrl+v", "update-anki-card", ex)
mp.add_key_binding("ctrl+t", "toggle-clipboard-insertion", toggle_sub_to_clipboard)
mp.add_key_binding("ctrl+d", "toggle-debug-mode", toggle_debug_mode)
mp.add_key_binding("ctrl+V", ex)
mp.add_key_binding("ctrl+T", toggle_sub_to_clipboard)
mp.add_key_binding("ctrl+D", toggle_debug_mode)

View file

@ -0,0 +1,83 @@
-- mpv_websocket
-- https://github.com/kuroahna/mpv_websocket
local utils = require("mp.utils")
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")
local initialised_websocket
local _, err = utils.file_info(config_file_path)
if err then
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")
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
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
file:close()
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("/", "\\")
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",
},
})
end
local function end_websocket()
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
end
mp.register_script_message("togglewebsocket", toggle_websocket)
start_websocket()

View file

@ -0,0 +1,757 @@
local mp = require 'mp'
local msg = require 'mp.msg'
local utils = require 'mp.utils'
local options = require 'mp.options'
-- Default options
local opts = {
-- All drawing is scaled by this value, including the text borders and the
-- cursor. Change it if you have a high-DPI display.
scale = 1,
-- Set the font used for the REPL and the console. This probably doesn't
-- have to be a monospaced font.
font = "",
-- Set the font size used for the REPL and the console. This will be
-- multiplied by "scale."
font_size = 16,
}
options.read_options(opts, "user_input")
local API_VERSION = "0.1.0"
local API_MAJOR_MINOR = API_VERSION:match("%d+%.%d+")
local co = nil
local queue = {}
local active_ids = {}
local histories = {}
local request = nil
local line = ''
--[[
The below code is a modified implementation of text input from mpv's console.lua:
https://github.com/mpv-player/mpv/blob/7ca14d646c7e405f3fb1e44600e2a67fc4607238/player/lua/console.lua
Modifications:
removed support for log messages, sending commands, tab complete, help commands
removed update timer
Changed esc key to call handle_esc function
handle_esc and handle_enter now resume the main coroutine with a response table
made history specific to request ids
localised all functions - reordered some to fit
keybindings use new names
]]--
------------------------------START ORIGINAL MPV CODE-----------------------------------
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
-- Copyright (C) 2019 the mpv developers
--
-- Permission to use, copy, modify, and/or distribute this software for any
-- purpose with or without fee is hereby granted, provided that the above
-- copyright notice and this permission notice appear in all copies.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
local assdraw = require 'mp.assdraw'
local function detect_platform()
local o = {}
-- Kind of a dumb way of detecting the platform but whatever
if mp.get_property_native('options/vo-mmcss-profile', o) ~= o then
return 'windows'
elseif mp.get_property_native('options/macos-force-dedicated-gpu', o) ~= o then
return 'macos'
elseif os.getenv('WAYLAND_DISPLAY') then
return 'wayland'
end
return 'x11'
end
-- Pick a better default font for Windows and macOS
local platform = detect_platform()
if platform == 'windows' then
opts.font = 'Consolas'
elseif platform == 'macos' then
opts.font = 'Menlo'
else
opts.font = 'monospace'
end
local repl_active = false
local insert_mode = false
local cursor = 1
local key_bindings = {}
local global_margin_y = 0
-- Escape a string for verbatim display on the OSD
local function ass_escape(str)
-- There is no escape for '\' in ASS (I think?) but '\' is used verbatim if
-- it isn't followed by a recognised character, so add a zero-width
-- non-breaking space
str = str:gsub('\\', '\\\239\187\191')
str = str:gsub('{', '\\{')
str = str:gsub('}', '\\}')
-- Precede newlines with a ZWNBSP to prevent ASS's weird collapsing of
-- consecutive newlines
str = str:gsub('\n', '\239\187\191\\N')
-- Turn leading spaces into hard spaces to prevent ASS from stripping them
str = str:gsub('\\N ', '\\N\\h')
str = str:gsub('^ ', '\\h')
return str
end
-- Render the REPL and console as an ASS OSD
local function update()
local dpi_scale = mp.get_property_native("display-hidpi-scale", 1.0)
dpi_scale = dpi_scale * opts.scale
local screenx, screeny, aspect = mp.get_osd_size()
screenx = screenx / dpi_scale
screeny = screeny / dpi_scale
-- Clear the OSD if the REPL is not active
if not repl_active then
mp.set_osd_ass(screenx, screeny, '')
return
end
local ass = assdraw.ass_new()
local style = '{\\r' ..
'\\1a&H00&\\3a&H00&\\4a&H99&' ..
'\\1c&Heeeeee&\\3c&H111111&\\4c&H000000&' ..
'\\fn' .. opts.font .. '\\fs' .. opts.font_size ..
'\\bord1\\xshad0\\yshad1\\fsp0\\q1}'
local queue_style = '{\\r' ..
'\\1a&H00&\\3a&H00&\\4a&H99&' ..
'\\1c&Heeeeee&\\3c&H111111&\\4c&H000000&' ..
'\\fn' .. opts.font .. '\\fs' .. opts.font_size .. '\\c&H66ccff&' ..
'\\bord1\\xshad0\\yshad1\\fsp0\\q1}'
-- Create the cursor glyph as an ASS drawing. ASS will draw the cursor
-- inline with the surrounding text, but it sets the advance to the width
-- of the drawing. So the cursor doesn't affect layout too much, make it as
-- thin as possible and make it appear to be 1px wide by giving it 0.5px
-- horizontal borders.
local cheight = opts.font_size * 8
local cglyph = '{\\r' ..
'\\1a&H44&\\3a&H44&\\4a&H99&' ..
'\\1c&Heeeeee&\\3c&Heeeeee&\\4c&H000000&' ..
'\\xbord0.5\\ybord0\\xshad0\\yshad1\\p4\\pbo24}' ..
'm 0 0 l 1 0 l 1 ' .. cheight .. ' l 0 ' .. cheight ..
'{\\p0}'
local before_cur = ass_escape(line:sub(1, cursor - 1))
local after_cur = ass_escape(line:sub(cursor))
ass:new_event()
ass:an(1)
ass:pos(2, screeny - 2 - global_margin_y * screeny)
if (#queue == 2) then ass:append(queue_style .. string.format("There is 1 more request queued\\N"))
elseif (#queue > 2) then ass:append(queue_style .. string.format("There are %d more requests queued\\N", #queue-1)) end
ass:append(style .. request.text .. '\\N')
ass:append('> ' .. before_cur)
ass:append(cglyph)
ass:append(style .. after_cur)
-- Redraw the cursor with the REPL text invisible. This will make the
-- cursor appear in front of the text.
ass:new_event()
ass:an(1)
ass:pos(2, screeny - 2)
ass:append(style .. '{\\alpha&HFF&}> ' .. before_cur)
ass:append(cglyph)
ass:append(style .. '{\\alpha&HFF&}' .. after_cur)
mp.set_osd_ass(screenx, screeny, ass.text)
end
-- Naive helper function to find the next UTF-8 character in 'str' after 'pos'
-- by skipping continuation bytes. Assumes 'str' contains valid UTF-8.
local function next_utf8(str, pos)
if pos > str:len() then return pos end
repeat
pos = pos + 1
until pos > str:len() or str:byte(pos) < 0x80 or str:byte(pos) > 0xbf
return pos
end
-- As above, but finds the previous UTF-8 charcter in 'str' before 'pos'
local function prev_utf8(str, pos)
if pos <= 1 then return pos end
repeat
pos = pos - 1
until pos <= 1 or str:byte(pos) < 0x80 or str:byte(pos) > 0xbf
return pos
end
-- Insert a character at the current cursor position (any_unicode)
local function handle_char_input(c)
if insert_mode then
line = line:sub(1, cursor - 1) .. c .. line:sub(next_utf8(line, cursor))
else
line = line:sub(1, cursor - 1) .. c .. line:sub(cursor)
end
cursor = cursor + #c
update()
end
-- Remove the character behind the cursor (Backspace)
local function handle_backspace()
if cursor <= 1 then return end
local prev = prev_utf8(line, cursor)
line = line:sub(1, prev - 1) .. line:sub(cursor)
cursor = prev
update()
end
-- Remove the character in front of the cursor (Del)
local function handle_del()
if cursor > line:len() then return end
line = line:sub(1, cursor - 1) .. line:sub(next_utf8(line, cursor))
update()
end
-- Toggle insert mode (Ins)
local function handle_ins()
insert_mode = not insert_mode
end
-- Move the cursor to the next character (Right)
local function next_char(amount)
cursor = next_utf8(line, cursor)
update()
end
-- Move the cursor to the previous character (Left)
local function prev_char(amount)
cursor = prev_utf8(line, cursor)
update()
end
-- Clear the current line (Ctrl+C)
local function clear()
line = ''
cursor = 1
insert_mode = false
request.history.pos = #request.history.list + 1
update()
end
-- Close the REPL if the current line is empty, otherwise do nothing (Ctrl+D)
local function maybe_exit()
if line == '' then
else
handle_del()
end
end
local function handle_esc()
coroutine.resume(co, {
line = nil,
err = "exited"
})
end
-- Run the current command and clear the line (Enter)
local function handle_enter()
if request.history.list[#request.history.list] ~= line and line ~= "" then
request.history.list[#request.history.list + 1] = line
end
coroutine.resume(co, {
line = line
})
end
-- Go to the specified position in the command history
local function go_history(new_pos)
local old_pos = request.history.pos
request.history.pos = new_pos
-- Restrict the position to a legal value
if request.history.pos > #request.history.list + 1 then
request.history.pos = #request.history.list + 1
elseif request.history.pos < 1 then
request.history.pos = 1
end
-- Do nothing if the history position didn't actually change
if request.history.pos == old_pos then
return
end
-- If the user was editing a non-history line, save it as the last history
-- entry. This makes it much less frustrating to accidentally hit Up/Down
-- while editing a line.
if old_pos == #request.history.list + 1 and line ~= '' and request.history.list[#request.history.list] ~= line then
request.history.list[#request.history.list + 1] = line
end
-- Now show the history line (or a blank line for #history + 1)
if request.history.pos <= #request.history.list then
line = request.history.list[request.history.pos]
else
line = ''
end
cursor = line:len() + 1
insert_mode = false
update()
end
-- Go to the specified relative position in the command history (Up, Down)
local function move_history(amount)
go_history(request.history.pos + amount)
end
-- Go to the first command in the command history (PgUp)
local function handle_pgup()
go_history(1)
end
-- Stop browsing history and start editing a blank line (PgDown)
local function handle_pgdown()
go_history(#request.history.list + 1)
end
-- Move to the start of the current word, or if already at the start, the start
-- of the previous word. (Ctrl+Left)
local function prev_word()
-- This is basically the same as next_word() but backwards, so reverse the
-- string in order to do a "backwards" find. This wouldn't be as annoying
-- to do if Lua didn't insist on 1-based indexing.
cursor = line:len() - select(2, line:reverse():find('%s*[^%s]*', line:len() - cursor + 2)) + 1
update()
end
-- Move to the end of the current word, or if already at the end, the end of
-- the next word. (Ctrl+Right)
local function next_word()
cursor = select(2, line:find('%s*[^%s]*', cursor)) + 1
update()
end
-- Move the cursor to the beginning of the line (HOME)
local function go_home()
cursor = 1
update()
end
-- Move the cursor to the end of the line (END)
local function go_end()
cursor = line:len() + 1
update()
end
-- Delete from the cursor to the beginning of the word (Ctrl+Backspace)
local function del_word()
local before_cur = line:sub(1, cursor - 1)
local after_cur = line:sub(cursor)
before_cur = before_cur:gsub('[^%s]+%s*$', '', 1)
line = before_cur .. after_cur
cursor = before_cur:len() + 1
update()
end
-- Delete from the cursor to the end of the word (Ctrl+Del)
local function del_next_word()
if cursor > line:len() then return end
local before_cur = line:sub(1, cursor - 1)
local after_cur = line:sub(cursor)
after_cur = after_cur:gsub('^%s*[^%s]+', '', 1)
line = before_cur .. after_cur
update()
end
-- Delete from the cursor to the end of the line (Ctrl+K)
local function del_to_eol()
line = line:sub(1, cursor - 1)
update()
end
-- Delete from the cursor back to the start of the line (Ctrl+U)
local function del_to_start()
line = line:sub(cursor)
cursor = 1
update()
end
-- Returns a string of UTF-8 text from the clipboard (or the primary selection)
local function get_clipboard(clip)
if platform == 'x11' then
local res = utils.subprocess({
args = { 'xclip', '-selection', clip and 'clipboard' or 'primary', '-out' },
playback_only = false,
})
if not res.error then
return res.stdout
end
elseif platform == 'wayland' then
local res = utils.subprocess({
args = { 'wl-paste', clip and '-n' or '-np' },
playback_only = false,
})
if not res.error then
return res.stdout
end
elseif platform == 'windows' then
local res = utils.subprocess({
args = { 'powershell', '-NoProfile', '-Command', [[& {
Trap {
Write-Error -ErrorRecord $_
Exit 1
}
$clip = ""
if (Get-Command "Get-Clipboard" -errorAction SilentlyContinue) {
$clip = Get-Clipboard -Raw -Format Text -TextFormatType UnicodeText
} else {
Add-Type -AssemblyName PresentationCore
$clip = [Windows.Clipboard]::GetText()
}
$clip = $clip -Replace "`r",""
$u8clip = [System.Text.Encoding]::UTF8.GetBytes($clip)
[Console]::OpenStandardOutput().Write($u8clip, 0, $u8clip.Length)
}]] },
playback_only = false,
})
if not res.error then
return res.stdout
end
elseif platform == 'macos' then
local res = utils.subprocess({
args = { 'pbpaste' },
playback_only = false,
})
if not res.error then
return res.stdout
end
end
return ''
end
-- Paste text from the window-system's clipboard. 'clip' determines whether the
-- clipboard or the primary selection buffer is used (on X11 and Wayland only.)
local function paste(clip)
local text = get_clipboard(clip)
local before_cur = line:sub(1, cursor - 1)
local after_cur = line:sub(cursor)
line = before_cur .. text .. after_cur
cursor = cursor + text:len()
update()
end
-- List of input bindings. This is a weird mashup between common GUI text-input
-- bindings and readline bindings.
local function get_bindings()
local bindings = {
{ 'esc', handle_esc },
{ 'enter', handle_enter },
{ 'kp_enter', handle_enter },
{ 'shift+enter', function() handle_char_input('\n') end },
{ 'ctrl+j', handle_enter },
{ 'ctrl+m', handle_enter },
{ 'bs', handle_backspace },
{ 'shift+bs', handle_backspace },
{ 'ctrl+h', handle_backspace },
{ 'del', handle_del },
{ 'shift+del', handle_del },
{ 'ins', handle_ins },
{ 'shift+ins', function() paste(false) end },
{ 'mbtn_mid', function() paste(false) end },
{ 'left', function() prev_char() end },
{ 'ctrl+b', function() prev_char() end },
{ 'right', function() next_char() end },
{ 'ctrl+f', function() next_char() end },
{ 'up', function() move_history(-1) end },
{ 'ctrl+p', function() move_history(-1) end },
{ 'wheel_up', function() move_history(-1) end },
{ 'down', function() move_history(1) end },
{ 'ctrl+n', function() move_history(1) end },
{ 'wheel_down', function() move_history(1) end },
{ 'wheel_left', function() end },
{ 'wheel_right', function() end },
{ 'ctrl+left', prev_word },
{ 'alt+b', prev_word },
{ 'ctrl+right', next_word },
{ 'alt+f', next_word },
{ 'ctrl+a', go_home },
{ 'home', go_home },
{ 'ctrl+e', go_end },
{ 'end', go_end },
{ 'pgup', handle_pgup },
{ 'pgdwn', handle_pgdown },
{ 'ctrl+c', clear },
{ 'ctrl+d', maybe_exit },
{ 'ctrl+k', del_to_eol },
{ 'ctrl+u', del_to_start },
{ 'ctrl+v', function() paste(true) end },
{ 'meta+v', function() paste(true) end },
{ 'ctrl+bs', del_word },
{ 'ctrl+w', del_word },
{ 'ctrl+del', del_next_word },
{ 'alt+d', del_next_word },
{ 'kp_dec', function() handle_char_input('.') end },
}
for i = 0, 9 do
bindings[#bindings + 1] =
{'kp' .. i, function() handle_char_input('' .. i) end}
end
return bindings
end
local function text_input(info)
if info.key_text and (info.event == "press" or info.event == "down"
or info.event == "repeat")
then
handle_char_input(info.key_text)
end
end
local function define_key_bindings()
if #key_bindings > 0 then
return
end
for _, bind in ipairs(get_bindings()) do
-- Generate arbitrary name for removing the bindings later.
local name = "_userinput_" .. bind[1]
key_bindings[#key_bindings + 1] = name
mp.add_forced_key_binding(bind[1], name, bind[2], {repeatable = true})
end
mp.add_forced_key_binding("any_unicode", "_userinput_text", text_input,
{repeatable = true, complex = true})
key_bindings[#key_bindings + 1] = "_userinput_text"
end
local function undefine_key_bindings()
for _, name in ipairs(key_bindings) do
mp.remove_key_binding(name)
end
key_bindings = {}
end
-- Set the REPL visibility ("enable", Esc)
local function set_active(active)
if active == repl_active then return end
if active then
repl_active = true
insert_mode = false
define_key_bindings()
else
clear()
repl_active = false
undefine_key_bindings()
collectgarbage()
end
update()
end
mp.observe_property("user-data/osc/margins", "native", function(_, val)
if val then
global_margins = val
else
global_margins = { t = 0, b = 0 }
end
update()
end)
-- Redraw the REPL when the OSD size changes. This is needed because the
-- PlayRes of the OSD will need to be adjusted.
mp.observe_property('osd-width', 'native', update)
mp.observe_property('osd-height', 'native', update)
mp.observe_property('display-hidpi-scale', 'native', update)
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
-------------------------------END ORIGINAL MPV CODE------------------------------------
--[[
sends a response to the original script in the form of a json string
it is expected that all requests get a response, if the input is nil then err should say why
current error codes are:
exited the user closed the input instead of pressing Enter
already_queued a request with the specified id was already in the queue
cancelled a script cancelled the request
replace replaced by another request
]]
local function send_response(res)
if res.source then
mp.commandv("script-message-to", res.source, res.response, (utils.format_json(res)))
else
mp.commandv("script-message", res.response, (utils.format_json(res)))
end
end
-- push new request onto the queue
-- if a request with the same id already exists and the queueable flag is not enabled then
-- a nil result will be returned to the function
function push_request(req)
if active_ids[req.id] then
if req.replace then
for i, q_req in ipairs(queue) do
if q_req.id == req.id then
send_response{ err = "replaced", response = q_req.response, source = q_req.source }
queue[i] = req
if i == 1 then request = req end
end
end
update()
return
end
if not req.queueable then
send_response{ err = "already_queued", response = req.response, source = req.source }
return
end
end
table.insert(queue, req)
active_ids[req.id] = (active_ids[req.id] or 0) + 1
if #queue == 1 then coroutine.resume(co) end
update()
end
-- safely removes an item from the queue and updates the set of active requests
function remove_request(index)
local req = table.remove(queue, index)
active_ids[req.id] = active_ids[req.id] - 1
if active_ids[req.id] == 0 then active_ids[req.id] = nil end
return req
end
--an infinite loop that moves through the request queue
--uses a coroutine to handle asynchronous operations
local function driver()
while (true) do
while queue[1] do
request = queue[1]
line = request.default_input
cursor = request.cursor_pos
if repl_active then update()
else set_active(true) end
res = coroutine.yield()
if res then
res.source, res.response = request.source, request.response
send_response(res)
remove_request(1)
end
end
set_active(false)
coroutine.yield()
end
end
co = coroutine.create(driver)
--cancels any input request that returns true for the given predicate function
local function cancel_input_request(pred)
for i = #queue, 1, -1 do
if pred(i) then
req = remove_request(i)
send_response{ err = "cancelled", response = req.response, source = req.source }
--if we're removing the first item then that means the coroutine is waiting for a response
--we will need to tell the coroutine to resume, upon which it will move to the next request
--if there is something in the buffer then save it to the history before erasing it
if i == 1 then
local old_line = line
if old_line ~= "" then table.insert(histories[req.id].list, old_line) end
clear()
coroutine.resume(co)
end
end
end
end
mp.register_script_message("cancel-user-input/uid", function(uid)
cancel_input_request(function(i) return queue[i].response == uid end)
end)
-- removes all requests with the specified id from the queue
mp.register_script_message("cancel-user-input/id", function(id)
cancel_input_request(function(i) return queue[i].id == id end)
end)
-- ensures a request has the correct fields and is correctly formatted
local function format_request_fields(req)
assert(req.version, "input requests require an API version string")
if not string.find(req.version, API_MAJOR_MINOR, 1, true) then
error(("input request has invalid version: expected %s.x, got %s"):format(API_MAJOR_MINOR, req.version))
end
assert(req.response, "input requests require a response string")
assert(req.id, "input requests require an id string")
req.text = ass_escape(req.request_text or "")
req.default_input = req.default_input or ""
req.cursor_pos = tonumber(req.cursor_pos) or 1
req.id = req.id or "mpv"
if req.cursor_pos ~= 1 then
if req.cursor_pos < 1 then req.cursor_pos = 1
elseif req.cursor_pos > #req.default_input then req.cursor_pos = #req.default_input + 1 end
end
if not histories[req.id] then histories[req.id] = {pos = 1, list = {}} end
req.history = histories[req.id]
return req
end
-- updates the fields of a specific request
mp.register_script_message("update-user-input/uid", function(uid, req_opts)
req_opts = utils.parse_json(req_opts)
req_opts.response = uid
for i, req in ipairs(queue) do
if req.response == uid then
local success, result = pcall(format_request_fields, req_opts)
if not success then return msg.error(result) end
queue[i] = result
if i == 1 then request = queue[1] end
update()
return
end
end
end)
--the function that parses the input requests
local function input_request(req)
req = format_request_fields(req)
push_request(req)
end
-- script message to recieve input requests, get-user-input.lua acts as an interface to call this script message
mp.register_script_message("request-user-input", function(req)
msg.debug(req)
req = utils.parse_json(req)
local success, err = pcall(input_request, req)
if not success then
send_response{ err = err, response = req.response, source = req.source}
msg.error(err)
end
end)

2734
.config/mpv/scripts/webm.lua Normal file

File diff suppressed because it is too large Load diff

View file

@ -672,4 +672,3 @@ may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View file

@ -0,0 +1,74 @@
* About
This plugin allows mpv to stream magnet links (and any other torrent identifier [[https://github.com/webtorrent/webtorrent-cli][webtorrent-cli]] handles) directly. It will automatically remove videos after they are finished playing (by default) and will set the title to be the name of the video.
This script will detect =magnet:= links, torrent files/urls ending in =torrent=, and info hashes. You can also explicitly prefix the identifier with =webtorrent://= to let this plugin know the path/url is a torrent (e.g. you could do this to play a torrent file that didn't end in =torrent=)
* Comparison with using ~webtorrent --mpv~
One benefit is consistency of syntax (e.g. if you have a shell command or keybinding to call ~mpv <clipboard>~, you don't need to handle torrents differently).
This script also provides more functionality and options. For example, it can automatically delete downloaded files, and it can remember and jump to the last video you played in a torrent file with multiple videos. See the settings heading below for more information.
Another reason you might want to use this script is that you can start mpv with a playlist of multiple magnet links or add magnet links to the playlist of an already open mpv window (e.g. using one of the scripts that allow appending a link from the clipboard to the playlist such as [[https://github.com/Eisa01/mpv-scripts#smartcopypaste-ii-script][SmartCopyPaste-II]]).
By using this script, you can also see mpv output (which is hidden when calling ~webtorrent~ directly). On the other hand, you won't be able to see both the normal ~webtorrent~ output and mpv's output at the same time. By default, this script will print the download speed while waiting for the video to load (see the information on the =webtorrent_verbosity= setting below for more options).
* Requirements
- [[https://github.com/webtorrent/webtorrent-cli][webtorrent-cli]]
- on linux (or maybe similar)
- basic shell utilities (bash, awk, grep, nohup, tail)
- [[https://github.com/stedolan/jq][jq]]
- [[https://github.com/benibela/xidel][xidel]]
Webtorrent-cli does not currently provide a way to get a json list of files which is why jq and xidel are required.
* Installation Instructions
Clone this repo into the mpv scripts directory (e.g. =git clone <url> ~/.config/mpv/scripts/webtorrent-hook=). You must put this whole directory in the scripts directory not just the lua file.
* Comparison with Peerflix-hook
Peerflix is unmaintained, and webtorrent is supposedly significantly faster.
Peerflix's output is not parseable, so the peerflix version of this script had to do a bunch of extra work with ~lsof~ to figure out the location of video files, the title of video files, and the process id of peerflix (in order to kill it). This script is a lot cleaner by comparison (though it could be better if webtorrent had a way to give [[https://github.com/webtorrent/webtorrent-cli/issues/132][more script-friendly output]]).
This script also has a lot more functionality than the peerflix version (e.g support for torrents containing multiple media files).
* Comparison With Btfs-stream
Webtorrent has parseable output but is still not very script friendly. [[https://github.com/noctuid/mpv-btfs-stream][mpv-btfs-stream]] is cleaner and simpler by comparison and does not rely on parsing output. The advantage of webtorrent over btfs is that webtorrent is much faster. Functionally, I am not aware of any downsides of using webtorrent-hook instead of btfs-stream though. See [[https://github.com/noctuid/mpv-btfs-hook#comparison-with-mpv-webtorrent-hook][here]] for a full comparison.
* Comparison with webtorrent-mpv-hook
There is a similarly named plugin [[https://github.com/mrxdst/webtorrent-mpv-hook][webtorrent-mpv-hook]] which directly uses the webtorrent library instead of webtorrent-cli.
Here are advantages of the other plugin:
- it directly uses the webtorrent library, which simplifies how the code works somewhat
- it has a much prettier speed/progress display while you are waiting for the torrent to start
Here are missing features of the other plugin:
- it has no option to delete files after exiting mpv
- it has no option to continue seeding after exiting mpv
- it does not remember the last file played for previously played torrents (it will always start at the first file)
- it does not work correctly with scripts that allow pasting a path/url into the playlist (it only supports one webtorrent instance; this plugin supports an arbitrary number of webtorrent-cli instances)
* Configuration
In =~/.config/mpv/script-opts/webtorrent-hook.conf=, you can change the following settings:
- =close_webtorrent= - whether to close webtorrent after unloading the video; if =no=, keep seeding (default: =yes=)
- =remove_files= - whether to remove the video file from disk after unloading; =yes= only has an effect if =close_webtorrent= is also =yes= (default: =yes=)
- =download_directory= - directory to download videos to; the script will run mpv's =expand-path= command on the string first so that mpv path abbreviations such as =~/= and =~~/= can be used (default: =/tmp/webtorrent-hook=)
- =webtorrent_flags= - json array of extra flags to pass to webtorrent (default: []; flags always used: =webtorrent --port 0 --out <download_directory> --keep-streaming=; keep-streaming is always passed, and =close_webtorrent= determines whether or not to stop webtorrent)
- =show_speed= - whether to continuously output webtorrent-cli's download speed line; the output stops once the video is loaded to prevent clobbering mpv's output (default: =yes=)
- =remember_last_played= - whether to store the last played video in a title and start at it in the future (default: =yes=)
- =remember_directory= - directory to store last played information in; make this something outside of =/tmp= if you want it to be remembered after computer reboot (default: =/tmp/webtorrent-hook-last-played=)
If you set =close_webtorrent= to =no=, you will have to manually kill the =WebTorrent= processes yourself when you want to stop seeding (~pgrep WebTorrent~ should show all processes).
Here is an example configuration file:
#+begin_src conf-unix
close_webtorrent=yes
remove_files=yes
# change download directory
download_directory=~/tmp/webtorrent-hook
# do not use --out, --keep-streaming, --port or most other flags (should be
# obvious; don't use --quiet, --mpv, etc.)
webtorrent_flags=["--blocklist", "<blocklist url>"]
show_speed=no
remember_last_played=yes
remember_directory=~/tmp/webtorrent-remember
#+end_src

View file

@ -0,0 +1,249 @@
-- TODO start webtorrent instance immediately when pasting into playlist instead
-- of waiting for load?
-- TODO what happens with --prefetch-playlist?
local settings = {
close_webtorrent = true,
remove_files = true,
download_directory = "/tmp/webtorrent-hook",
webtorrent_flags = [[]],
show_speed = true,
remember_last_played = true,
remember_directory = "/tmp/webtorrent-hook-last-played"
}
(require "mp.options").read_options(settings, "webtorrent-hook")
local utils = require "mp.utils";
local webtorrent_instances = {}
local webtorrent_files = {}
local script_dir = mp.get_script_directory()
local printer_pid = nil
-- * Helpers
-- http://lua-users.org/wiki/StringRecipes
function ends_with(str, ending)
return ending == "" or str:sub(-#ending) == ending
end
function read_file(file)
local fh = assert(io.open(file, "rb"))
local contents = fh:read("*all")
fh:close()
return contents
end
function write_file(file, text)
local fh = io.open(file, "w")
fh:write(text)
fh:close()
end
function is_handled_url(url, load_failed)
if load_failed then
-- info hash
return (load_failed and string.match(url, "%w+"))
else
return (url:find("magnet:") == 1 or url:find("peerflix://") == 1
or url:find("webtorrent://") == 1 or ends_with(url, "torrent"))
end
end
function load_file_after_current(url, option_table, num_entries)
mp.command_native({
"loadfile", url, "append", -1, option_table
})
local index = mp.get_property("playlist-pos")
mp.command_native({
"playlist-move",
mp.get_property("playlist-count") - 1,
index + 1 + num_entries
})
end
-- * Store Last Played Files
function file_info_hash(filename)
return webtorrent_files[filename]
end
function get_remember_file_path(info_hash)
return utils.join_path(settings.remember_directory, info_hash)
end
function maybe_store_last_played_torrent_file(_)
if settings.remember_last_played then
mp.commandv("run", "mkdir", "-p", settings.remember_directory)
local filename = mp.get_property("media-title")
local info_hash = file_info_hash(filename)
if info_hash ~= nil then
local remember_file = get_remember_file_path(info_hash)
write_file(remember_file, filename)
end
end
end
mp.register_event("file-loaded", maybe_store_last_played_torrent_file)
function get_last_played_filename_for_torrent(info_hash)
local remember_file = get_remember_file_path(info_hash)
if utils.file_info(remember_file) then
return read_file(remember_file)
end
end
-- * Play Torrents
function load_webtorrent_files(info_hash, webtorrent_info)
local first = true
local found_last_played = false
local last_played_filename = ""
if settings.remember_last_played then
last_played_filename = get_last_played_filename_for_torrent(info_hash)
end
local should_remember = settings.remember_last_played
and last_played_filename
local file_index = 0
local file_play_index = 0
for _, file in pairs(webtorrent_info["files"]) do
local title = file["title"]
webtorrent_files[title] = info_hash
local option_table = {}
-- TODO is it actually necessary to set force-media-title for sub
-- plugins? it seems to be correctly set by default for what I've
-- tried
option_table["force-media-title"] = title
local url = file["url"]
if first then
load_file_after_current(url, option_table, 0)
mp.command_native({"playlist-remove", mp.get_property("playlist-pos")})
else
load_file_after_current(url, option_table,
file_index - (file_play_index + 1))
if should_remember and not found_last_played then
file_play_index = file_play_index + 1
mp.set_property("playlist-pos", mp.get_property("playlist-pos") + 1)
if title == last_played_filename then
found_last_played = true
end
end
end
file_index = file_index + 1
first = false
end
end
function maybe_kill_printer()
if printer_pid then
mp.commandv("run", "kill", printer_pid)
printer_pid = nil
end
end
mp.register_event("file-loaded", maybe_kill_printer)
function start_speed_printer(out_dir)
if utils.file_info(utils.join_path(out_dir, "webtorrent-output")) then
local speed_printer_path =
utils.join_path(script_dir, "webtorrent-speed-printer.sh")
os.execute(speed_printer_path .. ' "' .. out_dir .. '"')
printer_pid = read_file(utils.join_path(out_dir, "printer.pid"))
end
end
function start_webtorrent(url, torrent_info)
local base_dir = mp.command_native({
"expand-path", settings.download_directory
})
local info_hash = torrent_info["infoHash"]
local out_dir = utils.join_path(base_dir, info_hash)
local wrapper_path =
utils.join_path(script_dir, "webtorrent-wrap.sh")
local webtorrent_args = {wrapper_path, out_dir, url}
local flags = utils.parse_json(settings.webtorrent_flags)
if flags ~= nil then
for _, flag in pairs(flags) do
table.insert(webtorrent_args, flag)
end
end
mp.msg.info("Waiting for webtorrent server")
local webtorrent_result = mp.command_native({
name = "subprocess",
playback_only = false,
capture_stdout = true,
args = webtorrent_args
})
if webtorrent_result.status == 0 then
mp.msg.info("Webtorrent server is up")
local webtorrent_info = utils.parse_json(webtorrent_result.stdout)
local pid = webtorrent_info["pid"]
mp.msg.debug(webtorrent_info)
local name = "Unknown name"
if torrent_info["name"] ~= nil then
name = torrent_info["name"]
end
table.insert(webtorrent_instances,
{download_dir=out_dir,pid=pid,name=name})
if settings.show_speed then
start_speed_printer(out_dir)
end
load_webtorrent_files(info_hash, webtorrent_info)
else
mp.msg.info("Failed to start webtorrent")
end
end
-- check if the url is a torrent and play it if it is
function maybe_play_torrent(load_failed)
local url = mp.get_property("stream-open-filename")
if is_handled_url(url, load_failed) then
if url:find("webtorrent://") == 1 then
url = url:sub(14)
end
if url:find("peerflix://") == 1 then
url = url:sub(12)
end
local torrent_info_command = mp.command_native({
name = "subprocess",
playback_only = false,
capture_stdout = true,
args = {"webtorrent", "info", url},
})
if torrent_info_command.status == 0 then
local torrent_info = utils.parse_json(torrent_info_command.stdout)
local info_hash = torrent_info["infoHash"]
if info_hash ~= nil then
start_webtorrent(url, torrent_info)
end
end
end
end
function check_if_torrent_on_load()
maybe_play_torrent(false)
end
function check_if_torrent_on_load_fail()
maybe_play_torrent(true)
end
function webtorrent_cleanup()
if settings.close_webtorrent then
for _, instance in pairs(webtorrent_instances) do
mp.msg.verbose("Killing WebTorrent pid " .. instance.pid)
mp.commandv("run", "kill", instance.pid)
if settings.remove_files then
mp.msg.verbose("Removing files for torrent " .. instance.name)
mp.commandv("run", "rm", "-r", instance.download_dir)
end
end
end
end
mp.add_hook("on_load", 50, check_if_torrent_on_load)
mp.add_hook("on_load_fail", 50, check_if_torrent_on_load_fail)
mp.register_event("shutdown", webtorrent_cleanup)

View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
out_dir=$1
output_file="$out_dir"/webtorrent-output
printer_pid_file="$out_dir"/printer.pid
tail -f "$output_file" \
| awk '/Speed:/ { printf ("\r%s%s%s", "\033[1;31m", $0, "\033[0m "); }' \
>&2 &
echo -n $! > "$printer_pid_file"

View file

@ -0,0 +1,46 @@
#!/usr/bin/env bash
out_dir=$1
shift
mkdir -p "$out_dir"
# using file over pipe so multiple processes can read from it and because >(tee
# "$pipe" "$second-pipe-or file") ends up blocking mpv
webtorrent_output_file="$out_dir"/webtorrent-output
nohup webtorrent download "$@" --port 0 --out "$out_dir" --keep-seeding \
&> "$webtorrent_output_file" &
pid=$!
cleanup() {
if (( $? == 1 )); then
# kill webtorrent if exit with error
kill $pid
fi
}
# shellcheck disable=SC2064
trap cleanup EXIT
url=$(tail -f "$webtorrent_output_file" \
| awk '/Server running at: ?/ {gsub(/Server running at: ?/, ""); print $1; exit}')
base_url=$(echo "$url" | grep --extended-regexp --only-matching \
'http://localhost:[0-9]+')
webtorrent_hash=$(echo "$url" | grep --extended-regexp --only-matching \
'webtorrent/[0-9a-f]+')
# Get json of files
webtorrent_results=$(xidel --silent --extract "//a/@href" "$base_url/$webtorrent_hash" |
jq --null-input --raw-input "
{
pid: $pid,
files: [inputs | select(length>0)] | map({title: . | sub(\"/$webtorrent_hash/\"; \"\"), url: (\"$base_url\" + .)})
}
")
# Uncomment for debugging info
# echo "$webtorrent_results" > ~/webtorrent-wrap.log
# echo "URL - $url" >> ~/webtorrent-wrap.log
# echo "WEBTORRENT_HASH - $webtorrent_hash" >> ~/webtorrent-wrap.log
# echo "BASE_URL - $base_url" >> ~/webtorrent-wrap.log
# Print results
echo "$webtorrent_results"

BIN
.config/neomutt/.github/title.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

52
.config/neomutt/binds Normal file
View file

@ -0,0 +1,52 @@
# vim: filetype=muttrc
#------------------------------------------------------------
# Vi Key Bindings
#------------------------------------------------------------
# Moving around
bind attach,browser,index g noop
bind attach,browser,index gg first-entry
bind attach,browser,index G last-entry
bind pager g noop
bind pager gg top
bind pager G bottom
bind pager k previous-line
bind pager j next-line
# Scrolling
bind attach,browser,pager,index \CF next-page
bind attach,browser,pager,index \CB previous-page
bind attach,browser,pager,index \Cu half-up
bind attach,browser,pager,index \Cd half-down
bind browser,pager \Ce next-line
bind browser,pager \Cy previous-line
bind index \Ce next-line
bind index \Cy previous-line
bind pager,index d noop
bind pager,index dd delete-message
# Mail & Reply
bind index \Cm list-reply # Doesn't work currently
# Threads
bind browser,pager,index N search-opposite
bind pager,index dT delete-thread
bind pager,index dt delete-subthread
bind pager,index gt next-thread
bind pager,index gT previous-thread
bind index za collapse-thread
bind index zA collapse-all # Missing :folddisable/foldenable
bind attach <return> view-mailcap
bind attach l view-mailcap
bind index,pager B sidebar-toggle-visible
macro compose A "<shell-escape>bash $HOME/.config/neomutt/scripts/filepicker<enter><enter-command>source $HOME/.config/neomutt/tmpfile<enter><shell-escape>bash $HOME/.config/neomutt/scripts/filepicker clean<enter>" "Attach with yazi"
# Go to specific folder
macro index gd "<change-folder>$postponed<enter>" "go to drafts"
macro index gs "<change-folder>$record<enter>" "go to sent"
macro index gi "<change-folder>$spoolfile<Enter>" "go to inbox"
macro index gt "<change-folder>$trash<enter>" "go to trash"

16
.config/neomutt/mailcap Normal file
View file

@ -0,0 +1,16 @@
# MS Word documents
application/msword; xdg-open %s
application/vnd.ms-excel; xdg-open %s
application/vnd.openxmlformats-officedocument.presentationml.presentation; xdg-open %s
application/vnd.oasis.opendocument.text; xdg-open %s
# HTML
text/html; w3m -o auto_image=TRUE -I %{charset} -T text/html; copiousoutput;
text/plain; nvim %s
# PDF
application/pdf; xdg-open %s
# Images
image/png; xdg-open %s
image/jpeg; xdg-open %s

View file

@ -0,0 +1,8 @@
# vim: filetype=muttrc
# Accounts
source "~/.config/neomutt/accounts/account.com.example"
# Source Files
source "~/.config/neomutt/binds"
source "~/.config/neomutt/options"
source "~/.config/neomutt/theme"

43
.config/neomutt/options Normal file
View file

@ -0,0 +1,43 @@
# vim: filetype=muttrc
# General settings
set editor='nvim'
set attach_save_dir="~/downloads/mail-attachments"
set mailcap_path = ~/.config/neomutt/mailcap
# Open mails on html view by default
auto_view text/html text/calendar
alternative_order text/calendar text/plain text/enriched text/html text/*
set sidebar_visible=yes
set sidebar_width=30
set sidebar_short_path=yes
set pager_stop # don't go to next message automatically
set menu_scroll # scroll in menus
set pager_format="%4C %Z %[!%b %e at %I:%M %p] %.20n %s%* -- (%P)"
set wait_key=no
set smart_wrap
set reflow_wrap=120
set reflow_text
set attach_format = '%u%D%I %t%4n %T%.40d%> [%.12m/%.12M, %.6e%?C?, %C?, %s] '
set folder_format = '%4C %t %f'
# Index View Options ---------------------------------
set date_format = "%d/%m/%y at %H:%M"
# Status Bar {{{
set status_chars = '—+#~'
set status_on_top = yes
## status_format - format of summary on the current folder in the index
# https://www.neomutt.org/guide/reference.html#status-format
##
## %?<sequence_char>?<optional_string>? optionally print string, if>0
## Default: -%r-NeoMutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?%?l? %l?]---(%s/%S)-%>-(%P)---
# set status_format = "%f%r—[%?M?%M/?%m messages, %?n?%n new, ?%?d?%d deleted, ?%?F?%F important, ?%?t?%t selected, ?%?p?%p drafts, ?%l]———(%s/%S)—%>—(%P)———"
set status_format = "%D %?u?[ %u] ?%?R?[ %R] ?%?d?[ %d] ?%?t?[ %t] ?%?F?[ %F] ?%?p?[ %p]? \n \n"
# Default is: Mutt with %?m?%m messages&no messages?%?n? [%n NEW]?
set ts_status_format = 'mutt %m messages%?n?, %n new?'

View file

@ -0,0 +1,10 @@
#!/bin/sh
tmpfile=$HOME/.config/neomutt/tmpdir
if \[ -z "$1" \]; then
yazi --cwd-file $tmpfile &&
echo "$(awk 'BEGIN {printf "%s", "push "} {printf "%s", "<save-entry>\""$0"\"<enter>"}' $tmpfile)" >$tmpfile
elif \[ $1 == "clean" \]; then
rm $tmpfile
fi

View file

@ -0,0 +1,11 @@
#!/bin/sh
tmpfile=$HOME/.config/neomutt/tmpfile
if \[ -z "$1" \]; then
yazi --chooser-file $tmpfile &&
sed -i 's/ /^V /g' $tmpfile &&
echo "$(awk 'BEGIN {printf "%s", "push "} {printf "%s", "<attach-file>\""$0"\"<enter>"}' $tmpfile)" >$tmpfile
elif \[ $1 == "clean" \]; then
rm $tmpfile
fi

104
.config/neomutt/theme Normal file
View file

@ -0,0 +1,104 @@
# vim: filetype=muttrc
# Header colors:
color header blue default ".*"
color header brightmagenta default "^(From)"
color header brightcyan default "^(Subject)"
color header brightwhite default "^(CC|BCC)"
mono bold bold
mono underline underline
mono indicator reverse
mono error bold
color normal default default
color indicator brightyellow default # currently selected message. default makes bar clear, disabled arrow to save space.
color sidebar_highlight red default
color sidebar_divider brightblack black
color sidebar_flagged red black
color sidebar_new green black
color normal brightyellow default
color error red default
color tilde black default
color message cyan default
color markers red white
color attachment white default
color search brightmagenta color0
color status brightyellow black
color hdrdefault brightgreen default
color quoted green default
color quoted1 blue default
color quoted2 cyan default
color quoted3 yellow default
color quoted4 red default
color quoted5 brightred default
color signature brightgreen default
color bold black default
color underline black default
color normal default default
color body brightred default "[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+" # Email addresses
color body brightblue default "(https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+" # URL
color body green default "\`[^\`]*\`" # Green text between ` and `
color body brightblue default "^# \.*" # Headings as bold blue
color body brightcyan default "^## \.*" # Subheadings as bold cyan
color body brightgreen default "^### \.*" # Subsubheadings as bold green
color body yellow default "^(\t| )*(-|\\*) \.*" # List items as yellow
color body brightcyan default "[;:][-o][)/(|]" # emoticons
color body brightcyan default "[;:][)(|]" # emoticons
color body brightcyan default "[ ][*][^*]*[*][ ]?" # more emoticon?
color body brightcyan default "[ ]?[*][^*]*[*][ ]" # more emoticon?
color body red default "(BAD signature)"
color body cyan default "(Good signature)"
color body brightblack default "^gpg: Good signature .*"
color body brightyellow default "^gpg: "
color body brightyellow red "^gpg: BAD signature from.*"
mono body bold "^gpg: Good signature"
mono body bold "^gpg: BAD signature from.*"
color body red default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
# Default index colors:
color index yellow default '.*'
color index_author red default '.*'
color index_number blue default
color index_subject cyan default '.*'
# For new mail:
color index brightyellow black "~N"
color index_author brightred black "~N"
color index_subject brightcyan black "~N"
color progress black cyan
# color normal default default # Text is "Text"
# color index color2 default ~N # New Messages are Green
# color index color1 default ~F # Flagged messages are Red
# color index color13 default ~T # Tagged Messages are Red
# color index color1 default ~D # Messages to delete are Red
# color attachment color5 default # Attachments are Pink
# color signature color8 default # Signatures are Surface 2
# color search color4 default # Highlighted results are Blue
#
# color indicator default color8 # currently highlighted message Surface 2=Background Text=Foreground
# color error color1 default # error messages are Red
# color status color15 default # status line "Subtext 0"
# color tree color15 default # thread tree arrows Subtext 0
# color tilde color15 default # blank line padding Subtext 0
#
# color hdrdefault color13 default # default headers Pink
# color header color13 default "^From:"
# color header color13 default "^Subject:"
#
# color quoted color15 default # Subtext 0
# color quoted1 color7 default # Subtext 1
# color quoted2 color8 default # Surface 2
# color quoted3 color0 default # Surface 1
# color quoted4 color0 default
# color quoted5 color0 default
#
# color body color2 default [\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+ # email addresses Green
# color body color2 default (https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+ # URLs Green
# color body color4 default (^|[[:space:]])\\*[^[:space:]]+\\*([[:space:]]|$) # *bold* text Blue
# color body color4 default (^|[[:space:]])_[^[:space:]]+_([[:space:]]|$) # _underlined_ text Blue
# color body color4 default (^|[[:space:]])/[^[:space:]]+/([[:space:]]|$) # /italic/ text Blue
#
# color sidebar_flagged color1 default # Mailboxes with flagged mails are Red
# color sidebar_new color10 default # Mailboxes with new mail are Green

View file

@ -153,8 +153,8 @@
"voldikss/vim-floaterm",
"vuki656/package-info.nvim",
"wakatime/vim-wakatime",
"williamboman/mason-lspconfig.nvim",
"williamboman/mason.nvim",
"mason-org/mason-lspconfig.nvim",
"mason-org/mason.nvim",
"windwp/nvim-ts-autotag",
"zapling/mason-lock.nvim",
"zeioth/garbage-day.nvim",

View file

@ -1,70 +1,67 @@
{
"LazyVim": { "branch": "main", "commit": "25abbf546d564dc484cf903804661ba12de45507" },
"SchemaStore.nvim": { "branch": "main", "commit": "a28cc71857f11a7370d81f5ba3c1f5bb8383b732" },
"autolist.nvim": { "branch": "main", "commit": "5f70a5f99e96c8fe3069de042abd2a8ed2deb855" },
"blink.cmp": { "branch": "main", "commit": "bae4bae0eedd1fa55f34b685862e94a222d5c6f8" },
"LazyVim": { "branch": "main", "commit": "b4606f9df3395a261bb6a09acc837993da5d8bfc" },
"SchemaStore.nvim": { "branch": "main", "commit": "22f0c2f7c727a15b45b7bfcbbab533720223b840" },
"blink.cmp": { "branch": "main", "commit": "327fff91fe6af358e990be7be1ec8b78037d2138" },
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
"catppuccin": { "branch": "main", "commit": "3aaf3ab60221bca8edb1354e41bd514a22c89de2" },
"conform.nvim": { "branch": "master", "commit": "973f3cb73887d510321653044791d7937c7ec0fa" },
"dial.nvim": { "branch": "master", "commit": "78bd73aaf2b9c8f80715a878feaf56f7ffa8b6ff" },
"catppuccin": { "branch": "main", "commit": "f19cab18ec4dc86d415512c7a572863b2adbcc18" },
"conform.nvim": { "branch": "master", "commit": "b4aab989db276993ea5dcb78872be494ce546521" },
"dial.nvim": { "branch": "master", "commit": "f0404ec1f83a03f2c3457e60087c6331d1cbb83f" },
"diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
"edgy.nvim": { "branch": "main", "commit": "7e8dedc39abebe40c289b8012cc89b11c69aa7a0" },
"flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
"gitsigns.nvim": { "branch": "main", "commit": "6e3c66548035e50db7bd8e360a29aec6620c3641" },
"gitsigns.nvim": { "branch": "main", "commit": "f780609807eca1f783a36a8a31c30a48fbe150c5" },
"grapple.nvim": { "branch": "main", "commit": "b41ddfc1c39f87f3d1799b99c2f0f1daa524c5f7" },
"grug-far.nvim": { "branch": "main", "commit": "385d1949dc21d0c39e7a74b4f4a25da18817bc86" },
"kulala.nvim": { "branch": "main", "commit": "65d102f65cfee9f338ba8a0bd43187a7cac898e9" },
"grug-far.nvim": { "branch": "main", "commit": "50d9ee2b5a19634670441948e7e4afaa042f1059" },
"kulala.nvim": { "branch": "main", "commit": "ab3effad17d5dbb4d5d34b6289fa4dc97155045c" },
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
"lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" },
"lazydev.nvim": { "branch": "main", "commit": "258d2a5ef4a3e3d6d9ba9da72c9725c53e9afcbd" },
"lualine.nvim": { "branch": "master", "commit": "b8c23159c0161f4b89196f74ee3a6d02cdc3a955" },
"markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "1a31f824b9cd5bc6f342fc29e9a53b60d74af245" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "a1067cf84b4ff81b66d2bf4d01f4cbdb5de40bd0" },
"mason-nvim-dap.nvim": { "branch": "main", "commit": "86389a3dd687cfaa647b6f44731e492970034baa" },
"mason.nvim": { "branch": "main", "commit": "fc98833b6da5de5a9c5b1446ac541577059555be" },
"mini.ai": { "branch": "main", "commit": "1cd4f021a05c29acd4ab511c0981da14217daf38" },
"mini.icons": { "branch": "main", "commit": "b8f6fa6f5a3fd0c56936252edcd691184e5aac0c" },
"mini.pairs": { "branch": "main", "commit": "1e1ca3f60f58d4050bf814902b472eec9963a5dd" },
"mini.surround": { "branch": "main", "commit": "7a8606333affe7ce637a0ba91bbafc46fc42bfa0" },
"mason.nvim": { "branch": "main", "commit": "7dc4facca9702f95353d5a1f87daf23d78e31c2a" },
"mini.ai": { "branch": "main", "commit": "dcd346a3eda9121e917950680e5eb59f59f78aae" },
"mini.icons": { "branch": "main", "commit": "f9a177c11daa7829389b7b6eaaec8b8a5c47052d" },
"mini.pairs": { "branch": "main", "commit": "3738ea30ff33e0cbf2983dc67319a5468d25b0a9" },
"mini.surround": { "branch": "main", "commit": "4b92d30fb5e021cced6cbb68698c73018211fbfa" },
"neo-tree.nvim": { "branch": "main", "commit": "8c6349bceb1d8a863964dd25dc7944d588a56aaa" },
"neotest": { "branch": "master", "commit": "ce178308ea30f96667f1c11f022880d8c04cafd3" },
"neotest-jest": { "branch": "main", "commit": "46ccc50273838f0b48e3c4814c1c46c0ccfe9edf" },
"neotest-mocha": { "branch": "main", "commit": "8239023d299a692784176f202f6a4a5e0a698ad2" },
"neotest-python": { "branch": "master", "commit": "ed9b4d794b89044cc32e5476e637936331473c6e" },
"neotest-vitest": { "branch": "main", "commit": "a6099e1fb55a2c2851da3dd0f4d510af9a234c92" },
"neotest": { "branch": "master", "commit": "2cf3544fb55cdd428a9a1b7154aea9c9823426e8" },
"neotest-jest": { "branch": "main", "commit": "1a54cf910571b9ae5216b8570367bcb0310d9f54" },
"neotest-mocha": { "branch": "main", "commit": "342664d54d2177cd0b21742ddf8c447ff278df46" },
"neotest-python": { "branch": "master", "commit": "1b1b1abf928f32bbd6a7d183f7ffc80a591eb162" },
"neotest-vitest": { "branch": "main", "commit": "f5560d7048e514d8da92a9e1e1f1c6d84dd9096f" },
"noice.nvim": { "branch": "main", "commit": "0427460c2d7f673ad60eb02b35f5e9926cf67c59" },
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-dap": { "branch": "master", "commit": "a479e25ed5b5d331fb46ee4b9e160ff02ac64310" },
"nvim-dap-python": { "branch": "master", "commit": "261ce649d05bc455a29f9636dc03f8cdaa7e0e2c" },
"nvim-dap": { "branch": "master", "commit": "7367cec8e8f7a0b1e4566af9a7ef5959d11206a7" },
"nvim-dap-python": { "branch": "master", "commit": "bfe572e4458e0ac876b9539a1e9f301c72db8ea0" },
"nvim-dap-ui": { "branch": "master", "commit": "cf91d5e2d07c72903d052f5207511bf7ecdb7122" },
"nvim-dap-view": { "branch": "main", "commit": "c0611ef470515e4ec7f6ffbe57b38ea640b8573b" },
"nvim-dap-view": { "branch": "main", "commit": "015822124280d0ee90fca04b0d1779381d6a4301" },
"nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" },
"nvim-highlight-colors": { "branch": "main", "commit": "b42a5ccec7457b44e89f7ed3b3afb1b375bb2093" },
"nvim-highlight-colors": { "branch": "main", "commit": "e0c4a58ec8c3ca7c92d3ee4eb3bc1dd0f7be317e" },
"nvim-jqx": { "branch": "master", "commit": "07393e80fa8097e82f9038fec05e948fe8a60fd1" },
"nvim-lint": { "branch": "master", "commit": "7ef127aaede2a4d5ad8df8321e2eb4e567f29594" },
"nvim-lspconfig": { "branch": "master", "commit": "45ff1914044de7dbd4cd85053dc09f47312a2f4d" },
"nvim-lint": { "branch": "master", "commit": "0864f81c681e15d9bdc1156fe3a17bd07db5a3ed" },
"nvim-lspconfig": { "branch": "master", "commit": "107c2458cdc780c4ed2c2b5e1b7800cd019010bd" },
"nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" },
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
"nvim-treesitter-context": { "branch": "master", "commit": "dca8726fea2c14e1ce6adbaa76a04816fbfaff61" },
"nvim-treesitter-textobjects": { "branch": "master", "commit": "71385f191ec06ffc60e80e6b0c9a9d5daed4824c" },
"nvim-ts-autotag": { "branch": "main", "commit": "a1d526af391f6aebb25a8795cbc05351ed3620b5" },
"obsidian.nvim": { "branch": "main", "commit": "4fd01de50c7fea3616f6809f19e9be8d2dc6ce63" },
"nvim-treesitter": { "branch": "main", "commit": "bd99d6bd2bdd346c5da090db5e3956de0e0a2f3f" },
"nvim-treesitter-context": { "branch": "master", "commit": "41847d3dafb5004464708a3db06b14f12bde548a" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "1b2d85d3de6114c4bcea89ffb2cd1ce9e3a19931" },
"nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" },
"obsidian.nvim": { "branch": "main", "commit": "2e97ec39570791675a05c29d888b48d1f4870e63" },
"persistence.nvim": { "branch": "main", "commit": "166a79a55bfa7a4db3e26fc031b4d92af71d0b51" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"py-requirements.nvim": { "branch": "main", "commit": "62363732a45e3200f38b772f4b3c0874f85342ba" },
"refactoring.nvim": { "branch": "master", "commit": "74b608dfee827c2372250519d433cc21cb083407" },
"render-markdown.nvim": { "branch": "main", "commit": "3da7bb459f6cff03980dd1e106c46f3e62ff4d9f" },
"snacks.nvim": { "branch": "main", "commit": "bc0630e43be5699bb94dadc302c0d21615421d93" },
"suda.vim": { "branch": "master", "commit": "9adda7d195222d4e2854efb2a88005a120296c47" },
"render-markdown.nvim": { "branch": "main", "commit": "67f2c7c8850bb11eefa6b22054a6f4cef1146de2" },
"snacks.nvim": { "branch": "main", "commit": "d67a47739dfc652cfcf66c59e929c704a854b37a" },
"todo-comments.nvim": { "branch": "main", "commit": "304a8d204ee787d2544d8bc23cd38d2f929e7cc5" },
"tokyonight.nvim": { "branch": "main", "commit": "057ef5d260c1931f1dffd0f052c685dcd14100a3" },
"trouble.nvim": { "branch": "main", "commit": "85bedb7eb7fa331a2ccbecb9202d8abba64d37b3" },
"tokyonight.nvim": { "branch": "main", "commit": "14fd5ff7f84027064724ec3157fe903199e77ded" },
"trouble.nvim": { "branch": "main", "commit": "f176232e7759c4f8abd923c21e3e5a5c76cd6837" },
"ts-comments.nvim": { "branch": "main", "commit": "1bd9d0ba1d8b336c3db50692ffd0955fe1bb9f0c" },
"ts-error-translator.nvim": { "branch": "main", "commit": "47e5ba89f71b9e6c72eaaaaa519dd59bd6897df4" },
"ts-node-action": { "branch": "master", "commit": "b0850ecd82a508ad846ba250ea13485b0e13321e" },
"tsc.nvim": { "branch": "main", "commit": "8c1b4ec6a48d038a79ced8674cb15e7db6dd8ef0" },
"vim-wakatime": { "branch": "master", "commit": "3403495670f0ee08887401a28f8430dc4ac67429" },
"venv-selector.nvim": { "branch": "main", "commit": "2b49d1f8b8fcf5cfbd0913136f48f118225cca5d" },
"vim-wakatime": { "branch": "master", "commit": "d7973b157a632d1edeff01818f18d67e584eeaff" },
"which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" },
"yanky.nvim": { "branch": "main", "commit": "04775cc6e10ef038c397c407bc17f00a2f52b378" },
"yazi.nvim": { "branch": "main", "commit": "74460dc4533bde424983702f1257df420455eebe" }
"yazi.nvim": { "branch": "main", "commit": "1769efadc505c297873c34e384b6630d4e06ab45" }
}

View file

@ -2,8 +2,8 @@
"extras": [
"lazyvim.plugins.extras.coding.mini-surround",
"lazyvim.plugins.extras.editor.dial",
"lazyvim.plugins.extras.editor.refactoring",
"lazyvim.plugins.extras.formatting.prettier",
"lazyvim.plugins.extras.lang.vue",
"lazyvim.plugins.extras.test.core",
"lazyvim.plugins.extras.ui.treesitter-context",
"lazyvim.plugins.extras.util.dot",
@ -12,11 +12,10 @@
"plugins.extras.coding.yanky-extended",
"plugins.extras.dap.core-extended",
"plugins.extras.editor.docs.obsidian",
"plugins.extras.editor.flash-extended",
"plugins.extras.editor.git.diffview",
"plugins.extras.editor.gitsigns-extended",
"plugins.extras.editor.marks.grapple",
"plugins.extras.editor.suda",
"plugins.extras.editor.treesitter-extended",
"plugins.extras.editor.trouble-extended",
"plugins.extras.lang.docker-extended",
"plugins.extras.lang.fish",
@ -24,11 +23,9 @@
"plugins.extras.lang.python-extended",
"plugins.extras.lang.web.html-css",
"plugins.extras.lang.web.typescript-extended",
"plugins.extras.lang.web.vue-3-extended",
"plugins.extras.linting.eslint-extended",
"plugins.extras.lsp.lspconfig-extended",
"plugins.extras.lsp.mason-extended",
"plugins.extras.ui.bufferline-extended",
"plugins.extras.ui.colorschemes.catppuccin",
"plugins.extras.ui.edgy-extended",
"plugins.extras.ui.highlight-colors",
@ -43,7 +40,8 @@
],
"install_version": 7,
"news": {
"NEWS.md": "10960"
"NEWS.md": "11866"
},
"version": 8
}
}

View file

@ -34,61 +34,13 @@ map("n", ">", ">>", { desc = "Indent" })
-- Save without formatting
map({ "n", "i" }, "<A-s>", "<cmd>noautocmd w<CR>", { desc = "Save Without Formatting" })
-- Cursor navigation on insert mode
map("i", "<M-h>", "<left>", { desc = "Move Cursor Left" })
map("i", "<M-l>", "<right>", { desc = "Move Cursor Left" })
map("i", "<M-j>", "<down>", { desc = "Move Cursor Left" })
map("i", "<M-k>", "<up>", { desc = "Move Cursor Left" })
-- End of the word backwards
map("n", "E", "ge")
-- Increment/decrement
map("n", "+", "<C-a>")
map("n", "-", "<C-x>")
-- Tabs
map("n", "]<tab>", "<cmd>tabnext<cr>", { desc = "Next Tab" })
map("n", "[<tab>", "<cmd>tabprevious<cr>", { desc = "Previous Tab" })
map("n", "<tab>", "<cmd>tabnext<cr>", { desc = "Next Tab" })
map("n", "<s-tab>", "<cmd>tabprevious<cr>", { desc = "Previous Tab" })
for i = 1, 9 do
map("n", "<leader><tab>" .. i, "<cmd>tabn " .. i .. "<cr>", { desc = "Tab " .. i })
end
map("n", "<leader>f<tab>", function()
vim.ui.select(vim.api.nvim_list_tabpages(), {
prompt = "Select Tab:",
format_item = function(tabid)
local wins = vim.api.nvim_tabpage_list_wins(tabid)
local not_floating_win = function(winid)
return vim.api.nvim_win_get_config(winid).relative == ""
end
wins = vim.tbl_filter(not_floating_win, wins)
local bufs = {}
for _, win in ipairs(wins) do
local buf = vim.api.nvim_win_get_buf(win)
local buftype = vim.api.nvim_get_option_value("buftype", { buf = buf })
if buftype ~= "nofile" then
local fname = vim.api.nvim_buf_get_name(buf)
table.insert(bufs, vim.fn.fnamemodify(fname, ":t"))
end
end
local tabnr = vim.api.nvim_tabpage_get_number(tabid)
local cwd = string.format(" %8s: ", vim.fn.fnamemodify(vim.fn.getcwd(-1, tabnr), ":t"))
local is_current = vim.api.nvim_tabpage_get_number(0) == tabnr and "" or " "
return tabnr .. is_current .. cwd .. table.concat(bufs, ", ")
end,
}, function(tabid)
if tabid ~= nil then
vim.cmd(tabid .. "tabnext")
end
end)
end, { desc = "Tabs" })
-- Buffers
map("n", "<leader>bf", "<cmd>bfirst<cr>", { desc = "First Buffer" })
map("n", "<leader>ba", "<cmd>blast<cr>", { desc = "Last Buffer" })
map("n", "<leader>b<tab>", "<cmd>tabnew %<cr>", { desc = "Current Buffer in New Tab" })
map("n", "<M-CR>", "<cmd>e #<cr>", { desc = "Switch to Other Buffer" })
-- Toggle statusline
@ -100,10 +52,6 @@ map("n", "<leader>uS", function()
end
end, { desc = "Toggle Statusline" })
-- Comment box
map("n", "]/", "/\\S\\zs\\s*╭<CR>zt", { desc = "Next Block Comment" })
map("n", "[/", "?\\S\\zs\\s*╭<CR>zt", { desc = "Prev Block Comment" })
-- Plugin Info
map("n", "<leader>cif", "<cmd>LazyFormatInfo<cr>", { desc = "Formatting" })
map("n", "<leader>cic", "<cmd>ConformInfo<cr>", { desc = "Conform" })
@ -128,45 +76,16 @@ end
map("n", "<leader>ciL", linters, { desc = "Lint" })
map("n", "<leader>cir", "<cmd>LazyRoot<cr>", { desc = "Root" })
-- U for redo
map("n", "U", "<C-r>", { desc = "Redo" })
-- Copy whole text to clipboard
map("n", "<C-c>", ":%y+<CR>", { desc = "Copy Whole Text to Clipboard", silent = true })
-- Motion
map("c", "<C-a>", "<C-b>", { desc = "Start Of Line" })
map("i", "<C-a>", "<Home>", { desc = "Start Of Line" })
map("i", "<C-e>", "<End>", { desc = "End Of Line" })
-- Select all text
map("n", "<C-e>", "gg<S-V>G", { desc = "Select all Text", silent = true, noremap = true })
-- Paste options
map("i", "<C-v>", '<C-r>"', { desc = "Paste on Insert Mode" })
map("v", "p", '"_dP', { desc = "Paste Without Overwriting" })
-- Delete and change without yanking
map({ "n", "x" }, "<A-d>", '"_d', { desc = "Delete Without Yanking" })
map({ "n", "x" }, "<A-c>", '"_c', { desc = "Change Without Yanking" })
-- Deleting without yanking empty line
map("n", "dd", function()
local is_empty_line = vim.api.nvim_get_current_line():match("^%s*$")
if is_empty_line then
return '"_dd'
else
return "dd"
end
end, { noremap = true, expr = true, desc = "Don't Yank Empty Line to Clipboard" })
-- Search inside visually highlighted text
map("x", "g/", "<esc>/\\%V", { silent = false, desc = "Search Inside Visual Selection" })
-- Search visually selected text (slightly better than builtins in Neovim>=0.8)
map("x", "*", [[y/\V<C-R>=escape(@", '/\')<CR><CR>]], { desc = "Search Selected Text", silent = true })
map("x", "#", [[y?\V<C-R>=escape(@", '?\')<CR><CR>]], { desc = "Search Selected Text (Backwards)", silent = true })
-- Dashboard
map("n", "<leader>fd", function()
if LazyVim.has("snacks.nvim") then
@ -195,33 +114,6 @@ if not LazyVim.has("floaterm.nvim") or not LazyVim.has("toggleterm.nvim") then
map("t", [[<c-\>]], "<cmd>close<cr>", { desc = "Hide Terminal" })
end
-- Marks
map("n", "dm", function()
local cur_line = vim.fn.line(".")
-- Delete buffer local mark
for _, mark in ipairs(vim.fn.getmarklist("%")) do
if mark.pos[2] == cur_line and mark.mark:match("[a-zA-Z]") then
vim.api.nvim_buf_del_mark(0, string.sub(mark.mark, 2, #mark.mark))
return
end
end
-- Delete global marks
local cur_buf = vim.api.nvim_win_get_buf(vim.api.nvim_get_current_win())
for _, mark in ipairs(vim.fn.getmarklist()) do
if mark.pos[1] == cur_buf and mark.pos[2] == cur_line and mark.mark:match("[a-zA-Z]") then
vim.api.nvim_buf_del_mark(0, string.sub(mark.mark, 2, #mark.mark))
return
end
end
end, { noremap = true, desc = "Mark on Current Line" })
-- Empty Line
map("n", "gO", "<Cmd>call append(line('.') - 1, repeat([''], v:count1))<CR>", { desc = "Empty Line Above" })
map("n", "go", "<Cmd>call append(line('.'), repeat([''], v:count1))<CR>", { desc = "Empty Line Below" })
-- Insert Mode
map({ "c", "i", "t" }, "<M-BS>", "<C-w>", { desc = "Delete Word" })
-- Git
map("n", "<leader>ghb", Snacks.git.blame_line, { desc = "Blame Line" })
@ -247,3 +139,6 @@ if Snacks.scroll.enabled then
return "<c-u>"
end, { expr = true })
end
-- Select first option for spelling
map("n", "<leader>S", "1z=", { desc = "Spelling (First Option)" })

View file

@ -40,6 +40,9 @@ o.showcmd = false
o.laststatus = 3
o.cmdheight = 0
-- Disable mouse
o.mouse = ""
-- Disable native bufferline
o.showtabline = 0

View file

@ -1,16 +1,7 @@
-- Delete this condition if you want to execute the file
if true then
return {}
end
-- Example of disabling some plugins. Add yours
local disabled = {
{
"akinsho/bufferline.nvim",
},
{
"nvim-lualine/lualine.nvim",
},
{ "akinsho/bufferline.nvim" },
{ "nvim-neo-tree/neo-tree.nvim" },
{ "folke/flash.nvim" },
}
for i, plugin in ipairs(disabled) do

View file

@ -65,17 +65,6 @@ return {
},
},
callbacks = {
enter_note = function(_, note)
vim.keymap.set("n", "gf", "<cmd>ObsidianFollowLink<cr>", {
buffer = note.bufnr,
expr = note.expr,
noremap = note.noremap,
desc = "File Passthrough",
})
end,
},
new_notes_location = "notes_subdir",
templates = {

View file

@ -4,7 +4,7 @@ return {
{ import = "lazyvim.plugins.extras.util.octo" },
{ import = "plugins.extras.lang.git-extended" },
{
"williamboman/mason.nvim",
"mason-org/mason.nvim",
opts = function(_, opts)
opts.ensure_installed = opts.ensure_installed or {}
vim.list_extend(opts.ensure_installed, { "gh" })

View file

@ -29,6 +29,7 @@ return {
keys = keys,
config = function()
require("grapple").setup({
scope = "git_branch",
win_opts = {
footer = "",
},

View file

@ -0,0 +1,12 @@
return {
"nvim-treesitter/nvim-treesitter",
opts = {
incremental_selection = {
enable = true,
keymaps = {
node_incremental = "v",
node_decremental = "V",
},
},
},
}

View file

@ -9,7 +9,7 @@ return {
end,
},
{
"williamboman/mason.nvim",
"mason-org/mason.nvim",
opts = {
ensure_installed = {
"ruff",

Some files were not shown because too many files have changed in this diff Show more