summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzachir <zachir@librem.one>2022-10-05 22:00:32 -0500
committerzachir <zachir@librem.one>2022-10-05 22:00:32 -0500
commitf39d735e2ba625a31a7dbf6fb8bdd62501379ad1 (patch)
treed17c96714c930e0b8bc75616cc9c81b961ed5aa0
Initial Commit
-rw-r--r--.gitignore185
-rw-r--r--.gitmodules12
-rw-r--r--Makefile50
-rw-r--r--README.md14
-rw-r--r--X11/Xresources492
-rwxr-xr-xX11/xinitrc4
-rwxr-xr-xX11/xprofile7
-rw-r--r--alacritty/alacritty.yml850
-rwxr-xr-xautostart.sh50
m---------awesome0
-rwxr-xr-xbspwm/bspwmrc66
-rw-r--r--bspwm/noswallow1
-rw-r--r--bspwm/terminals3
-rw-r--r--caffeine/audio_blacklist.txt0
-rw-r--r--caffeine/whitelist.txt0
-rw-r--r--computerrc.txt10
-rw-r--r--cool-retro-term/cool-retro-term.conf7
-rw-r--r--deadbeef/config79
-rw-r--r--deadbeef/dspconfig0
-rw-r--r--deadbeef/playlists/0.dbplbin0 -> 7050 bytes
-rw-r--r--deadbeef/playlists/1.dbplbin0 -> 6814 bytes
-rw-r--r--deadbeef/playlists/2.dbplbin0 -> 8914 bytes
-rw-r--r--doas.conf19
-rw-r--r--doom/config.el54
-rw-r--r--doom/init.el183
-rw-r--r--doom/packages.el50
-rw-r--r--dunst/dunstrc418
-rwxr-xr-xdwm/autostart.sh3
-rwxr-xr-xdwm/autostart_blocking.sh2
-rw-r--r--ff_enterprise_policy.zipbin0 -> 2479 bytes
-rw-r--r--firejail/disable-exec.local1
-rw-r--r--firejail/dolphin-emu.local4
-rw-r--r--firejail/librewolf.local4
-rw-r--r--firejail/lynx.local3
-rw-r--r--firejail/mpv.local3
-rw-r--r--firejail/neomutt.local24
-rw-r--r--firejail/nextcloud.local4
-rw-r--r--firejail/qutebrowser.local4
-rw-r--r--firejail/steam.local2
-rw-r--r--ghostwriter/ghostwriter.conf68
-rw-r--r--gtk-2.0/gtkfilechooser.ini11
-rw-r--r--gtk-2.0/gtkrc19
-rw-r--r--gtk-3.0/gtk.css12
-rw-r--r--gtk-3.0/settings.ini16
-rw-r--r--herbstluftwm/README.md3
-rwxr-xr-xherbstluftwm/autostart205
-rwxr-xr-xherbstluftwm/spblue17
-rwxr-xr-xherbstluftwm/sphtop18
-rwxr-xr-xherbstluftwm/spirss18
-rwxr-xr-xherbstluftwm/spmpv22
-rwxr-xr-xherbstluftwm/spmutt18
-rwxr-xr-xherbstluftwm/spncmp18
-rwxr-xr-xherbstluftwm/sppmxr18
-rwxr-xr-xherbstluftwm/spprof18
-rwxr-xr-xherbstluftwm/spterm18
-rwxr-xr-xinstallers/vimplug_nvim.sh4
-rwxr-xr-xinstallers/vimplug_vim.sh4
-rw-r--r--jellycli.yaml0
-rw-r--r--jellycli/jellycli.yaml38
-rw-r--r--kshrc38
-rwxr-xr-xlf/3q2
-rwxr-xr-xlf/cleaner4
-rwxr-xr-xlf/image18
-rw-r--r--lf/lfrc351
-rwxr-xr-xlf/preview83
-rw-r--r--lxqt/lxqt.conf3
-rw-r--r--mksh/mkshalias50
-rw-r--r--mksh/mkshfunc58
-rw-r--r--mksh/mkshrc684
-rw-r--r--modprobed-db.conf21
-rw-r--r--mpd/mpd.conf401
-rw-r--r--mpv/input.conf2
-rw-r--r--mpv/mpv.conf5
-rw-r--r--mpv/script-opts/quality-menu.conf95
-rw-r--r--mpv/script-opts/youtube-download.conf48
-rw-r--r--mpv/scripts/quality-menu-osc.lua2911
-rw-r--r--mpv/scripts/quality-menu.lua806
-rw-r--r--mpv/scripts/youtube-download.lua758
-rw-r--r--ncmpcpp/bindings543
-rw-r--r--ncmpcpp/config544
-rw-r--r--ncmpcpp/patterns.list0
-rw-r--r--newsboat/config55
-rw-r--r--nvim/init.vim267
-rw-r--r--nyxt/auto-config.lisp4
-rw-r--r--open/openrc15
-rw-r--r--paru/paru.conf37
-rw-r--r--picom.conf93
-rw-r--r--pipewire/pipewire.conf246
-rw-r--r--pipewire/wireplumber.conf90
-rw-r--r--polybar/config615
-rw-r--r--profanity/themes/redbox80
-rw-r--r--psub/config.yaml74
-rw-r--r--qt5ct/qt5ct.conf32
-rw-r--r--qt6ct/qt6ct.conf38
-rw-r--r--qtile/config.py539
-rw-r--r--qutebrowser/bookmarks/urls1
-rw-r--r--qutebrowser/config.py275
m---------qutebrowser/jmatrix0
-rw-r--r--qutebrowser/quickmarks1
-rwxr-xr-xriver/init167
-rw-r--r--sh/aliases70
-rw-r--r--sh/functions130
-rw-r--r--snownews/colors21
-rw-r--r--snownews/keybindings39
-rw-r--r--spectrwm/spectrwm.conf145
-rw-r--r--stalonetrayrc137
-rw-r--r--stmp6
-rw-r--r--swayidle/config2
-rwxr-xr-xswhkd/swhkdrc158
-rwxr-xr-xsx/sxrc1
-rwxr-xr-xsxhkd/sxhkdrc170
-rwxr-xr-xsxhkd/sxhkdrc.1329
-rwxr-xr-xsxhkd/sxhkdrc.bsp159
-rwxr-xr-xsxiv/exec/key-handler11
-rw-r--r--tmux/tmux.conf30
-rw-r--r--tofi/config18
-rw-r--r--trizen/trizen.conf57
-rw-r--r--user-dirs.dirs15
-rw-r--r--user-dirs.locale1
-rw-r--r--vlc/vlcrc5120
-rw-r--r--waybar/config474
-rw-r--r--waybar/style.css245
-rw-r--r--waylock/waylock.toml4
-rw-r--r--xmodmap26
-rw-r--r--xplr/init.lua2443
-rw-r--r--xplr/plugins/dragon/LICENSE21
-rw-r--r--xplr/plugins/dragon/README.md49
-rw-r--r--xplr/plugins/dragon/src/init.lua62
-rw-r--r--yay/config.json43
-rw-r--r--ytfzf/conf.sh9
-rw-r--r--zsh/.zlogout2
-rw-r--r--zsh/.zprofile6
-rw-r--r--zsh/.zshenv78
-rw-r--r--zsh/.zshrc79
134 files changed, 23367 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0f02088
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,185 @@
+zsh/hist
+zsh/zcompdump
+zoomus.conf
+zec-qt-wallet-org/
+ytfzf/subscriptions
+yabridgectl/
+xmonad/.stack-work
+xmonad/stack.yaml.lock
+xmonad/xmonad-x86_64-linux
+xmonad/xmonad.o
+xmonad/xmonad.hi
+weechat/
+vlc/vlc-qt-interface.conf
+vdirsyncer/
+unity3d/
+ubports-installer/
+transmission-daemon/
+transmission/*
+!transmission/settings.json
+torbrowser/
+tmux/plugins
+syncthing/
+switcher/
+straw-viewer/
+spotify-tui/
+spotifyd/
+snownews/urls.opml
+sh/weather
+rtorrent/
+rncbc.org/
+retroarch/
+rclone/
+qutebrowser/jmatrix-rules
+qtile/__pycache__/
+!qt6ct/qt6ct.conf
+qt6ct/*
+!qt5ct/qt5ct.conf
+qt5ct/*
+pupgui/
+pulse/
+protonmail/
+protonfixes/
+profanity/profrc
+print-manager/
+polychromatic/
+poezio/
+pmbootstrap.cfg
+pipewire/media-session.d/
+PCSX2/
+pcmanfm/
+pavucontrol.ini
+openrazer/
+okularrc
+okularpartrc
+nvim/plugged/
+nwg-outputs/
+nssdb/
+npm/
+notmuch/
+nitrogen/bg-saved.cfg
+newsboat/urls
+newsboat/cache.db
+nextcloud/
+neofetch/
+ncmpcpp/error.log
+mutt/
+musnify-mpd/musnify-mpd.config
+msmtp/
+mpv/watch_later/
+mpv/download.log
+mpd/database
+mpd/log
+mpd/pid
+mpd/socket
+mpd/state
+mpd/sticker.sql
+mpd/playlists/
+modprobed.db
+monero-project/
+mimeapps.list
+mksh/history
+minigalaxy/
+micro/buffers/
+mgba/
+menus/
+lutris/
+lsp-plugins/
+lkjb/
+linvst/
+light/
+libreoffice/
+libfm/
+lbry/
+lab/
+ksh/history
+kritarc
+kritadisplayrc
+kicad/
+keepassxc/
+kdenlive-layoutsrc
+kdenlive-appimagerc
+kdenliverc
+kdeglobals
+kdeconnect/
+kaidan/
+joplin/
+joplin-desktop/
+java/
+jack_mixer/
+jack/
+isync/
+irssi/
+inkscape/
+icedtea-web/
+htop/htoprc
+guitarix/
+gtk-3.0/bookmarks
+gtk-2.0/gtkfilechooser.ini
+gomuks/
+ghb/
+gaiasky/
+fontconfig/
+falkTX/
+enchant/
+emacs/
+dolphin-emu/
+dde-printer.ini
+dconf/
+cordless/config.json
+configstore/
+computerrc
+companion/
+coc/extensions/db.json
+clangd/
+chromium/
+cef_user_data
+calibre/conversion
+calibre/
+blender/
+autostart/
+ardour6/
+amsynth/
+abook/
+VirtualBox/
+UNDERTALE*/
+The Crown EXEX.settings
+SUPERHOT/
+Session/
+SchildiChat/
+RVXX v2/
+RVXX v2.settings
+RVXX EXEX.settings
+Resonant DSP/
+REAPER/
+ReAmp Studio R1.settings
+ReAmp Studio R1/
+QtProject.conf
+QtProject/
+Proton AG/
+Portmaster/
+NuGet/
+Nextcloud/
+LibrePCB/
+Kitware/
+Joplin/
+Iriun/
+GIMP/
+FreeTube/
+FreakQ305.settings
+FreakQ305/
+Epic/
+Etherdyne/
+EmeraldWallet/
+Element/
+Cadence/
+BULLDOG.settings
+BraveSoftware/
+Blacksun.settings
+Blacksun/
+Binance/
+AHM 5050 v3.settings
+AHM 5050 v3/
+@joplin/
+.tsrc
+.charles.config
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4528b81
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,12 @@
+[submodule "emacs"]
+ path = emacs
+ url = https://github.com/hlissner/doom-emacs
+[submodule "xplr/dragon.xplr"]
+ path = xplr/dragon.xplr
+ url = https://github.com/sayanarijit/dragon.xplr
+[submodule "awesome"]
+ path = awesome
+ url = https://gitlab.com/zachir/awesome-config
+[submodule "qutebrowser/jmatrix"]
+ path = qutebrowser/jmatrix
+ url = https://gitlab.com/jgkamat/jmatrix.git
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..0de9447
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,50 @@
+VIM := $(shell command -v vim 2>/dev/null)
+NVIM := $(shell command -v nvim 2>/dev/null)
+XCONFS := X11/xinitrc X11/xprofile X11/Xresources
+ZCONFS := zsh/.zshenv
+DCONFS := doas.conf
+
+all:
+
+install: install-xconfigs install-zshconfigs vimplug-vim vimplug-nvim doas-conf
+
+install-xconfigs: $(XCONFS)
+ @echo "Installing Xorg conf files..."
+ @echo "xinitrc..."
+ @ln -sf `pwd`/X11/xinitrc ~/.xinitrc
+ @echo "xprofile..."
+ @ln -sf `pwd`/X11/xprofile ~/.xprofile
+ @echo "Xresources..."
+ @ln -sf `pwd`/X11/Xresources ~/.Xresources
+ @echo "Done."
+
+install-zshconfigs: $(ZCONFS)
+ @echo "Installing zsh conf files..."
+ @echo ".zshenv..."
+ @ln -sf `pwd`/zsh/.zshenv ~/.zshenv
+ @echo "Done."
+
+vimplug-vim: installers/vimplug_vim.sh
+ifdef VIM
+ @echo "Installing vim-plug for vim..."
+ @$(shell installers/vimplug_vim.sh)
+ @echo "Done."
+else
+ @echo "vim not installed."
+endif
+
+vimplug-nvim: installers/vimplug_nvim.sh
+ifdef NVIM
+ @echo "Installing vim-plug for nvim..."
+ @$(shell installers/vimplug_nvim.sh)
+ @echo "Done."
+else
+ @echo "nvim not installed."
+endif
+
+doas-conf: $(DCONFS)
+ @echo "Installing doas config files..."
+ @echo "doas.conf..."
+ @$(foreach conf,$(DCONFS),\
+ $(sudo cp $(conf) /etc/$(conf)))
+ @echo "Done."
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9acdf05
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+## Zachir's Config Files
+
+Hello! These are all the config files I thought could potentially be useful, both to myself to make reinstalling Linux faster, as well as for anyone interested. There are a few notes I feel I should make:
+
+- I have a custom dwm build, which sources 'autostart.sh' and 'autostart_blocking.sh' from __*.config/dwm*__ not *.dwm*. This is available [here](https://gitlab.com/zachir/dwm-zir).
+- I also have a custom st build, which sources '.Xresources' (this is a common enough patch, but I thought I would mention it, as I include my .Xresources file) available [here](https://gitlab.com/zachir/st-zir).
+- I have gone through everything to remove personal information, however I might have missed something. If that happens, this repo will be updated, and the branch history deleted.
+
+My personal installation method is as follows (performed immediately following a clean install):
+`git clone https://gitlab.com/zachir/dotfiles ~/.config
+cd ~/.config
+make install`
+
+Note that the `make install` will only install the files in `HOME` to their corresponding place in the home dir as hard links. Make sure to save changes to these files before cloning! Additionally, if you only want my configs for specific programs, I would recommend cloning it into a separate directory and avoiding the `make install`.
diff --git a/X11/Xresources b/X11/Xresources
new file mode 100644
index 0000000..367f4d4
--- /dev/null
+++ b/X11/Xresources
@@ -0,0 +1,492 @@
+!! dmenu
+
+dmenu.font: mononoki Nerd Font Mono:size=12
+
+!! dwm
+
+dwm.normbgcolor: #000000
+dwm.normbordercolor: #1b1d1c
+dwm.normfgcolor: #ffffff
+dwm.selbgcolor: #2783a1
+dwm.selbordercolor: #2783a1
+dwm.selfgcolor: #ffffff
+dwm.urgfgcolor: #ffffff
+dwm.urgbordercolor: #2783a1
+dwm.urgbgcolor: #cc342b
+dwm.borderpx: 3
+dwm.gappx: 6
+dwm.snap: 32
+dwm.showbar: 1
+dwm.topbar: 1
+dwm.nmaster: 1
+dwm.resizehints: 1
+dwm.mfact: 0.50
+
+!! st
+
+! These options only take effect on startup.
+st.termname: st-256color
+! if you do not set shell, precedence is: -e arg, utmp option, SHELL env var, /etc/passwd shell
+st.shell: /usr/bin/tmux
+
+! The following options options can be reloaded via USR1 signal.
+st.font: mononoki Nerd Font Mono:pixelsize=12:antialias=true:autohint=true;
+st.font2: Symbola:pixelsize=11:antialias=true:autohint=true;
+st.borderpx: 0
+! st alpha
+st.alpha: 0.5
+! Available cursor values: 2 4 6 7 = █ _ | ☃ ( 1 3 5 are blinking versions)
+st.cursorshape: 6
+! thickness of underline and bar cursors
+st.cursorthickness: 2
+! 0: normal blinking, 1: leave cursor border and blink with cursor''s background
+st.cursorblinkstyle: 0
+! 0: cursor blinks with a constant interval; 1: blinking cycle resets on key input
+st.cursorblinkontype: 1
+! st.bold_font: 0
+st.xfps: 120
+st.actionfps: 60
+! Amount of lines scrolled
+st.mouseScrollLines: 1
+! Kerning / character bounding-box height multiplier
+st.chscale: 1.0
+! Kerning / character bounding-box width multiplier
+st.cwscale: 1.0
+! blinking timeout for terminal and cursor blinking (0 disables)
+st.blinktimeout: 800
+! bell volume. Value between -100 and 100. (0 disables)
+st.bellvolume: 0
+! this is a char that is exposed like so: `printf '\033[z'`
+st.prompt_char: $
+! This option is can be preedit style. Available values: `root` `overthespot` (Default taken `root`)
+st.imstyle: root
+
+!! RXVT-Unicode (urxvt) config
+! do not scroll with output
+URxvt.scrollTtyOutput: false
+! scroll in relation to buffer (with mouse scroll or Shift+Page Up)
+URxvt.scrollWithBuffer: true
+! scroll back to the bottom on keypress
+URxvt.scrollTtyKeypress: true
+! disable scrollback buffer for secondary screen
+URxvt.secondaryScreen: 1
+URxvt.secondaryScroll: 0
+URxvt.secondaryWheel: 1
+! URxvt font
+URxvt.font: xft:Fira Code:regular:size=8,xft:symbola:regular:size=9
+! fix font spacing
+URxvt.letterSpace: -1
+! Disable printing
+URxvt.print-pipe: "cat > /dev/null"
+! disable iso14755
+URxvt.iso14755: false
+URxvt.iso14755_52: false
+! enable transparency
+URxvt.depth: 32
+URxvt.background: rgba:0000/0000/0200/c800
+! disable scrollbar
+URxvt.scrollBar: false
+
+!! perls
+! perls
+URxvt.perl-ext: default,url-select,tabbed,resize-font,clipboard
+! clipboard
+URxvt.clipboard.autocopy: true
+URxvt.keysym.Shift-Control-C: perl:clipboard:copy
+URxvt.keysym.Shift-Control-V: perl:clipboard:paste
+! url-select
+URxvt.keysum.M-u: perl:url-select:select-next
+URxvt.url-select.launcher: /usr/bin/xdg-open
+URxvt.url-select.underline: true
+! tabbed
+URxvt.tabbed.tabbar-fg: 2
+URxvt.tabbed.tabbar-bg: 0
+URxvt.tabbed.tab-fg: 3
+URxvt.tabbed.tab-bg: 0
+! resize-font
+URxvt.keysym.C-Minus: resize-font:smaller
+URxvt.keysym.C-Plus: resize-font:bigger
+
+! "Enabled modi" Set from: Default
+rofi.modi: window,run,ssh,drun
+! "Window width" Set from: Default
+rofi.width: 1366
+! "Number of lines" Set from: Default
+! rofi.lines: 15
+! "Number of columns" Set from: Default
+! rofi.columns: 1
+! "Font to use" Set from: Default
+rofi.font: mononoki 9
+! "Border width" Set from: Default
+! rofi.bw: 1
+! "Location on screen" Set from: Default
+rofi.location: 2
+! "Padding" Set from: Default
+! rofi.padding: 5
+! "Y-offset relative to location" Set from: Default
+! rofi.yoffset: 0
+! "X-offset relative to location" Set from: Default
+! rofi.xoffset: 0
+! "Always show number of lines" Set from: Default
+! rofi.fixed-num-lines: true
+! "Whether to load and show icons" Set from: Default
+! rofi.show-icons: false
+! "Terminal to use" Set from: Default
+! rofi.terminal: rofi-sensible-terminal
+! "Ssh client to use" Set from: Default
+! rofi.ssh-client: ssh
+! "Ssh command to execute" Set from: Default
+! rofi.ssh-command: {terminal} -e {ssh-client} {host} [-p {port}]
+! "Run command to execute" Set from: Default
+! rofi.run-command: {cmd}
+! "Command to get extra run targets" Set from: Default
+! rofi.run-list-command:
+! "Run command to execute that runs in shell" Set from: Default
+! rofi.run-shell-command: {terminal} -e {cmd}
+! "Command to executed when -kb-accept-alt binding is hit on selected window " Set from: Default
+! rofi.window-command: wmctrl -i -R {window}
+! "Window fields to match in window mode" Set from: Default
+! rofi.window-match-fields: all
+! "Theme to use to look for icons" Set from: Default
+! rofi.icon-theme:
+! "Desktop entry fields to match in drun" Set from: Default
+! rofi.drun-match-fields: name,generic,exec,categories,keywords
+! "Only show Desktop entry from these categories" Set from: Default
+! rofi.drun-categories:
+! "Desktop entry show actions." Set from: Default
+! rofi.drun-show-actions: false
+! "DRUN format string. (Supports: generic,name,comment,exec,categories)" Set from: Default
+! rofi.drun-display-format: {name} [<span weight='light' size='small'><i>({generic})</i></span>]
+! "Command to open an Desktop Entry that is a Link." Set from: Default
+! rofi.drun-url-launcher: xdg-open
+! "Disable history in run/ssh" Set from: Default
+! rofi.disable-history: false
+! "Programs ignored for history" Set from: Default
+! rofi.ignored-prefixes:
+! "Use sorting" Set from: Default
+! rofi.sort: false
+! "Choose the strategy used for sorting: normal (levenshtein) or fzf." Set from: Default
+! rofi.sorting-method: normal
+! "Set case-sensitivity" Set from: Default
+! rofi.case-sensitive: false
+! "Cycle through the results list" Set from: Default
+! rofi.cycle: true
+! "Enable sidebar-mode" Set from: Default
+! rofi.sidebar-mode: false
+! "Row height (in chars)" Set from: Default
+! rofi.eh: 1
+! "Enable auto select mode" Set from: Default
+! rofi.auto-select: false
+! "Parse hosts file for ssh mode" Set from: Default
+! rofi.parse-hosts: false
+! "Parse known_hosts file for ssh mode" Set from: Default
+! rofi.parse-known-hosts: true
+! "Set the modi to combine in combi mode" Set from: Default
+! rofi.combi-modi: window,run
+! "Set the matching algorithm. (normal, regex, glob, fuzzy)" Set from: Default
+! rofi.matching: normal
+! "Tokenize input string" Set from: Default
+! rofi.tokenize: true
+! "Monitor id to show on" Set from: Default
+! rofi.m: -5
+! "Margin between rows *DEPRECATED*" Set from: Default
+! rofi.line-margin: 2
+! "Padding within rows *DEPRECATED*" Set from: Default
+! rofi.line-padding: 1
+! "Pre-set filter" Set from: Default
+! rofi.filter:
+! "Separator style (none, dash, solid) *DEPRECATED*" Set from: Default
+! rofi.separator-style: dash
+! "Hide scroll-bar *DEPRECATED*" Set from: Default
+! rofi.hide-scrollbar: false
+! "Fullscreen" Set from: Default
+! rofi.fullscreen: false
+! "Fake transparency *DEPRECATED*" Set from: Default
+! rofi.fake-transparency: false
+! "DPI" Set from: Default
+! rofi.dpi: -1
+! "Threads to use for string matching" Set from: Default
+! rofi.threads: 0
+! "Scrollbar width *DEPRECATED*" Set from: Default
+! rofi.scrollbar-width: 8
+! "Scrolling method. (0: Page, 1: Centered)" Set from: Default
+! rofi.scroll-method: 0
+! "Background to use for fake transparency. (background or screenshot) *DEPRECATED*" Set from: Default
+! rofi.fake-background: screenshot
+! "Window Format. w (desktop name), t (title), n (name), r (role), c (class)" Set from: Default
+! rofi.window-format: {w} {c} {t}
+! "Click outside the window to exit" Set from: Default
+! rofi.click-to-exit: true
+! "Indicate how it match by underlining it." Set from: Default
+! rofi.show-match: true
+! "New style theme file" Set from: Default
+! rofi.theme:
+! "Color scheme for normal row" Set from: Default
+! 'bg' 'fg' 'bgalt' 'hlbg' 'hlfg'
+rofi.color-normal: #000000, #b4b7b5, #89231d, #cc342b, #000000
+! "Color scheme for urgent row" Set from: Default
+! rofi.color-urgent:
+! "Color scheme for active row" Set from: Default
+! rofi.color-active:
+! "Color scheme window" Set from: Default
+! 'background' 'border' 'separator'
+rofi.color-window: #1d1f21, #101010, #000000
+! "Max history size (WARNING: can cause slowdowns when set to high)." Set from: Default
+! rofi.max-history-size: 25
+! "Hide the prefix mode prefix on the combi view." Set from: Default
+! rofi.combi-hide-mode-prefix: false
+! "Set the character used to negate the matching. ('\0' to disable)" Set from: Default
+! rofi.matching-negate-char: -
+! "Directory where history and temporary files are stored." Set from: Default
+! rofi.cache-dir:
+! "Show window thumbnail (if available) as icon in window switcher." Set from: Default
+! rofi.window-thumbnail: false
+! "DRUN: build and use a cache with desktop file content." Set from: Default
+! rofi.drun-use-desktop-cache: false
+! "DRUN: If enabled, reload the cache with desktop file content." Set from: Default
+! rofi.drun-reload-desktop-cache: false
+! "Normalize string when matching (implies -no-show-match)." Set from: Default
+! rofi.normalize-match: false
+! "Pidfile location" Set from: Default
+! rofi.pid: /run/user/1000/rofi.pid
+! "The display name of this browser" Set from: Default
+! rofi.display-window:
+! "The display name of this browser" Set from: Default
+! rofi.display-windowcd:
+! "The display name of this browser" Set from: Default
+! rofi.display-run:
+! "The display name of this browser" Set from: Default
+! rofi.display-ssh:
+! "The display name of this browser" Set from: Default
+! rofi.display-drun:
+! "The display name of this browser" Set from: Default
+! rofi.display-combi:
+! "The display name of this browser" Set from: Default
+! rofi.display-keys:
+! "The display name of this browser" Set from: Default
+! rofi.display-file-browser:
+! "Paste primary selection" Set from: Default
+! rofi.kb-primary-paste: Control+V,Shift+Insert
+! "Paste clipboard" Set from: Default
+! rofi.kb-secondary-paste: Control+v,Insert
+! "Clear input line" Set from: Default
+! rofi.kb-clear-line: Control+w
+! "Beginning of line" Set from: Default
+! rofi.kb-move-front: Control+a
+! "End of line" Set from: Default
+! rofi.kb-move-end: Control+e
+! "Move back one word" Set from: Default
+! rofi.kb-move-word-back: Alt+b,Control+Left
+! "Move forward one word" Set from: Default
+! rofi.kb-move-word-forward: Alt+f,Control+Right
+! "Move back one char" Set from: Default
+! rofi.kb-move-char-back: Left,Control+b
+! "Move forward one char" Set from: Default
+! rofi.kb-move-char-forward: Right,Control+f
+! "Delete previous word" Set from: Default
+! rofi.kb-remove-word-back: Control+Alt+h,Control+BackSpace
+! "Delete next word" Set from: Default
+! rofi.kb-remove-word-forward: Control+Alt+d
+! "Delete next char" Set from: Default
+! rofi.kb-remove-char-forward: Delete,Control+d
+! "Delete previous char" Set from: Default
+! rofi.kb-remove-char-back: BackSpace,Shift+BackSpace,Control+h
+! "Delete till the end of line" Set from: Default
+! rofi.kb-remove-to-eol: Control+k
+! "Delete till the start of line" Set from: Default
+! rofi.kb-remove-to-sol: Control+u
+! "Accept entry" Set from: Default
+! rofi.kb-accept-entry: Control+j,Control+m,Return,KP_Enter
+! "Use entered text as command (in ssh/run modi)" Set from: Default
+! rofi.kb-accept-custom: Control+Return
+! "Use alternate accept command." Set from: Default
+! rofi.kb-accept-alt: Shift+Return
+! "Delete entry from history" Set from: Default
+! rofi.kb-delete-entry: Shift+Delete
+! "Switch to the next mode." Set from: Default
+! rofi.kb-mode-next: Shift+Right,Control+Tab
+! "Switch to the previous mode." Set from: Default
+! rofi.kb-mode-previous: Shift+Left,Control+ISO_Left_Tab
+! "Go to the previous column" Set from: Default
+! rofi.kb-row-left: Control+Page_Up
+! "Go to the next column" Set from: Default
+! rofi.kb-row-right: Control+Page_Down
+! "Select previous entry" Set from: Default
+! rofi.kb-row-up: Up,Control+p,ISO_Left_Tab
+! "Select next entry" Set from: Default
+! rofi.kb-row-down: Down,Control+n
+! "Go to next row, if one left, accept it, if no left next mode." Set from: Default
+! rofi.kb-row-tab: Tab
+! "Go to the previous page" Set from: Default
+! rofi.kb-page-prev: Page_Up
+! "Go to the next page" Set from: Default
+! rofi.kb-page-next: Page_Down
+! "Go to the first entry" Set from: Default
+! rofi.kb-row-first: Home,KP_Home
+! "Go to the last entry" Set from: Default
+! rofi.kb-row-last: End,KP_End
+! "Set selected item as input text" Set from: Default
+! rofi.kb-row-select: Control+space
+! "Take a screenshot of the rofi window" Set from: Default
+! rofi.kb-screenshot: Alt+S
+! "Toggle between ellipsize modes for displayed data" Set from: Default
+! rofi.kb-ellipsize: Alt+period
+! "Toggle case sensitivity" Set from: Default
+! rofi.kb-toggle-case-sensitivity: grave,dead_grave
+! "Toggle sort" Set from: Default
+! rofi.kb-toggle-sort: Alt+grave
+! "Quit rofi" Set from: Default
+! rofi.kb-cancel: Escape,Control+g,Control+bracketleft
+! "Custom keybinding 1" Set from: Default
+! rofi.kb-custom-1: Alt+1
+! "Custom keybinding 2" Set from: Default
+! rofi.kb-custom-2: Alt+2
+! "Custom keybinding 3" Set from: Default
+! rofi.kb-custom-3: Alt+3
+! "Custom keybinding 4" Set from: Default
+! rofi.kb-custom-4: Alt+4
+! "Custom Keybinding 5" Set from: Default
+! rofi.kb-custom-5: Alt+5
+! "Custom keybinding 6" Set from: Default
+! rofi.kb-custom-6: Alt+6
+! "Custom Keybinding 7" Set from: Default
+! rofi.kb-custom-7: Alt+7
+! "Custom keybinding 8" Set from: Default
+! rofi.kb-custom-8: Alt+8
+! "Custom keybinding 9" Set from: Default
+! rofi.kb-custom-9: Alt+9
+! "Custom keybinding 10" Set from: Default
+! rofi.kb-custom-10: Alt+0
+! "Custom keybinding 11" Set from: Default
+! rofi.kb-custom-11: Alt+exclam
+! "Custom keybinding 12" Set from: Default
+! rofi.kb-custom-12: Alt+at
+! "Custom keybinding 13" Set from: Default
+! rofi.kb-custom-13: Alt+numbersign
+! "Custom keybinding 14" Set from: Default
+! rofi.kb-custom-14: Alt+dollar
+! "Custom keybinding 15" Set from: Default
+! rofi.kb-custom-15: Alt+percent
+! "Custom keybinding 16" Set from: Default
+! rofi.kb-custom-16: Alt+dead_circumflex
+! "Custom keybinding 17" Set from: Default
+! rofi.kb-custom-17: Alt+ampersand
+! "Custom keybinding 18" Set from: Default
+! rofi.kb-custom-18: Alt+asterisk
+! "Custom Keybinding 19" Set from: Default
+! rofi.kb-custom-19: Alt+parenleft
+! "Select row 1" Set from: Default
+! rofi.kb-select-1: Super+1
+! "Select row 2" Set from: Default
+! rofi.kb-select-2: Super+2
+! "Select row 3" Set from: Default
+! rofi.kb-select-3: Super+3
+! "Select row 4" Set from: Default
+! rofi.kb-select-4: Super+4
+! "Select row 5" Set from: Default
+! rofi.kb-select-5: Super+5
+! "Select row 6" Set from: Default
+! rofi.kb-select-6: Super+6
+! "Select row 7" Set from: Default
+! rofi.kb-select-7: Super+7
+! "Select row 8" Set from: Default
+! rofi.kb-select-8: Super+8
+! "Select row 9" Set from: Default
+! rofi.kb-select-9: Super+9
+! "Select row 10" Set from: Default
+! rofi.kb-select-10: Super+0
+! "Go to the previous column" Set from: Default
+! rofi.ml-row-left: ScrollLeft
+! "Go to the next column" Set from: Default
+! rofi.ml-row-right: ScrollRight
+! "Select previous entry" Set from: Default
+! rofi.ml-row-up: ScrollUp
+! "Select next entry" Set from: Default
+! rofi.ml-row-down: ScrollDown
+! "Select hovered row" Set from: Default
+! rofi.me-select-entry: MousePrimary
+! "Accept hovered row" Set from: Default
+! rofi.me-accept-entry: MouseDPrimary
+! "Accept hovered row with custom action" Set from: Default
+! rofi.me-accept-custom: Control+MouseDPrimary
+
+!! special
+!*.foreground: #c5c8c6
+!*.background: #1d1f21
+!*.cursorColor: #c5c8c6
+!
+!! black
+!*.color0: #282a2e
+!*.color8: #373b41
+!
+!! red
+!*.color1: #a54242
+!*.color9: #cc6666
+!
+!! green
+!*.color2: #8c9440
+!*.color10: #b5bd68
+!
+!! yellow
+!*.color3: #de935f
+!*.color11: #f0c674
+!
+!! blue
+!*.color4: #5f819d
+!*.color12: #81a2be
+!
+!! magenta
+!*.color5: #85678f
+!*.color13: #b294bb
+!
+!! cyan
+!*.color6: #5e8d87
+!*.color14: #8abeb7
+!
+!! white
+!*.color7: #707880
+!*.color15: #c5c8c6
+!
+!! special
+*.foreground: #c5c8c6
+*.background: #000000
+*.cursorColor: #c5c8c6
+*.reverseCursor: #333536
+dmenu.selbackground: #39c1ed
+dmenu.selforeground: #000000
+dmenu.hibackground: #000000
+dmenu.hiforeground: #198844
+dmenu.selhibackground: #39c1ed
+dmenu.selhiforeground: #198844
+
+! black
+*.color0: #1b1d1c
+*.color8: #969896
+
+! red
+*.color1: #89231d
+*.color9: #cc342b
+
+! green
+*.color2: #4eec4e
+*.color10: #198844
+
+! yellow
+*.color3: #ae7518
+*.color11: #fba922
+
+! blue
+*.color4: #2b55b2
+*.color12: #3971ed
+
+! magenta
+*.color5: #784e93
+*.color13: #a36ac7
+
+! cyan
+*.color6: #2783a1
+*.color14: #39c1ed
+
+! white
+*.color7: #b4b7b5
+*.color15: #ffffff
diff --git a/X11/xinitrc b/X11/xinitrc
new file mode 100755
index 0000000..3945b40
--- /dev/null
+++ b/X11/xinitrc
@@ -0,0 +1,4 @@
+xrdb ~/.Xresources
+sh -c ~/.xprofile &
+WM="$(~/.local/scripts/crcparse 'WM')"
+exec dbus-launch --exit-with-session $WM
diff --git a/X11/xprofile b/X11/xprofile
new file mode 100755
index 0000000..96f2954
--- /dev/null
+++ b/X11/xprofile
@@ -0,0 +1,7 @@
+#!/bin/sh
+layout.sh
+tsoff
+xrdb ~/.Xresources &
+setxkbmap -option "caps:escape" &
+xwallpaper --center ~/background.jpg &
+picom &
diff --git a/alacritty/alacritty.yml b/alacritty/alacritty.yml
new file mode 100644
index 0000000..1e4bfe0
--- /dev/null
+++ b/alacritty/alacritty.yml
@@ -0,0 +1,850 @@
+# Configuration for Alacritty, the GPU enhanced terminal emulator.
+
+# Import additional configuration files
+#
+# Imports are loaded in order, skipping all missing files, with the importing
+# file being loaded last. If a field is already present in a previous import, it
+# will be replaced.
+#
+# All imports must either be absolute paths starting with `/`, or paths relative
+# to the user's home directory starting with `~/`.
+#import:
+# - /path/to/alacritty.yml
+
+# Any items in the `env` entry below will be added as
+# environment variables. Some entries may override variables
+# set by alacritty itself.
+env:
+ # TERM variable
+ #
+ # This value is used to set the `$TERM` environment variable for
+ # each instance of Alacritty. If it is not present, alacritty will
+ # check the local terminfo database and use `alacritty` if it is
+ # available, otherwise `xterm-256color` is used.
+ TERM: xterm-256color
+
+window:
+ # Window dimensions (changes require restart)
+ #
+ # Number of lines/columns (not pixels) in the terminal. The number of columns
+ # must be at least `2`, while using a value of `0` for columns and lines will
+ # fall back to the window manager's recommended size.
+ #dimensions:
+ # columns: 0
+ # lines: 0
+
+ # Window position (changes require restart)
+ #
+ # Specified in number of pixels.
+ # If the position is not set, the window manager will handle the placement.
+ #position:
+ # x: 0
+ # y: 0
+
+ # Window padding (changes require restart)
+ #
+ # Blank space added around the window in pixels. This padding is scaled
+ # by DPI and the specified value is always added at both opposing sides.
+ #padding:
+ # x: 0
+ # y: 0
+
+ # Spread additional padding evenly around the terminal content.
+ #dynamic_padding: false
+
+ # Window decorations
+ #
+ # Values for `decorations`:
+ # - full: Borders and title bar
+ # - none: Neither borders nor title bar
+ #
+ # Values for `decorations` (macOS only):
+ # - transparent: Title bar, transparent background and title bar buttons
+ # - buttonless: Title bar, transparent background and no title bar buttons
+ #decorations: full
+
+ # Startup Mode (changes require restart)
+ #
+ # Values for `startup_mode`:
+ # - Windowed
+ # - Maximized
+ # - Fullscreen
+ #
+ # Values for `startup_mode` (macOS only):
+ # - SimpleFullscreen
+ #startup_mode: Windowed
+
+ # Window title
+ #title: Alacritty
+
+ # Allow terminal applications to change Alacritty's window title.
+ #dynamic_title: true
+
+ # Window class (Linux/BSD only):
+ #class:
+ # Application instance name
+ #instance: Alacritty
+ # General application class
+ #general: Alacritty
+
+ # GTK theme variant (Linux/BSD only)
+ #
+ # Override the variant of the GTK theme. Commonly supported values are `dark`
+ # and `light`. Set this to `None` to use the default theme variant.
+ #gtk_theme_variant: None
+
+ # Background opacity
+ #
+ opacity: 0.8
+
+scrolling:
+ # Maximum number of lines in the scrollback buffer.
+ # Specifying '0' will disable scrolling.
+ history: 10000
+
+ # Scrolling distance multiplier.
+ multiplier: 3
+
+# Font configuration
+font:
+ # Normal (roman) font face
+ normal:
+ # Font family
+ #
+ # Default:
+ # - (macOS) Menlo
+ # - (Linux/BSD) monospace
+ # - (Windows) Consolas
+ family: mononoki Nerd Font Mono
+
+ # The `style` can be specified to pick a specific face.
+ style: Regular
+
+ # Bold font face
+ bold:
+ # Font family
+ #
+ # If the bold family is not specified, it will fall back to the
+ # value specified for the normal font.
+ family: mononoki Nerd Font Mono
+
+ # The `style` can be specified to pick a specific face.
+ style: Bold
+
+ # Italic font face
+ italic:
+ # Font family
+ #
+ # If the italic family is not specified, it will fall back to the
+ # value specified for the normal font.
+ family: mononoki Nerd Font Mono
+
+ # The `style` can be specified to pick a specific face.
+ style: Italic
+
+ # Bold italic font face
+ bold_italic:
+ # Font family
+ #
+ # If the bold italic family is not specified, it will fall back to the
+ # value specified for the normal font.
+ family: mononoki Nerd Font Mono
+
+ # The `style` can be specified to pick a specific face.
+ style: Bold Italic
+
+ # Point size
+ size: 11.0
+
+ # Offset is the extra space around each character. `offset.y` can be thought
+ # of as modifying the line spacing, and `offset.x` as modifying the letter
+ # spacing.
+ #offset:
+ # x: 0
+ # y: 0
+
+ # Glyph offset determines the locations of the glyphs within their cells with
+ # the default being at the bottom. Increasing `x` moves the glyph to the
+ # right, increasing `y` moves the glyph upward.
+ #glyph_offset:
+ # x: 0
+ # y: 0
+
+ # Thin stroke font rendering (macOS only)
+ #
+ # Thin strokes are suitable for retina displays, but for non-retina screens
+ # it is recommended to set `use_thin_strokes` to `false`.
+ #use_thin_strokes: true
+
+# If `true`, bold text is drawn using the bright color variants.
+draw_bold_text_with_bright_colors: true
+
+# Colors (ZachIR)
+colors:
+ # Default colors
+ primary:
+ background: '#000000'
+ foreground: '#c5c8c6'
+
+ # Bright and dim foreground colors
+ #
+ # The dimmed foreground color is calculated automatically if it is not
+ # present. If the bright foreground color is not set, or
+ # `draw_bold_text_with_bright_colors` is `false`, the normal foreground
+ # color will be used.
+ dim_foreground: '#828482'
+ bright_foreground: '#eaeaea'
+
+ # Cursor colors
+ #
+ # Colors which should be used to draw the terminal cursor.
+ #
+ # Allowed values are CellForeground/CellBackground, which reference the
+ # affected cell, or hexadecimal colors like #ff00ff.
+ cursor:
+ text: CellBackground
+ cursor: CellForeground
+
+ # Vi mode cursor colors
+ #
+ # Colors for the cursor when the vi mode is active.
+ #
+ # Allowed values are CellForeground/CellBackground, which reference the
+ # affected cell, or hexadecimal colors like #ff00ff.
+ vi_mode_cursor:
+ text: CellBackground
+ cursor: CellForeground
+
+ # Search colors
+ #
+ # Colors used for the search bar and match highlighting.
+ search:
+ # Allowed values are CellForeground/CellBackground, which reference the
+ # affected cell, or hexadecimal colors like #ff00ff.
+ matches:
+ foreground: '#000000'
+ background: '#ffffff'
+ focused_match:
+ foreground: '#ffffff'
+ background: '#000000'
+
+ bar:
+ background: '#c5c8c6'
+ foreground: '#1d1f21'
+
+ # Keyboard regex hints
+ hints:
+ # First character in the hint label
+ #
+ # Allowed values are CellForeground/CellBackground, which reference the
+ # affected cell, or hexadecimal colors like #ff00ff.
+ start:
+ foreground: '#1d1f21'
+ background: '#e9ff5e'
+
+ # All characters after the first one in the hint label
+ #
+ # Allowed values are CellForeground/CellBackground, which reference the
+ # affected cell, or hexadecimal colors like #ff00ff.
+ end:
+ foreground: '#e9ff5e'
+ background: '#1d1f21'
+
+ # Line indicator
+ #
+ # Color used for the indicator displaying the position in history during
+ # search and vi mode.
+ #
+ # By default, these will use the opposing primary color.
+ line_indicator:
+ foreground: None
+ background: None
+
+ # Selection colors
+ #
+ # Colors which should be used to draw the selection area.
+ #
+ # Allowed values are CellForeground/CellBackground, which reference the
+ # affected cell, or hexadecimal colors like #ff00ff.
+ selection:
+ text: CellBackground
+ background: CellForeground
+
+ # Normal colors
+ normal:
+ black: '#1d1f21'
+ red: '#89231d'
+ green: '#146e37'
+ yellow: '#ae7518'
+ blue: '#2b55b2'
+ magenta: '#784e93'
+ cyan: '#2783a1'
+ white: '#b4b7b5'
+
+ # Bright colors
+ bright:
+ black: '#969896'
+ red: '#cc342b'
+ green: '#198844'
+ yellow: '#fba922'
+ blue: '#3971ed'
+ magenta: '#a36ac7'
+ cyan: '#39c1ed'
+ white: '#ffffff'
+
+ # Dim colors
+ #
+ # If the dim colors are not set, they will be calculated automatically based
+ # on the `normal` colors.
+ #dim:
+ # black: '#131415'
+ # red: '#864343'
+ # green: '#777c44'
+ # yellow: '#9e824c'
+ # blue: '#556a7d'
+ # magenta: '#75617b'
+ # cyan: '#5b7d78'
+ # white: '#828482'
+
+ # Indexed Colors
+ #
+ # The indexed colors include all colors from 16 to 256.
+ # When these are not set, they're filled with sensible defaults.
+ #
+ # Example:
+ # `- { index: 16, color: '#ff00ff' }`
+ #
+ #indexed_colors: []
+
+# Bell
+#
+# The bell is rung every time the BEL control character is received.
+bell:
+ # Visual Bell Animation
+ #
+ # Animation effect for flashing the screen when the visual bell is rung.
+ #
+ # Values for `animation`:
+ # - Ease
+ # - EaseOut
+ # - EaseOutSine
+ # - EaseOutQuad
+ # - EaseOutCubic
+ # - EaseOutQuart
+ # - EaseOutQuint
+ # - EaseOutExpo
+ # - EaseOutCirc
+ # - Linear
+ #animation: EaseOutExpo
+
+ # Duration of the visual bell flash in milliseconds. A `duration` of `0` will
+ # disable the visual bell animation.
+ duration: 0
+
+ # Visual bell animation color.
+ #color: '#ffffff'
+
+ # Bell Command
+ #
+ # This program is executed whenever the bell is rung.
+ #
+ # When set to `command: None`, no command will be executed.
+ #
+ # Example:
+ # command:
+ # program: notify-send
+ # args: ["Hello, World!"]
+ #
+ #command: None
+
+#selection:
+ # This string contains all characters that are used as separators for
+ # "semantic words" in Alacritty.
+ #semantic_escape_chars: ",│`|:\"' ()[]{}<>\t"
+
+ # When set to `true`, selected text will be copied to the primary clipboard.
+ #save_to_clipboard: false
+
+cursor:
+ # Cursor style
+ style:
+ # Cursor shape
+ #
+ # Values for `shape`:
+ # - ▇ Block
+ # - _ Underline
+ # - | Beam
+ shape: Block
+
+ # Cursor blinking state
+ #
+ # Values for `blinking`:
+ # - Never: Prevent the cursor from ever blinking
+ # - Off: Disable blinking by default
+ # - On: Enable blinking by default
+ # - Always: Force the cursor to always blink
+ blinking: Off
+
+ # Vi mode cursor style
+ #
+ # If the vi mode cursor style is `None` or not specified, it will fall back to
+ # the style of the active value of the normal cursor.
+ #
+ # See `cursor.style` for available options.
+ #vi_mode_style: None
+
+ # Cursor blinking interval in milliseconds.
+ #blink_interval: 750
+
+ # If this is `true`, the cursor will be rendered as a hollow box when the
+ # window is not focused.
+ #unfocused_hollow: true
+
+ # Thickness of the cursor relative to the cell width as floating point number
+ # from `0.0` to `1.0`.
+ #thickness: 0.15
+
+# Live config reload (changes require restart)
+#live_config_reload: true
+
+# Shell
+#
+# You can set `shell.program` to the path of your favorite shell, e.g.
+# `/bin/fish`. Entries in `shell.args` are passed unmodified as arguments to the
+# shell.
+#
+# Default:
+# - (macOS) /bin/bash --login
+# - (Linux/BSD) user login shell
+# - (Windows) powershell
+# shell:
+ # program: /bin/ksh
+ #args:
+ # - --login
+
+# Startup directory
+#
+# Directory the shell is started in. If this is unset, or `None`, the working
+# directory of the parent process will be used.
+#working_directory: None
+
+# Send ESC (\x1b) before characters when alt is pressed.
+#alt_send_esc: true
+
+#mouse:
+ # Click settings
+ #
+ # The `double_click` and `triple_click` settings control the time
+ # alacritty should wait for accepting multiple clicks as one double
+ # or triple click.
+ #double_click: { threshold: 300 }
+ #triple_click: { threshold: 300 }
+
+ # If this is `true`, the cursor is temporarily hidden when typing.
+ #hide_when_typing: false
+
+# Regex hints
+#
+# Terminal hints can be used to find text in the visible part of the terminal
+# and pipe it to other applications.
+#hints:
+ # Keys used for the hint labels.
+ #alphabet: "jfkdls;ahgurieowpq"
+
+ # List with all available hints
+ #
+ # Each hint must have a `regex` and either an `action` or a `command` field.
+ # The fields `mouse`, `binding` and `post_processing` are optional.
+ #
+ # The fields `command`, `binding.key`, `binding.mods` and `mouse.mods` accept
+ # the same values as they do in the `key_bindings` section.
+ #
+ # The `mouse.enabled` field controls if the hint should be underlined while
+ # the mouse with all `mouse.mods` keys held or the vi mode cursor is above it.
+ #
+ # If the `post_processing` field is set to `true`, heuristics will be used to
+ # shorten the match if there are characters likely not to be part of the hint
+ # (e.g. a trailing `.`). This is most useful for URIs.
+ #
+ # Values for `action`:
+ # - Copy
+ # Copy the hint's text to the clipboard.
+ # - Paste
+ # Paste the hint's text to the terminal or search.
+ # - Select
+ # Select the hint's text.
+ # - MoveViModeCursor
+ # Move the vi mode cursor to the beginning of the hint.
+ #enabled:
+ # - regex: "(ipfs:|ipns:|magnet:|mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)\
+ # [^\u0000-\u001F\u007F-\u009F<>\"\\s{-}\\^⟨⟩`]+"
+ # command: xdg-open
+ # post_processing: true
+ # mouse:
+ # enabled: true
+ # mods: None
+ # binding:
+ # key: U
+ # mods: Control|Shift
+
+# Mouse bindings
+#
+# Mouse bindings are specified as a list of objects, much like the key
+# bindings further below.
+#
+# To trigger mouse bindings when an application running within Alacritty
+# captures the mouse, the `Shift` modifier is automatically added as a
+# requirement.
+#
+# Each mouse binding will specify a:
+#
+# - `mouse`:
+#
+# - Middle
+# - Left
+# - Right
+# - Numeric identifier such as `5`
+#
+# - `action` (see key bindings)
+#
+# And optionally:
+#
+# - `mods` (see key bindings)
+#mouse_bindings:
+# - { mouse: Middle, action: PasteSelection }
+
+# Key bindings
+#
+# Key bindings are specified as a list of objects. For example, this is the
+# default paste binding:
+#
+# `- { key: V, mods: Control|Shift, action: Paste }`
+#
+# Each key binding will specify a:
+#
+# - `key`: Identifier of the key pressed
+#
+# - A-Z
+# - F1-F24
+# - Key0-Key9
+#
+# A full list with available key codes can be found here:
+# https://docs.rs/glutin/*/glutin/event/enum.VirtualKeyCode.html#variants
+#
+# Instead of using the name of the keys, the `key` field also supports using
+# the scancode of the desired key. Scancodes have to be specified as a
+# decimal number. This command will allow you to display the hex scancodes
+# for certain keys:
+#
+# `showkey --scancodes`.
+#
+# Then exactly one of:
+#
+# - `chars`: Send a byte sequence to the running application
+#
+# The `chars` field writes the specified string to the terminal. This makes
+# it possible to pass escape sequences. To find escape codes for bindings
+# like `PageUp` (`"\x1b[5~"`), you can run the command `showkey -a` outside
+# of tmux. Note that applications use terminfo to map escape sequences back
+# to keys. It is therefore required to update the terminfo when changing an
+# escape sequence.
+#
+# - `action`: Execute a predefined action
+#
+# - ToggleViMode
+# - SearchForward
+# Start searching toward the right of the search origin.
+# - SearchBackward
+# Start searching toward the left of the search origin.
+# - Copy
+# - Paste
+# - IncreaseFontSize
+# - DecreaseFontSize
+# - ResetFontSize
+# - ScrollPageUp
+# - ScrollPageDown
+# - ScrollHalfPageUp
+# - ScrollHalfPageDown
+# - ScrollLineUp
+# - ScrollLineDown
+# - ScrollToTop
+# - ScrollToBottom
+# - ClearHistory
+# Remove the terminal's scrollback history.
+# - Hide
+# Hide the Alacritty window.
+# - Minimize
+# Minimize the Alacritty window.
+# - Quit
+# Quit Alacritty.
+# - ToggleFullscreen
+# - SpawnNewInstance
+# Spawn a new instance of Alacritty.
+# - ClearLogNotice
+# Clear Alacritty's UI warning and error notice.
+# - ClearSelection
+# Remove the active selection.
+# - ReceiveChar
+# - None
+#
+# - Vi mode exclusive actions:
+#
+# - Open
+# Perform the action of the first matching hint under the vi mode cursor
+# with `mouse.enabled` set to `true`.
+# - ToggleNormalSelection
+# - ToggleLineSelection
+# - ToggleBlockSelection
+# - ToggleSemanticSelection
+# Toggle semantic selection based on `selection.semantic_escape_chars`.
+#
+# - Vi mode exclusive cursor motion actions:
+#
+# - Up
+# One line up.
+# - Down
+# One line down.
+# - Left
+# One character left.
+# - Right
+# One character right.
+# - First
+# First column, or beginning of the line when already at the first column.
+# - Last
+# Last column, or beginning of the line when already at the last column.
+# - FirstOccupied
+# First non-empty cell in this terminal row, or first non-empty cell of
+# the line when already at the first cell of the row.
+# - High
+# Top of the screen.
+# - Middle
+# Center of the screen.
+# - Low
+# Bottom of the screen.
+# - SemanticLeft
+# Start of the previous semantically separated word.
+# - SemanticRight
+# Start of the next semantically separated word.
+# - SemanticLeftEnd
+# End of the previous semantically separated word.
+# - SemanticRightEnd
+# End of the next semantically separated word.
+# - WordLeft
+# Start of the previous whitespace separated word.
+# - WordRight
+# Start of the next whitespace separated word.
+# - WordLeftEnd
+# End of the previous whitespace separated word.
+# - WordRightEnd
+# End of the next whitespace separated word.
+# - Bracket
+# Character matching the bracket at the cursor's location.
+# - SearchNext
+# Beginning of the next match.
+# - SearchPrevious
+# Beginning of the previous match.
+# - SearchStart
+# Start of the match to the left of the vi mode cursor.
+# - SearchEnd
+# End of the match to the right of the vi mode cursor.
+#
+# - Search mode exclusive actions:
+# - SearchFocusNext
+# Move the focus to the next search match.
+# - SearchFocusPrevious
+# Move the focus to the previous search match.
+# - SearchConfirm
+# - SearchCancel
+# - SearchClear
+# Reset the search regex.
+# - SearchDeleteWord
+# Delete the last word in the search regex.
+# - SearchHistoryPrevious
+# Go to the previous regex in the search history.
+# - SearchHistoryNext
+# Go to the next regex in the search history.
+#
+# - macOS exclusive actions:
+# - ToggleSimpleFullscreen
+# Enter fullscreen without occupying another space.
+#
+# - Linux/BSD exclusive actions:
+#
+# - CopySelection
+# Copy from the selection buffer.
+# - PasteSelection
+# Paste from the selection buffer.
+#
+# - `command`: Fork and execute a specified command plus arguments
+#
+# The `command` field must be a map containing a `program` string and an
+# `args` array of command line parameter strings. For example:
+# `{ program: "alacritty", args: ["-e", "vttest"] }`
+#
+# And optionally:
+#
+# - `mods`: Key modifiers to filter binding actions
+#
+# - Command
+# - Control
+# - Option
+# - Super
+# - Shift
+# - Alt
+#
+# Multiple `mods` can be combined using `|` like this:
+# `mods: Control|Shift`.
+# Whitespace and capitalization are relevant and must match the example.
+#
+# - `mode`: Indicate a binding for only specific terminal reported modes
+#
+# This is mainly used to send applications the correct escape sequences
+# when in different modes.
+#
+# - AppCursor
+# - AppKeypad
+# - Search
+# - Alt
+# - Vi
+#
+# A `~` operator can be used before a mode to apply the binding whenever
+# the mode is *not* active, e.g. `~Alt`.
+#
+# Bindings are always filled by default, but will be replaced when a new
+# binding with the same triggers is defined. To unset a default binding, it can
+# be mapped to the `ReceiveChar` action. Alternatively, you can use `None` for
+# a no-op if you do not wish to receive input characters for that binding.
+#
+# If the same trigger is assigned to multiple actions, all of them are executed
+# in the order they were defined in.
+#key_bindings:
+ #- { key: Paste, action: Paste }
+ #- { key: Copy, action: Copy }
+ #- { key: L, mods: Control, action: ClearLogNotice }
+ #- { key: L, mods: Control, mode: ~Vi|~Search, chars: "\x0c" }
+ #- { key: PageUp, mods: Shift, mode: ~Alt, action: ScrollPageUp, }
+ #- { key: PageDown, mods: Shift, mode: ~Alt, action: ScrollPageDown }
+ #- { key: Home, mods: Shift, mode: ~Alt, action: ScrollToTop, }
+ #- { key: End, mods: Shift, mode: ~Alt, action: ScrollToBottom }
+
+ # Vi Mode
+ #- { key: Space, mods: Shift|Control, mode: Vi|~Search, action: ScrollToBottom }
+ #- { key: Space, mods: Shift|Control, mode: ~Search, action: ToggleViMode }
+ #- { key: Escape, mode: Vi|~Search, action: ClearSelection }
+ #- { key: I, mode: Vi|~Search, action: ScrollToBottom }
+ #- { key: I, mode: Vi|~Search, action: ToggleViMode }
+ #- { key: C, mods: Control, mode: Vi|~Search, action: ToggleViMode }
+ #- { key: Y, mods: Control, mode: Vi|~Search, action: ScrollLineUp }
+ #- { key: E, mods: Control, mode: Vi|~Search, action: ScrollLineDown }
+ #- { key: G, mode: Vi|~Search, action: ScrollToTop }
+ #- { key: G, mods: Shift, mode: Vi|~Search, action: ScrollToBottom }
+ #- { key: B, mods: Control, mode: Vi|~Search, action: ScrollPageUp }
+ #- { key: F, mods: Control, mode: Vi|~Search, action: ScrollPageDown }
+ #- { key: U, mods: Control, mode: Vi|~Search, action: ScrollHalfPageUp }
+ #- { key: D, mods: Control, mode: Vi|~Search, action: ScrollHalfPageDown }
+ #- { key: Y, mode: Vi|~Search, action: Copy }
+ #- { key: Y, mode: Vi|~Search, action: ClearSelection }
+ #- { key: Copy, mode: Vi|~Search, action: ClearSelection }
+ #- { key: V, mode: Vi|~Search, action: ToggleNormalSelection }
+ #- { key: V, mods: Shift, mode: Vi|~Search, action: ToggleLineSelection }
+ #- { key: V, mods: Control, mode: Vi|~Search, action: ToggleBlockSelection }
+ #- { key: V, mods: Alt, mode: Vi|~Search, action: ToggleSemanticSelection }
+ #- { key: Return, mode: Vi|~Search, action: Open }
+ #- { key: K, mode: Vi|~Search, action: Up }
+ #- { key: J, mode: Vi|~Search, action: Down }
+ #- { key: H, mode: Vi|~Search, action: Left }
+ #- { key: L, mode: Vi|~Search, action: Right }
+ #- { key: Up, mode: Vi|~Search, action: Up }
+ #- { key: Down, mode: Vi|~Search, action: Down }
+ #- { key: Left, mode: Vi|~Search, action: Left }
+ #- { key: Right, mode: Vi|~Search, action: Right }
+ #- { key: Key0, mode: Vi|~Search, action: First }
+ #- { key: Key4, mods: Shift, mode: Vi|~Search, action: Last }
+ #- { key: Key6, mods: Shift, mode: Vi|~Search, action: FirstOccupied }
+ #- { key: H, mods: Shift, mode: Vi|~Search, action: High }
+ #- { key: M, mods: Shift, mode: Vi|~Search, action: Middle }
+ #- { key: L, mods: Shift, mode: Vi|~Search, action: Low }
+ #- { key: B, mode: Vi|~Search, action: SemanticLeft }
+ #- { key: W, mode: Vi|~Search, action: SemanticRight }
+ #- { key: E, mode: Vi|~Search, action: SemanticRightEnd }
+ #- { key: B, mods: Shift, mode: Vi|~Search, action: WordLeft }
+ #- { key: W, mods: Shift, mode: Vi|~Search, action: WordRight }
+ #- { key: E, mods: Shift, mode: Vi|~Search, action: WordRightEnd }
+ #- { key: Key5, mods: Shift, mode: Vi|~Search, action: Bracket }
+ #- { key: Slash, mode: Vi|~Search, action: SearchForward }
+ #- { key: Slash, mods: Shift, mode: Vi|~Search, action: SearchBackward }
+ #- { key: N, mode: Vi|~Search, action: SearchNext }
+ #- { key: N, mods: Shift, mode: Vi|~Search, action: SearchPrevious }
+
+ # Search Mode
+ #- { key: Return, mode: Search|Vi, action: SearchConfirm }
+ #- { key: Escape, mode: Search, action: SearchCancel }
+ #- { key: C, mods: Control, mode: Search, action: SearchCancel }
+ #- { key: U, mods: Control, mode: Search, action: SearchClear }
+ #- { key: W, mods: Control, mode: Search, action: SearchDeleteWord }
+ #- { key: P, mods: Control, mode: Search, action: SearchHistoryPrevious }
+ #- { key: N, mods: Control, mode: Search, action: SearchHistoryNext }
+ #- { key: Up, mode: Search, action: SearchHistoryPrevious }
+ #- { key: Down, mode: Search, action: SearchHistoryNext }
+ #- { key: Return, mode: Search|~Vi, action: SearchFocusNext }
+ #- { key: Return, mods: Shift, mode: Search|~Vi, action: SearchFocusPrevious }
+
+ # (Windows, Linux, and BSD only)
+ #- { key: V, mods: Control|Shift, mode: ~Vi, action: Paste }
+ #- { key: C, mods: Control|Shift, action: Copy }
+ #- { key: F, mods: Control|Shift, mode: ~Search, action: SearchForward }
+ #- { key: B, mods: Control|Shift, mode: ~Search, action: SearchBackward }
+ #- { key: C, mods: Control|Shift, mode: Vi|~Search, action: ClearSelection }
+ #- { key: Insert, mods: Shift, action: PasteSelection }
+ #- { key: Key0, mods: Control, action: ResetFontSize }
+ #- { key: Equals, mods: Control, action: IncreaseFontSize }
+ #- { key: Plus, mods: Control, action: IncreaseFontSize }
+ #- { key: NumpadAdd, mods: Control, action: IncreaseFontSize }
+ #- { key: Minus, mods: Control, action: DecreaseFontSize }
+ #- { key: NumpadSubtract, mods: Control, action: DecreaseFontSize }
+
+ # (Windows only)
+ #- { key: Return, mods: Alt, action: ToggleFullscreen }
+
+ # (macOS only)
+ #- { key: K, mods: Command, mode: ~Vi|~Search, chars: "\x0c" }
+ #- { key: K, mods: Command, mode: ~Vi|~Search, action: ClearHistory }
+ #- { key: Key0, mods: Command, action: ResetFontSize }
+ #- { key: Equals, mods: Command, action: IncreaseFontSize }
+ #- { key: Plus, mods: Command, action: IncreaseFontSize }
+ #- { key: NumpadAdd, mods: Command, action: IncreaseFontSize }
+ #- { key: Minus, mods: Command, action: DecreaseFontSize }
+ #- { key: NumpadSubtract, mods: Command, action: DecreaseFontSize }
+ #- { key: V, mods: Command, action: Paste }
+ #- { key: C, mods: Command, action: Copy }
+ #- { key: C, mods: Command, mode: Vi|~Search, action: ClearSelection }
+ #- { key: H, mods: Command, action: Hide }
+ #- { key: H, mods: Command|Alt, action: HideOtherApplications }
+ #- { key: M, mods: Command, action: Minimize }
+ #- { key: Q, mods: Command, action: Quit }
+ #- { key: W, mods: Command, action: Quit }
+ #- { key: N, mods: Command, action: SpawnNewInstance }
+ #- { key: F, mods: Command|Control, action: ToggleFullscreen }
+ #- { key: F, mods: Command, mode: ~Search, action: SearchForward }
+ #- { key: B, mods: Command, mode: ~Search, action: SearchBackward }
+
+#debug:
+ # Display the time it takes to redraw each frame.
+ #render_timer: false
+
+ # Keep the log file after quitting Alacritty.
+ #persistent_logging: false
+
+ # Log level
+ #
+ # Values for `log_level`:
+ # - Off
+ # - Error
+ # - Warn
+ # - Info
+ # - Debug
+ # - Trace
+ #log_level: Warn
+
+ # Print all received window events.
+ #print_events: false
diff --git a/autostart.sh b/autostart.sh
new file mode 100755
index 0000000..bb5e986
--- /dev/null
+++ b/autostart.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+runifnot () {
+ if type $1 >/dev/null; then
+ echo $1
+ if [ -z "$(pgrep -f $1)" ]; then
+ $@ &
+ fi
+ fi
+}
+
+runifnot `crcparse snd`
+if type mpd >/dev/null; then
+ runifnot mpd
+elif type musicpd >/dev/null; then
+ runifnot musicpd
+fi
+runifnot mpd-mpris -network unix
+runifnot mpd-notification
+runifnot transmission-daemon
+#runifnot dbus-daemon --session --address=unix:path=$XDG_RUNTIME_DIR/bus
+runifnot openrazer-daemon
+runifnot lxqt-policykit-agent
+razer-cli -e static &
+#runifnot nextcloud
+if [ -z "$WAYLAND_DISPLAY" ]; then
+ runifnot xss-lock -n notify-send slockd
+ #if pgrep -x swhkd; then
+ # doas killall swhkd && pkexec swhkd
+ #fi
+ #pkexec swhkd &
+ #runifnot swhks
+ runifnot sxhkd
+ runifnot dunst
+ runifnot caffeine-ng
+ if [ "$(crcparse WM)" = "$(which xmonad)" ]; then
+ runifnot stalonetray
+ fi
+ xwallpaper --zoom ~/background.jpg
+ setxkbmap -option "caps:escape"
+else
+ toggle swaybg -i ~/background.jpg
+ gsettings set org.gnome.desktop.interface gtk-theme Sweet-Dark-v40
+ gsettings set org.gnome.desktop.interface icon-theme Paper-Mono-Dark
+ runifnot swayidle -w
+ hotkeys.sh
+ runifnot mako
+ if [ "$(crcparse WC)" != "$(which qtile)" ]; then
+ runifnot waybar
+ fi
+fi
diff --git a/awesome b/awesome
new file mode 160000
+Subproject 98e36e5087a8855bf758c95d9e90d6feae15a61
diff --git a/bspwm/bspwmrc b/bspwm/bspwmrc
new file mode 100755
index 0000000..5799efb
--- /dev/null
+++ b/bspwm/bspwmrc
@@ -0,0 +1,66 @@
+#! /bin/sh
+sxhkd -c ~/.config/sxhkd/sxhkdrc.1 &
+launch_polybar.sh 'bspwm' &
+pgrep -fl 'pidswallow -gl' || pidswallow -gl
+~/.config/autostart.sh
+
+set_desktops () {
+ case "$1" in
+ "2")
+ bspc monitor "$2" -d I II III IV V
+ bspc monitor "$3" -d VI VII VIII IX X
+ ;;
+ "3")
+ bspc monitor "$2" -d I II III
+ bspc monitor "$3" -d IV V VI VIII
+ bspc monitor "$4" -d VIII IX X
+ ;;
+ "4")
+ bspc monitor "$2" -d I II III
+ bspc monitor "$3" -d IV V
+ bspc monitor "$4" -d VI VII
+ bspc monitor "$5" -d VIII IX X
+ ;;
+ "5")
+ bspc monitor "$2" -d I II
+ bspc monitor "$3" -d III IV
+ bspc monitor "$4" -d V VI
+ bspc monitor "$5" -d VII VIII
+ bspc monitor "$6" -d IX X
+ esac
+}
+
+MONITORS=`xrandr | awk '/ connected/ && /[[:digit:]]x[[:digit:]].*+/{print $1}'`
+MONITOR_COUNT=`echo "$MONITORS" | wc -l`
+if [ "$MONITOR_COUNT" -lt 2 ]; then
+ bspc monitor -d I II III IV V VI VII VIII IX X
+else
+ set_desktops "$MONITOR_COUNT" `echo "$MONITORS" | sed 's/\n/ /g'`
+fi
+
+bspc config border_width 2
+bspc config window_gap 10
+bspc config top_padding 27
+
+bspc config split_ratio 0.50
+bspc config borderless_monocle true
+bspc config gapless_monocle true
+
+bspc config focus_follows_pointer true
+
+bspc rule -a Thunderbird:\* desktop=X
+bspc rule -a Nextcloud:nextcloud state=tiled
+bspc rule -a Surf:surf state=tiled
+bspc rule -a QjackCtl:qjackctl state=floating
+bspc rule -a Ardour-5.12.0:ardour-5.12.0 state=floating
+
+bspc rule -a sphtop sticky=on state=floating
+bspc rule -a spterm sticky=on state=floating
+bspc rule -a sppmxr sticky=on state=floating
+bspc rule -a spblue sticky=on state=floating
+bspc rule -a spncmp sticky=on state=floating
+bspc rule -a spmutt sticky=on state=floating
+bspc rule -a spprof sticky=on state=floating
+bspc rule -a spircc sticky=on state=floating
+bspc rule -a sptodo sticky=on state=floating
+bspc rule -a sptrem sticky=on state=floating
diff --git a/bspwm/noswallow b/bspwm/noswallow
new file mode 100644
index 0000000..b75624e
--- /dev/null
+++ b/bspwm/noswallow
@@ -0,0 +1 @@
+REAPER
diff --git a/bspwm/terminals b/bspwm/terminals
new file mode 100644
index 0000000..974a8d3
--- /dev/null
+++ b/bspwm/terminals
@@ -0,0 +1,3 @@
+tabbed
+st
+"tabbed"
diff --git a/caffeine/audio_blacklist.txt b/caffeine/audio_blacklist.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/caffeine/audio_blacklist.txt
diff --git a/caffeine/whitelist.txt b/caffeine/whitelist.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/caffeine/whitelist.txt
diff --git a/computerrc.txt b/computerrc.txt
new file mode 100644
index 0000000..3f3209b
--- /dev/null
+++ b/computerrc.txt
@@ -0,0 +1,10 @@
+The following fields are expected in computerrc:
+
+inet: internet interface i.e. eth0, trunk0, em0
+OS: base operating system/kernel i.e. Linux, OpenBSD, FreeBSD
+WM: default x11 window manager command i.e. awesome, qtile start
+WC: default wayland compositor command i.e. river, qtile start --backend wayland
+snd: sound server to launch automatically i.e. pipewire, pulseaudio, sndio, oss
+batt: if there is a battery or not i.e. y or n
+wayland: if boot into wayland or not i.e. y or n
+tsname: touchscreen xorg device i.e. device from xinput
diff --git a/cool-retro-term/cool-retro-term.conf b/cool-retro-term/cool-retro-term.conf
new file mode 100644
index 0000000..d190d88
--- /dev/null
+++ b/cool-retro-term/cool-retro-term.conf
@@ -0,0 +1,7 @@
+[QQControlsFileDialog]
+favoriteFolders=@Invalid()
+height=0
+sidebarSplit=118.575
+sidebarVisible=true
+sidebarWidth=80
+width=0
diff --git a/deadbeef/config b/deadbeef/config
new file mode 100644
index 0000000..16ff3ae
--- /dev/null
+++ b/deadbeef/config
@@ -0,0 +1,79 @@
+artwork.filemask *cover*.jpg;*front*.jpg;*folder*.jpg;*cover*.png;*front*.png;*folder*.png
+cli_add_playlist_name Default
+cli_add_to_specific_playlist 1
+close_send_to_tray 1
+deadbeef_version 0.7.2
+filechooser.lastdir file:///home/zachir/Music/Starset/VESSELS
+gtkui.columns.playlist [{"title":"♫","id":"1","format":"%playstatus%","size":"50","align":"0","color_override":"0","color":"#ff000000"},{"title":"Artist / Album","id":"-1","format":"%artist% - %album%","size":"161","align":"0","color_override":"0","color":"#ff000000"},{"title":"Track No","id":"-1","format":"%tracknumber%","size":"50","align":"1","color_override":"0","color":"#ff000000"},{"title":"Title","id":"-1","format":"%title%","size":"160","align":"0","color_override":"0","color":"#ff000000"},{"title":"Duration","id":"-1","format":"%length%","size":"50","align":"0","color_override":"0","color":"#ff000000"}]
+gtkui.layout.0.6.2 vbox expand="0 1" fill="1 1" homogeneous=0 {hbox expand="0 1 0" fill="1 1 1" homogeneous=0 {playtb {} seekbar {} volumebar {} } hsplitter pos=481 locked=0 {tabbed_playlist hideheaders=0 width=481 {} vsplitter pos=234 locked=0 {spectrum {} coverart {} } } }
+gtkui.mmb_delete_playlist 1
+gtkui.name_playlist_from_folder 1
+gtkui.statusbar.visible 1
+gtkui.tabscroll 0
+gtkui.titlebar_playing_tf %artist% - %title% - DeaDBeeF-%_deadbeef_version%
+gtkui.titlebar_stopped_tf DeaDBeeF-%_deadbeef_version%
+hotkey.key01 "Ctrl f" 0 0 find
+hotkey.key02 "Ctrl o" 0 0 open_files
+hotkey.key03 "Ctrl q" 0 0 quit
+hotkey.key04 "Ctrl n" 0 0 new_playlist
+hotkey.key05 "Ctrl a" 0 0 select_all
+hotkey.key06 "Escape" 0 0 deselect_all
+hotkey.key07 "Ctrl m" 0 0 toggle_stop_after_current
+hotkey.key08 "Ctrl j" 0 0 jump_to_current_track
+hotkey.key09 "F1" 0 0 help
+hotkey.key10 "Delete" 1 0 remove_from_playlist
+hotkey.key11 "Ctrl w" 0 0 remove_current_playlist
+hotkey.key14 "Return" 0 0 play
+hotkey.key15 "Ctrl p" 0 0 toggle_pause
+hotkey.key16 "Alt 1" 0 0 playlist1
+hotkey.key17 "Alt 2" 0 0 playlist2
+hotkey.key18 "Alt 3" 0 0 playlist3
+hotkey.key19 "Alt 4" 0 0 playlist4
+hotkey.key20 "Alt 5" 0 0 playlist5
+hotkey.key21 "Alt 6" 0 0 playlist6
+hotkey.key22 "Alt 7" 0 0 playlist7
+hotkey.key23 "Alt 8" 0 0 playlist8
+hotkey.key24 "Alt 9" 0 0 playlist9
+hotkey.key25 "Alt 0" 0 0 playlist10
+hotkey.key26 z 0 0 prev
+hotkey.key27 x 0 0 play
+hotkey.key28 c 0 0 toggle_pause
+hotkey.key29 v 0 0 stop
+hotkey.key30 b 0 0 next
+hotkey.key31 n 0 0 playback_random
+hotkey.key32 "Ctrl k" 0 0 toggle_stop_after_album
+hotkeys_created 1
+ignore_archives 1
+junk.enable_cp1251_detection 1
+mainwin.geometry.h 343
+mainwin.geometry.w 946
+mainwin.geometry.x 966
+mainwin.geometry.y 372
+network.http_user_agent deadbeef
+network.proxy.port 8080
+network.proxy.type HTTP
+playback.loop 0
+playback.order 0
+playback.volume 0.0000000
+playlist.current 2
+playlist.cursor.0 1
+playlist.cursor.1 9
+playlist.cursor.2 2
+playlist.scroll.0 0
+playlist.scroll.1 0
+playlist.scroll.2 0
+playlist.scroll.cursorfollowplayback 1
+playlist.tab.00000 Van Weezer
+playlist.tab.00001 Blue Album
+playlist.tab.00002 VESSELS
+prefwin.geometry.h 511
+prefwin.geometry.w 665
+prefwin.geometry.x 627
+prefwin.geometry.y 284
+replaygain_mode 0
+replaygain_scale 1
+resume.paused 0
+resume.playlist 2
+resume.position -1.000000
+resume.track -1
+streamer.8_to_16 1
diff --git a/deadbeef/dspconfig b/deadbeef/dspconfig
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/deadbeef/dspconfig
diff --git a/deadbeef/playlists/0.dbpl b/deadbeef/playlists/0.dbpl
new file mode 100644
index 0000000..f1fd6b4
--- /dev/null
+++ b/deadbeef/playlists/0.dbpl
Binary files differ
diff --git a/deadbeef/playlists/1.dbpl b/deadbeef/playlists/1.dbpl
new file mode 100644
index 0000000..11fc9eb
--- /dev/null
+++ b/deadbeef/playlists/1.dbpl
Binary files differ
diff --git a/deadbeef/playlists/2.dbpl b/deadbeef/playlists/2.dbpl
new file mode 100644
index 0000000..7421fa7
--- /dev/null
+++ b/deadbeef/playlists/2.dbpl
Binary files differ
diff --git a/doas.conf b/doas.conf
new file mode 100644
index 0000000..b4065ab
--- /dev/null
+++ b/doas.conf
@@ -0,0 +1,19 @@
+permit persist zachir
+permit nopass zachir cmd make args install
+permit nopass zachir cmd rsm args start libvirtd virtlockd virtlogd
+permit nopass zachir cmd rsm args stop libvirtd virtlockd virtlogd
+permit nopass zachir cmd pacman
+permit nopass zachir cmd iptables
+permit nopass zachir cmd ip6tables
+permit nopass zachir cmd mount
+permit nopass zachir cmd mount.exfat
+permit nopass zachir cmd umount
+permit nopass zachir cmd modprobe
+permit nopass zachir cmd zzz
+permit nopass zachir cmd sv
+permit nopass zachir cmd swhkd args
+permit nopass zachir cmd pkill args -HUP swhkd
+permit nopass zachir cmd killall args swhkd
+permit nopass keepenv zachir as zachir
+
+permit nopass keepenv root
diff --git a/doom/config.el b/doom/config.el
new file mode 100644
index 0000000..ccb55a5
--- /dev/null
+++ b/doom/config.el
@@ -0,0 +1,54 @@
+;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
+
+;; Place your private configuration here! Remember, you do not need to run 'doom
+;; sync' after modifying this file!
+
+
+;; Some functionality uses this to identify you, e.g. GPG configuration, email
+;; clients, file templates and snippets.
+(setq user-full-name "ZachIR"
+ user-mail-address "zachir@librem.one")
+
+;; Doom exposes five (optional) variables for controlling fonts in Doom. Here
+;; are the three important ones:
+;;
+;; + `doom-font'
+;; + `doom-variable-pitch-font'
+;; + `doom-big-font' -- used for `doom-big-font-mode'; use this for
+;; presentations or streaming.
+;;
+;; They all accept either a font-spec, font string ("Input Mono-12"), or xlfd
+;; font string. You generally only need these two:
+;; (setq doom-font (font-spec :family "monospace" :size 12 :weight 'semi-light)
+;; doom-variable-pitch-font (font-spec :family "sans" :size 13))
+
+;; There are two ways to load a theme. Both assume the theme is installed and
+;; available. You can either set `doom-theme' or manually load a theme with the
+;; `load-theme' function. This is the default:
+(setq doom-theme 'doom-one)
+
+;; If you use `org' and don't want your org files in the default location below,
+;; change `org-directory'. It must be set before org loads!
+(setq org-directory "~/org/")
+
+;; This determines the style of line numbers in effect. If set to `nil', line
+;; numbers are disabled. For relative line numbers, set this to `relative'.
+(setq display-line-numbers-type t)
+
+
+;; Here are some additional functions/macros that could help you configure Doom:
+;;
+;; - `load!' for loading external *.el files relative to this one
+;; - `use-package!' for configuring packages
+;; - `after!' for running code after a package has loaded
+;; - `add-load-path!' for adding directories to the `load-path', relative to
+;; this file. Emacs searches the `load-path' when you load packages with
+;; `require' or `use-package'.
+;; - `map!' for binding new keys
+;;
+;; To get information about any of these functions/macros, move the cursor over
+;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
+;; This will open documentation for it, including demos of how they are used.
+;;
+;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
+;; they are implemented.
diff --git a/doom/init.el b/doom/init.el
new file mode 100644
index 0000000..c4b979a
--- /dev/null
+++ b/doom/init.el
@@ -0,0 +1,183 @@
+;;; init.el -*- lexical-binding: t; -*-
+
+;; This file controls what Doom modules are enabled and what order they load
+;; in. Remember to run 'doom sync' after modifying it!
+
+;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
+;; documentation. There you'll find a "Module Index" link where you'll find
+;; a comprehensive list of Doom's modules and what flags they support.
+
+;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
+;; 'C-c c k' for non-vim users) to view its documentation. This works on
+;; flags as well (those symbols that start with a plus).
+;;
+;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
+;; directory (for easy access to its source code).
+
+(doom! :input
+ ;;chinese
+ ;;japanese
+ ;;layout ; auie,ctsrnm is the superior home row
+
+ :completion
+ company ; the ultimate code completion backend
+ ;;helm ; the *other* search engine for love and life
+ ;;ido ; the other *other* search engine...
+ ivy ; a search engine for love and life
+
+ :ui
+ ;;deft ; notational velocity for Emacs
+ doom ; what makes DOOM look the way it does
+ doom-dashboard ; a nifty splash screen for Emacs
+ doom-quit ; DOOM quit-message prompts when you quit Emacs
+ ;;fill-column ; a `fill-column' indicator
+ hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
+ ;;hydra
+ ;;indent-guides ; highlighted indent columns
+ ;;ligatures ; ligatures and symbols to make your code pretty again
+ ;;minimap ; show a map of the code on the side
+ modeline ; snazzy, Atom-inspired modeline, plus API
+ ;;nav-flash ; blink cursor line after big motions
+ ;;neotree ; a project drawer, like NERDTree for vim
+ ophints ; highlight the region an operation acts on
+ (popup +defaults) ; tame sudden yet inevitable temporary windows
+ ;;tabs ; a tab bar for Emacs
+ ;;treemacs ; a project drawer, like neotree but cooler
+ ;;unicode ; extended unicode support for various languages
+ vc-gutter ; vcs diff in the fringe
+ vi-tilde-fringe ; fringe tildes to mark beyond EOB
+ ;;window-select ; visually switch windows
+ workspaces ; tab emulation, persistence & separate workspaces
+ ;;zen ; distraction-free coding or writing
+
+ :editor
+ (evil +everywhere); come to the dark side, we have cookies
+ file-templates ; auto-snippets for empty files
+ fold ; (nigh) universal code folding
+ ;;(format +onsave) ; automated prettiness
+ ;;god ; run Emacs commands without modifier keys
+ ;;lispy ; vim for lisp, for people who don't like vim
+ ;;multiple-cursors ; editing in many places at once
+ ;;objed ; text object editing for the innocent
+ ;;parinfer ; turn lisp into python, sort of
+ ;;rotate-text ; cycle region at point between text candidates
+ snippets ; my elves. They type so I don't have to
+ word-wrap ; soft wrapping with language-aware indent
+
+ :emacs
+ dired ; making dired pretty [functional]
+ electric ; smarter, keyword-based electric-indent
+ ;;ibuffer ; interactive buffer management
+ undo ; persistent, smarter undo for your inevitable mistakes
+ vc ; version-control and Emacs, sitting in a tree
+
+ :term
+ ;;eshell ; the elisp shell that works everywhere
+ ;;shell ; simple shell REPL for Emacs
+ ;;term ; basic terminal emulator for Emacs
+ vterm ; the best terminal emulation in Emacs
+
+ :checkers
+ syntax ; tasing you for every semicolon you forget
+ spell ; tasing you for misspelling mispelling
+ grammar ; tasing grammar mistake every you make
+
+ :tools
+ ;;ansible
+ ;;debugger ; FIXME stepping through code, to help you add bugs
+ ;;direnv
+ ;;docker
+ ;;editorconfig ; let someone else argue about tabs vs spaces
+ ;;ein ; tame Jupyter notebooks with emacs
+ (eval +overlay) ; run code, run (also, repls)
+ ;;gist ; interacting with github gists
+ lookup ; navigate your code and its documentation
+ ;;lsp
+ magit ; a git porcelain for Emacs
+ make ; run make tasks from Emacs
+ pass ; password manager for nerds
+ pdf ; pdf enhancements
+ ;;prodigy ; FIXME managing external services & code builders
+ rgb ; creating color strings
+ ;;taskrunner ; taskrunner for all your projects
+ ;;terraform ; infrastructure as code
+ tmux ; an API for interacting with tmux
+ ;;upload ; map local to remote projects via ssh/ftp
+
+ :os
+ (:if IS-MAC macos) ; improve compatibility with macOS
+ ;;tty ; improve the terminal Emacs experience
+
+ :lang
+ ;;agda ; types of types of types of types...
+ cc ; C/C++/Obj-C madness
+ ;;clojure ; java with a lisp
+ ;;common-lisp ; if you've seen one lisp, you've seen them all
+ ;;coq ; proofs-as-programs
+ ;;crystal ; ruby at the speed of c
+ ;;csharp ; unity, .NET, and mono shenanigans
+ ;;data ; config/data formats
+ ;;(dart +flutter) ; paint ui and not much else
+ ;;elixir ; erlang done right
+ ;;elm ; care for a cup of TEA?
+ emacs-lisp ; drown in parentheses
+ ;;erlang ; an elegant language for a more civilized age
+ ;;ess ; emacs speaks statistics
+ ;;faust ; dsp, but you get to keep your soul
+ ;;fsharp ; ML stands for Microsoft's Language
+ ;;fstar ; (dependent) types and (monadic) effects and Z3
+ ;;gdscript ; the language you waited for
+ ;;(go +lsp) ; the hipster dialect
+ (haskell +dante) ; a language that's lazier than I am
+ ;;hy ; readability of scheme w/ speed of python
+ ;;idris ;
+ ;;json ; At least it ain't XML
+ ;;(java +meghanada) ; the poster child for carpal tunnel syndrome
+ ;;javascript ; all(hope(abandon(ye(who(enter(here))))))
+ ;;julia ; a better, faster MATLAB
+ ;;kotlin ; a better, slicker Java(Script)
+ ;;latex ; writing papers in Emacs has never been so fun
+ ;;lean
+ ;;factor
+ ;;ledger ; an accounting system in Emacs
+ lua ; one-based indices? one-based indices
+ markdown ; writing docs for people to ignore
+ nim ; python + lisp at the speed of c
+ ;;nix ; I hereby declare "nix geht mehr!"
+ ;;ocaml ; an objective camel
+ org ; organize your plain life in plain text
+ ;;php ; perl's insecure younger brother
+ ;;plantuml ; diagrams for confusing people more
+ ;;purescript ; javascript, but functional
+ ;;python ; beautiful is better than ugly
+ ;;qt ; the 'cutest' gui framework ever
+ ;;racket ; a DSL for DSLs
+ ;;raku ; the artist formerly known as perl6
+ ;;rest ; Emacs as a REST client
+ ;;rst ; ReST in peace
+ ;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
+ rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
+ ;;scala ; java, but good
+ ;;scheme ; a fully conniving family of lisps
+ sh ; she sells {ba,z,fi}sh shells on the C xor
+ ;;sml
+ ;;solidity ; do you need a blockchain? No.
+ ;;swift ; who asked for emoji variables?
+ ;;terra ; Earth and Moon in alignment for performance.
+ ;;web ; the tubes
+ ;;yaml ; JSON, but readable
+
+ :email
+ ;;(mu4e +gmail)
+ ;;notmuch
+ ;;(wanderlust +gmail)
+
+ :app
+ ;;calendar
+ ;;irc ; how neckbeards socialize
+ ;;(rss +org) ; emacs as an RSS reader
+ ;;twitter ; twitter client https://twitter.com/vnought
+
+ :config
+ ;;literate
+ (default +bindings +smartparens))
diff --git a/doom/packages.el b/doom/packages.el
new file mode 100644
index 0000000..b80e9cc
--- /dev/null
+++ b/doom/packages.el
@@ -0,0 +1,50 @@
+;; -*- no-byte-compile: t; -*-
+;;; $DOOMDIR/packages.el
+
+;; To install a package with Doom you must declare them here and run 'doom sync'
+;; on the command line, then restart Emacs for the changes to take effect -- or
+;; use 'M-x doom/reload'.
+
+
+;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
+;(package! some-package)
+
+;; To install a package directly from a remote git repo, you must specify a
+;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
+;; https://github.com/raxod502/straight.el#the-recipe-format
+;(package! another-package
+; :recipe (:host github :repo "username/repo"))
+
+;; If the package you are trying to install does not contain a PACKAGENAME.el
+;; file, or is located in a subdirectory of the repo, you'll need to specify
+;; `:files' in the `:recipe':
+;(package! this-package
+; :recipe (:host github :repo "username/repo"
+; :files ("some-file.el" "src/lisp/*.el")))
+
+;; If you'd like to disable a package included with Doom, you can do so here
+;; with the `:disable' property:
+;(package! builtin-package :disable t)
+
+;; You can override the recipe of a built in package without having to specify
+;; all the properties for `:recipe'. These will inherit the rest of its recipe
+;; from Doom or MELPA/ELPA/Emacsmirror:
+;(package! builtin-package :recipe (:nonrecursive t))
+;(package! builtin-package-2 :recipe (:repo "myfork/package"))
+
+;; Specify a `:branch' to install a package from a particular branch or tag.
+;; This is required for some packages whose default branch isn't 'master' (which
+;; our package manager can't deal with; see raxod502/straight.el#279)
+;(package! builtin-package :recipe (:branch "develop"))
+
+;; Use `:pin' to specify a particular commit to install.
+;(package! builtin-package :pin "1a2b3c4d5e")
+
+
+;; Doom's packages are pinned to a specific commit and updated from release to
+;; release. The `unpin!' macro allows you to unpin single packages...
+;(unpin! pinned-package)
+;; ...or multiple packages
+;(unpin! pinned-package another-pinned-package)
+;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
+;(unpin! t)
diff --git a/dunst/dunstrc b/dunst/dunstrc
new file mode 100644
index 0000000..7d8963b
--- /dev/null
+++ b/dunst/dunstrc
@@ -0,0 +1,418 @@
+[global]
+ ### Display ###
+
+ # Which monitor should the notifications be displayed on.
+ monitor = 0
+
+ # Display notification on focused monitor. Possible modes are:
+ # mouse: follow mouse pointer
+ # keyboard: follow window with keyboard focus
+ # none: don't follow anything
+ #
+ # "keyboard" needs a window manager that exports the
+ # _NET_ACTIVE_WINDOW property.
+ # This should be the case for almost all modern window managers.
+ #
+ # If this option is set to mouse or keyboard, the monitor option
+ # will be ignored.
+ follow = mouse
+
+ # The geometry of the window:
+ # [{width}]x{height}[+/-{x}+/-{y}]
+ # The geometry of the message window.
+ # The height is measured in number of notifications everything else
+ # in pixels. If the width is omitted but the height is given
+ # ("-geometry x2"), the message window expands over the whole screen
+ # (dmenu-like). If width is 0, the window expands to the longest
+ # message displayed. A positive x is measured from the left, a
+ # negative from the right side of the screen. Y is measured from
+ # the top and down respectively.
+ # The width can be negative. In this case the actual width is the
+ # screen width minus the width defined in within the geometry option.
+ geometry = "0x0-30+20"
+
+ # Show how many messages are currently hidden (because of geometry).
+ indicate_hidden = yes
+
+ # Shrink window if it's smaller than the width. Will be ignored if
+ # width is 0.
+ shrink = no
+
+ # The transparency of the window. Range: [0; 100].
+ # This option will only work if a compositing window manager is
+ # present (e.g. xcompmgr, compiz, etc.).
+ transparency = 10
+
+ # The height of the entire notification. If the height is smaller
+ # than the font height and padding combined, it will be raised
+ # to the font height and padding.
+ notification_height = 0
+
+ # Draw a line of "separator_height" pixel height between two
+ # notifications.
+ # Set to 0 to disable.
+ separator_height = 2
+
+ # Padding between text and separator.
+ padding = 8
+
+ # Horizontal padding.
+ horizontal_padding = 8
+
+ # Defines width in pixels of frame around the notification window.
+ # Set to 0 to disable.
+ frame_width = 3
+
+ # Defines color of the frame around the notification window.
+ frame_color = "#aaaaaa"
+
+ # Define a color for the separator.
+ # possible values are:
+ # * auto: dunst tries to find a color fitting to the background;
+ # * foreground: use the same color as the foreground;
+ # * frame: use the same color as the frame;
+ # * anything else will be interpreted as a X color.
+ separator_color = frame
+
+ # Sort messages by urgency.
+ sort = yes
+
+ # Don't remove messages, if the user is idle (no mouse or keyboard input)
+ # for longer than idle_threshold seconds.
+ # Set to 0 to disable.
+ # A client can set the 'transient' hint to bypass this. See the rules
+ # section for how to disable this if necessary
+ idle_threshold = 120
+
+ ### Text ###
+
+ font = Monospace 8
+
+ # The spacing between lines. If the height is smaller than the
+ # font height, it will get raised to the font height.
+ line_height = 0
+
+ # Possible values are:
+ # full: Allow a small subset of html markup in notifications:
+ # <b>bold</b>
+ # <i>italic</i>
+ # <s>strikethrough</s>
+ # <u>underline</u>
+ #
+ # For a complete reference see
+ # <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
+ #
+ # strip: This setting is provided for compatibility with some broken
+ # clients that send markup even though it's not enabled on the
+ # server. Dunst will try to strip the markup but the parsing is
+ # simplistic so using this option outside of matching rules for
+ # specific applications *IS GREATLY DISCOURAGED*.
+ #
+ # no: Disable markup parsing, incoming notifications will be treated as
+ # plain text. Dunst will not advertise that it has the body-markup
+ # capability if this is set as a global setting.
+ #
+ # It's important to note that markup inside the format option will be parsed
+ # regardless of what this is set to.
+ markup = full
+
+ # The format of the message. Possible variables are:
+ # %a appname
+ # %s summary
+ # %b body
+ # %i iconname (including its path)
+ # %I iconname (without its path)
+ # %p progress value if set ([ 0%] to [100%]) or nothing
+ # %n progress value if set without any extra characters
+ # %% Literal %
+ # Markup is allowed
+ format = "<b>%s</b>\n%b"
+
+ # Alignment of message text.
+ # Possible values are "left", "center" and "right".
+ alignment = left
+
+ # Show age of message if message is older than show_age_threshold
+ # seconds.
+ # Set to -1 to disable.
+ show_age_threshold = 60
+
+ # Split notifications into multiple lines if they don't fit into
+ # geometry.
+ word_wrap = yes
+
+ # When word_wrap is set to no, specify where to make an ellipsis in long lines.
+ # Possible values are "start", "middle" and "end".
+ ellipsize = middle
+
+ # Ignore newlines '\n' in notifications.
+ ignore_newline = no
+
+ # Stack together notifications with the same content
+ stack_duplicates = true
+
+ # Hide the count of stacked notifications with the same content
+ hide_duplicate_count = false
+
+ # Display indicators for URLs (U) and actions (A).
+ show_indicators = yes
+
+ ### Icons ###
+
+ # Align icons left/right/off
+ icon_position = off
+
+ # Scale larger icons down to this size, set to 0 to disable
+ max_icon_size = 24
+
+ # Paths to default icons.
+ icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
+
+ ### History ###
+
+ # Should a notification popped up from history be sticky or timeout
+ # as if it would normally do.
+ sticky_history = yes
+
+ # Maximum amount of notifications kept in history
+ history_length = 20
+
+ ### Misc/Advanced ###
+
+ # dmenu path.
+ dmenu = /usr/bin/dmenu -p dunst:
+
+ # Browser for opening urls in context menu.
+ browser = /usr/bin/firefox -new-tab
+
+ # Always run rule-defined scripts, even if the notification is suppressed
+ always_run_script = true
+
+ # Define the title of the windows spawned by dunst
+ title = Dunst
+
+ # Define the class of the windows spawned by dunst
+ class = Dunst
+
+ # Print a notification on startup.
+ # This is mainly for error detection, since dbus (re-)starts dunst
+ # automatically after a crash.
+ startup_notification = false
+
+ # Manage dunst's desire for talking
+ # Can be one of the following values:
+ # crit: Critical features. Dunst aborts
+ # warn: Only non-fatal warnings
+ # mesg: Important Messages
+ # info: all unimportant stuff
+ # debug: all less than unimportant stuff
+ verbosity = mesg
+
+ # Define the corner radius of the notification window
+ # in pixel size. If the radius is 0, you have no rounded
+ # corners.
+ # The radius will be automatically lowered if it exceeds half of the
+ # notification height to avoid clipping text and/or icons.
+ corner_radius = 0
+
+ ### Legacy
+
+ # Use the Xinerama extension instead of RandR for multi-monitor support.
+ # This setting is provided for compatibility with older nVidia drivers that
+ # do not support RandR and using it on systems that support RandR is highly
+ # discouraged.
+ #
+ # By enabling this setting dunst will not be able to detect when a monitor
+ # is connected or disconnected which might break follow mode if the screen
+ # layout changes.
+ force_xinerama = false
+
+ ### mouse
+
+ # Defines action of mouse event
+ # Possible values are:
+ # * none: Don't do anything.
+ # * do_action: If the notification has exactly one action, or one is marked as default,
+ # invoke it. If there are multiple and no default, open the context menu.
+ # * close_current: Close current notification.
+ # * close_all: Close all notifications.
+ mouse_left_click = close_current
+ mouse_middle_click = do_action
+ mouse_right_click = close_all
+
+# Experimental features that may or may not work correctly. Do not expect them
+# to have a consistent behaviour across releases.
+[experimental]
+ # Calculate the dpi to use on a per-monitor basis.
+ # If this setting is enabled the Xft.dpi value will be ignored and instead
+ # dunst will attempt to calculate an appropriate dpi value for each monitor
+ # using the resolution and physical size. This might be useful in setups
+ # where there are multiple screens with very different dpi values.
+ per_monitor_dpi = false
+
+[shortcuts]
+
+ # Shortcuts are specified as [modifier+][modifier+]...key
+ # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
+ # "mod3" and "mod4" (windows-key).
+ # Xev might be helpful to find names for keys.
+
+ # Close notification.
+ close = ctrl+space
+
+ # Close all notifications.
+ close_all = ctrl+shift+space
+
+ # Redisplay last message(s).
+ # On the US keyboard layout "grave" is normally above TAB and left
+ # of "1". Make sure this key actually exists on your keyboard layout,
+ # e.g. check output of 'xmodmap -pke'
+ history = ctrl+grave
+
+ # Context menu.
+ context = ctrl+shift+period
+
+[urgency_low]
+ # IMPORTANT: colors have to be defined in quotation marks.
+ # Otherwise the "#" and following would be interpreted as a comment.
+ background = "#222222"
+ foreground = "#888888"
+ timeout = 10
+ # Icon for notifications with low urgency, uncomment to enable
+ #icon = /path/to/icon
+
+[urgency_normal]
+ background = "#285577"
+ foreground = "#ffffff"
+ timeout = 10
+ # Icon for notifications with normal urgency, uncomment to enable
+ #icon = /path/to/icon
+
+[urgency_critical]
+ background = "#900000"
+ foreground = "#ffffff"
+ frame_color = "#ff0000"
+ timeout = 0
+ # Icon for notifications with critical urgency, uncomment to enable
+ #icon = /path/to/icon
+
+# Every section that isn't one of the above is interpreted as a rules to
+# override settings for certain messages.
+#
+# Messages can be matched by
+# appname (discouraged, see desktop_entry)
+# body
+# category
+# desktop_entry
+# icon
+# match_transient
+# msg_urgency
+# stack_tag
+# summary
+#
+# and you can override the
+# background
+# foreground
+# format
+# frame_color
+# fullscreen
+# new_icon
+# set_stack_tag
+# set_transient
+# timeout
+# urgency
+#
+# Shell-like globbing will get expanded.
+#
+# Instead of the appname filter, it's recommended to use the desktop_entry filter.
+# GLib based applications export their desktop-entry name. In comparison to the appname,
+# the desktop-entry won't get localized.
+#
+# SCRIPTING
+# You can specify a script that gets run when the rule matches by
+# setting the "script" option.
+# The script will be called as follows:
+# script appname summary body icon urgency
+# where urgency can be "LOW", "NORMAL" or "CRITICAL".
+#
+# NOTE: if you don't want a notification to be displayed, set the format
+# to "".
+# NOTE: It might be helpful to run dunst -print in a terminal in order
+# to find fitting options for rules.
+
+# Disable the transient hint so that idle_threshold cannot be bypassed from the
+# client
+#[transient_disable]
+# match_transient = yes
+# set_transient = no
+#
+# Make the handling of transient notifications more strict by making them not
+# be placed in history.
+#[transient_history_ignore]
+# match_transient = yes
+# history_ignore = yes
+
+# fullscreen values
+# show: show the notifications, regardless if there is a fullscreen window opened
+# delay: displays the new notification, if there is no fullscreen window active
+# If the notification is already drawn, it won't get undrawn.
+# pushback: same as delay, but when switching into fullscreen, the notification will get
+# withdrawn from screen again and will get delayed like a new notification
+#[fullscreen_delay_everything]
+# fullscreen = delay
+#[fullscreen_show_critical]
+# msg_urgency = critical
+# fullscreen = show
+
+#[espeak]
+# summary = "*"
+# script = dunst_espeak.sh
+
+#[script-test]
+# summary = "*script*"
+# script = dunst_test.sh
+
+#[ignore]
+# # This notification will not be displayed
+# summary = "foobar"
+# format = ""
+
+#[history-ignore]
+# # This notification will not be saved in history
+# summary = "foobar"
+# history_ignore = yes
+
+#[skip-display]
+# # This notification will not be displayed, but will be included in the history
+# summary = "foobar"
+# skip_display = yes
+
+#[signed_on]
+# appname = Pidgin
+# summary = "*signed on*"
+# urgency = low
+#
+#[signed_off]
+# appname = Pidgin
+# summary = *signed off*
+# urgency = low
+#
+#[says]
+# appname = Pidgin
+# summary = *says*
+# urgency = critical
+#
+#[twitter]
+# appname = Pidgin
+# summary = *twitter.com*
+# urgency = normal
+#
+#[stack-volumes]
+# appname = "some_volume_notifiers"
+# set_stack_tag = "volume"
+
+[play_sound]
+ summary = "*"
+ script = notify-sound.sh
+
+# vim: ft=cfg
diff --git a/dwm/autostart.sh b/dwm/autostart.sh
new file mode 100755
index 0000000..000d580
--- /dev/null
+++ b/dwm/autostart.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+sh -c ~/.config/autostart.sh
+pgrep -x dwmblocks >/dev/null || dwmblocks
diff --git a/dwm/autostart_blocking.sh b/dwm/autostart_blocking.sh
new file mode 100755
index 0000000..3927441
--- /dev/null
+++ b/dwm/autostart_blocking.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+sh -c ~/.xprofile & disown
diff --git a/ff_enterprise_policy.zip b/ff_enterprise_policy.zip
new file mode 100644
index 0000000..a2fc6d9
--- /dev/null
+++ b/ff_enterprise_policy.zip
Binary files differ
diff --git a/firejail/disable-exec.local b/firejail/disable-exec.local
new file mode 100644
index 0000000..3162dc1
--- /dev/null
+++ b/firejail/disable-exec.local
@@ -0,0 +1 @@
+ignore noexec ${HOME}
diff --git a/firejail/dolphin-emu.local b/firejail/dolphin-emu.local
new file mode 100644
index 0000000..43c8046
--- /dev/null
+++ b/firejail/dolphin-emu.local
@@ -0,0 +1,4 @@
+noblacklist ${HOME}/roms
+
+mkdir ${HOME}/roms
+whitelist ${HOME}/roms
diff --git a/firejail/librewolf.local b/firejail/librewolf.local
new file mode 100644
index 0000000..cede7d2
--- /dev/null
+++ b/firejail/librewolf.local
@@ -0,0 +1,4 @@
+noblacklist ${HOME}/dwhelper
+
+mkdir ${HOME}/dwhelper
+whitelist ${HOME}/dwhelper
diff --git a/firejail/lynx.local b/firejail/lynx.local
new file mode 100644
index 0000000..acdd06c
--- /dev/null
+++ b/firejail/lynx.local
@@ -0,0 +1,3 @@
+noblacklist /tmp/neomutt.html
+
+whitelist /tmp/neomutt.html
diff --git a/firejail/mpv.local b/firejail/mpv.local
new file mode 100644
index 0000000..b6915f0
--- /dev/null
+++ b/firejail/mpv.local
@@ -0,0 +1,3 @@
+whitelist ${HOME}/videos
+whitelist ${HOME}/Videos
+whitelist ${HOME}/Media
diff --git a/firejail/neomutt.local b/firejail/neomutt.local
new file mode 100644
index 0000000..ce84d3f
--- /dev/null
+++ b/firejail/neomutt.local
@@ -0,0 +1,24 @@
+noblacklist ${HOME}/.mbsyncrc
+noblacklist ${HOME}/.local/scripts
+noblacklist ${HOME}/.local/share/mail
+noblacklist ${HOME}/.local/share/pass
+noblacklist ${HOME}/.local/share/gnupg
+noblacklist /etc/ld.so.preload
+noblacklist /etc/lynx.cfg
+noblacklist /etc/ssl/certs/ca-certificates.crt
+noblacklist /usr/share/mutt-wizard
+
+mkdir ${HOME}/.local/share/mail
+mkdir ${HOME}/.local/share/pass
+mkdir ${HOME}/.local/share/gnupg
+whitelist ${HOME}/.mbsyncrc
+whitelist ${HOME}/.local/scripts
+whitelist ${HOME}/.local/share/mail
+whitelist ${HOME}/.local/share/pass
+whitelist ${HOME}/.local/share/gnupg
+whitelist /etc/ld.so.preload
+whitelist /etc/lynx.cfg
+whitelist /etc/ssl/certs/ca-certificates.crt
+whitelist /usr/share/mutt-wizard
+
+ignore apparmor
diff --git a/firejail/nextcloud.local b/firejail/nextcloud.local
new file mode 100644
index 0000000..94f4aec
--- /dev/null
+++ b/firejail/nextcloud.local
@@ -0,0 +1,4 @@
+noblacklist ${HOME}/nc
+
+mkdir ${HOME}/nc
+whitelist ${HOME}/nc
diff --git a/firejail/qutebrowser.local b/firejail/qutebrowser.local
new file mode 100644
index 0000000..82a6106
--- /dev/null
+++ b/firejail/qutebrowser.local
@@ -0,0 +1,4 @@
+noblacklist ${HOME}/.local/share/qutebrowser-profiles
+
+mkdir ${HOME}/.local/share/qutebrowser-profiles
+whitelist ${HOME}/.local/share/qutebrowser-profiles
diff --git a/firejail/steam.local b/firejail/steam.local
new file mode 100644
index 0000000..33c6b88
--- /dev/null
+++ b/firejail/steam.local
@@ -0,0 +1,2 @@
+seccomp !ptrace,!mount,!name_to_handle_at,!pivot_root,!umount2,!chroot
+ignore seccomp
diff --git a/ghostwriter/ghostwriter.conf b/ghostwriter/ghostwriter.conf
new file mode 100644
index 0000000..b0789b2
--- /dev/null
+++ b/ghostwriter/ghostwriter.conf
@@ -0,0 +1,68 @@
+[Application]
+locale=en_US
+
+[Export]
+lastUsedExporter=Sundown
+smartTypographyEnabled=true
+
+[FileHistory]
+1\cursorPosition=5268
+1\filePath=/home/zachir/Documents/Aquaria/chapter1.md
+size=1
+
+[HUD]
+alternateRowColors=false
+cheatSheetHudGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\0\0\0\0\0\a\x80\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W)
+cheatSheetHudOpen=false
+desktopCompositingEnabled=true
+documentStatisticsHudGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\0\0\0\0\0\a\x80\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W)
+documentStatisticsHudOpen=false
+opacity=200
+outlineHudGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\0\0\0\0\0\a\x80\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W)
+outlineHudOpen=false
+sessionStatisticsHudGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W\0\0\0\0\0\0\0\0\a\x80\0\0\0\xc8\0\0\0\xc8\0\0\x1\xc1\0\0\x2W)
+sessionStatisticsHudOpen=false
+windowButtonLayout=0
+
+[Preview]
+customStyleSheets=@Invalid()
+htmlPreviewOpen=false
+lastUsedExporter=Sundown
+lastUsedStyleSheet=:/resources/github-dark.css
+
+[Save]
+autoSave=true
+backupFile=true
+rememberFileHistory=true
+
+[Spelling]
+liveSpellCheck=true
+locale=en_US
+
+[Style]
+blockquoteStyle=0
+displayTimeInFullScreen=true
+editorWidth=1
+focusMode=1
+font="DejaVu Sans Mono,12,-1,5,50,0,0,0,0,0"
+hideHudsOnPreviewEnabled=false
+hideHudsWhenTypingEnabled=false
+hideMenuBarInFullScreenEnabled=true
+highlightLineBreaks=false
+interfaceStyle=1
+largeHeadings=true
+theme=Classic Dark
+underlineInsteadOfItalics=false
+
+[Tabs]
+insertSpacesForTabs=false
+tabWidth=4
+
+[Typing]
+autoMatchEnabled=true
+autoMatchFilter=\"'([{*_`<
+bulletPointCyclingEnabled=true
+
+[Window]
+mainWindowGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\x10\0\0\a\x7f\0\0\x4\x37\0\0\0\0\0\0\0\x10\0\0\a\x7f\0\0\x4\x37\0\0\0\0\0\0\0\0\a\x80\0\0\0\0\0\0\0\x10\0\0\a\x7f\0\0\x4\x37)
+mainWindowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\a\x80\0\0\x3\xf1\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\0)
diff --git a/gtk-2.0/gtkfilechooser.ini b/gtk-2.0/gtkfilechooser.ini
new file mode 100644
index 0000000..62930e9
--- /dev/null
+++ b/gtk-2.0/gtkfilechooser.ini
@@ -0,0 +1,11 @@
+[Filechooser Settings]
+LocationMode=path-bar
+ShowHidden=false
+ShowSizeColumn=true
+GeometryX=-1
+GeometryY=-1
+GeometryWidth=-1
+GeometryHeight=-1
+SortColumn=name
+SortOrder=ascending
+StartupMode=recent
diff --git a/gtk-2.0/gtkrc b/gtk-2.0/gtkrc
new file mode 100644
index 0000000..f0f7bf1
--- /dev/null
+++ b/gtk-2.0/gtkrc
@@ -0,0 +1,19 @@
+# DO NOT EDIT! This file will be overwritten by LXAppearance.
+# Any customization should be done in ~/.gtkrc-2.0.mine instead.
+
+include "/home/zachir/.gtkrc-2.0.mine"
+gtk-theme-name="Plata-Noir-Compact"
+gtk-icon-theme-name="Paper-Mono-Dark"
+gtk-font-name="Sans 10"
+gtk-cursor-theme-name="Paper"
+gtk-cursor-theme-size=0
+gtk-toolbar-style=GTK_TOOLBAR_BOTH
+gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
+gtk-button-images=1
+gtk-menu-images=1
+gtk-enable-event-sounds=1
+gtk-enable-input-feedback-sounds=1
+gtk-xft-antialias=1
+gtk-xft-hinting=1
+gtk-xft-hintstyle="hintfull"
+gtk-xft-rgba="rgb"
diff --git a/gtk-3.0/gtk.css b/gtk-3.0/gtk.css
new file mode 100644
index 0000000..bc747b9
--- /dev/null
+++ b/gtk-3.0/gtk.css
@@ -0,0 +1,12 @@
+.mate-panel-menu-bar button {
+ color: transparent;
+}
+panel-toplevel.background.horizontal,
+.mate-panel-menu-bar,
+#clock-applet-button,
+#clock-applet-button:hover {
+ color: white;
+}
+#tasklist-button {
+ color: white;
+}
diff --git a/gtk-3.0/settings.ini b/gtk-3.0/settings.ini
new file mode 100644
index 0000000..e2f0a04
--- /dev/null
+++ b/gtk-3.0/settings.ini
@@ -0,0 +1,16 @@
+[Settings]
+gtk-theme-name=Sweet-mars-v40
+gtk-icon-theme-name=Paper-Mono-Dark
+gtk-font-name=Sans 10
+gtk-cursor-theme-size=0
+gtk-toolbar-style=GTK_TOOLBAR_BOTH
+gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
+gtk-button-images=1
+gtk-menu-images=1
+gtk-enable-event-sounds=1
+gtk-enable-input-feedback-sounds=1
+gtk-xft-antialias=1
+gtk-xft-hinting=1
+gtk-xft-hintstyle=hintmedium
+gtk-xft-rgba=rgb
+gtk-cursor-theme-name=Bibata-Modern-Classic
diff --git a/herbstluftwm/README.md b/herbstluftwm/README.md
new file mode 100644
index 0000000..e257a35
--- /dev/null
+++ b/herbstluftwm/README.md
@@ -0,0 +1,3 @@
+# Herbstluftwm Config
+
+My Herbstluftwm Config \ No newline at end of file
diff --git a/herbstluftwm/autostart b/herbstluftwm/autostart
new file mode 100755
index 0000000..3f53457
--- /dev/null
+++ b/herbstluftwm/autostart
@@ -0,0 +1,205 @@
+#!/usr/bin/bash
+
+# this is a simple config for herbstluftwm
+
+hc() {
+ herbstclient "$@"
+}
+
+if [ -n "$XDG_CONFIG_HOME" ]; then
+ $XDG_CONFIG_HOME/X11/xprofile &
+ $XDG_CONFIG_HOME/autostart.sh &
+else
+ $HOME/.config/X11/xprofile &
+ $HOME/.config/autostart.sh &
+fi
+
+launch_polybar.sh herbstluft
+
+hc emit_hook reload
+
+# remove all existing keybindings
+hc keyunbind --all
+
+hc pad 0 20
+
+hc detect_monitors
+
+# keybindings
+# if you have a super key you will be much happier with Mod set to Mod4
+Mod=Mod1 # Use alt as the main modifier
+#Mod=Mod4 # Use the super key as the main modifier
+TERMINAL=st
+
+hc keybind $Mod-Shift-e quit
+hc keybind $Mod-Shift-r reload
+hc keybind $Mod-Shift-q close
+hc keybind $Mod-Return spawn $TERMINAL
+hc keybind $Mod-Shift-Return spawn $TERMINAL
+#hc keybind Super-l spawn i3lock-fancy
+#hc keybind $Mod-m spawn mpcalbum.sh
+#hc keybind $Mod-Shift-m spawn mpvlist.sh
+
+# scratchpads
+hc keybind $Mod+Control+z spawn ~/.config/herbstluftwm/sphtop
+hc keybind $Mod+Control+x spawn ~/.config/herbstluftwm/spterm
+hc keybind $Mod+Control+c spawn ~/.config/herbstluftwm/sppmxr
+hc keybind $Mod+Control+v spawn ~/.config/herbstluftwm/spblue
+hc keybind $Mod+Control+b spawn ~/.config/herbstluftwm/spncmp
+hc keybind $Mod+Control+a spawn ~/.config/herbstluftwm/spmutt
+hc keybind $Mod+Control+s spawn ~/.config/herbstluftwm/spprof
+hc keybind $Mod+Control+d spawn ~/.config/herbstluftwm/spirss
+#hc keybind $Mod+Control+f spawn ~/.config/herbstluftwm/spmpv
+
+# minimize and unminimize
+hc keybind $Mod+n jumpto last-minimized
+hc keybind $Mod+Shift+n set_attr clients.focus.minimized toggle
+
+# basic movement
+# focusing clients
+hc keybind $Mod-h focus left
+hc keybind $Mod-j focus down
+hc keybind $Mod-k focus up
+hc keybind $Mod-l focus right
+
+# moving clients
+hc keybind $Mod-Shift-h shift left
+hc keybind $Mod-Shift-j shift down
+hc keybind $Mod-Shift-k shift up
+hc keybind $Mod-Shift-l shift right
+
+# splitting frames
+# create an empty frame at the specified direction
+hc keybind $Mod-u split bottom 0.5
+hc keybind $Mod-o split right 0.5
+# let the current frame explode into subframes
+hc keybind $Mod-Control-space split explode
+
+# resizing frames
+resizestep=0.05
+hc keybind $Mod-Control-h resize left +$resizestep
+hc keybind $Mod-Control-j resize down +$resizestep
+hc keybind $Mod-Control-k resize up +$resizestep
+hc keybind $Mod-Control-l resize right +$resizestep
+hc keybind $Mod-Control-Left resize left +$resizestep
+hc keybind $Mod-Control-Down resize down +$resizestep
+hc keybind $Mod-Control-Up resize up +$resizestep
+hc keybind $Mod-Control-Right resize right +$resizestep
+
+# tags
+tag_names=( {1..9} )
+tag_keys=( {1..9} 0 )
+
+hc rename default "${tag_names[0]}" || true
+for i in ${!tag_names[@]} ; do
+ hc add "${tag_names[$i]}"
+ key="${tag_keys[$i]}"
+ if ! [ -z "$key" ] ; then
+ hc keybind "$Mod-$key" spawn hwinmv use_index $i
+ hc keybind "$Mod-Shift-$key" spawn hwinmv move_index "$i"
+ fi
+done
+
+# cycle through tags
+hc keybind $Mod-period use_index +1 --skip-visible
+hc keybind $Mod-comma use_index -1 --skip-visible
+
+# layouting
+hc keybind $Mod-e remove
+hc keybind $Mod-Shift-f floating toggle
+hc keybind $Mod-f fullscreen toggle
+# The following cycles through the available layouts within a frame, but skips
+# layouts, if the layout change wouldn't affect the actual window positions.
+# I.e. if there are two windows within a frame, the grid layout is skipped.
+hc keybind $Mod-space \
+ or , and . compare tags.focus.curframe_wcount = 2 \
+ . cycle_layout +1 vertical horizontal max vertical grid \
+ , cycle_layout +1
+
+# mouse
+hc mouseunbind --all
+hc mousebind $Mod-Button1 move
+hc mousebind $Mod-Button2 zoom
+hc mousebind $Mod-Button3 resize
+
+# focus
+hc keybind $Mod-BackSpace cycle_monitor
+hc keybind $Mod-Tab cycle_all +1
+hc keybind $Mod-Shift-Tab cycle_all -1
+hc keybind $Mod-c cycle
+hc keybind $Mod-i jumpto urgent
+
+# theme
+hc attr theme.tiling.reset 1
+hc attr theme.floating.reset 1
+hc set frame_border_active_color '#222222'
+hc set frame_border_normal_color '#101010'
+hc set frame_bg_normal_color '#565656'
+hc set frame_bg_active_color '#345F0C'
+hc set frame_border_width 1
+hc set always_show_frame 1
+hc set frame_bg_transparent 1
+hc set frame_transparent_width 5
+hc set frame_gap 4
+hc set hide_covered_windows on
+
+hc attr theme.active.color '#9fbc00'
+hc attr theme.normal.color '#454545'
+hc attr theme.urgent.color orange
+hc attr theme.inner_width 1
+hc attr theme.inner_color black
+hc attr theme.border_width 3
+hc attr theme.floating.border_width 4
+hc attr theme.floating.outer_width 1
+hc attr theme.floating.outer_color black
+hc attr theme.active.inner_color '#3E4A00'
+hc attr theme.active.outer_color '#3E4A00'
+hc attr theme.background_color '#141414'
+
+hc set window_gap 0
+hc set frame_padding 0
+hc set smart_window_surroundings 0
+hc set smart_frame_surroundings 1
+hc set mouse_recenter_gap 0
+hc set focus_follows_mouse 1
+
+# rules
+hc unrule -F
+#hc rule class=XTerm tag=3 # move all xterms to tag 3
+hc rule focus=on # normally focus new clients
+#hc rule focus=off # normally do not focus new clients
+# give focus to most common terminals
+#hc rule class~'(.*[Rr]xvt.*|.*[Tt]erm|Konsole)' focus=on
+hc rule windowtype~'_NET_WM_WINDOW_TYPE_(DIALOG|UTILITY|SPLASH)' pseudotile=on
+hc rule windowtype='_NET_WM_WINDOW_TYPE_DIALOG' focus=on
+hc rule windowtype~'_NET_WM_WINDOW_TYPE_(NOTIFICATION|DOCK|DESKTOP)' manage=off
+# scratchpad rules
+hc rule instance=sphtop floatplacement=center floating=true floating_geometry=900x600
+hc rule instance=spterm floatplacement=center floating=true floating_geometry=900x600
+hc rule instance=sppmxr floatplacement=center floating=true floating_geometry=900x600
+hc rule instance=spblue floatplacement=center floating=true floating_geometry=900x600
+hc rule instance=spncmp floatplacement=center floating=true floating_geometry=900x600
+hc rule instance=spmutt floatplacement=center floating=true floating_geometry=900x600
+hc rule class=spprof floatplacement=center floating=true floating_geometry=900x600
+hc rule class=spirss floatplacement=center floating=true floating_geometry=900x600
+#hc rule class=mpv floatplacement=center floating=true floating_geometry=900x600
+
+hc set tree_style '╾│ ├└╼─┐'
+
+# unlock, just to be sure
+hc unlock
+
+# do multi monitor setup here, e.g.:
+# hc set_monitors 1280x1024+0+0 1280x1024+1280+0
+# or simply:
+# hc detect_monitors
+
+# find the panel
+#panel=~/.config/herbstluftwm/backup_panel.sh
+#[ -x "$panel" ] || panel=/etc/xdg/herbstluftwm/panel.sh
+#for monitor in $(herbstclient list_monitors | cut -d: -f1) ; do
+# # start it on each monitor
+# "$panel" $monitor &
+#done
+
+sh tagmv 0
diff --git a/herbstluftwm/spblue b/herbstluftwm/spblue
new file mode 100755
index 0000000..1f0c395
--- /dev/null
+++ b/herbstluftwm/spblue
@@ -0,0 +1,17 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:spblue
+if xdotool search --onlyvisible --classname 'spblue'; then
+ if [ "`herbstclient list_monitors | grep '[FOCUS]' | cut -d\\\" -f2`" = "`herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/\"//g'`" ]; then
+ xdotool search -onlyvisible -classname 'spblue' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then xdotool search -classname 'spblue' windowmap && exit
+ fi
+fi
+if ! xdotool search --classname 'spblue' windowmap; then
+ setsid -f st -t 'spblue' -n 'spblue' -- zsh -c bluetoothctl
+ xdotool search -sync -onlyvisible -classname 'spblue'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/herbstluftwm/sphtop b/herbstluftwm/sphtop
new file mode 100755
index 0000000..2d55a9f
--- /dev/null
+++ b/herbstluftwm/sphtop
@@ -0,0 +1,18 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:sphtop
+if xdotool search --onlyvisible --classname 'sphtop'; then
+ if [ $(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/"//g') ]; then
+ xdotool search -onlyvisible -classname 'sphtop' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -classname 'sphtop' windowmap && exit
+ fi
+fi
+if ! xdotool search --classname 'sphtop' windowmap; then
+ setsid -f st -t 'sphtop' -n 'sphtop' -- zsh -c htop
+ xdotool search -sync -onlyvisible -classname 'sphtop'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/herbstluftwm/spirss b/herbstluftwm/spirss
new file mode 100755
index 0000000..eb67989
--- /dev/null
+++ b/herbstluftwm/spirss
@@ -0,0 +1,18 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:spirss
+if xdotool search --class 'spirss'; then
+ if [ "$(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2)" = "$(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/\"//g')" ]; then
+ xdotool search -class 'spirss' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -class 'spirss' windowmap && exit
+ fi
+fi
+if ! xdotool search -class 'spirss' windowmap; then
+ . ~/.profile && st -t 'spirss' -c 'spirss' -e irssi &
+ xdotool search -sync -onlyvisible -class 'spirss'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/herbstluftwm/spmpv b/herbstluftwm/spmpv
new file mode 100755
index 0000000..76038ab
--- /dev/null
+++ b/herbstluftwm/spmpv
@@ -0,0 +1,22 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:spmpv
+if [ -f "$scratchpad" ]; then
+ if xdotool search -class 'mpv'; then
+ if [ "$(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2)" = "$(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/\"//g')" ]; then
+ xdotool search -class 'mpv' windowunmap
+ exit
+ fi
+ fi
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -class 'mpv' windowmap && exit
+ fi
+ if ! xdotool search -class 'mpv' windowmap; then
+ xdotool search -sync -onlyvisible -class 'mpv'
+ herbstclient attr clients.focus.winid > $scratchpad
+ fi
+else
+ if ! xdotool search -class 'mpv' windowmap; then
+ xdotool search -sync -onlyvisible -class 'mpv'
+ herbstclient attr clients.focus.winid > $scratchpad
+ fi
+fi
diff --git a/herbstluftwm/spmutt b/herbstluftwm/spmutt
new file mode 100755
index 0000000..510764e
--- /dev/null
+++ b/herbstluftwm/spmutt
@@ -0,0 +1,18 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:spmutt
+if xdotool search --onlyvisible --classname 'spmutt'; then
+ if [ $(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/"//g') ]; then
+ xdotool search -onlyvisible -classname 'spmutt' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -classname 'spmutt' windowmap && exit
+ fi
+fi
+if ! xdotool search --classname 'spmutt' windowmap; then
+ setsid -f st -t 'spmutt' -n 'spmutt' -- zsh -c neomutt
+ xdotool search -sync -onlyvisible -classname 'spmutt'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/herbstluftwm/spncmp b/herbstluftwm/spncmp
new file mode 100755
index 0000000..0ad5bec
--- /dev/null
+++ b/herbstluftwm/spncmp
@@ -0,0 +1,18 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:spncmp
+if xdotool search --onlyvisible --classname 'spncmp'; then
+ if [ $(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/"//g') ]; then
+ xdotool search -onlyvisible -classname 'spncmp' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -classname 'spncmp' windowmap && exit
+ fi
+fi
+if ! xdotool search --classname 'spncmp' windowmap; then
+ setsid -f st -t 'spncmp' -n 'spncmp' -- zsh -c ncmpcpp
+ xdotool search -sync -onlyvisible -classname 'spncmp'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/herbstluftwm/sppmxr b/herbstluftwm/sppmxr
new file mode 100755
index 0000000..7499312
--- /dev/null
+++ b/herbstluftwm/sppmxr
@@ -0,0 +1,18 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:sppmxr
+if xdotool search --onlyvisible --classname 'sppmxr'; then
+ if [ $(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/"//g') ]; then
+ xdotool search -onlyvisible -classname 'sppmxr' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -classname 'sppmxr' windowmap && exit
+ fi
+fi
+if ! xdotool search --classname 'sppmxr' windowmap; then
+ setsid -f st -t 'sppmxr' -n 'sppmxr' -- zsh -c pulsemixer
+ xdotool search -sync -onlyvisible -classname 'sppmxr'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/herbstluftwm/spprof b/herbstluftwm/spprof
new file mode 100755
index 0000000..1a4dc40
--- /dev/null
+++ b/herbstluftwm/spprof
@@ -0,0 +1,18 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:spprof
+if xdotool search --onlyvisible --class 'spprof'; then
+ if [ $(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/"//g') ]; then
+ xdotool search -onlyvisible -class 'spprof' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -class 'spprof' windowmap && exit
+ fi
+fi
+if ! xdotool search --class 'spprof' windowmap; then
+ . ~/.profile && st -t 'spprof' -c 'spprof' -e profanity &
+ xdotool search -sync -onlyvisible -class 'spprof'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/herbstluftwm/spterm b/herbstluftwm/spterm
new file mode 100755
index 0000000..67f4f60
--- /dev/null
+++ b/herbstluftwm/spterm
@@ -0,0 +1,18 @@
+#!/bin/sh
+scratchpad=/tmp/herbstluftwm:spterm
+if xdotool search --onlyvisible --classname 'spterm'; then
+ if [ $(herbstclient list_monitors | grep '[FOCUS]' | cut -d\" -f2) = $(herbstclient attr clients.$(cat $scratchpad) | grep 's - - tag' | awk '{ print $6 }' | sed 's/"//g') ]; then
+ xdotool search -onlyvisible -classname 'spterm' windowunmap
+ exit
+ fi
+fi
+if [ -f $scratchpad ]; then
+ if ! herbstclient bring $(cat $scratchpad); then
+ xdotool search -classname 'spterm' windowmap && exit
+ fi
+fi
+if ! xdotool search --classname 'spterm' windowmap; then
+ st -t ‘spterm’ -n 'spterm' &
+ xdotool search -sync -onlyvisible -classname 'spterm'
+ herbstclient attr clients.focus.winid > $scratchpad
+fi
diff --git a/installers/vimplug_nvim.sh b/installers/vimplug_nvim.sh
new file mode 100755
index 0000000..feddd03
--- /dev/null
+++ b/installers/vimplug_nvim.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
+ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
diff --git a/installers/vimplug_vim.sh b/installers/vimplug_vim.sh
new file mode 100755
index 0000000..7f32b3c
--- /dev/null
+++ b/installers/vimplug_vim.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
+ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
diff --git a/jellycli.yaml b/jellycli.yaml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jellycli.yaml
diff --git a/jellycli/jellycli.yaml b/jellycli/jellycli.yaml
new file mode 100644
index 0000000..e777549
--- /dev/null
+++ b/jellycli/jellycli.yaml
@@ -0,0 +1,38 @@
+gui:
+ debug_mode: false
+ double_click_ms: 220
+ enable_filtering: false
+ enable_results_filtering: true
+ enable_sorting: false
+ limit_recently_played: true
+ mouse_enabled: true
+ pagesize: 100
+ search_results_limit: 30
+ search_types:
+ - Artist
+ - Album
+ - Song
+ - Playlist
+ volume_steps: 20
+jellyfin:
+ device_id: ""
+ music_view: ""
+ server_id: ""
+ token: ""
+ url: ""
+ userid: ""
+player:
+ audio_buffering_ms: 150
+ enable_local_cache: false
+ enable_remote_control: true
+ http_buffering_limit_mem: 20
+ http_buffering_s: 5
+ local_cache_dir: /home/zachir/.cache/jellycli
+ logfile: /tmp/jellycli.log
+ loglevel: info
+ server: jellyfin
+subsonic:
+ salt: ""
+ token: ""
+ url: ""
+ username: ""
diff --git a/kshrc b/kshrc
new file mode 100644
index 0000000..cd372c4
--- /dev/null
+++ b/kshrc
@@ -0,0 +1,38 @@
+# zachir's ksh config
+
+[ -f /etc/ksh.kshrc ] && . /etc/ksh.kshrc
+
+[ -f $HOME/.config/sh/aliases ] && . $HOME/.config/sh/aliases
+[ -f $HOME/.config/sh/functions ] && . $HOME/.config/sh/functions
+
+RED="\033[1;31m"
+GRE="\033[1;32m"
+YEL="\033[1;33m"
+BLU="\033[1;34m"
+PUR="\033[1;35m"
+CYA="\033[1;36m"
+CLR="\033[1;0m"
+
+[ -f "$XDG_CONFIG_HOME"/sh/aliases ] && . "$XDG_CONFIG_HOME"/sh/aliases
+[ -f "$XDG_CONFIG_HOME"/sh/functions ] && . "$XDG_CONFIG_HOME"/sh/functions
+
+case "$-" in
+*i*) # we are interactive
+ # we may have su'ed so reset these
+ HOSTNAME=${HOSTNAME:-$(uname -n)}
+ HOST=${HOSTNAME%%.*}
+
+ #PROMPT="$USER:!$PS1S"
+ #PROMPT="<$USER@$HOST:!>$PS1S"
+ case "$USER" in
+ "root") COLOR='\e[1;31m' ;;
+ "git") COLOR='\e[1;32m' ;;
+ "zachir") COLOR='\e[1;36m' ;;
+ esac
+ PROMPT="$COLOR"'[\u@\h]:\e[0m\w'"$COLOR"'\$ \e[0m'
+ PS1=$PROMPT
+
+ set -o vi
+
+;;
+esac
diff --git a/lf/3q b/lf/3q
new file mode 100755
index 0000000..06ec272
--- /dev/null
+++ b/lf/3q
@@ -0,0 +1,2 @@
+#!/bin/sh
+chafa "$1"
diff --git a/lf/cleaner b/lf/cleaner
new file mode 100755
index 0000000..a184d84
--- /dev/null
+++ b/lf/cleaner
@@ -0,0 +1,4 @@
+#!/bin/sh
+if [ -n "$FIFO_UEBERZUG" ]; then
+ printf '{"action": "remove", "identifier": "PREVIEW"}\n' > "$FIFO_UEBERZUG"
+fi
diff --git a/lf/image b/lf/image
new file mode 100755
index 0000000..77ddb5b
--- /dev/null
+++ b/lf/image
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+readonly ID_PREVIEW="preview"
+main() {
+ case "$1" in
+ "clear")
+ declare -p -A cmd=([action]=remove [identifier]="$ID_PREVIEW") \
+ > "$FIFO_UEBERZUG"
+ ;;
+ "draw")
+ declare -p -A cmd=([action]=add [identifier]="$ID_PREVIEW" \
+ [x]="$3" [y]="$4" [max_width]="$5" [max_height]="$6" \
+ [path]="$2") > "$FIFO_UEBERZUG"
+ ;;
+ "*") echo "Unknown command: '$1', '$2'" ;;
+ esac
+}
+main "$@"
+
diff --git a/lf/lfrc b/lf/lfrc
new file mode 100644
index 0000000..37c9fc7
--- /dev/null
+++ b/lf/lfrc
@@ -0,0 +1,351 @@
+set ratios 1:2:3
+set cleaner ~/.config/lf/cleaner
+set previewer ~/.config/lf/preview
+# Basic Settings
+set preview true
+set drawbox false
+set icons true
+set ignorecase true
+
+# Custom Functions
+cmd open ${{
+ case $(file --mime-type "$f" -bL) in
+ text/*|application/json) $EDITOR "$f";;
+ video/*) mpv "$f";;
+ audio/*) mpv "$f";;
+ application/pdf) zathura "$f" ;;
+ image/*) sxiv "$f" ;;
+ *) xdg-open "$f" ;;
+ esac
+}}
+
+cmd mkdir ${{
+ printf "Directory Name: "
+ read ans
+ mkdir $ans
+}}
+
+cmd mkfile ${{
+ printf "File Name: "
+ read ans
+ $EDITOR $ans
+}}
+
+cmd chmod ${{
+ printf "Mode Bits: "
+ read ans
+
+ for file in "$fx"
+ do
+ chmod $ans $file
+ done
+}}
+
+cmd sudomkfile ${{
+ printf "File Name: "
+ read ans
+ doas $EDITOR $ans
+}}
+
+cmd setwallpaper %cp "$f" ~/background.jpg && xwallpaper --center "$f"
+
+cmd fzf_jump ${{
+ res="$(find . -maxdepth 3 | fzf --reverse --header='Jump to location')"
+ if [ -f "$res" ]; then
+ cmd="select"
+ elif [ -d "$res" ]; then
+ cmd="cd"
+ fi
+ lf -remote "send $id $cmd \"$res\""
+}}
+
+cmd broot_jump ${{
+ f=$(mktemp)
+ res="$(broot --outcmd $f && cat $f | sed 's/cd //')"
+ rm -f "$f"
+ if [ -f "$res" ]; then
+ cmd="select"
+ elif [ -d "$res" ]; then
+ cmd="cd"
+ fi
+ lf -remote "send $id $cmd \"$res\""
+}}
+
+cmd open_config ${{
+ $EDITOR $(bookmenu -b ~/.config/bookmenu/configs -f fzf -o)
+}}
+
+cmd dragon %dragon-drop -a -x $fx
+cmd dragon-stay %dragon-drop -a $fx
+cmd dragon-individual %dragon-drop $fx
+cmd cpdragon %cpdragon
+cmd mvdragon %mvdragon
+cmd dlfile %dlfile
+
+# Archive bindings
+cmd unarchive ${{
+ case "$f" in
+ *.zip) unzip "$f" ;;
+ *.tar.gz) tar -xzvf "$f" ;;
+ *.tar.bz2) tar -xjvf "$f" ;;
+ *.tar.xz) tar -xJvf "$f" ;;
+ *.tar) tar -xvf "$f" ;;
+ *) echo "Unsupported format" ;;
+ esac
+}}
+
+cmd gitpull ${{
+ git pull
+ read dummy
+}}
+
+cmd gitadd ${{
+ git add $(basename $fx)
+}}
+
+cmd gitaddall ${{
+ git add .
+}}
+
+cmd gitpush ${{
+ git push
+ read dummy
+}}
+
+cmd gitcommit ${{
+ git commit -S
+}}
+
+cmd gitdiff ${{
+ git diff
+ read dummy
+}}
+
+cmd gitdifffile ${{
+ git diff `basename $fx`
+ read dummy
+}}
+
+cmd gitstatus ${{
+ git status | less
+}}
+
+cmd gitrestore ${{
+ git restore `basename $fx`
+ read dummy
+}}
+
+cmd gitsubmoduleupdate ${{
+ git submodule update
+ read dummy
+}}
+
+cmd gitsubmoduleinit ${{
+ git submodule update --init
+ read dummy
+}}
+
+cmd gitsubmoduleadd ${{
+ read url
+ read folder
+ git submodule add "$url" "$folder"
+ read dummy
+}}
+
+cmd make ${{
+ make -j4 all
+ read dummy
+}}
+
+cmd makeinstall ${{
+ sudo make -j4 install
+ read dummy
+}}
+
+cmd makeclean ${{
+ make -j4 clean
+ read dummy
+}}
+
+cmd openshell ${{
+ zsh
+}}
+
+cmd catclip ${{
+ catclip "$fx"
+}}
+
+cmd zip %zip -r "$f" "$f"
+cmd tar %tar cvf "$f.tar" "$f"
+cmd targz %tar cvzf "$f.tar.gz" "$f"
+cmd tarbz2 %tar cjvf "$f.tar.bz2" "$f"
+
+# Trash cli bindings
+cmd trash ${{
+ files=$(printf "$fx" | tr '\n' ';')
+ while [ "$files" ]; do
+ # extract the substring from start of string up to delimiter.
+ # this is the first "element" of the string.
+ file=${files%%;*}
+
+ trash-put "$(basename "$file")"
+ # if there's only one element left, set `files` to an empty string.
+ # this causes us to exit this `while` loop.
+ # else, we delete the first "element" of the string from files, and move onto the next.
+ if [ "$files" = "$file" ]; then
+ files=''
+ else
+ files="${files#*;}"
+ fi
+ done
+}}
+
+cmd clear_trash %trash-empty
+
+cmd restore_trash ${{
+ trash-restore
+}}
+
+cmd stripspace %stripspace "$f"
+
+# Bindings
+# Remove some defaults
+map m
+map o
+map n
+map "'"
+map '"'
+map d
+map c
+map e
+map f
+map ,
+
+# ZachIR bindings
+map ,gp gitpull
+map ,gP gitpush
+map ,gc gitcommit
+map ,ga gitadd
+map ,gA gitaddall
+map ,gd gitdifffile
+map ,gD gitdiff
+map ,gu gitsubmoduleupdate
+map ,gi gitsubmoduleinit
+map ,gm gitsubmoduleadd
+map ,gs gitstatus
+map ,gr gitrestore
+map ,mk make
+map ,mi makeinstall
+map ,mC makeclean
+map ,ss openshell
+map ,sc catclip
+
+
+# Not really image preview
+map - $~/.config/lf/draw_img "$f"
+
+cmd video_preview ${{
+ CACHE=$(mktemp /tmp/thumb_cache.XXXXX)
+ ffmpegthumbnailer -i "$f" -o $CACHE -s 0
+ ~/.config/lf/draw_img $CACHE && rm $CACHE
+}}
+map + :video_preview
+
+# File Openers
+map ee $$EDITOR "$f"
+map u $view "$f"
+
+# Archive Mappings
+map az zip
+map at tar
+map ag targz
+map ab targz
+map au unarchive
+
+# Trash Mappings
+map dd trash
+map tc clear_trash
+map tr restore_trash
+
+# Broot Mapping
+map f broot_jump
+
+# Dragon Mapping
+map dr dragon
+map ds dragon-stay
+map di dragon-individual
+map dm mvdragon
+map dc cpdragon
+map dl dlfile
+
+map ss stripspace
+
+# Basic Functions
+map . set hidden!
+map DD delete
+map p paste
+map x cut
+map y copy
+map <enter> open
+map mf mkfile
+map mr sudomkfile
+map md mkdir
+map ms $mkscript
+map ch chmod
+map bg setwallpaper
+map o open_config
+map br $vimv $fx
+map r rename
+map H top
+map L bottom
+map R reload
+map C clear
+map U unselect
+
+# Movement
+map ga cd ~/.config/awesome
+map gb cd ~/.local/bin
+map gc cd ~/.config
+map gdc cd ~/Documents
+map gdo cd ~/Downloads
+map gdw cd ~/suckless/dwm
+map gdb cd ~/.local/src/dwmbar
+map ge cd ~/Desktop
+map gE cd /etc
+map gf cd ~/.var/app
+map glb cd ~/.local/bin
+map glc cd ~/Games/cache
+map gls cd ~/.local/share
+map glf cd ~/.config/lf
+map gnv cd ~/.config/nvim
+map gns cd ~/.natvst
+map gp cd ~/Pictures
+map gqc cd ~/.config/qutebrowser
+map gqp cd ~/.local/share/qutebrowser-profiles
+map gqt cd ~/.config/qtile
+map gre cd ~/.local/src
+map grs cd /etc/runit/sv
+map gsc cd ~/.local/scripts
+map gsh cd ~/.config/sh
+map gsl cd ~/.local/src/slock
+map gss cd /etc/s6/sv
+map gsx cd ~/.config/sxhkd
+map gtr cd ~/.local/share/Trash/files
+map gU. cd /usr
+map gUs cd /usr/share
+map gva cd ~/.var
+map gVa cd /var
+map gvi cd ~/Videos
+map gvs cd ~/.vst
+map gv3 cd ~/.vst3
+map gwa cd ~/git/wallpapers
+map gwd cd ~/.local/share/wineprefixes/default
+map gwD cd ~/.local/share/wineprefixes/default/drive_c/users/zachir/Downloads
+map gwr cd ~/.local/share/wineprefixes
+map gww cd ~/.local/share/wineprefixes/work
+map gx cd ~/.config/X11
+map gyb cd ~/.cache/yay
+map gyc cd ~/.config/yay
+map gzs cd ~/.config/zsh
+map gzx cd ~/Documents/zachir.xyz
+
diff --git a/lf/preview b/lf/preview
new file mode 100755
index 0000000..4b70b2e
--- /dev/null
+++ b/lf/preview
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+image() {
+ if [ -n "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ]; then
+ printf '{"action": "add", "identifier": "PREVIEW", "x": "%s", "y": "%s", "width": "%s", "height": "%s", "scaler": "contain", "path": "%s"}\n' "$4" "$5" "$(($2-1))" "$(($3-1))" "$1" > "$FIFO_UEBERZUG"
+ exit 1
+ else
+ chafa "$1" -s "$4x"
+ fi
+}
+
+batorcat() {
+ file="$1"
+ shift
+ if command -v bat > /dev/null 2>&1
+ then
+ bat --color=always --style=plain --pager=never "$file" "$@"
+ else
+ cat "$file"
+ fi
+}
+
+CACHE="$HOME/.cache/lf/thumbnail.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | awk '{print $1}'))"
+
+case "$(printf "%s\n" "$(readlink -f "$1")" | awk '{print tolower($0)}')" in
+ *.tgz|*.tar.gz) tar tzf "$1" ;;
+ *.tar.bz2|*.tbz2) tar tjf "$1" ;;
+ *.tar.txz|*.txz) xz --list "$1" ;;
+ *.tar) tar tf "$1" ;;
+ *.zip|*.jar|*.war|*.ear|*.oxt) unzip -l "$1" ;;
+ *.rar) unrar l "$1" ;;
+ *.md) glow -s dark "$1" ;;
+ *.7z) 7z l "$1" ;;
+ *.[1-8]) man "$1" | col -b ;;
+ *.o) nm "$1";;
+ *.torrent) transmission-show "$1" ;;
+ *.iso) iso-info --no-header -l "$1" ;;
+ *.odt|*.ods|*.odp|*.sxw) odt2txt "$1" ;;
+ *.doc) catdoc "$1" ;;
+ *.docx) docx2txt "$1" - ;;
+ *.xml|*.html) w3m -dump "$1";;
+ *.xls|*.xlsx)
+ ssconvert --export-type=Gnumeric_stf:stf_csv "$1" "fd://1" | batorcat --language=csv
+ ;;
+ *.wav|*.mp3|*.flac|*.m4a|*.wma|*.ape|*.ac3|*.og[agx]|*.spx|*.opus|*.as[fx]|*.mka)
+ exiftool "$1"
+ ;;
+ *.pdf)
+ [ ! -f "${CACHE}.jpg" ] && \
+ pdftoppm -jpeg -f 1 -singlefile "$1" "$CACHE"
+ image "${CACHE}.jpg" "$2" "$3" "$4" "$5"
+ ;;
+ *.epub)
+ [ ! -f "$CACHE" ] && \
+ epub-thumbnailer "$1" "$CACHE" 1024
+ image "$CACHE" "$2" "$3" "$4" "$5"
+ ;;
+ *.cbz|*.cbr|*.cbt)
+ [ ! -f "$CACHE" ] && \
+ comicthumb "$1" "$CACHE" 1024
+ image "$CACHE" "$2" "$3" "$4" "$5"
+ ;;
+ *.avi|*.mp4|*.wmv|*.dat|*.3gp|*.ogv|*.mkv|*.mpg|*.mpeg|*.vob|*.fl[icv]|*.m2v|*.mov|*.webm|*.ts|*.mts|*.m4v|*.r[am]|*.qt|*.divx)
+ [ ! -f "${CACHE}.jpg" ] && \
+ ffmpegthumbnailer -i "$1" -o "${CACHE}.jpg" -s 0 -q 5
+ image "${CACHE}.jpg" "$2" "$3" "$4" "$5"
+ ;;
+ *.bmp|*.jpg|*.jpeg|*.png|*.xpm|*.webp|*.gif|*.jfif)
+ image "$1" "$2" "$3" "$4" "$5"
+ ;;
+ *.svg)
+ [ ! -f "${CACHE}.jpg" ] && \
+ convert "$1" "${CACHE}.jpg"
+ image "${CACHE}.jpg" "$2" "$3" "$4" "$5"
+ ;;
+ *.ino)
+ batorcat --language=cpp "$1"
+ ;;
+ *)
+ batorcat "$1"
+ ;;
+esac
+exit 0
diff --git a/lxqt/lxqt.conf b/lxqt/lxqt.conf
new file mode 100644
index 0000000..1a15670
--- /dev/null
+++ b/lxqt/lxqt.conf
@@ -0,0 +1,3 @@
+[General]
+__userfile__=true
+icon_theme=oxygen
diff --git a/mksh/mkshalias b/mksh/mkshalias
new file mode 100644
index 0000000..c43e240
--- /dev/null
+++ b/mksh/mkshalias
@@ -0,0 +1,50 @@
+#!/bin/mksh
+## CD Ups
+alias ...='cd ../..'
+alias ....='cd ../../..'
+alias .....='cd ../../../..'
+alias ......='cd ../../../../..'
+alias .......='cd ../../../../../..'
+alias ........='cd ../../../../../../..'
+
+## Base Utils
+alias ls="ls -h --color='auto' --group-directories-first"
+alias ll='ls -l'
+alias la='ls -A'
+alias lla='ls -la'
+alias md='mkdir -p'
+alias ch='cd $HOME'
+alias exa='exa --group-directories-first -a'
+alias exla='exa -l'
+
+## Change utils
+alias rm='rm -i'
+alias cp='cp -i'
+
+## git stuff
+alias gs='git status'
+alias commit='git commit -S -m'
+alias ga='git add -A'
+
+## Internet
+alias weather='curl http://wttr.in/Pearland'
+
+## Single Chars
+alias r='cd ~ && clear && exec zsh'
+alias e='source $ENV'
+alias i='sudo ~/scripts/install.sh'
+alias q='exit'
+alias c='clear'
+alias m='make'
+
+## SSH
+alias sshz='ssh zachir@therealir.xyz'
+
+## Programming
+# Rust
+alias crr='cargo run --release'
+alias cbr='cargo build --release'
+
+## Arch Linux aliases --sudoloop
+#alias yay='yay --sudo doas'
+alias yu='yay -Syu --noconfirm'
diff --git a/mksh/mkshfunc b/mksh/mkshfunc
new file mode 100644
index 0000000..adb6a91
--- /dev/null
+++ b/mksh/mkshfunc
@@ -0,0 +1,58 @@
+#!/bin/mksh
+catclip () {
+ cat "$@" | xclip -selection clipboard
+}
+
+catpass () {
+ PASSWD=$(cat ~/pass.txt); echo "$PASSWD\n$PASSWD" | pass insert "$1"; unset PASSWD
+}
+
+sigdwmblocks () {
+ pkill -RTMIN+$(grep "$1" ~/git/dwmblocks/config.h | awk '{print $4}' | cut -d'}' -f1) dwmblocks
+}
+
+mkcd () {
+ mkdir $@ && cd $1
+}
+
+sc () {
+ if [ "$1" = "" ]; then
+ cd $HOME
+ else
+ case "$1" in
+ "-l") echo "
+a - ~/.config/awesome
+cpr- ~/.config/primrose
+db - ~/git/dwmbar
+dwm- ~/suckless/dwm
+g - ~/git
+pr - ~/git/primrose
+s - ~/.local/scripts
+slo- ~/suckless/slock
+st - ~/suckless/st
+tfd- ~/Documents/fllixel/TheFiniteDemo
+tst- !tabbed -c st -w
+v - ~/.vst
+vsv- ~/.local/volsv
+z - ~/.config/zsh
+zx - ~/Documents/zachir.xyz
+";;
+ "a") cd $XDG_CONFIG_HOME/awesome/ ;;
+ "cpr") cd $XDG_CONFIG_HOME/primrose/ ;;
+ "dwm") cd $HOME/suckless/dwm/ ;;
+ "db") cd $HOME/git/dwmbar/ ;;
+ "g") cd $HOME/git/ ;;
+ "pr") cd $HOME/git/primrose/ ;;
+ "slo") cd $HOME/suckless/slock/ ;;
+ "s") cd $HOME/.local/scripts/ ;;
+ "st") cd $HOME/suckless/st/ ;;
+ "tfd") cd $HOME/Documents/flixel/TheFiniteDemo/ ;;
+ "tst") tabbed -c st -w ;;
+ "v") cd $HOME/.vst/ ;;
+ "vsv") cd $HOME/.local/volsv ;;
+ "z") cd $ZDOTDIR/ ;;
+ "zx") cd $HOME/Documents/zachir.xyz/ ;;
+ *) cd $1 ;;
+ esac
+ fi
+}
diff --git a/mksh/mkshrc b/mksh/mkshrc
new file mode 100644
index 0000000..5b61ae3
--- /dev/null
+++ b/mksh/mkshrc
@@ -0,0 +1,684 @@
+# $Id$
+# $MirOS: src/bin/mksh/dot.mkshrc,v 1.128 2020/04/13 18:39:03 tg Exp $
+#-
+# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019,
+# 2020
+# mirabilos <m@mirbsd.org>
+#
+# Provided that these terms and disclaimer and all copyright notices
+# are retained or reproduced in an accompanying document, permission
+# is granted to deal in this work without restriction, including un-
+# limited rights to use, publicly perform, distribute, sell, modify,
+# merge, give away, or sublicence.
+#
+# This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+# the utmost extent permitted by applicable law, neither express nor
+# implied; without malicious intent or gross negligence. In no event
+# may a licensor, author or contributor be held liable for indirect,
+# direct, other damage, loss, or other issues arising in any way out
+# of dealing in the work, even if advised of the possibility of such
+# damage or existence of a defect, except proven that it results out
+# of said person's immediate fault when using the work as intended.
+#-
+# ${ENV:-~/.mkshrc}: mksh initialisation file for interactive shells
+
+# catch non-mksh, non-lksh, trying to run this file
+case ${KSH_VERSION:-} in
+*LEGACY\ KSH*|*MIRBSD\ KSH*) ;;
+*) \return 0 ;;
+esac
+
+# give MidnightBSD's laffer1 a bit of csh feeling
+function setenv {
+ if (( $# )); then
+ \\builtin eval '\\builtin export "$1"="${2:-}"'
+ else
+ \\builtin typeset -x
+ fi
+}
+
+# pager (not control character safe)
+smores() (
+ \\builtin set +m
+ \\builtin cat "$@" |&
+ \\builtin trap "rv=\$?; \\\\builtin kill $! >/dev/null 2>&1; \\\\builtin exit \$rv" EXIT
+ while IFS= \\builtin read -pr line; do
+ llen=${%line}
+ (( llen == -1 )) && llen=${#line}
+ (( llen = llen ? (llen + COLUMNS - 1) / COLUMNS : 1 ))
+ if (( (curlin += llen) >= LINES )); then
+ \\builtin print -nr -- $'\e[7m--more--\e[0m'
+ \\builtin read -u1 || \\builtin exit $?
+ [[ $REPLY = [Qq]* ]] && \\builtin exit 0
+ curlin=$llen
+ fi
+ \\builtin print -r -- "$line"
+ done
+)
+
+# customise your favourite editor here; the first one found is used
+for EDITOR in "${EDITOR:-}" jupp jstar mcedit ed vi; do
+ EDITOR=$(\\builtin whence -p "$EDITOR") || EDITOR=
+ [[ -n $EDITOR && -x $EDITOR ]] && break
+ EDITOR=nvim
+done
+
+\\builtin alias ls=ls l='ls -F' la='l -a' ll='l -l' lo='l -alo'
+\: "${EDITOR:=/bin/ed}${TERM:=vt100}${USER:=$(\\builtin ulimit -c 0; id -un \
+ 2>/dev/null)}${HOSTNAME:=$(\\builtin ulimit -c 0; hostname 2>/dev/null)}"
+[[ $HOSTNAME = ?(?(ip6-)localhost?(6)) ]] && HOSTNAME=nil; \\builtin unalias ls
+\\builtin export EDITOR HOSTNAME TERM USER="${USER:-?}"
+
+# minimal support for lksh users
+if [[ $KSH_VERSION = *LEGACY\ KSH* ]]; then
+ PS1='$USER@${HOSTNAME%%.*}:$PWD>'
+ \\builtin return 0
+else
+ PS1='$(print -n "\E[1;32m[`logname`@`hostname`]:\E[1;37m";if [ "${PWD#$HOME}" = "$PWD" ]; then print -n "$PWD"; else print -n "~${PWD#$HOME}"; fi; print "\E[1;32m$\E[0m ")'
+fi
+
+# mksh-specific from here
+\: "${MKSH:=$(\\builtin whence -p mksh)}${MKSH:=/bin/mksh}"
+\\builtin export MKSH
+
+# prompts
+#PS4='[$EPOCHREALTIME] '; PS1='#'; (( USER_ID )) && PS1='$'; PS1=$'\001\r''${|
+# \\builtin typeset e=$?
+#
+# (( e )) && REPLY+="$e|"
+# REPLY+=${USER}@${HOSTNAME%%.*}:
+#
+# \\builtin typeset d=${PWD:-?}/ p=~; [[ $p = ?(*/) ]] || d=${d/#$p\//\~/}
+# d=${d%/}; \\builtin typeset m=${%d} n p=...; (( m > 0 )) || m=${#d}
+# (( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || p=
+# REPLY+=$p$d
+#
+# \\builtin return $e
+#} '"$PS1 "
+
+# utilities
+\\builtin alias doch='sudo mksh -c "$(\\builtin fc -ln -1)"'
+\\builtin command -v rot13 >/dev/null || \\builtin alias rot13='tr \
+ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ \
+ nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'
+if \\builtin command -v hd >/dev/null; then
+ \:
+elif \\builtin command -v hexdump >/dev/null; then
+ function hd {
+ hexdump -e '"%08.8_ax " 8/1 "%02X " " - " 8/1 "%02X "' \
+ -e '" |" "%_p"' -e '"|\n"' "$@"
+ }
+else
+ function hd {
+ \\builtin cat "$@" | hd_mksh
+ }
+fi
+
+# NUL-safe and EBCDIC-safe hexdump (from stdin)
+function hd_mksh {
+ \\builtin typeset -Uui16 -Z11 pos=0
+ \\builtin typeset -Uui16 -Z5 hv=2147483647
+ \\builtin typeset dasc dn line i
+ \\builtin set +U
+
+ while \\builtin read -arn 512 line; do
+ \\builtin typeset -i1 'line[*]'
+ i=0
+ while (( i < ${#line[*]} )); do
+ dn=
+ (( (hv = line[i++]) != 0 )) && dn=${line[i-1]#1#}
+ if (( (pos & 15) == 0 )); then
+ (( pos )) && \
+ \\builtin print -r -- "$dasc|"
+ \\builtin print -nr "${pos#16#} "
+ dasc=' |'
+ fi
+ \\builtin print -nr "${hv#16#} "
+ if [[ $dn = [[:print:]] ]]; then
+ dasc+=$dn
+ else
+ dasc+=.
+ fi
+ (( (pos++ & 15) == 7 )) && \
+ \\builtin print -nr -- '- '
+ done
+ done
+ while (( pos & 15 )); do
+ \\builtin print -nr ' '
+ (( (pos++ & 15) == 7 )) && \
+ \\builtin print -nr -- '- '
+ done
+ (( hv == 2147483647 )) || \\builtin print -r -- "$dasc|"
+}
+
+function which {
+ \\builtin typeset p x c
+ \\builtin typeset -i a=0 rv=2 e
+ \\builtin set +e
+ \\builtin set -o noglob
+
+ while \\builtin getopts "a" x; do
+ case $x {
+ (a) a=1 ;;
+ (+a) a=0 ;;
+ (*) \\builtin print -ru2 'Usage: which [-a] name [...]'
+ \\builtin return 255 ;;
+ }
+ done
+ \\builtin shift $((OPTIND - 1))
+
+ # vvvvvvvvvvvvvvvvvvvv should be def_path
+ p=${PATH-/usr/bin$PATHSEP/bin}
+ # ^ no colon!
+
+ # trailing PATHSEP vs field splitting
+ [[ $p = *"$PATHSEP" ]] && p+=.
+
+ IFS=$PATHSEP
+ \\builtin set -A p -- ${p:-.}
+ IFS=$' \t\n'
+
+ for x in "$@"; do
+ if (( !a )) || [[ $x = */* ]]; then
+ \\builtin whence -p -- "$x"
+ e=$?
+ else
+ e=1
+ for c in "${p[@]}"; do
+ PATH=${c:-.} \\builtin whence -p -- "$x" && e=0
+ done
+ fi
+ (( rv = (e == 0) ? (rv & ~2) : (rv == 2 ? 2 : 1) ))
+ done
+ \\builtin return $rv
+}
+
+# Berkeley C shell compatible dirs, popd, and pushd functions
+# Z shell compatible chpwd() hook, used to update DIRSTACK[0]
+DIRSTACKBASE=$(\\builtin realpath ~/. 2>/dev/null || \
+ \\builtin print -nr -- "${HOME:-/}")
+\\builtin set -A DIRSTACK
+function chpwd {
+ DIRSTACK[0]=$(\\builtin realpath . 2>/dev/null || \
+ \\builtin print -nr -- "$PWD")
+ [[ $DIRSTACKBASE = ?(*/) ]] || \
+ DIRSTACK[0]=${DIRSTACK[0]/#$DIRSTACKBASE/\~}
+ \:
+}
+\chpwd .
+cd() {
+ \\builtin cd "$@" || \\builtin return $?
+ \chpwd "$@"
+}
+function cd_csh {
+ \\builtin typeset d t=${1/#\~/$DIRSTACKBASE}
+
+ if ! d=$(\\builtin cd "$t" 2>&1); then
+ \\builtin print -ru2 "${1}: ${d##*cd: $t: }."
+ \\builtin return 1
+ fi
+ \cd "$t"
+}
+function dirs {
+ \\builtin typeset d dwidth
+ \\builtin typeset -i fl=0 fv=0 fn=0 cpos=0
+
+ while \\builtin getopts ":lvn" d; do
+ case $d {
+ (l) fl=1 ;;
+ (v) fv=1 ;;
+ (n) fn=1 ;;
+ (*) \\builtin print -ru2 'Usage: dirs [-lvn].'
+ \\builtin return 1 ;;
+ }
+ done
+ \\builtin shift $((OPTIND - 1))
+ if (( $# > 0 )); then
+ \\builtin print -ru2 'Usage: dirs [-lvn].'
+ \\builtin return 1
+ fi
+ if (( fv )); then
+ fv=0
+ while (( fv < ${#DIRSTACK[*]} )); do
+ d=${DIRSTACK[fv]}
+ (( fl )) && d=${d/#\~/$DIRSTACKBASE}
+ \\builtin print -r -- "$fv $d"
+ (( ++fv ))
+ done
+ else
+ fv=0
+ while (( fv < ${#DIRSTACK[*]} )); do
+ d=${DIRSTACK[fv]}
+ (( fl )) && d=${d/#\~/$DIRSTACKBASE}
+ (( dwidth = (${%d} > 0 ? ${%d} : ${#d}) ))
+ if (( fn && (cpos += dwidth + 1) >= 79 && \
+ dwidth < 80 )); then
+ \\builtin print
+ (( cpos = dwidth + 1 ))
+ fi
+ \\builtin print -nr -- "$d "
+ (( ++fv ))
+ done
+ \\builtin print
+ fi
+ \\builtin return 0
+}
+function popd {
+ \\builtin typeset d fa
+ \\builtin typeset -i n=1
+
+ while \\builtin getopts ":0123456789lvn" d; do
+ case $d {
+ (l|v|n) fa+=" -$d" ;;
+ (+*) n=2
+ \\builtin break ;;
+ (*) \\builtin print -ru2 'Usage: popd [-lvn] [+<n>].'
+ \\builtin return 1 ;;
+ }
+ done
+ \\builtin shift $((OPTIND - n))
+ n=0
+ if (( $# > 1 )); then
+ \\builtin print -ru2 popd: Too many arguments.
+ \\builtin return 1
+ elif [[ $1 = ++([0-9]) && $1 != +0 ]]; then
+ if (( (n = ${1#+}) >= ${#DIRSTACK[*]} )); then
+ \\builtin print -ru2 popd: Directory stack not that deep.
+ \\builtin return 1
+ fi
+ elif [[ -n $1 ]]; then
+ \\builtin print -ru2 popd: Bad directory.
+ \\builtin return 1
+ fi
+ if (( ${#DIRSTACK[*]} < 2 )); then
+ \\builtin print -ru2 popd: Directory stack empty.
+ \\builtin return 1
+ fi
+ \\builtin unset DIRSTACK[n]
+ \\builtin set -A DIRSTACK -- "${DIRSTACK[@]}"
+ \cd_csh "${DIRSTACK[0]}" || \\builtin return 1
+ \dirs $fa
+}
+function pushd {
+ \\builtin typeset d fa
+ \\builtin typeset -i n=1
+
+ while \\builtin getopts ":0123456789lvn" d; do
+ case $d {
+ (l|v|n) fa+=" -$d" ;;
+ (+*) n=2
+ \\builtin break ;;
+ (*) \\builtin print -ru2 'Usage: pushd [-lvn] [<dir>|+<n>].'
+ \\builtin return 1 ;;
+ }
+ done
+ \\builtin shift $((OPTIND - n))
+ if (( $# == 0 )); then
+ if (( ${#DIRSTACK[*]} < 2 )); then
+ \\builtin print -ru2 pushd: No other directory.
+ \\builtin return 1
+ fi
+ d=${DIRSTACK[1]}
+ DIRSTACK[1]=${DIRSTACK[0]}
+ \cd_csh "$d" || \\builtin return 1
+ elif (( $# > 1 )); then
+ \\builtin print -ru2 pushd: Too many arguments.
+ \\builtin return 1
+ elif [[ $1 = ++([0-9]) && $1 != +0 ]]; then
+ if (( (n = ${1#+}) >= ${#DIRSTACK[*]} )); then
+ \\builtin print -ru2 pushd: Directory stack not that deep.
+ \\builtin return 1
+ fi
+ while (( n-- )); do
+ d=${DIRSTACK[0]}
+ \\builtin unset DIRSTACK[0]
+ \\builtin set -A DIRSTACK -- "${DIRSTACK[@]}" "$d"
+ done
+ \cd_csh "${DIRSTACK[0]}" || \\builtin return 1
+ else
+ \\builtin set -A DIRSTACK -- placeholder "${DIRSTACK[@]}"
+ \cd_csh "$1" || \\builtin return 1
+ fi
+ \dirs $fa
+}
+
+# base64 encoder and decoder, RFC compliant, NUL safe, not EBCDIC safe
+function Lb64decode {
+ \\builtin set +U
+ \\builtin typeset c s="$*" t
+ [[ -n $s ]] || { s=$(\\builtin cat; \\builtin print x); s=${s%x}; }
+ \\builtin typeset -i i=0 j=0 n=${#s} p=0 v x
+ \\builtin typeset -i16 o
+
+ while (( i < n )); do
+ c=${s:(i++):1}
+ case $c {
+ (=) \\builtin break ;;
+ ([A-Z]) (( v = 1#$c - 65 )) ;;
+ ([a-z]) (( v = 1#$c - 71 )) ;;
+ ([0-9]) (( v = 1#$c + 4 )) ;;
+ (+) v=62 ;;
+ (/) v=63 ;;
+ (*) \\builtin continue ;;
+ }
+ (( x = (x << 6) | v ))
+ case $((p++)) {
+ (0) \\builtin continue ;;
+ (1) (( o = (x >> 4) & 255 )) ;;
+ (2) (( o = (x >> 2) & 255 )) ;;
+ (3) (( o = x & 255 ))
+ p=0
+ ;;
+ }
+ t+=\\x${o#16#}
+ (( ++j & 4095 )) && \\builtin continue
+ \\builtin print -n $t
+ t=
+ done
+ \\builtin print -n $t
+}
+function Lb64encode {
+ \\builtin set +U
+ \\builtin typeset c s t table
+ \\builtin set -A table -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
+ a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /
+ if (( $# )); then
+ \\builtin read -raN-1 s <<<"$*"
+ \\builtin unset s[${#s[*]}-1]
+ else
+ \\builtin read -raN-1 s
+ fi
+ \\builtin typeset -i i=0 n=${#s[*]} v
+
+ while (( i < n )); do
+ (( v = s[i++] << 16 ))
+ (( v |= s[i++] << 8 ))
+ (( v |= s[i++] ))
+ t+=${table[v >> 18]}${table[v >> 12 & 63]}
+ c=${table[v >> 6 & 63]}
+ if (( i <= n )); then
+ t+=$c${table[v & 63]}
+ elif (( i == n + 1 )); then
+ t+=$c=
+ else
+ t+===
+ fi
+ if (( ${#t} == 76 || i >= n )); then
+ \\builtin print -r $t
+ t=
+ fi
+ done
+}
+
+# Better Avalanche for the Jenkins Hash
+\\builtin typeset -Z11 -Uui16 Lbafh_v
+function Lbafh_init {
+ Lbafh_v=0
+}
+function Lbafh_add {
+ \\builtin set +U
+ \\builtin typeset s
+ if (( $# )); then
+ \\builtin read -raN-1 s <<<"$*"
+ \\builtin unset s[${#s[*]}-1]
+ else
+ \\builtin read -raN-1 s
+ fi
+ \\builtin typeset -i i=0 n=${#s[*]}
+
+ while (( i < n )); do
+ ((# Lbafh_v = (Lbafh_v + s[i++] + 1) * 1025 ))
+ ((# Lbafh_v ^= Lbafh_v >> 6 ))
+ done
+}
+function Lbafh_finish {
+ \\builtin typeset -Ui t
+
+ ((# t = (((Lbafh_v >> 7) & 0x01010101) * 0x1B) ^ \
+ ((Lbafh_v << 1) & 0xFEFEFEFE) ))
+ ((# Lbafh_v = t ^ (t ^> 8) ^ (Lbafh_v ^> 8) ^ \
+ (Lbafh_v ^> 16) ^ (Lbafh_v ^> 24) ))
+ \:
+}
+
+# strip comments (and leading/trailing whitespace if IFS is set) from
+# any file(s) given as argument, or stdin if none, and spew to stdout
+function Lstripcom {
+ \\builtin set -o noglob
+ \\builtin cat "$@" | while \\builtin read _line; do
+ _line=${_line%%#*}
+ [[ -n $_line ]] && \\builtin print -r -- $_line
+ done
+}
+
+# toggle built-in aliases and utilities, and aliases and functions from mkshrc
+function enable {
+ \\builtin typeset doprnt=0 mode=1 x y z rv=0
+ \\builtin typeset b_alias i_alias i_func nalias=0 nfunc=0 i_all
+ \\builtin set -A b_alias
+ \\builtin set -A i_alias
+ \\builtin set -A i_func
+
+ # accumulate mksh built-in aliases, in ASCIIbetical order
+ i_alias[nalias]=autoload; b_alias[nalias++]='\\builtin typeset -fu'
+ i_alias[nalias]=functions; b_alias[nalias++]='\\builtin typeset -f'
+ i_alias[nalias]=hash; b_alias[nalias++]='\\builtin alias -t'
+ i_alias[nalias]=history; b_alias[nalias++]='\\builtin fc -l'
+ i_alias[nalias]=integer; b_alias[nalias++]='\\builtin typeset -i'
+ i_alias[nalias]=local; b_alias[nalias++]='\\builtin typeset'
+ i_alias[nalias]=login; b_alias[nalias++]='\\builtin exec login'
+ i_alias[nalias]=nameref; b_alias[nalias++]='\\builtin typeset -n'
+ i_alias[nalias]=nohup; b_alias[nalias++]='nohup '
+ i_alias[nalias]=r; b_alias[nalias++]='\\builtin fc -e -'
+ i_alias[nalias]=type; b_alias[nalias++]='\\builtin whence -v'
+
+ # accumulate mksh built-in utilities, in definition order, even ifndef
+ i_func[nfunc++]=.
+ i_func[nfunc++]=:
+ i_func[nfunc++]='['
+ i_func[nfunc++]=alias
+ i_func[nfunc++]=break
+ # \\builtin cannot, by design, be overridden
+ i_func[nfunc++]=builtin
+ i_func[nfunc++]=cat
+ i_func[nfunc++]=cd
+ i_func[nfunc++]=chdir
+ i_func[nfunc++]=command
+ i_func[nfunc++]=continue
+ i_func[nfunc++]=echo
+ i_func[nfunc++]=eval
+ i_func[nfunc++]=exec
+ i_func[nfunc++]=exit
+ i_func[nfunc++]=export
+ i_func[nfunc++]=false
+ i_func[nfunc++]=fc
+ i_func[nfunc++]=getopts
+ i_func[nfunc++]=jobs
+ i_func[nfunc++]=kill
+ i_func[nfunc++]=let
+ i_func[nfunc++]=print
+ i_func[nfunc++]=pwd
+ i_func[nfunc++]=read
+ i_func[nfunc++]=readonly
+ i_func[nfunc++]=realpath
+ i_func[nfunc++]=rename
+ i_func[nfunc++]=return
+ i_func[nfunc++]=set
+ i_func[nfunc++]=shift
+ i_func[nfunc++]=source
+ i_func[nfunc++]=suspend
+ i_func[nfunc++]=test
+ i_func[nfunc++]=times
+ i_func[nfunc++]=trap
+ i_func[nfunc++]=true
+ i_func[nfunc++]=typeset
+ i_func[nfunc++]=ulimit
+ i_func[nfunc++]=umask
+ i_func[nfunc++]=unalias
+ i_func[nfunc++]=unset
+ i_func[nfunc++]=wait
+ i_func[nfunc++]=whence
+ i_func[nfunc++]=bg
+ i_func[nfunc++]=fg
+ i_func[nfunc++]=bind
+ i_func[nfunc++]=mknod
+ i_func[nfunc++]=printf
+ i_func[nfunc++]=sleep
+ i_func[nfunc++]=domainname
+ i_func[nfunc++]=extproc
+
+ # accumulate aliases from dot.mkshrc, in definition order
+ i_alias[nalias]=l; b_alias[nalias++]='ls -F'
+ i_alias[nalias]=la; b_alias[nalias++]='l -a'
+ i_alias[nalias]=ll; b_alias[nalias++]='l -l'
+ i_alias[nalias]=lo; b_alias[nalias++]='l -alo'
+ i_alias[nalias]=doch; b_alias[nalias++]='sudo mksh -c "$(\\builtin fc -ln -1)"'
+ i_alias[nalias]=rot13; b_alias[nalias++]='tr abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'
+ i_alias[nalias]=cls; b_alias[nalias++]='\\builtin print -n \\ec'
+
+ # accumulate functions from dot.mkshrc, in definition order
+ i_func[nfunc++]=setenv
+ i_func[nfunc++]=smores
+ i_func[nfunc++]=hd
+ i_func[nfunc++]=hd_mksh
+ i_func[nfunc++]=which
+ i_func[nfunc++]=chpwd
+ i_func[nfunc++]=cd
+ i_func[nfunc++]=cd_csh
+ i_func[nfunc++]=dirs
+ i_func[nfunc++]=popd
+ i_func[nfunc++]=pushd
+ i_func[nfunc++]=Lb64decode
+ i_func[nfunc++]=Lb64encode
+ i_func[nfunc++]=Lbafh_init
+ i_func[nfunc++]=Lbafh_add
+ i_func[nfunc++]=Lbafh_finish
+ i_func[nfunc++]=Lstripcom
+ i_func[nfunc++]=enable
+
+ # collect all identifiers, sorted ASCIIbetically
+ \\builtin set -sA i_all -- "${i_alias[@]}" "${i_func[@]}"
+
+ # handle options, we don't do dynamic loading
+ while \\builtin getopts "adf:nps" x; do
+ case $x {
+ (a)
+ mode=-1
+ ;;
+ (d)
+ # deliberately causing an error, like bash-static
+ ;|
+ (f)
+ \\builtin print -ru2 enable: dynamic loading not available
+ \\builtin return 2
+ ;;
+ (n)
+ mode=0
+ ;;
+ (p)
+ doprnt=1
+ ;;
+ (s)
+ \\builtin set -sA i_all -- . : break continue eval \
+ exec exit export readonly return set shift times \
+ trap unset
+ ;;
+ (*)
+ \\builtin print -ru2 enable: usage: \
+ "enable [-adnps] [-f filename] [name ...]"
+ return 2
+ ;;
+ }
+ done
+ \\builtin shift $((OPTIND - 1))
+
+ # display builtins enabled/disabled/all/special?
+ if (( doprnt || ($# == 0) )); then
+ for x in "${i_all[@]}"; do
+ y=$(\\builtin alias "$x") || y=
+ [[ $y = "$x='\\\\builtin whence -p $x >/dev/null || (\\\\builtin print -r mksh: $x: not found; \\\\builtin exit 127) && \$(\\\\builtin whence -p $x)'" ]]; z=$?
+ case $mode:$z {
+ (-1:0|0:0)
+ \\builtin print -r -- "enable -n $x"
+ ;;
+ (-1:1|1:1)
+ \\builtin print -r -- "enable $x"
+ ;;
+ }
+ done
+ \\builtin return 0
+ fi
+
+ for x in "$@"; do
+ z=0
+ for y in "${i_alias[@]}" "${i_func[@]}"; do
+ [[ $x = "$y" ]] || \\builtin continue
+ z=1
+ \\builtin break
+ done
+ if (( !z )); then
+ \\builtin print -ru2 enable: "$x": not a shell builtin
+ rv=1
+ \\builtin continue
+ fi
+ if (( !mode )); then
+ # disable this
+ \\builtin alias "$x=\\\\builtin whence -p $x >/dev/null || (\\\\builtin print -r mksh: $x: not found; \\\\builtin exit 127) && \$(\\\\builtin whence -p $x)"
+ else
+ # find out if this is an alias or not, first
+ z=0
+ y=-1
+ while (( ++y < nalias )); do
+ [[ $x = "${i_alias[y]}" ]] || \\builtin continue
+ z=1
+ \\builtin break
+ done
+ if (( z )); then
+ # re-enable the original alias body
+ \\builtin alias "$x=${b_alias[y]}"
+ else
+ # re-enable the original utility/function
+ \\builtin unalias "$x"
+ fi
+ fi
+ done
+ \\builtin return $rv
+}
+
+\: place customisations below this line
+
+# some defaults / samples which you are supposed to adjust to your
+# liking; by default we add ~/.etc/bin and ~/bin (whichever exist)
+# to $PATH, set $SHELL to mksh, set some defaults for man and less
+# and show a few more possible things for users to begin moving in
+
+for p in ~/.etc/bin ~/bin; do
+ [[ -d $p/. ]] || \\builtin continue
+ [[ $PATHSEP$PATH$PATHSEP = *"$PATHSEP$p$PATHSEP"* ]] || \
+ PATH=$p$PATHSEP$PATH
+done
+
+\\builtin export SHELL=$MKSH MANWIDTH=80 LESSHISTFILE=-
+\\builtin alias cls='\\builtin print -n \\ec'
+
+#\\builtin unset LC_ADDRESS LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+# LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+# LC_TELEPHONE LC_TIME LANGUAGE LANG LC_ALL
+#p=en_GB.UTF-8
+#\\builtin export LANG=C LC_CTYPE=$p LC_MEASUREMENT=$p LC_MESSAGES=$p LC_PAPER=$p
+#\\builtin export LANG=C.UTF-8 LC_CTYPE=C.UTF-8
+#\\builtin export LC_ALL=C.UTF-8
+#\\builtin set -U
+#[[ ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} = *[Uu][Tt][Ff]?(-)8* ]] || \\builtin set +U
+
+\\builtin unset p
+
+set -o vi
+
+[ -r $MKSHDIR/mkshfunc ] && source $MKSHDIR/mkshfunc
+[ -r $MKSHDIR/mkshalias ] && source $MKSHDIR/mkshalias
+
+HISTFILE="$MKSHDIR"/history
+
+\: place customisations above this line
diff --git a/modprobed-db.conf b/modprobed-db.conf
new file mode 100644
index 0000000..42b32af
--- /dev/null
+++ b/modprobed-db.conf
@@ -0,0 +1,21 @@
+# For documentation, see the manpage for modprobed-db
+
+# Path where database will reside.
+# Do NOT use a variable in the following path like $HOME
+# You MUST use a fully qualified path or else invoking the script via sudo
+# will trick it into thinking that the db is in /root/foo/bar
+DBPATH="/home/zachir/.config"
+
+# Define the background of your terminal theme here.
+# A setting of dark will produce colors that nicely contrast a dark background.
+# A setting of light will produce colors that nicely contrast a light background.
+COLORS=dark
+#COLORS=light
+
+
+# Add modules in the ignore array that you do NOT want counted, for example out-of-tree
+# modules and those provided by another package.
+#
+# For Arch Linux, some examples are given below but this is not an fully inclusive list.
+
+IGNORE=(nvidia nvidia_drm nvidia_modeset nvidia_uvm vboxdrv vboxnetadp vboxnetflt vboxpci acpi_call tp_smapi-dkms)
diff --git a/mpd/mpd.conf b/mpd/mpd.conf
new file mode 100644
index 0000000..e26dbd1
--- /dev/null
+++ b/mpd/mpd.conf
@@ -0,0 +1,401 @@
+# An example configuration file for MPD.
+# Read the user manual for documentation: http://www.musicpd.org/doc/user/
+
+
+# Files and directories #######################################################
+#
+# This setting controls the top directory which MPD will search to discover the
+# available audio files and add them to the daemon's online database. This
+# setting defaults to the XDG directory, otherwise the music directory will be
+# be disabled and audio files will only be accepted over ipc socket (using
+# file:// protocol) or streaming files over an accepted protocol.
+#
+music_directory "~/Music"
+#
+# This setting sets the MPD internal playlist directory. The purpose of this
+# directory is storage for playlists created by MPD. The server will use
+# playlist files not created by the server but only if they are in the MPD
+# format. This setting defaults to playlist saving being disabled.
+#
+playlist_directory "~/.config/mpd/playlists"
+#
+# This setting sets the location of the MPD database. This file is used to
+# load the database at server start up and store the database while the
+# server is not up. This setting defaults to disabled which will allow
+# MPD to accept files over ipc socket (using file:// protocol) or streaming
+# files over an accepted protocol.
+#
+db_file "~/.config/mpd/database"
+#
+# These settings are the locations for the daemon log files for the daemon.
+# These logs are great for troubleshooting, depending on your log_level
+# settings.
+#
+# The special value "syslog" makes MPD use the local syslog daemon. This
+# setting defaults to logging to syslog.
+#
+log_file "~/.config/mpd/log"
+#
+# This setting sets the location of the file which stores the process ID
+# for use of mpd --kill and some init scripts. This setting is disabled by
+# default and the pid file will not be stored.
+#
+pid_file "~/.config/mpd/pid"
+#
+# This setting sets the location of the file which contains information about
+# most variables to get MPD back into the same general shape it was in before
+# it was brought down. This setting is disabled by default and the server
+# state will be reset on server start up.
+#
+state_file "~/.config/mpd/state"
+#
+# The location of the sticker database. This is a database which
+# manages dynamic information attached to songs.
+#
+sticker_file "~/.config/mpd/sticker.sql"
+#
+###############################################################################
+
+
+# General music daemon options ################################################
+#
+# This setting specifies the user that MPD will run as. MPD should never run as
+# root and you may use this setting to make MPD change its user ID after
+# initialization. This setting is disabled by default and MPD is run as the
+# current user.
+#
+#user "nobody"
+#
+# This setting specifies the group that MPD will run as. If not specified
+# primary group of user specified with "user" setting will be used (if set).
+# This is useful if MPD needs to be a member of group such as "audio" to
+# have permission to use sound card.
+#
+#group "nogroup"
+#
+# This setting sets the address for the daemon to listen on. Careful attention
+# should be paid if this is assigned to anything other then the default, any.
+# This setting can deny access to control of the daemon. Not effective if
+# systemd socket activiation is in use.
+#
+# For network
+# bind_to_address "127.0.0.1"
+#
+# And for Unix Socket
+bind_to_address "~/.config/mpd/socket"
+#
+# This setting is the TCP port that is desired for the daemon to get assigned
+# to.
+#
+#port "6600"
+#
+# This setting controls the type of information which is logged. Available
+# setting arguments are "default", "secure" or "verbose". The "verbose" setting
+# argument is recommended for troubleshooting, though can quickly stretch
+# available resources on limited hardware storage.
+#
+log_level "default"
+#
+# Setting "restore_paused" to "yes" puts MPD into pause mode instead
+# of starting playback after startup.
+#
+restore_paused "yes"
+#
+# This setting enables MPD to create playlists in a format usable by other
+# music players.
+#
+save_absolute_paths_in_playlists "yes"
+#
+# This setting defines a list of tag types that will be extracted during the
+# audio file discovery process. The complete list of possible values can be
+# found in the user manual.
+metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
+#
+# This example just enables the "comment" tag without disabling all
+# the other supported tags:
+#metadata_to_use "+comment"
+#
+# This setting enables automatic update of MPD's database when files in
+# music_directory are changed.
+#
+auto_update "yes"
+#
+# Limit the depth of the directories being watched, 0 means only watch
+# the music directory itself. There is no limit by default.
+#
+auto_update_depth "0"
+#
+###############################################################################
+
+
+# Symbolic link behavior ######################################################
+#
+# If this setting is set to "yes", MPD will discover audio files by following
+# symbolic links outside of the configured music_directory.
+#
+follow_outside_symlinks "yes"
+#
+# If this setting is set to "yes", MPD will discover audio files by following
+# symbolic links inside of the configured music_directory.
+#
+#follow_inside_symlinks "yes"
+#
+###############################################################################
+
+
+# Zeroconf / Avahi Service Discovery ##########################################
+#
+# If this setting is set to "yes", service information will be published with
+# Zeroconf / Avahi.
+#
+#zeroconf_enabled "yes"
+#
+# The argument to this setting will be the Zeroconf / Avahi unique name for
+# this MPD server on the network. %h will be replaced with the hostname.
+#
+#zeroconf_name "Music Player @ %h"
+#
+###############################################################################
+
+
+# Permissions #################################################################
+#
+# If this setting is set, MPD will require password authorization. The password
+# setting can be specified multiple times for different password profiles.
+#
+#password "password@read,add,control,admin"
+#
+# This setting specifies the permissions a user has who has not yet logged in.
+#
+#default_permissions "read,add,control,admin"
+#
+###############################################################################
+
+
+# Database #######################################################################
+#
+
+#database {
+# plugin "proxy"
+# host "other.mpd.host"
+# port "6600"
+#}
+
+# Input #######################################################################
+#
+
+input {
+ plugin "curl"
+# proxy "proxy.isp.com:8080"
+# proxy_user "user"
+# proxy_password "password"
+}
+
+#
+###############################################################################
+
+# Audio Output ################################################################
+#
+# MPD supports various audio output types, as well as playing through multiple
+# audio outputs at the same time, through multiple audio_output settings
+# blocks. Setting this block is optional, though the server will only attempt
+# autodetection for one sound card.
+#
+# An example of an ALSA output:
+#
+#audio_output {
+# # type "alsa"
+# # name "Master"
+# # device "hw:2" # optional
+## mixer_type "hardware" # optional
+## mixer_device "default" # optional
+## mixer_control "PCM" # optional
+## mixer_index "0" # optional
+#}
+#
+# An example of an OSS output:
+#
+#audio_output {
+# type "oss"
+# name "My OSS Device"
+## device "/dev/dsp" # optional
+## mixer_type "hardware" # optional
+## mixer_device "/dev/mixer" # optional
+## mixer_control "PCM" # optional
+#}
+#
+# An example of a shout output (for streaming to Icecast):
+#
+#audio_output {
+# type "shout"
+# encoder "vorbis" # optional
+# name "My Shout Stream"
+# host "localhost"
+# port "8000"
+# mount "/mpd.ogg"
+# password "hackme"
+# quality "5.0"
+# bitrate "128"
+# format "44100:16:1"
+## protocol "icecast2" # optional
+## user "source" # optional
+## description "My Stream Description" # optional
+## url "http://example.com" # optional
+## genre "jazz" # optional
+## public "no" # optional
+## timeout "2" # optional
+## mixer_type "software" # optional
+#}
+#
+# An example of a recorder output:
+#
+#audio_output {
+# type "recorder"
+# name "My recorder"
+# encoder "vorbis" # optional, vorbis or lame
+# path "/var/lib/mpd/recorder/mpd.ogg"
+## quality "5.0" # do not define if bitrate is defined
+# bitrate "128" # do not define if quality is defined
+# format "44100:16:1"
+#}
+#
+# An example of a httpd output (built-in HTTP streaming server):
+#
+#audio_output {
+# type "httpd"
+# name "My HTTP Stream"
+# encoder "vorbis" # optional, vorbis or lame
+# port "8000"
+# bind_to_address "0.0.0.0" # optional, IPv4 or IPv6
+## quality "5.0" # do not define if bitrate is defined
+# bitrate "128" # do not define if quality is defined
+# format "44100:16:1"
+# max_clients "0" # optional 0=no limit
+#}
+#
+# An example of a pulseaudio output (streaming to a remote pulseaudio server)
+#
+audio_output {
+ type "pulse"
+ name "My Pulse Output"
+# server "remote_server" # optional
+# sink "remote_server_sink" # optional
+}
+
+audio_output {
+ type "fifo"
+ name "my_fifo"
+ path "/tmp/mpd.fifo"
+ format "44100:16:2"
+}
+#
+# An example of a winmm output (Windows multimedia API).
+#
+#audio_output {
+# type "winmm"
+# name "My WinMM output"
+## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
+# or
+## device "0" # optional
+## mixer_type "hardware" # optional
+#}
+#
+# An example of an openal output.
+#
+#audio_output {
+# type "openal"
+# name "My OpenAL output"
+## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
+#}
+#
+# An example of an sndio output.
+#
+#audio_output {
+# type "sndio"
+# name "sndio output"
+# mixer_type "hardware"
+#}
+#
+# An example of an OS X output:
+#
+#audio_output {
+# type "osx"
+# name "My OS X Device"
+## device "Built-in Output" # optional
+## channel_map "-1,-1,0,1" # optional
+#}
+#
+## Example "pipe" output:
+#
+#audio_output {
+# type "pipe"
+# name "my pipe"
+# command "aplay -f cd 2>/dev/null"
+## Or if you're want to use AudioCompress
+# command "AudioCompress -m | aplay -f cd 2>/dev/null"
+## Or to send raw PCM stream through PCM:
+# command "nc example.org 8765"
+# format "44100:16:2"
+#}
+#
+## An example of a null output (for no audio output):
+#
+#audio_output {
+# type "null"
+# name "My Null Output"
+# mixer_type "none" # optional
+#}
+#audio_output {
+# type "jack"
+# name "MPD"
+#}
+#
+###############################################################################
+
+
+# Normalization automatic volume adjustments ##################################
+#
+# This setting specifies the type of ReplayGain to use. This setting can have
+# the argument "off", "album", "track" or "auto". "auto" is a special mode that
+# chooses between "track" and "album" depending on the current state of
+# random playback. If random playback is enabled then "track" mode is used.
+# See <http://www.replaygain.org> for more details about ReplayGain.
+# This setting is off by default.
+#
+replaygain "auto"
+#
+# This setting sets the pre-amp used for files that have ReplayGain tags. By
+# default this setting is disabled.
+#
+replaygain_preamp "0"
+#
+# This setting sets the pre-amp used for files that do NOT have ReplayGain tags.
+# By default this setting is disabled.
+#
+replaygain_missing_preamp "0"
+#
+# This setting enables or disables ReplayGain limiting.
+# MPD calculates actual amplification based on the ReplayGain tags
+# and replaygain_preamp / replaygain_missing_preamp setting.
+# If replaygain_limit is enabled MPD will never amplify audio signal
+# above its original level. If replaygain_limit is disabled such amplification
+# might occur. By default this setting is enabled.
+#
+replaygain_limit "yes"
+#
+# This setting enables on-the-fly normalization volume adjustment. This will
+# result in the volume of all playing audio to be adjusted so the output has
+# equal "loudness". This setting is disabled by default.
+#
+volume_normalization "no"
+#
+###############################################################################
+
+# Character Encoding ##########################################################
+#
+# If file or directory names do not display correctly for your locale then you
+# may need to modify this setting.
+#
+#filesystem_charset "UTF-8"
+#
+###############################################################################
diff --git a/mpv/input.conf b/mpv/input.conf
new file mode 100644
index 0000000..d28ab28
--- /dev/null
+++ b/mpv/input.conf
@@ -0,0 +1,2 @@
+Ctrl+f script-binding quality_menu/video_formats_toggle
+Ctrl+a script-binding quality_menu/audio_formats_toggle
diff --git a/mpv/mpv.conf b/mpv/mpv.conf
new file mode 100644
index 0000000..63f8119
--- /dev/null
+++ b/mpv/mpv.conf
@@ -0,0 +1,5 @@
+save-position-on-quit
+osc=no
+ao=pulse
+vo=gpu
+audio-channels=2
diff --git a/mpv/script-opts/quality-menu.conf b/mpv/script-opts/quality-menu.conf
new file mode 100644
index 0000000..80ab845
--- /dev/null
+++ b/mpv/script-opts/quality-menu.conf
@@ -0,0 +1,95 @@
+# KEY BINDINGS
+
+# move the menu cursor up
+up_binding=UP WHEEL_UP
+# move the menu cursor down
+down_binding=DOWN WHEEL_DOWN
+# select menu entry
+select_binding=ENTER MBTN_LEFT
+# close menu
+close_menu_binding=ESC MBTN_RIGHT Ctrl+f Alt+f
+
+# youtube-dl version(could be youtube-dl or yt-dlp, or something else)
+ytdl_ver=yt-dlp
+
+# formatting / cursors
+selected_and_active=▶ -
+selected_and_inactive=● -
+unselected_and_active=▷ -
+unselected_and_inactive=○ -
+
+# font size scales by window, if false requires larger font and padding sizes
+scale_playlist_by_window=yes
+
+# playlist ass style overrides inside curly brackets, \keyvalue is one field, extra \ for escape in lua
+# example {\\fnUbuntu\\fs10\\b0\\bord1} equals: font=Ubuntu, size=10, bold=no, border=1
+# read http://docs.aegisub.org/3.2/ASS_Tags/ for reference of tags
+# undeclared tags will use default osd settings
+# these styles will be used for the whole playlist. More specific styling will need to be hacked in
+#
+# (a monospaced font is recommended but not required)
+style_ass_tags={\\fnmonospace\\fs10\\bord1}
+
+# paddings for top left corner
+text_padding_x=5
+text_padding_y=5
+
+# how many seconds until the quality menu times out
+# setting this to 0 deactivates the timeout
+menu_timeout=6
+
+# use youtube-dl to fetch a list of available formats (overrides quality_strings)
+fetch_formats=yes
+
+# list of ytdl-format strings to choose from
+quality_strings=[ {"4320p" : "bestvideo[height<=?4320p]+bestaudio/best"}, {"2160p" : "bestvideo[height<=?2160]+bestaudio/best"}, {"1440p" : "bestvideo[height<=?1440]+bestaudio/best"}, {"1080p" : "bestvideo[height<=?1080]+bestaudio/best"}, {"720p" : "bestvideo[height<=?720]+bestaudio/best"}, {"480p" : "bestvideo[height<=?480]+bestaudio/best"}, {"360p" : "bestvideo[height<=?360]+bestaudio/best"}, {"240p" : "bestvideo[height<=?240]+bestaudio/best"}, {"144p" : "bestvideo[height<=?144]+bestaudio/best"} ]
+
+# reset youtube-dl format to the original format string when changing files (e.g. going to the next playlist entry)
+# if file was opened previously, reset to previously selected format
+reset_format=yes
+
+# automatically fetch available formats when opening an url
+fetch_on_start=yes
+
+# show the video format menu after opening an url
+start_with_menu=no
+
+# include unknown formats in the list
+# Unfortunately choosing which formats are video or audio is not always perfect.
+# Set to true to make sure you don't miss any formats, but then the list
+# might also include formats that aren't actually video or audio.
+# Formats that are known to not be video or audio are still filtered out.
+include_unknown=no
+
+# hide columns that are identical for all formats
+hide_identical_columns=yes
+
+# which columns are shown in which order
+# comma separated list, prefix column with "-" to align left
+#
+# columns that might be useful are:
+# resolution, width, height, fps, dynamic_range, tbr, vbr, abr, asr,
+# filesize, filesize_approx, vcodec, acodec, ext, video_ext, audio_ext,
+# language, format, format_note, quality
+#
+# columns that are derived from the above, but with special treatment:
+# frame_rate, bitrate_total, bitrate_video, bitrate_audio,
+# codec_video, codec_audio, audio_sample_rate
+#
+# If those still aren't enough or you're just curious, run:
+# yt-dlp -j <url>
+# This outputs unformatted JSON.
+# Format it and look under "formats" to see what's available.
+#
+# Not all videos have all columns available.
+# Be careful, misspelled columns simply won't be displayed, there is no error.
+columns_video=-resolution,frame_rate,dynamic_range,language,bitrate_total,size,-codec_video,-codec_audio
+columns_audio=audio_sample_rate,bitrate_total,size,language,-codec_audio
+
+# columns used for sorting, see "columns_video" for available columns
+# comma separated list, prefix column with "-" to reverse sorting order
+# Leaving this empty keeps the order from yt-dlp/youtube-dl.
+# Be careful, misspelled columns won't result in an error,
+# but they might influence the result.
+sort_video=height,fps,tbr,size,format_id
+sort_audio=asr,tbr,size,format_id
diff --git a/mpv/script-opts/youtube-download.conf b/mpv/script-opts/youtube-download.conf
new file mode 100644
index 0000000..33630bf
--- /dev/null
+++ b/mpv/script-opts/youtube-download.conf
@@ -0,0 +1,48 @@
+# KEY BINDINGS
+download_video_binding=ctrl+d
+download_audio_binding=ctrl+a
+#download_subtitle_binding=ctrl+s
+#download_video_embed_subtitle_binding=ctrl+i
+#select_range_binding=ctrl+r
+
+# Specify audio format: "best", "aac","flac", "mp3", "m4a", "opus", "vorbis", or "wav"
+audio_format=best
+
+# Specify ffmpeg/avconv audio quality
+# insert a value between 0 (better) and 9 (worse) for VBR or a specific bitrate like 128K
+audio_quality=0
+
+# Same as youtube-dl --format FORMAT
+# see https://github.com/ytdl-org/youtube-dl/blob/master/README.md#format-selection
+# set to "current" to download the same quality that is currently playing
+video_format=best
+
+# Encode the video to another format if necessary (currently supported: mp4|flv|ogg|webm|mkv|avi)
+# recode_video="mp4"
+
+# Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames
+restrict_filenames=yes
+
+# Download the whole playlist (no) or only one video (yes)
+# Same as youtube-dl --no-playlist
+no_playlist=yes
+
+# Use an archive file, see youtube-dl --download-archive
+# You have these options:
+# * Set to empty string "" to not use an archive file
+# * Set an absolute path to use one archive for all downloads e.g. download_archive="/home/user/archive.txt"
+# * Set a relative path/only a filename to use one archive per directory e.g. download_archive="archive.txt"
+# * Use $PLAYLIST to create one archive per playlist e.g. download_archive="/home/user/archives/$PLAYLIST.txt"
+download_archive=~/Videos/archive/archive.txt
+
+# Filename or full path
+# Same youtube-dl -o
+# see https://github.com/ytdl-org/youtube-dl/blob/master/README.md#output-template
+filename=~/Videos/%(title)s.%(ext)s
+
+# Use a cookies file for youtube-dl
+# Same as youtube-dl --cookies
+#cookies=C:\Users\username\cookies.txt
+
+# Write download errors to a log file
+log_file=~/.config/mpv/download.log
diff --git a/mpv/scripts/quality-menu-osc.lua b/mpv/scripts/quality-menu-osc.lua
new file mode 100644
index 0000000..0a2f6c2
--- /dev/null
+++ b/mpv/scripts/quality-menu-osc.lua
@@ -0,0 +1,2911 @@
+local assdraw = require 'mp.assdraw'
+local msg = require 'mp.msg'
+local opt = require 'mp.options'
+local utils = require 'mp.utils'
+
+--
+-- Parameters
+--
+-- default user option values
+-- do not touch, change them in osc.conf
+local user_opts = {
+ showwindowed = true, -- show OSC when windowed?
+ showfullscreen = true, -- show OSC when fullscreen?
+ idlescreen = true, -- show mpv logo on idle
+ scalewindowed = 1, -- scaling of the controller when windowed
+ scalefullscreen = 1, -- scaling of the controller when fullscreen
+ scaleforcedwindow = 2, -- scaling when rendered on a forced window
+ vidscale = true, -- scale the controller with the video?
+ valign = 0.8, -- vertical alignment, -1 (top) to 1 (bottom)
+ halign = 0, -- horizontal alignment, -1 (left) to 1 (right)
+ barmargin = 0, -- vertical margin of top/bottombar
+ boxalpha = 80, -- alpha of the background box,
+ -- 0 (opaque) to 255 (fully transparent)
+ hidetimeout = 500, -- duration in ms until the OSC hides if no
+ -- mouse movement. enforced non-negative for the
+ -- user, but internally negative is "always-on".
+ fadeduration = 200, -- duration of fade out in ms, 0 = no fade
+ deadzonesize = 0.5, -- size of deadzone
+ minmousemove = 0, -- minimum amount of pixels the mouse has to
+ -- move between ticks to make the OSC show up
+ iamaprogrammer = false, -- use native mpv values and disable OSC
+ -- internal track list management (and some
+ -- functions that depend on it)
+ layout = "bottombar",
+ seekbarstyle = "bar", -- bar, diamond or knob
+ seekbarhandlesize = 0.6, -- size ratio of the diamond and knob handle
+ seekrangestyle = "inverted",-- bar, line, slider, inverted or none
+ seekrangeseparate = true, -- whether the seekranges overlay on the bar-style seekbar
+ seekrangealpha = 200, -- transparency of seekranges
+ seekbarkeyframes = true, -- use keyframes when dragging the seekbar
+ title = "${media-title}", -- string compatible with property-expansion
+ -- to be shown as OSC title
+ tooltipborder = 1, -- border of tooltip in bottom/topbar
+ timetotal = false, -- display total time instead of remaining time?
+ timems = false, -- display timecodes with milliseconds?
+ tcspace = 100, -- timecode spacing (compensate font size estimation)
+ visibility = "auto", -- only used at init to set visibility_mode(...)
+ boxmaxchars = 80, -- title crop threshold for box layout
+ boxvideo = false, -- apply osc_param.video_margins to video
+ windowcontrols = "auto", -- whether to show window controls
+ windowcontrols_alignment = "right", -- which side to show window controls on
+ greenandgrumpy = false, -- disable santa hat
+ livemarkers = true, -- update seekbar chapter markers on duration change
+ chapters_osd = true, -- whether to show chapters OSD on next/prev
+ playlist_osd = true, -- whether to show playlist OSD on next/prev
+ chapter_fmt = "Chapter: %s", -- chapter print format for seekbar-hover. "no" to disable
+ unicodeminus = false, -- whether to use the Unicode minus sign character
+}
+
+-- read options from config and command-line
+opt.read_options(user_opts, "osc", function(list) update_options(list) end)
+
+local osc_param = { -- calculated by osc_init()
+ playresy = 0, -- canvas size Y
+ playresx = 0, -- canvas size X
+ display_aspect = 1,
+ unscaled_y = 0,
+ areas = {},
+ video_margins = {
+ l = 0, r = 0, t = 0, b = 0, -- left/right/top/bottom
+ },
+}
+
+local osc_styles = {
+ bigButtons = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs50\\fnmpv-osd-symbols}",
+ smallButtonsL = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs19\\fnmpv-osd-symbols}",
+ smallButtonsLlabel = "{\\fscx105\\fscy105\\fn" .. mp.get_property("options/osd-font") .. "}",
+ smallButtonsR = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs30\\fnmpv-osd-symbols}",
+ topButtons = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs12\\fnmpv-osd-symbols}",
+
+ elementDown = "{\\1c&H999999}",
+ timecodes = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs20}",
+ vidtitle = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs12\\q2}",
+ box = "{\\rDefault\\blur0\\bord1\\1c&H000000\\3c&HFFFFFF}",
+
+ topButtonsBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs18\\fnmpv-osd-symbols}",
+ smallButtonsBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs28\\fnmpv-osd-symbols}",
+ timecodesBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs27}",
+ timePosBar = "{\\blur0\\bord".. user_opts.tooltipborder .."\\1c&HFFFFFF\\3c&H000000\\fs30}",
+ vidtitleBar = "{\\blur0\\bord0\\1c&HFFFFFF\\3c&HFFFFFF\\fs18\\q2}",
+
+ wcButtons = "{\\1c&HFFFFFF\\fs24\\fnmpv-osd-symbols}",
+ wcTitle = "{\\1c&HFFFFFF\\fs24\\q2}",
+ wcBar = "{\\1c&H000000}",
+}
+
+-- internal states, do not touch
+local state = {
+ showtime, -- time of last invocation (last mouse move)
+ osc_visible = false,
+ anistart, -- time when the animation started
+ anitype, -- current type of animation
+ animation, -- current animation alpha
+ mouse_down_counter = 0, -- used for softrepeat
+ active_element = nil, -- nil = none, 0 = background, 1+ = see elements[]
+ active_event_source = nil, -- the "button" that issued the current event
+ rightTC_trem = not user_opts.timetotal, -- if the right timecode should display total or remaining time
+ tc_ms = user_opts.timems, -- Should the timecodes display their time with milliseconds
+ mp_screen_sizeX, mp_screen_sizeY, -- last screen-resolution, to detect resolution changes to issue reINITs
+ initREQ = false, -- is a re-init request pending?
+ marginsREQ = false, -- is a margins update pending?
+ last_mouseX, last_mouseY, -- last mouse position, to detect significant mouse movement
+ mouse_in_window = false,
+ message_text,
+ message_hide_timer,
+ fullscreen = false,
+ tick_timer = nil,
+ tick_last_time = 0, -- when the last tick() was run
+ hide_timer = nil,
+ cache_state = nil,
+ idle = false,
+ enabled = true,
+ input_enabled = true,
+ showhide_enabled = false,
+ dmx_cache = 0,
+ using_video_margins = false,
+ border = true,
+ maximized = false,
+ osd = mp.create_osd_overlay("ass-events"),
+ chapter_list = {}, -- sorted by time
+}
+
+local window_control_box_width = 80
+local tick_delay = 0.03
+
+local is_december = os.date("*t").month == 12
+
+--
+-- Helperfunctions
+--
+
+function kill_animation()
+ state.anistart = nil
+ state.animation = nil
+ state.anitype = nil
+end
+
+function set_osd(res_x, res_y, text)
+ if state.osd.res_x == res_x and
+ state.osd.res_y == res_y and
+ state.osd.data == text then
+ return
+ end
+ state.osd.res_x = res_x
+ state.osd.res_y = res_y
+ state.osd.data = text
+ state.osd.z = 1000
+ state.osd:update()
+end
+
+local margins_opts = {
+ {"l", "video-margin-ratio-left"},
+ {"r", "video-margin-ratio-right"},
+ {"t", "video-margin-ratio-top"},
+ {"b", "video-margin-ratio-bottom"},
+}
+
+-- scale factor for translating between real and virtual ASS coordinates
+function get_virt_scale_factor()
+ local w, h = mp.get_osd_size()
+ if w <= 0 or h <= 0 then
+ return 0, 0
+ end
+ return osc_param.playresx / w, osc_param.playresy / h
+end
+
+-- return mouse position in virtual ASS coordinates (playresx/y)
+function get_virt_mouse_pos()
+ if state.mouse_in_window then
+ local sx, sy = get_virt_scale_factor()
+ local x, y = mp.get_mouse_pos()
+ return x * sx, y * sy
+ else
+ return -1, -1
+ end
+end
+
+function set_virt_mouse_area(x0, y0, x1, y1, name)
+ local sx, sy = get_virt_scale_factor()
+ mp.set_mouse_area(x0 / sx, y0 / sy, x1 / sx, y1 / sy, name)
+end
+
+function scale_value(x0, x1, y0, y1, val)
+ local m = (y1 - y0) / (x1 - x0)
+ local b = y0 - (m * x0)
+ return (m * val) + b
+end
+
+-- returns hitbox spanning coordinates (top left, bottom right corner)
+-- according to alignment
+function get_hitbox_coords(x, y, an, w, h)
+
+ local alignments = {
+ [1] = function () return x, y-h, x+w, y end,
+ [2] = function () return x-(w/2), y-h, x+(w/2), y end,
+ [3] = function () return x-w, y-h, x, y end,
+
+ [4] = function () return x, y-(h/2), x+w, y+(h/2) end,
+ [5] = function () return x-(w/2), y-(h/2), x+(w/2), y+(h/2) end,
+ [6] = function () return x-w, y-(h/2), x, y+(h/2) end,
+
+ [7] = function () return x, y, x+w, y+h end,
+ [8] = function () return x-(w/2), y, x+(w/2), y+h end,
+ [9] = function () return x-w, y, x, y+h end,
+ }
+
+ return alignments[an]()
+end
+
+function get_hitbox_coords_geo(geometry)
+ return get_hitbox_coords(geometry.x, geometry.y, geometry.an,
+ geometry.w, geometry.h)
+end
+
+function get_element_hitbox(element)
+ return element.hitbox.x1, element.hitbox.y1,
+ element.hitbox.x2, element.hitbox.y2
+end
+
+function mouse_hit(element)
+ return mouse_hit_coords(get_element_hitbox(element))
+end
+
+function mouse_hit_coords(bX1, bY1, bX2, bY2)
+ local mX, mY = get_virt_mouse_pos()
+ return (mX >= bX1 and mX <= bX2 and mY >= bY1 and mY <= bY2)
+end
+
+function limit_range(min, max, val)
+ if val > max then
+ val = max
+ elseif val < min then
+ val = min
+ end
+ return val
+end
+
+-- translate value into element coordinates
+function get_slider_ele_pos_for(element, val)
+
+ local ele_pos = scale_value(
+ element.slider.min.value, element.slider.max.value,
+ element.slider.min.ele_pos, element.slider.max.ele_pos,
+ val)
+
+ return limit_range(
+ element.slider.min.ele_pos, element.slider.max.ele_pos,
+ ele_pos)
+end
+
+-- translates global (mouse) coordinates to value
+function get_slider_value_at(element, glob_pos)
+
+ local val = scale_value(
+ element.slider.min.glob_pos, element.slider.max.glob_pos,
+ element.slider.min.value, element.slider.max.value,
+ glob_pos)
+
+ return limit_range(
+ element.slider.min.value, element.slider.max.value,
+ val)
+end
+
+-- get value at current mouse position
+function get_slider_value(element)
+ return get_slider_value_at(element, get_virt_mouse_pos())
+end
+
+function countone(val)
+ if not (user_opts.iamaprogrammer) then
+ val = val + 1
+ end
+ return val
+end
+
+-- align: -1 .. +1
+-- frame: size of the containing area
+-- obj: size of the object that should be positioned inside the area
+-- margin: min. distance from object to frame (as long as -1 <= align <= +1)
+function get_align(align, frame, obj, margin)
+ return (frame / 2) + (((frame / 2) - margin - (obj / 2)) * align)
+end
+
+-- multiplies two alpha values, formular can probably be improved
+function mult_alpha(alphaA, alphaB)
+ return 255 - (((1-(alphaA/255)) * (1-(alphaB/255))) * 255)
+end
+
+function add_area(name, x1, y1, x2, y2)
+ -- create area if needed
+ if (osc_param.areas[name] == nil) then
+ osc_param.areas[name] = {}
+ end
+ table.insert(osc_param.areas[name], {x1=x1, y1=y1, x2=x2, y2=y2})
+end
+
+function ass_append_alpha(ass, alpha, modifier)
+ local ar = {}
+
+ for ai, av in pairs(alpha) do
+ av = mult_alpha(av, modifier)
+ if state.animation then
+ av = mult_alpha(av, state.animation)
+ end
+ ar[ai] = av
+ end
+
+ ass:append(string.format("{\\1a&H%X&\\2a&H%X&\\3a&H%X&\\4a&H%X&}",
+ ar[1], ar[2], ar[3], ar[4]))
+end
+
+function ass_draw_rr_h_cw(ass, x0, y0, x1, y1, r1, hexagon, r2)
+ if hexagon then
+ ass:hexagon_cw(x0, y0, x1, y1, r1, r2)
+ else
+ ass:round_rect_cw(x0, y0, x1, y1, r1, r2)
+ end
+end
+
+function ass_draw_rr_h_ccw(ass, x0, y0, x1, y1, r1, hexagon, r2)
+ if hexagon then
+ ass:hexagon_ccw(x0, y0, x1, y1, r1, r2)
+ else
+ ass:round_rect_ccw(x0, y0, x1, y1, r1, r2)
+ end
+end
+
+
+--
+-- Tracklist Management
+--
+
+local nicetypes = {video = "Video", audio = "Audio", sub = "Subtitle"}
+
+-- updates the OSC internal playlists, should be run each time the track-layout changes
+function update_tracklist()
+ local tracktable = mp.get_property_native("track-list", {})
+
+ -- by osc_id
+ tracks_osc = {}
+ tracks_osc.video, tracks_osc.audio, tracks_osc.sub = {}, {}, {}
+ -- by mpv_id
+ tracks_mpv = {}
+ tracks_mpv.video, tracks_mpv.audio, tracks_mpv.sub = {}, {}, {}
+ for n = 1, #tracktable do
+ if not (tracktable[n].type == "unknown") then
+ local type = tracktable[n].type
+ local mpv_id = tonumber(tracktable[n].id)
+
+ -- by osc_id
+ table.insert(tracks_osc[type], tracktable[n])
+
+ -- by mpv_id
+ tracks_mpv[type][mpv_id] = tracktable[n]
+ tracks_mpv[type][mpv_id].osc_id = #tracks_osc[type]
+ end
+ end
+end
+
+-- return a nice list of tracks of the given type (video, audio, sub)
+function get_tracklist(type)
+ local msg = "Available " .. nicetypes[type] .. " Tracks: "
+ if not tracks_osc or #tracks_osc[type] == 0 then
+ msg = msg .. "none"
+ else
+ for n = 1, #tracks_osc[type] do
+ local track = tracks_osc[type][n]
+ local lang, title, selected = "unknown", "", "○"
+ if not(track.lang == nil) then lang = track.lang end
+ if not(track.title == nil) then title = track.title end
+ if (track.id == tonumber(mp.get_property(type))) then
+ selected = "●"
+ end
+ msg = msg.."\n"..selected.." "..n..": ["..lang.."] "..title
+ end
+ end
+ return msg
+end
+
+-- relatively change the track of given <type> by <next> tracks
+ --(+1 -> next, -1 -> previous)
+function set_track(type, next)
+ local current_track_mpv, current_track_osc
+ if (mp.get_property(type) == "no") then
+ current_track_osc = 0
+ else
+ current_track_mpv = tonumber(mp.get_property(type))
+ current_track_osc = tracks_mpv[type][current_track_mpv].osc_id
+ end
+ local new_track_osc = (current_track_osc + next) % (#tracks_osc[type] + 1)
+ local new_track_mpv
+ if new_track_osc == 0 then
+ new_track_mpv = "no"
+ else
+ new_track_mpv = tracks_osc[type][new_track_osc].id
+ end
+
+ mp.commandv("set", type, new_track_mpv)
+
+ if (new_track_osc == 0) then
+ show_message(nicetypes[type] .. " Track: none")
+ else
+ show_message(nicetypes[type] .. " Track: "
+ .. new_track_osc .. "/" .. #tracks_osc[type]
+ .. " [".. (tracks_osc[type][new_track_osc].lang or "unknown") .."] "
+ .. (tracks_osc[type][new_track_osc].title or ""))
+ end
+end
+
+-- get the currently selected track of <type>, OSC-style counted
+function get_track(type)
+ local track = mp.get_property(type)
+ if track ~= "no" and track ~= nil then
+ local tr = tracks_mpv[type][tonumber(track)]
+ if tr then
+ return tr.osc_id
+ end
+ end
+ return 0
+end
+
+-- WindowControl helpers
+function window_controls_enabled()
+ val = user_opts.windowcontrols
+ if val == "auto" then
+ return not state.border
+ else
+ return val ~= "no"
+ end
+end
+
+function window_controls_alignment()
+ return user_opts.windowcontrols_alignment
+end
+
+--
+-- Element Management
+--
+
+local elements = {}
+
+function prepare_elements()
+
+ -- remove elements without layout or invisble
+ local elements2 = {}
+ for n, element in pairs(elements) do
+ if not (element.layout == nil) and (element.visible) then
+ table.insert(elements2, element)
+ end
+ end
+ elements = elements2
+
+ function elem_compare (a, b)
+ return a.layout.layer < b.layout.layer
+ end
+
+ table.sort(elements, elem_compare)
+
+
+ for _,element in pairs(elements) do
+
+ local elem_geo = element.layout.geometry
+
+ -- Calculate the hitbox
+ local bX1, bY1, bX2, bY2 = get_hitbox_coords_geo(elem_geo)
+ element.hitbox = {x1 = bX1, y1 = bY1, x2 = bX2, y2 = bY2}
+
+ local style_ass = assdraw.ass_new()
+
+ -- prepare static elements
+ style_ass:append("{}") -- hack to troll new_event into inserting a \n
+ style_ass:new_event()
+ style_ass:pos(elem_geo.x, elem_geo.y)
+ style_ass:an(elem_geo.an)
+ style_ass:append(element.layout.style)
+
+ element.style_ass = style_ass
+
+ local static_ass = assdraw.ass_new()
+
+
+ if (element.type == "box") then
+ --draw box
+ static_ass:draw_start()
+ ass_draw_rr_h_cw(static_ass, 0, 0, elem_geo.w, elem_geo.h,
+ element.layout.box.radius, element.layout.box.hexagon)
+ static_ass:draw_stop()
+
+ elseif (element.type == "slider") then
+ --draw static slider parts
+
+ local r1 = 0
+ local r2 = 0
+ local slider_lo = element.layout.slider
+ -- offset between element outline and drag-area
+ local foV = slider_lo.border + slider_lo.gap
+
+ -- calculate positions of min and max points
+ if (slider_lo.stype ~= "bar") then
+ r1 = elem_geo.h / 2
+ element.slider.min.ele_pos = elem_geo.h / 2
+ element.slider.max.ele_pos = elem_geo.w - (elem_geo.h / 2)
+ if (slider_lo.stype == "diamond") then
+ r2 = (elem_geo.h - 2 * slider_lo.border) / 2
+ elseif (slider_lo.stype == "knob") then
+ r2 = r1
+ end
+ else
+ element.slider.min.ele_pos =
+ slider_lo.border + slider_lo.gap
+ element.slider.max.ele_pos =
+ elem_geo.w - (slider_lo.border + slider_lo.gap)
+ end
+
+ element.slider.min.glob_pos =
+ element.hitbox.x1 + element.slider.min.ele_pos
+ element.slider.max.glob_pos =
+ element.hitbox.x1 + element.slider.max.ele_pos
+
+ -- -- --
+
+ static_ass:draw_start()
+
+ -- the box
+ ass_draw_rr_h_cw(static_ass, 0, 0, elem_geo.w, elem_geo.h, r1, slider_lo.stype == "diamond")
+
+ -- the "hole"
+ ass_draw_rr_h_ccw(static_ass, slider_lo.border, slider_lo.border,
+ elem_geo.w - slider_lo.border, elem_geo.h - slider_lo.border,
+ r2, slider_lo.stype == "diamond")
+
+ -- marker nibbles
+ if not (element.slider.markerF == nil) and (slider_lo.gap > 0) then
+ local markers = element.slider.markerF()
+ for _,marker in pairs(markers) do
+ if (marker > element.slider.min.value) and
+ (marker < element.slider.max.value) then
+
+ local s = get_slider_ele_pos_for(element, marker)
+
+ if (slider_lo.gap > 1) then -- draw triangles
+
+ local a = slider_lo.gap / 0.5 --0.866
+
+ --top
+ if (slider_lo.nibbles_top) then
+ static_ass:move_to(s - (a/2), slider_lo.border)
+ static_ass:line_to(s + (a/2), slider_lo.border)
+ static_ass:line_to(s, foV)
+ end
+
+ --bottom
+ if (slider_lo.nibbles_bottom) then
+ static_ass:move_to(s - (a/2),
+ elem_geo.h - slider_lo.border)
+ static_ass:line_to(s,
+ elem_geo.h - foV)
+ static_ass:line_to(s + (a/2),
+ elem_geo.h - slider_lo.border)
+ end
+
+ else -- draw 2x1px nibbles
+
+ --top
+ if (slider_lo.nibbles_top) then
+ static_ass:rect_cw(s - 1, slider_lo.border,
+ s + 1, slider_lo.border + slider_lo.gap);
+ end
+
+ --bottom
+ if (slider_lo.nibbles_bottom) then
+ static_ass:rect_cw(s - 1,
+ elem_geo.h -slider_lo.border -slider_lo.gap,
+ s + 1, elem_geo.h - slider_lo.border);
+ end
+ end
+ end
+ end
+ end
+ end
+
+ element.static_ass = static_ass
+
+
+ -- if the element is supposed to be disabled,
+ -- style it accordingly and kill the eventresponders
+ if not (element.enabled) then
+ element.layout.alpha[1] = 136
+ element.eventresponder = nil
+ end
+ end
+end
+
+
+--
+-- Element Rendering
+--
+
+-- returns nil or a chapter element from the native property chapter-list
+function get_chapter(possec)
+ local cl = state.chapter_list -- sorted, get latest before possec, if any
+
+ for n=#cl,1,-1 do
+ if possec >= cl[n].time then
+ return cl[n]
+ end
+ end
+end
+
+function render_elements(master_ass)
+
+ -- when the slider is dragged or hovered and we have a target chapter name
+ -- then we use it instead of the normal title. we calculate it before the
+ -- render iterations because the title may be rendered before the slider.
+ state.forced_title = nil
+ local se, ae = state.slider_element, elements[state.active_element]
+ if user_opts.chapter_fmt ~= "no" and se and (ae == se or (not ae and mouse_hit(se))) then
+ local dur = mp.get_property_number("duration", 0)
+ if dur > 0 then
+ local possec = get_slider_value(se) * dur / 100 -- of mouse pos
+ local ch = get_chapter(possec)
+ if ch and ch.title and ch.title ~= "" then
+ state.forced_title = string.format(user_opts.chapter_fmt, ch.title)
+ end
+ end
+ end
+
+ for n=1, #elements do
+ local element = elements[n]
+
+ local style_ass = assdraw.ass_new()
+ style_ass:merge(element.style_ass)
+ ass_append_alpha(style_ass, element.layout.alpha, 0)
+
+ if element.eventresponder and (state.active_element == n) then
+
+ -- run render event functions
+ if not (element.eventresponder.render == nil) then
+ element.eventresponder.render(element)
+ end
+
+ if mouse_hit(element) then
+ -- mouse down styling
+ if (element.styledown) then
+ style_ass:append(osc_styles.elementDown)
+ end
+
+ if (element.softrepeat) and (state.mouse_down_counter >= 15
+ and state.mouse_down_counter % 5 == 0) then
+
+ element.eventresponder[state.active_event_source.."_down"](element)
+ end
+ state.mouse_down_counter = state.mouse_down_counter + 1
+ end
+
+ end
+
+ local elem_ass = assdraw.ass_new()
+
+ elem_ass:merge(style_ass)
+
+ if not (element.type == "button") then
+ elem_ass:merge(element.static_ass)
+ end
+
+ if (element.type == "slider") then
+
+ local slider_lo = element.layout.slider
+ local elem_geo = element.layout.geometry
+ local s_min = element.slider.min.value
+ local s_max = element.slider.max.value
+
+ -- draw pos marker
+ local foH, xp
+ local pos = element.slider.posF()
+ local foV = slider_lo.border + slider_lo.gap
+ local innerH = elem_geo.h - (2 * foV)
+ local seekRanges = element.slider.seekRangesF()
+ local seekRangeLineHeight = innerH / 5
+
+ if slider_lo.stype ~= "bar" then
+ foH = elem_geo.h / 2
+ else
+ foH = slider_lo.border + slider_lo.gap
+ end
+
+ if pos then
+ xp = get_slider_ele_pos_for(element, pos)
+
+ if slider_lo.stype ~= "bar" then
+ local r = (user_opts.seekbarhandlesize * innerH) / 2
+ ass_draw_rr_h_cw(elem_ass, xp - r, foH - r,
+ xp + r, foH + r,
+ r, slider_lo.stype == "diamond")
+ else
+ local h = 0
+ if seekRanges and user_opts.seekrangeseparate and slider_lo.rtype ~= "inverted" then
+ h = seekRangeLineHeight
+ end
+ elem_ass:rect_cw(foH, foV, xp, elem_geo.h - foV - h)
+
+ if seekRanges and not user_opts.seekrangeseparate and slider_lo.rtype ~= "inverted" then
+ -- Punch holes for the seekRanges to be drawn later
+ for _,range in pairs(seekRanges) do
+ if range["start"] < pos then
+ local pstart = get_slider_ele_pos_for(element, range["start"])
+ local pend = xp
+
+ if pos > range["end"] then
+ pend = get_slider_ele_pos_for(element, range["end"])
+ end
+ elem_ass:rect_ccw(pstart, elem_geo.h - foV - seekRangeLineHeight, pend, elem_geo.h - foV)
+ end
+ end
+ end
+ end
+
+ if slider_lo.rtype == "slider" then
+ ass_draw_rr_h_cw(elem_ass, foH - innerH / 6, foH - innerH / 6,
+ xp, foH + innerH / 6,
+ innerH / 6, slider_lo.stype == "diamond", 0)
+ ass_draw_rr_h_cw(elem_ass, xp, foH - innerH / 15,
+ elem_geo.w - foH + innerH / 15, foH + innerH / 15,
+ 0, slider_lo.stype == "diamond", innerH / 15)
+ for _,range in pairs(seekRanges or {}) do
+ local pstart = get_slider_ele_pos_for(element, range["start"])
+ local pend = get_slider_ele_pos_for(element, range["end"])
+ ass_draw_rr_h_ccw(elem_ass, pstart, foH - innerH / 21,
+ pend, foH + innerH / 21,
+ innerH / 21, slider_lo.stype == "diamond")
+ end
+ end
+ end
+
+ if seekRanges then
+ if slider_lo.rtype ~= "inverted" then
+ elem_ass:draw_stop()
+ elem_ass:merge(element.style_ass)
+ ass_append_alpha(elem_ass, element.layout.alpha, user_opts.seekrangealpha)
+ elem_ass:merge(element.static_ass)
+ end
+
+ for _,range in pairs(seekRanges) do
+ local pstart = get_slider_ele_pos_for(element, range["start"])
+ local pend = get_slider_ele_pos_for(element, range["end"])
+
+ if slider_lo.rtype == "slider" then
+ ass_draw_rr_h_cw(elem_ass, pstart, foH - innerH / 21,
+ pend, foH + innerH / 21,
+ innerH / 21, slider_lo.stype == "diamond")
+ elseif slider_lo.rtype == "line" then
+ if slider_lo.stype == "bar" then
+ elem_ass:rect_cw(pstart, elem_geo.h - foV - seekRangeLineHeight, pend, elem_geo.h - foV)
+ else
+ ass_draw_rr_h_cw(elem_ass, pstart - innerH / 8, foH - innerH / 8,
+ pend + innerH / 8, foH + innerH / 8,
+ innerH / 8, slider_lo.stype == "diamond")
+ end
+ elseif slider_lo.rtype == "bar" then
+ if slider_lo.stype ~= "bar" then
+ ass_draw_rr_h_cw(elem_ass, pstart - innerH / 2, foV,
+ pend + innerH / 2, foV + innerH,
+ innerH / 2, slider_lo.stype == "diamond")
+ elseif range["end"] >= (pos or 0) then
+ elem_ass:rect_cw(pstart, foV, pend, elem_geo.h - foV)
+ else
+ elem_ass:rect_cw(pstart, elem_geo.h - foV - seekRangeLineHeight, pend, elem_geo.h - foV)
+ end
+ elseif slider_lo.rtype == "inverted" then
+ if slider_lo.stype ~= "bar" then
+ ass_draw_rr_h_ccw(elem_ass, pstart, (elem_geo.h / 2) - 1, pend,
+ (elem_geo.h / 2) + 1,
+ 1, slider_lo.stype == "diamond")
+ else
+ elem_ass:rect_ccw(pstart, (elem_geo.h / 2) - 1, pend, (elem_geo.h / 2) + 1)
+ end
+ end
+ end
+ end
+
+ elem_ass:draw_stop()
+
+ -- add tooltip
+ if not (element.slider.tooltipF == nil) then
+
+ if mouse_hit(element) then
+ local sliderpos = get_slider_value(element)
+ local tooltiplabel = element.slider.tooltipF(sliderpos)
+
+ local an = slider_lo.tooltip_an
+
+ local ty
+
+ if (an == 2) then
+ ty = element.hitbox.y1 - slider_lo.border
+ else
+ ty = element.hitbox.y1 + elem_geo.h/2
+ end
+
+ local tx = get_virt_mouse_pos()
+ if (slider_lo.adjust_tooltip) then
+ if (an == 2) then
+ if (sliderpos < (s_min + 3)) then
+ an = an - 1
+ elseif (sliderpos > (s_max - 3)) then
+ an = an + 1
+ end
+ elseif (sliderpos > (s_max-s_min)/2) then
+ an = an + 1
+ tx = tx - 5
+ else
+ an = an - 1
+ tx = tx + 10
+ end
+ end
+
+ -- tooltip label
+ elem_ass:new_event()
+ elem_ass:pos(tx, ty)
+ elem_ass:an(an)
+ elem_ass:append(slider_lo.tooltip_style)
+ ass_append_alpha(elem_ass, slider_lo.alpha, 0)
+ elem_ass:append(tooltiplabel)
+
+ end
+ end
+
+ elseif (element.type == "button") then
+
+ local buttontext
+ if type(element.content) == "function" then
+ buttontext = element.content() -- function objects
+ elseif not (element.content == nil) then
+ buttontext = element.content -- text objects
+ end
+
+ local maxchars = element.layout.button.maxchars
+ if not (maxchars == nil) and (#buttontext > maxchars) then
+ local max_ratio = 1.25 -- up to 25% more chars while shrinking
+ local limit = math.max(0, math.floor(maxchars * max_ratio) - 3)
+ if (#buttontext > limit) then
+ while (#buttontext > limit) do
+ buttontext = buttontext:gsub(".[\128-\191]*$", "")
+ end
+ buttontext = buttontext .. "..."
+ end
+ local _, nchars2 = buttontext:gsub(".[\128-\191]*", "")
+ local stretch = (maxchars/#buttontext)*100
+ buttontext = string.format("{\\fscx%f}",
+ (maxchars/#buttontext)*100) .. buttontext
+ end
+
+ elem_ass:append(buttontext)
+ end
+
+ master_ass:merge(elem_ass)
+ end
+end
+
+--
+-- Message display
+--
+
+-- pos is 1 based
+function limited_list(prop, pos)
+ local proplist = mp.get_property_native(prop, {})
+ local count = #proplist
+ if count == 0 then
+ return count, proplist
+ end
+
+ local fs = tonumber(mp.get_property('options/osd-font-size'))
+ local max = math.ceil(osc_param.unscaled_y*0.75 / fs)
+ if max % 2 == 0 then
+ max = max - 1
+ end
+ local delta = math.ceil(max / 2) - 1
+ local begi = math.max(math.min(pos - delta, count - max + 1), 1)
+ local endi = math.min(begi + max - 1, count)
+
+ local reslist = {}
+ for i=begi, endi do
+ local item = proplist[i]
+ item.current = (i == pos) and true or nil
+ table.insert(reslist, item)
+ end
+ return count, reslist
+end
+
+function get_playlist()
+ local pos = mp.get_property_number('playlist-pos', 0) + 1
+ local count, limlist = limited_list('playlist', pos)
+ if count == 0 then
+ return 'Empty playlist.'
+ end
+
+ local message = string.format('Playlist [%d/%d]:\n', pos, count)
+ for i, v in ipairs(limlist) do
+ local title = v.title
+ local _, filename = utils.split_path(v.filename)
+ if title == nil then
+ title = filename
+ end
+ message = string.format('%s %s %s\n', message,
+ (v.current and '●' or '○'), title)
+ end
+ return message
+end
+
+function get_chapterlist()
+ local pos = mp.get_property_number('chapter', 0) + 1
+ local count, limlist = limited_list('chapter-list', pos)
+ if count == 0 then
+ return 'No chapters.'
+ end
+
+ local message = string.format('Chapters [%d/%d]:\n', pos, count)
+ for i, v in ipairs(limlist) do
+ local time = mp.format_time(v.time)
+ local title = v.title
+ if title == nil then
+ title = string.format('Chapter %02d', i)
+ end
+ message = string.format('%s[%s] %s %s\n', message, time,
+ (v.current and '●' or '○'), title)
+ end
+ return message
+end
+
+function show_message(text, duration)
+
+ --print("text: "..text.." duration: " .. duration)
+ if duration == nil then
+ duration = tonumber(mp.get_property("options/osd-duration")) / 1000
+ elseif not type(duration) == "number" then
+ print("duration: " .. duration)
+ end
+
+ -- cut the text short, otherwise the following functions
+ -- may slow down massively on huge input
+ text = string.sub(text, 0, 4000)
+
+ -- replace actual linebreaks with ASS linebreaks
+ text = string.gsub(text, "\n", "\\N")
+
+ state.message_text = text
+
+ if not state.message_hide_timer then
+ state.message_hide_timer = mp.add_timeout(0, request_tick)
+ end
+ state.message_hide_timer:kill()
+ state.message_hide_timer.timeout = duration
+ state.message_hide_timer:resume()
+ request_tick()
+end
+
+function render_message(ass)
+ if state.message_hide_timer and state.message_hide_timer:is_enabled() and
+ state.message_text
+ then
+ local _, lines = string.gsub(state.message_text, "\\N", "")
+
+ local fontsize = tonumber(mp.get_property("options/osd-font-size"))
+ local outline = tonumber(mp.get_property("options/osd-border-size"))
+ local maxlines = math.ceil(osc_param.unscaled_y*0.75 / fontsize)
+ local counterscale = osc_param.playresy / osc_param.unscaled_y
+
+ fontsize = fontsize * counterscale / math.max(0.65 + math.min(lines/maxlines, 1), 1)
+ outline = outline * counterscale / math.max(0.75 + math.min(lines/maxlines, 1)/2, 1)
+
+ local style = "{\\bord" .. outline .. "\\fs" .. fontsize .. "}"
+
+
+ ass:new_event()
+ ass:append(style .. state.message_text)
+ else
+ state.message_text = nil
+ end
+end
+
+--
+-- Initialisation and Layout
+--
+
+function new_element(name, type)
+ elements[name] = {}
+ elements[name].type = type
+
+ -- add default stuff
+ elements[name].eventresponder = {}
+ elements[name].visible = true
+ elements[name].enabled = true
+ elements[name].softrepeat = false
+ elements[name].styledown = (type == "button")
+ elements[name].state = {}
+
+ if (type == "slider") then
+ elements[name].slider = {min = {value = 0}, max = {value = 100}}
+ end
+
+
+ return elements[name]
+end
+
+function add_layout(name)
+ if not (elements[name] == nil) then
+ -- new layout
+ elements[name].layout = {}
+
+ -- set layout defaults
+ elements[name].layout.layer = 50
+ elements[name].layout.alpha = {[1] = 0, [2] = 255, [3] = 255, [4] = 255}
+
+ if (elements[name].type == "button") then
+ elements[name].layout.button = {
+ maxchars = nil,
+ }
+ elseif (elements[name].type == "slider") then
+ -- slider defaults
+ elements[name].layout.slider = {
+ border = 1,
+ gap = 1,
+ nibbles_top = true,
+ nibbles_bottom = true,
+ stype = "slider",
+ adjust_tooltip = true,
+ tooltip_style = "",
+ tooltip_an = 2,
+ alpha = {[1] = 0, [2] = 255, [3] = 88, [4] = 255},
+ }
+ elseif (elements[name].type == "box") then
+ elements[name].layout.box = {radius = 0, hexagon = false}
+ end
+
+ return elements[name].layout
+ else
+ msg.error("Can't add_layout to element \""..name.."\", doesn't exist.")
+ end
+end
+
+-- Window Controls
+function window_controls(topbar)
+ local wc_geo = {
+ x = 0,
+ y = 30 + user_opts.barmargin,
+ an = 1,
+ w = osc_param.playresx,
+ h = 30,
+ }
+
+ local alignment = window_controls_alignment()
+ local controlbox_w = window_control_box_width
+ local titlebox_w = wc_geo.w - controlbox_w
+
+ -- Default alignment is "right"
+ local controlbox_left = wc_geo.w - controlbox_w
+ local titlebox_left = wc_geo.x
+ local titlebox_right = wc_geo.w - controlbox_w
+
+ if alignment == "left" then
+ controlbox_left = wc_geo.x
+ titlebox_left = wc_geo.x + controlbox_w
+ titlebox_right = wc_geo.w
+ end
+
+ add_area("window-controls",
+ get_hitbox_coords(controlbox_left, wc_geo.y, wc_geo.an,
+ controlbox_w, wc_geo.h))
+
+ local lo
+
+ -- Background Bar
+ new_element("wcbar", "box")
+ lo = add_layout("wcbar")
+ lo.geometry = wc_geo
+ lo.layer = 10
+ lo.style = osc_styles.wcBar
+ lo.alpha[1] = user_opts.boxalpha
+
+ local button_y = wc_geo.y - (wc_geo.h / 2)
+ local first_geo =
+ {x = controlbox_left + 5, y = button_y, an = 4, w = 25, h = 25}
+ local second_geo =
+ {x = controlbox_left + 30, y = button_y, an = 4, w = 25, h = 25}
+ local third_geo =
+ {x = controlbox_left + 55, y = button_y, an = 4, w = 25, h = 25}
+
+ -- Window control buttons use symbols in the custom mpv osd font
+ -- because the official unicode codepoints are sufficiently
+ -- exotic that a system might lack an installed font with them,
+ -- and libass will complain that they are not present in the
+ -- default font, even if another font with them is available.
+
+ -- Close: 🗙
+ ne = new_element("close", "button")
+ ne.content = "\238\132\149"
+ ne.eventresponder["mbtn_left_up"] =
+ function () mp.commandv("quit") end
+ lo = add_layout("close")
+ lo.geometry = alignment == "left" and first_geo or third_geo
+ lo.style = osc_styles.wcButtons
+
+ -- Minimize: 🗕
+ ne = new_element("minimize", "button")
+ ne.content = "\238\132\146"
+ ne.eventresponder["mbtn_left_up"] =
+ function () mp.commandv("cycle", "window-minimized") end
+ lo = add_layout("minimize")
+ lo.geometry = alignment == "left" and second_geo or first_geo
+ lo.style = osc_styles.wcButtons
+
+ -- Maximize: 🗖 /🗗
+ ne = new_element("maximize", "button")
+ if state.maximized or state.fullscreen then
+ ne.content = "\238\132\148"
+ else
+ ne.content = "\238\132\147"
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function ()
+ if state.fullscreen then
+ mp.commandv("cycle", "fullscreen")
+ else
+ mp.commandv("cycle", "window-maximized")
+ end
+ end
+ lo = add_layout("maximize")
+ lo.geometry = alignment == "left" and third_geo or second_geo
+ lo.style = osc_styles.wcButtons
+
+ -- deadzone below window controls
+ local sh_area_y0, sh_area_y1
+ sh_area_y0 = user_opts.barmargin
+ sh_area_y1 = (wc_geo.y + (wc_geo.h / 2)) +
+ get_align(1 - (2 * user_opts.deadzonesize),
+ osc_param.playresy - (wc_geo.y + (wc_geo.h / 2)), 0, 0)
+ add_area("showhide_wc", wc_geo.x, sh_area_y0, wc_geo.w, sh_area_y1)
+
+ if topbar then
+ -- The title is already there as part of the top bar
+ return
+ else
+ -- Apply boxvideo margins to the control bar
+ osc_param.video_margins.t = wc_geo.h / osc_param.playresy
+ end
+
+ -- Window Title
+ ne = new_element("wctitle", "button")
+ ne.content = function ()
+ local title = mp.command_native({"expand-text", user_opts.title})
+ -- escape ASS, and strip newlines and trailing slashes
+ title = title:gsub("\\n", " "):gsub("\\$", ""):gsub("{","\\{")
+ return not (title == "") and title or "mpv"
+ end
+ local left_pad = 5
+ local right_pad = 10
+ lo = add_layout("wctitle")
+ lo.geometry =
+ { x = titlebox_left + left_pad, y = wc_geo.y - 3, an = 1,
+ w = titlebox_w, h = wc_geo.h }
+ lo.style = string.format("%s{\\clip(%f,%f,%f,%f)}",
+ osc_styles.wcTitle,
+ titlebox_left + left_pad, wc_geo.y - wc_geo.h,
+ titlebox_right - right_pad , wc_geo.y + wc_geo.h)
+
+ add_area("window-controls-title",
+ titlebox_left, 0, titlebox_right, wc_geo.h)
+end
+
+--
+-- Layouts
+--
+
+local layouts = {}
+
+-- Classic box layout
+layouts["box"] = function ()
+
+ local osc_geo = {
+ w = 550, -- width
+ h = 138, -- height
+ r = 10, -- corner-radius
+ p = 15, -- padding
+ }
+
+ -- make sure the OSC actually fits into the video
+ if (osc_param.playresx < (osc_geo.w + (2 * osc_geo.p))) then
+ osc_param.playresy = (osc_geo.w+(2*osc_geo.p))/osc_param.display_aspect
+ osc_param.playresx = osc_param.playresy * osc_param.display_aspect
+ end
+
+ -- position of the controller according to video aspect and valignment
+ local posX = math.floor(get_align(user_opts.halign, osc_param.playresx,
+ osc_geo.w, 0))
+ local posY = math.floor(get_align(user_opts.valign, osc_param.playresy,
+ osc_geo.h, 0))
+
+ -- position offset for contents aligned at the borders of the box
+ local pos_offsetX = (osc_geo.w - (2*osc_geo.p)) / 2
+ local pos_offsetY = (osc_geo.h - (2*osc_geo.p)) / 2
+
+ osc_param.areas = {} -- delete areas
+
+ -- area for active mouse input
+ add_area("input", get_hitbox_coords(posX, posY, 5, osc_geo.w, osc_geo.h))
+
+ -- area for show/hide
+ local sh_area_y0, sh_area_y1
+ if user_opts.valign > 0 then
+ -- deadzone above OSC
+ sh_area_y0 = get_align(-1 + (2*user_opts.deadzonesize),
+ posY - (osc_geo.h / 2), 0, 0)
+ sh_area_y1 = osc_param.playresy
+ else
+ -- deadzone below OSC
+ sh_area_y0 = 0
+ sh_area_y1 = (posY + (osc_geo.h / 2)) +
+ get_align(1 - (2*user_opts.deadzonesize),
+ osc_param.playresy - (posY + (osc_geo.h / 2)), 0, 0)
+ end
+ add_area("showhide", 0, sh_area_y0, osc_param.playresx, sh_area_y1)
+
+ -- fetch values
+ local osc_w, osc_h, osc_r, osc_p =
+ osc_geo.w, osc_geo.h, osc_geo.r, osc_geo.p
+
+ local lo
+
+ --
+ -- Background box
+ --
+
+ new_element("bgbox", "box")
+ lo = add_layout("bgbox")
+
+ lo.geometry = {x = posX, y = posY, an = 5, w = osc_w, h = osc_h}
+ lo.layer = 10
+ lo.style = osc_styles.box
+ lo.alpha[1] = user_opts.boxalpha
+ lo.alpha[3] = user_opts.boxalpha
+ lo.box.radius = osc_r
+
+ --
+ -- Title row
+ --
+
+ local titlerowY = posY - pos_offsetY - 10
+
+ lo = add_layout("title")
+ lo.geometry = {x = posX, y = titlerowY, an = 8, w = 496, h = 12}
+ lo.style = osc_styles.vidtitle
+ lo.button.maxchars = user_opts.boxmaxchars
+
+ lo = add_layout("pl_prev")
+ lo.geometry =
+ {x = (posX - pos_offsetX), y = titlerowY, an = 7, w = 12, h = 12}
+ lo.style = osc_styles.topButtons
+
+ lo = add_layout("pl_next")
+ lo.geometry =
+ {x = (posX + pos_offsetX), y = titlerowY, an = 9, w = 12, h = 12}
+ lo.style = osc_styles.topButtons
+
+ --
+ -- Big buttons
+ --
+
+ local bigbtnrowY = posY - pos_offsetY + 35
+ local bigbtndist = 60
+
+ lo = add_layout("playpause")
+ lo.geometry =
+ {x = posX, y = bigbtnrowY, an = 5, w = 40, h = 40}
+ lo.style = osc_styles.bigButtons
+
+ lo = add_layout("skipback")
+ lo.geometry =
+ {x = posX - bigbtndist, y = bigbtnrowY, an = 5, w = 40, h = 40}
+ lo.style = osc_styles.bigButtons
+
+ lo = add_layout("skipfrwd")
+ lo.geometry =
+ {x = posX + bigbtndist, y = bigbtnrowY, an = 5, w = 40, h = 40}
+ lo.style = osc_styles.bigButtons
+
+ lo = add_layout("ch_prev")
+ lo.geometry =
+ {x = posX - (bigbtndist * 2), y = bigbtnrowY, an = 5, w = 40, h = 40}
+ lo.style = osc_styles.bigButtons
+
+ lo = add_layout("ch_next")
+ lo.geometry =
+ {x = posX + (bigbtndist * 2), y = bigbtnrowY, an = 5, w = 40, h = 40}
+ lo.style = osc_styles.bigButtons
+
+ lo = add_layout("cy_audio")
+ lo.geometry =
+ {x = posX - pos_offsetX, y = bigbtnrowY, an = 1, w = 70, h = 18}
+ lo.style = osc_styles.smallButtonsL
+
+ lo = add_layout("cy_sub")
+ lo.geometry =
+ {x = posX - pos_offsetX, y = bigbtnrowY, an = 7, w = 70, h = 18}
+ lo.style = osc_styles.smallButtonsL
+
+ lo = add_layout("tog_fs")
+ lo.geometry =
+ {x = posX+pos_offsetX - 25, y = bigbtnrowY, an = 4, w = 25, h = 25}
+ lo.style = osc_styles.smallButtonsR
+
+ lo = add_layout("volume")
+ lo.geometry =
+ {x = posX+pos_offsetX - (25 * 2) - osc_geo.p,
+ y = bigbtnrowY, an = 4, w = 25, h = 25}
+ lo.style = osc_styles.smallButtonsR
+
+ --
+ -- Seekbar
+ --
+
+ lo = add_layout("seekbar")
+ lo.geometry =
+ {x = posX, y = posY+pos_offsetY-22, an = 2, w = pos_offsetX*2, h = 15}
+ lo.style = osc_styles.timecodes
+ lo.slider.tooltip_style = osc_styles.vidtitle
+ lo.slider.stype = user_opts["seekbarstyle"]
+ lo.slider.rtype = user_opts["seekrangestyle"]
+
+ --
+ -- Timecodes + Cache
+ --
+
+ local bottomrowY = posY + pos_offsetY - 5
+
+ lo = add_layout("tc_left")
+ lo.geometry =
+ {x = posX - pos_offsetX, y = bottomrowY, an = 4, w = 110, h = 18}
+ lo.style = osc_styles.timecodes
+
+ lo = add_layout("tc_right")
+ lo.geometry =
+ {x = posX + pos_offsetX, y = bottomrowY, an = 6, w = 110, h = 18}
+ lo.style = osc_styles.timecodes
+
+ lo = add_layout("cache")
+ lo.geometry =
+ {x = posX, y = bottomrowY, an = 5, w = 110, h = 18}
+ lo.style = osc_styles.timecodes
+
+end
+
+-- slim box layout
+layouts["slimbox"] = function ()
+
+ local osc_geo = {
+ w = 660, -- width
+ h = 70, -- height
+ r = 10, -- corner-radius
+ }
+
+ -- make sure the OSC actually fits into the video
+ if (osc_param.playresx < (osc_geo.w)) then
+ osc_param.playresy = (osc_geo.w)/osc_param.display_aspect
+ osc_param.playresx = osc_param.playresy * osc_param.display_aspect
+ end
+
+ -- position of the controller according to video aspect and valignment
+ local posX = math.floor(get_align(user_opts.halign, osc_param.playresx,
+ osc_geo.w, 0))
+ local posY = math.floor(get_align(user_opts.valign, osc_param.playresy,
+ osc_geo.h, 0))
+
+ osc_param.areas = {} -- delete areas
+
+ -- area for active mouse input
+ add_area("input", get_hitbox_coords(posX, posY, 5, osc_geo.w, osc_geo.h))
+
+ -- area for show/hide
+ local sh_area_y0, sh_area_y1
+ if user_opts.valign > 0 then
+ -- deadzone above OSC
+ sh_area_y0 = get_align(-1 + (2*user_opts.deadzonesize),
+ posY - (osc_geo.h / 2), 0, 0)
+ sh_area_y1 = osc_param.playresy
+ else
+ -- deadzone below OSC
+ sh_area_y0 = 0
+ sh_area_y1 = (posY + (osc_geo.h / 2)) +
+ get_align(1 - (2*user_opts.deadzonesize),
+ osc_param.playresy - (posY + (osc_geo.h / 2)), 0, 0)
+ end
+ add_area("showhide", 0, sh_area_y0, osc_param.playresx, sh_area_y1)
+
+ local lo
+
+ local tc_w, ele_h, inner_w = 100, 20, osc_geo.w - 100
+
+ -- styles
+ local styles = {
+ box = "{\\rDefault\\blur0\\bord1\\1c&H000000\\3c&HFFFFFF}",
+ timecodes = "{\\1c&HFFFFFF\\3c&H000000\\fs20\\bord2\\blur1}",
+ tooltip = "{\\1c&HFFFFFF\\3c&H000000\\fs12\\bord1\\blur0.5}",
+ }
+
+
+ new_element("bgbox", "box")
+ lo = add_layout("bgbox")
+
+ lo.geometry = {x = posX, y = posY - 1, an = 2, w = inner_w, h = ele_h}
+ lo.layer = 10
+ lo.style = osc_styles.box
+ lo.alpha[1] = user_opts.boxalpha
+ lo.alpha[3] = 0
+ if not (user_opts["seekbarstyle"] == "bar") then
+ lo.box.radius = osc_geo.r
+ lo.box.hexagon = user_opts["seekbarstyle"] == "diamond"
+ end
+
+
+ lo = add_layout("seekbar")
+ lo.geometry =
+ {x = posX, y = posY - 1, an = 2, w = inner_w, h = ele_h}
+ lo.style = osc_styles.timecodes
+ lo.slider.border = 0
+ lo.slider.gap = 1.5
+ lo.slider.tooltip_style = styles.tooltip
+ lo.slider.stype = user_opts["seekbarstyle"]
+ lo.slider.rtype = user_opts["seekrangestyle"]
+ lo.slider.adjust_tooltip = false
+
+ --
+ -- Timecodes
+ --
+
+ lo = add_layout("tc_left")
+ lo.geometry =
+ {x = posX - (inner_w/2) + osc_geo.r, y = posY + 1,
+ an = 7, w = tc_w, h = ele_h}
+ lo.style = styles.timecodes
+ lo.alpha[3] = user_opts.boxalpha
+
+ lo = add_layout("tc_right")
+ lo.geometry =
+ {x = posX + (inner_w/2) - osc_geo.r, y = posY + 1,
+ an = 9, w = tc_w, h = ele_h}
+ lo.style = styles.timecodes
+ lo.alpha[3] = user_opts.boxalpha
+
+ -- Cache
+
+ lo = add_layout("cache")
+ lo.geometry =
+ {x = posX, y = posY + 1,
+ an = 8, w = tc_w, h = ele_h}
+ lo.style = styles.timecodes
+ lo.alpha[3] = user_opts.boxalpha
+
+
+end
+
+function bar_layout(direction)
+ local osc_geo = {
+ x = -2,
+ y,
+ an = (direction < 0) and 7 or 1,
+ w,
+ h = 56,
+ }
+
+ local padX = 9
+ local padY = 3
+ local buttonW = 27
+ local tcW = (state.tc_ms) and 170 or 110
+ if user_opts.tcspace >= 50 and user_opts.tcspace <= 200 then
+ -- adjust our hardcoded font size estimation
+ tcW = tcW * user_opts.tcspace / 100
+ end
+
+ local tsW = 90
+ local minW = (buttonW + padX)*5 + (tcW + padX)*4 + (tsW + padX)*2
+
+ -- Special topbar handling when window controls are present
+ local padwc_l
+ local padwc_r
+ if direction < 0 or not window_controls_enabled() then
+ padwc_l = 0
+ padwc_r = 0
+ elseif window_controls_alignment() == "left" then
+ padwc_l = window_control_box_width
+ padwc_r = 0
+ else
+ padwc_l = 0
+ padwc_r = window_control_box_width
+ end
+
+ if ((osc_param.display_aspect > 0) and (osc_param.playresx < minW)) then
+ osc_param.playresy = minW / osc_param.display_aspect
+ osc_param.playresx = osc_param.playresy * osc_param.display_aspect
+ end
+
+ osc_geo.y = direction * (54 + user_opts.barmargin)
+ osc_geo.w = osc_param.playresx + 4
+ if direction < 0 then
+ osc_geo.y = osc_geo.y + osc_param.playresy
+ end
+
+ local line1 = osc_geo.y - direction * (9 + padY)
+ local line2 = osc_geo.y - direction * (36 + padY)
+
+ osc_param.areas = {}
+
+ add_area("input", get_hitbox_coords(osc_geo.x, osc_geo.y, osc_geo.an,
+ osc_geo.w, osc_geo.h))
+
+ local sh_area_y0, sh_area_y1
+ if direction > 0 then
+ -- deadzone below OSC
+ sh_area_y0 = user_opts.barmargin
+ sh_area_y1 = (osc_geo.y + (osc_geo.h / 2)) +
+ get_align(1 - (2*user_opts.deadzonesize),
+ osc_param.playresy - (osc_geo.y + (osc_geo.h / 2)), 0, 0)
+ else
+ -- deadzone above OSC
+ sh_area_y0 = get_align(-1 + (2*user_opts.deadzonesize),
+ osc_geo.y - (osc_geo.h / 2), 0, 0)
+ sh_area_y1 = osc_param.playresy - user_opts.barmargin
+ end
+ add_area("showhide", 0, sh_area_y0, osc_param.playresx, sh_area_y1)
+
+ local lo, geo
+
+ -- Background bar
+ new_element("bgbox", "box")
+ lo = add_layout("bgbox")
+
+ lo.geometry = osc_geo
+ lo.layer = 10
+ lo.style = osc_styles.box
+ lo.alpha[1] = user_opts.boxalpha
+
+
+ -- Playlist prev/next
+ geo = { x = osc_geo.x + padX, y = line1,
+ an = 4, w = 18, h = 18 - padY }
+ lo = add_layout("pl_prev")
+ lo.geometry = geo
+ lo.style = osc_styles.topButtonsBar
+
+ geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
+ lo = add_layout("pl_next")
+ lo.geometry = geo
+ lo.style = osc_styles.topButtonsBar
+
+ local t_l = geo.x + geo.w + padX
+
+ -- Cache
+ geo = { x = osc_geo.x + osc_geo.w - padX, y = geo.y,
+ an = 6, w = 150, h = geo.h }
+ lo = add_layout("cache")
+ lo.geometry = geo
+ lo.style = osc_styles.vidtitleBar
+
+ local t_r = geo.x - geo.w - padX*2
+
+ -- Title
+ geo = { x = t_l, y = geo.y, an = 4,
+ w = t_r - t_l, h = geo.h }
+ lo = add_layout("title")
+ lo.geometry = geo
+ lo.style = string.format("%s{\\clip(%f,%f,%f,%f)}",
+ osc_styles.vidtitleBar,
+ geo.x, geo.y-geo.h, geo.w, geo.y+geo.h)
+
+
+ -- Playback control buttons
+ geo = { x = osc_geo.x + padX + padwc_l, y = line2, an = 4,
+ w = buttonW, h = 36 - padY*2}
+ lo = add_layout("playpause")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+
+ geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
+ lo = add_layout("ch_prev")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+
+ geo = { x = geo.x + geo.w + padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
+ lo = add_layout("ch_next")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+
+ -- Left timecode
+ geo = { x = geo.x + geo.w + padX + tcW, y = geo.y, an = 6,
+ w = tcW, h = geo.h }
+ lo = add_layout("tc_left")
+ lo.geometry = geo
+ lo.style = osc_styles.timecodesBar
+
+ local sb_l = geo.x + padX
+
+ -- Fullscreen button
+ geo = { x = osc_geo.x + osc_geo.w - buttonW - padX - padwc_r, y = geo.y, an = 4,
+ w = buttonW, h = geo.h }
+ lo = add_layout("tog_fs")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+
+ -- START quality-menu
+ geo = { x = geo.x - geo.w - padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
+ lo = add_layout("quality-menu")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+ -- END quality-menu
+
+ -- Volume
+ geo = { x = geo.x - geo.w - padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
+ lo = add_layout("volume")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+
+ -- Track selection buttons
+ geo = { x = geo.x - tsW - padX, y = geo.y, an = geo.an, w = tsW, h = geo.h }
+ lo = add_layout("cy_sub")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+
+ geo = { x = geo.x - geo.w - padX, y = geo.y, an = geo.an, w = geo.w, h = geo.h }
+ lo = add_layout("cy_audio")
+ lo.geometry = geo
+ lo.style = osc_styles.smallButtonsBar
+
+
+ -- Right timecode
+ geo = { x = geo.x - padX - tcW - 10, y = geo.y, an = geo.an,
+ w = tcW, h = geo.h }
+ lo = add_layout("tc_right")
+ lo.geometry = geo
+ lo.style = osc_styles.timecodesBar
+
+ local sb_r = geo.x - padX
+
+
+ -- Seekbar
+ geo = { x = sb_l, y = geo.y, an = geo.an,
+ w = math.max(0, sb_r - sb_l), h = geo.h }
+ new_element("bgbar1", "box")
+ lo = add_layout("bgbar1")
+
+ lo.geometry = geo
+ lo.layer = 15
+ lo.style = osc_styles.timecodesBar
+ lo.alpha[1] =
+ math.min(255, user_opts.boxalpha + (255 - user_opts.boxalpha)*0.8)
+ if not (user_opts["seekbarstyle"] == "bar") then
+ lo.box.radius = geo.h / 2
+ lo.box.hexagon = user_opts["seekbarstyle"] == "diamond"
+ end
+
+ lo = add_layout("seekbar")
+ lo.geometry = geo
+ lo.style = osc_styles.timecodesBar
+ lo.slider.border = 0
+ lo.slider.gap = 2
+ lo.slider.tooltip_style = osc_styles.timePosBar
+ lo.slider.tooltip_an = 5
+ lo.slider.stype = user_opts["seekbarstyle"]
+ lo.slider.rtype = user_opts["seekrangestyle"]
+
+ if direction < 0 then
+ osc_param.video_margins.b = osc_geo.h / osc_param.playresy
+ else
+ osc_param.video_margins.t = osc_geo.h / osc_param.playresy
+ end
+end
+
+layouts["bottombar"] = function()
+ bar_layout(-1)
+end
+
+layouts["topbar"] = function()
+ bar_layout(1)
+end
+
+-- Validate string type user options
+function validate_user_opts()
+ if layouts[user_opts.layout] == nil then
+ msg.warn("Invalid setting \""..user_opts.layout.."\" for layout")
+ user_opts.layout = "bottombar"
+ end
+
+ if user_opts.seekbarstyle ~= "bar" and
+ user_opts.seekbarstyle ~= "diamond" and
+ user_opts.seekbarstyle ~= "knob" then
+ msg.warn("Invalid setting \"" .. user_opts.seekbarstyle
+ .. "\" for seekbarstyle")
+ user_opts.seekbarstyle = "bar"
+ end
+
+ if user_opts.seekrangestyle ~= "bar" and
+ user_opts.seekrangestyle ~= "line" and
+ user_opts.seekrangestyle ~= "slider" and
+ user_opts.seekrangestyle ~= "inverted" and
+ user_opts.seekrangestyle ~= "none" then
+ msg.warn("Invalid setting \"" .. user_opts.seekrangestyle
+ .. "\" for seekrangestyle")
+ user_opts.seekrangestyle = "inverted"
+ end
+
+ if user_opts.seekrangestyle == "slider" and
+ user_opts.seekbarstyle == "bar" then
+ msg.warn("Using \"slider\" seekrangestyle together with \"bar\" seekbarstyle is not supported")
+ user_opts.seekrangestyle = "inverted"
+ end
+
+ if user_opts.windowcontrols ~= "auto" and
+ user_opts.windowcontrols ~= "yes" and
+ user_opts.windowcontrols ~= "no" then
+ msg.warn("windowcontrols cannot be \"" ..
+ user_opts.windowcontrols .. "\". Ignoring.")
+ user_opts.windowcontrols = "auto"
+ end
+ if user_opts.windowcontrols_alignment ~= "right" and
+ user_opts.windowcontrols_alignment ~= "left" then
+ msg.warn("windowcontrols_alignment cannot be \"" ..
+ user_opts.windowcontrols_alignment .. "\". Ignoring.")
+ user_opts.windowcontrols_alignment = "right"
+ end
+end
+
+function update_options(list)
+ validate_user_opts()
+ request_tick()
+ visibility_mode(user_opts.visibility, true)
+ update_duration_watch()
+ request_init()
+end
+
+local UNICODE_MINUS = string.char(0xe2, 0x88, 0x92) -- UTF-8 for U+2212 MINUS SIGN
+
+-- OSC INIT
+function osc_init()
+ msg.debug("osc_init")
+
+ -- set canvas resolution according to display aspect and scaling setting
+ local baseResY = 720
+ local display_w, display_h, display_aspect = mp.get_osd_size()
+ local scale = 1
+
+ if (mp.get_property("video") == "no") then -- dummy/forced window
+ scale = user_opts.scaleforcedwindow
+ elseif state.fullscreen then
+ scale = user_opts.scalefullscreen
+ else
+ scale = user_opts.scalewindowed
+ end
+
+ if user_opts.vidscale then
+ osc_param.unscaled_y = baseResY
+ else
+ osc_param.unscaled_y = display_h
+ end
+ osc_param.playresy = osc_param.unscaled_y / scale
+ if (display_aspect > 0) then
+ osc_param.display_aspect = display_aspect
+ end
+ osc_param.playresx = osc_param.playresy * osc_param.display_aspect
+
+ -- stop seeking with the slider to prevent skipping files
+ state.active_element = nil
+
+ osc_param.video_margins = {l = 0, r = 0, t = 0, b = 0}
+
+ elements = {}
+
+ -- some often needed stuff
+ local pl_count = mp.get_property_number("playlist-count", 0)
+ local have_pl = (pl_count > 1)
+ local pl_pos = mp.get_property_number("playlist-pos", 0) + 1
+ local have_ch = (mp.get_property_number("chapters", 0) > 0)
+ local loop = mp.get_property("loop-playlist", "no")
+
+ local ne
+
+ -- title
+ ne = new_element("title", "button")
+
+ ne.content = function ()
+ local title = state.forced_title or
+ mp.command_native({"expand-text", user_opts.title})
+ -- escape ASS, and strip newlines and trailing slashes
+ title = title:gsub("\\n", " "):gsub("\\$", ""):gsub("{","\\{")
+ return not (title == "") and title or "mpv"
+ end
+
+ ne.eventresponder["mbtn_left_up"] = function ()
+ local title = mp.get_property_osd("media-title")
+ if (have_pl) then
+ title = string.format("[%d/%d] %s", countone(pl_pos - 1),
+ pl_count, title)
+ end
+ show_message(title)
+ end
+
+ ne.eventresponder["mbtn_right_up"] =
+ function () show_message(mp.get_property_osd("filename")) end
+
+ -- playlist buttons
+
+ -- prev
+ ne = new_element("pl_prev", "button")
+
+ ne.content = "\238\132\144"
+ ne.enabled = (pl_pos > 1) or (loop ~= "no")
+ ne.eventresponder["mbtn_left_up"] =
+ function ()
+ mp.commandv("playlist-prev", "weak")
+ if user_opts.playlist_osd then
+ show_message(get_playlist(), 3)
+ end
+ end
+ ne.eventresponder["shift+mbtn_left_up"] =
+ function () show_message(get_playlist(), 3) end
+ ne.eventresponder["mbtn_right_up"] =
+ function () show_message(get_playlist(), 3) end
+
+ --next
+ ne = new_element("pl_next", "button")
+
+ ne.content = "\238\132\129"
+ ne.enabled = (have_pl and (pl_pos < pl_count)) or (loop ~= "no")
+ ne.eventresponder["mbtn_left_up"] =
+ function ()
+ mp.commandv("playlist-next", "weak")
+ if user_opts.playlist_osd then
+ show_message(get_playlist(), 3)
+ end
+ end
+ ne.eventresponder["shift+mbtn_left_up"] =
+ function () show_message(get_playlist(), 3) end
+ ne.eventresponder["mbtn_right_up"] =
+ function () show_message(get_playlist(), 3) end
+
+
+ -- big buttons
+
+ --playpause
+ ne = new_element("playpause", "button")
+
+ ne.content = function ()
+ if mp.get_property("pause") == "yes" then
+ return ("\238\132\129")
+ else
+ return ("\238\128\130")
+ end
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function () mp.commandv("cycle", "pause") end
+
+ --skipback
+ ne = new_element("skipback", "button")
+
+ ne.softrepeat = true
+ ne.content = "\238\128\132"
+ ne.eventresponder["mbtn_left_down"] =
+ function () mp.commandv("seek", -5, "relative", "keyframes") end
+ ne.eventresponder["shift+mbtn_left_down"] =
+ function () mp.commandv("frame-back-step") end
+ ne.eventresponder["mbtn_right_down"] =
+ function () mp.commandv("seek", -30, "relative", "keyframes") end
+
+ --skipfrwd
+ ne = new_element("skipfrwd", "button")
+
+ ne.softrepeat = true
+ ne.content = "\238\128\133"
+ ne.eventresponder["mbtn_left_down"] =
+ function () mp.commandv("seek", 10, "relative", "keyframes") end
+ ne.eventresponder["shift+mbtn_left_down"] =
+ function () mp.commandv("frame-step") end
+ ne.eventresponder["mbtn_right_down"] =
+ function () mp.commandv("seek", 60, "relative", "keyframes") end
+
+ --ch_prev
+ ne = new_element("ch_prev", "button")
+
+ ne.enabled = have_ch
+ ne.content = "\238\132\132"
+ ne.eventresponder["mbtn_left_up"] =
+ function ()
+ mp.commandv("add", "chapter", -1)
+ if user_opts.chapters_osd then
+ show_message(get_chapterlist(), 3)
+ end
+ end
+ ne.eventresponder["shift+mbtn_left_up"] =
+ function () show_message(get_chapterlist(), 3) end
+ ne.eventresponder["mbtn_right_up"] =
+ function () show_message(get_chapterlist(), 3) end
+
+ --ch_next
+ ne = new_element("ch_next", "button")
+
+ ne.enabled = have_ch
+ ne.content = "\238\132\133"
+ ne.eventresponder["mbtn_left_up"] =
+ function ()
+ mp.commandv("add", "chapter", 1)
+ if user_opts.chapters_osd then
+ show_message(get_chapterlist(), 3)
+ end
+ end
+ ne.eventresponder["shift+mbtn_left_up"] =
+ function () show_message(get_chapterlist(), 3) end
+ ne.eventresponder["mbtn_right_up"] =
+ function () show_message(get_chapterlist(), 3) end
+
+ --
+ update_tracklist()
+
+ --cy_audio
+ ne = new_element("cy_audio", "button")
+
+ ne.enabled = (#tracks_osc.audio > 0)
+ ne.content = function ()
+ local aid = "–"
+ if not (get_track("audio") == 0) then
+ aid = get_track("audio")
+ end
+ return ("\238\132\134" .. osc_styles.smallButtonsLlabel
+ .. " " .. aid .. "/" .. #tracks_osc.audio)
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function () set_track("audio", 1) end
+ ne.eventresponder["mbtn_right_up"] =
+ function () set_track("audio", -1) end
+ ne.eventresponder["shift+mbtn_left_down"] =
+ function () show_message(get_tracklist("audio"), 2) end
+
+ --cy_sub
+ ne = new_element("cy_sub", "button")
+
+ ne.enabled = (#tracks_osc.sub > 0)
+ ne.content = function ()
+ local sid = "–"
+ if not (get_track("sub") == 0) then
+ sid = get_track("sub")
+ end
+ return ("\238\132\135" .. osc_styles.smallButtonsLlabel
+ .. " " .. sid .. "/" .. #tracks_osc.sub)
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function () set_track("sub", 1) end
+ ne.eventresponder["mbtn_right_up"] =
+ function () set_track("sub", -1) end
+ ne.eventresponder["shift+mbtn_left_down"] =
+ function () show_message(get_tracklist("sub"), 2) end
+
+ --tog_fs
+ ne = new_element("tog_fs", "button")
+ ne.content = function ()
+ if (state.fullscreen) then
+ return ("\238\132\137")
+ else
+ return ("\238\132\136")
+ end
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function () mp.commandv("cycle", "fullscreen") end
+
+ --seekbar
+ ne = new_element("seekbar", "slider")
+
+ ne.enabled = not (mp.get_property("percent-pos") == nil)
+ state.slider_element = ne.enabled and ne or nil -- used for forced_title
+ ne.slider.markerF = function ()
+ local duration = mp.get_property_number("duration", nil)
+ if not (duration == nil) then
+ local chapters = mp.get_property_native("chapter-list", {})
+ local markers = {}
+ for n = 1, #chapters do
+ markers[n] = (chapters[n].time / duration * 100)
+ end
+ return markers
+ else
+ return {}
+ end
+ end
+ ne.slider.posF =
+ function () return mp.get_property_number("percent-pos", nil) end
+ ne.slider.tooltipF = function (pos)
+ local duration = mp.get_property_number("duration", nil)
+ if not ((duration == nil) or (pos == nil)) then
+ possec = duration * (pos / 100)
+ return mp.format_time(possec)
+ else
+ return ""
+ end
+ end
+ ne.slider.seekRangesF = function()
+ if user_opts.seekrangestyle == "none" then
+ return nil
+ end
+ local cache_state = state.cache_state
+ if not cache_state then
+ return nil
+ end
+ local duration = mp.get_property_number("duration", nil)
+ if (duration == nil) or duration <= 0 then
+ return nil
+ end
+ local ranges = cache_state["seekable-ranges"]
+ if #ranges == 0 then
+ return nil
+ end
+ local nranges = {}
+ for _, range in pairs(ranges) do
+ nranges[#nranges + 1] = {
+ ["start"] = 100 * range["start"] / duration,
+ ["end"] = 100 * range["end"] / duration,
+ }
+ end
+ return nranges
+ end
+ ne.eventresponder["mouse_move"] = --keyframe seeking when mouse is dragged
+ function (element)
+ -- mouse move events may pile up during seeking and may still get
+ -- sent when the user is done seeking, so we need to throw away
+ -- identical seeks
+ local seekto = get_slider_value(element)
+ if (element.state.lastseek == nil) or
+ (not (element.state.lastseek == seekto)) then
+ local flags = "absolute-percent"
+ if not user_opts.seekbarkeyframes then
+ flags = flags .. "+exact"
+ end
+ mp.commandv("seek", seekto, flags)
+ element.state.lastseek = seekto
+ end
+
+ end
+ ne.eventresponder["mbtn_left_down"] = --exact seeks on single clicks
+ function (element) mp.commandv("seek", get_slider_value(element),
+ "absolute-percent", "exact") end
+ ne.eventresponder["reset"] =
+ function (element) element.state.lastseek = nil end
+
+
+ -- tc_left (current pos)
+ ne = new_element("tc_left", "button")
+
+ ne.content = function ()
+ if (state.tc_ms) then
+ return (mp.get_property_osd("playback-time/full"))
+ else
+ return (mp.get_property_osd("playback-time"))
+ end
+ end
+ ne.eventresponder["mbtn_left_up"] = function ()
+ state.tc_ms = not state.tc_ms
+ request_init()
+ end
+
+ -- tc_right (total/remaining time)
+ ne = new_element("tc_right", "button")
+
+ ne.visible = (mp.get_property_number("duration", 0) > 0)
+ ne.content = function ()
+ if (state.rightTC_trem) then
+ local minus = user_opts.unicodeminus and UNICODE_MINUS or "-"
+ if state.tc_ms then
+ return (minus..mp.get_property_osd("playtime-remaining/full"))
+ else
+ return (minus..mp.get_property_osd("playtime-remaining"))
+ end
+ else
+ if state.tc_ms then
+ return (mp.get_property_osd("duration/full"))
+ else
+ return (mp.get_property_osd("duration"))
+ end
+ end
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function () state.rightTC_trem = not state.rightTC_trem end
+
+ -- cache
+ ne = new_element("cache", "button")
+
+ ne.content = function ()
+ local cache_state = state.cache_state
+ if not (cache_state and cache_state["seekable-ranges"] and
+ #cache_state["seekable-ranges"] > 0) then
+ -- probably not a network stream
+ return ""
+ end
+ local dmx_cache = cache_state and cache_state["cache-duration"]
+ local thresh = math.min(state.dmx_cache * 0.05, 5) -- 5% or 5s
+ if dmx_cache and math.abs(dmx_cache - state.dmx_cache) >= thresh then
+ state.dmx_cache = dmx_cache
+ else
+ dmx_cache = state.dmx_cache
+ end
+ local min = math.floor(dmx_cache / 60)
+ local sec = math.floor(dmx_cache % 60) -- don't round e.g. 59.9 to 60
+ return "Cache: " .. (min > 0 and
+ string.format("%sm%02.0fs", min, sec) or
+ string.format("%3.0fs", sec))
+ end
+
+ -- START quality-menu
+ ne = new_element("quality-menu", "button")
+ ne.content = function()
+ return ("≚")
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function () mp.commandv("script-message", "video_formats_toggle") end
+ ne.eventresponder["mbtn_right_up"] =
+ function () mp.commandv("script-message", "audio_formats_toggle") end
+ -- END quality-menu
+
+ -- volume
+ ne = new_element("volume", "button")
+
+ ne.content = function()
+ local volume = mp.get_property_number("volume", 0)
+ local mute = mp.get_property_native("mute")
+ local volicon = {"\238\132\139", "\238\132\140",
+ "\238\132\141", "\238\132\142"}
+ if volume == 0 or mute then
+ return "\238\132\138"
+ else
+ return volicon[math.min(4,math.ceil(volume / (100/3)))]
+ end
+ end
+ ne.eventresponder["mbtn_left_up"] =
+ function () mp.commandv("cycle", "mute") end
+
+ ne.eventresponder["wheel_up_press"] =
+ function () mp.commandv("osd-auto", "add", "volume", 5) end
+ ne.eventresponder["wheel_down_press"] =
+ function () mp.commandv("osd-auto", "add", "volume", -5) end
+
+
+ -- load layout
+ layouts[user_opts.layout]()
+
+ -- load window controls
+ if window_controls_enabled() then
+ window_controls(user_opts.layout == "topbar")
+ end
+
+ --do something with the elements
+ prepare_elements()
+
+ update_margins()
+end
+
+function reset_margins()
+ if state.using_video_margins then
+ for _, opt in ipairs(margins_opts) do
+ mp.set_property_number(opt[2], 0.0)
+ end
+ state.using_video_margins = false
+ end
+end
+
+function update_margins()
+ local margins = osc_param.video_margins
+
+ -- Don't use margins if it's visible only temporarily.
+ if (not state.osc_visible) or (get_hidetimeout() >= 0) or
+ (state.fullscreen and not user_opts.showfullscreen) or
+ (not state.fullscreen and not user_opts.showwindowed)
+ then
+ margins = {l = 0, r = 0, t = 0, b = 0}
+ end
+
+ if user_opts.boxvideo then
+ -- check whether any margin option has a non-default value
+ local margins_used = false
+
+ if not state.using_video_margins then
+ for _, opt in ipairs(margins_opts) do
+ if mp.get_property_number(opt[2], 0.0) ~= 0.0 then
+ margins_used = true
+ end
+ end
+ end
+
+ if not margins_used then
+ for _, opt in ipairs(margins_opts) do
+ local v = margins[opt[1]]
+ if (v ~= 0) or state.using_video_margins then
+ mp.set_property_number(opt[2], v)
+ state.using_video_margins = true
+ end
+ end
+ end
+ else
+ reset_margins()
+ end
+
+ utils.shared_script_property_set("osc-margins",
+ string.format("%f,%f,%f,%f", margins.l, margins.r, margins.t, margins.b))
+end
+
+function shutdown()
+ reset_margins()
+ utils.shared_script_property_set("osc-margins", nil)
+end
+
+--
+-- Other important stuff
+--
+
+
+function show_osc()
+ -- show when disabled can happen (e.g. mouse_move) due to async/delayed unbinding
+ if not state.enabled then return end
+
+ msg.trace("show_osc")
+ --remember last time of invocation (mouse move)
+ state.showtime = mp.get_time()
+
+ osc_visible(true)
+
+ if (user_opts.fadeduration > 0) then
+ state.anitype = nil
+ end
+end
+
+function hide_osc()
+ msg.trace("hide_osc")
+ if not state.enabled then
+ -- typically hide happens at render() from tick(), but now tick() is
+ -- no-op and won't render again to remove the osc, so do that manually.
+ state.osc_visible = false
+ render_wipe()
+ elseif (user_opts.fadeduration > 0) then
+ if not(state.osc_visible == false) then
+ state.anitype = "out"
+ request_tick()
+ end
+ else
+ osc_visible(false)
+ end
+end
+
+function osc_visible(visible)
+ if state.osc_visible ~= visible then
+ state.osc_visible = visible
+ update_margins()
+ end
+ request_tick()
+end
+
+function pause_state(name, enabled)
+ state.paused = enabled
+ request_tick()
+end
+
+function cache_state(name, st)
+ state.cache_state = st
+ request_tick()
+end
+
+-- Request that tick() is called (which typically re-renders the OSC).
+-- The tick is then either executed immediately, or rate-limited if it was
+-- called a small time ago.
+function request_tick()
+ if state.tick_timer == nil then
+ state.tick_timer = mp.add_timeout(0, tick)
+ end
+
+ if not state.tick_timer:is_enabled() then
+ local now = mp.get_time()
+ local timeout = tick_delay - (now - state.tick_last_time)
+ if timeout < 0 then
+ timeout = 0
+ end
+ state.tick_timer.timeout = timeout
+ state.tick_timer:resume()
+ end
+end
+
+function mouse_leave()
+ if get_hidetimeout() >= 0 then
+ hide_osc()
+ end
+ -- reset mouse position
+ state.last_mouseX, state.last_mouseY = nil, nil
+ state.mouse_in_window = false
+end
+
+function request_init()
+ state.initREQ = true
+ request_tick()
+end
+
+-- Like request_init(), but also request an immediate update
+function request_init_resize()
+ request_init()
+ -- ensure immediate update
+ state.tick_timer:kill()
+ state.tick_timer.timeout = 0
+ state.tick_timer:resume()
+end
+
+function render_wipe()
+ msg.trace("render_wipe()")
+ state.osd.data = "" -- allows set_osd to immediately update on enable
+ state.osd:remove()
+end
+
+function render()
+ msg.trace("rendering")
+ local current_screen_sizeX, current_screen_sizeY, aspect = mp.get_osd_size()
+ local mouseX, mouseY = get_virt_mouse_pos()
+ local now = mp.get_time()
+
+ -- check if display changed, if so request reinit
+ if not (state.mp_screen_sizeX == current_screen_sizeX
+ and state.mp_screen_sizeY == current_screen_sizeY) then
+
+ request_init_resize()
+
+ state.mp_screen_sizeX = current_screen_sizeX
+ state.mp_screen_sizeY = current_screen_sizeY
+ end
+
+ -- init management
+ if state.active_element then
+ -- mouse is held down on some element - keep ticking and igore initReq
+ -- till it's released, or else the mouse-up (click) will misbehave or
+ -- get ignored. that's because osc_init() recreates the osc elements,
+ -- but mouse handling depends on the elements staying unmodified
+ -- between mouse-down and mouse-up (using the index active_element).
+ request_tick()
+ elseif state.initREQ then
+ osc_init()
+ state.initREQ = false
+
+ -- store initial mouse position
+ if (state.last_mouseX == nil or state.last_mouseY == nil)
+ and not (mouseX == nil or mouseY == nil) then
+
+ state.last_mouseX, state.last_mouseY = mouseX, mouseY
+ end
+ end
+
+
+ -- fade animation
+ if not(state.anitype == nil) then
+
+ if (state.anistart == nil) then
+ state.anistart = now
+ end
+
+ if (now < state.anistart + (user_opts.fadeduration/1000)) then
+
+ if (state.anitype == "in") then --fade in
+ osc_visible(true)
+ state.animation = scale_value(state.anistart,
+ (state.anistart + (user_opts.fadeduration/1000)),
+ 255, 0, now)
+ elseif (state.anitype == "out") then --fade out
+ state.animation = scale_value(state.anistart,
+ (state.anistart + (user_opts.fadeduration/1000)),
+ 0, 255, now)
+ end
+
+ else
+ if (state.anitype == "out") then
+ osc_visible(false)
+ end
+ kill_animation()
+ end
+ else
+ kill_animation()
+ end
+
+ --mouse show/hide area
+ for k,cords in pairs(osc_param.areas["showhide"]) do
+ set_virt_mouse_area(cords.x1, cords.y1, cords.x2, cords.y2, "showhide")
+ end
+ if osc_param.areas["showhide_wc"] then
+ for k,cords in pairs(osc_param.areas["showhide_wc"]) do
+ set_virt_mouse_area(cords.x1, cords.y1, cords.x2, cords.y2, "showhide_wc")
+ end
+ else
+ set_virt_mouse_area(0, 0, 0, 0, "showhide_wc")
+ end
+ do_enable_keybindings()
+
+ --mouse input area
+ local mouse_over_osc = false
+
+ for _,cords in ipairs(osc_param.areas["input"]) do
+ if state.osc_visible then -- activate only when OSC is actually visible
+ set_virt_mouse_area(cords.x1, cords.y1, cords.x2, cords.y2, "input")
+ end
+ if state.osc_visible ~= state.input_enabled then
+ if state.osc_visible then
+ mp.enable_key_bindings("input")
+ else
+ mp.disable_key_bindings("input")
+ end
+ state.input_enabled = state.osc_visible
+ end
+
+ if (mouse_hit_coords(cords.x1, cords.y1, cords.x2, cords.y2)) then
+ mouse_over_osc = true
+ end
+ end
+
+ if osc_param.areas["window-controls"] then
+ for _,cords in ipairs(osc_param.areas["window-controls"]) do
+ if state.osc_visible then -- activate only when OSC is actually visible
+ set_virt_mouse_area(cords.x1, cords.y1, cords.x2, cords.y2, "window-controls")
+ mp.enable_key_bindings("window-controls")
+ else
+ mp.disable_key_bindings("window-controls")
+ end
+
+ if (mouse_hit_coords(cords.x1, cords.y1, cords.x2, cords.y2)) then
+ mouse_over_osc = true
+ end
+ end
+ end
+
+ if osc_param.areas["window-controls-title"] then
+ for _,cords in ipairs(osc_param.areas["window-controls-title"]) do
+ if (mouse_hit_coords(cords.x1, cords.y1, cords.x2, cords.y2)) then
+ mouse_over_osc = true
+ end
+ end
+ end
+
+ -- autohide
+ if not (state.showtime == nil) and (get_hidetimeout() >= 0) then
+ local timeout = state.showtime + (get_hidetimeout()/1000) - now
+ if timeout <= 0 then
+ if (state.active_element == nil) and not (mouse_over_osc) then
+ hide_osc()
+ end
+ else
+ -- the timer is only used to recheck the state and to possibly run
+ -- the code above again
+ if not state.hide_timer then
+ state.hide_timer = mp.add_timeout(0, tick)
+ end
+ state.hide_timer.timeout = timeout
+ -- re-arm
+ state.hide_timer:kill()
+ state.hide_timer:resume()
+ end
+ end
+
+
+ -- actual rendering
+ local ass = assdraw.ass_new()
+
+ -- Messages
+ render_message(ass)
+
+ -- actual OSC
+ if state.osc_visible then
+ render_elements(ass)
+ end
+
+ -- submit
+ set_osd(osc_param.playresy * osc_param.display_aspect,
+ osc_param.playresy, ass.text)
+end
+
+--
+-- Eventhandling
+--
+
+local function element_has_action(element, action)
+ return element and element.eventresponder and
+ element.eventresponder[action]
+end
+
+function process_event(source, what)
+ local action = string.format("%s%s", source,
+ what and ("_" .. what) or "")
+
+ if what == "down" or what == "press" then
+
+ for n = 1, #elements do
+
+ if mouse_hit(elements[n]) and
+ elements[n].eventresponder and
+ (elements[n].eventresponder[source .. "_up"] or
+ elements[n].eventresponder[action]) then
+
+ if what == "down" then
+ state.active_element = n
+ state.active_event_source = source
+ end
+ -- fire the down or press event if the element has one
+ if element_has_action(elements[n], action) then
+ elements[n].eventresponder[action](elements[n])
+ end
+
+ end
+ end
+
+ elseif what == "up" then
+
+ if elements[state.active_element] then
+ local n = state.active_element
+
+ if n == 0 then
+ --click on background (does not work)
+ elseif element_has_action(elements[n], action) and
+ mouse_hit(elements[n]) then
+
+ elements[n].eventresponder[action](elements[n])
+ end
+
+ --reset active element
+ if element_has_action(elements[n], "reset") then
+ elements[n].eventresponder["reset"](elements[n])
+ end
+
+ end
+ state.active_element = nil
+ state.mouse_down_counter = 0
+
+ elseif source == "mouse_move" then
+
+ state.mouse_in_window = true
+
+ local mouseX, mouseY = get_virt_mouse_pos()
+ if (user_opts.minmousemove == 0) or
+ (not ((state.last_mouseX == nil) or (state.last_mouseY == nil)) and
+ ((math.abs(mouseX - state.last_mouseX) >= user_opts.minmousemove)
+ or (math.abs(mouseY - state.last_mouseY) >= user_opts.minmousemove)
+ )
+ ) then
+ show_osc()
+ end
+ state.last_mouseX, state.last_mouseY = mouseX, mouseY
+
+ local n = state.active_element
+ if element_has_action(elements[n], action) then
+ elements[n].eventresponder[action](elements[n])
+ end
+ end
+
+ -- ensure rendering after any (mouse) event - icons could change etc
+ request_tick()
+end
+
+
+local logo_lines = {
+ -- White border
+ "{\\c&HE5E5E5&\\p6}m 895 10 b 401 10 0 410 0 905 0 1399 401 1800 895 1800 1390 1800 1790 1399 1790 905 1790 410 1390 10 895 10 {\\p0}",
+ -- Purple fill
+ "{\\c&H682167&\\p6}m 925 42 b 463 42 87 418 87 880 87 1343 463 1718 925 1718 1388 1718 1763 1343 1763 880 1763 418 1388 42 925 42{\\p0}",
+ -- Darker fill
+ "{\\c&H430142&\\p6}m 1605 828 b 1605 1175 1324 1456 977 1456 631 1456 349 1175 349 828 349 482 631 200 977 200 1324 200 1605 482 1605 828{\\p0}",
+ -- White fill
+ "{\\c&HDDDBDD&\\p6}m 1296 910 b 1296 1131 1117 1310 897 1310 676 1310 497 1131 497 910 497 689 676 511 897 511 1117 511 1296 689 1296 910{\\p0}",
+ -- Triangle
+ "{\\c&H691F69&\\p6}m 762 1113 l 762 708 b 881 776 1000 843 1119 911 1000 978 881 1046 762 1113{\\p0}",
+}
+
+local santa_hat_lines = {
+ -- Pompoms
+ "{\\c&HC0C0C0&\\p6}m 500 -323 b 491 -322 481 -318 475 -311 465 -312 456 -319 446 -318 434 -314 427 -304 417 -297 410 -290 404 -282 395 -278 390 -274 387 -267 381 -265 377 -261 379 -254 384 -253 397 -244 409 -232 425 -228 437 -228 446 -218 457 -217 462 -216 466 -213 468 -209 471 -205 477 -203 482 -206 491 -211 499 -217 508 -222 532 -235 556 -249 576 -267 584 -272 584 -284 578 -290 569 -305 550 -312 533 -309 523 -310 515 -316 507 -321 505 -323 503 -323 500 -323{\\p0}",
+ "{\\c&HE0E0E0&\\p6}m 315 -260 b 286 -258 259 -240 246 -215 235 -210 222 -215 211 -211 204 -188 177 -176 172 -151 170 -139 163 -128 154 -121 143 -103 141 -81 143 -60 139 -46 125 -34 129 -17 132 -1 134 16 142 30 145 56 161 80 181 96 196 114 210 133 231 144 266 153 303 138 328 115 373 79 401 28 423 -24 446 -73 465 -123 483 -174 487 -199 467 -225 442 -227 421 -232 402 -242 384 -254 364 -259 342 -250 322 -260 320 -260 317 -261 315 -260{\\p0}",
+ -- Main cap
+ "{\\c&H0000F0&\\p6}m 1151 -523 b 1016 -516 891 -458 769 -406 693 -369 624 -319 561 -262 526 -252 465 -235 479 -187 502 -147 551 -135 588 -111 1115 165 1379 232 1909 761 1926 800 1952 834 1987 858 2020 883 2053 912 2065 952 2088 1000 2146 962 2139 919 2162 836 2156 747 2143 662 2131 615 2116 567 2122 517 2120 410 2090 306 2089 199 2092 147 2071 99 2034 64 1987 5 1928 -41 1869 -86 1777 -157 1712 -256 1629 -337 1578 -389 1521 -436 1461 -476 1407 -509 1343 -507 1284 -515 1240 -519 1195 -521 1151 -523{\\p0}",
+ -- Cap shadow
+ "{\\c&H0000AA&\\p6}m 1657 248 b 1658 254 1659 261 1660 267 1669 276 1680 284 1689 293 1695 302 1700 311 1707 320 1716 325 1726 330 1735 335 1744 347 1752 360 1761 371 1753 352 1754 331 1753 311 1751 237 1751 163 1751 90 1752 64 1752 37 1767 14 1778 -3 1785 -24 1786 -45 1786 -60 1786 -77 1774 -87 1760 -96 1750 -78 1751 -65 1748 -37 1750 -8 1750 20 1734 78 1715 134 1699 192 1694 211 1689 231 1676 246 1671 251 1661 255 1657 248 m 1909 541 b 1914 542 1922 549 1917 539 1919 520 1921 502 1919 483 1918 458 1917 433 1915 407 1930 373 1942 338 1947 301 1952 270 1954 238 1951 207 1946 214 1947 229 1945 239 1939 278 1936 318 1924 356 1923 362 1913 382 1912 364 1906 301 1904 237 1891 175 1887 150 1892 126 1892 101 1892 68 1893 35 1888 2 1884 -9 1871 -20 1859 -14 1851 -6 1854 9 1854 20 1855 58 1864 95 1873 132 1883 179 1894 225 1899 273 1908 362 1910 451 1909 541{\\p0}",
+ -- Brim and tip pompom
+ "{\\c&HF8F8F8&\\p6}m 626 -191 b 565 -155 486 -196 428 -151 387 -115 327 -101 304 -47 273 2 267 59 249 113 219 157 217 213 215 265 217 309 260 302 285 283 373 264 465 264 555 257 608 252 655 292 709 287 759 294 816 276 863 298 903 340 972 324 1012 367 1061 394 1125 382 1167 424 1213 462 1268 482 1322 506 1385 546 1427 610 1479 662 1510 690 1534 725 1566 752 1611 796 1664 830 1703 880 1740 918 1747 986 1805 1005 1863 991 1897 932 1916 880 1914 823 1945 777 1961 725 1979 673 1957 622 1938 575 1912 534 1862 515 1836 473 1790 417 1755 351 1697 305 1658 266 1633 216 1593 176 1574 138 1539 116 1497 110 1448 101 1402 77 1371 37 1346 -16 1295 15 1254 6 1211 -27 1170 -62 1121 -86 1072 -104 1027 -128 976 -133 914 -130 851 -137 794 -162 740 -181 679 -168 626 -191 m 2051 917 b 1971 932 1929 1017 1919 1091 1912 1149 1923 1214 1970 1254 2000 1279 2027 1314 2066 1325 2139 1338 2212 1295 2254 1238 2281 1203 2287 1158 2282 1116 2292 1061 2273 1006 2229 970 2206 941 2167 938 2138 918{\\p0}",
+}
+
+-- called by mpv on every frame
+function tick()
+ if state.marginsREQ == true then
+ update_margins()
+ state.marginsREQ = false
+ end
+
+ if (not state.enabled) then return end
+
+ if (state.idle) then
+
+ -- render idle message
+ msg.trace("idle message")
+ local icon_x, icon_y = 320 - 26, 140
+ local line_prefix = ("{\\rDefault\\an7\\1a&H00&\\bord0\\shad0\\pos(%f,%f)}"):format(icon_x, icon_y)
+
+ local ass = assdraw.ass_new()
+ -- mpv logo
+ if user_opts.idlescreen then
+ for i, line in ipairs(logo_lines) do
+ ass:new_event()
+ ass:append(line_prefix .. line)
+ end
+ end
+
+ -- Santa hat
+ if is_december and user_opts.idlescreen and not user_opts.greenandgrumpy then
+ for i, line in ipairs(santa_hat_lines) do
+ ass:new_event()
+ ass:append(line_prefix .. line)
+ end
+ end
+
+ if user_opts.idlescreen then
+ ass:new_event()
+ ass:pos(320, icon_y+65)
+ ass:an(8)
+ ass:append("Drop files or URLs to play here.")
+ end
+ set_osd(640, 360, ass.text)
+
+ if state.showhide_enabled then
+ mp.disable_key_bindings("showhide")
+ mp.disable_key_bindings("showhide_wc")
+ state.showhide_enabled = false
+ end
+
+
+ elseif (state.fullscreen and user_opts.showfullscreen)
+ or (not state.fullscreen and user_opts.showwindowed) then
+
+ -- render the OSC
+ render()
+ else
+ -- Flush OSD
+ render_wipe()
+ end
+
+ state.tick_last_time = mp.get_time()
+
+ if state.anitype ~= nil then
+ -- state.anistart can be nil - animation should now start, or it can
+ -- be a timestamp when it started. state.idle has no animation.
+ if not state.idle and
+ (not state.anistart or
+ mp.get_time() < 1 + state.anistart + user_opts.fadeduration/1000)
+ then
+ -- animating or starting, or still within 1s past the deadline
+ request_tick()
+ else
+ kill_animation()
+ end
+ end
+end
+
+function do_enable_keybindings()
+ if state.enabled then
+ if not state.showhide_enabled then
+ mp.enable_key_bindings("showhide", "allow-vo-dragging+allow-hide-cursor")
+ mp.enable_key_bindings("showhide_wc", "allow-vo-dragging+allow-hide-cursor")
+ end
+ state.showhide_enabled = true
+ end
+end
+
+function enable_osc(enable)
+ state.enabled = enable
+ if enable then
+ do_enable_keybindings()
+ else
+ hide_osc() -- acts immediately when state.enabled == false
+ if state.showhide_enabled then
+ mp.disable_key_bindings("showhide")
+ mp.disable_key_bindings("showhide_wc")
+ end
+ state.showhide_enabled = false
+ end
+end
+
+-- duration is observed for the sole purpose of updating chapter markers
+-- positions. live streams with chapters are very rare, and the update is also
+-- expensive (with request_init), so it's only observed when we have chapters
+-- and the user didn't disable the livemarkers option (update_duration_watch).
+function on_duration() request_init() end
+
+local duration_watched = false
+function update_duration_watch()
+ local want_watch = user_opts.livemarkers and
+ (mp.get_property_number("chapters", 0) or 0) > 0 and
+ true or false -- ensure it's a boolean
+
+ if (want_watch ~= duration_watched) then
+ if want_watch then
+ mp.observe_property("duration", nil, on_duration)
+ else
+ mp.unobserve_property(on_duration)
+ end
+ duration_watched = want_watch
+ end
+end
+
+validate_user_opts()
+update_duration_watch()
+
+mp.register_event("shutdown", shutdown)
+mp.register_event("start-file", request_init)
+mp.observe_property("track-list", nil, request_init)
+mp.observe_property("playlist", nil, request_init)
+mp.observe_property("chapter-list", "native", function(_, list)
+ list = list or {} -- safety, shouldn't return nil
+ table.sort(list, function(a, b) return a.time < b.time end)
+ state.chapter_list = list
+ update_duration_watch()
+ request_init()
+end)
+
+mp.register_script_message("osc-message", show_message)
+mp.register_script_message("osc-chapterlist", function(dur)
+ show_message(get_chapterlist(), dur)
+end)
+mp.register_script_message("osc-playlist", function(dur)
+ show_message(get_playlist(), dur)
+end)
+mp.register_script_message("osc-tracklist", function(dur)
+ local msg = {}
+ for k,v in pairs(nicetypes) do
+ table.insert(msg, get_tracklist(k))
+ end
+ show_message(table.concat(msg, '\n\n'), dur)
+end)
+
+mp.observe_property("fullscreen", "bool",
+ function(name, val)
+ state.fullscreen = val
+ state.marginsREQ = true
+ request_init_resize()
+ end
+)
+mp.observe_property("border", "bool",
+ function(name, val)
+ state.border = val
+ request_init_resize()
+ end
+)
+mp.observe_property("window-maximized", "bool",
+ function(name, val)
+ state.maximized = val
+ request_init_resize()
+ end
+)
+mp.observe_property("idle-active", "bool",
+ function(name, val)
+ state.idle = val
+ request_tick()
+ end
+)
+mp.observe_property("pause", "bool", pause_state)
+mp.observe_property("demuxer-cache-state", "native", cache_state)
+mp.observe_property("vo-configured", "bool", function(name, val)
+ request_tick()
+end)
+mp.observe_property("playback-time", "number", function(name, val)
+ request_tick()
+end)
+mp.observe_property("osd-dimensions", "native", function(name, val)
+ -- (we could use the value instead of re-querying it all the time, but then
+ -- we might have to worry about property update ordering)
+ request_init_resize()
+end)
+
+-- mouse show/hide bindings
+mp.set_key_bindings({
+ {"mouse_move", function(e) process_event("mouse_move", nil) end},
+ {"mouse_leave", mouse_leave},
+}, "showhide", "force")
+mp.set_key_bindings({
+ {"mouse_move", function(e) process_event("mouse_move", nil) end},
+ {"mouse_leave", mouse_leave},
+}, "showhide_wc", "force")
+do_enable_keybindings()
+
+--mouse input bindings
+mp.set_key_bindings({
+ {"mbtn_left", function(e) process_event("mbtn_left", "up") end,
+ function(e) process_event("mbtn_left", "down") end},
+ {"shift+mbtn_left", function(e) process_event("shift+mbtn_left", "up") end,
+ function(e) process_event("shift+mbtn_left", "down") end},
+ {"mbtn_right", function(e) process_event("mbtn_right", "up") end,
+ function(e) process_event("mbtn_right", "down") end},
+ -- alias to shift_mbtn_left for single-handed mouse use
+ {"mbtn_mid", function(e) process_event("shift+mbtn_left", "up") end,
+ function(e) process_event("shift+mbtn_left", "down") end},
+ {"wheel_up", function(e) process_event("wheel_up", "press") end},
+ {"wheel_down", function(e) process_event("wheel_down", "press") end},
+ {"mbtn_left_dbl", "ignore"},
+ {"shift+mbtn_left_dbl", "ignore"},
+ {"mbtn_right_dbl", "ignore"},
+}, "input", "force")
+mp.enable_key_bindings("input")
+
+mp.set_key_bindings({
+ {"mbtn_left", function(e) process_event("mbtn_left", "up") end,
+ function(e) process_event("mbtn_left", "down") end},
+}, "window-controls", "force")
+mp.enable_key_bindings("window-controls")
+
+function get_hidetimeout()
+ if user_opts.visibility == "always" then
+ return -1 -- disable autohide
+ end
+ return user_opts.hidetimeout
+end
+
+function always_on(val)
+ if state.enabled then
+ if val then
+ show_osc()
+ else
+ hide_osc()
+ end
+ end
+end
+
+-- mode can be auto/always/never/cycle
+-- the modes only affect internal variables and not stored on its own.
+function visibility_mode(mode, no_osd)
+ if mode == "cycle" then
+ if not state.enabled then
+ mode = "auto"
+ elseif user_opts.visibility ~= "always" then
+ mode = "always"
+ else
+ mode = "never"
+ end
+ end
+
+ if mode == "auto" then
+ always_on(false)
+ enable_osc(true)
+ elseif mode == "always" then
+ enable_osc(true)
+ always_on(true)
+ elseif mode == "never" then
+ enable_osc(false)
+ else
+ msg.warn("Ignoring unknown visibility mode '" .. mode .. "'")
+ return
+ end
+
+ user_opts.visibility = mode
+ utils.shared_script_property_set("osc-visibility", mode)
+
+ if not no_osd and tonumber(mp.get_property("osd-level")) >= 1 then
+ mp.osd_message("OSC visibility: " .. mode)
+ end
+
+ -- Reset the input state on a mode change. The input state will be
+ -- recalculated on the next render cycle, except in 'never' mode where it
+ -- will just stay disabled.
+ mp.disable_key_bindings("input")
+ mp.disable_key_bindings("window-controls")
+ state.input_enabled = false
+
+ update_margins()
+ request_tick()
+end
+
+function idlescreen_visibility(mode, no_osd)
+ if mode == "cycle" then
+ if user_opts.idlescreen then
+ mode = "no"
+ else
+ mode = "yes"
+ end
+ end
+
+ if mode == "yes" then
+ user_opts.idlescreen = true
+ else
+ user_opts.idlescreen = false
+ end
+
+ utils.shared_script_property_set("osc-idlescreen", mode)
+
+ if not no_osd and tonumber(mp.get_property("osd-level")) >= 1 then
+ mp.osd_message("OSC logo visibility: " .. tostring(mode))
+ end
+
+ request_tick()
+end
+
+visibility_mode(user_opts.visibility, true)
+mp.register_script_message("osc-visibility", visibility_mode)
+mp.add_key_binding(nil, "visibility", function() visibility_mode("cycle") end)
+
+mp.register_script_message("osc-idlescreen", idlescreen_visibility)
+
+set_virt_mouse_area(0, 0, 0, 0, "input")
+set_virt_mouse_area(0, 0, 0, 0, "window-controls")
diff --git a/mpv/scripts/quality-menu.lua b/mpv/scripts/quality-menu.lua
new file mode 100644
index 0000000..c5da0d3
--- /dev/null
+++ b/mpv/scripts/quality-menu.lua
@@ -0,0 +1,806 @@
+-- quality-menu.lua
+--
+-- Change the stream video and audio quality on the fly.
+--
+-- Usage:
+-- add bindings to input.conf:
+-- Ctrl+f script-message-to quality_menu video_formats_toggle
+-- Alt+f script-message-to quality_menu audio_formats_toggle
+--
+-- Displays a menu that lets you switch to different ytdl-format settings while
+-- you're in the middle of a video (just like you were using the web player).
+
+local mp = require 'mp'
+local utils = require 'mp.utils'
+local msg = require 'mp.msg'
+local assdraw = require 'mp.assdraw'
+local opt = require('mp.options')
+
+local opts = {
+ --key bindings
+ up_binding = "UP WHEEL_UP",
+ down_binding = "DOWN WHEEL_DOWN",
+ select_binding = "ENTER MBTN_LEFT",
+ close_menu_binding = "ESC MBTN_RIGHT Ctrl+f Alt+f",
+
+ --youtube-dl version(could be youtube-dl or yt-dlp, or something else)
+ ytdl_ver = "yt-dlp",
+
+ --formatting / cursors
+ selected_and_active = "▶ - ",
+ selected_and_inactive = "● - ",
+ unselected_and_active = "▷ - ",
+ unselected_and_inactive = "○ - ",
+
+ --font size scales by window, if false requires larger font and padding sizes
+ scale_playlist_by_window=true,
+
+ --playlist ass style overrides inside curly brackets, \keyvalue is one field, extra \ for escape in lua
+ --example {\\fnUbuntu\\fs10\\b0\\bord1} equals: font=Ubuntu, size=10, bold=no, border=1
+ --read http://docs.aegisub.org/3.2/ASS_Tags/ for reference of tags
+ --undeclared tags will use default osd settings
+ --these styles will be used for the whole playlist. More specific styling will need to be hacked in
+ --
+ --(a monospaced font is recommended but not required)
+ style_ass_tags = "{\\fnmonospace\\fs10\\bord1}",
+
+ --paddings for top left corner
+ text_padding_x = 5,
+ text_padding_y = 5,
+
+ --how many seconds until the quality menu times out
+ --setting this to 0 deactivates the timeout
+ menu_timeout = 6,
+
+ --use youtube-dl to fetch a list of available formats (overrides quality_strings)
+ fetch_formats = true,
+
+ --default menu entries
+ quality_strings=[[
+ [
+ {"4320p" : "bestvideo[height<=?4320p]+bestaudio/best"},
+ {"2160p" : "bestvideo[height<=?2160]+bestaudio/best"},
+ {"1440p" : "bestvideo[height<=?1440]+bestaudio/best"},
+ {"1080p" : "bestvideo[height<=?1080]+bestaudio/best"},
+ {"720p" : "bestvideo[height<=?720]+bestaudio/best"},
+ {"480p" : "bestvideo[height<=?480]+bestaudio/best"},
+ {"360p" : "bestvideo[height<=?360]+bestaudio/best"},
+ {"240p" : "bestvideo[height<=?240]+bestaudio/best"},
+ {"144p" : "bestvideo[height<=?144]+bestaudio/best"}
+ ]
+ ]],
+
+ --reset ytdl-format to the original format string when changing files (e.g. going to the next playlist entry)
+ --if file was opened previously, reset to previously selected format
+ reset_format = true,
+
+ --automatically fetch available formats when opening an url
+ fetch_on_start = true,
+
+ --show the video format menu after opening an url
+ start_with_menu = false,
+
+ --include unknown formats in the list
+ --Unfortunately choosing which formats are video or audio is not always perfect.
+ --Set to true to make sure you don't miss any formats, but then the list
+ --might also include formats that aren't actually video or audio.
+ --Formats that are known to not be video or audio are still filtered out.
+ include_unknown = false,
+
+ --hide columns that are identical for all formats
+ hide_identical_columns = true,
+
+ --which columns are shown in which order
+ --comma separated list, prefix column with "-" to align left
+ --
+ --columns that might be useful are:
+ --resolution, width, height, fps, dynamic_range, tbr, vbr, abr, asr,
+ --filesize, filesize_approx, vcodec, acodec, ext, video_ext, audio_ext,
+ --language, format, format_note, quality
+ --
+ --columns that are derived from the above, but with special treatment:
+ --frame_rate, bitrate_total, bitrate_video, bitrate_audio,
+ --codec_video, codec_audio, audio_sample_rate
+ --
+ --If those still aren't enough or you're just curious, run:
+ --yt-dlp -j <url>
+ --This outputs unformatted JSON.
+ --Format it and look under "formats" to see what's available.
+ --
+ --Not all videos have all columns available.
+ --Be careful, misspelled columns simply won't be displayed, there is no error.
+ columns_video = '-resolution,frame_rate,dynamic_range,language,bitrate_total,size,-codec_video,-codec_audio',
+ columns_audio = 'audio_sample_rate,bitrate_total,size,language,-codec_audio',
+
+ --columns used for sorting, see "columns_video" for available columns
+ --comma separated list, prefix column with "-" to reverse sorting order
+ --Leaving this empty keeps the order from yt-dlp/youtube-dl.
+ --Be careful, misspelled columns won't result in an error,
+ --but they might influence the result.
+ sort_video = 'height,fps,tbr,size,format_id',
+ sort_audio = 'asr,tbr,size,format_id',
+}
+opt.read_options(opts, "quality-menu")
+opts.quality_strings = utils.parse_json(opts.quality_strings)
+
+-- special thanks to reload.lua (https://github.com/4e6/mpv-reload/)
+local function reload_resume()
+ local playlist_pos = mp.get_property_number("playlist-pos")
+ local reload_duration = mp.get_property_native("duration")
+ local time_pos = mp.get_property("time-pos")
+
+ mp.set_property_number("playlist-pos", playlist_pos)
+
+ -- Tries to determine live stream vs. pre-recorded VOD. VOD has non-zero
+ -- duration property. When reloading VOD, to keep the current time position
+ -- we should provide offset from the start. Stream doesn't have fixed start.
+ -- Decent choice would be to reload stream from it's current 'live' position.
+ -- That's the reason we don't pass the offset when reloading streams.
+ if reload_duration and reload_duration > 0 then
+ local function seeker()
+ mp.commandv("seek", time_pos, "absolute")
+ mp.unregister_event(seeker)
+ end
+ mp.register_event("file-loaded", seeker)
+ end
+end
+
+local ytdl = {
+ path = opts.ytdl_ver,
+ searched = false,
+ blacklisted = {}
+}
+
+local function process_json(json)
+ local function is_video(format)
+ -- "none" means it is not a video
+ -- nil means it is unknown
+ return (opts.include_unknown or format.vcodec) and format.vcodec ~= "none"
+ end
+
+ local function is_audio(format)
+ return (opts.include_unknown or format.acodec) and format.acodec ~= "none"
+ end
+
+ local vfmt = nil
+ local afmt = nil
+ local requested_formats = json["requested_formats"] or json["requested_downloads"]
+ for _, format in ipairs(requested_formats) do
+ if is_video(format) then
+ vfmt = format["format_id"]
+ elseif is_audio(format) then
+ afmt = format["format_id"]
+ end
+ end
+
+ local video_formats = {}
+ local audio_formats = {}
+ local all_formats = {}
+ for i = #json.formats, 1, -1 do
+ local format = json.formats[i]
+ if is_video(format) then
+ video_formats[#video_formats+1] = format
+ all_formats[#all_formats+1] = format
+ elseif is_audio(format) then
+ audio_formats[#audio_formats+1] = format
+ all_formats[#all_formats+1] = format
+ end
+ end
+
+ local function populate_special_fields(format)
+ format.size = format.filesize or format.filesize_approx
+ format.frame_rate = format.fps
+ format.bitrate_total = format.tbr
+ format.bitrate_video = format.vbr
+ format.bitrate_audio = format.abr
+ format.codec_video = format.vcodec
+ format.codec_audio = format.acodec
+ format.audio_sample_rate = format.asr
+ end
+
+ for _,format in ipairs(all_formats) do
+ populate_special_fields(format)
+ end
+
+ local function strip_minus(list)
+ local stripped_list = {}
+ local had_minus = {}
+ for i, val in ipairs(list) do
+ if string.sub(val, 1, 1) == "-" then
+ val = string.sub(val, 2)
+ had_minus[val] = true
+ end
+ stripped_list[i] = val
+ end
+ return stripped_list, had_minus
+ end
+
+ local function string_split (inputstr, sep)
+ if sep == nil then
+ sep = "%s"
+ end
+ local t={}
+ for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
+ table.insert(t, str)
+ end
+ return t
+ end
+
+ local sort_video, reverse_video = strip_minus(string_split(opts.sort_video, ','))
+ local sort_audio, reverse_audio = strip_minus(string_split(opts.sort_audio, ','))
+
+ local function comp(properties, reverse)
+ return function (a, b)
+ for _,prop in ipairs(properties) do
+ local a_val = a[prop]
+ local b_val = b[prop]
+ if a_val and b_val and type(a_val) ~= 'table' and a_val ~= b_val then
+ if reverse[prop] then
+ return a_val < b_val
+ else
+ return a_val > b_val
+ end
+ end
+ end
+ return false
+ end
+ end
+
+ if #sort_video > 0 then
+ table.sort(video_formats, comp(sort_video, reverse_video))
+ end
+ if #sort_audio > 0 then
+ table.sort(audio_formats, comp(sort_audio, reverse_audio))
+ end
+
+ local function scale_filesize(size)
+ if size == nil then
+ return ""
+ end
+ size = tonumber(size)
+
+ local counter = 0
+ while size > 1024 do
+ size = size / 1024
+ counter = counter+1
+ end
+
+ if counter >= 3 then return string.format("%.1fGiB", size)
+ elseif counter >= 2 then return string.format("%.1fMiB", size)
+ elseif counter >= 1 then return string.format("%.1fKiB", size)
+ else return string.format("%.1fB ", size)
+ end
+ end
+
+ local function scale_bitrate(br)
+ if br == nil then
+ return ""
+ end
+ br = tonumber(br)
+
+ local counter = 0
+ while br > 1000 do
+ br = br / 1000
+ counter = counter+1
+ end
+
+ if counter >= 2 then return string.format("%.1fGbps", br)
+ elseif counter >= 1 then return string.format("%.1fMbps", br)
+ else return string.format("%.1fKbps", br)
+ end
+ end
+
+ local function format_special_fields(format)
+ local size_prefix = not format.filesize and format.filesize_approx and "~" or ""
+ format.size = (size_prefix) .. scale_filesize(format.size)
+ format.frame_rate = format.fps and format.fps.."fps" or ""
+ format.bitrate_total = scale_bitrate(format.tbr)
+ format.bitrate_video = scale_bitrate(format.vbr)
+ format.bitrate_audio = scale_bitrate(format.abr)
+ format.codec_video = format.vcodec == nil and "unknown" or format.vcodec == "none" and "" or format.vcodec
+ format.codec_audio = format.acodec == nil and "unknown" or format.acodec == "none" and "" or format.acodec
+ format.audio_sample_rate = format.asr and tostring(format.asr) .. "Hz" or ""
+ end
+
+ for _,format in ipairs(all_formats) do
+ format_special_fields(format)
+ end
+
+ local function format_table(formats, columns)
+ local function calc_shown_columns()
+ local display_col = {}
+ local column_widths = {}
+ local column_values = {}
+ local columns, column_align_left = strip_minus(columns)
+
+ for _,format in pairs(formats) do
+ for col, prop in ipairs(columns) do
+ local label = tostring(format[prop] or "")
+ format[prop] = label
+
+ if not column_widths[col] or column_widths[col] < label:len() then
+ column_widths[col] = label:len()
+ end
+
+ column_values[col] = column_values[col] or label
+ display_col[col] = display_col[col] or (column_values[col] ~= label)
+ end
+ end
+
+ local show_columns={}
+ for i, width in ipairs(column_widths) do
+ if width > 0 and not opts.hide_identical_columns or display_col[i] then
+ local prop = columns[i]
+ show_columns[#show_columns+1] = {
+ prop=prop,
+ width=width,
+ align_left=column_align_left[prop]
+ }
+ end
+ end
+ return show_columns
+ end
+
+ local show_columns = calc_shown_columns()
+
+ local spacing = 2
+ local res = {}
+ for _,f in ipairs(formats) do
+ local row = ''
+ for i,column in ipairs(show_columns) do
+ -- lua errors out with width > 99 ("invalid conversion specification")
+ local width = math.min(column.width * (column.align_left and -1 or 1), 99)
+ row = row .. (i > 1 and string.format('%' .. spacing .. 's', '') or '')
+ .. string.format('%' .. width .. 's', f[column.prop] or "")
+ end
+ res[#res+1] = {label=row, format=f.format_id}
+ end
+ return res
+ end
+
+ local columns_video = string_split(opts.columns_video, ',')
+ local columns_audio = string_split(opts.columns_audio, ',')
+ local vres = format_table(video_formats, columns_video)
+ local ares = format_table(audio_formats, columns_audio)
+ return vres, ares , vfmt, afmt
+end
+
+local function get_url()
+ local path = mp.get_property("path")
+ path = string.gsub(path, "ytdl://", "") -- Strip possible ytdl:// prefix.
+
+ local function is_url(s)
+ -- adapted the regex from https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url
+ return nil ~= string.match(path, "^[%w]-://[-a-zA-Z0-9@:%._\\+~#=]+%.[a-zA-Z0-9()][a-zA-Z0-9()]?[a-zA-Z0-9()]?[a-zA-Z0-9()]?[a-zA-Z0-9()]?[a-zA-Z0-9()]?[-a-zA-Z0-9()@:%_\\+.~#?&/=]*")
+ end
+
+ return is_url(path) and path or nil
+end
+
+local uosc = false
+local url_data={}
+local function process_json_string(url, json)
+ local json, err = utils.parse_json(json)
+
+ if (json == nil) then
+ mp.osd_message("fetching formats failed...", 2)
+ msg.error("failed to parse JSON data: " .. err)
+ return
+ end
+
+ if json.formats == nil then
+ return
+ end
+
+ local vres, ares , vfmt, afmt = process_json(json)
+ url_data[url] = {voptions=vres, aoptions=ares, vfmt=vfmt, afmt=afmt}
+ if uosc and get_url() == url then
+ mp.commandv('script-message-to', 'uosc', 'set', 'vformats', #vres)
+ mp.commandv('script-message-to', 'uosc', 'set', 'aformats', #ares)
+ end
+ return vres, ares , vfmt, afmt
+end
+
+local function download_formats(url)
+
+ mp.osd_message("fetching available formats with youtube-dl...", 60)
+
+ if not (ytdl.searched) then
+ local ytdl_mcd = mp.find_config_file(opts.ytdl_ver)
+ if not (ytdl_mcd == nil) then
+ msg.verbose("found youtube-dl at: " .. ytdl_mcd)
+ ytdl.path = ytdl_mcd
+ end
+ ytdl.searched = true
+ end
+
+ local function exec(args)
+ local res, err = mp.command_native({name = "subprocess", args = args, capture_stdout = true, capture_stderr = true})
+ return res.status, res.stdout, res.stderr
+ end
+
+ local ytdl_format = mp.get_property("ytdl-format")
+ local command = nil
+ if (ytdl_format == nil or ytdl_format == "") then
+ command = {ytdl.path, "--no-warnings", "--no-playlist", "-J", url}
+ else
+ command = {ytdl.path, "--no-warnings", "--no-playlist", "-J", "-f", ytdl_format, url}
+ end
+
+ msg.verbose("calling youtube-dl with command: " .. table.concat(command, " "))
+
+ local es, stdout, stderr = exec(command)
+
+ if (es < 0) or (stdout == nil) or (stdout == "") then
+ mp.osd_message("fetching formats failed...", 2)
+ msg.error("failed to get format list: " .. es)
+ msg.error("stderr: " .. stderr)
+ return
+ end
+
+ msg.verbose("youtube-dl succeeded!")
+ mp.osd_message("", 0)
+
+ local vres, ares , vfmt, afmt = process_json_string(url, stdout)
+ return vres, ares , vfmt, afmt
+end
+
+local function send_formats_to(type, url, script_name, options, format_id)
+ mp.commandv('script-message-to', script_name, type .. '_formats', url, utils.format_json(options or {}), format_id or '')
+end
+
+local queue_callback_video = {}
+local queue_callback_audio = {}
+local function get_formats()
+
+ local url = get_url()
+ if url == nil then
+ return
+ end
+
+ if url_data[url] then
+ local data = url_data[url]
+ return data.voptions, data.aoptions, data.vfmt, data.afmt, url
+ end
+
+ if opts.fetch_formats == false then
+ local vres = {}
+ for i,v in ipairs(opts.quality_strings) do
+ for k,v2 in pairs(v) do
+ vres[i] = {label = k, format=v2}
+ end
+ end
+ url_data[url] = {voptions=vres, aoptions={}, vfmt=nil, afmt=nil}
+ return vres, {}, nil, nil, url
+ end
+
+ local vres, ares , vfmt, afmt = download_formats(url)
+
+ for _, script_name in ipairs(queue_callback_video[url] or {}) do
+ send_formats_to('video', url, script_name, vres, vfmt)
+ end
+ for _, script_name in ipairs(queue_callback_audio[url] or {}) do
+ send_formats_to('audio', url, script_name, ares, afmt)
+ end
+
+ queue_callback_video[url] = nil
+ queue_callback_audio[url] = nil
+ return vres, ares , vfmt, afmt, url
+end
+
+local function format_string(vfmt, afmt)
+ if vfmt and afmt then
+ return vfmt.."+"..afmt
+ elseif vfmt then
+ return vfmt
+ elseif afmt then
+ return afmt
+ else
+ return ""
+ end
+end
+
+local function set_format(url, vfmt, afmt)
+ if (url_data[url].vfmt ~= vfmt or url_data[url].afmt ~= afmt) then
+ url_data[url].afmt = afmt
+ url_data[url].vfmt = vfmt
+ if url == mp.get_property("path") then
+ mp.set_property("ytdl-format", format_string(vfmt, afmt))
+ reload_resume()
+ end
+ end
+end
+
+local destroyer = nil
+local function show_menu(isvideo)
+
+ if destroyer then
+ destroyer()
+ end
+
+ local voptions, aoptions, vfmt, afmt, url = get_formats()
+
+ local options
+ local fmt
+ if isvideo then
+ options = voptions
+ fmt = vfmt
+ else
+ options = aoptions
+ fmt = afmt
+ end
+
+ if options == nil then
+ if uosc then
+ if isvideo then
+ mp.commandv('script-binding', 'uosc/video')
+ else
+ mp.commandv('script-binding', 'uosc/audio')
+ end
+ end
+
+ return
+ end
+
+ msg.verbose("current ytdl-format: "..format_string(vfmt, afmt))
+
+ local active = 0
+ local selected = 1
+ --set the cursor to the current format
+ if fmt then
+ for i,v in ipairs(options) do
+ if v.format == fmt then
+ active = i
+ selected = active
+ break
+ end
+ end
+ else
+ active = #options + 1
+ selected = active
+ end
+
+ if uosc then
+ local menu = {
+ title = isvideo and 'Video Formats' or 'Audio Formats',
+ items = {},
+ type = (isvideo and 'video' or 'audio') .. '_formats',
+ }
+ for i, option in ipairs(options) do
+ menu.items[i] = {
+ title = option.label,
+ active = i == active,
+ value = {
+ 'script-message-to',
+ 'quality_menu',
+ (isvideo and 'video' or 'audio') .. '-format-set',
+ url,
+ option.format}
+ }
+ end
+ menu.items[#menu.items + 1] = {
+ title = 'None',
+ value = {
+ 'script-message-to',
+ 'quality_menu',
+ (isvideo and 'video' or 'audio') .. '-format-set',
+ url}
+ }
+ local json = utils.format_json(menu)
+ mp.commandv('script-message-to', 'uosc', 'open-menu', json)
+ return
+ end
+
+ local function choose_prefix(i)
+ if i == selected and i == active then return opts.selected_and_active
+ elseif i == selected then return opts.selected_and_inactive end
+
+ if i ~= selected and i == active then return opts.unselected_and_active
+ elseif i ~= selected then return opts.unselected_and_inactive end
+ return "> " --shouldn't get here.
+ end
+
+ local function draw_menu()
+ local ass = assdraw.ass_new()
+
+ ass:pos(opts.text_padding_x, opts.text_padding_y)
+ ass:append(opts.style_ass_tags)
+
+ if #options > 0 then
+ for i,v in ipairs(options) do
+ ass:append(choose_prefix(i)..v.label.."\\N")
+ end
+ ass:append(choose_prefix(#options+1).."None")
+ else
+ ass:append("no formats found")
+ end
+
+ local w, h = mp.get_osd_size()
+ if opts.scale_playlist_by_window then w,h = 0, 0 end
+ mp.set_osd_ass(w, h, ass.text)
+ end
+
+ local num_options = #options + 1
+ local timeout = nil
+
+ local function selected_move(amt)
+ selected = selected + amt
+ if selected < 1 then selected = num_options
+ elseif selected > num_options then selected = 1 end
+ if timeout then
+ timeout:kill()
+ timeout:resume()
+ end
+ draw_menu()
+ end
+
+ local function bind_keys(keys, name, func, opts)
+ if not keys then
+ mp.add_forced_key_binding(keys, name, func, opts)
+ return
+ end
+ local i = 1
+ for key in keys:gmatch("[^%s]+") do
+ local prefix = i == 1 and '' or i
+ mp.add_forced_key_binding(key, name..prefix, func, opts)
+ i = i + 1
+ end
+ end
+
+ local function unbind_keys(keys, name)
+ if not keys then
+ mp.remove_key_binding(name)
+ return
+ end
+ local i = 1
+ for key in keys:gmatch("[^%s]+") do
+ local prefix = i == 1 and '' or i
+ mp.remove_key_binding(name..prefix)
+ i = i + 1
+ end
+ end
+
+ local function destroy()
+ if timeout then
+ timeout:kill()
+ end
+ mp.set_osd_ass(0,0,"")
+ unbind_keys(opts.up_binding, "move_up")
+ unbind_keys(opts.down_binding, "move_down")
+ unbind_keys(opts.select_binding, "select")
+ unbind_keys(opts.close_menu_binding, "close")
+ destroyer = nil
+ end
+
+ if opts.menu_timeout > 0 then
+ timeout = mp.add_periodic_timer(opts.menu_timeout, destroy)
+ end
+ destroyer = destroy
+
+ bind_keys(opts.up_binding, "move_up", function() selected_move(-1) end, {repeatable=true})
+ bind_keys(opts.down_binding, "move_down", function() selected_move(1) end, {repeatable=true})
+ if #options > 0 then
+ bind_keys(opts.select_binding, "select", function()
+ destroy()
+ if selected == active then return end
+
+ fmt = options[selected] and options[selected].format or nil
+ if isvideo then
+ vfmt = fmt
+ else
+ afmt = fmt
+ end
+ set_format(url, vfmt, afmt)
+ end)
+ end
+ bind_keys(opts.close_menu_binding, "close", destroy) --close menu using ESC
+ mp.osd_message("", 0)
+ draw_menu()
+end
+
+local ui_callback = {}
+
+local function video_formats_toggle()
+ if #ui_callback > 0 then
+ for _, name in ipairs(ui_callback) do
+ mp.commandv('script-message-to', name, 'video-formats-menu')
+ end
+ else
+ show_menu(true)
+ end
+end
+
+local function audio_formats_toggle()
+ if #ui_callback > 0 then
+ for _, name in ipairs(ui_callback) do
+ mp.commandv('script-message-to', name, 'audio-formats-menu')
+ end
+ else
+ show_menu(false)
+ end
+end
+
+-- keybind to launch menu
+mp.add_key_binding(nil, "video_formats_toggle", video_formats_toggle)
+mp.add_key_binding(nil, "audio_formats_toggle", audio_formats_toggle)
+mp.add_key_binding(nil, "reload", reload_resume)
+
+local original_format = mp.get_property("ytdl-format")
+local path = nil
+local function file_start()
+ local new_path = get_url()
+ if not new_path then return end
+
+ local data = url_data[new_path]
+
+ if uosc then
+ if data then
+ mp.commandv('script-message-to', 'uosc', 'set', 'vformats', #data.voptions)
+ mp.commandv('script-message-to', 'uosc', 'set', 'aformats', #data.aoptions)
+ else
+ mp.commandv('script-message-to', 'uosc', 'set', 'vformats', 0)
+ mp.commandv('script-message-to', 'uosc', 'set', 'aformats', 0)
+ end
+ end
+
+ if opts.reset_format and path and new_path ~= path then
+ if data then
+ msg.verbose("setting previously set format")
+ mp.set_property("ytdl-format", format_string(data.vfmt, data.afmt))
+ else
+ msg.verbose("setting original format")
+ mp.set_property("ytdl-format", original_format)
+ end
+ end
+ if opts.start_with_menu and new_path ~= path then
+ video_formats_toggle()
+ elseif opts.fetch_on_start and not data then
+ download_formats(new_path)
+ end
+ path = new_path
+end
+mp.register_event("start-file", file_start)
+
+mp.register_script_message('video-formats-get', function(url, script_name)
+ local data = url_data[url]
+ if data then
+ send_formats_to('video', url, script_name, data.voptions, data.vfmt)
+ else
+ local queue = queue_callback_video[url] or {}
+ queue[#queue + 1] = script_name
+ queue_callback_video[url] = queue
+ get_formats()
+ end
+end)
+
+mp.register_script_message('audio-formats-get', function(url, script_name)
+ local data = url_data[url]
+ if data then
+ send_formats_to('audio', url, script_name, data.aoptions, data.afmt)
+ else
+ local queue = queue_callback_audio[url] or {}
+ queue[#queue + 1] = script_name
+ queue_callback_audio[url] = queue
+ get_formats()
+ end
+end)
+
+mp.register_script_message('video-format-set', function(url, format_id)
+ set_format(url, format_id, url_data[url].afmt)
+end)
+
+mp.register_script_message('audio-format-set', function(url, format_id)
+ set_format(url, url_data[url].vfmt, format_id)
+end)
+
+mp.register_script_message('register-ui', function(script_name)
+ ui_callback[#ui_callback + 1] = script_name
+end)
+
+-- check if uosc is running
+mp.register_script_message('uosc-version', function(version)
+ version = tonumber((version:gsub('%.', '')))
+---@diagnostic disable-next-line: cast-local-type
+ uosc = version and version >= 400
+end)
+mp.commandv('script-message-to', 'uosc', 'get-version', mp.get_script_name()) \ No newline at end of file
diff --git a/mpv/scripts/youtube-download.lua b/mpv/scripts/youtube-download.lua
new file mode 100644
index 0000000..3050b39
--- /dev/null
+++ b/mpv/scripts/youtube-download.lua
@@ -0,0 +1,758 @@
+-- youtube-download.lua
+--
+-- Download video/audio from youtube via youtube-dl and ffmpeg/avconv
+-- This is forked/based on https://github.com/jgreco/mpv-youtube-quality
+--
+-- Video download bound to ctrl-d by default.
+-- Audio download bound to ctrl-a by default.
+
+-- Requires youtube-dl in PATH for video download
+-- Requires ffmpeg or avconv in PATH for audio download
+
+local mp = require 'mp'
+local utils = require 'mp.utils'
+local msg = require 'mp.msg'
+
+local opts = {
+ -- Key bindings
+ -- Set to empty string "" to disable
+ download_video_binding = "ctrl+d",
+ download_audio_binding = "ctrl+a",
+ download_subtitle_binding = "ctrl+s",
+ download_video_embed_subtitle_binding = "ctrl+i",
+ select_range_binding = "ctrl+r",
+
+ -- Specify audio format: "best", "aac","flac", "mp3", "m4a", "opus", "vorbis", or "wav"
+ audio_format = "mp3",
+
+ -- Specify ffmpeg/avconv audio quality
+ -- insert a value between 0 (better) and 9 (worse) for VBR or a specific bitrate like 128K
+ audio_quality = "0",
+
+ -- Same as youtube-dl --format FORMAT
+ -- see https://github.com/ytdl-org/youtube-dl/blob/master/README.md#format-selection
+ -- set to "current" to download the same quality that is currently playing
+ video_format = "",
+
+ -- Encode the video to another format if necessary: "mp4", "flv", "ogg", "webm", "mkv", "avi"
+ recode_video = "",
+
+ -- Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames
+ restrict_filenames = true,
+
+ -- Download the whole playlist (false) or only one video (true)
+ -- Same as youtube-dl --no-playlist
+ no_playlist = true,
+
+ -- Use an archive file, see youtube-dl --download-archive
+ -- You have these options:
+ -- * Set to empty string "" to not use an archive file
+ -- * Set an absolute path to use one archive for all downloads e.g. download_archive="/home/user/archive.txt"
+ -- * Set a relative path/only a filename to use one archive per directory e.g. download_archive="archive.txt"
+ -- * Use $PLAYLIST to create one archive per playlist e.g. download_archive="/home/user/archives/$PLAYLIST.txt"
+ download_archive = "",
+
+ -- Use a cookies file for youtube-dl
+ -- Same as youtube-dl --cookies
+ -- On Windows you need to use a double blackslash or a single fordwardslash
+ -- For example "C:\\Users\\Username\\cookies.txt"
+ -- Or "C:/Users/Username/cookies.txt"
+ cookies = "",
+
+ -- Filename or full path
+ -- Same as youtube-dl -o FILETEMPLATE
+ -- see https://github.com/ytdl-org/youtube-dl/blob/master/README.md#output-template
+ -- A relative path or a file name is relative to the path mpv was launched from
+ -- On Windows you need to use a double blackslash or a single fordwardslash
+ -- For example "C:\\Users\\Username\\Downloads\\%(title)s.%(ext)s"
+ -- Or "C:/Users/Username/Downloads/%(title)s.%(ext)s"
+ filename = "%(title)s.%(ext)s",
+
+ -- Subtitle language
+ -- Same as youtube-dl --sub-lang en
+ sub_lang = "en",
+
+ -- Subtitle format
+ -- Same as youtube-dl --sub-format best
+ sub_format = "best",
+
+ -- Log file for download errors
+ log_file = "",
+
+}
+
+--Read configuration file
+(require 'mp.options').read_options(opts, "youtube-download")
+
+--Read command line arguments
+local ytdl_raw_options = mp.get_property("ytdl-raw-options")
+if ytdl_raw_options ~= nil and ytdl_raw_options:find("cookies=") ~= nil then
+ local cookie_file = ytdl_raw_options:match("cookies=([^,]+)")
+ if cookie_file ~= nil then
+ opts.cookies = cookie_file
+ end
+end
+
+local function exec(args, capture_stdout, capture_stderr)
+ local ret = mp.command_native({
+ name = "subprocess",
+ playback_only = false,
+ capture_stdout = capture_stdout,
+ capture_stderr = capture_stderr,
+ args = args,
+ })
+ return ret.status, ret.stdout, ret.stderr, ret
+end
+
+local function trim(str)
+ return str:gsub("^%s+", ""):gsub("%s+$", "")
+end
+
+local function not_empty(str)
+ if str == nil or str == "" then
+ return false
+ end
+ return trim(str) ~= ""
+end
+
+local function path_separator()
+ return package.config:sub(1,1)
+end
+
+local function path_join(...)
+ return table.concat({...}, path_separator())
+end
+
+local function get_current_format()
+ -- get the current youtube-dl format or the default value
+ local ytdl_format = mp.get_property("options/ytdl-format")
+ if not_empty(ytdl_format) then
+ return ytdl_format
+ end
+ ytdl_format = mp.get_property("ytdl-format")
+ if not_empty(ytdl_format) then
+ return ytdl_format
+ end
+ return "bestvideo+bestaudio/best"
+end
+
+local DOWNLOAD = {
+ VIDEO=1,
+ AUDIO=2,
+ SUBTITLE=3,
+ VIDEO_EMBED_SUBTITLE=4
+}
+local select_range_mode = 0
+local start_time_seconds = nil
+local start_time_formated = nil
+local end_time_seconds = nil
+local end_time_formated = nil
+
+local is_downloading = false
+
+local function disable_select_range()
+ -- Disable range mode
+ select_range_mode = 0
+ -- Remove the arrow key key bindings
+ mp.remove_key_binding("select-range-set-up")
+ mp.remove_key_binding("select-range-set-down")
+ mp.remove_key_binding("select-range-set-left")
+ mp.remove_key_binding("select-range-set-right")
+end
+
+
+local function download(download_type)
+ local start_time = os.date("%c")
+ if is_downloading then
+ return
+ end
+ is_downloading = true
+
+ local ass0 = mp.get_property("osd-ass-cc/0")
+ local ass1 = mp.get_property("osd-ass-cc/1")
+ local url = mp.get_property("path")
+
+ url = string.gsub(url, "ytdl://", "") -- Strip possible ytdl:// prefix.
+
+ if string.find(url, "//youtu.be/") == nil
+ and string.find(url, "//ww.youtu.be/") == nil
+ and string.find(url, "//youtube.com/") == nil
+ and string.find(url, "//www.youtube.com/") == nil
+ then
+ mp.osd_message("Not a youtube URL: " .. tostring(url), 10)
+ is_downloading = false
+ return
+ end
+
+ local list_match = url:match("list=(%w+)")
+ local download_archive = opts.download_archive
+ if list_match ~= nil and opts.download_archive ~= nil and opts.download_archive:find("$PLAYLIST", 1, true) then
+ download_archive = opts.download_archive:gsub("$PLAYLIST", list_match)
+ end
+
+ if download_type == DOWNLOAD.AUDIO then
+ mp.osd_message("Audio download started", 2)
+ elseif download_type == DOWNLOAD.SUBTITLE then
+ mp.osd_message("Subtitle download started", 2)
+ elseif download_type == DOWNLOAD.VIDEO_EMBED_SUBTITLE then
+ mp.osd_message("Video w/ subtitle download started", 2)
+ else
+ mp.osd_message("Video download started", 2)
+ end
+
+ -- Compose command line arguments
+ local command = {}
+
+ local range_mode_file_name = nil
+ local range_mode_subtitle_file_name = nil
+ local start_time_offset = 0
+
+ if select_range_mode == 0 or (select_range_mode > 0 and (download_type == DOWNLOAD.AUDIO or download_type == DOWNLOAD.SUBTITLE)) then
+ table.insert(command, "youtube-dl")
+ table.insert(command, "--no-overwrites")
+ if opts.restrict_filenames then
+ table.insert(command, "--restrict-filenames")
+ end
+ if not_empty(opts.filename) then
+ table.insert(command, "-o")
+ table.insert(command, opts.filename)
+ end
+ if opts.no_playlist then
+ table.insert(command, "--no-playlist")
+ end
+ if not_empty(download_archive) then
+ table.insert(command, "--download-archive")
+ table.insert(command, download_archive)
+ end
+
+ if download_type == DOWNLOAD.SUBTITLE then
+ table.insert(command, "--sub-lang")
+ table.insert(command, opts.sub_lang)
+ table.insert(command, "--write-sub")
+ table.insert(command, "--skip-download")
+ if not_empty(opts.sub_format) then
+ table.insert(command, "--sub-format")
+ table.insert(command, opts.sub_format)
+ end
+ if select_range_mode > 0 then
+ mp.osd_message("Range mode is not available for subtitle-only download", 10)
+ is_downloading = false
+ return
+ end
+ elseif download_type == DOWNLOAD.AUDIO then
+ table.insert(command, "--extract-audio")
+ if not_empty(opts.audio_format) then
+ table.insert(command, "--audio-format")
+ table.insert(command, opts.audio_format)
+ end
+ if not_empty(opts.audio_quality) then
+ table.insert(command, "--audio-quality")
+ table.insert(command, opts.audio_quality)
+ end
+ if select_range_mode > 0 then
+ local start_time_str = tostring(start_time_seconds)
+ local end_time_str = tostring(end_time_seconds)
+ table.insert(command, "--external-downloader")
+ table.insert(command, "ffmpeg")
+ table.insert(command, "--external-downloader-args")
+ table.insert(command, "-loglevel warning -nostats -hide_banner -ss ".. start_time_str .. " -to " .. end_time_str .. " -avoid_negative_ts make_zero")
+ end
+ else --DOWNLOAD.VIDEO or DOWNLOAD.VIDEO_EMBED_SUBTITLE
+ if download_type == DOWNLOAD.VIDEO_EMBED_SUBTITLE then
+ table.insert(command, "--all-subs")
+ table.insert(command, "--write-sub")
+ table.insert(command, "--embed-subs")
+ if not_empty(opts.sub_format) then
+ table.insert(command, "--sub-format")
+ table.insert(command, opts.sub_format)
+ end
+ end
+ if not_empty(opts.video_format) then
+ table.insert(command, "--format")
+ if opts.video_format == "current" then
+ table.insert(command, get_current_format())
+ else
+ table.insert(command, opts.video_format)
+ end
+ end
+ if not_empty(opts.recode_video) then
+ table.insert(command, "--recode-video")
+ table.insert(command, opts.recode_video)
+ end
+ end
+ if not_empty(opts.cookies) then
+ table.insert(command, "--cookies")
+ table.insert(command, opts.cookies)
+ end
+ table.insert(command, url)
+
+ elseif select_range_mode > 0 and
+ (download_type == DOWNLOAD.VIDEO or download_type == DOWNLOAD.VIDEO_EMBED_SUBTITLE) then
+
+ -- Show download indicator
+ mp.set_osd_ass(0, 0, "{\\an9}{\\fs12}⌛🔗")
+
+ start_time_seconds = math.floor(start_time_seconds)
+ end_time_seconds = math.ceil(end_time_seconds)
+
+ local start_time_str = tostring(start_time_seconds)
+ local end_time_str = tostring(end_time_seconds)
+
+ -- Add time to the file name of the video
+ local filename_format
+ -- Insert start time/end time
+ if not_empty(opts.filename) then
+ if opts.filename:find("%%%(start_time%)") ~= nil then
+ -- Found "start_time" -> replace it
+ filename_format = tostring(opts.filename:
+ gsub("%%%(start_time%)[^diouxXeEfFgGcrs]*[diouxXeEfFgGcrs]", start_time_str):
+ gsub("%%%(end_time%)[^diouxXeEfFgGcrs]*[diouxXeEfFgGcrs]", end_time_str))
+ else
+ local ext_pattern = "%(ext)s"
+ if opts.filename:sub(-#ext_pattern) == ext_pattern then
+ -- Insert before ext
+ filename_format = opts.filename:sub(1, #(opts.filename) - #ext_pattern) ..
+ start_time_str .. "-" ..
+ end_time_str .. ".%(ext)s"
+ else
+ -- append at end
+ filename_format = opts.filename .. start_time_str .. "-" .. end_time_str
+ end
+ end
+ else
+ -- default youtube-dl filename pattern
+ filename_format = "%(title)s-%(id)s." .. start_time_str .. "-" .. end_time_str .. ".%(ext)s"
+ end
+
+ -- Find a suitable format
+ local format = "bestvideo[ext*=mp4]+bestaudio/best[ext*=mp4]/best"
+ local requested_format = opts.video_format
+ if requested_format == "current" then
+ requested_format = get_current_format()
+ end
+ if requested_format == nil or requested_format == "" then
+ format = format
+ elseif requested_format == "best" then
+ -- "best" works, because its a single file stream
+ format = "best"
+ elseif requested_format:find("mp4") ~= nil then
+ -- probably a mp4 format, so use it
+ format = requested_format
+ else
+ -- custom format, no "mp4" found -> use default
+ msg.warn("Select range mode requires a .mp4 format or \"best\", found " ..
+ requested_format .. "\n(" .. opts.video_format .. ")" ..
+ "\nUsing default format instead: " .. format)
+ end
+
+ -- Get the download url of the video file
+ -- e.g.: youtube-dl -g -f bestvideo[ext*=mp4]+bestaudio/best[ext*=mp4]/best -s --get-filename https://www.youtube.com/watch?v=abcdefg
+ command = {"youtube-dl"}
+ if opts.restrict_filenames then
+ table.insert(command, "--restrict-filenames")
+ end
+ if not_empty(opts.cookies) then
+ table.insert(command, "--cookies")
+ table.insert(command, opts.cookies)
+ end
+ table.insert(command, "-g")
+ table.insert(command, "--no-playlist")
+ table.insert(command, "-f")
+ table.insert(command, format)
+ table.insert(command, "-o")
+ table.insert(command, filename_format)
+ table.insert(command, "-s")
+ table.insert(command, "--get-filename")
+ table.insert(command, url)
+
+ msg.debug("info exec: " .. table.concat(command, " "))
+ local info_status, info_stdout, info_stderr = exec(command, true, true)
+ if info_status ~= 0 then
+ mp.set_osd_ass(0, 0, "")
+ mp.osd_message("Could not retieve download stream url: status=" .. tostring(info_status) .. "\n" ..
+ ass0 .. "{\\fs8} " .. info_stdout:gsub("\r", "") .."\n" .. info_stderr:gsub("\r", "") .. ass1, 20)
+ msg.debug("info_stdout:\n" .. info_stdout)
+ msg.debug("info_stderr:\n" .. info_stderr)
+ mp.set_osd_ass(0, 0, "")
+ is_downloading = false
+ return
+ end
+
+ -- Split result into lines
+ local info_lines = {}
+ local last_index = 0
+ local info_lines_N = 0
+ while true do
+ local start_i, end_i = info_stdout:find("\n", last_index, true)
+ if start_i then
+ local line = tostring(trim(info_stdout:sub(last_index, start_i)))
+ if line ~= "" then
+ table.insert(info_lines, line)
+ info_lines_N = info_lines_N + 1
+ end
+ else
+ break
+ end
+ last_index = end_i + 1
+ end
+
+ if info_lines_N < 2 then
+ mp.set_osd_ass(0, 0, "")
+ mp.osd_message("Could not extract download stream urls and filename from output\n" ..
+ ass0 .. "{\\fs8} " .. info_stdout:gsub("\r", "") .."\n" .. info_stderr:gsub("\r", "") .. ass1, 20)
+ msg.debug("info_stdout:\n" .. info_stdout)
+ msg.debug("info_stderr:\n" .. info_stderr)
+ mp.set_osd_ass(0, 0, "")
+ is_downloading = false
+ return
+ end
+ range_mode_file_name = info_lines[info_lines_N]
+ table.remove(info_lines)
+
+ if download_type == DOWNLOAD.VIDEO_EMBED_SUBTITLE then
+ -- youtube-dl --write-sub --skip-download https://www.youtube.com/watch?v=abcdefg -o "temp.%(ext)s"
+ command = {"youtube-dl", "--write-sub", "--skip-download", "--sub-lang", opts.sub_lang}
+ if not_empty(opts.sub_format) then
+ table.insert(command, "--sub-format")
+ table.insert(command, opts.sub_format)
+ end
+ local randomName = "tmp_" .. tostring(math.random())
+ table.insert(command, "-o")
+ table.insert(command, randomName .. ".%(ext)s")
+ table.insert(command, url)
+
+ -- Start subtitle download
+ msg.debug("exec: " .. table.concat(command, " "))
+ local subtitle_status, subtitle_stdout, subtitle_stderr = exec(command, true, true)
+ if subtitle_status == 0 and subtitle_stdout:find(randomName) then
+ local i, j = subtitle_stdout:find(randomName .. "[^\n]+")
+ range_mode_subtitle_file_name = trim(subtitle_stdout:sub(i, j))
+ if range_mode_subtitle_file_name ~= "" then
+ if range_mode_file_name:sub(-4) ~= ".mkv" then
+ -- Only mkv supports all kinds of subtitle formats
+ range_mode_file_name = range_mode_file_name:sub(1,-4) .. "mkv"
+ end
+ end
+ else
+ mp.osd_message("Could not find a suitable subtitle")
+ msg.debug("subtitle_stdout:\n" .. subtitle_stdout)
+ msg.debug("subtitle_stderr:\n" .. subtitle_stderr)
+ end
+
+ end
+
+ -- Download earlier (cut off afterwards)
+ start_time_offset = math.min(15, start_time_seconds)
+ start_time_seconds = start_time_seconds - start_time_offset
+
+ start_time_str = tostring(start_time_seconds)
+ end_time_str = tostring(end_time_seconds)
+
+ command = {"ffmpeg", "-loglevel", "warning", "-nostats", "-hide_banner", "-y"}
+ for _, value in ipairs(info_lines) do
+ table.insert(command, "-ss")
+ table.insert(command, start_time_str)
+ table.insert(command, "-to")
+ table.insert(command, end_time_str)
+ table.insert(command, "-i")
+ table.insert(command, value)
+ end
+ if not_empty(range_mode_subtitle_file_name) then
+ table.insert(command, "-ss")
+ table.insert(command, start_time_str)
+ table.insert(command, "-i")
+ table.insert(command, range_mode_subtitle_file_name)
+ table.insert(command, "-to") -- To must be after input for subtitle
+ table.insert(command, end_time_str)
+ end
+ table.insert(command, "-c")
+ table.insert(command, "copy")
+ table.insert(command, range_mode_file_name)
+
+ disable_select_range()
+ end
+
+ -- Show download indicator
+ mp.set_osd_ass(0, 0, "{\\an9}{\\fs12}⌛💾")
+
+ -- Start download
+ msg.debug("exec: " .. table.concat(command, " "))
+ local status, stdout, stderr = exec(command, true, true)
+
+ if status == 0 and range_mode_file_name ~= nil then
+ mp.set_osd_ass(0, 0, "{\\an9}{\\fs12}⌛🔨")
+
+ -- Cut first few seconds to fix errors
+ local start_time_offset_str = tostring(start_time_offset)
+ if #start_time_offset_str == 1 then
+ start_time_offset_str = "0" .. start_time_offset_str
+ end
+ local max_length = end_time_seconds - start_time_seconds + start_time_offset + 12
+ local tmp_file_name = range_mode_file_name .. ".tmp." .. range_mode_file_name:sub(-3)
+ command = {"ffmpeg", "-loglevel", "warning", "-nostats", "-hide_banner", "-y",
+ "-i", range_mode_file_name, "-ss", "00:00:" .. start_time_offset_str,
+ "-c", "copy", "-avoid_negative_ts", "make_zero", "-t", tostring(max_length), tmp_file_name}
+ msg.debug("mux exec: " .. table.concat(command, " "))
+ local muxstatus, muxstdout, muxstderr = exec(command, true, true)
+ if muxstatus ~= 0 and not_empty(muxstderr) then
+ msg.warn("Remux log:" .. tostring(muxstdout))
+ msg.warn("Remux errorlog:" .. tostring(muxstderr))
+ end
+ if muxstatus == 0 then
+ os.remove(range_mode_file_name)
+ os.rename(tmp_file_name, range_mode_file_name)
+ if not_empty(range_mode_subtitle_file_name) then
+ os.remove(range_mode_subtitle_file_name)
+ end
+ end
+
+ end
+
+
+ is_downloading = false
+
+ -- Hide download indicator
+ mp.set_osd_ass(0, 0, "")
+
+ local wrote_error_log = false
+ if stderr ~= nil and not_empty(opts.log_file) and not_empty(stderr) then
+ -- Write stderr to log file
+ local title = mp.get_property("media-title")
+ local file = io.open (opts.log_file , "a+")
+ file:write("\n[")
+ file:write(start_time)
+ file:write("] ")
+ file:write(url)
+ file:write("\n[\"")
+ file:write(title)
+ file:write("\"]\n")
+ file:write(stderr)
+ file:close()
+ wrote_error_log = true
+ end
+
+ if (status ~= 0) then
+ mp.osd_message("download failed:\n" .. tostring(stderr), 10)
+ msg.error("URL: " .. tostring(url))
+ msg.error("Return status code: " .. tostring(status))
+ msg.debug(tostring(stderr))
+ msg.debug(tostring(stdout))
+ return
+ end
+
+ if string.find(stdout, "has already been recorded in archive") ~=nil then
+ mp.osd_message("Has already been recorded in archive", 5)
+ return
+ end
+
+ -- Retrieve the file name
+ local filename = nil
+ if range_mode_file_name == nil and stdout then
+ local i, j, last_i, start_index = 0
+ while i ~= nil do
+ last_i, start_index = i, j
+ i, j = stdout:find ("Destination: ",j, true)
+ end
+
+ if last_i ~= nil then
+ local end_index = stdout:find ("\n", start_index, true)
+ if end_index ~= nil and start_index ~= nil then
+ filename = trim(stdout:sub(start_index, end_index))
+ end
+ end
+ elseif not_empty(range_mode_file_name) then
+ filename = range_mode_file_name
+ end
+
+ local osd_text = "Download succeeded\n"
+ local osd_time = 5
+ -- Find filename or directory
+ if filename then
+ local filepath
+ local basepath
+ if filename:find("/") == nil and filename:find("\\") == nil then
+ basepath = utils.getcwd()
+ filepath = path_join(utils.getcwd(), filename)
+ else
+ basepath = ""
+ filepath = filename
+ end
+
+ if filepath:len() < 100 then
+ osd_text = osd_text .. ass0 .. "{\\fs12} " .. filepath .. " {\\fs20}" .. ass1
+ elseif basepath == "" then
+ osd_text = osd_text .. ass0 .. "{\\fs8} " .. filepath .. " {\\fs20}" .. ass1
+ else
+ osd_text = osd_text .. ass0 .. "{\\fs11} " .. basepath .. "\n" .. filename .. " {\\fs20}" .. ass1
+ end
+ if wrote_error_log then
+ -- Write filename and end time to log file
+ local file = io.open (opts.log_file , "a+")
+ file:write("[" .. filepath .. "]\n")
+ file:write(os.date("[end %c]\n"))
+ file:close()
+ end
+ else
+ if wrote_error_log then
+ -- Write directory and end time to log file
+ local file = io.open (opts.log_file , "a+")
+ file:write("[" .. utils.getcwd() .. "]\n")
+ file:write(os.date("[end %c]\n"))
+ file:close()
+ end
+ osd_text = osd_text .. utils.getcwd()
+ end
+
+ -- Show warnings
+ if not_empty(stderr) then
+ msg.warn("Errorlog:" .. tostring(stderr))
+ if stderr:find("incompatible for merge") == nil then
+ local i = stderr:find("Input #")
+ if i ~= nil then
+ stderr = stderr:sub(i)
+ end
+ osd_text = osd_text .. "\n" .. ass0 .. "{\\fs8} " .. stderr:gsub("\r", "") .. ass1
+ osd_time = osd_time + 5
+ end
+ end
+
+ mp.osd_message(osd_text, osd_time)
+end
+
+local function select_range_show()
+ local status
+ if select_range_mode > 0 then
+ if select_range_mode == 2 then
+ status = "Download range: Fine tune\n← → start time\n↓ ↑ end time\n" ..
+ tostring(opts.select_range_binding) .. " next mode"
+ elseif select_range_mode == 1 then
+ status = "Download range: Select interval\n← start here\n→ end here\n↓from beginning\n↑til end\n" ..
+ tostring(opts.select_range_binding) .. " next mode"
+ end
+ mp.osd_message("Start: " .. start_time_formated .. "\nEnd: " .. end_time_formated .. "\n" .. status, 30)
+ else
+ status = "Download range: Disabled (download full length)"
+ mp.osd_message(status, 3)
+ end
+end
+
+local function select_range_set_left()
+ if select_range_mode == 2 then
+ start_time_seconds = math.max(0, start_time_seconds - 1)
+ if start_time_seconds < 86400 then
+ start_time_formated = os.date("!%H:%M:%S", start_time_seconds)
+ else
+ start_time_formated = tostring(start_time_seconds) .. "s"
+ end
+ elseif select_range_mode == 1 then
+ start_time_seconds = mp.get_property_number("time-pos")
+ start_time_formated = mp.command_native({"expand-text","${time-pos}"})
+ end
+ select_range_show()
+end
+
+local function select_range_set_start()
+ if select_range_mode == 2 then
+ end_time_seconds = math.max(1, end_time_seconds - 1)
+ if end_time_seconds < 86400 then
+ end_time_formated = os.date("!%H:%M:%S", end_time_seconds)
+ else
+ end_time_formated = tostring(end_time_seconds) .. "s"
+ end
+ elseif select_range_mode == 1 then
+ start_time_seconds = 0
+ start_time_formated = "00:00:00"
+ end
+ select_range_show()
+end
+
+local function select_range_set_end()
+ if select_range_mode == 2 then
+ end_time_seconds = math.min(mp.get_property_number("duration"), end_time_seconds + 1)
+ if end_time_seconds < 86400 then
+ end_time_formated = os.date("!%H:%M:%S", end_time_seconds)
+ else
+ end_time_formated = tostring(end_time_seconds) .. "s"
+ end
+ elseif select_range_mode == 1 then
+ end_time_seconds = mp.get_property_number("duration")
+ end_time_formated = mp.command_native({"expand-text","${duration}"})
+ end
+ select_range_show()
+end
+
+local function select_range_set_right()
+ if select_range_mode == 2 then
+ start_time_seconds = math.min(mp.get_property_number("duration") - 1, start_time_seconds + 1)
+ if start_time_seconds < 86400 then
+ start_time_formated = os.date("!%H:%M:%S", start_time_seconds)
+ else
+ start_time_formated = tostring(start_time_seconds) .. "s"
+ end
+ elseif select_range_mode == 1 then
+ end_time_seconds = mp.get_property_number("time-pos")
+ end_time_formated = mp.command_native({"expand-text","${time-pos}"})
+ end
+ select_range_show()
+end
+
+
+local function select_range()
+ -- Cycle through modes
+ if select_range_mode == 2 then
+ -- Disable range mode
+ disable_select_range()
+ elseif select_range_mode == 1 then
+ -- Switch to "fine tune" mode
+ select_range_mode = 2
+ else
+ select_range_mode = 1
+ -- Add keybinds for arrow keys
+ mp.add_key_binding("up", "select-range-set-up", select_range_set_end)
+ mp.add_key_binding("down", "select-range-set-down", select_range_set_start)
+ mp.add_key_binding("left", "select-range-set-left", select_range_set_left)
+ mp.add_key_binding("right", "select-range-set-right", select_range_set_right)
+
+ -- Defaults
+ if start_time_seconds == nil then
+ start_time_seconds = mp.get_property_number("time-pos")
+ start_time_formated = mp.command_native({"expand-text","${time-pos}"})
+ end_time_seconds = mp.get_property_number("duration")
+ end_time_formated = mp.command_native({"expand-text","${duration}"})
+ end
+ end
+ select_range_show()
+end
+
+local function download_video()
+ return download(DOWNLOAD.VIDEO)
+end
+
+local function download_audio()
+ return download(DOWNLOAD.AUDIO)
+end
+
+local function download_subtitle()
+ return download(DOWNLOAD.SUBTITLE)
+end
+
+local function download_embed_subtitle()
+ return download(DOWNLOAD.VIDEO_EMBED_SUBTITLE)
+end
+
+-- keybind
+if not_empty(opts.download_video_binding) then
+ mp.add_key_binding(opts.download_video_binding, "download-video", download_video)
+end
+if not_empty(opts.download_audio_binding) then
+ mp.add_key_binding(opts.download_audio_binding, "download-audio", download_audio)
+end
+if not_empty(opts.download_subtitle_binding) then
+ mp.add_key_binding(opts.download_subtitle_binding, "download-subtitle", download_subtitle)
+end
+if not_empty(opts.download_video_embed_subtitle_binding) then
+ mp.add_key_binding(opts.download_video_embed_subtitle_binding, "download-embed-subtitle", download_embed_subtitle)
+end
+if not_empty(opts.select_range_binding) then
+ mp.add_key_binding(opts.select_range_binding, "select-range-start", select_range)
+end
diff --git a/ncmpcpp/bindings b/ncmpcpp/bindings
new file mode 100644
index 0000000..9b8f4da
--- /dev/null
+++ b/ncmpcpp/bindings
@@ -0,0 +1,543 @@
+##############################################################
+## This is the example bindings file. Copy it to ##
+## ~/.ncmpcpp/bindings or $XDG_CONFIG_HOME/ncmpcpp/bindings ##
+## and set up your preferences ##
+##############################################################
+##
+##### General rules #####
+##
+## 1) Because each action has runtime checks whether it's
+## ok to run it, a few actions can be bound to one key.
+## Actions will be bound in order given in configuration
+## file. When a key is pressed, first action in order
+## will test itself whether it's possible to run it. If
+## test succeeds, action is executed and other actions
+## bound to this key are ignored. If it doesn't, next
+## action in order tests itself etc.
+##
+## 2) It's possible to bind more that one action at once
+## to a key. It can be done using the following syntax:
+##
+## def_key "key"
+## action1
+## action2
+## ...
+##
+## This creates a chain of actions. When such chain is
+## executed, each action in chain is run until the end of
+## chain is reached or one of its actions fails to execute
+## due to its requirements not being met. If multiple actions
+## and/or chains are bound to the same key, they will be
+## consecutively run until one of them gets fully executed.
+##
+## 3) When ncmpcpp starts, bindings configuration file is
+## parsed and then ncmpcpp provides "missing pieces"
+## of default keybindings. If you want to disable some
+## bindings, there is a special action called 'dummy'
+## for that purpose. Eg. if you want to disable ability
+## to crop playlists, you need to put the following
+## into configuration file:
+##
+## def_key "C"
+## dummy
+##
+## After that ncmpcpp will not bind any default action
+## to this key.
+##
+## 4) To let you write simple macros, the following special
+## actions are provided:
+##
+## - push_character "character" - pushes given special
+## character into input queue, so it will be immediately
+## picked by ncmpcpp upon next call to readKey function.
+## Accepted values: mouse, up, down, page_up, page_down,
+## home, end, space, enter, insert, delete, left, right,
+## tab, ctrl-a, ctrl-b, ..., ctrl-z, ctrl-[, ctrl-\\,
+## ctrl-], ctrl-^, ctrl-_, f1, f2, ..., f12, backspace.
+## In addition, most of these names can be prefixed with
+## alt-/ctrl-/shift- to be recognized with the appropriate
+## modifier key(s).
+##
+## - push_characters "string" - pushes given string into
+## input queue.
+##
+## - require_runnable "action" - checks whether given action
+## is runnable and fails if it isn't. This is especially
+## useful when mixed with previous two functions. Consider
+## the following macro definition:
+##
+## def_key "key"
+## push_characters "custom_filter"
+## apply_filter
+##
+## If apply_filter can't be currently run, we end up with
+## sequence of characters in input queue which will be
+## treated just as we typed them. This may lead to unexpected
+## results (in this case 'c' will most likely clear current
+## playlist, 'u' will trigger database update, 's' will stop
+## playback etc.). To prevent such thing from happening, we
+## need to change above definition to this one:
+##
+## def_key "key"
+## require_runnable "apply_filter"
+## push_characters "custom_filter"
+## apply_filter
+##
+## Here, first we test whether apply_filter can be actually run
+## before we stuff characters into input queue, so if condition
+## is not met, whole chain is aborted and we're fine.
+##
+## - require_screen "screen" - checks whether given screen is
+## currently active. accepted values: browser, clock, help,
+## media_library, outputs, playlist, playlist_editor,
+## search_engine, tag_editor, visualizer, last_fm, lyrics,
+## selected_items_adder, server_info, song_info,
+## sort_playlist_dialog, tiny_tag_editor.
+##
+## - run_external_command "command" - runs given command using
+## system() function.
+##
+## 5) In addition to binding to a key, you can also bind actions
+## or chains of actions to a command. If it comes to commands,
+## syntax is very similar to defining keys. Here goes example
+## definition of a command:
+##
+## def_command "quit" [deferred]
+## stop
+## quit
+##
+## If you execute the above command (which can be done by
+## invoking action execute_command, typing 'quit' and pressing
+## enter), ncmpcpp will stop the player and then quit. Note the
+## presence of word 'deferred' enclosed in square brackets. It
+## tells ncmpcpp to wait for confirmation (ie. pressing enter)
+## after you typed quit. Instead of 'deferred', 'immediate'
+## could be used. Then ncmpcpp will not wait for confirmation
+## (enter) and will execute the command the moment it sees it.
+##
+## Note: while command chains are executed, internal environment
+## update (which includes current window refresh and mpd status
+## update) is not performed for performance reasons. However, it
+## may be desirable to do so in some situration. Therefore it's
+## possible to invoke by hand by performing 'update enviroment'
+## action.
+##
+## Note: There is a difference between:
+##
+## def_key "key"
+## action1
+##
+## def_key "key"
+## action2
+##
+## and
+##
+## def_key "key"
+## action1
+## action2
+##
+## First one binds two single actions to the same key whilst
+## second one defines a chain of actions. The behavior of
+## these two is different and is described in (1) and (2).
+##
+## Note: Function def_key accepts non-ascii characters.
+##
+##### List of unbound actions #####
+##
+## The following actions are not bound to any key/command:
+##
+## - set_volume
+##
+#
+#def_key "mouse"
+# mouse_event
+#
+def_key "k"
+ scroll_up
+
+def_key "K"
+ select_item
+ scroll_up
+
+def_key "j"
+ scroll_down
+
+def_key "J"
+ select_item
+ scroll_down
+
+def_key "["
+ scroll_up_album
+
+def_key "]"
+ scroll_down_album
+
+def_key "{"
+ scroll_up_artist
+
+def_key "}"
+ scroll_down_artist
+
+#def_key "page_up"
+# page_up
+#
+#def_key "page_down"
+# page_down
+#
+#def_key "home"
+# move_home
+#
+#def_key "end"
+# move_end
+#
+#def_key "insert"
+# select_item
+#
+#def_key "enter"
+# enter_directory
+#
+#def_key "enter"
+# toggle_output
+#
+#def_key "enter"
+# run_action
+#
+#def_key "enter"
+# play_item
+#
+#def_key "space"
+# add_item_to_playlist
+#
+#def_key "space"
+# toggle_lyrics_update_on_song_change
+#
+#def_key "space"
+# toggle_visualization_type
+#
+#def_key "delete"
+# delete_playlist_items
+#
+#def_key "delete"
+# delete_browser_items
+#
+#def_key "delete"
+# delete_stored_playlist
+
+def_key "l"
+ next_column
+
+def_key "l"
+ slave_screen
+
+#def_key "right"
+# volume_up
+#
+#def_key "+"
+# volume_up
+
+def_key "h"
+ previous_column
+
+def_key "h"
+ master_screen
+
+#def_key "left"
+# volume_down
+#
+#def_key "-"
+# volume_down
+#
+#def_key ":"
+# execute_command
+#
+#def_key "tab"
+# next_screen
+#
+#def_key "shift-tab"
+# previous_screen
+#
+#def_key "f1"
+# show_help
+#
+#def_key "1"
+# show_playlist
+#
+#def_key "2"
+# show_browser
+#
+#def_key "2"
+# change_browse_mode
+#
+#def_key "3"
+# show_search_engine
+#
+#def_key "3"
+# reset_search_engine
+#
+#def_key "4"
+# show_media_library
+#
+#def_key "4"
+# toggle_media_library_columns_mode
+#
+#def_key "5"
+# show_playlist_editor
+#
+#def_key "6"
+# show_tag_editor
+#
+#def_key "7"
+# show_outputs
+#
+#def_key "8"
+# show_visualizer
+#
+#def_key "="
+# show_clock
+#
+#def_key "@"
+# show_server_info
+#
+#def_key "s"
+# stop
+#
+#def_key "p"
+# pause
+#
+#def_key ">"
+# next
+#
+#def_key "<"
+# previous
+#
+#def_key "ctrl-h"
+# jump_to_parent_directory
+#
+#def_key "ctrl-h"
+# replay_song
+#
+#def_key "backspace"
+# jump_to_parent_directory
+#
+#def_key "backspace"
+# replay_song
+#
+#def_key "f"
+# seek_forward
+#
+#def_key "b"
+# seek_backward
+#
+#def_key "r"
+# toggle_repeat
+#
+#def_key "z"
+# toggle_random
+#
+#def_key "y"
+# save_tag_changes
+#
+#def_key "y"
+# start_searching
+#
+#def_key "y"
+# toggle_single
+#
+#def_key "R"
+# toggle_consume
+#
+#def_key "Y"
+# toggle_replay_gain_mode
+#
+#def_key "T"
+# toggle_add_mode
+#
+#def_key "|"
+# toggle_mouse
+#
+#def_key "#"
+# toggle_bitrate_visibility
+#
+#def_key "Z"
+# shuffle
+#
+#def_key "x"
+# toggle_crossfade
+#
+#def_key "X"
+# set_crossfade
+#
+#def_key "u"
+# update_database
+#
+#def_key "ctrl-s"
+# sort_playlist
+#
+#def_key "ctrl-s"
+# toggle_browser_sort_mode
+#
+#def_key "ctrl-s"
+# toggle_media_library_sort_mode
+#
+#def_key "ctrl-r"
+# reverse_playlist
+#
+#def_key "ctrl-f"
+# apply_filter
+#
+#def_key "ctrl-_"
+# select_found_items
+#
+#def_key "/"
+# find
+#
+#def_key "/"
+# find_item_forward
+#
+#def_key "?"
+# find
+#
+#def_key "?"
+# find_item_backward
+#
+#def_key "."
+# next_found_item
+#
+#def_key ","
+# previous_found_item
+#
+#def_key "w"
+# toggle_find_mode
+#
+#def_key "e"
+# edit_song
+#
+#def_key "e"
+# edit_library_tag
+#
+#def_key "e"
+# edit_library_album
+#
+#def_key "e"
+# edit_directory_name
+#
+#def_key "e"
+# edit_playlist_name
+#
+#def_key "e"
+# edit_lyrics
+#
+#def_key "i"
+# show_song_info
+#
+#def_key "I"
+# show_artist_info
+#
+#def_key "g"
+# jump_to_position_in_song
+#
+#def_key "l"
+# show_lyrics
+#
+#def_key "ctrl-v"
+# select_range
+#
+#def_key "v"
+# reverse_selection
+#
+#def_key "V"
+# remove_selection
+#
+#def_key "B"
+# select_album
+#
+#def_key "a"
+# add_selected_items
+#
+#def_key "c"
+# clear_playlist
+#
+#def_key "c"
+# clear_main_playlist
+#
+#def_key "C"
+# crop_playlist
+#
+#def_key "C"
+# crop_main_playlist
+#
+#def_key "m"
+# move_sort_order_up
+#
+#def_key "m"
+# move_selected_items_up
+#
+#def_key "n"
+# move_sort_order_down
+#
+#def_key "n"
+# move_selected_items_down
+#
+#def_key "M"
+# move_selected_items_to
+#
+#def_key "A"
+# add
+#
+#def_key "S"
+# save_playlist
+#
+#def_key "o"
+# jump_to_playing_song
+#
+#def_key "G"
+# jump_to_browser
+#
+#def_key "G"
+# jump_to_playlist_editor
+#
+#def_key "~"
+# jump_to_media_library
+#
+#def_key "E"
+# jump_to_tag_editor
+#
+#def_key "U"
+# toggle_playing_song_centering
+#
+#def_key "P"
+# toggle_display_mode
+#
+#def_key "\\"
+# toggle_interface
+#
+#def_key "!"
+# toggle_separators_between_albums
+#
+#def_key "L"
+# toggle_lyrics_fetcher
+#
+#def_key "F"
+# fetch_lyrics_in_background
+#
+#def_key "alt-l"
+# toggle_fetching_lyrics_in_background
+#
+#def_key "ctrl-l"
+# toggle_screen_lock
+#
+#def_key "`"
+# toggle_library_tag_type
+#
+#def_key "`"
+# refetch_lyrics
+#
+#def_key "`"
+# add_random_items
+#
+#def_key "ctrl-p"
+# set_selected_items_priority
+#
+#def_key "q"
+# quit
+#
diff --git a/ncmpcpp/config b/ncmpcpp/config
new file mode 100644
index 0000000..2b4b68f
--- /dev/null
+++ b/ncmpcpp/config
@@ -0,0 +1,544 @@
+##############################################################################
+## This is the example configuration file. Copy it to $HOME/.ncmpcpp/config ##
+## or $XDG_CONFIG_HOME/ncmpcpp/config and set up your preferences. ##
+##############################################################################
+#
+##### directories ######
+##
+## Directory for storing ncmpcpp related files. Changing it is useful if you
+## want to store everything somewhere else and provide command line setting for
+## alternative location to config file which defines that while launching
+## ncmpcpp.
+##
+#
+ncmpcpp_directory = ~/.config/ncmpcpp
+#
+##
+## Directory for storing downloaded lyrics. It defaults to ~/.lyrics since other
+## MPD clients (eg. ncmpc) also use that location.
+##
+#
+lyrics_directory = ~/.config/ncmpcpp/lyrics
+#
+##### connection settings #####
+#
+mpd_host = ~/.config/mpd/socket
+#
+#mpd_port = 6600
+#
+#mpd_connection_timeout = 5
+#
+## Needed for tag editor and file operations to work.
+##
+#mpd_music_dir = ~/music
+#
+#mpd_crossfade_time = 5
+#
+##### music visualizer #####
+##
+## Note: In order to make music visualizer work you'll need to use mpd fifo
+## output, whose format parameter has to be set to 44100:16:1 for mono
+## visualization or 44100:16:2 for stereo visualization. Example configuration
+## (it has to be put into mpd.conf):
+##
+audio_output {
+ type "fifo"
+ name "Visualizer feed"
+ path "/tmp/mpd.fifo"
+ format "44100:16:2"
+}
+##
+#
+visualizer_data_source = /tmp/mpd.fifo
+#
+##
+## Note: Below parameter is needed for ncmpcpp to determine which output
+## provides data for visualizer and thus allow syncing between visualization and
+## sound as currently there are some problems with it.
+##
+#
+visualizer_output_name = my_fifo
+#
+##
+## If you set format to 44100:16:2, make it 'yes'.
+##
+#visualizer_in_stereo = yes
+#
+##
+## Note: Below parameter defines how often ncmpcpp has to "synchronize"
+## visualizer and audio outputs. 30 seconds is optimal value, but if you
+## experience synchronization problems, set it to lower value. Keep in mind
+## that sane values start with >=10.
+##
+#
+#visualizer_sync_interval = 30
+#
+##
+## Note: To enable spectrum frequency visualization you need to compile ncmpcpp
+## with fftw3 support.
+##
+#
+## Available values: spectrum, wave, wave_filled, ellipse.
+##
+visualizer_type = spectrum
+#
+visualizer_look = ●▮
+#
+#visualizer_color = blue, cyan, green, yellow, magenta, red
+#
+## Alternative subset of 256 colors for terminals that support it.
+##
+#visualizer_color = 41, 83, 119, 155, 185, 215, 209, 203, 197, 161
+#
+##### system encoding #####
+##
+## ncmpcpp should detect your charset encoding but if it failed to do so, you
+## can specify charset encoding you are using here.
+##
+## Note: You can see whether your ncmpcpp build supports charset detection by
+## checking output of `ncmpcpp --version`.
+##
+## Note: Since MPD uses UTF-8 by default, setting this option makes sense only
+## if your encoding is different.
+##
+#
+#system_encoding = ""
+#
+##### delays #####
+#
+## Time of inactivity (in seconds) after playlist highlighting will be disabled
+## (0 = always on).
+##
+#playlist_disable_highlight_delay = 5
+#
+## Defines how long messages are supposed to be visible.
+##
+#message_delay_time = 5
+#
+##### song format #####
+##
+## For a song format you can use:
+##
+## %l - length
+## %f - filename
+## %D - directory
+## %a - artist
+## %A - album artist
+## %t - title
+## %b - album
+## %y - date
+## %n - track number (01/12 -> 01)
+## %N - full track info (01/12 -> 01/12)
+## %g - genre
+## %c - composer
+## %p - performer
+## %d - disc
+## %C - comment
+## %P - priority
+## $R - begin right alignment
+##
+## If you want to make sure that a part of the format is displayed only when
+## certain tags are present, you can archieve it by grouping them with brackets,
+## e.g. '{%a - %t}' will be evaluated to 'ARTIST - TITLE' if both tags are
+## present or '' otherwise. It is also possible to define a list of
+## alternatives by providing several groups and separating them with '|',
+## e.g. '{%t}|{%f}' will be evaluated to 'TITLE' or 'FILENAME' if the former is
+## not present.
+##
+## Note: If you want to set limit on maximal length of a tag, just put the
+## appropriate number between % and character that defines tag type, e.g. to
+## make album take max. 20 terminal cells, use '%20b'.
+##
+## In addition, formats support markers used for text attributes. They are
+## followed by character '$'. After that you can put:
+##
+## - 0 - default window color (discards all other colors)
+## - 1 - black
+## - 2 - red
+## - 3 - green
+## - 4 - yellow
+## - 5 - blue
+## - 6 - magenta
+## - 7 - cyan
+## - 8 - white
+## - 9 - end of current color
+## - b - bold text
+## - u - underline text
+## - r - reverse colors
+## - a - use alternative character set
+##
+## If you don't want to use a non-color attribute anymore, just put it again,
+## but this time insert character '/' between '$' and attribute character,
+## e.g. {$b%t$/b}|{$r%f$/r} will display bolded title tag or filename with
+## reversed colors.
+##
+## If you want to use 256 colors and/or background colors in formats (the naming
+## scheme is described below in section about color definitions), it can be done
+## with the syntax $(COLOR), e.g. to set the artist tag to one of the
+## non-standard colors and make it have yellow background, you need to write
+## $(197_yellow)%a$(end). Note that for standard colors this is interchangable
+## with attributes listed above.
+##
+## Note: colors can be nested.
+##
+#
+#song_list_format = {%a - }{%t}|{$8%f$9}$R{$3(%l)$9}
+#
+#song_status_format = {{%a{ "%b"{ (%y)}} - }{%t}}|{%f}
+#
+#song_library_format = {%n - }{%t}|{%f}
+#
+#alternative_header_first_line_format = $b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b
+#
+#alternative_header_second_line_format = {{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D}
+#
+#current_item_prefix = $(yellow)$r
+#
+#current_item_suffix = $/r$(end)
+#
+#current_item_inactive_column_prefix = $(white)$r
+#
+#current_item_inactive_column_suffix = $/r$(end)
+#
+#now_playing_prefix = $b
+#
+#now_playing_suffix = $/b
+#
+#browser_playlist_prefix = "$2playlist$9 "
+#
+#selected_item_prefix = $6
+#
+#selected_item_suffix = $9
+#
+#modified_item_prefix = $3> $9
+#
+##
+## Note: attributes are not supported for the following variables.
+##
+#song_window_title_format = {%a - }{%t}|{%f}
+##
+## Note: Below variables are used for sorting songs in browser. The sort mode
+## determines how songs are sorted, and can be used in combination with a sort
+## format to specify a custom sorting format. Available values for
+## browser_sort_mode are "name", "mtime", "format" and "noop".
+##
+#
+#browser_sort_mode = name
+#
+#browser_sort_format = {%a - }{%t}|{%f} {(%l)}
+#
+##### columns settings #####
+##
+## syntax of song columns list format is "column column etc."
+##
+## - syntax for each column is:
+##
+## (width of the column)[color of the column]{displayed tag}
+##
+## Note: Width is by default in %, if you want a column to have fixed size, add
+## 'f' after the value, e.g. (10)[white]{a} will be the column that take 10% of
+## screen (so the real width will depend on actual screen size), whereas
+## (10f)[white]{a} will take 10 terminal cells, no matter how wide the screen
+## is.
+##
+## - color is optional (if you want the default one, leave the field empty).
+##
+## Note: You can give a column additional attributes by putting appropriate
+## character after displayed tag character. Available attributes are:
+##
+## - r - column will be right aligned
+## - E - if tag is empty, empty tag marker won't be displayed
+##
+## You can also:
+##
+## - give a column custom name by putting it after attributes, separated with
+## character ':', e.g. {lr:Length} gives you right aligned column of lengths
+## named "Length".
+##
+## - define sequence of tags, that have to be displayed in case predecessor is
+## empty in a way similar to the one in classic song format, i.e. using '|'
+## character, e.g. {a|c|p:Owner} creates column named "Owner" that tries to
+## display artist tag and then composer and performer if previous ones are not
+## available.
+##
+#
+#song_columns_list_format = (20)[]{a} (6f)[green]{NE} (50)[white]{t|f:Title} (20)[cyan]{b} (7f)[magenta]{l}
+#
+##### various settings #####
+#
+##
+## Note: Custom command that will be executed each time song changes. Useful for
+## notifications etc.
+##
+#execute_on_song_change = ""
+#
+##
+## Note: Custom command that will be executed each time player state
+## changes. The environment variable MPD_PLAYER_STATE is set to the current
+## state (either unknown, play, pause, or stop) for its duration.
+##
+#
+#execute_on_player_state_change = ""
+#
+#playlist_show_mpd_host = no
+#
+#playlist_show_remaining_time = no
+#
+#playlist_shorten_total_times = no
+#
+#playlist_separate_albums = no
+#
+##
+## Note: Possible display modes: classic, columns.
+##
+#playlist_display_mode = columns
+#
+#browser_display_mode = classic
+#
+#search_engine_display_mode = classic
+#
+#playlist_editor_display_mode = classic
+#
+#discard_colors_if_item_is_selected = yes
+#
+#show_duplicate_tags = yes
+#
+#incremental_seeking = yes
+#
+#seek_time = 1
+#
+#volume_change_step = 2
+#
+#autocenter_mode = no
+#
+#centered_cursor = no
+#
+##
+## Note: You can specify third character which will be used to build 'empty'
+## part of progressbar.
+##
+#progressbar_look = =>
+#
+## Available values: database, playlist.
+##
+#default_place_to_search_in = database
+#
+## Available values: classic, alternative.
+##
+#user_interface = classic
+#
+#data_fetching_delay = yes
+#
+## Available values: artist, album_artist, date, genre, composer, performer.
+##
+#media_library_primary_tag = artist
+#
+#media_library_albums_split_by_date = yes
+#
+## Available values: wrapped, normal.
+##
+#default_find_mode = wrapped
+#
+#default_tag_editor_pattern = %n - %t
+#
+#header_visibility = yes
+#
+#statusbar_visibility = yes
+#
+#titles_visibility = yes
+#
+#header_text_scrolling = yes
+#
+#cyclic_scrolling = no
+#
+#lines_scrolled = 2
+#
+#lyrics_fetchers = lyricwiki, azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, jahlyrics, plyrics, tekstowo, internet
+#
+#follow_now_playing_lyrics = no
+#
+#fetch_lyrics_for_current_song_in_background = no
+#
+#store_lyrics_in_song_dir = no
+#
+#generate_win32_compatible_filenames = yes
+#
+#allow_for_physical_item_deletion = no
+#
+##
+## Note: If you set this variable, ncmpcpp will try to get info from last.fm in
+## language you set and if it fails, it will fall back to english. Otherwise it
+## will use english the first time.
+##
+## Note: Language has to be expressed as an ISO 639 alpha-2 code.
+##
+#lastfm_preferred_language = en
+#
+#space_add_mode = add_remove
+#
+#show_hidden_files_in_local_browser = no
+#
+##
+## How shall screen switcher work?
+##
+## - "previous" - switch between the current and previous screen.
+## - "screen1,...,screenN" - switch between given sequence of screens.
+##
+## Screens available for use: help, playlist, browser, search_engine,
+## media_library, playlist_editor, tag_editor, outputs, visualizer, clock,
+## lyrics, last_fm.
+##
+#screen_switcher_mode = playlist, browser
+#
+##
+## Note: You can define startup screen by choosing screen from the list above.
+##
+#startup_screen = playlist
+#
+##
+## Note: You can define startup slave screen by choosing screen from the list
+## above or an empty value for no slave screen.
+##
+#startup_slave_screen = ""
+#
+#startup_slave_screen_focus = no
+#
+##
+## Default width of locked screen (in %). Acceptable values are from 20 to 80.
+##
+#
+#locked_screen_width_part = 50
+#
+#ask_for_locked_screen_width_part = yes
+#
+#jump_to_now_playing_song_at_start = yes
+#
+#ask_before_clearing_playlists = yes
+#
+#clock_display_seconds = no
+#
+#display_volume_level = yes
+#
+#display_bitrate = no
+#
+#display_remaining_time = no
+#
+## Available values: none, basic, extended, perl.
+##
+#regular_expressions = perl
+#
+##
+## Note: if below is enabled, ncmpcpp will ignore leading "The" word while
+## sorting items in browser, tags in media library, etc.
+##
+#ignore_leading_the = no
+#
+##
+## Note: if below is enabled, ncmpcpp will ignore diacritics while searching and
+## filtering lists. This takes an effect only if boost was compiled with ICU
+## support.
+##
+#ignore_diacritics = no
+#
+#block_search_constraints_change_if_items_found = yes
+#
+#mouse_support = yes
+#
+#mouse_list_scroll_whole_page = yes
+#
+#empty_tag_marker = <empty>
+#
+#tags_separator = " | "
+#
+#tag_editor_extended_numeration = no
+#
+#media_library_sort_by_mtime = no
+#
+#enable_window_title = yes
+#
+##
+## Note: You can choose default search mode for search engine. Available modes
+## are:
+##
+## - 1 - use mpd built-in searching (no regexes, pattern matching)
+##
+## - 2 - use ncmpcpp searching (pattern matching with support for regexes, but
+## if your mpd is on a remote machine, downloading big database to process
+## it can take a while
+##
+## - 3 - match only exact values (this mode uses mpd function for searching in
+## database and local one for searching in current playlist)
+##
+#
+#search_engine_default_search_mode = 1
+#
+#external_editor = nano
+#
+## Note: set to yes if external editor is a console application.
+##
+#use_console_editor = yes
+#
+##### colors definitions #####
+##
+## It is possible to set a background color by setting a color value
+## "<foreground>_<background>", e.g. red_black will set foregound color to red
+## and background color to black.
+##
+## In addition, for terminals that support 256 colors it is possible to set one
+## of them by using a number in range [1, 256] instead of color name,
+## e.g. numerical value corresponding to red_black is 2_1. To find out if the
+## terminal supports 256 colors, run ncmpcpp and check out the bottom of the
+## help screen for list of available colors and their numerical values.
+##
+## What is more, there are two special values for the background color:
+## "transparent" and "current". The first one explicitly sets the background to
+## be transparent, while the second one allows you to preserve current
+## background color and change only the foreground one. It's used implicitly
+## when background color is not specified.
+##
+## Moreover, it is possible to attach format information to selected color
+## variables by appending to their end a colon followed by one or more format
+## flags, e.g. black:b or red:ur. The following variables support this syntax:
+## visualizer_color, color1, color2, empty_tag_color, volume_color,
+## state_line_color, state_flags_color, progressbar_color,
+## progressbar_elapsed_color, player_state_color, statusbar_time_color,
+## alternative_ui_separator_color.
+##
+## Note: due to technical limitations of older ncurses version, if 256 colors
+## are used there is a possibility that you'll be able to use only colors with
+## transparent background.
+#
+#colors_enabled = yes
+#
+#empty_tag_color = cyan
+#
+#header_window_color = default
+#
+#volume_color = default
+#
+#state_line_color = default
+#
+#state_flags_color = default:b
+#
+#main_window_color = yellow
+#
+#color1 = white
+#
+#color2 = green
+#
+#progressbar_color = black:b
+#
+#progressbar_elapsed_color = green:b
+#
+#statusbar_color = default
+#
+#statusbar_time_color = default:b
+#
+#player_state_color = default:b
+#
+#alternative_ui_separator_color = black:b
+#
+#window_border_color = green
+#
+#active_window_border = red
+#
diff --git a/ncmpcpp/patterns.list b/ncmpcpp/patterns.list
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ncmpcpp/patterns.list
diff --git a/newsboat/config b/newsboat/config
new file mode 100644
index 0000000..b9b8b26
--- /dev/null
+++ b/newsboat/config
@@ -0,0 +1,55 @@
+#show-read-feeds no
+auto-reload yes
+
+external-url-viewer "urlscan -dc -r 'browser {}'"
+
+bind-key j down
+bind-key k up
+bind-key j next articlelist
+bind-key k prev articlelist
+bind-key J next-feed articlelist
+bind-key K prev-feed articlelist
+bind-key G end
+bind-key g home
+bind-key d pagedown
+bind-key u pageup
+bind-key l open
+bind-key h quit
+bind-key a toggle-article-read
+bind-key n next-unread
+bind-key N prev-unread
+bind-key D pb-download
+bind-key U show-urls
+bind-key x pb-delete
+
+color listnormal cyan default
+color listfocus black yellow standout bold
+color listnormal_unread blue default
+color listfocus_unread yellow default bold
+color info red black bold
+color article white default bold
+
+browser browser
+macro , open-in-browser
+macro t set browser "qndl" ; open-in-browser ; set browser browser
+macro a set browser "tsp youtube-dl --add-metadata -xic -f bestaudio/best" ; open-in-browser ; set browser browser
+macro v set browser "setsid -f mpv" ; open-in-browser ; set browser browser
+macro w set browser "lynx" ; open-in-browser ; set browser browser
+macro d set browser "dmenuhandler" ; open-in-browser ; set browser browser
+macro c set browser "echo %u | xclip -r -sel c" ; open-in-browser ; set browser browser
+macro C set browser "youtube-viewer --comments=%u" ; open-in-browser ; set browser browser
+macro p set browser "peertubetorrent %u 480" ; open-in-browser ; set browser browser
+macro P set browser "peertubetorrent %u 1080" ; open-in-browser ; set browser browser
+
+highlight all "---.*---" yellow
+highlight feedlist ".*(0/0))" black
+highlight article "(^Feed:.*|^Title:.*|^Author:.*)" cyan default bold
+highlight article "(^Link:.*|^Date:.*)" default default
+highlight article "https?://[^ ]+" green default
+highlight article "^(Title):.*$" blue default
+highlight article "\\[[0-9][0-9]*\\]" magenta default bold
+highlight article "\\[image\\ [0-9]+\\]" green default bold
+highlight article "\\[embedded flash: [0-9][0-9]*\\]" green default bold
+highlight article ":.*\\(link\\)$" cyan default
+highlight article ":.*\\(image\\)$" blue default
+highlight article ":.*\\(embedded flash\\)$" magenta default
diff --git a/nvim/init.vim b/nvim/init.vim
new file mode 100644
index 0000000..b5831c2
--- /dev/null
+++ b/nvim/init.vim
@@ -0,0 +1,267 @@
+" vimplugs {{{
+call plug#begin('~/.config/nvim/plugged')
+" colorschemes {{{
+Plug 'tomasiser/vim-code-dark' " codedark color scheme
+Plug 'flazz/vim-colorschemes' " meta-color scheme package
+" }}}
+" language support {{{
+Plug 'axvr/org.vim' " basic org markup language implementation
+Plug 'ziglang/zig.vim' " zig programming language
+Plug 'jdonaldson/vaxe' " haxe programming language
+Plug 'xuhdev/vim-latex-live-preview', { 'for': 'tex' } " latex live preview support
+Plug 'waycrate/swhkd-vim' " swhkd syntax highlighting
+Plug 'HiPhish/guile.vim' " guile syntax highlighting
+" }}}
+" utility {{{
+Plug 'preservim/nerdtree' " directory tree interface
+Plug 'Xuyuanp/nerdtree-git-plugin' " git status indicator for nerdtree
+Plug 'PhilRunninger/nerdtree-visual-selection' " allows visual selection mode in nerdtree
+Plug 'tpope/vim-fugitive' " git command interface
+Plug 'junegunn/goyo.vim' " simplify the user interface (distraction-free) [BROKEN]
+Plug 'junegunn/limelight.vim' " focus on single paragraph of text at a time
+Plug 'vim-airline/vim-airline' " powerline the vim bottom bar
+Plug 'nathanaelkane/vim-indent-guides' " indent guides for vim
+Plug 'mhinz/vim-signify' " use signs to show diffs
+Plug 'tpope/vim-endwise' " auto end functions/if statements
+Plug 'tpope/vim-surround' " auto close stuff
+Plug 'mattn/emmet-vim' " html css easy formating
+Plug 'godlygeek/tabular' " Needed for vim-markdown
+Plug 'plasticboy/vim-markdown' " Better markdown support
+Plug 'ryanoasis/vim-devicons' " dev icons for nerdtree
+" }}}
+call plug#end()
+
+" }}}
+" nvim options {{{
+
+"" nvimrc:
+"" General
+
+set showmatch " Highlight matching brace
+
+set number
+set relativenumber
+
+colorscheme BlackSea
+
+set hlsearch " Highlight all search results
+set smartcase " Enable smart-case search
+set incsearch " Searches for strings incrementally
+
+set expandtab " Use spaces instead of tabs
+set shiftwidth=2 " Number of auto-indent spaces
+set smartindent " Enable smart-indent
+set smarttab " Enable smart-tabs
+set softtabstop=2 " Number of spaces per Tab
+
+"" Advanced
+set ruler " Show row and column ruler information
+set undolevels=1000 " Number of undo levels
+set backspace=indent,eol,start " Backspace behaviour
+filetype plugin indent on
+
+"" GUI Config
+set guifont=mononoki\ Nerd\ Font\ Mono:h12
+
+hi Normal guibg=NONE ctermbg=NONE
+hi NonText guibg=NONE ctermbg=NONE
+set background=dark
+
+set foldmethod=marker
+
+set conceallevel=2
+
+" set leader key
+
+let mapleader="'"
+
+" emmet {{{
+let g:user_emmet_leader_key=';'
+" }}}
+
+" zig config {{{
+let g:zig_fmt_autosave = 1
+" }}}
+
+" latex live preview {{{
+let g:livepreview_previewer = 'zathura'
+let g:livepreview_use_biber = 1
+let g:livepreview_cursorhold_recompile = 0
+" }}}
+
+" vim-markdown {{{
+let g:vim_markdown_folding_disabled = 1
+let g:vim_markdown_folding_level = 3
+let g:vim_markdown_toc_autofit = 1
+let g:vim_markdown_emphasis_multiline = 0
+let g:tex_conceal = ""
+let g:vim_markdown_math = 1
+let g:vim_markdown_conceal_code_blocks = 1
+let g:vim_markdown_fenced_languages = ['c++=cpp', 'viml=vim', 'bash=sh', 'ini=dosini']
+let g:vim_markdown_follow_anchor = 1
+let g:vim_markdown_math = 1
+let g:vim_markdown_frontmatter = 1
+let g:vim_markdown_toml_frontmatter = 1
+let g:vim_markdown_strikethrough = 1
+let g:vim_markdown_no_extensions_in_markdown = 1
+let g:vim_markdown_autowrite = 1
+let g:vim_markdown_auto_insert_bullets = 0
+let g:vim_markdown_new_list_item_indent = 0
+let g:vim_markdown_edit_url_in = 'tab'
+" }}}
+
+" NERDTree config {{{
+let g:NERDTreeGitStatusUseNerdFonts = 1 " use nerd fonts
+let g:NERDTreeGitStatusShowClean = 1 " default: 0
+let g:NERDTreeDirArrowExpandable = '>'
+let g:NERDTreeDirArrowCollapsible = '<'
+let g:NERDTreeMapToggleHidden = 'z'
+" }}}
+
+" Goyo config {{{
+let g:goyo_width = '90%'
+let g:goyo_height = '100%'
+" }}}
+
+" limelight config {{{
+let g:limelight_conceal_ctermfg = 'gray'
+let g:limelight_conceal_guifg = 'gray'
+" }}}
+
+" devicon config {{{
+let g:airline_powerline_fonts = 1
+let g:webdevicons_enable_nerdtree = 1
+" }}}
+
+" vim-indent-guides config {{{
+let g:indent_guides_enable_on_vim_startup = 0
+" }}}
+
+" vim-signify config {{{
+set updatetime=100
+" }}}
+
+" }}}
+" Functions {{{
+" Goyo functions {{{
+function! s:goyo_enter()
+ if executable('tmux') && strlen($TMUX)
+ silent !tmux set status off
+ silent !tmux list-panes -F '\#F' | grep -q Z || tmux resize-pane -Z
+ endif
+ set noshowmode
+ set noshowcmd
+ set scrolloff=999
+ Limelight
+ NERDTreeClose
+endfunction
+function! s:goyo_leave()
+ if executable('tmux') && strlen('$TMUX')
+ silent !tmux set status on
+ silent !tmux list-panes -F '\#F' | grep -q Z && tmux resize-pane -Z
+ endif
+ set showmode
+ set showcmd
+ set scrolloff=5
+ Limelight!
+ NERDTree
+endfunction
+" }}}
+" }}}
+" Autocommands {{{
+" Goyo autocommands {{{
+autocmd! User GoyoEnter nested call <SID>goyo_enter()
+autocmd! User GoyoLeave nested call <SID>goyo_leave()
+" }}}
+" NERDTree autocmds {{{
+autocmd StdinReadPre * let s:std_in=1
+autocmd VimEnter * if argc() == 0 && !exists('s:std_in') | NERDTree | wincmd p | endif
+autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in') |
+ \ execute 'NERDTree' argv()[0] | wincmd p | enew | execute 'cd '.argv()[0] | endif
+autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
+autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
+"autocmd BufEnter * if bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 |
+ "\ let buf=bufnr() | buffer# | execute "normal! \<C-W>w" | execute 'buffer;.buf | endif
+autocmd BufWinEnter * if getcmdwintype() == '' | silent NERDTreeMirror | endif
+" }}}
+" custom augroup {{{
+augroup custom
+ autocmd!
+ au BufEnter *.tex :LLPStartPreview
+ au BufEnter *.md :set textwidth=80
+ au BufWritePost init.vim :source %
+ au BufWritePost *.tex :make
+ au BufWritePost *sxhkdrc* :!pkill -USR1 -x sxhkd
+ au BufWritePost .Xresources :!xrdb ~/.Xresources
+ au BufWritePost .gitignore :!git add .gitignore
+augroup end
+" }}}
+" }}}
+" keybindings {{{
+
+inoremap <Down> <C-o>gj
+inoremap <Up> <C-o>gk
+inoremap <Home> <C-o>g<Home>
+inoremap <End> <C-o>g<End>
+vnoremap <Down> <C-o>gj
+vnoremap <Up> <C-o>gk
+vnoremap <Home> <C-o>g<Home>
+vnoremap <End> <C-o>g<End>
+noremap <Down> gj
+noremap <Up> gk
+
+" toggles
+noremap <leader>tn :set number!<CR>
+noremap <leader>tr :set relativenumber!<CR>
+noremap <leader>tt :NERDTreeToggle<CR>
+
+" tabs
+noremap <leader>th :tabprevious<CR>
+noremap <leader>tl :tabnext<CR>
+noremap <leader>tk :tabnew<CR>
+noremap <leader>tj :tabclose<CR>
+
+" splits
+noremap <leader>wh :vertical resize -1<CR>
+noremap <leader>wj :resize -1<CR>
+noremap <leader>wk :resize +1<CR>
+noremap <leader>wl :vertical resize +1<CR>
+
+" config
+noremap <leader>en :e ~/.config/nvim/init.vim<CR>
+noremap <leader>ec :source %<CR>
+
+" write as root
+noremap ZW :w !pkexec tee % >/dev/null
+
+" Goyo
+noremap <leader>G :Goyo<CR>
+
+" windows
+nnoremap <C-h> <C-w>h
+nnoremap <C-j> <C-w>j
+nnoremap <C-k> <C-w>k
+nnoremap <C-l> <C-w>l
+vnoremap <C-h> <C-w>h
+vnoremap <C-j> <C-w>j
+vnoremap <C-k> <C-w>k
+vnoremap <C-l> <C-w>l
+noremap <leader>xx :q<CR>
+noremap <leader>x! :q!<CR>
+noremap <leader>xw :wq<CR>
+noremap <leader>w :w<CR>
+
+" escape for term windows
+tnoremap <Esc> <C-\><C-n>
+
+" vim-plug
+noremap <leader>pi :PlugInstall<CR>
+noremap <leader>pu :PlugUpdate<CR>
+noremap <leader>pU :PlugUpgrade<CR>
+noremap <leader>pc :PlugClean<CR>
+
+" fugitive
+noremap <leader>gp :G pull<CR>
+noremap <leader>gd :G diff %<CR>
+
+" }}}
diff --git a/nyxt/auto-config.lisp b/nyxt/auto-config.lisp
new file mode 100644
index 0000000..88335fa
--- /dev/null
+++ b/nyxt/auto-config.lisp
@@ -0,0 +1,4 @@
+(DEFINE-CONFIGURATION BUFFER
+ ((DEFAULT-MODES (APPEND '(NYXT::VI-NORMAL-MODE) %SLOT-DEFAULT%))))
+(DEFINE-CONFIGURATION PROMPT-BUFFER
+ ((DEFAULT-MODES (APPEND '(NYXT::VI-INSERT-MODE) %SLOT-DEFAULT%))))
diff --git a/open/openrc b/open/openrc
new file mode 100644
index 0000000..2c5ebd0
--- /dev/null
+++ b/open/openrc
@@ -0,0 +1,15 @@
+[full]
+browser: ^https?://, www\., \.com, \.co\.uk, \.net
+#in_terminal yplay.pl: ^(http://)?(www\.)?youtube\.com/watch\?v=
+in_terminal $VISUAL: \.[^/]*rc$
+
+[suffix]
+soffice: odp, pptx?, docx?
+neovide: txt, c, cpp, nfo, pl, py, s, conf, md, yaml, toml, lua, h, lisp
+st -e less: log
+mpv: mp3, wav, mp4, wmv
+zathura: pdf, epub, ps
+browser: html?
+soffice: odt
+
+#xterm -e wget: http://.*.(tar|gz|bz2) - not called due to hash ordering
diff --git a/paru/paru.conf b/paru/paru.conf
new file mode 100644
index 0000000..8932c55
--- /dev/null
+++ b/paru/paru.conf
@@ -0,0 +1,37 @@
+#
+# $PARU_CONF
+# /etc/paru.conf
+# ~/.config/paru/paru.conf
+#
+# See the paru.conf(5) manpage for options
+
+#
+# GENERAL OPTIONS
+#
+[options]
+PgpFetch
+Devel
+Provides
+DevelSuffixes = -git -cvs -svn -bzr -darcs -always
+#AurOnly
+BottomUp
+#RemoveMake
+#SudoLoop
+UseAsk
+#CombinedUpgrade
+CleanAfter
+#UpgradeMenu
+NewsOnUpgrade
+
+#LocalRepo
+#Chroot
+#Sign
+#SignDb
+
+#
+# Binary OPTIONS
+#
+[bin]
+FileManager = lf
+#MFlags = --skippgpcheck
+Sudo = doas
diff --git a/picom.conf b/picom.conf
new file mode 100644
index 0000000..a98405c
--- /dev/null
+++ b/picom.conf
@@ -0,0 +1,93 @@
+# Shadow
+shadow = true;
+shadow-radius = 7;
+shadow-offset-x = -7;
+shadow-offset-y = -7;
+# shadow-opacity = 0.7;
+# shadow-red = 0.0;
+# shadow-green = 0.0;
+# shadow-blue = 0.0;
+shadow-exclude = [ "name = 'Notification'", "class_g = 'Conky'", "class_g ?= 'Notify-osd'", "class_g = 'Cairo-clock'" ];
+# shadow-exclude = "n:e:Notification";
+shadow-ignore-shaped = false;
+inactive-opacity = 1.0;
+active-opacity = 1.0;
+frame-opacity = 1.0;
+inactive-opacity-override = false;
+# inactive-dim = 0.2;
+# inactive-dim-fixed = true;
+blur-background = false;
+# blur-background-frame = true;
+blur-kern = "3x3box"
+# blur-kern = "5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+# blur-background-fixed = true;
+blur-background-exclude = [ "window_type = 'dock'", "window_type = 'desktop'" ];
+# opacity-rule = [ "80:class_g = 'URxvt'" ];
+
+# Fading
+fading = false;
+# fade-delta = 30;
+fade-in-step = 0.03;
+fade-out-step = 0.03;
+# no-fading-openclose = true;
+fade-exclude = [ ];
+
+# Other
+backend = "xrender"
+mark-wmwin-focused = true;
+mark-ovredir-focused = true;
+# use-ewmh-active-win = true;
+detect-rounded-corners = true;
+detect-client-opacity = true;
+refresh-rate = 0;
+vsync = true;
+dbe = false;
+# sw-opti = true;
+# unredir-if-possible = true;
+# unredir-if-possible-delay = 5000;
+# unredir-if-possible-exclude = [ ];
+focus-exclude = [ "class_g = 'Cairo-clock'" ];
+detect-transient = true;
+detect-client-leader = true;
+invert-color-include = [ ];
+# resize-damage = 1;
+
+# GLX backend
+# glx-no-stencil = true;
+glx-copy-from-front = "false";
+# glx-use-copysubbuffermesa = true;
+# glx-no-rebind-pixmap = true;
+use-damage = "true";
+# glx-use-gpushader4 = true;
+
+opacity-rule = [ "99:name *?= 'Screenshot'",
+"99:class_g = 'Firefox'",
+"99:name *?= 'Pale Moon'",
+"99:name *?= 'QupZilla'",
+"99:class_g = 'Midori'",
+"99:class_g = 'Lazpaint'",
+"99:class_g = 'Pinta'",
+"99:class_g = 'Viewnior'",
+"99:class_g = 'GIMP'",
+"99:class_g = 'Darktable'",
+"99:name *?= 'VLC'",
+"99:name *?= 'Event'",
+"99:name *?= 'Call'",
+"99:name *?= 'Minitube'",
+"99:name *?= 'Write'",
+"99:name *?= 'VirtualBox'",
+"99:name *?= 'Conky'",
+"90:name *?= 'Panel'",
+"90:name *?= 'Restart'",
+"90:name *?= 'Page Info'",
+"99:name *?= 'Image'",
+"75:class_g = 'kwrite'",
+"75:name *?= 'mousepad'"];
+
+# Window type settings
+wintypes:
+{
+ tooltip = { fade = true; shadow = false; opacity = 0.75; focus = true; };
+ dock = { opacity = 1; shadow = false; };
+};
+
diff --git a/pipewire/pipewire.conf b/pipewire/pipewire.conf
new file mode 100644
index 0000000..ac5f9c6
--- /dev/null
+++ b/pipewire/pipewire.conf
@@ -0,0 +1,246 @@
+# Daemon config file for PipeWire version "0.3.34" #
+#
+# Copy and edit this file in /etc/pipewire for systemwide changes
+# or in ~/.config/pipewire for local changes.
+
+context.properties = {
+ ## Configure properties in the system.
+ #library.name.system = support/libspa-support
+ #context.data-loop.library.name.system = support/libspa-support
+ #support.dbus = true
+ #link.max-buffers = 64
+ link.max-buffers = 16 # version < 3 clients can't handle more
+ #mem.warn-mlock = false
+ #mem.allow-mlock = true
+ #mem.mlock-all = false
+ #clock.power-of-two-quantum = true
+ #log.level = 2
+
+ core.daemon = true # listening for socket connections
+ core.name = pipewire-0 # core name and socket name
+
+ ## Properties for the DSP configuration.
+ #default.clock.rate = 48000
+ #default.clock.allowed-rates = [ 48000 ]
+ #default.clock.quantum = 1024
+ #default.clock.min-quantum = 32
+ #default.clock.max-quantum = 8192
+ #default.video.width = 640
+ #default.video.height = 480
+ #default.video.rate.num = 25
+ #default.video.rate.denom = 1
+ #
+ # These overrides are only applied when running in a vm.
+ vm.overrides = {
+ default.clock.min-quantum = 1024
+ }
+}
+
+context.spa-libs = {
+ #<factory-name regex> = <library-name>
+ #
+ # Used to find spa factory names. It maps an spa factory name
+ # regular expression to a library name that should contain
+ # that factory.
+ #
+ audio.convert.* = audioconvert/libspa-audioconvert
+ api.alsa.* = alsa/libspa-alsa
+ api.v4l2.* = v4l2/libspa-v4l2
+ api.libcamera.* = libcamera/libspa-libcamera
+ api.bluez5.* = bluez5/libspa-bluez5
+ api.vulkan.* = vulkan/libspa-vulkan
+ api.jack.* = jack/libspa-jack
+ support.* = support/libspa-support
+ #videotestsrc = videotestsrc/libspa-videotestsrc
+ #audiotestsrc = audiotestsrc/libspa-audiotestsrc
+}
+
+context.modules = [
+ #{ name = <module-name>
+ # [ args = { <key> = <value> ... } ]
+ # [ flags = [ [ ifexists ] [ nofail ] ]
+ #}
+ #
+ # Loads a module with the given parameters.
+ # If ifexists is given, the module is ignored when it is not found.
+ # If nofail is given, module initialization failures are ignored.
+ #
+
+ # Uses RTKit to boost the data thread priority.
+ { name = libpipewire-module-rtkit
+ args = {
+ #nice.level = -11
+ #rt.prio = 88
+ #rt.time.soft = 2000000
+ #rt.time.hard = 2000000
+ }
+ flags = [ ifexists nofail ]
+ }
+
+ # Set thread priorities without using RTKit.
+ #{ name = libpipewire-module-rt
+ # args = {
+ # nice.level = -11
+ # rt.prio = 88
+ # rt.time.soft = 2000000
+ # rt.time.hard = 2000000
+ # }
+ # flags = [ ifexists nofail ]
+ #}
+
+ # The native communication protocol.
+ { name = libpipewire-module-protocol-native }
+
+ # The profile module. Allows application to access profiler
+ # and performance data. It provides an interface that is used
+ # by pw-top and pw-profiler.
+ { name = libpipewire-module-profiler }
+
+ # Allows applications to create metadata objects. It creates
+ # a factory for Metadata objects.
+ { name = libpipewire-module-metadata }
+
+ # Creates a factory for making devices that run in the
+ # context of the PipeWire server.
+ { name = libpipewire-module-spa-device-factory }
+
+ # Creates a factory for making nodes that run in the
+ # context of the PipeWire server.
+ { name = libpipewire-module-spa-node-factory }
+
+ # Allows creating nodes that run in the context of the
+ # client. Is used by all clients that want to provide
+ # data to PipeWire.
+ { name = libpipewire-module-client-node }
+
+ # Allows creating devices that run in the context of the
+ # client. Is used by the session manager.
+ { name = libpipewire-module-client-device }
+
+ # The portal module monitors the PID of the portal process
+ # and tags connections with the same PID as portal
+ # connections.
+ { name = libpipewire-module-portal
+ flags = [ ifexists nofail ]
+ }
+
+ # The access module can perform access checks and block
+ # new clients.
+ { name = libpipewire-module-access
+ args = {
+ # access.allowed to list an array of paths of allowed
+ # apps.
+ #access.allowed = [
+ # /usr/bin/pipewire-media-session
+ #]
+
+ # An array of rejected paths.
+ #access.rejected = [ ]
+
+ # An array of paths with restricted access.
+ #access.restricted = [ ]
+
+ # Anything not in the above lists gets assigned the
+ # access.force permission.
+ #access.force = flatpak
+ }
+ }
+
+ # Makes a factory for wrapping nodes in an adapter with a
+ # converter and resampler.
+ { name = libpipewire-module-adapter }
+
+ # Makes a factory for creating links between ports.
+ { name = libpipewire-module-link-factory }
+
+ # Provides factories to make session manager objects.
+ { name = libpipewire-module-session-manager }
+]
+
+context.objects = [
+ #{ factory = <factory-name>
+ # [ args = { <key> = <value> ... } ]
+ # [ flags = [ [ nofail ] ]
+ #}
+ #
+ # Creates an object from a PipeWire factory with the given parameters.
+ # If nofail is given, errors are ignored (and no object is created).
+ #
+ #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
+ #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
+ #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
+ #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
+ #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } }
+ #{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
+
+ # A default dummy driver. This handles nodes marked with the "node.always-driver"
+ # property when no other driver is currently active. JACK clients need this.
+ { factory = spa-node-factory
+ args = {
+ factory.name = support.node.driver
+ node.name = Dummy-Driver
+ node.group = pipewire.dummy
+ priority.driver = 20000
+ }
+ }
+ { factory = spa-node-factory
+ args = {
+ factory.name = support.node.driver
+ node.name = Freewheel-Driver
+ priority.driver = 19000
+ node.group = pipewire.freewheel
+ node.freewheel = true
+ }
+ }
+ # This creates a new Source node. It will have input ports
+ # that you can link, to provide audio for this source.
+ #{ factory = adapter
+ # args = {
+ # factory.name = support.null-audio-sink
+ # node.name = "my-mic"
+ # node.description = "Microphone"
+ # media.class = "Audio/Source/Virtual"
+ # audio.position = "FL,FR"
+ # }
+ #}
+
+ # This creates a single PCM source device for the given
+ # alsa device path hw:0. You can change source to sink
+ # to make a sink in the same way.
+ #{ factory = adapter
+ # args = {
+ # factory.name = api.alsa.pcm.source
+ # node.name = "alsa-source"
+ # node.description = "PCM Source"
+ # media.class = "Audio/Source"
+ # api.alsa.path = "hw:0"
+ # #api.alsa.period-size = 1024
+ # #api.alsa.headroom = 0
+ # #api.alsa.disable-mmap = false
+ # #api.alsa.disable-batch = false
+ # #audio.format = "S16LE"
+ # #audio.rate = 48000
+ # #audio.channels = 2
+ # #audio.position = "FL,FR"
+ # }
+ #}
+]
+
+context.exec = [
+ #{ path = <program-name> [ args = "<arguments>" ] }
+ #
+ # Execute the given program with arguments.
+ #
+ # You can optionally start the session manager here,
+ # but it is better to start it as a systemd service.
+ # Run the session manager with -h for options.
+ #
+ { path = "/usr/bin/wireplumber" args = "-c wireplumber.conf" }
+ #
+ # You can optionally start the pulseaudio-server here as well
+ # but it is better to start it as a systemd service.
+ # It can be interesting to start another daemon here that listens
+ # on another address with the -a option (eg. -a tcp:4713).
+ #
+ { path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" }
+]
diff --git a/pipewire/wireplumber.conf b/pipewire/wireplumber.conf
new file mode 100644
index 0000000..3595858
--- /dev/null
+++ b/pipewire/wireplumber.conf
@@ -0,0 +1,90 @@
+# WirePlumber daemon context configuration #
+
+context.properties = {
+ ## Properties to configure the PipeWire context and some modules
+
+ #application.name = WirePlumber
+ log.level = 2
+ wireplumber.script-engine = lua-scripting
+ #wireplumber.export-core = true
+
+ #mem.mlock-all = false
+ #support.dbus = true
+}
+
+context.spa-libs = {
+ #<factory-name regex> = <library-name>
+ #
+ # Used to find spa factory names. It maps an spa factory name
+ # regular expression to a library name that should contain
+ # that factory.
+ #
+ api.alsa.* = alsa/libspa-alsa
+ api.bluez5.* = bluez5/libspa-bluez5
+ api.v4l2.* = v4l2/libspa-v4l2
+ api.libcamera.* = libcamera/libspa-libcamera
+ audio.convert.* = audioconvert/libspa-audioconvert
+ support.* = support/libspa-support
+}
+
+context.modules = [
+ #{ name = <module-name>
+ # [ args = { <key> = <value> ... } ]
+ # [ flags = [ [ ifexists ] [ nofail ] ]
+ #}
+ #
+ # PipeWire modules to load.
+ # If ifexists is given, the module is ignored when it is not found.
+ # If nofail is given, module initialization failures are ignored.
+ #
+
+ # Uses RTKit to boost the data thread priority.
+ { name = libpipewire-module-rt
+ args = {
+ nice.level = -11
+ #rt.prio = 88
+ #rt.time.soft = -1
+ #rt.time.hard = -1
+ }
+ flags = [ ifexists nofail ]
+ }
+
+ # The native communication protocol.
+ { name = libpipewire-module-protocol-native }
+
+ # Allows creating nodes that run in the context of the
+ # client. Is used by all clients that want to provide
+ # data to PipeWire.
+ { name = libpipewire-module-client-node }
+
+ # Allows creating devices that run in the context of the
+ # client. Is used by the session manager.
+ { name = libpipewire-module-client-device }
+
+ # Makes a factory for wrapping nodes in an adapter with a
+ # converter and resampler.
+ { name = libpipewire-module-adapter }
+
+ # Allows applications to create metadata objects. It creates
+ # a factory for Metadata objects.
+ { name = libpipewire-module-metadata }
+
+ # Provides factories to make session manager objects.
+ { name = libpipewire-module-session-manager }
+]
+
+wireplumber.components = [
+ #{ name = <component-name>, type = <component-type> }
+ #
+ # WirePlumber components to load
+ #
+
+ # The lua scripting engine
+ { name = libwireplumber-module-lua-scripting, type = module }
+
+ # The lua configuration file(s)
+ # Other components are loaded from there
+ { name = main.lua, type = config/lua }
+ { name = policy.lua, type = config/lua }
+ { name = bluetooth.lua, type = config/lua }
+]
diff --git a/polybar/config b/polybar/config
new file mode 100644
index 0000000..f7b924d
--- /dev/null
+++ b/polybar/config
@@ -0,0 +1,615 @@
+;==========================================================
+;
+;
+; ██████╗ ██████╗ ██╗ ██╗ ██╗██████╗ █████╗ ██████╗
+; ██╔══██╗██╔═══██╗██║ ╚██╗ ██╔╝██╔══██╗██╔══██╗██╔══██╗
+; ██████╔╝██║ ██║██║ ╚████╔╝ ██████╔╝███████║██████╔╝
+; ██╔═══╝ ██║ ██║██║ ╚██╔╝ ██╔══██╗██╔══██║██╔══██╗
+; ██║ ╚██████╔╝███████╗██║ ██████╔╝██║ ██║██║ ██║
+; ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
+;
+;
+; To learn more about how to configure Polybar
+; go to https://github.com/jaagr/polybar
+;
+; The README contains alot of information
+;
+;==========================================================
+
+[colors]
+;background = ${xrdb:color0:#222}
+background = #000
+background-alt = #222
+;foreground = ${xrdb:color7:#222}
+foreground = #fff
+foreground-alt = #ddd
+primary = #ffb52a
+secondary = #9f9
+alert = #bd2c40
+
+[bar/xmonad]
+monitor = ${env:MONITOR:}
+width = 100%
+height = 24
+;offset-x = 1%
+;offset-y = 1%
+radius = 0.0
+fixed-center = false
+
+background = ${colors.background}
+foreground = ${colors.foreground}
+
+line-size = 3
+line-color = #f00
+
+border-size = 0
+border-color = #00000000
+
+padding-left = 0
+padding-right = 0
+
+module-margin-left = 1
+module-margin-right = 2
+font-0 = mononoki Nerd Font:pixelsize=10;1
+font-1 = JoyPixels:pixelsize=10;1
+
+modules-left = ewmh
+;i3
+modules-center =
+modules-right = mpd packages pulse battery memory cpu wlan eth filesystem date powermenu
+;xbacklight temperature
+tray-position = right
+tray-padding = 2
+;tray-background = #0063ff
+
+;wm-restack = bspwm
+;wm-restack = i3
+
+;override-redirect = true
+
+;scroll-up = bspwm-desknext
+;scroll-down = bspwm-deskprev
+
+;scroll-up = i3wm-wsnext
+;scroll-down = i3wm-wsprev
+
+cursor-click = pointer
+cursor-scroll = ns-resize
+
+[bar/herbstluft]
+monitor = ${env:MONITOR:}
+width = 100%
+height = 20
+;offset-x = 1%
+;offset-y = 1%
+radius = 0.0
+fixed-center = false
+enable-ipc = true
+
+background = ${colors.background}
+foreground = ${colors.foreground}
+
+line-size = 3
+line-color = #f00
+
+border-size = 0
+border-color = #00000000
+
+padding-left = 0
+padding-right = 0
+
+module-margin-left = 1
+module-margin-right = 2
+
+font-0 = mononoki Nerd Font:pixelsize=10;1
+font-1 = JoyPixels:pixelsize=10;1
+
+modules-left = ewmh title
+modules-center =
+modules-right = packages mail filesystem pulseaudio xkeyboard mem cpu wlan eth battery date powermenu
+;xbacklight temperature
+tray-position = right
+tray-padding = 2
+;tray-background = #0063ff
+
+;wm-restack = bspwm
+;wm-restack = i3
+
+;override-redirect = true
+
+;scroll-up = bspwm-desknext
+;scroll-down = bspwm-deskprev
+
+;scroll-up = i3wm-wsnext
+;scroll-down = i3wm-wsprev
+
+cursor-click = pointer
+cursor-scroll = ns-resize
+
+[bar/bspwm]
+monitor = ${env:MONITOR:}
+width = 100%
+height = 20
+;offset-x = 1%
+;offset-y = 1%
+radius = 0.0
+fixed-center = false
+
+background = ${colors.background}
+foreground = ${colors.foreground}
+
+line-size = 3
+line-color = #f00
+
+border-size = 0
+border-color = #00000000
+
+padding-left = 0
+padding-right = 0
+
+module-margin-left = 1
+module-margin-right = 2
+
+font-0 = mononoki Nerd Font:pixelsize=10;1
+font-1 = JoyPixels:pixelsize=10;1
+
+modules-left = bspwm
+;i3
+modules-center =
+modules-right = mail mpd filesystem pulseaudio alsa xkeyboard memory cpu wlan eth battery date powermenu
+;xbacklight temperature
+tray-position = right
+tray-padding = 2
+;tray-background = #0063ff
+
+wm-restack = bspwm
+;wm-restack = i3
+
+;override-redirect = true
+
+scroll-up = bspwm-desknext
+scroll-down = bspwm-deskprev
+
+;scroll-up = i3wm-wsnext
+;scroll-down = i3wm-wsprev
+
+cursor-click = pointer
+cursor-scroll = ns-resize
+
+[module/title]
+type = internal/xwindow
+label = %title%
+label-maxlen = 45
+
+[module/ewmh]
+type = internal/xworkspaces
+
+; Only show workspaces defined on the same output as the bar
+;
+; Useful if you want to show monitor specific workspaces
+; on different bars
+;
+; Default: false
+pin-workspaces = false
+
+; Create click handler used to focus desktop
+; Default: true
+enable-click = true
+
+; Create scroll handlers used to cycle desktops
+; Default: true
+enable-scroll = false
+
+label-active = %name%
+label-active-foreground = #ffffff
+label-active-background = #222222
+label-active-padding = 2
+
+label-occupied = %name%
+label-occupied-foreground = #ffffff
+label-occupied-background = #000000
+label-occupied-padding = 2
+
+label-urgent = %name%
+label-urgent-foreground = #ff0000
+label-urgent-background = #000000
+label-urgent-padding = 2
+
+label-empty = %name%
+label-empty-foreground = #7b7b7b
+label-empty-backgorund = #000000
+label-empty-padding = 2
+
+[module/packages]
+type = custom/ipc
+format-underline = #3399bb
+hook-0 = pacpackages
+initial = 1
+
+[module/herbstluftwm]
+type = custom/ipc
+hook-0 = herbsttags
+initial = 1
+
+[module/mail]
+type = custom/script
+exec = mail
+format-underline = #020
+interval = 10
+
+[module/mem]
+type = custom/script
+exec = free -h | awk '/Mem/ {print $3}'
+format-underline = #ff6c6b
+interval = 5
+
+[module/workspaces-xmonad]
+type = custom/script
+exec = tail -F /tmp/.xmonad-workspace-log
+exec-if = [ -p /tmp/.xmonad-workspace-log ]
+tail = true
+
+[module/title-xmonad]
+type = custom/script
+exec = tail -F /tmp/.xmonad-title-log
+exec-if = [ -p /tmp/.xmonad-title-log ]
+tail = true
+
+[module/xwindow]
+type = internal/xwindow
+label = %title:0:30:...%
+
+[module/xkeyboard]
+type = internal/xkeyboard
+blacklist-0 = num lock
+
+format-prefix =
+format-prefix-foreground = ${colors.foreground-alt}
+format-prefix-underline = ${colors.secondary}
+
+label-layout = %layout%
+label-layout-underline = ${colors.secondary}
+
+label-indicator-padding = 2
+label-indicator-margin = 1
+label-indicator-background = ${colors.secondary}
+label-indicator-underline = ${colors.secondary}
+
+[module/filesystem]
+type = internal/fs
+interval = 25
+
+mount-0 = /
+
+label-mounted = %{F#0a81f5}%mountpoint%%{F-}: %percentage_used%%
+label-unmounted = %mountpoint% not mounted
+label-unmounted-foreground = ${colors.foreground-alt}
+
+format-underline = #51afef
+
+[module/bspwm]
+type = internal/bspwm
+
+label-focused = %index%
+label-focused-background = ${colors.background-alt}
+label-focused-underline= ${colors.primary}
+label-focused-padding = 2
+
+label-occupied = %index%
+label-occupied-padding = 2
+
+label-urgent = %index%!
+label-urgent-background = ${colors.alert}
+label-urgent-padding = 2
+
+label-empty = %index%
+label-empty-foreground = ${colors.foreground-alt}
+label-empty-padding = 2
+
+; Separator in between workspaces
+; label-separator = |
+
+[module/i3]
+type = internal/i3
+format = <label-state> <label-mode>
+index-sort = true
+wrapping-scroll = false
+
+; Only show workspaces on the same output as the bar
+;pin-workspaces = true
+
+label-mode-padding = 2
+label-mode-foreground = #000
+label-mode-background = ${colors.primary}
+
+; focused = Active workspace on focused monitor
+label-focused = %index%
+label-focused-background = ${module/bspwm.label-focused-background}
+label-focused-underline = ${module/bspwm.label-focused-underline}
+label-focused-padding = ${module/bspwm.label-focused-padding}
+
+; unfocused = Inactive workspace on any monitor
+label-unfocused = %index%
+label-unfocused-padding = ${module/bspwm.label-occupied-padding}
+
+; visible = Active workspace on unfocused monitor
+label-visible = %index%
+label-visible-background = ${self.label-focused-background}
+label-visible-underline = ${self.label-focused-underline}
+label-visible-padding = ${self.label-focused-padding}
+
+; urgent = Workspace with urgency hint set
+label-urgent = %index%
+label-urgent-background = ${module/bspwm.label-urgent-background}
+label-urgent-padding = ${module/bspwm.label-urgent-padding}
+
+; Separator in between workspaces
+; label-separator = |
+
+
+[module/mpd]
+type = internal/mpd
+format-online = <label-song> <icon-prev> <icon-stop> <toggle> <icon-next>
+
+icon-prev = <
+icon-stop = s
+icon-play = p
+icon-pause = a
+icon-next = >
+
+label-song-maxlen = 25
+label-song-ellipsis = true
+
+[module/xbacklight]
+type = internal/xbacklight
+
+format = <label> <bar>
+label = BL
+
+bar-width = 10
+bar-indicator = |
+bar-indicator-foreground = #fff
+bar-indicator-font = 2
+bar-fill = -
+bar-fill-font = 2
+bar-fill-foreground = #9f78e1
+bar-empty = -
+bar-empty-font = 2
+bar-empty-foreground = ${colors.foreground-alt}
+
+[module/backlight-acpi]
+inherit = module/xbacklight
+type = internal/backlight
+card = intel_backlight
+
+[module/cpu]
+type = internal/cpu
+interval = 2
+format-prefix =
+format-prefix-foreground = #ecbe7b
+format-underline = #ecbe7b
+label = %percentage%%
+
+[module/memory]
+type = internal/memory
+interval = 2
+format-prefix =
+format-prefix-foreground = #ff6c6b
+format-underline = #ff6c6b
+label = %mb_used%
+
+[module/wlan]
+type = internal/network
+interface = wlan0
+interval = 3.0
+
+format-connected = <ramp-signal> <label-connected>
+format-connected-underline = #33bb99
+label-connected = %essid%
+
+format-disconnected =
+;format-disconnected = <label-disconnected>
+;format-disconnected-underline = ${self.format-connected-underline}
+;label-disconnected = %ifname% disconnected
+;label-disconnected-foreground = ${colors.foreground-alt}
+
+ramp-signal-0 =
+ramp-signal-1 =
+ramp-signal-2 =
+ramp-signal-3 =
+ramp-signal-4 =
+ramp-signal-foreground = #33bb99
+
+[module/eth]
+type = internal/network
+interface = eth0
+interval = 3.0
+
+format-connected-underline = #0f9
+format-connected-prefix =
+format-connected-prefix-foreground = ${colors.foreground-alt}
+label-connected = %local_ip%
+
+format-disconnected =
+;format-disconnected = <label-disconnected>
+;format-disconnected-underline = ${self.format-connected-underline}
+;label-disconnected = %ifname% disconnected
+;label-disconnected-foreground = ${colors.foreground-alt}
+
+[module/date]
+type = internal/date
+interval = 5
+
+date = "%m-%d-%Y"
+date-alt = "%Y-%m-%d"
+
+time = %I:%M %p
+time-alt = %H:%M:%S
+
+format-prefix =
+format-prefix-foreground = #46d9ff
+format-underline = #46d9ff
+
+label = %date% %time%
+
+[module/pulseaudio]
+type = internal/pulseaudio
+
+format-volume = <label-volume> <bar-volume>
+label-volume = VOL %percentage%%
+label-volume-foreground = ${root.foreground}
+
+label-muted = muted
+label-muted-foreground = #b00
+
+bar-volume-width = 10
+bar-volume-foreground-0 = #55aa55
+bar-volume-foreground-1 = #55aa55
+bar-volume-foreground-2 = #55aa55
+bar-volume-foreground-3 = #55aa55
+bar-volume-foreground-4 = #55aa55
+bar-volume-foreground-5 = #f5a70a
+bar-volume-foreground-6 = #ff5555
+bar-volume-gradient = false
+bar-volume-indicator = |
+bar-volume-indicator-font = 2
+bar-volume-fill = -
+bar-volume-fill-font = 2
+bar-volume-empty = -
+bar-volume-empty-font = 2
+bar-volume-empty-foreground = ${colors.foreground-alt}
+
+[module/alsa]
+type = internal/alsa
+
+master-mixer = Master
+mapped = true
+interval = 5
+
+format-volume = <label-volume> <bar-volume>
+label-volume = VOL
+label-volume-foreground = ${root.foreground}
+
+format-muted-prefix =
+format-muted-foreground = ${colors.foreground-alt}
+label-muted = sound muted
+
+ramp-volume-0 =
+ramp-volume-1 =
+ramp-volume-2 =
+
+bar-volume-width = 10
+bar-volume-foreground-0 = #55aa55
+bar-volume-foreground-1 = #55aa55
+bar-volume-foreground-2 = #55aa55
+bar-volume-foreground-3 = #55aa55
+bar-volume-foreground-4 = #55aa55
+bar-volume-foreground-5 = #f5a70a
+bar-volume-foreground-6 = #ff5555
+bar-volume-gradient = false
+bar-volume-indicator = |
+bar-volume-indicator-font = 2
+bar-volume-fill = -
+bar-volume-fill-font = 2
+bar-volume-empty = -
+bar-volume-empty-font = 2
+bar-volume-empty-foreground = ${colors.foreground-alt}
+
+[module/battery]
+type = internal/battery
+battery = BAT0
+adapter = AC
+full-at = 99
+
+format-charging = <animation-charging> <label-charging>
+format-charging-underline = #fb0
+
+format-discharging = <animation-discharging> <label-discharging>
+format-discharging-underline = #f00
+
+format-full-prefix =
+format-full-prefix-foreground = ${colors.foreground-alt}
+format-full-underline = #0f0
+
+ramp-capacity-0 =
+ramp-capacity-1 =
+ramp-capacity-2 =
+ramp-capacity-foreground = ${colors.foreground-alt}
+
+animation-charging-0 = +
+animation-charging-1 = +
+animation-charging-2 = +
+animation-charging-foreground = ${colors.foreground-alt}
+animation-charging-framerate = 750
+
+animation-discharging-0 = -
+animation-discharging-1 = -
+animation-discharging-2 = -
+animation-discharging-foreground = ${colors.foreground-alt}
+animation-discharging-framerate = 750
+
+[module/temperature]
+type = internal/temperature
+thermal-zone = 0
+warn-temperature = 60
+
+format = <ramp> <label>
+format-underline = #f50a4d
+format-warn = <ramp> <label-warn>
+format-warn-underline = ${self.format-underline}
+
+label = %temperature-c%
+label-warn = %temperature-c%
+label-warn-foreground = ${colors.secondary}
+
+ramp-0 =
+ramp-1 =
+ramp-2 =
+ramp-foreground = ${colors.foreground-alt}
+
+[module/powermenu]
+type = custom/menu
+
+expand-right = true
+
+format-spacing = 2
+
+label-open = +
+
+label-separator-foreground = ${colors.foreground-alt}
+
+menu-0-0 = r
+menu-0-0-exec = menu-open-1
+menu-0-1 = s
+menu-0-1-exec = menu-open-2
+menu-0-2 = h
+menu-0-2-exec = menu-open-3
+
+menu-1-0 = c
+menu-1-0-exec = menu-open-0
+menu-1-1 = r
+menu-1-1-exec = doas /sbin/reboot
+
+menu-2-0 = s
+menu-2-0-exec = doas /sbin/poweroff
+menu-2-1 = c
+menu-2-1-exec = menu-open-0
+
+menu-3-0 = h
+menu-3-0-exec = loginctl hibernate
+menu-3-1 = c
+menu-3-1-exec = menu-open-0
+
+[settings]
+screenchange-reload = true
+;compositing-background = xor
+;compositing-background = screen
+;compositing-foreground = source
+;compositing-border = over
+;pseudo-transparency = false
+
+[global/wm]
+margin-top = 5
+margin-bottom = 5
+
+; vim:ft=dosini
diff --git a/profanity/themes/redbox b/profanity/themes/redbox
new file mode 100644
index 0000000..68ed360
--- /dev/null
+++ b/profanity/themes/redbox
@@ -0,0 +1,80 @@
+[colours]
+bkgnd=default
+titlebar=bold_red
+titlebar.text=yellow
+titlebar.brackets=green
+titlebar.unencrypted=red
+titlebar.encrypted=yellow
+titlebar.untrusted=red
+titlebar.trusted=yellow
+titlebar.online=yellow
+titlebar.offline=red
+titlebar.away=purple
+titlebar.chat=yellow
+titlebar.dnd=red
+titlebar.xa=yellow
+statusbar=bold_red
+statusbar.text=yellow
+statusbar.brackets=purple
+statusbar.active=white
+statusbar.new=yellow
+main.text=white
+main.text.me=white
+main.text.them=white
+main.splash=red
+main.time=red
+input.text=white
+subscribed=yellow
+unsubscribed=red
+otr.started.trusted=yellow
+otr.started.untrusted=red
+otr.ended=yellow
+otr.trusted=yellow
+otr.untrusted=red
+online=yellow
+away=red
+chat=yellow
+dnd=purple
+xa=yellow
+offline=bold_black
+incoming=yellow
+mention=red
+trigger=red
+typing=yellow
+gone=red
+error=red
+roominfo=yellow
+roommention=red
+roommention.term=red
+roomtrigger=red
+roomtrigger.term=red
+me=blue
+them=yellow
+roster.header=white
+roster.chat=yellow
+roster.online=yellow
+roster.away=yellow
+roster.xa=yellow
+roster.dnd=purple
+roster.offline=bold_black
+roster.chat.active=yellow
+roster.online.active=yellow
+roster.away.active=yellow
+roster.xa.active=yellow
+roster.dnd.active=purple
+roster.offline.active=bold_black
+roster.chat.unread=white
+roster.online.unread=white
+roster.away.unread=yellow
+roster.xa.unread=yellow
+roster.dnd.unread=purple
+roster.offline.unread=bold_black
+roster.room=yellow
+roster.room.unread=white
+roster.room.mention=yellow
+roster.room.trigger=yellow
+occupants.header=white
+receipt.sent=red
+[ui]
+beep=false
+flash=false
diff --git a/psub/config.yaml b/psub/config.yaml
new file mode 100644
index 0000000..55b5421
--- /dev/null
+++ b/psub/config.yaml
@@ -0,0 +1,74 @@
+#
+# _________ ___.
+# ______ / _____/__ _\_ |__
+# \____ \\_____ \| | \ __ # | |_> > \ | / \_\ \
+# | __/_______ /____/|___ /
+# |__| \/ \/
+#
+#
+
+# This section defines the connection to your Subsonic server
+
+server:
+ # This is the url you would use to access your Subsonic server without the protocol
+ # (http:// or https://)
+
+ host: cloud.zachir.xyz/index.php/apps/music/subsonic
+
+ # Username and Password next
+
+ username: zachir
+ password: iagcuoc95i9j
+
+ # If your Subsonic server is accessed over https:// set this to 'true'
+
+ ssl: true
+
+ # If you use a server with a specific API version set it here
+
+ api: 1.16.0
+
+# This section defines the playback of music by pSub
+
+streaming:
+
+ # The default format is 'raw'
+ # this means the original file is streamed from your server
+ # and no transcoding takes place.
+ # set this to mp3 or wav etc.
+ # depending on the transcoders available to your user on the server
+
+ format: mp3
+
+ # pSub utilises ffplay (https://ffmpeg.org/ffplay.html) to play the streamed media
+ # by default the player window is hidden and control takes place through the cli
+ # set this to true to enable the player window.
+ # It allows for more controls (volume mainly) but will grab the focus of your
+ # keyboard when tracks change which can be annoying if you are typing
+
+ display: false
+
+ # When the player window is shown, choose the default show mode
+ # Options are:
+ # 0: show video or album art
+ # 1: show audio waves
+ # 2: show audio frequency band using RDFT ((Inverse) Real Discrete Fourier Transform)
+
+ show_mode: 0
+
+ # Artist, Album and Playlist playback can accept a -r/--random flag.
+ # by default, setting the flag on the command line means "randomise playback".
+ # Setting the following to true will invert that behaviour so that playback is randomised by default
+ # and passing the -r flag skips the random shuffle
+
+ invert_random: false
+
+ # pSub can use system notifications to alert you to a song change.
+ # it will show you the details of the currently playing song.
+ # to disable notification, set this to false
+
+ notify: false
+
+client:
+ # Added extra client config for pre-exe commands, like using it in flatpak-spawn
+ pre_exe: ''
diff --git a/qt5ct/qt5ct.conf b/qt5ct/qt5ct.conf
new file mode 100644
index 0000000..818f4cc
--- /dev/null
+++ b/qt5ct/qt5ct.conf
@@ -0,0 +1,32 @@
+[Appearance]
+color_scheme_path=/usr/share/qt5ct/colors/airy.conf
+custom_palette=false
+icon_theme=Paper-Mono-Dark
+standard_dialogs=default
+style=gtk2
+
+[Fonts]
+fixed=@Variant(\0\0\0@\0\0\0\x10\0m\0o\0n\0o\0n\0o\0k\0i@\"\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10)
+general=@Variant(\0\0\0@\0\0\0\x14\0S\0\x61\0n\0s\0 \0S\0\x65\0r\0i\0\x66@\"\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10)
+
+[Interface]
+activate_item_on_single_click=1
+buttonbox_layout=3
+cursor_flash_time=1000
+dialog_buttons_have_icons=2
+double_click_interval=400
+gui_effects=General, AnimateMenu, AnimateCombo, AnimateTooltip, AnimateToolBox
+keyboard_scheme=2
+menus_have_icons=true
+show_shortcuts_in_context_menus=true
+stylesheets=/usr/share/qt5ct/qss/fusion-fixes.qss, /usr/share/qt5ct/qss/scrollbar-simple.qss, /usr/share/qt5ct/qss/sliders-simple.qss, /usr/share/qt5ct/qss/tooltip-simple.qss, /usr/share/qt5ct/qss/traynotification-simple.qss
+toolbutton_style=4
+underline_shortcut=2
+wheel_scroll_lines=3
+
+[SettingsWindow]
+geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x2\xb0\0\0\x1\x88\0\0\x5N\0\0\x2\xf8\0\0\x2\xb1\0\0\x1\x89\0\0\x5M\0\0\x2\xf7\0\0\0\0\0\0\0\0\x5V\0\0\x2\xb1\0\0\x1\x89\0\0\x5M\0\0\x2\xf7)
+
+[Troubleshooting]
+force_raster_widgets=1
+ignored_applications=@Invalid()
diff --git a/qt6ct/qt6ct.conf b/qt6ct/qt6ct.conf
new file mode 100644
index 0000000..e0c4fe0
--- /dev/null
+++ b/qt6ct/qt6ct.conf
@@ -0,0 +1,38 @@
+[Appearance]
+<<<<<<< HEAD
+color_scheme_path=/usr/local/share/qt6ct/colors/airy.conf
+custom_palette=false
+standard_dialogs=default
+=======
+color_scheme_path=/usr/share/qt6ct/colors/darker.conf
+custom_palette=true
+icon_theme=Paper-Mono-Dark
+standard_dialogs=gtk2
+>>>>>>> 66e665f6f575c4e5a58074e143404d08b7a89d42
+style=gtk2
+
+[Fonts]
+fixed=@Variant(\0\0\0@\0\0\0\x1e\0\x44\0\x65\0j\0\x61\0V\0u\0 \0L\0G\0\x43\0 \0S\0\x61\0n\0s@(\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10)
+general=@Variant(\0\0\0@\0\0\0\x1e\0\x44\0\x65\0j\0\x61\0V\0u\0 \0L\0G\0\x43\0 \0S\0\x61\0n\0s@(\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10)
+
+[Interface]
+activate_item_on_single_click=1
+buttonbox_layout=0
+cursor_flash_time=1000
+dialog_buttons_have_icons=1
+double_click_interval=400
+gui_effects=@Invalid()
+keyboard_scheme=2
+menus_have_icons=true
+show_shortcuts_in_context_menus=true
+stylesheets=@Invalid()
+toolbutton_style=4
+underline_shortcut=1
+wheel_scroll_lines=3
+
+[SettingsWindow]
+geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\vC\0\0\0\x1b\0\0\xe\xf8\0\0\x4\x30\0\0\vE\0\0\0\x1d\0\0\xe\xf6\0\0\x4.\0\0\0\0\0\0\0\0\a\x80\0\0\vE\0\0\0\x1d\0\0\xe\xf6\0\0\x4.)
+
+[Troubleshooting]
+force_raster_widgets=1
+ignored_applications=@Invalid()
diff --git a/qtile/config.py b/qtile/config.py
new file mode 100644
index 0000000..4b13459
--- /dev/null
+++ b/qtile/config.py
@@ -0,0 +1,539 @@
+# Copyright (c) 2010 Aldo Cortesi
+# Copyright (c) 2010, 2014 dequis
+# Copyright (c) 2012 Randall Ma
+# Copyright (c) 2012-2014 Tycho Andersen
+# Copyright (c) 2012 Craig Barnes
+# Copyright (c) 2013 horsik
+# Copyright (c) 2013 Tao Sauvage
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os
+import subprocess
+import psutil
+
+from typing import List # noqa: F401
+
+from libqtile import bar, hook, layout, qtile, widget
+from libqtile.config import Click, Drag, DropDown, Group, Key, Match, ScratchPad, Screen
+from libqtile.lazy import lazy
+
+mod = "mod1"
+if qtile.core.name == "x11":
+ terminal = 'st'
+ terminal_session = 'tabbed -c st -w'
+ # terminal_session = 'st -e '
+elif qtile.core.name == "wayland":
+ terminal = 'alacritty'
+ terminal_session = 'tabbed -c alacritty --embed'
+ # terminal_session = 'alacritty -e'
+
+computerrc = open('/home/zachir/.config/computerrc', 'r')
+Lines = computerrc.readlines()
+count = 0
+for line in Lines:
+ if ('inet' in Lines[count][:5]):
+ break
+ count += 1
+inet = Lines[count][5:-1]
+
+barcolor_cyan = "39c1ed"
+barcolor_black = "000000"
+barcolor_gray1 = "111111"
+barcolor_gray2 = "222222"
+barcolor_gray6 = "666666"
+barcolor_gray8 = "888888"
+barcolor_graya = "aaaaaa"
+barcolor_white = "ffffff"
+barcolor_red = "ff0000"
+barcolor_magenta = "ff00ff"
+
+def resize(qtile, direction):
+ layout = qtile.current_layout
+ child = layout.current
+ parent = child.parent
+
+ while parent:
+ if child in parent.children:
+ layout_all = False
+
+ if (direction == "left" and parent.split_horizontal) or (
+ direction == "up" and not parent.split_horizontal
+ ):
+ parent.split_ratio = max(5, parent.split_ratio - layout.grow_amount)
+ layout_all = True
+ elif (direction == "right" and parent.split_horizontal) or (
+ direction == "down" and not parent.split_horizontal
+ ):
+ parent.split_ratio = min(95, parent.split_ratio + layout.grow_amount)
+ layout_all = True
+
+ if layout_all:
+ layout.group.layout_all()
+ break
+
+ child = parent
+ parent = child.parent
+
+@lazy.function
+def resize_left(qtile):
+ resize(qtile, "left")
+
+@lazy.function
+def resize_right(qtile):
+ resize(qtile, "right")
+
+@lazy.function
+def resize_up(qtile):
+ resize(qtile, "up")
+
+@lazy.function
+def resize_down(qtile):
+ resize(qtile, "down")
+
+keys = [
+ # Switch between windows
+ Key([mod], "h", lazy.layout.left(), desc="Move focus down"),
+ Key([mod], "l", lazy.layout.right(), desc="Move focus up"),
+ Key([mod], "j", lazy.layout.down(), desc="Move focus down"),
+ Key([mod], "k", lazy.layout.up(), desc="Move focus up"),
+ Key([mod, "shift"], "space", lazy.layout.next(),
+ desc="Move window focus to other window"),
+
+ # swap columns
+ Key([mod, "shift", "control"], "h", lazy.layout.swap_column_left()),
+ Key([mod, "shift", "control"], "l", lazy.layout.swap_column_right()),
+
+ # Move windows between left/right columns or move up/down in current stack.
+ # Moving out of range in Columns layout will create new column.
+ Key([mod, "shift"], "h", lazy.layout.shuffle_left(),
+ desc="Move window to the left"),
+ Key([mod, "shift"], "l", lazy.layout.shuffle_right(),
+ desc="Move window to the right"),
+ Key([mod, "shift"], "j", lazy.layout.shuffle_down(),
+ desc="Move window down"),
+ Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),
+
+ # Grow windows. If current window is on the edge of screen and direction
+ # will be to screen edge - window would shrink.
+ Key([mod, "control"], "h", lazy.layout.grow_left(),
+ desc="Grow window to the left"),
+ Key([mod, "control"], "l", lazy.layout.grow_right(),
+ desc="Grow window to the right"),
+ Key([mod, "control"], "j", lazy.layout.grow_down(),
+ desc="Grow window down"),
+ Key([mod, "control"], "k", lazy.layout.grow_up(), desc="Grow window up"),
+ Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
+
+ # Grow windows. If current window is on the edge of screen and direction
+ # will be to screen edge - window would shrink.
+ Key([mod, "mod4"], "h", resize_left,
+ desc="Grow window to the left"),
+ Key([mod, "mod4"], "l", resize_right,
+ desc="Grow window to the right"),
+ Key([mod, "mod4"], "j", resize_down,
+ desc="Grow window down"),
+ Key([mod, "mod4"], "k", resize_up, desc="Grow window up"),
+ Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
+
+ # Toggle between split and unsplit sides of stack.
+ # Split = all windows displayed
+ # Unsplit = 1 window displayed, like Max layout, but still with
+ # multiple stack panes
+ Key([mod, "shift"], "Return", lazy.layout.toggle_split(),
+ desc="Toggle between split and unsplit sides of stack"),
+ Key([mod], "Return", lazy.spawn(terminal), desc="Launch terminal"),
+ Key([mod], "f", lazy.window.toggle_fullscreen(), desc="Toggle fullscreen"),
+ Key([mod, "shift"], "n", lazy.spawn('Qminimize -u'), desc="Unminimize window"),
+ Key([mod], "n", lazy.spawn('Qminimize -m'), desc="Minimize window"),
+ Key([mod], "space", lazy.window.toggle_floating(),
+ desc="Toggle floating"),
+
+ # Toggle between different layouts as defined below
+ Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"),
+ Key([mod, "shift"], "Tab", lazy.prev_layout(), desc="Toggle between layouts"),
+ Key([mod, "shift"], "q", lazy.window.kill(), desc="Kill focused window"),
+
+ Key([mod, "shift"], "r", lazy.restart(), desc="Restart Qtile"),
+ Key([mod, "shift"], "e", lazy.shutdown(), desc="Shutdown Qtile"),
+ #Key([mod], "r", lazy.spawncmd(),
+ #desc="Spawn a command using a prompt widget"),
+]
+
+groups = [Group(i) for i in "123456789"]
+
+groups += [
+ ScratchPad("scratchpad", [
+ DropDown("htop", terminal + " htop",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("term", terminal,
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("alsa", terminal + " pulsemixer",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("blue", terminal + " bluetoothctl",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("ncmp", terminal + " ncmpcpp",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("mutt", terminal + " neomutt",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("prof", terminal + " /usr/bin/profanity",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("ircc", terminal + " /usr/bin/irssi",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("todo", terminal + " /usr/bin/todo",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ DropDown("trem", terminal + " /usr/bin/tremc",
+ x=0.25, y=0.2, width=0.5, height=0.6,
+ on_focus_lost_hide=True, warp_pointer=True),
+ ])
+ ]
+
+@hook.subscribe.startup
+def autostart():
+ home = os.path.expanduser('~/.config/autostart.sh')
+ subprocess.call([home])
+
+keys.extend([
+ Key([mod, "control"], 'z', lazy.group['scratchpad'].dropdown_toggle('htop'),
+ desc="Toggle htop scratchpad"),
+ Key([mod, "control"], 'x', lazy.group['scratchpad'].dropdown_toggle('term'),
+ desc="Toggle terminal scratchpad"),
+ Key([mod, "control"], 'c', lazy.group['scratchpad'].dropdown_toggle('alsa'),
+ desc="Toggle alsamixer scratchpad"),
+ Key([mod, "control"], 'v', lazy.group['scratchpad'].dropdown_toggle('blue'),
+ desc="Toggle alsamixer scratchpad"),
+ Key([mod, "control"], 'b', lazy.group['scratchpad'].dropdown_toggle('ncmp'),
+ desc="Toggle ncmpcpp scratchpad"),
+ Key([mod, "control"], 'a', lazy.group['scratchpad'].dropdown_toggle('mutt'),
+ desc="Toggle neomutt scratchpad"),
+ Key([mod, "control"], 's', lazy.group['scratchpad'].dropdown_toggle('prof'),
+ desc="Toggle profanity scratchpad"),
+ Key([mod, "control"], 'd', lazy.group['scratchpad'].dropdown_toggle('ircc'),
+ desc="Toggle irssi scratchpad"),
+ Key([mod, "control"], 'f', lazy.group['scratchpad'].dropdown_toggle('todo'),
+ desc="Toggle todo.txt scratchpad"),
+ Key([mod, "control"], 'g', lazy.group['scratchpad'].dropdown_toggle('trem'),
+ desc="Toggle tremc scratchpad"),
+ ])
+
+for i in "123456789":
+ keys.extend([
+ # mod1 + letter of group = switch to group
+ Key([mod], i, lazy.group[i].toscreen(),
+ desc="Switch to group {}".format(i)),
+
+ # mod1 + shift + letter of group = switch to & move focused window to group
+ Key([mod, "shift"], i, lazy.window.togroup(i, switch_group=False),
+ desc="Switch to & move focused window to group {}".format(i)),
+ # Or, use below if you prefer not to switch to that group.
+ # # mod1 + shift + letter of group = move focused window to group
+ # Key([mod, "shift"], i, lazy.window.togroup(i),
+ # desc="move focused window to group {}".format(i)),
+ ])
+
+layouts = [
+ layout.Columns(
+ border_focus=barcolor_gray8,
+ border_focus_stack=barcolor_gray8,
+ border_normal=barcolor_black,
+ border_normal_stack=barcolor_black,
+ insert_position=1,
+ margin=5
+ ),
+ layout.Bsp(
+ border_focus=barcolor_gray8,
+ border_normal=barcolor_black,
+ fair=False,
+ margin=5
+ ),
+ # layout.Max(),
+ # Try more layouts by unleashing below layouts.
+ # layout.Stack(num_stacks=2),
+ # layout.Matrix(),
+ # layout.MonadTall(),
+ # layout.MonadWide(),
+ # layout.RatioTile(),
+ # layout.Tile(),
+ # layout.TreeTab(),
+ # layout.VerticalTile(),
+ # layout.Zoomy(),
+]
+
+widget_defaults = dict(
+ font='mononoki Nerd Font Mono',
+ fontsize=12,
+ padding=3,
+)
+extension_defaults = widget_defaults.copy()
+
+bar_array_1 = [
+ widget.WindowName(
+ background=barcolor_cyan,
+ foreground=barcolor_black,
+ format='{state}{name}'
+ ),
+ widget.Chord(
+ chords_colors={
+ 'launch': (barcolor_red, barcolor_white),
+ },
+ name_transform=lambda name: name.upper(),
+ ),
+ widget.TextBox("ZachIR", name="default",
+ background=barcolor_black,
+ foreground=barcolor_white
+ ),
+ widget.CPU(
+ background=barcolor_cyan,
+ foreground=barcolor_black,
+ format='CPU {load_percent}%',
+ update_interval=1.0
+ ),
+ widget.CPUGraph(
+ background=barcolor_cyan,
+ border_color=barcolor_black,
+ core='all',
+ fill_color=barcolor_graya,
+ graph_color=barcolor_white
+ ),
+ widget.Memory(
+ background=barcolor_black,
+ foreground=barcolor_white,
+ format='RAM {MemUsed: .0f}{mm}',
+ measure_mem='M',
+ measure_swap='M',
+ update_interval=1.0
+ ),
+ widget.MemoryGraph(
+ background=barcolor_black,
+ border_color=barcolor_cyan,
+ fill_color=barcolor_graya,
+ frequency=1,
+ graph_color=barcolor_white
+ ),
+ widget.Mpd2(
+ background=barcolor_cyan,
+ foreground=barcolor_black,
+ status_format='{play_status} {artist} - {title} \
+[{repeat}{random}{single}{consume}{updating_db}]',
+ idle_format='{idle_message}',
+ idle_message='MPD',
+ host=os.path.expanduser('~/.config/mpd/socket'),
+ prepare_status={
+ 'consume': 'c',
+ 'random': 'z',
+ 'repeat': 'r',
+ 'single': 'y',
+ 'updating_db': 'u' }
+ ),
+ widget.Net(
+ background=barcolor_black,
+ interface=inet
+ )
+ ]
+
+bar_array_2 = [
+ widget.Clock(
+ background=barcolor_black,
+ format='%Y-%m-%d %a %I:%M %p',
+ update_interval=1.0
+ ),
+ widget.QuickExit(
+ background=barcolor_cyan,
+ foreground=barcolor_black,
+ countdown_format='[ {}sec ]',
+ countdown_start=5,
+ default_text='[ exit ]',
+ timer_interval=1
+ )
+ ]
+
+bar_systray = [
+ widget.Systray(
+ background=barcolor_black
+ )
+ ]
+
+bar_battery = [
+ widget.Battery(
+ background=barcolor_cyan,
+ foreground=barcolor_black,
+ battery=0,
+ charge_char='+',
+ discharge_char='-',
+ empty_char='X',
+ format='{char}{percent:2.0%} {hour:d}:{min:02d}',
+ full_char='|',
+ low_foreground=barcolor_red,
+ low_percentage=0.15,
+ notify_below=0.15,
+ unknown_char='?',
+ update_interval=60
+ )
+ ]
+
+bar_no_battery = [
+ widget.TextBox("None", name="default",
+ background=barcolor_cyan,
+ foreground=barcolor_black
+ )
+ ]
+
+bar_1 = bar_array_1
+if (psutil.sensors_battery() != None):
+ bar_1 = bar_1 + bar_battery
+else:
+ bar_1 = bar_1 + bar_no_battery
+if qtile.core.name == "x11":
+ bar_1 = bar_1 + bar_systray
+bar_1 = bar_1 + bar_array_2
+
+bar_2 = bar_array_1
+if (psutil.sensors_battery() != None):
+ bar_2 = bar_2 + bar_battery
+else:
+ bar_2 = bar_2 + bar_no_battery
+bar_2 = bar_2 + bar_array_2
+
+screens = [
+ Screen(
+ top=bar.Bar(
+ [
+ widget.CurrentLayoutIcon(
+ background=barcolor_cyan,
+ foreground=barcolor_black,
+ scale=0.8
+ ),
+ widget.GroupBox(
+ active=barcolor_white,
+ background=barcolor_black,
+ center_aligned=True,
+ highlight_color=barcolor_gray1,
+ highlight_method='line',
+ inactive=barcolor_gray6,
+ margin_x=2,
+ margin_y=5,
+ other_current_screen_border=barcolor_gray2,
+ other_screen_border=barcolor_gray2,
+ padding_y=5,
+ padding_x=3,
+ this_current_screen_border=barcolor_white,
+ this_screen_border=barcolor_white,
+ urgent_alert_method='block',
+ urgent_border=barcolor_magenta,
+ urgent_text=barcolor_magenta
+ )
+ ] + bar_1,
+ 24,
+ ),
+ ),
+ Screen(
+ top=bar.Bar(
+ [
+ widget.CurrentLayoutIcon(
+ background=barcolor_cyan,
+ foreground=barcolor_black,
+ scale=0.8
+ ),
+ widget.GroupBox(
+ active=barcolor_white,
+ background=barcolor_black,
+ center_aligned=True,
+ highlight_color=barcolor_gray1,
+ highlight_method='line',
+ inactive=barcolor_gray6,
+ margin_x=2,
+ margin_y=5,
+ other_current_screen_border=barcolor_gray2,
+ other_screen_border=barcolor_gray2,
+ padding_y=5,
+ padding_x=3,
+ this_current_screen_border=barcolor_white,
+ this_screen_border=barcolor_white,
+ urgent_alert_method='block',
+ urgent_border=barcolor_magenta,
+ urgent_text=barcolor_magenta
+ )
+ ] + bar_2,
+ 24,
+ ),
+ ),
+]
+
+# Drag floating layouts.
+mouse = [
+ Drag([mod], "Button1", lazy.window.set_position_floating(),
+ start=lazy.window.get_position()),
+ Drag([mod], "Button3", lazy.window.set_size_floating(),
+ start=lazy.window.get_size()),
+ Click([mod], "Button2", lazy.window.bring_to_front())
+]
+
+dgroups_key_binder = None
+dgroups_app_rules = [] # type: List
+follow_mouse_focus = True
+bring_front_click = False
+cursor_warp = False
+floating_layout = layout.Floating(float_rules=[
+ # Run the utility of `xprop` to see the wm class and name of an X client.
+ # *layout.Floating.default_float_rules,
+ Match(title='FX: Track 1'), # REAPER
+ Match(title='Add FX to: Track 1'), # REAPER
+ Match(title='REAPER (loading)'), # REAPER
+ Match(title='REAPER Query'), # REAPER
+ Match(title='REAPER (initializing)'), # REAPER
+ Match(title='Browse FX'), # REAPER
+ Match(title='Ardour - Preferences'), # ardour
+ Match(wm_instance_class='import'), # ardour
+ Match(wm_class='ardour-6.9.0'), # ardour
+ #Match(wm_class="lin-vst-servertrack.exe.so"), #linvst
+ Match(title='Edit Text on the Schematic:'), # LTspiceXVII
+ Match(wm_class='confirmreset'), # gitk
+ Match(wm_class='makebranch'), # gitk
+ Match(wm_class='maketag'), # gitk
+ Match(title='branchdialog'), # gitk
+ Match(wm_class='ssh-askpass'), # ssh-askpass
+ Match(title='Create Snapshot'), # timeshift-gtk
+ Match(title='pinentry'), # GPG key password entry
+], border_focus=barcolor_gray8, border_normal=barcolor_black)
+auto_fullscreen = False
+focus_on_window_activation = "smart"
+reconfigure_screens = True
+
+# If things like steam games want to auto-minimize themselves when losing
+# focus, should we respect this or not?
+auto_minimize = False
+
+# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
+# string besides java UI toolkits; you can see several discussions on the
+# mailing lists, GitHub issues, and other WM documentation that suggest setting
+# this string if your java app doesn't work correctly. We may as well just lie
+# and say that we're a working one by default.
+#
+# We choose LG3D to ], border_focus='', border_normal=''aximize irony: it is a 3D non-reparenting WM written in
+# java that happens to be on java's whitelist.
+# wmname = "LG3D"
diff --git a/qutebrowser/bookmarks/urls b/qutebrowser/bookmarks/urls
new file mode 100644
index 0000000..eeef6ee
--- /dev/null
+++ b/qutebrowser/bookmarks/urls
@@ -0,0 +1 @@
+https://wiki.archlinux.org/index.php/Qutebrowser#Keybindings qutebrowser - ArchWiki
diff --git a/qutebrowser/config.py b/qutebrowser/config.py
new file mode 100644
index 0000000..e75f46c
--- /dev/null
+++ b/qutebrowser/config.py
@@ -0,0 +1,275 @@
+# Autogenerated config.py
+#
+# NOTE: config.py is intended for advanced users who are comfortable
+# with manually migrating the config file on qutebrowser upgrades. If
+# you prefer, you can also configure qutebrowser using the
+# :set/:bind/:config-* commands without having to write a config.py
+# file.
+#
+# Documentation:
+# qute://help/configuring.html
+# qute://help/settings.html
+
+import sys, os
+
+try:
+ home = os.environ['XDG_CONFIG_HOME']
+except KeyError:
+ home = os.environ['HOME'] + '/.config'
+
+sys.path.append(os.path.join(sys.path[0], 'jmatrix'))
+config.source(home + "/qutebrowser/jmatrix/jmatrix/integrations/qutebrowser.py")
+
+# Change the argument to True to still load settings configured via autoconfig.yml
+config.load_autoconfig(True)
+
+# Backend to use to display websites. qutebrowser supports two different
+# web rendering engines / backends, QtWebEngine and QtWebKit (not
+# recommended). QtWebEngine is Qt's official successor to QtWebKit, and
+# both the default/recommended backend. It's based on a stripped-down
+# Chromium and regularly updated with security fixes and new features by
+# the Qt project: https://wiki.qt.io/QtWebEngine QtWebKit was
+# qutebrowser's original backend when the project was started. However,
+# support for QtWebKit was discontinued by the Qt project with Qt 5.6 in
+# 2016. The development of QtWebKit was picked up in an official fork:
+# https://github.com/qtwebkit/qtwebkit - however, the project seems to
+# have stalled again. The latest release (5.212.0 Alpha 4) from March
+# 2020 is based on a WebKit version from 2016, with many known security
+# vulnerabilities. Additionally, there is no process isolation and
+# sandboxing. Due to all those issues, while support for QtWebKit is
+# still available in qutebrowser for now, using it is strongly
+# discouraged.
+# Type: String
+# Valid values:
+# - webengine: Use QtWebEngine (based on Chromium - recommended).
+# - webkit: Use QtWebKit (based on WebKit, similar to Safari - many known security issues!).
+c.backend = 'webengine'
+
+# Always restore open sites when qutebrowser is reopened. Without this
+# option set, `:wq` (`:quit --save`) needs to be used to save open tabs
+# (and restore them), while quitting qutebrowser in any other way will
+# not save/restore the session. By default, this will save to the
+# session which was last loaded. This behavior can be customized via the
+# `session.default_name` setting.
+# Type: Bool
+c.auto_save.session = False
+
+# Which cookies to accept. With QtWebEngine, this setting also controls
+# other features with tracking capabilities similar to those of cookies;
+# including IndexedDB, DOM storage, filesystem API, service workers, and
+# AppCache. Note that with QtWebKit, only `all` and `never` are
+# supported as per-domain values. Setting `no-3rdparty` or `no-
+# unknown-3rdparty` per-domain on QtWebKit will have the same effect as
+# `all`. If this setting is used with URL patterns, the pattern gets
+# applied to the origin/first party URL of the page making the request,
+# not the request URL. With QtWebEngine 5.15.0+, paths will be stripped
+# from URLs, so URL patterns using paths will not match. With
+# QtWebEngine 5.15.2+, subdomains are additionally stripped as well, so
+# you will typically need to set this setting for `example.com` when the
+# cookie is set on `somesubdomain.example.com` for it to work properly.
+# To debug issues with this setting, start qutebrowser with `--debug
+# --logfilter network --debug-flag log-cookies` which will show all
+# cookies being set.
+# Type: String
+# Valid values:
+# - all: Accept all cookies.
+# - no-3rdparty: Accept cookies from the same origin only. This is known to break some sites, such as GMail.
+# - no-unknown-3rdparty: Accept cookies from the same origin only, unless a cookie is already set for the domain. On QtWebEngine, this is the same as no-3rdparty.
+# - never: Don't accept cookies at all.
+config.set('content.cookies.accept', 'no-3rdparty')
+
+# Value to send in the `Accept-Language` header. Note that the value
+# read from JavaScript is always the global value.
+# Type: String
+config.set('content.headers.accept_language', '', 'https://matchmaker.krunker.io/*')
+
+# User agent to send. The following placeholders are defined: *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version. The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine. Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) {upstream_browser_key}/{upstream_browser_version} Safari/{webkit_version}', 'https://web.whatsapp.com/')
+
+# User agent to send. The following placeholders are defined: *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version. The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine. Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}; rv:90.0) Gecko/20100101 Firefox/90.0', 'https://accounts.google.com/*')
+
+# User agent to send. The following placeholders are defined: *
+# `{os_info}`: Something like "X11; Linux x86_64". * `{webkit_version}`:
+# The underlying WebKit version (set to a fixed value with
+# QtWebEngine). * `{qt_key}`: "Qt" for QtWebKit, "QtWebEngine" for
+# QtWebEngine. * `{qt_version}`: The underlying Qt version. *
+# `{upstream_browser_key}`: "Version" for QtWebKit, "Chrome" for
+# QtWebEngine. * `{upstream_browser_version}`: The corresponding
+# Safari/Chrome version. * `{qutebrowser_version}`: The currently
+# running qutebrowser version. The default value is equal to the
+# unchanged user agent of QtWebKit/QtWebEngine. Note that the value
+# read from JavaScript is always the global value. With QtWebEngine
+# between 5.12 and 5.14 (inclusive), changing the value exposed to
+# JavaScript requires a restart.
+# Type: FormatString
+config.set('content.headers.user_agent', 'Mozilla/5.0 ({os_info}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99 Safari/537.36', 'https://*.slack.com/*')
+
+# Load images automatically in web pages.
+# Type: Bool
+config.set('content.images', True, 'chrome-devtools://*')
+
+# Load images automatically in web pages.
+# Type: Bool
+config.set('content.images', True, 'devtools://*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'chrome-devtools://*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'devtools://*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'chrome://*/*')
+
+# Enable JavaScript.
+# Type: Bool
+config.set('content.javascript.enabled', True, 'qute://*/*')
+
+# List of user stylesheet filenames to use.
+# Type: List of File, or File
+c.content.user_stylesheets = []
+
+# Editor (and arguments) to use for the `edit-*` commands. The following
+# placeholders are defined: * `{file}`: Filename of the file to be
+# edited. * `{line}`: Line in which the caret is found in the text. *
+# `{column}`: Column in which the caret is found in the text. *
+# `{line0}`: Same as `{line}`, but starting from index 0. * `{column0}`:
+# Same as `{column}`, but starting from index 0.
+# Type: ShellCommand
+c.editor.command = ['neovide', '{file}']
+
+# Page to open if :open -t/-b/-w is used without URL. Use `about:blank`
+# for a blank page.
+# Type: FuzzyUrl
+c.url.default_page = 'https://search.brave.com'
+
+# Search engines which can be used via the address bar. Maps a search
+# engine name (such as `DEFAULT`, or `ddg`) to a URL with a `{}`
+# placeholder. The placeholder will be replaced by the search term, use
+# `{{` and `}}` for literal `{`/`}` braces. The following further
+# placeholds are defined to configure how special characters in the
+# search terms are replaced by safe characters (called 'quoting'): *
+# `{}` and `{semiquoted}` quote everything except slashes; this is the
+# most sensible choice for almost all search engines (for the search
+# term `slash/and&amp` this placeholder expands to `slash/and%26amp`).
+# * `{quoted}` quotes all characters (for `slash/and&amp` this
+# placeholder expands to `slash%2Fand%26amp`). * `{unquoted}` quotes
+# nothing (for `slash/and&amp` this placeholder expands to
+# `slash/and&amp`). * `{0}` means the same as `{}`, but can be used
+# multiple times. The search engine named `DEFAULT` is used when
+# `url.auto_search` is turned on and something else than a URL was
+# entered to be opened. Other search engines can be used by prepending
+# the search engine name to the search term, e.g. `:open google
+# qutebrowser`.
+# Type: Dict
+c.url.searchengines = {'DEFAULT': 'https://search.brave.com/search?q={}', 'dg': 'https://duckduckgo.com/?q={}', 'aw': 'https://wiki.archlinux.org/?search={}', 'sp': 'https://startpage.com/sp/search?q={}', 'yt': 'https://yewtu.be/search?q={}', 'lv': 'https://videos.lukesmith.xyz/search?search={}&searchTarget=local'}
+
+# Page(s) to open at the start.
+# Type: List of FuzzyUrl, or FuzzyUrl
+c.url.start_pages = 'https://search.brave.com'
+
+# Background color for webpages if unset (or empty to use the theme's
+# color).
+# Type: QtColor
+c.colors.webpage.bg = 'black'
+
+# Render all web contents using a dark theme. Example configurations
+# from Chromium's `chrome://flags`: - "With simple HSL/CIELAB/RGB-based
+# inversion": Set `colors.webpage.darkmode.algorithm` accordingly. -
+# "With selective image inversion": Set
+# `colors.webpage.darkmode.policy.images` to `smart`. - "With selective
+# inversion of non-image elements": Set
+# `colors.webpage.darkmode.threshold.text` to 150 and
+# `colors.webpage.darkmode.threshold.background` to 205. - "With
+# selective inversion of everything": Combines the two variants above.
+# Type: Bool
+c.colors.webpage.darkmode.enabled = True
+
+# Which algorithm to use for modifying how colors are rendered with
+# darkmode. The `lightness-cielab` value was added with QtWebEngine 5.14
+# and is treated like `lightness-hsl` with older QtWebEngine versions.
+# Type: String
+# Valid values:
+# - lightness-cielab: Modify colors by converting them to CIELAB color space and inverting the L value. Not available with Qt < 5.14.
+# - lightness-hsl: Modify colors by converting them to the HSL color space and inverting the lightness (i.e. the "L" in HSL).
+# - brightness-rgb: Modify colors by subtracting each of r, g, and b from their maximum value.
+c.colors.webpage.darkmode.algorithm = 'lightness-cielab'
+
+# Which images to apply dark mode to. With QtWebEngine 5.15.0, this
+# setting can cause frequent renderer process crashes due to a
+# https://codereview.qt-project.org/c/qt/qtwebengine-
+# chromium/+/304211[bug in Qt].
+# Type: String
+# Valid values:
+# - always: Apply dark mode filter to all images.
+# - never: Never apply dark mode filter to any images.
+# - smart: Apply dark mode based on image content. Not available with Qt 5.15.0.
+c.colors.webpage.darkmode.policy.images = 'never'
+
+# Threshold for inverting background elements with dark mode. Background
+# elements with brightness above this threshold will be inverted, and
+# below it will be left as in the original, non-dark-mode page. Set to
+# 256 to never invert the color or to 0 to always invert it. Note: This
+# behavior is the opposite of `colors.webpage.darkmode.threshold.text`!
+# Type: Int
+c.colors.webpage.darkmode.threshold.background = 48
+
+# Map keys to other keys, so that they are equivalent in all modes. When
+# the key used as dictionary-key is pressed, the binding for the key
+# used as dictionary-value is invoked instead. This is useful for global
+# remappings of keys, for example to map <Ctrl-[> to <Escape>. NOTE:
+# This should only be used if two keys should always be equivalent, i.e.
+# for things like <Enter> (keypad) and <Return> (non-keypad). For normal
+# command bindings, qutebrowser works differently to vim: You always
+# bind keys to commands, usually via `:bind` or `config.bind()`. Instead
+# of using this setting, consider finding the command a key is bound to
+# (e.g. via `:bind gg`) and then binding the same command to the desired
+# key. Note that when a key is bound (via `bindings.default` or
+# `bindings.commands`), the mapping is ignored.
+# Type: Dict
+c.bindings.key_mappings = {'<Ctrl+6>': '<Ctrl+^>', '<Ctrl+Enter>': '<Ctrl+Return>', '<Ctrl+i>': '<Tab>', '<Ctrl+j>': '<Return>', '<Ctrl+m>': '<Return>', '<Ctrl+[>': '<Escape>', '<Enter>': '<Return>', '<Shift+Enter>': '<Return>', '<Shift+Return>': '<Return>'}
+
+# Bindings for normal mode
+config.bind('<Ctrl+0>', 'tab-select 10')
+config.bind('<Ctrl+1>', 'tab-select 1')
+config.bind('<Ctrl+2>', 'tab-select 2')
+config.bind('<Ctrl+3>', 'tab-select 3')
+config.bind('<Ctrl+4>', 'tab-select 4')
+config.bind('<Ctrl+5>', 'tab-select 5')
+config.bind('<Ctrl+6>', 'tab-select 6')
+config.bind('<Ctrl+7>', 'tab-select 7')
+config.bind('<Ctrl+8>', 'tab-select 8')
+config.bind('<Ctrl+9>', 'tab-select 9')
+config.bind('X', 'hint links spawn mpv {hint-url}')
+config.bind('ar', 'download-retry')
+config.bind('pa', 'spawn --userscript qute-pass')
diff --git a/qutebrowser/jmatrix b/qutebrowser/jmatrix
new file mode 160000
+Subproject b197ae15cafdeb9e864df24c6914192d07d2319
diff --git a/qutebrowser/quickmarks b/qutebrowser/quickmarks
new file mode 100644
index 0000000..93c8b7e
--- /dev/null
+++ b/qutebrowser/quickmarks
@@ -0,0 +1 @@
+lv https://videos.lukesmith.xyz
diff --git a/river/init b/river/init
new file mode 100755
index 0000000..c3e0fb2
--- /dev/null
+++ b/river/init
@@ -0,0 +1,167 @@
+#!/bin/sh
+
+. ~/.profile
+
+mod="Alt"
+
+riverctl attach-mode bottom
+riverctl map normal $mod Return spawn alacritty
+riverctl map normal $mod+Control Return spawn 'cage alacritty'
+riverctl map normal $mod+Shift Q close
+riverctl map normal Alt+Super Q spawn 'loginctl suspend'
+riverctl map normal $mod+Shift E exit
+riverctl map normal $mod J focus-view next
+riverctl map normal $mod K focus-view previous
+riverctl map normal $mod+Shift J swap next
+riverctl map normal $mod+Shift K swap previous
+riverctl map normal $mod D spawn bemenu-run
+riverctl map normal $mod P spawn passmenu
+riverctl map normal $mod R spawn 'j4-dmenu-desktop --dmenu="bemenu -l 15"'
+riverctl map normal $mod C spawn swayidletog
+riverctl map normal $mod Q spawn 'loginctl lock-session'
+riverctl map normal $mod W spawn "waytoggle"
+riverctl map normal $mod Y spawn 'alacritty --class ytfzft -e ytfzf -l'
+riverctl map normal $mod+Shift Y spawn 'cage -d -- alacritty -e ytfzf -l'
+riverctl map normal Alt+Super Q spawn qbc
+riverctl map normal Alt+Super W spawn lwc
+riverctl map normal Alt+Super E spawn fdc
+riverctl map normal Alt+Super Comma spawn dmenumount
+riverctl map normal Alt+Super Period spawn dmenuumount
+riverctl map normal Alt+Control v spawn 'alacritty -e bluetoothctl'
+
+riverctl map normal None XF86_MonBrightnessUp spawn 'light -A 1'
+riverctl map normal None XF86_MonBrightnessDown spawn 'light -U 1'
+riverctl map normal None XF86_AudioMute spawn 'volsv -t'
+riverctl map normal None XF86_AudioMicMute spawn 'pamixer --source 1 -t'
+riverctl map normal None XF86_AudioLowerVolume spawn 'volsv -d'
+riverctl map normal None XF86_AudioRaiseVolume spawn 'volsv -i'
+riverctl map normal None XF86_AudioNext spawn 'playerctl next'
+riverctl map normal None XF86_AudioPrev spawn 'playerctl previous'
+riverctl map normal None XF86_AudioPlay spawn 'playerctl play-pause'
+riverctl map normal None XF86_AudioStop spawn 'playerctl stop'
+
+# Mod+Period and Mod+Comma to focus the next/previous output
+riverctl map normal $mod+Control Period focus-output next
+riverctl map normal $mod+Control Comma focus-output previous
+
+# Mod+Shift+{Period,Comma} to send the focused view to the next/previous output
+riverctl map normal $mod+Control+Shift Period send-to-output next
+riverctl map normal $mod+Control+Shift Comma send-to-output previous
+
+# Mod+Return to bump the focused view to the top of the layout stack, making
+# it the new master
+riverctl map normal $mod+Shift Return zoom
+
+# Mod+H and Mod+L to decrease/increase the width of the master column by 5%
+riverctl map normal $mod H send-layout-cmd rivertile "main-ratio -0.05"
+riverctl map normal $mod L send-layout-cmd rivertile "main-ratio +0.05"
+
+# Mod+Shift+H and Mod+Shift+L to increment/decrement the number of
+# master views in the layout
+riverctl map normal $mod+Shift H send-layout-cmd rivertile "main-count +1"
+riverctl map normal $mod+Shift L send-layout-cmd rivertile "main-count -1"
+
+for i in $(seq 1 9); do
+ tagmask=$((1 << ($i - 1)))
+
+ # Mod+[1-9] to focus tag [0-8]
+ riverctl map normal $mod $i set-focused-tags $tagmask
+
+ # Mod+Shift+[1-9] to tag focused view with tag [0-8]
+ riverctl map normal $mod+Shift $i set-view-tags $tagmask
+
+ # Mod+Ctrl+[1-9] to toggle focus of tag [0-8]
+ riverctl map normal $mod+Control $i toggle-focused-tags $tagmask
+
+ # Mod+Shift+Ctrl+[1-9] to toggle tag [0-8] of focused view
+ riverctl map normal $mod+Shift+Control $i toggle-view-tags $tagmask
+done
+
+# Mod+0 to focus all tags
+# Mod+Shift+0 to tag focused view with all tags
+all_tags_mask=$(((1 << 32) - 1))
+riverctl map normal $mod 0 set-focused-tags $all_tags_mask
+riverctl map normal $mod+Shift 0 set-view-tags $all_tags_mask
+
+# Mod+Space to toggle float
+riverctl map normal $mod Space toggle-float
+
+# Mod+F to toggle fullscreen
+riverctl map normal $mod F toggle-fullscreen
+
+
+# Super+Alt+{H,J,K,L} to move views
+riverctl map normal Super+Alt H move left 100
+riverctl map normal Super+Alt J move down 100
+riverctl map normal Super+Alt K move up 100
+riverctl map normal Super+Alt L move right 100
+
+# Super+Alt+Control+{H,J,K,L} to snap views to screen edges
+riverctl map normal Super+Alt+Control H snap left
+riverctl map normal Super+Alt+Control J snap down
+riverctl map normal Super+Alt+Control K snap up
+riverctl map normal Super+Alt+Control L snap right
+
+# Super+Alt+Shift+{H,J,K,L} to resize views
+riverctl map normal Super+Alt+Shift H resize horizontal -100
+riverctl map normal Super+Alt+Shift J resize vertical 100
+riverctl map normal Super+Alt+Shift K resize vertical -100
+riverctl map normal Super+Alt+Shift L resize horizontal 100
+
+# Mod+{Up,Right,Down,Left} to change master orientation
+riverctl map normal $mod Up layout rivertile top
+riverctl map normal $mod Right layout rivertile right
+riverctl map normal $mod Down layout rivertile down
+riverctl map normal $mod Left layout rivertile left
+
+# Super+{Up,Right,Down,Left} to change layout orientation
+riverctl map normal Super Up send-layout-cmd rivertile "main-location top"
+riverctl map normal Super Right send-layout-cmd rivertile "main-location right"
+riverctl map normal Super Down send-layout-cmd rivertile "main-location bottom"
+riverctl map normal Super Left send-layout-cmd rivertile "main-location left"
+
+# Mod+S to change to Full layout
+riverctl map normal $mod S layout full
+
+riverctl map normal $mod T layout rivertile left
+
+# Declare a passthrough mode. This mode has only a single mapping to return to
+# normal mode. This makes it useful for testing a nested wayland compositor
+riverctl declare-mode passthrough
+
+# Mod+F11 to enter passthrough mode
+riverctl map normal $mod F11 enter-mode passthrough
+
+# Mod+F11 to return to normal mode
+riverctl map passthrough $mod F11 enter-mode normal
+
+# Set app-ids of views which should float
+riverctl float-filter-add "float"
+riverctl float-filter-add "popup"
+riverctl float-filter-add 'ytfzft'
+
+# Set app-ids of views which should use client side decorations
+riverctl csd-filter-add app-id "gedit"
+riverctl csd-filter-add app-id "libreoffice"
+riverctl csd-filter-add app-id "firedragon"
+
+riverctl focus-follows-cursor normal
+riverctl map-pointer normal $Mod BTN_LEFT move-view
+riverctl map-pointer normal $mod BTN_RIGHT resize-view
+
+## AUTOSTART
+
+#setsid -f swaybg -i ~/background.jpg
+#setsid -f mpd
+#gsettings set org.gnome.desktop.interface gtk-theme Plata-Noir-Compact
+#gsettings set org.gnome.desktop.interface icon-theme Paper-Mono-Dark
+#setsid -f dbus-daemon --session --address=unix:path=$XDG_RUNTIME_DIR/bus
+#setsid -f swayidle timeout 300 'loginctl lock-session' timeout 600 'loginctl suspend' lock slockd before-sleep slockd
+#setsid -f mako
+#setsid -f waybar
+setsid -f ~/.config/autostart.sh
+
+# Set the layout on startup
+riverctl default-layout rivertile
+
+exec rivertile -view-padding 6 -outer-padding 6
diff --git a/sh/aliases b/sh/aliases
new file mode 100644
index 0000000..0aa9869
--- /dev/null
+++ b/sh/aliases
@@ -0,0 +1,70 @@
+#!/bin/sh
+## CD Ups
+alias ..='cd ..'
+alias ...='cd ../..'
+alias ....='cd ../../..'
+alias .....='cd ../../../..'
+alias ......='cd ../../../../..'
+alias .......='cd ../../../../../..'
+alias ........='cd ../../../../../../..'
+
+COLOR_FLAGS_GNU="--color='auto' --group-directories-first"
+
+. $HOME/.config/sh/weather
+
+## Base Utils
+case `uname -s` in
+ "OpenBSD")
+ alias ls="ls -h"
+ ;;
+ "Linux")
+ alias ls="ls -h $COLOR_FLAGS_GNU"
+ ;;
+esac
+alias ll='ls -l'
+alias la='ls -A'
+alias lla='ls -lA'
+alias md='mkdir -p'
+alias ch='cd $HOME'
+alias du='du -sxhc'
+
+#alias nvim='vim'
+alias nv='nvim'
+alias v='nvim'
+alias lf='lfrun'
+
+## Change utils
+alias rm='rm -i'
+alias cp='cp -i'
+
+## git stuff
+alias gs='git status'
+alias commit='git commit -S -m'
+alias ga='git add -A'
+alias gd='git diff'
+
+## Single Chars
+alias r='cd ~ && clear && exec $SHELL'
+case "$(echo $0 | xargs basename)" in
+ "zsh") alias e='. $ZDOTDIR/.zshrc' ;;
+ "ksh"|"oksh") alias e='. ~/.config/kshrc' ;;
+esac
+alias q='exit'
+alias c='clear'
+alias m='make'
+
+## Programming
+# Rust
+alias crr='cargo run --release'
+alias cbr='cargo build --release'
+
+## Arch Linux aliases --sudoloop
+#alias yu='yay -Syu --noconfirm'
+
+## OpenBSD
+alias pq='pkg_info -Q'
+alias pu='doas pkg_add -u'
+alias pa='doas pkg_add'
+
+## Runit
+#alias ursm='env SVDIR="$HOME/.local/sv/" rsm'
diff --git a/sh/functions b/sh/functions
new file mode 100644
index 0000000..69b26c3
--- /dev/null
+++ b/sh/functions
@@ -0,0 +1,130 @@
+#!/bin/sh
+catclip () {
+ cat $@ | xclip -selection clipboard
+}
+
+catpass () {
+ PASSWD=$(cat ~/pass.txt); echo "$PASSWD\n$PASSWD" | pass insert "$1"; unset PASSWD
+}
+
+mpt () {
+ for i in $@; do
+ echo "" > $i
+ done
+}
+
+mkcd () {
+ mkdir $@ && cd $1
+}
+
+ntharg () {
+ shift $1
+ printf '%s\n' "$1"
+}
+
+mvcd () {
+ mv $@ && cd `ntharg $# "$@"`
+}
+
+scd () {
+ if [ "$1" = "" ]; then
+ cd $HOME
+ else
+ case "$1" in
+ "-l") echo "
+aw - ~/.config/awesome
+al - ~/.config/alacritty
+b - ~/.local/bin
+c - ~/.config
+db - ~/.local/src/dwmblocks
+dc - ~/Documents
+do - ~/Downloads
+dw - ~/.local/src/dwm
+e - ~/Desktop
+E - /etc
+f - ~/.var/app
+h - ~/.config/herbstluftwm
+lb - ~/.local/bin
+lc - ~/Games/cache
+lf - ~/.config/lf
+ls - ~/.local/share
+nv - ~/.config/nvim
+ns - ~/.natvst
+p - ~/Pictures
+qc - ~/.config/qutebrowser
+qp - ~/.local/share/qutebrowser-profiles
+qt - ~/.config/qtile
+re - ~/.local/src
+ri - ~/.config/river
+rs - /etc/runit/sv
+sc - ~/.local/bin/scripts
+sh - ~/.config/sh
+sl - ~/.local/src/slock
+ss - /etc/s6/sv
+st - ~/.local/src/st
+sx - ~/.config/sxhkd
+Va - /var
+v3 - ~/.vst3
+va - ~/.var
+vs - ~/.vst
+vv - ~/.local/volsv
+wa - ~/.local/src/wallpapers
+wd - ~/.local/share/wineprefixes/default
+wh - ~/.local/share/wineprefixes/[CURRENT]
+wr - ~/.local/share/wineprefixes
+ww - ~/.local/share/wineprefixes/work
+x - ~/.config/X11
+yb - ~/.cache/yay
+yc - ~/.config/yay
+zs - ~/.config/zsh
+zx - ~/Documents/zachir.xyz
+";;
+ "aw") cd $XDG_CONFIG_HOME/awesome/ ;;
+ "al") cd $XDG_CONFIG_HOME/alacritty/ ;;
+ "b") cd "$HOME"/.local/bin/ ;;
+ "c") cd $XDG_CONFIG_HOME/ ;;
+ "dc") cd $HOME/Documents/ ;;
+ "do") cd $HOME/Downloads/ ;;
+ "dw") cd $HOME/.local/src/dwm/ ;;
+ "db") cd $HOME/.local/src/dwmbar/ ;;
+ "e") cd $HOME/Desktop ;;
+ "E") cd /etc ;;
+ "f") cd $HOME/.var/app ;;
+ "h") cd "$XDG_CONFIG_HOME"/herbstluftwm ;;
+ "lb") cd $HOME/.local/bin ;;
+ "lc") cd $HOME/Games/cache ;;
+ "ls") cd $XDG_DATA_HOME ;;
+ "lf") cd $XDG_CONFIG_HOME/lf ;;
+ "nv") cd $XDG_CONFIG_HOME/nvim ;;
+ "ns") cd $HOME/.natvst ;;
+ "p") cd $HOME/Pictures ;;
+ "qc") cd $XDG_CONFIG_HOME/qutebrowser/ ;;
+ "qp") cd $XDG_DATA_HOME/qutebrowser-profiles/ ;;
+ "qt") cd $XDG_CONFIG_HOME/qtile/ ;;
+ "re") cd $HOME/.local/src/ ;;
+ "ri") cd $XDG_CONFIG_HOME/river ;;
+ "rs") cd /etc/runit/sv ;;
+ "sc") cd $HOME/.local/bin/scripts/ ;;
+ "sh") cd $XDG_CONFIG_HOME/sh/ ;;
+ "sl") cd $HOME/.local/src/slock/ ;;
+ "ss") cd /etc/s6/sv ;;
+ "st") cd $HOME/.local/src/st/ ;;
+ "sx") cd $XDG_CONFIG_HOME/sxhkd/ ;;
+ "v3") cd $HOME/.vst3 ;;
+ "vi") cd $HOME/Videos ;;
+ "vs") cd $HOME/.vst/ ;;
+ "vv") cd $HOME/.local/volsv/ ;;
+ "wa") cd $HOME/.local/src/wallpapers ;;
+ "wd") cd $WINEROOT/default ;;
+ "wh") cd $WINEPREFIX ;;
+ "wr") cd $WINEROOT ;;
+ "ww") cd $WINEROOT/work ;;
+ "x") cd $XDG_CONFIG_HOME/X11 ;;
+ "yb") cd $XDG_CACHE_HOME/yay ;;
+ "yc") cd $XDG_CONFIG_HOME/yay ;;
+ "zs") cd $ZDOTDIR/ ;;
+ "zx") cd $HOME/Documents/zachir.xyz/ ;;
+ *) echo "\"$1\" is not a known location" ;;
+ esac
+ fi
+}
diff --git a/snownews/colors b/snownews/colors
new file mode 100644
index 0000000..8675dde
--- /dev/null
+++ b/snownews/colors
@@ -0,0 +1,21 @@
+# Snownews color definitons
+# black:0
+# red:1
+# green:2
+# orange:3
+# blue:4
+# magenta(tm):5
+# cyan:6
+# gray:7
+# brightred:9
+# brightgreen:10
+# yellow:11
+# brightblue:12
+# brightmagenta:13
+# brightcyan:14
+# white:15
+# no color:-1
+enabled:1
+new item:5
+goto url:4
+feedtitle:-1
diff --git a/snownews/keybindings b/snownews/keybindings
new file mode 100644
index 0000000..73d0f9e
--- /dev/null
+++ b/snownews/keybindings
@@ -0,0 +1,39 @@
+# Snownews keybindings configfile
+# Main menu bindings
+add feed:a
+delete feed:D
+reload all feeds:R
+change default browser:B
+move item up:K
+move item down:J
+change feedname:r
+sort feeds:s
+categorize feed:C
+apply filter:f
+only current category:c
+mark all as read:A
+remove filter:F
+per feed filter:e
+toggle AND/OR filtering:X
+quit:q
+# Feed display menu bindings
+show feedinfo:i
+mark feed as read:n
+mark item unread:N
+# General keybindungs
+next item:j
+previous item:k
+return to previous menu:h
+reload feed:R
+force reload feed:T
+open url:o
+open item url in overview:O
+page up:b
+page down:
+top:g
+bottom:G
+enter:l
+show new headlines:H
+help menu:?
+about:>
+type ahead find:/
diff --git a/spectrwm/spectrwm.conf b/spectrwm/spectrwm.conf
new file mode 100644
index 0000000..c87d40f
--- /dev/null
+++ b/spectrwm/spectrwm.conf
@@ -0,0 +1,145 @@
+# PLEASE READ THE MAN PAGE BEFORE EDITING THIS FILE!
+# https://htmlpreview.github.io/?https://github.com/conformal/spectrwm/blob/master/spectrwm.html
+# NOTE: all rgb color values in this file are in hex! see XQueryColor for examples
+
+workspace_limit = 22
+focus_mode = follow
+focus_close = previous
+focus_close_wrap = 1
+focus_default = last
+spawn_position = next
+workspace_clamp = 1
+warp_focus = 1
+warp_pointer = 1
+
+# Window Decoration
+border_width = 1
+color_focus = black
+color_focus_maximized = black
+color_unfocus = rgb:22/22/22
+color_unfocus_maximized = rgb:22/22/22
+region_padding = 2
+tile_gap = 5
+
+# Region containment
+# Distance window must be dragged/resized beyond the region edge before it is
+# allowed outside the region.
+boundary_width = 50
+
+# Remove window border when bar is disabled and there is only one window in workspace
+disable_border = 1
+
+# Bar Settings
+bar_enabled = 1
+# bar_enabled_ws[1] = 1
+bar_border_width = 1
+bar_border[1] = rgb:22/22/22
+bar_border_unfocus[1] = rgb:22/22/22
+bar_color[1] = black
+bar_color_selected[1] = rgb:00/80/80
+bar_font_color[1] = rgb:a0/a0/a0
+bar_font_color_selected = white
+bar_font = mononoki Nerd Font Mono:pixelsize=16:antialias=true
+bar_font_pua = Symbola:pixelsize=12:antialias=true
+bar_action = conky
+bar_action_expand = 1
+bar_justify = left
+bar_format = +N:+I +W +|R+A
+workspace_indicator = listcurrent,listactive,markcurrent,printnames
+bar_at_bottom = 0
+# stack_enabled = 0
+# clock_enabled = 1
+# clock_format = %a %b %d %R %Z %Y
+# iconic_enabled = 0
+maximize_hide_bar = 1
+# window_class_enabled = 0
+# window_instance_enabled = 0
+# window_name_enabled = 0
+# verbose_layout = 1
+# urgent_enabled = 1
+# urgent_collapse = 0
+
+# Dialog box size ratio when using TRANSSZ quirk; 0.3 < dialog_ratio <= 1.0
+dialog_ratio = 0.6
+
+# Split a non-RandR dual head setup into one region per monitor
+# (non-standard driver-based multihead is not seen by spectrwm)
+# region = screen[1]:1280x1024+0+0
+# region = screen[1]:1280x1024+1280+0
+
+# Launch applications in a workspace of choice
+# autorun = ws[1]:xterm
+# autorun = ws[2]:xombrero http://www.openbsd.org
+
+# Customize workspace layout at start
+layout = ws[1]:4:0:0:0:vertical
+# layout = ws[2]:0:0:0:0:horizontal
+# layout = ws[3]:0:0:0:0:fullscreen
+# layout = ws[4]:4:0:0:0:vertical_flip
+# layout = ws[5]:0:0:0:0:horizontal_flip
+
+# Set workspace name at start
+# name = ws[1]:IRC
+# name = ws[2]:Email
+# name = ws[3]:Browse
+# name = ws[10]:Music
+
+# Mod key, (Windows key is Mod4) (Apple key on OSX is Mod2)
+modkey = Mod1
+
+# This allows you to include pre-defined key bindings for your keyboard layout.
+# keyboard_mapping = ~/.spectrwm_us.conf
+
+# PROGRAMS
+
+# Validated default programs:
+program[lock] = slock
+program[term] = tabbed -c st -w
+program[menu] = dmenu_run $dmenu_bottom -fn $bar_font -nb $bar_color -nf $bar_font_color -sb $bar_color_selected -sf $bar_font_color_selected
+program[search] = dmenu $dmenu_bottom -i -fn $bar_font -nb $bar_color -nf $bar_font_color -sb $bar_color_selected -sf $bar_font_color_selected
+program[name_workspace] = dmenu $dmenu_bottom -p Workspace -fn $bar_font -nb $bar_color -nf $bar_font_color -sb $bar_color_selected -sf $bar_font_color_selected
+
+# To disable validation of the above, free the respective binding(s):
+bind[] = MOD+Shift+Delete # disable lock
+bind[] = MOD+Shift+Return # disable term
+bind[] = MOD+p # disable menu
+
+#Rebind WM Keys
+bind[wind_kill] = MOD+Shift+q # remap close window command
+bind[quit] = MOD+Shift+e # remap quit command
+bind[term] = MOD+Return # remap terminal command
+bind[swap_main] = MOD+Shift+Return # remap swap master command
+bind[restart] = MOD+Shift+r # remap restart command
+bind[lock] = MOD+q # remap lock command
+bind[float_toggle] = MOD+space # map toggle float command
+
+#Bind WM Keys
+bind[layout_vertical] = MOD+t # set vertical layout
+bind[layout_horizontal] = MOD+y # set horizontal layout
+bind[fullscreen_toggle] = MOD+f # set max layout
+
+# Optional default programs that will only be validated if you override:
+program[screenshot_all] = maim # optional
+# program[screenshot_wind] = screenshot.sh window # optional
+# program[initscr] = initscreen.sh # optional
+
+# EXAMPLE: Define 'firefox' action and bind to key.
+# program[firefox] = firefox http://spectrwm.org/
+# bind[firefox] = MOD+Shift+b
+
+# QUIRKS
+# Default quirks, remove with: quirk[class:name] = NONE
+# quirk[MPlayer:xv] = FLOAT + FULLSCREEN + FOCUSPREV
+# quirk[OpenOffice.org 2.4:VCLSalFrame] = FLOAT
+# quirk[OpenOffice.org 3.0:VCLSalFrame] = FLOAT
+# quirk[OpenOffice.org 3.1:VCLSalFrame] = FLOAT
+# quirk[Firefox-bin:firefox-bin] = TRANSSZ
+# quirk[Firefox:Dialog] = FLOAT
+# quirk[Gimp:gimp] = FLOAT + ANYWHERE
+# quirk[XTerm:xterm] = XTERM_FONTADJ
+# quirk[xine:Xine Window] = FLOAT + ANYWHERE
+# quirk[Xitk:Xitk Combo] = FLOAT + ANYWHERE
+# quirk[xine:xine Panel] = FLOAT + ANYWHERE
+# quirk[Xitk:Xine Window] = FLOAT + ANYWHERE
+# quirk[xine:xine Video Fullscreen Window] = FULLSCREEN + FLOAT
+# quirk[pcb:pcb] = FLOAT
diff --git a/stalonetrayrc b/stalonetrayrc
new file mode 100644
index 0000000..5723ac7
--- /dev/null
+++ b/stalonetrayrc
@@ -0,0 +1,137 @@
+# vim:filetype=config:tw=80:et
+#
+# This is sample ~/.stalonetrayrc, resembling default configuration.
+# Remember: command line parameters take precedence.
+#
+# Directives introduced in @VERSION_STR@ are marked with "NEW in @VERSION_STR@"
+#
+####################################################################
+#
+# stalonetray understands following directives
+#
+####################################################################
+
+# background <color> # color can be specified as an HTML hex triplet or
+ # as a name from rgb.txt, note that '#' must be quoted
+background "#282c34"
+
+# decorations <decspec> # set trays window decorations; possible values for
+ # decspec are: all, title, border, none
+decorations none
+
+# display <display name> # as usual
+
+# dockapp_mode <mode> # set dockapp mode, which can be either simple (for
+ # e.g. OpenBox, wmaker for WindowMaker, or none
+ # (default). NEW in @VERSION_STR@.
+dockapp_mode none
+
+# fuzzy_edges [<level>] # enable fuzzy edges and set fuzziness level. level
+ # can be from 0 (disabled) to 3; this setting works
+ # with tinting and/or transparent and/or pixmap
+ # backgrounds
+fuzzy_edges 0
+
+# geometry <geometry> # tray's geometry in standard X notation; width and
+ # height are specified in slot_size multiples
+geometry 1x1+1884+0
+
+# grow_gravity <gravity> # one of N, S, E, W, NW, NE, SW, SE; tray will grow
+ # in the direction opposite to one specified by
+ # grow_gravity; if horizontal or vertical
+ # direction is not specified, tray will not grow in
+ # that direction
+grow_gravity NE
+
+# icon_gravity <gravity> # icon placement gravity, one of NW, NE, SW, SE
+icon_gravity NE
+
+# icon_size <int> # specifies dimensions of typical icon slot
+icon_size 24
+
+# log_level <level> # controls the amount of logging output, level can
+ # be err (default), info, or trace (enabled only
+ # when stalonetray configured with --enable-debug)
+ # NEW in @VERSION_STR@.
+log_level err
+
+# kludges kludge[,kludge] # enable specific kludges to work around
+ # non-conforming WMs and/or stalonetray bugs.
+ # NEW in @VERSION_STR@. Argument is a
+ # comma-separated list of
+ # * fix_window_pos - fix tray window position on
+ # erroneous moves by WM
+ # * force_icons_size - ignore resize events on all
+ # icons; force their size to be equal to
+ # icon_size
+ # * use_icon_hints - use icon window hints to
+ # dtermine icon size
+
+# max_geometry <geometry> # maximal tray dimensions; 0 in width/height means
+ # no limit
+max_geometry 1x1
+
+# no_shrink [<bool>] # disables shrink-back mode
+no_shrink false
+
+# parent_bg [<bool>] # whether to use pseudo-transparency
+ # (looks better when reparented into smth like FvwmButtons)
+parent_bg false
+
+# pixmap_bg <path_to_xpm> # use pixmap from specified xpm file for (tiled) background
+# pixmap_bg /home/user/.stalonetraybg.xpm
+
+# scrollbars <mode> # enable/disable scrollbars; mode is either
+ # vertical, horizontal, all or none (default)
+ # NEW in @VERSION_STR@.
+scrollbars horizontal
+
+# scrollbars-size <size> # scrollbars step in pixels; default is slot_size / 4
+# scrollbars-step 8
+
+# scrollbars-step <step> # scrollbars step in pixels; default is slot_size / 2
+# scrollbars-step 32
+
+# slot_size <int> # specifies size of icon slot, defaults to
+ # icon_size NEW in @VERSION_STR@.
+
+# skip_taskbar [<bool>] # hide tray`s window from the taskbar
+skip_taskbar true
+
+# sticky [<bool>] # make a tray`s window sticky across the
+ # desktops/pages
+sticky true
+
+# tint_color <color> # set tinting color
+tint_color white
+
+# tint_level <level> # set tinting level; level ranges from 0 (disabled)
+ # to 255
+tint_level 0
+
+# transparent [<bool>] # whether to use root-transparency (background
+ # image must be set with Esetroot or compatible utility)
+transparent false
+
+# vertical [<bool>] # whether to use vertical layout (horisontal layout
+ # is used by default)
+vertical false
+
+# window_layer <layer> # set the EWMH-compatible window layer; one of:
+ # bottom, normal, top
+window_layer normal
+
+# window_strut <mode> # enable/disable window struts for tray window (to
+ # avoid converting of tray window by maximized
+ # windows); mode defines to which screen border tray
+ # will be attached; it can be either top, bottom,
+ # left, right, none or auto (default)
+window_strut none
+
+# window_type <type> # set the EWMH-compatible window type; one of:
+ # desktop, dock, normal, toolbar, utility
+window_type dock
+
+# xsync [<bool>] # whether to operate on X server synchronously (SLOOOOW)
+xsync false
+
diff --git a/stmp b/stmp
new file mode 100644
index 0000000..24e7eab
--- /dev/null
+++ b/stmp
@@ -0,0 +1,6 @@
+[auth]
+username = 'zachir'
+password = 'seeqsn7ur53b'
+
+[server]
+host = 'https://cloud.zachir.xyz/index.php/apps/music/subsonic'
diff --git a/swayidle/config b/swayidle/config
new file mode 100644
index 0000000..2d29891
--- /dev/null
+++ b/swayidle/config
@@ -0,0 +1,2 @@
+before-sleep 'loginctl lock-session'
+lock slockd
diff --git a/swhkd/swhkdrc b/swhkd/swhkdrc
new file mode 100755
index 0000000..2042b69
--- /dev/null
+++ b/swhkd/swhkdrc
@@ -0,0 +1,158 @@
+#
+# wm independent hotkeys
+#
+
+# reload sxhkd config
+alt + Escape
+ doas pkill -HUP -x swhkd
+
+#
+# dmenu interfaces
+#
+
+# program launcher
+alt + d
+ tofi_run
+
+# desktop application launcher
+alt + r
+ tofi-drun --drun-launch true
+
+# dmenu prompt for recording
+alt + control + r
+ tofirecord
+
+# run dmenu interface for keepassxc
+alt + p
+ tofikeepass --height 24
+
+# run dmenu interface for pass
+alt + super + p
+ passmenu
+
+# run dmenu interface for mpv
+alt + v
+ tofimpv
+
+# run dmenu interface for ytfzf
+alt + y
+ ytfzf-launcher -D 'tofi --height 24'
+
+# run dmenu interface to spawn browsers
+alt + super + 1
+ browser-tofi
+
+# run dmenu interface for qutebrowser profile chooser
+alt + super + q
+ qbc-tofi
+ #qbpm choose
+
+# run dmenu interface for librewolf profile chooser
+alt + super + w
+ lwc-tofi
+
+# run dmenu interface for librewolf profile chooser
+alt + super + e
+ fdc-tofi
+
+# run dmenu interface to open book
+alt + super + b
+ tofi_books
+
+# run dmenu interface for mpris
+alt + super + u
+ mprisctl-tofi
+
+# run dmenu interface for monattach
+alt + super + m
+ monattach-tofi right
+
+# run dmenu interface for mondetach
+alt + super + n
+ mondetach-tofi
+
+# run dmenu interface for mount
+alt + super + comma
+ tofimount
+
+# run dmenu interface for umount
+alt + super + period
+ tofiumount
+
+#run dmenu prompt for unicode chars
+alt + super + u
+ tofiunicode
+
+#
+# utilities
+#
+
+# toggle x idle state
+alt + c
+ swayidletog
+
+# toggle waybar
+alt + w
+ waytoggle
+
+# warp cursor to left or right monitor
+alt + super + {Left,Right}
+ mwarp.py {left,right}
+
+# lock the screen
+alt + q
+ loginctl lock-session self
+
+# spawn file manager
+alt + super + f
+ $TERMINAL -e lfrun
+
+# toggle touchpad
+alt + super + t
+ toggletouchpad
+
+# notify-send firewall rules
+alt + super + o
+ notify-iptables
+
+# mute volume
+alt + super + m
+ volsv -t
+
+# mute microphone
+alt + super + shift + m
+ volsv -m
+
+#
+# xf86 keys
+#
+
+# manipulate audio stream
+XF86Audio{Prev,Next,Play,Stop}
+ mpc {prev,next,toggle,stop}
+
+# turn the brightness up
+XF86MonBrightnessUp
+ xbacklight -inc 1
+ # light -A 1
+
+# turn the brightness down
+XF86MonBrightnessDown
+ xbacklight -dec 1
+ # light -U 1
+
+# raise the volume
+XF86AudioRaiseVolume
+ volsv -i
+
+# lower the volume
+XF86AudioLowerVolume
+ volsv -d
+
+# toggle mute
+XF86AudioMute
+ volsv -t
+
+# mute mic
+XF86AudioMicMute
+ volsv -m
diff --git a/sx/sxrc b/sx/sxrc
new file mode 100755
index 0000000..22b9734
--- /dev/null
+++ b/sx/sxrc
@@ -0,0 +1 @@
+exec qtile start
diff --git a/sxhkd/sxhkdrc b/sxhkd/sxhkdrc
new file mode 100755
index 0000000..3fdd764
--- /dev/null
+++ b/sxhkd/sxhkdrc
@@ -0,0 +1,170 @@
+#
+# wm independent hotkeys
+#
+
+# reload sxhkd config
+alt + Escape
+ pkill -USR1 -x sxhkd
+
+#
+# dmenu interfaces
+#
+
+# program launcher
+alt + d
+ dmenu_run -h 24
+
+# desktop application launcher
+alt + r
+ j4-dmenu-desktop --dmenu="barmenu -h 24 -l 15"
+
+# dmenu prompt for recording
+alt + control + r
+ dmenurecord
+
+# run dmenu interface for keepassxc
+alt + p
+ dmenu_keepass -H 24
+
+# run dmenu interface for pass
+alt + super + p
+ passmenu
+
+# run dmenu interface for mpv
+alt + v
+ dmpv
+
+# run dmenu interface for ytfzf
+alt + y
+ ytfzf-launcher -D 'barmenu -h 24 -l 15'
+
+# run dmenu interface to spawn browsers
+alt + super + 1
+ browser
+
+# run dmenu interface for qutebrowser profile chooser
+alt + super + q
+ qbc
+ #qbpm choose
+
+# run dmenu interface for librewolf profile chooser
+alt + super + w
+ lwc
+
+# run dmenu interface for librewolf profile chooser
+alt + super + e
+ fdc
+
+# run dmenu interface to open book
+alt + super + b
+ dmenu_books
+
+# run dmenu interface for mpris
+alt + super + u
+ mprisctl
+
+# run dmenu interface for monattach
+alt + super + m
+ monattach right
+
+# run dmenu interface for mondetach
+alt + super + n
+ mondetach
+
+# run dmenu interface for mount
+alt + super + comma
+ dmenumount
+
+# run dmenu interface for umount
+alt + super + period
+ dmenuumount
+
+#run dmenu prompt for unicode chars
+alt + super + u
+ dmenuunicode
+
+#
+# utilities
+#
+
+# toggle x idle state
+alt + c
+ xidletog
+
+# warp cursor to left or right monitor
+alt + {Left,Right}
+ mwarp.py {left,right}
+
+# lock the screen
+alt + q
+ loginctl lock-session self
+
+# restart dwmblocks
+alt + super + 9
+ toggle dwmblocks
+
+# signal all dwmblocks modules
+alt + super + 0
+ sigdwmb all
+
+# spawn file manager
+alt + super + f
+ $TERMINAL -e lfrun
+
+# toggle touchpad
+alt + super + t
+ toggletouchpad
+
+# notify-send firewall rules
+alt + super + f
+ notify-iptables
+
+# mute volume
+alt + super + m
+ volsv -t
+
+# mute microphone
+alt + super + shift + m
+ volsv -m
+
+# load sxiv for backgrounds
+alt + super + x
+ sxiv ~/.local/src/wallpapers
+
+# xkill
+alt + x
+ xkill
+
+#
+# xf86 keys
+#
+
+# manipulate audio stream
+XF86Audio{Prev,Next,Play,Stop}
+ mpc {prev,next,toggle,stop}
+
+# turn the brightness up
+XF86MonBrightnessUp
+ xbacklight -inc 1
+ # light -A 1
+
+# turn the brightness down
+XF86MonBrightnessDown
+ xbacklight -dec 1
+ # light -U 1
+
+# raise the volume
+XF86AudioRaiseVolume
+ volsv -i
+
+# lower the volume
+XF86AudioLowerVolume
+ volsv -d
+
+# toggle mute
+XF86AudioMute
+ volsv -t
+
+# mute mic
+XF86AudioMicMute
+ volsv -m
diff --git a/sxhkd/sxhkdrc.1 b/sxhkd/sxhkdrc.1
new file mode 100755
index 0000000..0af969a
--- /dev/null
+++ b/sxhkd/sxhkdrc.1
@@ -0,0 +1,329 @@
+#
+# wm independent hotkeys
+#
+
+# reload sxhkd config
+alt + Escape
+ pkill -USR1 -x sxhkd
+
+#
+# dmenu interfaces
+#
+
+# program launcher
+alt + d
+ dmenu_run -h 24
+
+# desktop application launcher
+alt + r
+ j4-dmenu-desktop --dmenu="barmenu -h 24 -l 15"
+
+# dmenu prompt for recording
+alt + control + r
+ dmenurecord
+
+# run dmenu interface for keepassxc
+alt + p
+ dmenu_keepass -H 24
+
+# run dmenu interface for pass
+alt + super + p
+ passmenu
+
+# run dmenu interface for mpv
+alt + v
+ dmpv
+
+# run dmenu interface for ytfzf
+alt + y
+ ytfzf-launcher -D 'barmenu -h 24 -l 15'
+
+# run dmenu interface to spawn browsers
+alt + super + 1
+ browser
+
+# run dmenu interface for qutebrowser profile chooser
+alt + super + q
+ qbc
+ #qbpm choose
+
+# run dmenu interface for librewolf profile chooser
+alt + super + w
+ lwc
+
+# run dmenu interface for librewolf profile chooser
+alt + super + e
+ fdc
+
+# run dmenu interface to open book
+alt + super + b
+ dmenu_books
+
+# run dmenu interface for mpris
+alt + super + u
+ mprisctl
+
+# run dmenu interface for monattach
+alt + super + m
+ monattach right
+
+# run dmenu interface for mondetach
+alt + super + n
+ mondetach
+
+# run dmenu interface for mount
+alt + super + comma
+ dmenumount
+
+# run dmenu interface for umount
+alt + super + period
+ dmenuumount
+
+#run dmenu prompt for unicode chars
+alt + super + u
+ dmenuunicode
+
+#
+# utilities
+#
+
+# toggle x idle state
+alt + c
+ xidletog
+
+# warp cursor to left or right monitor
+alt + {Left,Right}
+ mwarp {left,right}
+
+# lock the screen
+alt + q
+ loginctl lock-session self
+
+# restart dwmblocks
+alt + super + 9
+ toggle dwmblocks
+
+# signal all dwmblocks modules
+alt + super + 0
+ sigdwmb all
+
+# spawn file manager
+alt + super + f
+ $TERMINAL -e lfrun
+
+# toggle touchpad
+alt + super + t
+ toggletouchpad
+
+# notify-send firewall rules
+alt + super + f
+ notify-iptables
+
+# mute volume
+alt + super + m
+ volsv -t
+
+# mute microphone
+alt + super + shift + m
+ volsv -m
+
+# load sxiv for backgrounds
+alt + super + x
+ sxiv ~/.local/src/wallpapers
+
+# xkill
+alt + x
+ xkill
+
+#
+# xf86 keys
+#
+
+# manipulate audio stream
+XF86Audio{Prev,Next,Play,Stop}
+ mpc {prev,next,toggle,stop}
+
+# turn the brightness up
+XF86MonBrightnessUp
+ xbacklight -inc 1
+ # light -A 1
+
+# turn the brightness down
+XF86MonBrightnessDown
+ xbacklight -dec 1
+ # light -U 1
+
+# raise the volume
+XF86AudioRaiseVolume
+ volsv -i
+
+# lower the volume
+XF86AudioLowerVolume
+ volsv -d
+
+# toggle mute
+XF86AudioMute
+ volsv -t
+
+# mute mic
+XF86AudioMicMute
+ volsv -m
+#
+# bspwm hotkeys
+#
+
+# launch terminal
+alt + Return
+ st
+
+# quit/restart bspwm
+alt + shift + {e,r}
+ bspc {quit,wm -r}
+
+# close
+alt + shift + {q, super + k}
+ bspc node {-c,-k}
+
+# alternate between the tiled and monocle layout
+# alt + m
+# bspc desktop -l next
+
+# send the newest marked node to the newest preselected node
+alt + y
+ bspc node newest.marked.local -n newest.!automatic.local
+
+# swap the current node and the biggest node
+alt + g
+ bspc node -s biggest
+
+#
+# state/flags
+#
+
+# set the window state
+alt + super + {t,shift + t,s,f}
+ bspc node -t {tiled,pseudo_tiled,floating,fullscreen}
+
+# set the node flags
+alt + super + {m,x,y,z}
+ bspc node -g {marked,locked,sticky,private}
+
+#
+# focus/swap
+#
+
+# focus the node in the given direction
+alt + {_,shift + }{h,j,k,l}
+ bspc node -{f,s} {west,south,north,east}
+
+# focus the node for the given path jump
+alt + {p,b,comma,period}
+ bspc node -f @{parent,brother,first,second}
+
+# focus the next/previous node in the current desktop
+alt + {_,shift + }c
+ bspc node -f {next,prev}.local
+
+# focus the next/previous desktop in the current Monitor
+alt + bracket{left,right}
+ bspc desktop -f {prev,next}.local
+
+# focus the last node/desktop
+alt + {grave,Tab}
+ bspc {node,desktop} -f last
+
+# focus the older or newer node in the focus history
+alt + {o,i}
+ bspc wm -h off; \
+ bspc node {older,newer} -f; \
+ bspc wm -h on
+
+# focus or send to the given desktop
+alt + {_,shift + }{1-9,0}
+ bspc {desktop -f,node -d} '^{1-9,10}'
+
+#
+# preselect
+#
+
+# preselect the direction
+alt + ctrl + {h,j,k,l}
+ bspc node -p {west,south,north,east}
+
+# preselect the ratio
+alt + ctrl + {1-9}
+ bspc node -o 0.{1-9}
+
+# cancel the preselection for the focused node
+alt + ctrl + space
+ bspc node -p cancel
+
+# cancel the preselection for the focused desktop
+alt + ctrl + shift + space
+ bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
+
+#
+# move/resize
+#
+
+# expand a window by moving one of its side outward
+super + alt + {h,j,k,l}
+ bspc node -z {left -20 0,bottom 0 20,top 0 -20,right 20 0}
+
+# contract a window by moving one of its side inward
+super + alt + shift + {h,j,k,l}
+ bspc node -z {right -20 0,top :0 20,bottom 0 -20,left 20 0}
+
+# move a floating window
+super + {Left,Down,Up,Right}
+ bspc node -v {-20 0,0 20,0 -20,20 0}
+
+#
+# bsp-layout
+#
+alt + {t,shift + t}
+ bsp-layout set {tile,tall -- --master-size 0.5}
+
+#
+# scratchpads
+#
+
+# htop
+alt + control + z
+ bspt sphtop htop
+
+# terminal
+alt + control + x
+ bspt spterm tmux
+
+# pulsemixer
+alt + control + c
+ bspt sppmxr pulsemixer
+
+# bluetoothctl
+alt + control + v
+ bspt spblue bluetoothctl
+
+# ncmpcpp
+alt + control + b
+ bspt spncmp ncmpcpp
+
+# neomutt
+alt + control + a
+ bspt spmutt neomutt
+
+# profanity
+alt + control + s
+ bspt spprof profanity
+
+# irssi
+alt + control + d
+ bspt spircc irssi
+
+# todo
+alt + control + f
+ bspt sptodo todo
+
+# trem
+alt + control + g
+ bspt sptrem tremc
diff --git a/sxhkd/sxhkdrc.bsp b/sxhkd/sxhkdrc.bsp
new file mode 100755
index 0000000..e31576b
--- /dev/null
+++ b/sxhkd/sxhkdrc.bsp
@@ -0,0 +1,159 @@
+#
+# bspwm hotkeys
+#
+
+# launch terminal
+alt + Return
+ st
+
+# quit/restart bspwm
+alt + shift + {e,r}
+ bspc {quit,wm -r}
+
+# close
+alt + shift + {q, super + k}
+ bspc node {-c,-k}
+
+# alternate between the tiled and monocle layout
+# alt + m
+# bspc desktop -l next
+
+# send the newest marked node to the newest preselected node
+alt + y
+ bspc node newest.marked.local -n newest.!automatic.local
+
+# swap the current node and the biggest node
+alt + g
+ bspc node -s biggest
+
+#
+# state/flags
+#
+
+# set the window state
+alt + super + {t,shift + t,s,f}
+ bspc node -t {tiled,pseudo_tiled,floating,fullscreen}
+
+# set the node flags
+alt + super + {m,x,y,z}
+ bspc node -g {marked,locked,sticky,private}
+
+#
+# focus/swap
+#
+
+# focus the node in the given direction
+alt + {_,shift + }{h,j,k,l}
+ bspc node -{f,s} {west,south,north,east}
+
+# focus the node for the given path jump
+alt + {p,b,comma,period}
+ bspc node -f @{parent,brother,first,second}
+
+# focus the next/previous node in the current desktop
+alt + {_,shift + }c
+ bspc node -f {next,prev}.local
+
+# focus the next/previous desktop in the current Monitor
+alt + bracket{left,right}
+ bspc desktop -f {prev,next}.local
+
+# focus the last node/desktop
+alt + {grave,Tab}
+ bspc {node,desktop} -f last
+
+# focus the older or newer node in the focus history
+alt + {o,i}
+ bspc wm -h off; \
+ bspc node {older,newer} -f; \
+ bspc wm -h on
+
+# focus or send to the given desktop
+alt + {_,shift + }{1-9,0}
+ bspc {desktop -f,node -d} '^{1-9,10}'
+
+#
+# preselect
+#
+
+# preselect the direction
+alt + ctrl + {h,j,k,l}
+ bspc node -p {west,south,north,east}
+
+# preselect the ratio
+alt + ctrl + {1-9}
+ bspc node -o 0.{1-9}
+
+# cancel the preselection for the focused node
+alt + ctrl + space
+ bspc node -p cancel
+
+# cancel the preselection for the focused desktop
+alt + ctrl + shift + space
+ bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
+
+#
+# move/resize
+#
+
+# expand a window by moving one of its side outward
+super + alt + {h,j,k,l}
+ bspc node -z {left -20 0,bottom 0 20,top 0 -20,right 20 0}
+
+# contract a window by moving one of its side inward
+super + alt + shift + {h,j,k,l}
+ bspc node -z {right -20 0,top :0 20,bottom 0 -20,left 20 0}
+
+# move a floating window
+super + {Left,Down,Up,Right}
+ bspc node -v {-20 0,0 20,0 -20,20 0}
+
+#
+# bsp-layout
+#
+alt + {t,shift + t}
+ bsp-layout set {tile,tall -- --master-size 0.5}
+
+#
+# scratchpads
+#
+
+# htop
+alt + control + z
+ bspt sphtop htop
+
+# terminal
+alt + control + x
+ bspt spterm tmux
+
+# pulsemixer
+alt + control + c
+ bspt sppmxr pulsemixer
+
+# bluetoothctl
+alt + control + v
+ bspt spblue bluetoothctl
+
+# ncmpcpp
+alt + control + b
+ bspt spncmp ncmpcpp
+
+# neomutt
+alt + control + a
+ bspt spmutt neomutt
+
+# profanity
+alt + control + s
+ bspt spprof profanity
+
+# irssi
+alt + control + d
+ bspt spircc irssi
+
+# todo
+alt + control + f
+ bspt sptodo todo
+
+# trem
+alt + control + g
+ bspt sptrem tremc
diff --git a/sxiv/exec/key-handler b/sxiv/exec/key-handler
new file mode 100755
index 0000000..08e06d5
--- /dev/null
+++ b/sxiv/exec/key-handler
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+IMAGES=`cat -`
+
+case "$1" in
+ "w")
+ notify-send "$IMAGES" "background"
+ ln -sf $IMAGES ~/background.jpg
+ xwallpaper --zoom ~/background.jpg
+ ;;
+esac
diff --git a/tmux/tmux.conf b/tmux/tmux.conf
new file mode 100644
index 0000000..d421349
--- /dev/null
+++ b/tmux/tmux.conf
@@ -0,0 +1,30 @@
+# improve colors
+set -g default-terminal "screen-256color"
+
+# change status bar color to black and white
+set -g status-bg "#000000"
+set -g status-fg "#c5c6c4"
+
+# remove administrative debris (session-name, hostname, time) in status bar
+set -g status-left ''
+set -g status-right '#{battery_status_bg} Batt: #{battery_icon} #{battery_percentage} #{battery_remain}'
+
+# act live dvtm
+unbind C-b
+set -g prefix C-z
+
+# act like vim
+setw -g mode-keys vi
+bind h select-pane -L
+bind j select-pane -D
+bind k select-pane -U
+bind l select-pane -R
+bind-key -r C-h select-window -t :-
+bind-key -r C-l select-window -t :+
+
+set -g @plugin 'tmux-plugins/tpm'
+set -g @plugin 'tmux-plugins/tmux-sensible'
+set -g @plugin 'https://git.linux-help.org/psi-jack/tmux-indicators'
+set -g @plugin 'tmux-plugins/tmux-battery'
+
+run '/usr/share/tmux-plugin-manager/tpm'
diff --git a/tofi/config b/tofi/config
new file mode 100644
index 0000000..ca63d6e
--- /dev/null
+++ b/tofi/config
@@ -0,0 +1,18 @@
+anchor = top
+width = 100%
+height = 24
+horizontal = true
+font-size = 11
+prompt-text = " run: "
+font = mononoki Nerd Font Mono
+outline-width = 0
+border-width = 0
+background-color = #000000
+text-color = #198844
+selection-color = #39c1ed
+min-input-width = 120
+result-spacing = 15
+padding-top = 3
+padding-bottom = 0
+padding-left = 0
+padding-right = 0
diff --git a/trizen/trizen.conf b/trizen/trizen.conf
new file mode 100644
index 0000000..a770759
--- /dev/null
+++ b/trizen/trizen.conf
@@ -0,0 +1,57 @@
+#!/usr/bin/perl
+
+# trizen configuration file
+
+our $CONFIG = {
+ ask_for_retry => 1, # bool -- When `makepkg` fails to build a package, offer the option for trying again.
+ aur_results_last_modified => 1, # bool -- Show the date when the packages were last updated in AUR results.
+ aur_results_popularity => 1, # bool -- Show the popularity score in AUR results.
+ aur_results_show_installed => 1, # bool -- Show when a package is installed in AUR results.
+ aur_results_sort_by => "name", # str -- Sort the AUR results by "name", "votes", "popularity" or "date".
+ aur_results_sort_order => "ascending", # str -- Sort the AUR results in "ascending" or "descending" order.
+ aur_results_votes => 1, # bool -- Show the number of votes in AUR results.
+ clone_dir => "/tmp/trizen-zachir", # str -- Absolute path to the directory where to clone and build packages.
+ color_code_dependencies => 1, # bool -- Display the dependencies of a package in specific colors (green = installed; cyan = in repo; purple = in AUR).
+ debug => 0, # bool -- Verbose mode.
+ flip_indices => 0, # bool -- In search+install mode, show the indices of packages in reverse order.
+ flip_results => 0, # bool -- Show the search results in reverse order.
+ forcecolors => 0, # bool -- Force output colors even when not writing to STDOUT.
+ git_clone_depth => 0, # int -- Pass the `--depth int` flag to `git clone`. (0 means no limit)
+ lwp_env_proxy => 1, # bool -- Use proxy settings defined in `env` (if any).
+ lwp_show_progress => 0, # bool -- Show the HTTPS requests made by LWP::UserAgent to the AUR servers.
+ lwp_timeout => 60, # int -- Seconds after which an HTTPS connection is aborted.
+ makepkg_command => "/usr/bin/makepkg -scf", # str -- The `makepkg` command that is used internally in building a package.
+ movepkg => 0, # bool -- Move built packages in the directory `movepkg_dir`.
+ movepkg_dir => "/var/cache/pacman/pkg", # str -- Absolute path to the directory where to move built packages (with `movepkg`).
+ nocolors => 0, # bool -- Disable output colors for `trizen`.
+ noedit => 0, # bool -- Do not prompt to edit files when installing an AUR package.
+ noinfo => 0, # bool -- Do not display package information when installing an AUR package.
+ noinstall => 0, # bool -- Do not install built packages -- builds only.
+ nopull => 0, # bool -- Do not `git pull` new changes from the AUR git server.
+ one_line_edit => 1, # bool -- Select one or more build files to view/edit with one-line prompt.
+ packages_in_stats => 5, # int -- The number of packages to display in `--stats`
+ pacman_command => "pacman", # str -- The `pacman` command that is used internally for pacman operations.
+ pacman_local_dir => "/var/lib/pacman/local", # str -- Absolute path to the pacman's local directory.
+ pager_mode => 0, # bool -- Show the build files in pager mode using pager.
+ recompute_deps => 1, # bool -- Recompute the dependencies of a package (after its build files are inspected / edited).
+ show_build_files_content => 1, # bool -- Show the content of the build files of a package before building it.
+ show_comments => 0, # int -- Show the `n` most recent AUR comments for a package before building it. (max: 10)
+ show_diff_only => 0, # bool -- When the build files of a package already exist locally, show the diff only.
+ show_inexistent => 1, # bool -- Warn about packages that do not exist in AUR, during -Su.
+ show_ood => 0, # bool -- Warn about out-of-date marked packages, during -Su.
+ show_unmaintained => 1, # bool -- Warn about unmaintained packages, during -Su.
+ skipinteg => 0, # bool -- Pass the `--skipinteg` argument to `makepkg`.
+ split_packages => 1, # bool -- Ask about installing the other parts of a split package.
+ ssl_verify_hostname => 1, # bool -- Ensure LWP::UserAgent connects to servers that have a valid certificate.
+ su_command => "/usr/bin/su -c", # str -- Command used when special permissions are required and `use_sudo` is set to 0.
+ sudo_autorepeat => 0, # bool -- Automatically repeat `sudo -v` in the background after a `sudo` command was first executed.
+ sudo_autorepeat_at_runtime => 0, # bool -- Execute `sudo -v` when `trizen` is first executed and apply the behavior of `sudo_autorepeat`.
+ sudo_autorepeat_interval => 180, # int -- Interval, in seconds, after which `sudo -v` is executed in background (with `sudo_autorepeat`).
+ sudo_command => "/usr/bin/doas", # str -- Command used when special permissions are required and `use_sudo` is set to 1.
+ sudo_remove_timestamp => 0, # bool -- Remove the cached sudo credentials before `makepkg` is executed (`sudo --remove-timestamp`).
+ syntax_highlighting => 0, # bool -- Syntax highlighting of the build files, using the `highlight` tool from [community].
+ syntax_highlighting_cmd => "/usr/bin/highlight -O ansi", # str -- The `highlight` command used in highlighting the syntax of the build files (with `syntax_highlighting`).
+ use_github_api => 1, # bool -- Check GitHub sources for updates using GitHub's API. (during `--devel --needed`)
+ use_gitlab_api => 1, # bool -- Check GitLab sources for updates using GitLab's API. (during `--devel --needed`)
+ use_sudo => 1, # bool -- Use the `sudo` command when special permissions are required.
+}
diff --git a/user-dirs.dirs b/user-dirs.dirs
new file mode 100644
index 0000000..7f9a959
--- /dev/null
+++ b/user-dirs.dirs
@@ -0,0 +1,15 @@
+# This file is written by xdg-user-dirs-update
+# If you want to change or add directories, just edit the line you're
+# interested in. All local changes will be retained on the next run.
+# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
+# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
+# absolute path. No other format is supported.
+#
+XDG_DESKTOP_DIR="$HOME/Desktop"
+XDG_DOWNLOAD_DIR="$HOME/Downloads"
+XDG_TEMPLATES_DIR="$HOME/Templates"
+XDG_PUBLICSHARE_DIR="$HOME/Public"
+XDG_DOCUMENTS_DIR="$HOME/Documents"
+XDG_MUSIC_DIR="$HOME/Music"
+XDG_PICTURES_DIR="$HOME/Pictures"
+XDG_VIDEOS_DIR="$HOME/Videos"
diff --git a/user-dirs.locale b/user-dirs.locale
new file mode 100644
index 0000000..3e0b419
--- /dev/null
+++ b/user-dirs.locale
@@ -0,0 +1 @@
+en_US \ No newline at end of file
diff --git a/vlc/vlcrc b/vlc/vlcrc
new file mode 100644
index 0000000..f3d384b
--- /dev/null
+++ b/vlc/vlcrc
@@ -0,0 +1,5120 @@
+###
+### vlc 3.0.16
+###
+
+###
+### lines beginning with a '#' character are comments
+###
+
+[upnp] # Universal Plug'n'Play
+
+# SAT>IP channel list (string)
+#satip-channelist=auto
+
+# Custom SAT>IP channel list URL (string)
+#satip-channellist-url=
+
+[sap] # Network streams (SAP)
+
+# SAP multicast address (string)
+#sap-addr=
+
+# SAP timeout (seconds) (integer)
+#sap-timeout=1800
+
+# Try to parse the announce (boolean)
+#sap-parse=1
+
+# SAP Strict mode (boolean)
+#sap-strict=0
+
+[podcast] # Podcasts
+
+# Podcast URLs list (string)
+#podcast-urls=
+
+[hqdn3d] # High Quality 3D Denoiser filter
+
+# Spatial luma strength (0-254) (float)
+#hqdn3d-luma-spat=4.000000
+
+# Spatial chroma strength (0-254) (float)
+#hqdn3d-chroma-spat=3.000000
+
+# Temporal luma strength (0-254) (float)
+#hqdn3d-luma-temp=6.000000
+
+# Temporal chroma strength (0-254) (float)
+#hqdn3d-chroma-temp=4.500000
+
+[antiflicker] # antiflicker video filter
+
+# Window size (integer)
+#antiflicker-window-size=10
+
+# Softening value (integer)
+#antiflicker-softening-size=10
+
+[postproc] # Video post processing filter
+
+# Post processing quality (integer)
+#postproc-q=6
+
+# FFmpeg post processing filter chains (string)
+#postproc-name=default
+
+[erase] # Erase video filter
+
+# Image mask (string)
+#erase-mask=
+
+# X coordinate (integer)
+#erase-x=0
+
+# Y coordinate (integer)
+#erase-y=0
+
+[canvas] # Canvas video filter
+
+# Output width (integer)
+#canvas-width=0
+
+# Output height (integer)
+#canvas-height=0
+
+# Output picture aspect ratio (string)
+#canvas-aspect=
+
+# Pad video (boolean)
+#canvas-padd=1
+
+[bluescreen] # Bluescreen video filter
+
+# Bluescreen U value (integer)
+#bluescreen-u=120
+
+# Bluescreen V value (integer)
+#bluescreen-v=90
+
+# Bluescreen U tolerance (integer)
+#bluescreen-ut=17
+
+# Bluescreen V tolerance (integer)
+#bluescreen-vt=17
+
+[puzzle] # Puzzle interactive game video filter
+
+# Number of puzzle rows (integer)
+#puzzle-rows=4
+
+# Number of puzzle columns (integer)
+#puzzle-cols=4
+
+# Border (integer)
+#puzzle-border=3
+
+# Small preview (boolean)
+#puzzle-preview=0
+
+# Small preview size (integer)
+#puzzle-preview-size=15
+
+# Piece edge shape size (integer)
+#puzzle-shape-size=90
+
+# Auto shuffle (integer)
+#puzzle-auto-shuffle=0
+
+# Auto solve (integer)
+#puzzle-auto-solve=0
+
+# Rotation (integer)
+#puzzle-rotation=0
+
+# Game mode (integer)
+#puzzle-mode=0
+
+[transform] # Video transformation filter
+
+# Transform type (string)
+#transform-type=90
+
+[grain] # Grain video filter
+
+# Variance (float)
+#grain-variance=2.000000
+
+# Minimal period (integer)
+#grain-period-min=1
+
+# Maximal period (integer)
+#grain-period-max=48
+
+[alphamask] # Alpha mask video filter
+
+# Transparency mask (string)
+#alphamask-mask=
+
+[rotate] # Rotate video filter
+
+# Angle in degrees (float)
+#rotate-angle=30.000000
+
+# Use motion sensors (boolean)
+#rotate-use-motion=0
+
+[mirror] # Mirror video filter
+
+# Mirror orientation (integer)
+#mirror-split=0
+
+# Direction (integer)
+#mirror-direction=0
+
+[croppadd] # Video cropping filter
+
+# Pixels to crop from top (integer)
+#croppadd-croptop=0
+
+# Pixels to crop from bottom (integer)
+#croppadd-cropbottom=0
+
+# Pixels to crop from left (integer)
+#croppadd-cropleft=0
+
+# Pixels to crop from right (integer)
+#croppadd-cropright=0
+
+# Pixels to padd to top (integer)
+#croppadd-paddtop=0
+
+# Pixels to padd to bottom (integer)
+#croppadd-paddbottom=0
+
+# Pixels to padd to left (integer)
+#croppadd-paddleft=0
+
+# Pixels to padd to right (integer)
+#croppadd-paddright=0
+
+[gradient] # Gradient video filter
+
+# Distort mode (string)
+#gradient-mode=gradient
+
+# Gradient image type (integer)
+#gradient-type=0
+
+# Apply cartoon effect (boolean)
+#gradient-cartoon=1
+
+[posterize] # Posterize video filter
+
+# Posterize level (integer)
+#posterize-level=6
+
+[anaglyph] # Convert 3D picture to anaglyph image video filter
+
+# Color scheme (string)
+#anaglyph-scheme=red-cyan
+
+[gaussianblur] # Gaussian blur video filter
+
+# Gaussian's std deviation (float)
+#gaussianblur-sigma=2.000000
+
+[fps] # FPS conversion video filter
+
+# Frame rate (string)
+#fps-fps=
+
+[colorthres] # Color threshold filter
+
+# Color (integer)
+#colorthres-color=16711680
+
+# Saturation threshold (integer)
+#colorthres-saturationthres=20
+
+# Similarity threshold (integer)
+#colorthres-similaritythres=15
+
+[sharpen] # Sharpen video filter
+
+# Sharpen strength (0-2) (float)
+#sharpen-sigma=0.050000
+
+[deinterlace] # Deinterlacing video filter
+
+# Streaming deinterlace mode (string)
+#sout-deinterlace-mode=blend
+
+# Phosphor chroma mode for 4:2:0 input (integer)
+#sout-deinterlace-phosphor-chroma=2
+
+# Phosphor old field dimmer strength (integer)
+#sout-deinterlace-phosphor-dimmer=2
+
+[motionblur] # Motion blur filter
+
+# Blur factor (1-127) (integer)
+#blur-factor=80
+
+[scene] # Scene video filter
+
+# Image format (string)
+#scene-format=png
+
+# Image width (integer)
+#scene-width=-1
+
+# Image height (integer)
+#scene-height=-1
+
+# Filename prefix (string)
+#scene-prefix=scene
+
+# Directory path prefix (string)
+#scene-path=
+
+# Always write to the same file (boolean)
+#scene-replace=0
+
+# Recording ratio (integer)
+#scene-ratio=50
+
+[sepia] # Sepia video filter
+
+# Sepia intensity (integer)
+#sepia-intensity=120
+
+[gradfun] # Gradfun video filter
+
+# Radius (integer)
+#gradfun-radius=16
+
+# Strength (float)
+#gradfun-strength=1.200000
+
+[blendbench] # Blending benchmark filter
+
+# Number of time to blend (integer)
+#blendbench-loops=1000
+
+# Alpha of the blended image (integer)
+#blendbench-alpha=128
+
+# Image to be blended onto (string)
+#blendbench-base-image=
+
+# Chroma for the base image (string)
+#blendbench-base-chroma=I420
+
+# Image which will be blended (string)
+#blendbench-blend-image=
+
+# Chroma for the blend image (string)
+#blendbench-blend-chroma=YUVA
+
+[ball] # Ball video filter
+
+# Ball color (string)
+#ball-color=red
+
+# Ball speed (integer)
+#ball-speed=4
+
+# Ball size (integer)
+#ball-size=10
+
+# Gradient threshold (integer)
+#ball-gradient-threshold=40
+
+# Edge visible (boolean)
+#ball-edge-visible=1
+
+[extract] # Extract RGB component video filter
+
+# RGB component to extract (integer)
+#extract-component=16711680
+
+[adjust] # Image properties filter
+
+# Image contrast (0-2) (float)
+#contrast=1.000000
+
+# Image brightness (0-2) (float)
+#brightness=1.000000
+
+# Image hue (-180..180) (float)
+#hue=0.000000
+
+# Image saturation (0-3) (float)
+#saturation=1.000000
+
+# Image gamma (0-10) (float)
+#gamma=1.000000
+
+# Brightness threshold (boolean)
+#brightness-threshold=0
+
+[samplerate] # Secret Rabbit Code (libsamplerate) resampler
+
+# Sample rate converter type (integer)
+#src-converter-type=2
+
+[scaletempo] # Audio tempo scaler synched with rate
+
+# Stride Length (integer)
+#scaletempo-stride=30
+
+# Overlap Length (float)
+#scaletempo-overlap=0.200000
+
+# Search Length (integer)
+#scaletempo-search=14
+
+[spatialaudio] # Ambisonics renderer and binauralizer
+
+# Headphones mode (binaural) (boolean)
+#spatialaudio-headphones=0
+
+# HRTF file for the binauralization (string)
+#hrtf-file=
+
+[normvol] # Volume normalizer
+
+# Number of audio buffers (integer)
+#norm-buff-size=20
+
+# Maximal volume level (float)
+#norm-max-level=2.000000
+
+[spatializer] # Audio Spatializer
+
+# Room size (float)
+#spatializer-roomsize=0.850000
+
+# Room width (float)
+#spatializer-width=1.000000
+
+# Wet (float)
+#spatializer-wet=0.400000
+
+# Dry (float)
+#spatializer-dry=0.500000
+
+# Damp (float)
+#spatializer-damp=0.500000
+
+[compressor] # Dynamic range compressor
+
+# RMS/peak (float)
+#compressor-rms-peak=0.200000
+
+# Attack time (float)
+#compressor-attack=25.000000
+
+# Release time (float)
+#compressor-release=100.000000
+
+# Threshold level (float)
+#compressor-threshold=-11.000000
+
+# Ratio (float)
+#compressor-ratio=4.000000
+
+# Knee radius (float)
+#compressor-knee=5.000000
+
+# Makeup gain (float)
+#compressor-makeup-gain=7.000000
+
+[param_eq] # Parametric Equalizer
+
+# Low freq (Hz) (float)
+#param-eq-lowf=100.000000
+
+# Low freq gain (dB) (float)
+#param-eq-lowgain=0.000000
+
+# High freq (Hz) (float)
+#param-eq-highf=10000.000000
+
+# High freq gain (dB) (float)
+#param-eq-highgain=0.000000
+
+# Freq 1 (Hz) (float)
+#param-eq-f1=300.000000
+
+# Freq 1 gain (dB) (float)
+#param-eq-gain1=0.000000
+
+# Freq 1 Q (float)
+#param-eq-q1=3.000000
+
+# Freq 2 (Hz) (float)
+#param-eq-f2=1000.000000
+
+# Freq 2 gain (dB) (float)
+#param-eq-gain2=0.000000
+
+# Freq 2 Q (float)
+#param-eq-q2=3.000000
+
+# Freq 3 (Hz) (float)
+#param-eq-f3=3000.000000
+
+# Freq 3 gain (dB) (float)
+#param-eq-gain3=0.000000
+
+# Freq 3 Q (float)
+#param-eq-q3=3.000000
+
+[stereo_widen] # Simple stereo widening effect
+
+# Delay time (float)
+#stereowiden-delay=20.000000
+
+# Feedback gain (float)
+#stereowiden-feedback=0.300000
+
+# Crossfeed (float)
+#stereowiden-crossfeed=0.300000
+
+# Dry mix (float)
+#stereowiden-dry-mix=0.800000
+
+[soxr] # soxr
+
+# Resampling quality (integer)
+#soxr-resampler-quality=2
+
+[scaletempo_pitch] # Pitch Shifter
+
+# Stride Length (integer)
+#scaletempo-stride=30
+
+# Overlap Length (float)
+#scaletempo-overlap=0.200000
+
+# Search Length (integer)
+#scaletempo-search=14
+
+# Pitch Shift (float)
+#pitch-shift=0.000000
+
+[gain] # Gain control filter
+
+# Gain multiplier (float)
+#gain-value=1.000000
+
+[headphone] # Headphone virtual spatialization effect
+
+# Characteristic dimension (integer)
+#headphone-dim=10
+
+# Compensate delay (boolean)
+#headphone-compensate=0
+
+# No decoding of Dolby Surround (boolean)
+#headphone-dolby=0
+
+[chorus_flanger] # Sound Delay
+
+# Delay time (float)
+#delay-time=20.000000
+
+# Sweep Depth (float)
+#sweep-depth=6.000000
+
+# Sweep Rate (float)
+#sweep-rate=6.000000
+
+# Feedback gain (float)
+#feedback-gain=0.500000
+
+# Wet mix (float)
+#wet-mix=0.400000
+
+# Dry Mix (float)
+#dry-mix=0.400000
+
+[mono] # Stereo to mono downmixer
+
+# Use downmix algorithm (boolean)
+#sout-mono-downmix=1
+
+# Select channel to keep (integer)
+#sout-mono-channel=-1
+
+[speex_resampler] # Speex resampler
+
+# Resampling quality (integer)
+#speex-resampler-quality=4
+
+[equalizer] # Equalizer with 10 bands
+
+# Equalizer preset (string)
+#equalizer-preset=flat
+
+# Bands gain (string)
+#equalizer-bands=
+
+# Two pass (boolean)
+#equalizer-2pass=0
+
+# Use VLC frequency bands (boolean)
+#equalizer-vlcfreqs=1
+
+# Global gain (float)
+#equalizer-preamp=12.000000
+
+[audiobargraph_a] # Audio part of the BarGraph function
+
+# Defines if BarGraph information should be sent (integer)
+#audiobargraph_a-bargraph=1
+
+# Sends the barGraph information every n audio packets (integer)
+#audiobargraph_a-bargraph_repetition=4
+
+# Defines if silence alarm information should be sent (integer)
+#audiobargraph_a-silence=1
+
+# Time window to use in ms (integer)
+#audiobargraph_a-time_window=5000
+
+# Minimum Audio level to raise the alarm (float)
+#audiobargraph_a-alarm_threshold=0.020000
+
+# Time between two alarm messages in ms (integer)
+#audiobargraph_a-repetition_time=2000
+
+[remap] # Audio channel remapper
+
+# Left (integer)
+#aout-remap-channel-left=0
+
+# Center (integer)
+#aout-remap-channel-center=1
+
+# Right (integer)
+#aout-remap-channel-right=2
+
+# Rear left (integer)
+#aout-remap-channel-rearleft=3
+
+# Rear center (integer)
+#aout-remap-channel-rearcenter=4
+
+# Rear right (integer)
+#aout-remap-channel-rearright=5
+
+# Side left (integer)
+#aout-remap-channel-middleleft=6
+
+# Side right (integer)
+#aout-remap-channel-middleright=7
+
+# Low-frequency effects (integer)
+#aout-remap-channel-lfe=8
+
+# Normalize channels (boolean)
+#aout-remap-normalize=1
+
+[syslog] # System logger (syslog)
+
+# System log (syslog) (boolean)
+#syslog=0
+
+# Debug messages (boolean)
+#syslog-debug=0
+
+# Identity (string)
+#syslog-ident=vlc
+
+# Facility (string)
+#syslog-facility=user
+
+[console] # Console logger
+
+[file] # File logger
+
+# Log to file (boolean)
+#file-logging=0
+
+# Log filename (string)
+#logfile=
+
+# Log format (string)
+#logmode=text
+
+# Verbosity (integer)
+#log-verbose=-1
+
+[visual] # Visualizer filter
+
+# Effects list (string)
+#effect-list=spectrum
+
+# Video width (integer)
+#effect-width=800
+
+# Video height (integer)
+#effect-height=500
+
+# FFT window (string)
+#effect-fft-window=flat
+
+# Kaiser window parameter (float)
+#effect-kaiser-param=3.000000
+
+# Show 80 bands instead of 20 (boolean)
+#visual-80-bands=1
+
+# Draw peaks in the analyzer (boolean)
+#visual-peaks=1
+
+# Enable original graphic spectrum (boolean)
+#spect-show-original=0
+
+# Draw the base of the bands (boolean)
+#spect-show-base=1
+
+# Base pixel radius (integer)
+#spect-radius=42
+
+# Spectral sections (integer)
+#spect-sections=3
+
+# V-plane color (integer)
+#spect-color=80
+
+# Draw bands in the spectrometer (boolean)
+#spect-show-bands=1
+
+# Show 80 bands instead of 20 (boolean)
+#spect-80-bands=1
+
+# Number of blank pixels between bands. (integer)
+#spect-separ=1
+
+# Amplification (integer)
+#spect-amp=8
+
+# Draw peaks in the analyzer (boolean)
+#spect-show-peaks=1
+
+# Peak extra width (integer)
+#spect-peak-width=61
+
+# Peak height (integer)
+#spect-peak-height=1
+
+[glspectrum] # 3D OpenGL spectrum visualization
+
+# Video width (integer)
+#glspectrum-width=400
+
+# Video height (integer)
+#glspectrum-height=300
+
+[ps] # MPEG-PS demuxer
+
+# Trust MPEG timestamps (boolean)
+#ps-trust-timestamps=1
+
+[es] # MPEG-I/II/4 / A52 / DTS / MLP audio
+
+# Frames per Second (float)
+#es-fps=25.000000
+
+[mp4] # MP4 stream demuxer
+
+# M4A audio only (boolean)
+#mp4-m4a-audioonly=0
+
+[rawaud] # Raw audio demuxer
+
+# Audio channels (integer)
+#rawaud-channels=2
+
+# Audio samplerate (Hz) (integer)
+#rawaud-samplerate=48000
+
+# FOURCC code of raw input format (string)
+#rawaud-fourcc=s16l
+
+# Forces the audio language (string)
+#rawaud-lang=eng
+
+[ts] # MPEG Transport Stream demuxer
+
+# Digital TV Standard (string)
+#ts-standard=auto
+
+# Extra PMT (string)
+#ts-extra-pmt=
+
+# Trust in-stream PCR (boolean)
+#ts-trust-pcr=1
+
+# Set id of ES to PID (boolean)
+#ts-es-id-pid=1
+
+# CSA Key (string)
+#ts-csa-ck=
+
+# Second CSA Key (string)
+#ts-csa2-ck=
+
+# Packet size in bytes to decrypt (integer)
+#ts-csa-pkt=188
+
+# Separate sub-streams (boolean)
+#ts-split-es=1
+
+# Seek based on percent not time (boolean)
+#ts-seek-percent=0
+
+# Check packets continuity counter (boolean)
+#ts-cc-check=1
+
+# Only create ES on program sending data (boolean)
+#ts-pmtfix-waitdata=1
+
+# Try to generate PAT/PMT if missing (boolean)
+#ts-patfix=1
+
+# Try to fix too early PCR (or late DTS) (boolean)
+#ts-pcr-offsetfix=1
+
+[avi] # AVI demuxer
+
+# Force interleaved method (boolean)
+#avi-interleaved=0
+
+# Force index creation (integer)
+#avi-index=0
+
+[playlist] # Playlist
+
+# Skip ads (boolean)
+#playlist-skip-ads=1
+
+# Show shoutcast adult content (boolean)
+#shoutcast-show-adult=0
+
+[adaptive] # Unified adaptive streaming for DASH/HLS
+
+# Adaptive Logic (string)
+#adaptive-logic=
+
+# Maximum device width (integer)
+#adaptive-maxwidth=0
+
+# Maximum device height (integer)
+#adaptive-maxheight=0
+
+# Fixed Bandwidth in KiB/s (integer)
+#adaptive-bw=250
+
+# Use regular HTTP modules (boolean)
+#adaptive-use-access=0
+
+# Live Playback delay (ms) (integer)
+#adaptive-livedelay=15000
+
+# Max buffering (ms) (integer)
+#adaptive-maxbuffer=30000
+
+# Low latency (integer)
+#adaptive-lowlatency=-1
+
+[mod] # MOD demuxer (libmodplug)
+
+# Noise reduction (boolean)
+#mod-noisereduction=1
+
+# Reverb (boolean)
+#mod-reverb=0
+
+# Reverberation level (integer)
+#mod-reverb-level=0
+
+# Reverberation delay (integer)
+#mod-reverb-delay=40
+
+# Mega bass (boolean)
+#mod-megabass=0
+
+# Mega bass level (integer)
+#mod-megabass-level=0
+
+# Mega bass cutoff (integer)
+#mod-megabass-range=10
+
+# Surround (boolean)
+#mod-surround=0
+
+# Surround level (integer)
+#mod-surround-level=0
+
+# Surround delay (ms) (integer)
+#mod-surround-delay=5
+
+[avformat] # Avformat demuxer
+
+# Format name (string)
+#avformat-format=
+
+# Advanced options (string)
+#avformat-options=
+
+# Avformat mux (string)
+#sout-avformat-mux=
+
+# Advanced options (string)
+#sout-avformat-options=
+
+# Reset timestamps (boolean)
+#sout-avformat-reset-ts=0
+
+[rawdv] # DV (Digital Video) demuxer
+
+# Hurry up (boolean)
+#rawdv-hurry-up=0
+
+[demuxdump] # File dumper
+
+# Dump module (string)
+#demuxdump-access=file
+
+# Dump filename (string)
+#demuxdump-file=stream-demux.dump
+
+# Append to existing file (boolean)
+#demuxdump-append=0
+
+[vc1] # VC1 video demuxer
+
+# Frames per Second (float)
+#vc1-fps=25.000000
+
+[rawvid] # Raw video demuxer
+
+# Frames per Second (string)
+#rawvid-fps=
+
+# Width (integer)
+#rawvid-width=0
+
+# Height (integer)
+#rawvid-height=0
+
+# Force chroma (Use carefully) (string)
+#rawvid-chroma=
+
+# Aspect ratio (string)
+#rawvid-aspect-ratio=
+
+[image] # Image demuxer
+
+# ES ID (integer)
+#image-id=-1
+
+# Group (integer)
+#image-group=0
+
+# Decode (boolean)
+#image-decode=1
+
+# Forced chroma (string)
+#image-chroma=
+
+# Duration in seconds (float)
+#image-duration=10.000000
+
+# Frame rate (string)
+#image-fps=10/1
+
+# Real-time (boolean)
+#image-realtime=0
+
+[mkv] # Matroska stream demuxer
+
+# Respect ordered chapters (boolean)
+#mkv-use-ordered-chapters=1
+
+# Chapter codecs (boolean)
+#mkv-use-chapter-codec=1
+
+# Preload MKV files in the same directory (boolean)
+#mkv-preload-local-dir=1
+
+# Seek based on percent not time (boolean)
+#mkv-seek-percent=0
+
+# Dummy Elements (boolean)
+#mkv-use-dummy=0
+
+# Preload clusters (boolean)
+#mkv-preload-clusters=0
+
+[h26x] # H264 video demuxer
+
+# Frames per Second (float)
+#h264-fps=0.000000
+
+# Frames per Second (float)
+#hevc-fps=0.000000
+
+[mjpeg] # M-JPEG camera demuxer
+
+# Frames per Second (float)
+#mjpeg-fps=0.000000
+
+[diracsys] # Dirac video demuxer
+
+# Value to adjust dts by (integer)
+#dirac-dts-offset=0
+
+[subtitle] # Text subtitle parser
+
+# Frames per Second (float)
+#sub-fps=0.000000
+
+# Subtitle delay (integer)
+#sub-delay=0
+
+# Subtitle format (string)
+#sub-type=auto
+
+# Subtitle description (string)
+#sub-description=
+
+[prefetch] # Stream prefetch filter
+
+# Buffer size (integer)
+#prefetch-buffer-size=16384
+
+# Read size (integer)
+#prefetch-read-size=16777216
+
+# Seek threshold (integer)
+#prefetch-seek-threshold=16384
+
+[udp] # UDP input
+
+# UDP Source timeout (sec) (integer)
+#udp-timeout=-1
+
+[rist] # RIST input
+
+# RIST maximum packet size (bytes) (integer)
+#packet-size=1472
+
+# RIST demux/decode maximum jitter (default is 5ms) (integer)
+#maximum-jitter=5
+
+# RIST latency (ms) (integer)
+#latency=1000
+
+# RIST nack retry interval (ms) (integer)
+#retry-interval=132
+
+# RIST reorder buffer (ms) (integer)
+#reorder-buffer=70
+
+# RIST maximum retry count (integer)
+#max-retries=10
+
+# RIST nack type, 0 = range, 1 = bitmask. Default is range (integer)
+#nack-type=0
+
+# Disable NACK output packets (boolean)
+#disable-nacks=0
+
+# Do not check for a valid rtcp message from the encoder (boolean)
+#mcast-blind-nacks=0
+
+[v4l2] # Video4Linux input
+
+# Video capture device (string)
+#v4l2-dev=/dev/video0
+
+# VBI capture device (string)
+#v4l2-vbidev=
+
+# Standard (string)
+#v4l2-standard=
+
+# Video input chroma format (string)
+#v4l2-chroma=
+
+# Input (integer)
+#v4l2-input=0
+
+# Audio input (integer)
+#v4l2-audio-input=-1
+
+# Width (integer)
+#v4l2-width=0
+
+# Height (integer)
+#v4l2-height=0
+
+# Picture aspect-ratio n:m (string)
+#v4l2-aspect-ratio=4:3
+
+# Frame rate (string)
+#v4l2-fps=60
+
+# Radio device (string)
+#v4l2-radio-dev=/dev/radio0
+
+# Frequency (integer)
+#v4l2-tuner-frequency=-1
+
+# Audio mode (integer)
+#v4l2-tuner-audio-mode=3
+
+# Reset controls (boolean)
+#v4l2-controls-reset=0
+
+# Brightness (integer)
+#v4l2-brightness=-1
+
+# Automatic brightness (integer)
+#v4l2-brightness-auto=-1
+
+# Contrast (integer)
+#v4l2-contrast=-1
+
+# Saturation (integer)
+#v4l2-saturation=-1
+
+# Hue (integer)
+#v4l2-hue=-1
+
+# Automatic hue (integer)
+#v4l2-hue-auto=-1
+
+# White balance temperature (K) (integer)
+#v4l2-white-balance-temperature=-1
+
+# Automatic white balance (integer)
+#v4l2-auto-white-balance=-1
+
+# Red balance (integer)
+#v4l2-red-balance=-1
+
+# Blue balance (integer)
+#v4l2-blue-balance=-1
+
+# Gamma (integer)
+#v4l2-gamma=-1
+
+# Automatic gain (integer)
+#v4l2-autogain=-1
+
+# Gain (integer)
+#v4l2-gain=-1
+
+# Sharpness (integer)
+#v4l2-sharpness=-1
+
+# Chroma gain (integer)
+#v4l2-chroma-gain=-1
+
+# Automatic chroma gain (integer)
+#v4l2-chroma-gain-auto=-1
+
+# Power line frequency (integer)
+#v4l2-power-line-frequency=-1
+
+# Backlight compensation (integer)
+#v4l2-backlight-compensation=-1
+
+# Band-stop filter (integer)
+#v4l2-band-stop-filter=-1
+
+# Horizontal flip (boolean)
+#v4l2-hflip=0
+
+# Vertical flip (boolean)
+#v4l2-vflip=0
+
+# Rotate (degrees) (integer)
+#v4l2-rotate=-1
+
+# Color killer (integer)
+#v4l2-color-killer=-1
+
+# Color effect (integer)
+#v4l2-color-effect=-1
+
+# Audio volume (integer)
+#v4l2-audio-volume=-1
+
+# Audio balance (integer)
+#v4l2-audio-balance=-1
+
+# Mute (boolean)
+#v4l2-audio-mute=0
+
+# Bass level (integer)
+#v4l2-audio-bass=-1
+
+# Treble level (integer)
+#v4l2-audio-treble=-1
+
+# Loudness mode (boolean)
+#v4l2-audio-loudness=0
+
+# v4l2 driver controls (string)
+#v4l2-set-ctrls=
+
+[concat] # Concatenated inputs
+
+# Inputs list (string)
+#concat-list=
+
+[cdda] # Audio CD input
+
+# Audio CD device (string)
+#cd-audio=/dev/sr0
+
+# CDDB Server (string)
+#cddb-server=freedb.videolan.org
+
+# CDDB port (integer)
+#cddb-port=80
+
+[access] # HTTPS input
+
+# Cookies forwarding (boolean)
+#http-forward-cookies=1
+
+# User agent (string)
+#http-user-agent=
+
+[nfs] # NFS input
+
+# Set NFS uid/guid automatically (boolean)
+#nfs-auto-guid=1
+
+[timecode] # Time code subpicture elementary stream generator
+
+# Frame rate (string)
+#timecode-fps=25/1
+
+[http] # HTTP input
+
+# Auto re-connect (boolean)
+#http-reconnect=0
+
+[vdr] # VDR recordings
+
+# Chapter offset in ms (integer)
+#vdr-chapter-offset=0
+
+# Frame rate (float)
+#vdr-fps=25.000000
+
+[smb] # SMB input
+
+# Username (string)
+#smb-user=
+
+# Password (string)
+#smb-pwd=
+
+# SMB domain (string)
+#smb-domain=
+
+[vnc] # VNC client access
+
+# Username (string)
+#rfb-user=
+
+# Password (string)
+#rfb-password=
+
+# X.509 Certificate Authority (string)
+#rfb-x509-ca=
+
+# X.509 Certificate Revocation List (string)
+#rfb-x509-crl=
+
+# X.509 Client certificate (string)
+#rfb-x509-client-cert=
+
+# X.509 Client private key (string)
+#rfb-x509-client-key=
+
+# Frame rate (float)
+#rfb-fps=5.000000
+
+# Frame buffer depth (string)
+#rfb-chroma=RV32
+
+# Compression level (integer)
+#rfb-compress-level=0
+
+# Image quality (integer)
+#rfb-quality-level=9
+
+[dvb] # DVB input with v4l2 support
+
+# Probe DVB card for capabilities (boolean)
+#dvb-probe=1
+
+# Satellite scanning config (string)
+#dvb-satellite=
+
+# Scan tuning list (string)
+#dvb-scanlist=
+
+# Use NIT for scanning services (boolean)
+#dvb-scan-nit=1
+
+[filesystem] # File input
+
+# List special files (boolean)
+#list-special-files=0
+
+[dvdread] # DVDRead Input (no menu support)
+
+# DVD angle (integer)
+#dvdread-angle=1
+
+[dtv] # Digital Television and Radio
+
+# DVB adapter (integer)
+#dvb-adapter=0
+
+# DVB device (integer)
+#dvb-device=0
+
+# Do not demultiplex (boolean)
+#dvb-budget-mode=0
+
+# Frequency (Hz) (integer)
+#dvb-frequency=0
+
+# Spectrum inversion (integer)
+#dvb-inversion=-1
+
+# Bandwidth (MHz) (integer)
+#dvb-bandwidth=0
+
+# Transmission mode (integer)
+#dvb-transmission=0
+
+# Guard interval (string)
+#dvb-guard=
+
+# High-priority code rate (string)
+#dvb-code-rate-hp=
+
+# Low-priority code rate (string)
+#dvb-code-rate-lp=
+
+# Hierarchy mode (integer)
+#dvb-hierarchy=-1
+
+# DVB-T2 Physical Layer Pipe (integer)
+#dvb-plp-id=0
+
+# Layer A modulation (string)
+#dvb-a-modulation=
+
+# Layer A code rate (string)
+#dvb-a-fec=
+
+# Layer A segments count (integer)
+#dvb-a-count=0
+
+# Layer A time interleaving (integer)
+#dvb-a-interleaving=0
+
+# Layer B modulation (string)
+#dvb-b-modulation=
+
+# Layer B code rate (string)
+#dvb-b-fec=
+
+# Layer B segments count (integer)
+#dvb-b-count=0
+
+# Layer B time interleaving (integer)
+#dvb-b-interleaving=0
+
+# Layer C modulation (string)
+#dvb-c-modulation=
+
+# Layer C code rate (string)
+#dvb-c-fec=
+
+# Layer C segments count (integer)
+#dvb-c-count=0
+
+# Layer C time interleaving (integer)
+#dvb-c-interleaving=0
+
+# Modulation / Constellation (string)
+#dvb-modulation=
+
+# Symbol rate (bauds) (integer)
+#dvb-srate=0
+
+# FEC code rate (string)
+#dvb-fec=
+
+# Stream identifier (integer)
+#dvb-stream=0
+
+# Pilot (integer)
+#dvb-pilot=-1
+
+# Roll-off factor (integer)
+#dvb-rolloff=-1
+
+# Transport stream ID (integer)
+#dvb-ts-id=0
+
+# Polarization (Voltage) (string)
+#dvb-polarization=
+
+# (integer)
+#dvb-voltage=13
+
+# High LNB voltage (boolean)
+#dvb-high-voltage=0
+
+# Local oscillator low frequency (kHz) (integer)
+#dvb-lnb-low=0
+
+# Local oscillator high frequency (kHz) (integer)
+#dvb-lnb-high=0
+
+# Universal LNB switch frequency (kHz) (integer)
+#dvb-lnb-switch=11700000
+
+# DiSEqC LNB number (integer)
+#dvb-satno=0
+
+# Uncommitted DiSEqC LNB number (integer)
+#dvb-uncommitted=0
+
+# Continuous 22kHz tone (integer)
+#dvb-tone=-1
+
+[linsys_sdi] # SDI Input
+
+# Link # (integer)
+#linsys-sdi-link=0
+
+# Video ID (integer)
+#linsys-sdi-id-video=0
+
+# Aspect ratio (string)
+#linsys-sdi-aspect-ratio=
+
+# Audio configuration (string)
+#linsys-sdi-audio=0=1,1
+
+# Teletext configuration (string)
+#linsys-sdi-telx=
+
+# Teletext language (string)
+#linsys-sdi-telx-lang=
+
+[libbluray] # Blu-ray Disc support (libbluray)
+
+# Blu-ray menus (boolean)
+#bluray-menu=1
+
+# Region code (string)
+#bluray-region=B
+
+[access_alsa] # ALSA audio capture
+
+# Stereo (boolean)
+#alsa-stereo=1
+
+# Sample rate (integer)
+#alsa-samplerate=48000
+
+[access_mms] # Microsoft Media Server (MMS) input
+
+# TCP/UDP timeout (ms) (integer)
+#mms-timeout=5000
+
+# Force selection of all streams (boolean)
+#mms-all=0
+
+# Maximum bitrate (integer)
+#mms-maxbitrate=0
+
+[imem] # Memory input
+
+# ID (integer)
+#imem-id=-1
+
+# Group (integer)
+#imem-group=0
+
+# Category (integer)
+#imem-cat=0
+
+# Codec (string)
+#imem-codec=
+
+# Language (string)
+#imem-language=
+
+# Sample rate (integer)
+#imem-samplerate=0
+
+# Channels count (integer)
+#imem-channels=0
+
+# Width (integer)
+#imem-width=0
+
+# Height (integer)
+#imem-height=0
+
+# Display aspect ratio (string)
+#imem-dar=
+
+# Frame rate (string)
+#imem-fps=
+
+# Size (integer)
+#imem-size=0
+
+[ftp] # FTP input
+
+# Username (string)
+#ftp-user=
+
+# Password (string)
+#ftp-pwd=
+
+# FTP account (string)
+#ftp-account=anonymous
+
+[xcb_screen] # Screen capture (with X11/XCB)
+
+# Frame rate (float)
+#screen-fps=2.000000
+
+# Region left column (integer)
+#screen-left=0
+
+# Region top row (integer)
+#screen-top=0
+
+# Capture region width (integer)
+#screen-width=0
+
+# Capture region height (integer)
+#screen-height=0
+
+# Follow the mouse (boolean)
+#screen-follow-mouse=0
+
+[linsys_hdsdi] # HD-SDI Input
+
+# Link # (integer)
+#linsys-hdsdi-link=0
+
+# Video ID (integer)
+#linsys-hdsdi-id-video=0
+
+# Aspect ratio (string)
+#linsys-hdsdi-aspect-ratio=
+
+# Audio configuration (string)
+#linsys-hdsdi-audio=0=1,1
+
+[avio] # libavformat AVIO access
+
+# Advanced options (string)
+#avio-options=
+
+# Advanced options (string)
+#sout-avio-options=
+
+[dvdnav] # DVDnav Input
+
+# DVD angle (integer)
+#dvdnav-angle=1
+
+# Start directly in menu (boolean)
+#dvdnav-menu=1
+
+[shm] # Shared memory framebuffer
+
+# Frame rate (float)
+#shm-fps=10.000000
+
+# Frame buffer depth (integer)
+#shm-depth=0
+
+# Frame buffer width (integer)
+#shm-width=800
+
+# Frame buffer height (integer)
+#shm-height=480
+
+[satip] # SAT>IP Receiver Plugin
+
+# Receive buffer (integer)
+#satip-buffer=4194304
+
+# Request multicast stream (boolean)
+#satip-multicast=0
+
+# Host (string)
+#satip-host=
+
+[sftp] # SFTP input
+
+# SFTP port (integer)
+#sftp-port=22
+
+# Username (string)
+#sftp-user=
+
+# Password (string)
+#sftp-pwd=
+
+[rtp] # Real-Time Protocol (RTP) input
+
+# RTCP (local) port (integer)
+#rtcp-port=0
+
+# SRTP key (hexadecimal) (string)
+#srtp-key=
+
+# SRTP salt (hexadecimal) (string)
+#srtp-salt=
+
+# Maximum RTP sources (integer)
+#rtp-max-src=1
+
+# RTP source timeout (sec) (integer)
+#rtp-timeout=5
+
+# Maximum RTP sequence number dropout (integer)
+#rtp-max-dropout=3000
+
+# Maximum RTP sequence number misordering (integer)
+#rtp-max-misorder=100
+
+# RTP payload format assumed for dynamic payloads (string)
+#rtp-dynamic-pt=
+
+[stream_out_rtp] # RTP stream output
+
+# Destination (string)
+#sout-rtp-dst=
+
+# SDP (string)
+#sout-rtp-sdp=
+
+# Muxer (string)
+#sout-rtp-mux=
+
+# SAP announcing (boolean)
+#sout-rtp-sap=0
+
+# Session name (string)
+#sout-rtp-name=
+
+# Session category (string)
+#sout-rtp-cat=
+
+# Session description (string)
+#sout-rtp-description=
+
+# Session URL (string)
+#sout-rtp-url=
+
+# Session email (string)
+#sout-rtp-email=
+
+# Transport protocol (string)
+#sout-rtp-proto=udp
+
+# Port (integer)
+#sout-rtp-port=5004
+
+# Audio port (integer)
+#sout-rtp-port-audio=0
+
+# Video port (integer)
+#sout-rtp-port-video=0
+
+# Hop limit (TTL) (integer)
+#sout-rtp-ttl=-1
+
+# RTP/RTCP multiplexing (boolean)
+#sout-rtp-rtcp-mux=0
+
+# Caching value (ms) (integer)
+#sout-rtp-caching=300
+
+# SRTP key (hexadecimal) (string)
+#sout-rtp-key=
+
+# SRTP salt (hexadecimal) (string)
+#sout-rtp-salt=
+
+# MP4A LATM (boolean)
+#sout-rtp-mp4a-latm=0
+
+# RTSP session timeout (s) (integer)
+#rtsp-timeout=60
+
+# Username (string)
+#sout-rtsp-user=
+
+# Password (string)
+#sout-rtsp-pwd=
+
+[display] # Display stream output
+
+# Enable audio (boolean)
+#sout-display-audio=1
+
+# Enable video (boolean)
+#sout-display-video=1
+
+# Delay (ms) (integer)
+#sout-display-delay=100
+
+[delay] # Delay a stream
+
+# Elementary Stream ID (integer)
+#sout-delay-id=0
+
+# Delay of the ES (ms) (integer)
+#sout-delay-delay=0
+
+[stream_out_chromaprint] # Chromaprint stream output
+
+# Duration of the fingerprinting (integer)
+#duration=90
+
+[stream_out_standard] # Standard stream output
+
+# Output access method (string)
+#sout-standard-access=
+
+# Output muxer (string)
+#sout-standard-mux=
+
+# Output destination (string)
+#sout-standard-dst=
+
+# Address to bind to (helper setting for dst) (string)
+#sout-standard-bind=
+
+# Filename for stream (helper setting for dst) (string)
+#sout-standard-path=
+
+# SAP announcing (boolean)
+#sout-standard-sap=0
+
+# Session name (string)
+#sout-standard-name=
+
+# Session description (string)
+#sout-standard-description=
+
+# Session URL (string)
+#sout-standard-url=
+
+# Session email (string)
+#sout-standard-email=
+
+[stats] # Writes statistic info about stream
+
+# Output file (string)
+#sout-stats-output=
+
+# Prefix to show on output line (string)
+#sout-stats-prefix=stats
+
+[setid] # Change the id of an elementary stream
+
+# Elementary Stream ID (integer)
+#sout-setid-id=0
+
+# New ES ID (integer)
+#sout-setid-new-id=0
+
+# Elementary Stream ID (integer)
+#sout-setlang-id=0
+
+# Language (string)
+#sout-setlang-lang=eng
+
+[bridge] # Bridge stream output
+
+# ID (integer)
+#sout-bridge-out-id=0
+
+# Destination bridge-in name (string)
+#sout-bridge-out-in-name=default
+
+# Delay (integer)
+#sout-bridge-in-delay=0
+
+# ID Offset (integer)
+#sout-bridge-in-id-offset=8192
+
+# Name of current instance (string)
+#sout-bridge-in-name=default
+
+# Fallback to placeholder stream when out of data (boolean)
+#sout-bridge-in-placeholder=0
+
+# Placeholder delay (integer)
+#sout-bridge-in-placeholder-delay=200
+
+# Wait for I frame before toggling placeholder (boolean)
+#sout-bridge-in-placeholder-switch-on-iframe=1
+
+[es] # Elementary stream output
+
+# Output access method (string)
+#sout-es-access=
+
+# Output muxer (string)
+#sout-es-mux=
+
+# Output URL (string)
+#sout-es-dst=
+
+# Audio output access method (string)
+#sout-es-access-audio=
+
+# Audio output muxer (string)
+#sout-es-mux-audio=
+
+# Audio output URL (string)
+#sout-es-dst-audio=
+
+# Video output access method (string)
+#sout-es-access-video=
+
+# Video output muxer (string)
+#sout-es-mux-video=
+
+# Video output URL (string)
+#sout-es-dst-video=
+
+[stream_out_transcode] # Transcode stream output
+
+# Video encoder (string)
+#sout-transcode-venc=
+
+# Destination video codec (string)
+#sout-transcode-vcodec=
+
+# Video bitrate (integer)
+#sout-transcode-vb=0
+
+# Video scaling (float)
+#sout-transcode-scale=0.000000
+
+# Video frame-rate (string)
+#sout-transcode-fps=
+
+# Deinterlace video (boolean)
+#sout-transcode-deinterlace=0
+
+# Deinterlace module (string)
+#sout-transcode-deinterlace-module=deinterlace
+
+# Video width (integer)
+#sout-transcode-width=0
+
+# Video height (integer)
+#sout-transcode-height=0
+
+# Maximum video width (integer)
+#sout-transcode-maxwidth=0
+
+# Maximum video height (integer)
+#sout-transcode-maxheight=0
+
+# Video filter (string)
+#sout-transcode-vfilter=
+
+# Audio encoder (string)
+#sout-transcode-aenc=
+
+# Destination audio codec (string)
+#sout-transcode-acodec=
+
+# Audio bitrate (integer)
+#sout-transcode-ab=96
+
+# Audio language (string)
+#sout-transcode-alang=
+
+# Audio channels (integer)
+#sout-transcode-channels=0
+
+# Audio sample rate (integer)
+#sout-transcode-samplerate=0
+
+# Audio filter (string)
+#sout-transcode-afilter=
+
+# Subtitle encoder (string)
+#sout-transcode-senc=
+
+# Destination subtitle codec (string)
+#sout-transcode-scodec=
+
+# Destination subtitle codec (boolean)
+#sout-transcode-soverlay=0
+
+# Overlays (string)
+#sout-transcode-sfilter=
+
+# Number of threads (integer)
+#sout-transcode-threads=0
+
+# Picture pool size (integer)
+#sout-transcode-pool-size=10
+
+# High priority (boolean)
+#sout-transcode-high-priority=0
+
+[mosaic_bridge] # Mosaic bridge stream output
+
+# ID (string)
+#sout-mosaic-bridge-id=Id
+
+# Video width (integer)
+#sout-mosaic-bridge-width=0
+
+# Video height (integer)
+#sout-mosaic-bridge-height=0
+
+# Sample aspect ratio (string)
+#sout-mosaic-bridge-sar=1:1
+
+# Image chroma (string)
+#sout-mosaic-bridge-chroma=
+
+# Video filter (string)
+#sout-mosaic-bridge-vfilter=
+
+# Transparency (integer)
+#sout-mosaic-bridge-alpha=255
+
+# X offset (integer)
+#sout-mosaic-bridge-x=-1
+
+# Y offset (integer)
+#sout-mosaic-bridge-y=-1
+
+[record] # Record stream output
+
+# Destination prefix (string)
+#sout-record-dst-prefix=
+
+[smem] # Stream output to memory buffer
+
+# Time Synchronized output (boolean)
+#sout-smem-time-sync=1
+
+[stream_out_chromecast] # Chromecast stream output
+
+# ? (string)
+#sout-chromecast-ip=
+
+# ? (integer)
+#sout-chromecast-port=8009
+
+# ? (boolean)
+#sout-chromecast-video=1
+
+# HTTP port (integer)
+#sout-chromecast-http-port=8010
+
+# Performance warning (integer)
+#sout-chromecast-show-perf-warning=1
+
+# Enable Audio passthrough (boolean)
+#sout-chromecast-audio-passthrough=0
+
+# Conversion quality (integer)
+#sout-chromecast-conversion-quality=1
+
+[lua] # Lua interpreter
+
+# Lua interface (string)
+#lua-intf=dummy
+
+# Lua interface configuration (string)
+#lua-config=
+
+# Password (string)
+#http-password=
+
+# Source directory (string)
+#http-src=
+
+# Directory index (boolean)
+#http-index=0
+
+# TCP command input (string)
+#rc-host=
+
+# CLI input (string)
+#cli-host=
+
+# Host (string)
+#telnet-host=localhost
+
+# Port (integer)
+#telnet-port=4212
+
+# Password (string)
+#telnet-password=
+
+[mux_ts] # TS muxer (libdvbpsi)
+
+# Digital TV Standard (string)
+#sout-ts-standard=dvb
+
+# Video PID (integer)
+#sout-ts-pid-video=100
+
+# Audio PID (integer)
+#sout-ts-pid-audio=200
+
+# SPU PID (integer)
+#sout-ts-pid-spu=300
+
+# PMT PID (integer)
+#sout-ts-pid-pmt=32
+
+# TS ID (integer)
+#sout-ts-tsid=0
+
+# NET ID (integer)
+#sout-ts-netid=0
+
+# PMT Program numbers (string)
+#sout-ts-program-pmt=
+
+# Set PID to ID of ES (boolean)
+#sout-ts-es-id-pid=0
+
+# Mux PMT (requires --sout-ts-es-id-pid) (string)
+#sout-ts-muxpmt=
+
+# SDT Descriptors (requires --sout-ts-es-id-pid) (string)
+#sout-ts-sdtdesc=
+
+# Data alignment (boolean)
+#sout-ts-alignment=1
+
+# Shaping delay (ms) (integer)
+#sout-ts-shaping=200
+
+# Use keyframes (boolean)
+#sout-ts-use-key-frames=0
+
+# PCR interval (ms) (integer)
+#sout-ts-pcr=70
+
+# Minimum B (deprecated) (integer)
+#sout-ts-bmin=0
+
+# Maximum B (deprecated) (integer)
+#sout-ts-bmax=0
+
+# DTS delay (ms) (integer)
+#sout-ts-dts-delay=400
+
+# Crypt audio (boolean)
+#sout-ts-crypt-audio=1
+
+# Crypt video (boolean)
+#sout-ts-crypt-video=1
+
+# CSA Key (string)
+#sout-ts-csa-ck=
+
+# Second CSA Key (string)
+#sout-ts-csa2-ck=
+
+# CSA Key in use (string)
+#sout-ts-csa-use=1
+
+# Packet size in bytes to encrypt (integer)
+#sout-ts-csa-pkt=188
+
+[mux_ogg] # Ogg/OGM muxer
+
+# Index interval (integer)
+#sout-ogg-indexintvl=1000
+
+# Index size ratio (float)
+#sout-ogg-indexratio=1.000000
+
+[avi] # AVI muxer
+
+# Artist (string)
+#sout-avi-artist=
+
+# Date (string)
+#sout-avi-date=
+
+# Genre (string)
+#sout-avi-genre=
+
+# Copyright (string)
+#sout-avi-copyright=
+
+# Comment (string)
+#sout-avi-comment=
+
+# Name (string)
+#sout-avi-name=
+
+# Subject (string)
+#sout-avi-subject=
+
+# Encoder (string)
+#sout-avi-encoder=VLC Media Player - 3.0.16 Vetinari
+
+# Keywords (string)
+#sout-avi-keywords=
+
+[ps] # PS muxer
+
+# DTS delay (ms) (integer)
+#sout-ps-dts-delay=200
+
+# PES maximum size (integer)
+#sout-ps-pes-max-size=65500
+
+[asf] # ASF muxer
+
+# Title (string)
+#sout-asf-title=
+
+# Author (string)
+#sout-asf-author=
+
+# Copyright (string)
+#sout-asf-copyright=
+
+# Comment (string)
+#sout-asf-comment=
+
+# Rating (string)
+#sout-asf-rating=
+
+# Packet Size (integer)
+#sout-asf-packet-size=4096
+
+# Bitrate override (integer)
+#sout-asf-bitrate-override=0
+
+[mp4] # MP4/MOV muxer
+
+# Create "Fast Start" files (boolean)
+#sout-mp4-faststart=1
+
+[access_output_livehttp] # HTTP Live streaming output
+
+# Segment length (integer)
+#sout-livehttp-seglen=10
+
+# Number of segments (integer)
+#sout-livehttp-numsegs=0
+
+# Number of first segment (integer)
+#sout-livehttp-initial-segment-number=1
+
+# Split segments anywhere (boolean)
+#sout-livehttp-splitanywhere=0
+
+# Delete segments (boolean)
+#sout-livehttp-delsegs=1
+
+# Use muxers rate control mechanism (boolean)
+#sout-livehttp-ratecontrol=0
+
+# Allow cache (boolean)
+#sout-livehttp-caching=0
+
+# Use randomized IV for encryption (boolean)
+#sout-livehttp-generate-iv=0
+
+# Index file (string)
+#sout-livehttp-index=
+
+# Full URL to put in index file (string)
+#sout-livehttp-index-url=
+
+# AES key URI to place in playlist (string)
+#sout-livehttp-key-uri=
+
+# AES key file (string)
+#sout-livehttp-key-file=
+
+# File where vlc reads key-uri and keyfile-location (string)
+#sout-livehttp-key-loadfile=
+
+[access_output_rist] # RIST stream output
+
+# RIST target packet size (bytes) (integer)
+#sout-rist-packet-size=1328
+
+# RIST data output caching size (ms) (integer)
+#sout-rist-caching=50
+
+# RIST retry-buffer queue size (ms) (integer)
+#sout-rist-buffer-size=0
+
+# SSRC used in RTP output (default is random, i.e. 0) (integer)
+#sout-rist-ssrc=0
+
+# Stream name (string)
+#sout-rist-stream-name=
+
+[udp] # UDP stream output
+
+# Caching value (ms) (integer)
+#sout-udp-caching=300
+
+# Group packets (integer)
+#sout-udp-group=1
+
+[access_output_shout] # IceCAST output
+
+# Stream name (string)
+#sout-shout-name=VLC media player - Live stream
+
+# Stream description (string)
+#sout-shout-description=Live stream from VLC media player
+
+# Stream MP3 (boolean)
+#sout-shout-mp3=0
+
+# Genre description (string)
+#sout-shout-genre=Alternative
+
+# URL description (string)
+#sout-shout-url=http://www.videolan.org/vlc
+
+# Bitrate (string)
+#sout-shout-bitrate=
+
+# Samplerate (string)
+#sout-shout-samplerate=
+
+# Number of channels (string)
+#sout-shout-channels=
+
+# Ogg Vorbis Quality (string)
+#sout-shout-quality=
+
+# Stream public (boolean)
+#sout-shout-public=0
+
+[http] # HTTP stream output
+
+# Username (string)
+#sout-http-user=
+
+# Password (string)
+#sout-http-pwd=
+
+# Mime (string)
+#sout-http-mime=
+
+# Metacube (boolean)
+#sout-http-metacube=0
+
+[file] # File stream output
+
+# Overwrite existing file (boolean)
+#sout-file-overwrite=1
+
+# Append to file (boolean)
+#sout-file-append=0
+
+# Format time and date (boolean)
+#sout-file-format=0
+
+# Synchronous writing (boolean)
+#sout-file-sync=0
+
+[panoramix] # Panoramix: wall with overlap video filter
+
+# Number of columns (integer)
+#panoramix-cols=-1
+
+# Number of rows (integer)
+#panoramix-rows=-1
+
+# length of the overlapping area (in %) (integer)
+#panoramix-bz-length=100
+
+# height of the overlapping area (in %) (integer)
+#panoramix-bz-height=100
+
+# Attenuation (boolean)
+#panoramix-attenuate=1
+
+# Attenuation, begin (in %) (integer)
+#panoramix-bz-begin=0
+
+# Attenuation, middle (in %) (integer)
+#panoramix-bz-middle=50
+
+# Attenuation, end (in %) (integer)
+#panoramix-bz-end=100
+
+# middle position (in %) (integer)
+#panoramix-bz-middle-pos=50
+
+# Gamma (Red) correction (float)
+#panoramix-bz-gamma-red=1.000000
+
+# Gamma (Green) correction (float)
+#panoramix-bz-gamma-green=1.000000
+
+# Gamma (Blue) correction (float)
+#panoramix-bz-gamma-blue=1.000000
+
+# Black Crush for Red (integer)
+#panoramix-bz-blackcrush-red=140
+
+# Black Crush for Green (integer)
+#panoramix-bz-blackcrush-green=140
+
+# Black Crush for Blue (integer)
+#panoramix-bz-blackcrush-blue=140
+
+# White Crush for Red (integer)
+#panoramix-bz-whitecrush-red=200
+
+# White Crush for Green (integer)
+#panoramix-bz-whitecrush-green=200
+
+# White Crush for Blue (integer)
+#panoramix-bz-whitecrush-blue=200
+
+# Black Level for Red (integer)
+#panoramix-bz-blacklevel-red=150
+
+# Black Level for Green (integer)
+#panoramix-bz-blacklevel-green=150
+
+# Black Level for Blue (integer)
+#panoramix-bz-blacklevel-blue=150
+
+# White Level for Red (integer)
+#panoramix-bz-whitelevel-red=0
+
+# White Level for Green (integer)
+#panoramix-bz-whitelevel-green=0
+
+# White Level for Blue (integer)
+#panoramix-bz-whitelevel-blue=0
+
+# Active windows (string)
+#panoramix-active=
+
+[clone] # Clone video filter
+
+# Number of clones (integer)
+#clone-count=2
+
+# Video output modules (string)
+#clone-vout-list=
+
+[wall] # Wall video filter
+
+# Number of columns (integer)
+#wall-cols=3
+
+# Number of rows (integer)
+#wall-rows=3
+
+# Active windows (string)
+#wall-active=
+
+# Element aspect ratio (string)
+#wall-element-aspect=16:9
+
+[fb] # GNU/Linux framebuffer video output
+
+# Framebuffer device (string)
+#fbdev=/dev/fb0
+
+# Run fb on current tty (boolean)
+#fb-tty=1
+
+# Image format (default RGB) (string)
+#fb-chroma=
+
+# Framebuffer resolution to use (integer)
+#fb-mode=4
+
+# Framebuffer uses hw acceleration (boolean)
+#fb-hw-accel=1
+
+[gles2] # OpenGL for Embedded Systems 2 video output
+
+# OpenGL ES 2 extension (string)
+#gles2=
+
+# Open GL/GLES hardware converter (string)
+#glconv=
+
+# Rendering intent for color conversion (integer)
+#rendering-intent=1
+
+# Display primaries (integer)
+#target-prim=0
+
+# Display gamma / transfer function (integer)
+#target-trc=0
+
+# Tone-mapping algorithm (integer)
+#tone-mapping=3
+
+# Tone-mapping parameter (float)
+#tone-mapping-param=0.000000
+
+# Highlight clipped pixels (boolean)
+#tone-mapping-warn=0
+
+# Dithering algorithm (integer)
+#dither-algo=-1
+
+# Dither depth override (0 = framebuffer depth) (integer)
+#dither-depth=0
+
+# Desaturation strength (float)
+#desat-strength=0.750000
+
+# Desaturation exponent (float)
+#desat-exponent=1.500000
+
+# Desaturation base (float)
+#desat-base=0.180000
+
+# Maximum brightness boost (float)
+#max-boost=0.000000
+
+[xcb_window] # X11 video window (XCB)
+
+# X11 display (string)
+#x11-display=
+
+[flaschen] # Flaschen-Taschen video output
+
+# Flaschen-Taschen display address (string)
+#flaschen-display=
+
+# Width (integer)
+#flaschen-width=25
+
+# Height (integer)
+#flaschen-height=20
+
+[wl_shell] # Wayland shell surface
+
+# Wayland display (string)
+#wl-display=
+
+[yuv] # YUV video output
+
+# device, fifo or filename (string)
+#yuv-file=stream.yuv
+
+# Chroma used (string)
+#yuv-chroma=
+
+# Add a YUV4MPEG2 header (boolean)
+#yuv-yuv4mpeg2=0
+
+[vdummy] # Dummy video output
+
+# Dummy image chroma format (string)
+#dummy-chroma=
+
+[vmem] # Video memory output
+
+# Width (integer)
+#vmem-width=320
+
+# Height (integer)
+#vmem-height=200
+
+# Pitch (integer)
+#vmem-pitch=640
+
+# Chroma (string)
+#vmem-chroma=RV16
+
+[xcb_xv] # XVideo output (XCB)
+
+# XVideo adaptor number (integer)
+#xvideo-adaptor=-1
+
+# XVideo format id (integer)
+#xvideo-format-id=0
+
+[xcb_x11] # X11 video output (XCB)
+
+[gl] # OpenGL video output
+
+# OpenGL extension (string)
+#gl=
+
+# Open GL/GLES hardware converter (string)
+#glconv=
+
+# Rendering intent for color conversion (integer)
+#rendering-intent=1
+
+# Display primaries (integer)
+#target-prim=0
+
+# Display gamma / transfer function (integer)
+#target-trc=0
+
+# Tone-mapping algorithm (integer)
+#tone-mapping=3
+
+# Tone-mapping parameter (float)
+#tone-mapping-param=0.000000
+
+# Highlight clipped pixels (boolean)
+#tone-mapping-warn=0
+
+# Dithering algorithm (integer)
+#dither-algo=-1
+
+# Dither depth override (0 = framebuffer depth) (integer)
+#dither-depth=0
+
+# Desaturation strength (float)
+#desat-strength=0.750000
+
+# Desaturation exponent (float)
+#desat-exponent=1.500000
+
+# Desaturation base (float)
+#desat-base=0.180000
+
+# Maximum brightness boost (float)
+#max-boost=0.000000
+
+[xdg_shell] # XDG shell surface
+
+# Wayland display (string)
+#wl-display=
+
+[vdpau_chroma] # VDPAU surface conversions
+
+# Deinterlace (integer)
+#vdpau-deinterlace=1
+
+# Inverse telecine (boolean)
+#vdpau-ivtc=0
+
+# Deinterlace chroma skip (boolean)
+#vdpau-chroma-skip=0
+
+# Noise reduction level (float)
+#vdpau-noise-reduction=0.000000
+
+# Scaling quality (integer)
+#vdpau-scaling=0
+
+[twolame] # Libtwolame audio encoder
+
+# Encoding quality (float)
+#sout-twolame-quality=0.000000
+
+# Stereo mode (integer)
+#sout-twolame-mode=0
+
+# VBR mode (boolean)
+#sout-twolame-vbr=0
+
+# Psycho-acoustic model (integer)
+#sout-twolame-psy=3
+
+[subsdec] # Text subtitle decoder
+
+# Subtitle justification (integer)
+#subsdec-align=-1
+
+# Subtitle text encoding (string)
+#subsdec-encoding=
+
+# UTF-8 subtitle autodetection (boolean)
+#subsdec-autodetect-utf8=1
+
+[x26410b] # H.264/MPEG-4 Part 10/AVC encoder (x264 10-bit)
+
+# Maximum GOP size (integer)
+#sout-x26410b-keyint=250
+
+# Minimum GOP size (integer)
+#sout-x26410b-min-keyint=25
+
+# Use recovery points to close GOPs (boolean)
+#sout-x26410b-opengop=0
+
+# Enable compatibility hacks for Blu-ray support (boolean)
+#sout-x26410b-bluray-compat=0
+
+# Extra I-frames aggressivity (integer)
+#sout-x26410b-scenecut=40
+
+# B-frames between I and P (integer)
+#sout-x26410b-bframes=3
+
+# Adaptive B-frame decision (integer)
+#sout-x26410b-b-adapt=1
+
+# Influence (bias) B-frames usage (integer)
+#sout-x26410b-b-bias=0
+
+# Keep some B-frames as references (string)
+#sout-x26410b-bpyramid=normal
+
+# CABAC (boolean)
+#sout-x26410b-cabac=1
+
+# Use fullrange instead of TV colorrange (boolean)
+#sout-x26410b-fullrange=0
+
+# Number of reference frames (integer)
+#sout-x26410b-ref=3
+
+# Skip loop filter (boolean)
+#sout-x26410b-nf=0
+
+# Loop filter AlphaC0 and Beta parameters alpha:beta (string)
+#sout-x26410b-deblock=0:0
+
+# Strength of psychovisual optimization, default is "1.0:0.0" (string)
+#sout-x26410b-psy-rd=1.0:0.0
+
+# Use Psy-optimizations (boolean)
+#sout-x26410b-psy=1
+
+# H.264 level (string)
+#sout-x26410b-level=0
+
+# H.264 profile (string)
+#sout-x26410b-profile=high
+
+# Interlaced mode (boolean)
+#sout-x26410b-interlaced=0
+
+# Frame packing (integer)
+#sout-x26410b-frame-packing=-1
+
+# Force number of slices per frame (integer)
+#sout-x26410b-slices=0
+
+# Limit the size of each slice in bytes (integer)
+#sout-x26410b-slice-max-size=0
+
+# Limit the size of each slice in macroblocks (integer)
+#sout-x26410b-slice-max-mbs=0
+
+# HRD-timing information (string)
+#sout-x26410b-hrd=none
+
+# Set QP (integer)
+#sout-x26410b-qp=-1
+
+# Quality-based VBR (integer)
+#sout-x26410b-crf=23
+
+# Min QP (integer)
+#sout-x26410b-qpmin=10
+
+# Max QP (integer)
+#sout-x26410b-qpmax=51
+
+# Max QP step (integer)
+#sout-x26410b-qpstep=4
+
+# Average bitrate tolerance (float)
+#sout-x26410b-ratetol=1.000000
+
+# Max local bitrate (integer)
+#sout-x26410b-vbv-maxrate=0
+
+# VBV buffer (integer)
+#sout-x26410b-vbv-bufsize=0
+
+# Initial VBV buffer occupancy (float)
+#sout-x26410b-vbv-init=0.900000
+
+# QP factor between I and P (float)
+#sout-x26410b-ipratio=1.400000
+
+# QP factor between P and B (float)
+#sout-x26410b-pbratio=1.300000
+
+# QP difference between chroma and luma (integer)
+#sout-x26410b-chroma-qp-offset=0
+
+# Multipass ratecontrol (integer)
+#sout-x26410b-pass=0
+
+# QP curve compression (float)
+#sout-x26410b-qcomp=0.600000
+
+# Reduce fluctuations in QP (float)
+#sout-x26410b-cplxblur=20.000000
+
+# Reduce fluctuations in QP (float)
+#sout-x26410b-qblur=0.500000
+
+# How AQ distributes bits (integer)
+#sout-x26410b-aq-mode=1
+
+# Strength of AQ (float)
+#sout-x26410b-aq-strength=1.000000
+
+# Partitions to consider (string)
+#sout-x26410b-partitions=normal
+
+# Direct MV prediction mode (string)
+#sout-x26410b-direct=spatial
+
+# Direct prediction size (integer)
+#sout-x26410b-direct-8x8=1
+
+# Weighted prediction for B-frames (boolean)
+#sout-x26410b-weightb=1
+
+# Weighted prediction for P-frames (integer)
+#sout-x26410b-weightp=2
+
+# Integer pixel motion estimation method (string)
+#sout-x26410b-me=hex
+
+# Maximum motion vector search range (integer)
+#sout-x26410b-merange=16
+
+# Maximum motion vector length (integer)
+#sout-x26410b-mvrange=-1
+
+# Minimum buffer space between threads (integer)
+#sout-x26410b-mvrange-thread=-1
+
+# Subpixel motion estimation and partition decision quality (integer)
+#sout-x26410b-subme=7
+
+# Decide references on a per partition basis (boolean)
+#sout-x26410b-mixed-refs=1
+
+# Chroma in motion estimation (boolean)
+#sout-x26410b-chroma-me=1
+
+# Adaptive spatial transform size (boolean)
+#sout-x26410b-8x8dct=1
+
+# Trellis RD quantization (integer)
+#sout-x26410b-trellis=1
+
+# Framecount to use on frametype lookahead (integer)
+#sout-x26410b-lookahead=40
+
+# Use Periodic Intra Refresh (boolean)
+#sout-x26410b-intra-refresh=0
+
+# Use mb-tree ratecontrol (boolean)
+#sout-x26410b-mbtree=1
+
+# Early SKIP detection on P-frames (boolean)
+#sout-x26410b-fast-pskip=1
+
+# Coefficient thresholding on P-frames (boolean)
+#sout-x26410b-dct-decimate=1
+
+# Noise reduction (integer)
+#sout-x26410b-nr=0
+
+# Inter luma quantization deadzone (integer)
+#sout-x26410b-deadzone-inter=21
+
+# Intra luma quantization deadzone (integer)
+#sout-x26410b-deadzone-intra=11
+
+# Non-deterministic optimizations when threaded (boolean)
+#sout-x26410b-non-deterministic=0
+
+# CPU optimizations (boolean)
+#sout-x26410b-asm=1
+
+# PSNR computation (boolean)
+#sout-x26410b-psnr=0
+
+# SSIM computation (boolean)
+#sout-x26410b-ssim=0
+
+# Quiet mode (boolean)
+#sout-x26410b-quiet=0
+
+# SPS and PPS id numbers (integer)
+#sout-x26410b-sps-id=0
+
+# Access unit delimiters (boolean)
+#sout-x26410b-aud=0
+
+# Statistics (boolean)
+#sout-x26410b-verbose=0
+
+# Filename for 2 pass stats file (string)
+#sout-x26410b-stats=x264_2pass.log
+
+# Default preset setting used (string)
+#sout-x26410b-preset=
+
+# Default tune setting used (string)
+#sout-x26410b-tune=
+
+# x264 advanced options (string)
+#sout-x26410b-options=
+
+[zvbi] # VBI and Teletext decoder
+
+# Teletext page (integer)
+#vbi-page=100
+
+# Opacity (boolean)
+#vbi-opaque=0
+
+# Teletext alignment (integer)
+#vbi-position=8
+
+# Teletext text subtitles (boolean)
+#vbi-text=0
+
+# Presentation Level (integer)
+#vbi-level=3
+
+[theora] # Theora video decoder
+
+# Post processing quality (integer)
+#theora-postproc=-1
+
+# Encoding quality (integer)
+#sout-theora-quality=2
+
+[subsusf] # USF subtitles decoder
+
+# Formatted Subtitles (boolean)
+#subsdec-formatted=1
+
+[avcodec] # FFmpeg audio/video decoder
+
+# Direct rendering (boolean)
+#avcodec-dr=1
+
+# Show corrupted frames (boolean)
+#avcodec-corrupted=1
+
+# Error resilience (integer)
+#avcodec-error-resilience=1
+
+# Workaround bugs (integer)
+#avcodec-workaround-bugs=1
+
+# Hurry up (boolean)
+#avcodec-hurry-up=1
+
+# Skip frame (default=0) (integer)
+#avcodec-skip-frame=0
+
+# Skip idct (default=0) (integer)
+#avcodec-skip-idct=0
+
+# Allow speed tricks (boolean)
+#avcodec-fast=0
+
+# Skip the loop filter for H.264 decoding (integer)
+#avcodec-skiploopfilter=0
+
+# Debug mask (integer)
+#avcodec-debug=0
+
+# Codec name (string)
+#avcodec-codec=
+
+# Hardware decoding (string)
+#avcodec-hw=any
+
+# Threads (integer)
+#avcodec-threads=0
+
+# Advanced options (string)
+#avcodec-options=
+
+# Codec name (string)
+#sout-avcodec-codec=
+
+# Quality level (string)
+#sout-avcodec-hq=rd
+
+# Ratio of key frames (integer)
+#sout-avcodec-keyint=0
+
+# Ratio of B frames (integer)
+#sout-avcodec-bframes=0
+
+# Hurry up (boolean)
+#sout-avcodec-hurry-up=0
+
+# Interlaced encoding (boolean)
+#sout-avcodec-interlace=0
+
+# Interlaced motion estimation (boolean)
+#sout-avcodec-interlace-me=1
+
+# Video bitrate tolerance (integer)
+#sout-avcodec-vt=0
+
+# Pre-motion estimation (boolean)
+#sout-avcodec-pre-me=0
+
+# Rate control buffer size (integer)
+#sout-avcodec-rc-buffer-size=0
+
+# Rate control buffer aggressiveness (float)
+#sout-avcodec-rc-buffer-aggressivity=1.000000
+
+# I quantization factor (float)
+#sout-avcodec-i-quant-factor=0.000000
+
+# Noise reduction (integer)
+#sout-avcodec-noise-reduction=0
+
+# MPEG4 quantization matrix (boolean)
+#sout-avcodec-mpeg4-matrix=0
+
+# Minimum video quantizer scale (integer)
+#sout-avcodec-qmin=0
+
+# Maximum video quantizer scale (integer)
+#sout-avcodec-qmax=0
+
+# Trellis quantization (boolean)
+#sout-avcodec-trellis=0
+
+# Fixed quantizer scale (float)
+#sout-avcodec-qscale=3.000000
+
+# Strict standard compliance (integer)
+#sout-avcodec-strict=0
+
+# Luminance masking (float)
+#sout-avcodec-lumi-masking=0.000000
+
+# Darkness masking (float)
+#sout-avcodec-dark-masking=0.000000
+
+# Motion masking (float)
+#sout-avcodec-p-masking=0.000000
+
+# Border masking (float)
+#sout-avcodec-border-masking=0.000000
+
+# Luminance elimination (integer)
+#sout-avcodec-luma-elim-threshold=0
+
+# Chrominance elimination (integer)
+#sout-avcodec-chroma-elim-threshold=0
+
+# Specify AAC audio profile to use (string)
+#sout-avcodec-aac-profile=low
+
+# Advanced options (string)
+#sout-avcodec-options=
+
+[dvbsub] # DVB subtitles decoder
+
+# Subpicture position (integer)
+#dvbsub-position=8
+
+# Decoding X coordinate (integer)
+#dvbsub-x=-1
+
+# Decoding Y coordinate (integer)
+#dvbsub-y=-1
+
+# Encoding X coordinate (integer)
+#sout-dvbsub-x=-1
+
+# Encoding Y coordinate (integer)
+#sout-dvbsub-y=-1
+
+[vorbis] # Vorbis audio decoder
+
+# Encoding quality (integer)
+#sout-vorbis-quality=0
+
+# Maximum encoding bitrate (integer)
+#sout-vorbis-max-bitrate=0
+
+# Minimum encoding bitrate (integer)
+#sout-vorbis-min-bitrate=0
+
+# CBR encoding (boolean)
+#sout-vorbis-cbr=0
+
+[svcdsub] # Philips OGT (SVCD subtitle) decoder
+
+[cc] # Closed Captions decoder
+
+# Opacity (boolean)
+#cc-opaque=1
+
+[ddummy] # Dummy decoder
+
+# Save raw codec data (boolean)
+#dummy-save-es=0
+
+[ttml] # TTML subtitles decoder
+
+# Subtitle justification (integer)
+#ttml-align=0
+
+[spudec] # DVD subtitles decoder
+
+# Disable DVD subtitle transparency (boolean)
+#dvdsub-transparency=0
+
+[a52] # ATSC A/52 (AC-3) audio decoder
+
+# A/52 dynamic range compression (boolean)
+#a52-dynrng=1
+
+[dca] # DTS Coherent Acoustics audio decoder
+
+# DTS dynamic range compression (boolean)
+#dts-dynrng=1
+
+[speex] # Speex audio decoder
+
+# Mode (integer)
+#sout-speex-mode=0
+
+# Encoding complexity (integer)
+#sout-speex-complexity=3
+
+# CBR encoding (boolean)
+#sout-speex-cbr=0
+
+# Encoding quality (float)
+#sout-speex-quality=8.000000
+
+# Maximal bitrate (integer)
+#sout-speex-max-bitrate=0
+
+# Voice activity detection (boolean)
+#sout-speex-vad=1
+
+# Discontinuous Transmission (boolean)
+#sout-speex-dtx=0
+
+[libass] # Subtitle renderers using libass
+
+# Additional fonts directory (string)
+#ssa-fontsdir=
+
+[x264] # H.264/MPEG-4 Part 10/AVC encoder (x264)
+
+# Maximum GOP size (integer)
+#sout-x264-keyint=250
+
+# Minimum GOP size (integer)
+#sout-x264-min-keyint=25
+
+# Use recovery points to close GOPs (boolean)
+#sout-x264-opengop=0
+
+# Enable compatibility hacks for Blu-ray support (boolean)
+#sout-x264-bluray-compat=0
+
+# Extra I-frames aggressivity (integer)
+#sout-x264-scenecut=40
+
+# B-frames between I and P (integer)
+#sout-x264-bframes=3
+
+# Adaptive B-frame decision (integer)
+#sout-x264-b-adapt=1
+
+# Influence (bias) B-frames usage (integer)
+#sout-x264-b-bias=0
+
+# Keep some B-frames as references (string)
+#sout-x264-bpyramid=normal
+
+# CABAC (boolean)
+#sout-x264-cabac=1
+
+# Use fullrange instead of TV colorrange (boolean)
+#sout-x264-fullrange=0
+
+# Number of reference frames (integer)
+#sout-x264-ref=3
+
+# Skip loop filter (boolean)
+#sout-x264-nf=0
+
+# Loop filter AlphaC0 and Beta parameters alpha:beta (string)
+#sout-x264-deblock=0:0
+
+# Strength of psychovisual optimization, default is "1.0:0.0" (string)
+#sout-x264-psy-rd=1.0:0.0
+
+# Use Psy-optimizations (boolean)
+#sout-x264-psy=1
+
+# H.264 level (string)
+#sout-x264-level=0
+
+# H.264 profile (string)
+#sout-x264-profile=high
+
+# Interlaced mode (boolean)
+#sout-x264-interlaced=0
+
+# Frame packing (integer)
+#sout-x264-frame-packing=-1
+
+# Force number of slices per frame (integer)
+#sout-x264-slices=0
+
+# Limit the size of each slice in bytes (integer)
+#sout-x264-slice-max-size=0
+
+# Limit the size of each slice in macroblocks (integer)
+#sout-x264-slice-max-mbs=0
+
+# HRD-timing information (string)
+#sout-x264-hrd=none
+
+# Set QP (integer)
+#sout-x264-qp=-1
+
+# Quality-based VBR (integer)
+#sout-x264-crf=23
+
+# Min QP (integer)
+#sout-x264-qpmin=10
+
+# Max QP (integer)
+#sout-x264-qpmax=51
+
+# Max QP step (integer)
+#sout-x264-qpstep=4
+
+# Average bitrate tolerance (float)
+#sout-x264-ratetol=1.000000
+
+# Max local bitrate (integer)
+#sout-x264-vbv-maxrate=0
+
+# VBV buffer (integer)
+#sout-x264-vbv-bufsize=0
+
+# Initial VBV buffer occupancy (float)
+#sout-x264-vbv-init=0.900000
+
+# QP factor between I and P (float)
+#sout-x264-ipratio=1.400000
+
+# QP factor between P and B (float)
+#sout-x264-pbratio=1.300000
+
+# QP difference between chroma and luma (integer)
+#sout-x264-chroma-qp-offset=0
+
+# Multipass ratecontrol (integer)
+#sout-x264-pass=0
+
+# QP curve compression (float)
+#sout-x264-qcomp=0.600000
+
+# Reduce fluctuations in QP (float)
+#sout-x264-cplxblur=20.000000
+
+# Reduce fluctuations in QP (float)
+#sout-x264-qblur=0.500000
+
+# How AQ distributes bits (integer)
+#sout-x264-aq-mode=1
+
+# Strength of AQ (float)
+#sout-x264-aq-strength=1.000000
+
+# Partitions to consider (string)
+#sout-x264-partitions=normal
+
+# Direct MV prediction mode (string)
+#sout-x264-direct=spatial
+
+# Direct prediction size (integer)
+#sout-x264-direct-8x8=1
+
+# Weighted prediction for B-frames (boolean)
+#sout-x264-weightb=1
+
+# Weighted prediction for P-frames (integer)
+#sout-x264-weightp=2
+
+# Integer pixel motion estimation method (string)
+#sout-x264-me=hex
+
+# Maximum motion vector search range (integer)
+#sout-x264-merange=16
+
+# Maximum motion vector length (integer)
+#sout-x264-mvrange=-1
+
+# Minimum buffer space between threads (integer)
+#sout-x264-mvrange-thread=-1
+
+# Subpixel motion estimation and partition decision quality (integer)
+#sout-x264-subme=7
+
+# Decide references on a per partition basis (boolean)
+#sout-x264-mixed-refs=1
+
+# Chroma in motion estimation (boolean)
+#sout-x264-chroma-me=1
+
+# Adaptive spatial transform size (boolean)
+#sout-x264-8x8dct=1
+
+# Trellis RD quantization (integer)
+#sout-x264-trellis=1
+
+# Framecount to use on frametype lookahead (integer)
+#sout-x264-lookahead=40
+
+# Use Periodic Intra Refresh (boolean)
+#sout-x264-intra-refresh=0
+
+# Use mb-tree ratecontrol (boolean)
+#sout-x264-mbtree=1
+
+# Early SKIP detection on P-frames (boolean)
+#sout-x264-fast-pskip=1
+
+# Coefficient thresholding on P-frames (boolean)
+#sout-x264-dct-decimate=1
+
+# Noise reduction (integer)
+#sout-x264-nr=0
+
+# Inter luma quantization deadzone (integer)
+#sout-x264-deadzone-inter=21
+
+# Intra luma quantization deadzone (integer)
+#sout-x264-deadzone-intra=11
+
+# Non-deterministic optimizations when threaded (boolean)
+#sout-x264-non-deterministic=0
+
+# CPU optimizations (boolean)
+#sout-x264-asm=1
+
+# PSNR computation (boolean)
+#sout-x264-psnr=0
+
+# SSIM computation (boolean)
+#sout-x264-ssim=0
+
+# Quiet mode (boolean)
+#sout-x264-quiet=0
+
+# SPS and PPS id numbers (integer)
+#sout-x264-sps-id=0
+
+# Access unit delimiters (boolean)
+#sout-x264-aud=0
+
+# Statistics (boolean)
+#sout-x264-verbose=0
+
+# Filename for 2 pass stats file (string)
+#sout-x264-stats=x264_2pass.log
+
+# Default preset setting used (string)
+#sout-x264-preset=
+
+# Default tune setting used (string)
+#sout-x264-tune=
+
+# x264 advanced options (string)
+#sout-x264-options=
+
+[kate] # Kate overlay decoder
+
+# Formatted Subtitles (boolean)
+#kate-formatted=1
+
+[svgdec] # SVG video decoder
+
+# Image width (integer)
+#svg-width=-1
+
+# Image height (integer)
+#svg-height=-1
+
+# Scale factor (float)
+#svg-scale=-1.000000
+
+[jpeg] # JPEG image decoder
+
+# Quality level (integer)
+#sout-jpeg-quality=95
+
+[aribsub] # ARIB subtitles decoder
+
+# Ignore ruby (furigana) (boolean)
+#aribsub-ignore-ruby=0
+
+# Use Core Text renderer (boolean)
+#aribsub-use-coretext=0
+
+[dav1d] # Dav1d video decoder
+
+# Frames Threads (integer)
+#dav1d-thread-frames=0
+
+# Tiles Threads (integer)
+#dav1d-thread-tiles=0
+
+[swscale] # Video scaling filter
+
+# Scaling mode (integer)
+#swscale-mode=2
+
+[skins2] # Skinnable Interface
+
+# Skin to use (string)
+#skins2-last=
+
+# Config of last used skin (string)
+#skins2-config=
+
+# Enable transparency effects (boolean)
+#skins2-transparency=0
+
+# Use a skinned playlist (boolean)
+#skinned-playlist=1
+
+# Display video in a skinned window if any (boolean)
+#skinned-video=1
+
+[ncurses] # Ncurses interface
+
+# Filebrowser starting point (string)
+#browse-dir=
+
+[qt] # Qt interface
+
+# Start in minimal view (without menus) (boolean)
+#qt-minimal-view=0
+
+# Systray icon (boolean)
+#qt-system-tray=1
+
+# Show notification popup on track change (integer)
+#qt-notification=1
+
+# Start VLC with only a systray icon (boolean)
+#qt-start-minimized=0
+
+# Pause the video playback when minimized (boolean)
+#qt-pause-minimized=0
+
+# Windows opacity between 0.1 and 1 (float)
+#qt-opacity=1.000000
+
+# Fullscreen controller opacity between 0.1 and 1 (float)
+#qt-fs-opacity=0.800000
+
+# Resize interface to the native video size (boolean)
+#qt-video-autoresize=1
+
+# Show playing item name in window title (boolean)
+#qt-name-in-title=1
+
+# Show a controller in fullscreen mode (boolean)
+#qt-fs-controller=1
+
+# Save the recently played items in the menu (boolean)
+#qt-recentplay=1
+
+# List of words separated by | to filter (string)
+#qt-recentplay-filter=
+
+# Continue playback? (integer)
+#qt-continue=1
+
+# Embed the file browser in open dialog (boolean)
+#qt-embedded-open=0
+
+# Show advanced preferences over simple ones (boolean)
+#qt-advanced-pref=0
+
+# Show unimportant error and warnings dialogs (boolean)
+#qt-error-dialogs=1
+
+# Define the colors of the volume slider (string)
+#qt-slider-colours=153;210;153;20;210;20;255;199;15;245;39;29
+
+# Ask for network policy at start (boolean)
+qt-privacy-ask=0
+
+# Define which screen fullscreen goes (integer)
+#qt-fullscreen-screennumber=-1
+
+# Load extensions on startup (boolean)
+#qt-autoload-extensions=1
+
+# Display background cone or art (boolean)
+#qt-bgcone=1
+
+# Expanding background cone or art (boolean)
+#qt-bgcone-expands=0
+
+# Allow automatic icon changes (boolean)
+#qt-icon-change=1
+
+# Maximum Volume displayed (integer)
+#qt-max-volume=125
+
+# Fullscreen controller mouse sensitivity (integer)
+#qt-fs-sensitivity=3
+
+# When to raise the interface (integer)
+#qt-auto-raise=1
+
+[file] # Secrets are stored on a file without any encryption
+
+# ? (string)
+#keystore-file=
+
+[folder] # Folder meta data
+
+# Album art filename (string)
+#album-art-filename=
+
+[motion] # motion control interface
+
+[lirc] # Infrared remote control interface
+
+# Change the lirc configuration file (string)
+#lirc-file=
+
+[oldrc] # Remote control interface
+
+# Show stream position (boolean)
+#rc-show-pos=0
+
+# Fake TTY (boolean)
+#rc-fake-tty=0
+
+# UNIX socket command input (string)
+#rc-unix=
+
+# TCP command input (string)
+#rc-host=
+
+[netsync] # Network synchronization
+
+# Network master clock (boolean)
+#netsync-master=0
+
+# Master server IP address (string)
+#netsync-master-ip=
+
+# UDP timeout (in ms) (integer)
+#netsync-timeout=500
+
+[gestures] # Mouse gestures control interface
+
+# Motion threshold (10-100) (integer)
+#gestures-threshold=30
+
+# Trigger button (string)
+#gestures-button=left
+
+[vaapi_filters] # Video Accelerated API filters
+
+# Denoise strength (0-2) (float)
+#denoise-sigma=1.000000
+
+[alsa] # ALSA audio output
+
+# Audio output device (string)
+#alsa-audio-device=default
+
+# Audio output channels (integer)
+#alsa-audio-channels=6
+
+# Software gain (float)
+#alsa-gain=1.000000
+
+[afile] # File audio output
+
+# Output file (string)
+#audiofile-file=audiofile.wav
+
+# Output format (string)
+#audiofile-format=s16
+
+# Number of output channels (integer)
+#audiofile-channels=0
+
+# Add WAVE header (boolean)
+#audiofile-wav=1
+
+[amem] # Audio memory output
+
+# Sample format (string)
+#amem-format=S16N
+
+# Sample rate (integer)
+#amem-rate=44100
+
+# Channels count (integer)
+#amem-channels=2
+
+[notify] # LibNotify Notification Plugin
+
+# Timeout (ms) (integer)
+#notify-timeout=4000
+
+[rtsp] # Legacy RTSP VoD server
+
+# MUX for RAW RTSP transport (string)
+#rtsp-raw-mux=ts
+
+# Maximum number of connections (integer)
+#rtsp-throttle-users=0
+
+# Sets the timeout option in the RTSP session string (integer)
+#rtsp-session-timeout=5
+
+[logger] # File logging
+
+[gnutls] # GNU TLS transport layer security
+
+# Use system trust database (boolean)
+#gnutls-system-trust=1
+
+# Trust directory (string)
+#gnutls-dir-trust=
+
+# TLS cipher priorities (string)
+#gnutls-priorities=NORMAL
+
+[audioscrobbler] # Submission of played songs to last.fm
+
+# Username (string)
+#lastfm-username=
+
+# Password (string)
+#lastfm-password=
+
+# Scrobbler URL (string)
+#scrobbler-url=post.audioscrobbler.com
+
+[remoteosd] # Remote-OSD over VNC
+
+# VNC Host (string)
+#rmtosd-host=myvdr
+
+# VNC Port (integer)
+#rmtosd-port=20001
+
+# VNC Password (string)
+#rmtosd-password=
+
+# VNC poll interval (integer)
+#rmtosd-update=1000
+
+# VNC polling (boolean)
+#rmtosd-vnc-polling=0
+
+# Mouse events (boolean)
+#rmtosd-mouse-events=0
+
+# Key events (boolean)
+#rmtosd-key-events=0
+
+# Alpha transparency value (default 255) (integer)
+#rmtosd-alpha=255
+
+[dynamicoverlay] # Dynamic video overlay
+
+# Input FIFO (string)
+#overlay-input=
+
+# Output FIFO (string)
+#overlay-output=
+
+[logo] # Logo sub source
+
+# Logo filenames (string)
+#logo-file=
+
+# X coordinate (integer)
+#logo-x=-1
+
+# Y coordinate (integer)
+#logo-y=-1
+
+# Logo individual image time in ms (integer)
+#logo-delay=1000
+
+# Logo animation # of loops (integer)
+#logo-repeat=-1
+
+# Opacity of the logo (integer)
+#logo-opacity=255
+
+# Logo position (integer)
+#logo-position=-1
+
+[marq] # Marquee display
+
+# Text (string)
+#marq-marquee=VLC
+
+# Text file (string)
+#marq-file=
+
+# X offset (integer)
+#marq-x=0
+
+# Y offset (integer)
+#marq-y=0
+
+# Marquee position (integer)
+#marq-position=-1
+
+# Opacity (integer)
+#marq-opacity=255
+
+# Color (integer)
+#marq-color=16777215
+
+# Font size, pixels (integer)
+#marq-size=0
+
+# Timeout (integer)
+#marq-timeout=0
+
+# Refresh period in ms (integer)
+#marq-refresh=1000
+
+[mosaic] # Mosaic video sub source
+
+# Transparency (integer)
+#mosaic-alpha=255
+
+# Height (integer)
+#mosaic-height=100
+
+# Width (integer)
+#mosaic-width=100
+
+# Mosaic alignment (integer)
+#mosaic-align=5
+
+# Top left corner X coordinate (integer)
+#mosaic-xoffset=0
+
+# Top left corner Y coordinate (integer)
+#mosaic-yoffset=0
+
+# Border width (integer)
+#mosaic-borderw=0
+
+# Border height (integer)
+#mosaic-borderh=0
+
+# Positioning method (integer)
+#mosaic-position=0
+
+# Number of rows (integer)
+#mosaic-rows=2
+
+# Number of columns (integer)
+#mosaic-cols=2
+
+# Keep aspect ratio (boolean)
+#mosaic-keep-aspect-ratio=0
+
+# Keep original size (boolean)
+#mosaic-keep-picture=0
+
+# Elements order (string)
+#mosaic-order=
+
+# Offsets in order (string)
+#mosaic-offsets=
+
+# Delay (integer)
+#mosaic-delay=0
+
+[rss] # RSS and Atom feed display
+
+# Feed URLs (string)
+#rss-urls=
+
+# X offset (integer)
+#rss-x=0
+
+# Y offset (integer)
+#rss-y=0
+
+# Text position (integer)
+#rss-position=-1
+
+# Opacity (integer)
+#rss-opacity=255
+
+# Color (integer)
+#rss-color=16777215
+
+# Font size, pixels (integer)
+#rss-size=0
+
+# Speed of feeds (integer)
+#rss-speed=100000
+
+# Max length (integer)
+#rss-length=60
+
+# Refresh time (integer)
+#rss-ttl=1800
+
+# Feed images (boolean)
+#rss-images=1
+
+# Title display mode (integer)
+#rss-title=-1
+
+[subsdelay] # Subtitle delay
+
+# Delay calculation mode (integer)
+#subsdelay-mode=1
+
+# Calculation factor (float)
+#subsdelay-factor=2.000000
+
+# Maximum overlapping subtitles (integer)
+#subsdelay-overlap=3
+
+# Minimum alpha value (integer)
+#subsdelay-min-alpha=70
+
+# Interval between two disappearances (integer)
+#subsdelay-min-stops=1000
+
+# Interval between appearance and disappearance (integer)
+#subsdelay-min-start-stop=1000
+
+# Interval between disappearance and appearance (integer)
+#subsdelay-min-stop-start=1000
+
+[audiobargraph_v] # Audio Bar Graph Video sub source
+
+# X coordinate (integer)
+#audiobargraph_v-x=0
+
+# Y coordinate (integer)
+#audiobargraph_v-y=0
+
+# Transparency of the bargraph (integer)
+#audiobargraph_v-transparency=255
+
+# Bargraph position (integer)
+#audiobargraph_v-position=-1
+
+# Bar width in pixel (integer)
+#audiobargraph_v-barWidth=10
+
+# Bar Height in pixel (integer)
+#audiobargraph_v-barHeight=400
+
+[mpegvideo] # MPEG-I/II video packetizer
+
+# Sync on Intra Frame (boolean)
+#packetizer-mpegvideo-sync-iframe=0
+
+[freetype] # Freetype2 font renderer
+
+# Font (string)
+#freetype-font=Serif Bold
+
+# Monospace Font (string)
+#freetype-monofont=Monospace
+
+# Font size in pixels (integer)
+#freetype-fontsize=0
+
+# Relative font size (integer)
+#freetype-rel-fontsize=0
+
+# Text opacity (integer)
+#freetype-opacity=255
+
+# Text default color (integer)
+#freetype-color=16777215
+
+# Force bold (boolean)
+#freetype-bold=0
+
+# Background opacity (integer)
+#freetype-background-opacity=0
+
+# Background color (integer)
+#freetype-background-color=0
+
+# Outline opacity (integer)
+#freetype-outline-opacity=255
+
+# Outline color (integer)
+#freetype-outline-color=0
+
+# Outline thickness (integer)
+#freetype-outline-thickness=4
+
+# Shadow opacity (integer)
+#freetype-shadow-opacity=128
+
+# Shadow color (integer)
+#freetype-shadow-color=0
+
+# Shadow angle (float)
+#freetype-shadow-angle=-45.000000
+
+# Shadow distance (float)
+#freetype-shadow-distance=0.060000
+
+# Use YUVP renderer (boolean)
+#freetype-yuvp=0
+
+# Text direction (integer)
+#freetype-text-direction=0
+
+[core] # core program
+
+# Enable audio (boolean)
+#audio=1
+
+# Audio gain (float)
+#gain=1.000000
+
+# Audio output volume step (float)
+#volume-step=12.800000
+
+# Remember the audio volume (boolean)
+#volume-save=1
+
+# Force S/PDIF support (boolean)
+#spdif=0
+
+# Force detection of Dolby Surround (integer)
+#force-dolby-surround=0
+
+# Stereo audio output mode (integer)
+#stereo-mode=0
+
+# Audio desynchronization compensation (integer)
+#audio-desync=0
+
+# Replay gain mode (string)
+#audio-replay-gain-mode=none
+
+# Replay preamp (float)
+#audio-replay-gain-preamp=0.000000
+
+# Default replay gain (float)
+#audio-replay-gain-default=-7.000000
+
+# Peak protection (boolean)
+#audio-replay-gain-peak-protection=1
+
+# Enable time stretching audio (boolean)
+#audio-time-stretch=1
+
+# Audio output module (string)
+#aout=
+
+# Media role (string)
+#role=video
+
+# Audio filters (string)
+#audio-filter=
+
+# Audio visualizations (string)
+#audio-visual=none
+
+# Audio resampler (string)
+#audio-resampler=
+
+# Enable video (boolean)
+#video=1
+
+# Grayscale video output (boolean)
+#grayscale=0
+
+# Fullscreen video output (boolean)
+#fullscreen=0
+
+# Embedded video (boolean)
+#embedded-video=1
+
+# (boolean)
+#xlib=1
+
+# Drop late frames (boolean)
+#drop-late-frames=1
+
+# Skip frames (boolean)
+#skip-frames=1
+
+# Quiet synchro (boolean)
+#quiet-synchro=0
+
+# Key press events (boolean)
+#keyboard-events=1
+
+# Mouse events (boolean)
+#mouse-events=1
+
+# Always on top (boolean)
+#video-on-top=0
+
+# Enable wallpaper mode (boolean)
+#video-wallpaper=0
+
+# Disable screensaver (boolean)
+#disable-screensaver=1
+
+# Show media title on video (boolean)
+#video-title-show=1
+
+# Show video title for x milliseconds (integer)
+#video-title-timeout=5000
+
+# Position of video title (integer)
+#video-title-position=8
+
+# Hide cursor and fullscreen controller after x milliseconds (integer)
+#mouse-hide-timeout=1000
+
+# Video snapshot directory (or filename) (string)
+#snapshot-path=
+
+# Video snapshot file prefix (string)
+#snapshot-prefix=vlcsnap-
+
+# Video snapshot format (string)
+#snapshot-format=png
+
+# Display video snapshot preview (boolean)
+#snapshot-preview=1
+
+# Use sequential numbers instead of timestamps (boolean)
+#snapshot-sequential=0
+
+# Video snapshot width (integer)
+#snapshot-width=-1
+
+# Video snapshot height (integer)
+#snapshot-height=-1
+
+# Video width (integer)
+#width=-1
+
+# Video height (integer)
+#height=-1
+
+# Video X coordinate (integer)
+#video-x=0
+
+# Video Y coordinate (integer)
+#video-y=0
+
+# Video cropping (string)
+#crop=
+
+# Custom crop ratios list (string)
+#custom-crop-ratios=
+
+# Source aspect ratio (string)
+#aspect-ratio=
+
+# Video Auto Scaling (boolean)
+#autoscale=1
+
+# Monitor pixel aspect ratio (string)
+#monitor-par=
+
+# Custom aspect ratios list (string)
+#custom-aspect-ratios=
+
+# Fix HDTV height (boolean)
+#hdtv-fix=1
+
+# Window decorations (boolean)
+#video-deco=1
+
+# Video title (string)
+#video-title=
+
+# Video alignment (integer)
+#align=0
+
+# Zoom video (float)
+#zoom=1.000000
+
+# Deinterlace (integer)
+#deinterlace=-1
+
+# Deinterlace mode (string)
+#deinterlace-mode=auto
+
+# Video output module (string)
+#vout=
+
+# Video filter module (string)
+#video-filter=
+
+# Video splitter module (string)
+#video-splitter=
+
+# Enable sub-pictures (boolean)
+#spu=1
+
+# On Screen Display (boolean)
+#osd=1
+
+# Text rendering module (string)
+#text-renderer=
+
+# Use subtitle file (string)
+#sub-file=
+
+# Autodetect subtitle files (boolean)
+#sub-autodetect-file=1
+
+# Subtitle autodetection fuzziness (integer)
+#sub-autodetect-fuzzy=3
+
+# Subtitle autodetection paths (string)
+#sub-autodetect-path=./Subtitles, ./subtitles, ./Subs, ./subs
+
+# Force subtitle position (integer)
+#sub-margin=0
+
+# Subpictures source module (string)
+#sub-source=
+
+# Subpictures filter module (string)
+#sub-filter=
+
+# Program (integer)
+#program=0
+
+# Programs (string)
+#programs=
+
+# Audio track (integer)
+#audio-track=-1
+
+# Subtitle track (integer)
+#sub-track=-1
+
+# Audio language (string)
+#audio-language=
+
+# Subtitle language (string)
+#sub-language=
+
+# Menu language (string)
+#menu-language=
+
+# Audio track ID (integer)
+#audio-track-id=-1
+
+# Subtitle track ID (integer)
+#sub-track-id=-1
+
+# Preferred Closed Captions decoder (integer)
+#captions=608
+
+# Preferred video resolution (integer)
+#preferred-resolution=-1
+
+# Input repetitions (integer)
+#input-repeat=0
+
+# Start time (float)
+#start-time=0.000000
+
+# Stop time (float)
+#stop-time=0.000000
+
+# Run time (float)
+#run-time=0.000000
+
+# Fast seek (boolean)
+#input-fast-seek=0
+
+# Playback speed (float)
+#rate=1.000000
+
+# Input list (string)
+#input-list=
+
+# Input slave (experimental) (string)
+#input-slave=
+
+# Bookmarks list for a stream (string)
+#bookmarks=
+
+# DVD device (string)
+#dvd=/dev/sr0
+
+# VCD device (string)
+#vcd=/dev/sr0
+
+# MTU of the network interface (integer)
+#mtu=1400
+
+# TCP connection timeout (integer)
+#ipv4-timeout=5000
+
+# HTTP server address (string)
+#http-host=
+
+# HTTP server port (integer)
+#http-port=8080
+
+# HTTPS server port (integer)
+#https-port=8443
+
+# RTSP server address (string)
+#rtsp-host=
+
+# RTSP server port (integer)
+#rtsp-port=554
+
+# HTTP/TLS server certificate (string)
+#http-cert=
+
+# HTTP/TLS server private key (string)
+#http-key=
+
+# SOCKS server (string)
+#socks=
+
+# SOCKS user name (string)
+#socks-user=
+
+# SOCKS password (string)
+#socks-pwd=
+
+# Title metadata (string)
+#meta-title=
+
+# Author metadata (string)
+#meta-author=
+
+# Artist metadata (string)
+#meta-artist=
+
+# Genre metadata (string)
+#meta-genre=
+
+# Copyright metadata (string)
+#meta-copyright=
+
+# Description metadata (string)
+#meta-description=
+
+# Date metadata (string)
+#meta-date=
+
+# URL metadata (string)
+#meta-url=
+
+# File caching (ms) (integer)
+#file-caching=1000
+
+# Live capture caching (ms) (integer)
+#live-caching=300
+
+# Disc caching (ms) (integer)
+#disc-caching=300
+
+# Network caching (ms) (integer)
+#network-caching=1000
+
+# Clock reference average counter (integer)
+#cr-average=40
+
+# Clock synchronisation (integer)
+#clock-synchro=-1
+
+# Clock jitter (integer)
+#clock-jitter=5000
+
+# Network synchronisation (boolean)
+#network-synchronisation=0
+
+# Record directory (string)
+#input-record-path=
+
+# Prefer native stream recording (boolean)
+#input-record-native=1
+
+# Timeshift directory (string)
+#input-timeshift-path=
+
+# Timeshift granularity (integer)
+#input-timeshift-granularity=-1
+
+# Change title according to current media (string)
+#input-title-format=$Z
+
+# Disable all lua plugins (boolean)
+#lua=1
+
+# Preferred decoders list (string)
+#codec=
+
+# Preferred encoders list (string)
+#encoder=
+
+# Access module (string)
+#access=
+
+# Demux module (string)
+#demux=any
+
+# Stream filter module (string)
+#stream-filter=
+
+# Demux filter module (string)
+#demux-filter=
+
+# Default stream output chain (string)
+#sout=
+
+# Display while streaming (boolean)
+#sout-display=0
+
+# Keep stream output open (boolean)
+#sout-keep=0
+
+# Enable streaming of all ES (boolean)
+#sout-all=1
+
+# Enable audio stream output (boolean)
+#sout-audio=1
+
+# Enable video stream output (boolean)
+#sout-video=1
+
+# Enable SPU stream output (boolean)
+#sout-spu=1
+
+# Stream output muxer caching (ms) (integer)
+#sout-mux-caching=1500
+
+# VLM configuration file (string)
+#vlm-conf=
+
+# SAP announcement interval (integer)
+#sap-interval=5
+
+# Mux module (string)
+#mux=
+
+# Access output module (string)
+#access_output=
+
+# Hop limit (TTL) (integer)
+#ttl=-1
+
+# Multicast output interface (string)
+#miface=
+
+# DiffServ Code Point (integer)
+#dscp=0
+
+# Preferred packetizer list (string)
+#packetizer=
+
+# VoD server module (string)
+#vod-server=
+
+# Use a plugins cache (boolean)
+#plugins-cache=1
+
+# Scan for new plugins (boolean)
+#plugins-scan=1
+
+# Preferred keystore list (string)
+#keystore=
+
+# Allow real-time priority (boolean)
+#rt-priority=0
+
+# Adjust VLC priority (integer)
+#rt-offset=0
+
+# Play files randomly forever (boolean)
+#random=0
+
+# Repeat all (boolean)
+#loop=0
+
+# Repeat current item (boolean)
+#repeat=0
+
+# Play and exit (boolean)
+#play-and-exit=0
+
+# Play and stop (boolean)
+#play-and-stop=0
+
+# Play and pause (boolean)
+#play-and-pause=0
+
+# Start paused (boolean)
+#start-paused=0
+
+# Auto start (boolean)
+#playlist-autostart=1
+
+# Pause on audio communication (boolean)
+#playlist-cork=1
+
+# Allow only one running instance (boolean)
+#one-instance=0
+
+# Use only one instance when started from file manager (boolean)
+#one-instance-when-started-from-file=1
+
+# Enqueue items into playlist in one instance mode (boolean)
+#playlist-enqueue=0
+
+# Expose media player via D-Bus (boolean)
+#dbus=0
+
+# Use media library (boolean)
+#media-library=0
+
+# Display playlist tree (boolean)
+#playlist-tree=0
+
+# Default stream (string)
+#open=
+
+# Automatically preparse items (boolean)
+#auto-preparse=1
+
+# Preparsing timeout (integer)
+#preparse-timeout=5000
+
+# Allow metadata network access (boolean)
+#metadata-network-access=0
+
+# Subdirectory behavior (string)
+#recursive=collapse
+
+# Ignored extensions (string)
+#ignore-filetypes=m3u,db,nfo,ini,jpg,jpeg,ljpg,gif,png,pgm,pgmyuv,pbm,pam,tga,bmp,pnm,xpm,xcf,pcx,tif,tiff,lbm,sfv,txt,sub,idx,srt,cue,ssa
+
+# Show hidden files (boolean)
+#show-hiddenfiles=0
+
+# Services discovery modules (string)
+#services-discovery=
+
+# Run as daemon process (boolean)
+#daemon=0
+
+# Write process id to file (string)
+#pidfile=
+
+# Show advanced options (boolean)
+#advanced=0
+
+# Interface interaction (boolean)
+#interact=1
+
+# Locally collect statistics (boolean)
+#stats=1
+
+# Interface module (string)
+#intf=
+
+# Extra interface modules (string)
+#extraintf=
+
+# Control interfaces (string)
+#control=
+
+# Mouse wheel vertical axis control (integer)
+#hotkeys-y-wheel-mode=0
+
+# Mouse wheel horizontal axis control (integer)
+#hotkeys-x-wheel-mode=2
+
+# Fullscreen (string)
+#global-key-toggle-fullscreen=
+
+# Fullscreen (string)
+#key-toggle-fullscreen=f
+
+# Exit fullscreen (string)
+#global-key-leave-fullscreen=
+
+# Exit fullscreen (string)
+#key-leave-fullscreen=Esc
+
+# Play/Pause (string)
+#global-key-play-pause=
+
+# Play/Pause (string)
+#key-play-pause=Space Media Play Pause
+
+# Pause only (string)
+#global-key-pause=
+
+# Pause only (string)
+#key-pause=Browser Stop
+
+# Play only (string)
+#global-key-play=
+
+# Play only (string)
+#key-play=Browser Refresh
+
+# Faster (string)
+#global-key-faster=
+
+# Faster (string)
+#key-faster=+
+
+# Slower (string)
+#global-key-slower=
+
+# Slower (string)
+#key-slower=-
+
+# Normal rate (string)
+#global-key-rate-normal=
+
+# Normal rate (string)
+#key-rate-normal==
+
+# Faster (fine) (string)
+#global-key-rate-faster-fine=
+
+# Faster (fine) (string)
+#key-rate-faster-fine=]
+
+# Slower (fine) (string)
+#global-key-rate-slower-fine=
+
+# Slower (fine) (string)
+#key-rate-slower-fine=[
+
+# Next (string)
+#global-key-next=
+
+# Next (string)
+#key-next=n Media Next Track
+
+# Previous (string)
+#global-key-prev=
+
+# Previous (string)
+#key-prev=p Media Prev Track
+
+# Stop (string)
+#global-key-stop=
+
+# Stop (string)
+#key-stop=s Media Stop
+
+# Position (string)
+#global-key-position=
+
+# Position (string)
+#key-position=t
+
+# Very short backwards jump (string)
+#global-key-jump-extrashort=
+
+# Very short backwards jump (string)
+#key-jump-extrashort=Shift+Left
+
+# Very short forward jump (string)
+#global-key-jump+extrashort=
+
+# Very short forward jump (string)
+#key-jump+extrashort=Shift+Right
+
+# Short backwards jump (string)
+#global-key-jump-short=
+
+# Short backwards jump (string)
+#key-jump-short=Alt+Left
+
+# Short forward jump (string)
+#global-key-jump+short=
+
+# Short forward jump (string)
+#key-jump+short=Alt+Right
+
+# Medium backwards jump (string)
+#global-key-jump-medium=
+
+# Medium backwards jump (string)
+#key-jump-medium=Ctrl+Left
+
+# Medium forward jump (string)
+#global-key-jump+medium=
+
+# Medium forward jump (string)
+#key-jump+medium=Ctrl+Right
+
+# Long backwards jump (string)
+#global-key-jump-long=
+
+# Long backwards jump (string)
+#key-jump-long=Ctrl+Alt+Left
+
+# Long forward jump (string)
+#global-key-jump+long=
+
+# Long forward jump (string)
+#key-jump+long=Ctrl+Alt+Right
+
+# Next frame (string)
+#global-key-frame-next=
+
+# Next frame (string)
+#key-frame-next=e Browser Next
+
+# Activate (string)
+#global-key-nav-activate=
+
+# Activate (string)
+#key-nav-activate=Enter
+
+# Navigate up (string)
+#global-key-nav-up=
+
+# Navigate up (string)
+#key-nav-up=Up
+
+# Navigate down (string)
+#global-key-nav-down=
+
+# Navigate down (string)
+#key-nav-down=Down
+
+# Navigate left (string)
+#global-key-nav-left=
+
+# Navigate left (string)
+#key-nav-left=Left
+
+# Navigate right (string)
+#global-key-nav-right=
+
+# Navigate right (string)
+#key-nav-right=Right
+
+# Go to the DVD menu (string)
+#global-key-disc-menu=
+
+# Go to the DVD menu (string)
+#key-disc-menu=Shift+m
+
+# Select previous DVD title (string)
+#global-key-title-prev=
+
+# Select previous DVD title (string)
+#key-title-prev=Shift+o
+
+# Select next DVD title (string)
+#global-key-title-next=
+
+# Select next DVD title (string)
+#key-title-next=Shift+b
+
+# Select prev DVD chapter (string)
+#global-key-chapter-prev=
+
+# Select prev DVD chapter (string)
+#key-chapter-prev=Shift+p
+
+# Select next DVD chapter (string)
+#global-key-chapter-next=
+
+# Select next DVD chapter (string)
+#key-chapter-next=Shift+n
+
+# Quit (string)
+#global-key-quit=
+
+# Quit (string)
+#key-quit=Ctrl+q
+
+# Volume up (string)
+#global-key-vol-up=
+
+# Volume up (string)
+#key-vol-up=Ctrl+Up Volume Up
+
+# Volume down (string)
+#global-key-vol-down=
+
+# Volume down (string)
+#key-vol-down=Ctrl+Down Volume Down
+
+# Mute (string)
+#global-key-vol-mute=
+
+# Mute (string)
+#key-vol-mute=m Volume Mute
+
+# Subtitle delay up (string)
+#global-key-subdelay-up=
+
+# Subtitle delay up (string)
+#key-subdelay-up=h
+
+# Subtitle delay down (string)
+#global-key-subdelay-down=
+
+# Subtitle delay down (string)
+#key-subdelay-down=g
+
+# Subtitle sync / bookmark audio timestamp (string)
+#global-key-subsync-markaudio=
+
+# Subtitle sync / bookmark audio timestamp (string)
+#key-subsync-markaudio=Shift+h
+
+# Subtitle sync / bookmark subtitle timestamp (string)
+#global-key-subsync-marksub=
+
+# Subtitle sync / bookmark subtitle timestamp (string)
+#key-subsync-marksub=Shift+j
+
+# Subtitle sync / synchronize audio & subtitle timestamps (string)
+#global-key-subsync-apply=
+
+# Subtitle sync / synchronize audio & subtitle timestamps (string)
+#key-subsync-apply=Shift+k
+
+# Subtitle sync / reset audio & subtitle synchronization (string)
+#global-key-subsync-reset=
+
+# Subtitle sync / reset audio & subtitle synchronization (string)
+#key-subsync-reset=Ctrl+Shift+k
+
+# Subtitle position up (string)
+#global-key-subpos-up=
+
+# Subtitle position up (string)
+#key-subpos-up=
+
+# Subtitle position down (string)
+#global-key-subpos-down=
+
+# Subtitle position down (string)
+#key-subpos-down=
+
+# Audio delay up (string)
+#global-key-audiodelay-up=
+
+# Audio delay up (string)
+#key-audiodelay-up=k
+
+# Audio delay down (string)
+#global-key-audiodelay-down=
+
+# Audio delay down (string)
+#key-audiodelay-down=j
+
+# Cycle audio track (string)
+#global-key-audio-track=
+
+# Cycle audio track (string)
+#key-audio-track=b
+
+# Cycle through audio devices (string)
+#global-key-audiodevice-cycle=
+
+# Cycle through audio devices (string)
+#key-audiodevice-cycle=Shift+a
+
+# Cycle subtitle track in reverse order (string)
+#global-key-subtitle-revtrack=
+
+# Cycle subtitle track in reverse order (string)
+#key-subtitle-revtrack=Alt+v
+
+# Cycle subtitle track (string)
+#global-key-subtitle-track=
+
+# Cycle subtitle track (string)
+#key-subtitle-track=v
+
+# Toggle subtitles (string)
+#global-key-subtitle-toggle=
+
+# Toggle subtitles (string)
+#key-subtitle-toggle=Shift+v
+
+# Cycle next program Service ID (string)
+#global-key-program-sid-next=
+
+# Cycle next program Service ID (string)
+#key-program-sid-next=x
+
+# Cycle previous program Service ID (string)
+#global-key-program-sid-prev=
+
+# Cycle previous program Service ID (string)
+#key-program-sid-prev=Shift+x
+
+# Cycle source aspect ratio (string)
+#global-key-aspect-ratio=
+
+# Cycle source aspect ratio (string)
+#key-aspect-ratio=a
+
+# Cycle video crop (string)
+#global-key-crop=
+
+# Cycle video crop (string)
+#key-crop=c
+
+# Toggle autoscaling (string)
+#global-key-toggle-autoscale=
+
+# Toggle autoscaling (string)
+#key-toggle-autoscale=o
+
+# Increase scale factor (string)
+#global-key-incr-scalefactor=
+
+# Increase scale factor (string)
+#key-incr-scalefactor=Alt+o
+
+# Decrease scale factor (string)
+#global-key-decr-scalefactor=
+
+# Decrease scale factor (string)
+#key-decr-scalefactor=Alt+Shift+o
+
+# Toggle deinterlacing (string)
+#global-key-deinterlace=
+
+# Toggle deinterlacing (string)
+#key-deinterlace=d
+
+# Cycle deinterlace modes (string)
+#global-key-deinterlace-mode=
+
+# Cycle deinterlace modes (string)
+#key-deinterlace-mode=Shift+d
+
+# Show controller in fullscreen (string)
+#global-key-intf-show=
+
+# Show controller in fullscreen (string)
+#key-intf-show=i
+
+# Boss key (string)
+#global-key-intf-boss=
+
+# Boss key (string)
+#key-intf-boss=
+
+# Context menu (string)
+#global-key-intf-popup-menu=
+
+# Context menu (string)
+#key-intf-popup-menu=Menu
+
+# Take video snapshot (string)
+#global-key-snapshot=
+
+# Take video snapshot (string)
+#key-snapshot=Shift+s
+
+# Record (string)
+#global-key-record=
+
+# Record (string)
+#key-record=Shift+r
+
+# Zoom (string)
+#global-key-zoom=
+
+# Zoom (string)
+#key-zoom=z
+
+# Un-Zoom (string)
+#global-key-unzoom=
+
+# Un-Zoom (string)
+#key-unzoom=Shift+z
+
+# Toggle wallpaper mode in video output (string)
+#global-key-wallpaper=
+
+# Toggle wallpaper mode in video output (string)
+#key-wallpaper=w
+
+# Crop one pixel from the top of the video (string)
+#global-key-crop-top=
+
+# Crop one pixel from the top of the video (string)
+#key-crop-top=Alt+r
+
+# Uncrop one pixel from the top of the video (string)
+#global-key-uncrop-top=
+
+# Uncrop one pixel from the top of the video (string)
+#key-uncrop-top=Alt+Shift+r
+
+# Crop one pixel from the left of the video (string)
+#global-key-crop-left=
+
+# Crop one pixel from the left of the video (string)
+#key-crop-left=Alt+d
+
+# Uncrop one pixel from the left of the video (string)
+#global-key-uncrop-left=
+
+# Uncrop one pixel from the left of the video (string)
+#key-uncrop-left=Alt+Shift+d
+
+# Crop one pixel from the bottom of the video (string)
+#global-key-crop-bottom=
+
+# Crop one pixel from the bottom of the video (string)
+#key-crop-bottom=Alt+c
+
+# Uncrop one pixel from the bottom of the video (string)
+#global-key-uncrop-bottom=
+
+# Uncrop one pixel from the bottom of the video (string)
+#key-uncrop-bottom=Alt+Shift+c
+
+# Crop one pixel from the right of the video (string)
+#global-key-crop-right=
+
+# Crop one pixel from the right of the video (string)
+#key-crop-right=Alt+f
+
+# Uncrop one pixel from the right of the video (string)
+#global-key-uncrop-right=
+
+# Uncrop one pixel from the right of the video (string)
+#key-uncrop-right=Alt+Shift+f
+
+# Random (string)
+#global-key-random=
+
+# Random (string)
+#key-random=r
+
+# Normal/Loop/Repeat (string)
+#global-key-loop=
+
+# Normal/Loop/Repeat (string)
+#key-loop=l
+
+# Shrink the viewpoint field of view (360°) (string)
+#global-key-viewpoint-fov-in=
+
+# Shrink the viewpoint field of view (360°) (string)
+#key-viewpoint-fov-in=Page Up
+
+# Expand the viewpoint field of view (360°) (string)
+#global-key-viewpoint-fov-out=
+
+# Expand the viewpoint field of view (360°) (string)
+#key-viewpoint-fov-out=Page Down
+
+# Roll the viewpoint clockwise (360°) (string)
+#global-key-viewpoint-roll-clock=
+
+# Roll the viewpoint clockwise (360°) (string)
+#key-viewpoint-roll-clock=
+
+# Roll the viewpoint anti-clockwise (360°) (string)
+#global-key-viewpoint-roll-anticlock=
+
+# Roll the viewpoint anti-clockwise (360°) (string)
+#key-viewpoint-roll-anticlock=
+
+# 1:4 Quarter (string)
+#global-key-zoom-quarter=
+
+# 1:4 Quarter (string)
+#key-zoom-quarter=Alt+1
+
+# 1:2 Half (string)
+#global-key-zoom-half=
+
+# 1:2 Half (string)
+#key-zoom-half=Alt+2
+
+# 1:1 Original (string)
+#global-key-zoom-original=
+
+# 1:1 Original (string)
+#key-zoom-original=Alt+3
+
+# 2:1 Double (string)
+#global-key-zoom-double=
+
+# 2:1 Double (string)
+#key-zoom-double=Alt+4
+
+# Very short jump length (integer)
+#extrashort-jump-size=3
+
+# Short jump length (integer)
+#short-jump-size=10
+
+# Medium jump length (integer)
+#medium-jump-size=60
+
+# Long jump length (integer)
+#long-jump-size=300
+
+# Set playlist bookmark 1 (string)
+#global-key-set-bookmark1=
+
+# Set playlist bookmark 1 (string)
+#key-set-bookmark1=Ctrl+F1
+
+# Set playlist bookmark 2 (string)
+#global-key-set-bookmark2=
+
+# Set playlist bookmark 2 (string)
+#key-set-bookmark2=Ctrl+F2
+
+# Set playlist bookmark 3 (string)
+#global-key-set-bookmark3=
+
+# Set playlist bookmark 3 (string)
+#key-set-bookmark3=Ctrl+F3
+
+# Set playlist bookmark 4 (string)
+#global-key-set-bookmark4=
+
+# Set playlist bookmark 4 (string)
+#key-set-bookmark4=Ctrl+F4
+
+# Set playlist bookmark 5 (string)
+#global-key-set-bookmark5=
+
+# Set playlist bookmark 5 (string)
+#key-set-bookmark5=Ctrl+F5
+
+# Set playlist bookmark 6 (string)
+#global-key-set-bookmark6=
+
+# Set playlist bookmark 6 (string)
+#key-set-bookmark6=Ctrl+F6
+
+# Set playlist bookmark 7 (string)
+#global-key-set-bookmark7=
+
+# Set playlist bookmark 7 (string)
+#key-set-bookmark7=Ctrl+F7
+
+# Set playlist bookmark 8 (string)
+#global-key-set-bookmark8=
+
+# Set playlist bookmark 8 (string)
+#key-set-bookmark8=Ctrl+F8
+
+# Set playlist bookmark 9 (string)
+#global-key-set-bookmark9=
+
+# Set playlist bookmark 9 (string)
+#key-set-bookmark9=Ctrl+F9
+
+# Set playlist bookmark 10 (string)
+#global-key-set-bookmark10=
+
+# Set playlist bookmark 10 (string)
+#key-set-bookmark10=Ctrl+F10
+
+# Play playlist bookmark 1 (string)
+#global-key-play-bookmark1=
+
+# Play playlist bookmark 1 (string)
+#key-play-bookmark1=F1
+
+# Play playlist bookmark 2 (string)
+#global-key-play-bookmark2=
+
+# Play playlist bookmark 2 (string)
+#key-play-bookmark2=F2
+
+# Play playlist bookmark 3 (string)
+#global-key-play-bookmark3=
+
+# Play playlist bookmark 3 (string)
+#key-play-bookmark3=F3
+
+# Play playlist bookmark 4 (string)
+#global-key-play-bookmark4=
+
+# Play playlist bookmark 4 (string)
+#key-play-bookmark4=F4
+
+# Play playlist bookmark 5 (string)
+#global-key-play-bookmark5=
+
+# Play playlist bookmark 5 (string)
+#key-play-bookmark5=F5
+
+# Play playlist bookmark 6 (string)
+#global-key-play-bookmark6=
+
+# Play playlist bookmark 6 (string)
+#key-play-bookmark6=F6
+
+# Play playlist bookmark 7 (string)
+#global-key-play-bookmark7=
+
+# Play playlist bookmark 7 (string)
+#key-play-bookmark7=F7
+
+# Play playlist bookmark 8 (string)
+#global-key-play-bookmark8=
+
+# Play playlist bookmark 8 (string)
+#key-play-bookmark8=F8
+
+# Play playlist bookmark 9 (string)
+#global-key-play-bookmark9=
+
+# Play playlist bookmark 9 (string)
+#key-play-bookmark9=F9
+
+# Play playlist bookmark 10 (string)
+#global-key-play-bookmark10=
+
+# Play playlist bookmark 10 (string)
+#key-play-bookmark10=F10
+
+# Clear the playlist (string)
+#global-key-clear-playlist=
+
+# Clear the playlist (string)
+#key-clear-playlist=Ctrl+w
+
+# Reset subtitles text scale (string)
+#global-key-subtitle-text-scale-normal=
+
+# Reset subtitles text scale (string)
+#key-subtitle-text-scale-normal=Ctrl+0
+
+# Scale down subtitles text (string)
+#global-key-subtitle-text-scale-up=
+
+# Scale down subtitles text (string)
+#key-subtitle-text-scale-up=Ctrl+Mouse Wheel Up
+
+# Scale up subtitles text (string)
+#global-key-subtitle-text-scale-down=
+
+# Scale up subtitles text (string)
+#key-subtitle-text-scale-down=Ctrl+Mouse Wheel Down
+
+# Playlist bookmark 1 (string)
+#bookmark1=
+
+# Playlist bookmark 2 (string)
+#bookmark2=
+
+# Playlist bookmark 3 (string)
+#bookmark3=
+
+# Playlist bookmark 4 (string)
+#bookmark4=
+
+# Playlist bookmark 5 (string)
+#bookmark5=
+
+# Playlist bookmark 6 (string)
+#bookmark6=
+
+# Playlist bookmark 7 (string)
+#bookmark7=
+
+# Playlist bookmark 8 (string)
+#bookmark8=
+
+# Playlist bookmark 9 (string)
+#bookmark9=
+
+# Playlist bookmark 10 (string)
+#bookmark10=
+
diff --git a/waybar/config b/waybar/config
new file mode 100644
index 0000000..8be04aa
--- /dev/null
+++ b/waybar/config
@@ -0,0 +1,474 @@
+[{
+ "layer": "top", // Waybar at top layer
+ // "position": "bottom", // Waybar position (top|bottom|left|right)
+ "height": 20, // Waybar height (to be removed for auto height)
+ // "width": 1280, // Waybar width
+ // Choose the order of the modules
+ "output": "HDMI-A-1",
+ "modules-left": ["river/tags", "river/window", "custom/dwl_tag#0", "custom/dwl_tag#1", "custom/dwl_tag#2", "custom/dwl_tag#3", "custom/dwl_tag#4", "custom/dwl_tag#5", "custom/dwl_tag#6", "custom/dwl_tag#7", "custom/dwl_tag#8", "custom/dwl_layout", "custom/dwl_title"],
+ "modules-center": [],
+ "modules-right": ["custom/swayidle", "mpd", "pulseaudio", "network", "cpu", "memory", "backlight", "battery", "tray", "clock"],
+ // Modules configuration
+ // "sway/workspaces": {
+ // "disable-scroll": true,
+ // "all-outputs": true,
+ // "format": "{name}: {icon}",
+ // "format-icons": {
+ // "1": "",
+ // "2": "",
+ // "3": "",
+ // "4": "",
+ // "5": "",
+ // "urgent": "",
+ // "focused": "",
+ // "default": ""
+ // }
+ // },
+ "river/window": {
+ "max-length": 60
+ },
+ "custom/dwl_tag#0": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 0",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#1": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 1",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#2": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 2",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#3": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 3",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#4": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 4",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#5": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 5",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#6": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 6",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#7": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 7",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#8": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 8",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#9": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 9",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_layout": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 layout",
+ "format": "{}",
+ "escape": true,
+ "return-type": "json"
+ },
+ "custom/dwl_title": {
+ "exec": "~/.local/bin/waybar-dwl.sh HDMI-A-1 title",
+ "format": "{}",
+ "escape": true,
+ "return-type": "json"
+ },
+ "custom/swayidle": {
+ "exec": "~/.local/scripts/swayidlechk",
+ "signal": 8,
+ "interval": "once",
+ "format": " {} ",
+ "on-click": "~/.local/scripts/swayidletog"
+ },
+ "sway/mode": {
+ "format": "<span style=\"italic\">{}</span>"
+ },
+ "mpd": {
+ "signal": 7,
+ "server": "/home/zachir/.config/mpd/socket",
+ "format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist:.15} - {title:.15}",
+ // ({elapsedTime:%M:%S}/{totalTime:%M:%S})
+ "format-disconnected": "Disconnected",
+ "format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped",
+ "unknown-tag": "N/A",
+ "interval": 2,
+ "consume-icons": {
+ "on": "<span color=\"#dddddd\"></span> "
+ },
+ "random-icons": {
+ "off": " ",
+ "on": "<span color=\"#dddddd\"></span> "
+ },
+ "repeat-icons": {
+ "on": "<span color=\"#dddddd\"></span> "
+ },
+ "single-icons": {
+ "on": "<span color=\"#dddddd\">1</span> "
+ },
+ "state-icons": {
+ "paused": "",
+ "playing": "<span color=\"#dddddd\"></span>"
+ },
+ "tooltip-format": "MPD (connected)",
+ "tooltip-format-disconnected": "MPD (disconnected)",
+// "max-length": 50
+ },
+ "idle_inhibitor": {
+ "format": "{icon}",
+ "format-icons": {
+ "activated": "",
+ "deactivated": ""
+ }
+ },
+ "tray": {
+ // "icon-size": 21,
+ "spacing": 10
+ },
+ "clock": {
+ // "timezone": "America/New_York",
+ "tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
+ "format-alt": "{:%Y-%m-%d}"
+ },
+ "cpu": {
+ "format": "{usage}% ",
+ "tooltip": false
+ },
+ "memory": {
+ "format": "{}% "
+ },
+ "temperature": {
+ // "thermal-zone": 2,
+ // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
+ "critical-threshold": 80,
+ // "format-critical": "{temperatureC}°C {icon}",
+ "format": "{temperatureC}°C {icon}",
+ "format-icons": ["", "", ""]
+ },
+ "backlight": {
+ // "device": "acpi_video1",
+ "format": "{percent}% {icon}",
+ "format-icons": ["", ""]
+ },
+ "battery": {
+ "states": {
+ // "good": 95,
+ "warning": 30,
+ "critical": 15
+ },
+ "format": "{capacity}% {icon}",
+ "format-charging": "{capacity}% ",
+ "format-plugged": "{capacity}% ",
+ "format-alt": "{time} {icon}",
+ // "format-good": "", // An empty format will hide the module
+ // "format-full": "",
+ "format-icons": ["", "", "", "", ""]
+ },
+ "battery#bat2": {
+ "bat": "cw2015-battery",
+ "states": {
+ // "good": 95,
+ "warning": 30,
+ "critical": 15
+ },
+ "format": "{capacity}% {icon}",
+ "format-charging": "{capacity}% ",
+ "format-plugged": "{capacity}% ",
+ "format-alt": "{time} {icon}",
+ // "format-good": "", // An empty format will hide the module
+ // "format-full": "",
+ "format-icons": ["", "", "", "", ""]
+ },
+ "network": {
+ //"interface": "wl*", // (Optional) To force the use of this interface
+ "format-wifi": "{essid} ({signalStrength}%) ",
+ "format-ethernet": "{ifname}: {ipaddr}/{cidr} ",
+ "format-linked": "{ifname} (No IP) ",
+ "format-disconnected": "Disconnected ⚠",
+ "format-alt": "{ifname}: {ipaddr}/{cidr}",
+ "signal": 6
+ },
+ "pulseaudio": {
+ // "scroll-step": 1, // %, can be a float
+ "format": "{volume}% {icon} {format_source}",
+ "format-bluetooth": "{volume}% {icon} {format_source}",
+ "format-bluetooth-muted": " {icon} {format_source}",
+ "format-muted": " {format_source}",
+ "format-source": "{volume}% ",
+ "format-source-muted": "",
+ "format-icons": {
+ "headphone": "",
+ "hands-free": "",
+ "headset": "",
+ "phone": "",
+ "portable": "",
+ "car": "",
+ "default": ["", "", ""]
+ },
+ "on-click": "pavucontrol"
+ },
+ "custom/media": {
+ "format": "{icon} {}",
+ "return-type": "json",
+ "max-length": 40,
+ "format-icons": {
+ "spotify": "",
+ "default": "🎜"
+ },
+ "escape": true,
+ "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
+ // "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
+ }
+},
+{
+ "layer": "top", // Waybar at top layer
+ // "position": "bottom", // Waybar position (top|bottom|left|right)
+ "height": 20, // Waybar height (to be removed for auto height)
+ // "width": 1280, // Waybar width
+ // Choose the order of the modules
+ "output": "DP-1",
+ "modules-left": ["river/tags", "river/window", "custom/dwl_tag#0", "custom/dwl_tag#1", "custom/dwl_tag#2", "custom/dwl_tag#3", "custom/dwl_tag#4", "custom/dwl_tag#5", "custom/dwl_tag#6", "custom/dwl_tag#7", "custom/dwl_tag#8", "custom/dwl_layout", "custom/dwl_title"],
+ "modules-center": [],
+ "modules-right": ["custom/swayidle", "mpd", "pulseaudio", "network", "cpu", "memory", "backlight", "battery", "tray", "clock"],
+ // Modules configuration
+ // "sway/workspaces": {
+ // "disable-scroll": true,
+ // "all-outputs": true,
+ // "format": "{name}: {icon}",
+ // "format-icons": {
+ // "1": "",
+ // "2": "",
+ // "3": "",
+ // "4": "",
+ // "5": "",
+ // "urgent": "",
+ // "focused": "",
+ // "default": ""
+ // }
+ // },
+ "river/window": {
+ "max-length": 60
+ },
+ "custom/dwl_tag#0": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 0",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#1": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 1",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#2": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 2",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#3": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 3",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#4": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 4",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#5": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 5",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#6": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 6",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#7": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 7",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#8": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 8",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_tag#9": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 9",
+ "format": "{}",
+ "return-type": "json"
+ },
+ "custom/dwl_layout": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 layout",
+ "format": "{}",
+ "escape": true,
+ "return-type": "json"
+ },
+ "custom/dwl_title": {
+ "exec": "~/.local/bin/waybar-dwl.sh DP-1 title",
+ "format": "{}",
+ "escape": true,
+ "return-type": "json"
+ },
+ "custom/swayidle": {
+ "exec": "~/.local/scripts/swayidlechk",
+ "signal": 8,
+ "interval": "once",
+ "format": " {} ",
+ "on-click": "~/.local/scripts/swayidletog"
+ },
+ "sway/mode": {
+ "format": "<span style=\"italic\">{}</span>"
+ },
+ "mpd": {
+ "signal": 7,
+ "server": "/home/zachir/.config/mpd/socket",
+ "format": "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist:.15} - {title:.15}",
+ // ({elapsedTime:%M:%S}/{totalTime:%M:%S})
+ "format-disconnected": "Disconnected",
+ "format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped",
+ "unknown-tag": "N/A",
+ "interval": 2,
+ "consume-icons": {
+ "on": "<span color=\"#dddddd\"></span> "
+ },
+ "random-icons": {
+ "off": " ",
+ "on": "<span color=\"#dddddd\"></span> "
+ },
+ "repeat-icons": {
+ "on": "<span color=\"#dddddd\"></span> "
+ },
+ "single-icons": {
+ "on": "<span color=\"#dddddd\">1</span> "
+ },
+ "state-icons": {
+ "paused": "",
+ "playing": "<span color=\"#dddddd\"></span>"
+ },
+ "tooltip-format": "MPD (connected)",
+ "tooltip-format-disconnected": "MPD (disconnected)",
+// "max-length": 50
+ },
+ "idle_inhibitor": {
+ "format": "{icon}",
+ "format-icons": {
+ "activated": "",
+ "deactivated": ""
+ }
+ },
+ "tray": {
+ // "icon-size": 21,
+ "spacing": 10
+ },
+ "clock": {
+ // "timezone": "America/New_York",
+ "tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
+ "format-alt": "{:%Y-%m-%d}"
+ },
+ "cpu": {
+ "format": "{usage}% ",
+ "tooltip": false
+ },
+ "memory": {
+ "format": "{}% "
+ },
+ "temperature": {
+ // "thermal-zone": 2,
+ // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
+ "critical-threshold": 80,
+ // "format-critical": "{temperatureC}°C {icon}",
+ "format": "{temperatureC}°C {icon}",
+ "format-icons": ["", "", ""]
+ },
+ "backlight": {
+ // "device": "acpi_video1",
+ "format": "{percent}% {icon}",
+ "format-icons": ["", ""]
+ },
+ "battery": {
+ "states": {
+ // "good": 95,
+ "warning": 30,
+ "critical": 15
+ },
+ "format": "{capacity}% {icon}",
+ "format-charging": "{capacity}% ",
+ "format-plugged": "{capacity}% ",
+ "format-alt": "{time} {icon}",
+ // "format-good": "", // An empty format will hide the module
+ // "format-full": "",
+ "format-icons": ["", "", "", "", ""]
+ },
+ "battery#bat2": {
+ "bat": "cw2015-battery",
+ "states": {
+ // "good": 95,
+ "warning": 30,
+ "critical": 15
+ },
+ "format": "{capacity}% {icon}",
+ "format-charging": "{capacity}% ",
+ "format-plugged": "{capacity}% ",
+ "format-alt": "{time} {icon}",
+ // "format-good": "", // An empty format will hide the module
+ // "format-full": "",
+ "format-icons": ["", "", "", "", ""]
+ },
+ "network": {
+ //"interface": "wl*", // (Optional) To force the use of this interface
+ "format-wifi": "{essid} ({signalStrength}%) ",
+ "format-ethernet": "{ifname}: {ipaddr}/{cidr} ",
+ "format-linked": "{ifname} (No IP) ",
+ "format-disconnected": "Disconnected ⚠",
+ "format-alt": "{ifname}: {ipaddr}/{cidr}",
+ "signal": 6
+ },
+ "pulseaudio": {
+ // "scroll-step": 1, // %, can be a float
+ "format": "{volume}% {icon} {format_source}",
+ "format-bluetooth": "{volume}% {icon} {format_source}",
+ "format-bluetooth-muted": " {icon} {format_source}",
+ "format-muted": " {format_source}",
+ "format-source": "{volume}% ",
+ "format-source-muted": "",
+ "format-icons": {
+ "headphone": "",
+ "hands-free": "",
+ "headset": "",
+ "phone": "",
+ "portable": "",
+ "car": "",
+ "default": ["", "", ""]
+ },
+ "on-click": "pavucontrol"
+ },
+ "custom/media": {
+ "format": "{icon} {}",
+ "return-type": "json",
+ "max-length": 40,
+ "format-icons": {
+ "spotify": "",
+ "default": "🎜"
+ },
+ "escape": true,
+ "exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
+ // "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
+ }
+}]
diff --git a/waybar/style.css b/waybar/style.css
new file mode 100644
index 0000000..3b67c93
--- /dev/null
+++ b/waybar/style.css
@@ -0,0 +1,245 @@
+* {
+ border: none;
+ border-radius: 0;
+ /* `otf-font-awesome` is required to be installed for icons */
+ font-family: mononoki Nerd Font Mono;
+ font-size: 12px;
+ min-height: 24px;
+}
+
+window#waybar {
+ background-color: rgba(43, 48, 59, 0.5);
+ border-bottom: 3px solid rgba(100, 114, 125, 0.5);
+ color: #ffffff;
+ transition-property: background-color;
+ transition-duration: .5s;
+}
+
+window#waybar.hidden {
+ opacity: 1.0;
+}
+
+#custom-dwl_layout {
+ color: #EC5800;
+}
+
+#custom-dwl_title {
+ color: #017AFF;
+}
+
+#custom-dwl_tag {
+ color: #875F00;
+}
+
+#custom-dwl_tag.selected {
+ color: #017AFF;
+ border-bottom: 3px solid #017AFF;
+}
+
+#custom-dwl_tag.urgent {
+ background-color: #FF0000;
+ border-bottom: 3px solid #FF0000;
+}
+
+#custom-dwl_tag.active {
+ border-bottom: 3px solid #EC5800;
+}
+
+/*
+window#waybar.empty {
+ background-color: transparent;
+}
+window#waybar.solo {
+ background-color: #FFFFFF;
+}
+*/
+
+window#waybar.termite {
+ background-color: #3F3F3F;
+}
+
+window#waybar.chromium {
+ background-color: #000000;
+ border: none;
+}
+
+#workspaces button {
+ padding: 0 5px;
+ background-color: transparent;
+ color: #ffffff;
+ border-bottom: 3px solid transparent;
+}
+
+/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
+#workspaces button:hover {
+ background: rgba(0, 0, 0, 0.2);
+ box-shadow: inherit;
+ border-bottom: 3px solid #ffffff;
+}
+
+#workspaces button.focused {
+ background-color: #64727D;
+ border-bottom: 3px solid #ffffff;
+}
+
+#workspaces button.urgent {
+ background-color: #eb4d4b;
+}
+
+#mode {
+ background-color: #64727D;
+ border-bottom: 3px solid #ffffff;
+}
+
+#clock,
+#battery,
+#cpu,
+#memory,
+#temperature,
+#backlight,
+#network,
+#pulseaudio,
+#custom-media,
+#tray,
+#mode,
+#idle_inhibitor,
+#mpd {
+ padding: 0 10px;
+ margin: 0 4px;
+ color: #ffffff;
+}
+
+#tags button {
+ color: #ddd;
+ border-bottom: 3px solid rgba(100, 114, 125, 0.5);
+}
+
+#tags button.occupied {
+ color: #ddd;
+ border-bottom: 3px solid rgba(100, 114, 125, 0.5);
+ background-color: #000;
+}
+
+#tags button.focused {
+ color: #ddd;
+ border-bottom: 3px solid rgba(100, 114, 125, 0.5);
+ background-color: #700;
+}
+
+#clock {
+ background-color: #64727D;
+}
+
+#battery {
+ background-color: #ffffff;
+ color: #000000;
+}
+
+#battery.charging {
+ color: #ffffff;
+ background-color: #26A65B;
+}
+
+@keyframes blink {
+ to {
+ background-color: #ffffff;
+ color: #000000;
+ }
+}
+
+#battery.critical:not(.charging) {
+ background-color: #f53c3c;
+ color: #ffffff;
+ animation-name: blink;
+ animation-duration: 0.5s;
+ animation-timing-function: linear;
+ animation-iteration-count: infinite;
+ animation-direction: alternate;
+}
+
+label:focus {
+ background-color: #000000;
+}
+
+#cpu {
+ background-color: #2ecc71;
+ color: #000000;
+}
+
+#memory {
+ background-color: #9b59b6;
+}
+
+#backlight {
+ background-color: #90b1b1;
+}
+
+#network {
+ background-color: #2980b9;
+}
+
+#network.disconnected {
+ background-color: #f53c3c;
+}
+
+#pulseaudio {
+ background-color: #f1c40f;
+ color: #000000;
+}
+
+#pulseaudio.muted {
+ background-color: #90b1b1;
+ color: #2a5c45;
+}
+
+#custom-media {
+ background-color: #66cc99;
+ color: #2a5c45;
+ min-width: 100px;
+}
+
+#custom-media.custom-spotify {
+ background-color: #66cc99;
+}
+
+#custom-media.custom-vlc {
+ background-color: #ffa000;
+}
+
+#temperature {
+ background-color: #f0932b;
+}
+
+#temperature.critical {
+ background-color: #eb4d4b;
+}
+
+#tray {
+ background-color: #2980b9;
+}
+
+#idle_inhibitor {
+ background-color: #2d3436;
+}
+
+#idle_inhibitor.activated {
+ background-color: #ecf0f1;
+ color: #2d3436;
+}
+
+#mpd {
+ background-color: #66cc99;
+ color: #2a5c45;
+}
+
+#mpd.disconnected {
+ background-color: #f53c3c;
+}
+
+#mpd.stopped {
+ background-color: #90b1b1;
+}
+
+#mpd.paused {
+ background-color: #51a37a;
+}
diff --git a/waylock/waylock.toml b/waylock/waylock.toml
new file mode 100644
index 0000000..5379f1e
--- /dev/null
+++ b/waylock/waylock.toml
@@ -0,0 +1,4 @@
+[colors]
+init_color = 0x000000
+input_color = 0x005577
+fail_color = 0xdc322f
diff --git a/xmodmap b/xmodmap
new file mode 100644
index 0000000..59eb9cb
--- /dev/null
+++ b/xmodmap
@@ -0,0 +1,26 @@
+!
+!Change Caps Lock to Escape
+!
+! remove lock = Caps_Lock
+! keysym Caps_Lock = Escape
+! remove lock = Escape
+!
+! Add Hyper mod instead of left Alt
+!
+keysym Alt_L = Hyper_L
+!
+! Set Hyper to mod3
+!
+remove mod1 = Hyper_L
+remove mod4 = Hyper_L
+add mod3 = Hyper_L
+!!
+!! Set Alt_L to mod3
+!!
+!remove Mod1 = Alt_L
+!add Mod3 = Alt_L
+!
+! Fix backlight keybindings
+!
+!keycode 146 = XF86MonBrightnessDown NoSymbol XF86MonBrightnessDown
+!keycode 151 = XF86MonBrightnessUp NoSymbol XF86MonBrightnessUp
diff --git a/xplr/init.lua b/xplr/init.lua
new file mode 100644
index 0000000..8840f48
--- /dev/null
+++ b/xplr/init.lua
@@ -0,0 +1,2443 @@
+-- You need to define the script version for compatibility check.
+-- See https://github.com/sayanarijit/xplr/wiki/Upgrade-Guide.
+--
+package.path = os.getenv("HOME") .. '/.config/xplr/plugins/?/src/init.lua'
+
+version = "0.14.6"
+
+require("dragon").setup{
+ mode = "selection_ops",
+ key = "D",
+ drag_args = "",
+ drop_args = "",
+ keep_selection = true,
+}
+
+local xplr = xplr
+
+-- Config
+---- General
+------ Show hidden
+xplr.config.general.show_hidden = false
+
+------ Read only
+xplr.config.general.read_only = false
+
+------ Recover mode
+xplr.config.general.disable_recover_mode = false
+
+------ Start FIFO
+xplr.config.general.start_fifo = nil
+
+------ Prompt
+xplr.config.general.prompt.format = "❯ "
+xplr.config.general.prompt.style.add_modifiers = nil
+xplr.config.general.prompt.style.sub_modifiers = nil
+xplr.config.general.prompt.style.bg = nil
+xplr.config.general.prompt.style.fg = nil
+
+------ Cursor
+xplr.config.general.cursor.format = "█"
+xplr.config.general.cursor.style.add_modifiers = nil
+xplr.config.general.cursor.style.bg = nil
+xplr.config.general.cursor.style.fg = nil
+xplr.config.general.cursor.style.sub_modifiers = nil
+
+------ Initial layout
+xplr.config.general.initial_layout = "default"
+
+------ Initial mode
+xplr.config.general.initial_mode = "default"
+
+------ Initial sorting
+xplr.config.general.initial_sorting = {
+ { sorter = "ByCanonicalIsDir", reverse = true },
+ { sorter = "ByIRelativePath", reverse = false },
+}
+
+------ Logs
+-------- Error
+xplr.config.general.logs.error.format = "ERROR"
+xplr.config.general.logs.error.style.add_modifiers = nil
+xplr.config.general.logs.error.style.sub_modifiers = nil
+xplr.config.general.logs.error.style.bg = nil
+xplr.config.general.logs.error.style.fg = "Red"
+
+-------- Info
+xplr.config.general.logs.info.format = "INFO"
+xplr.config.general.logs.info.style.add_modifiers = nil
+xplr.config.general.logs.info.style.sub_modifiers = nil
+xplr.config.general.logs.info.style.bg = nil
+xplr.config.general.logs.info.style.fg = "LightBlue"
+
+-------- Success
+xplr.config.general.logs.success.format = "SUCCESS"
+xplr.config.general.logs.success.style.add_modifiers = nil
+xplr.config.general.logs.success.style.bg = nil
+xplr.config.general.logs.success.style.fg = "Green"
+xplr.config.general.logs.success.style.sub_modifiers = nil
+
+-------- Warning
+xplr.config.general.logs.warning.format = "WARNING"
+xplr.config.general.logs.warning.style.add_modifiers = nil
+xplr.config.general.logs.warning.style.bg = nil
+xplr.config.general.logs.warning.style.fg = "Yellow"
+xplr.config.general.logs.warning.style.sub_modifiers = nil
+
+------ Default UI
+xplr.config.general.default_ui.prefix = " "
+xplr.config.general.default_ui.suffix = ""
+xplr.config.general.default_ui.style.add_modifiers = nil
+xplr.config.general.default_ui.style.sub_modifiers = nil
+xplr.config.general.default_ui.style.bg = nil
+xplr.config.general.default_ui.style.fg = nil
+
+------ Focus UI
+xplr.config.general.focus_ui.prefix = "▸["
+xplr.config.general.focus_ui.suffix = "]"
+xplr.config.general.focus_ui.style.add_modifiers = { "Bold" }
+xplr.config.general.focus_ui.style.sub_modifiers = nil
+xplr.config.general.focus_ui.style.bg = nil
+xplr.config.general.focus_ui.style.fg = "Blue"
+
+------ Selection UI
+xplr.config.general.selection_ui.prefix = " {"
+xplr.config.general.selection_ui.suffix = "}"
+xplr.config.general.selection_ui.style.add_modifiers = { "Bold" }
+xplr.config.general.selection_ui.style.sub_modifiers = nil
+xplr.config.general.selection_ui.style.bg = nil
+xplr.config.general.selection_ui.style.fg = "LightGreen"
+
+------ Sort & filter UI
+-------- Separator
+xplr.config.general.sort_and_filter_ui.separator.format = " › "
+xplr.config.general.sort_and_filter_ui.separator.style.add_modifiers = { "Dim" }
+xplr.config.general.sort_and_filter_ui.separator.style.bg = nil
+xplr.config.general.sort_and_filter_ui.separator.style.fg = nil
+xplr.config.general.sort_and_filter_ui.separator.style.sub_modifiers = nil
+
+-------- Default identidier
+xplr.config.general.sort_and_filter_ui.default_identifier.format = nil
+xplr.config.general.sort_and_filter_ui.default_identifier.style.add_modifiers =
+ {
+ "Bold",
+ }
+xplr.config.general.sort_and_filter_ui.default_identifier.style.bg = nil
+xplr.config.general.sort_and_filter_ui.default_identifier.style.fg = nil
+xplr.config.general.sort_and_filter_ui.default_identifier.style.sub_modifiers =
+ nil
+
+-------- Filter identifiers
+xplr.config.general.sort_and_filter_ui.filter_identifiers = {
+ AbsolutePathDoesContain = {
+ format = "abs=~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ AbsolutePathDoesEndWith = {
+ format = "abs=$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ AbsolutePathDoesNotContain = {
+ format = "abs!~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ AbsolutePathDoesNotEndWith = {
+ format = "abs!$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ AbsolutePathDoesNotStartWith = {
+ format = "abs!^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ AbsolutePathDoesStartWith = {
+ format = "abs=^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ AbsolutePathIs = {
+ format = "abs==",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ AbsolutePathIsNot = {
+ format = "abs!=",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathDoesContain = {
+ format = "[i]abs=~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathDoesEndWith = {
+ format = "[i]abs=$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathDoesNotContain = {
+ format = "[i]abs!~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathDoesNotEndWith = {
+ format = "[i]abs!$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathDoesNotStartWith = {
+ format = "[i]abs!^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathDoesStartWith = {
+ format = "[i]abs=^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathIs = {
+ format = "[i]abs==",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IAbsolutePathIsNot = {
+ format = "[i]abs!=",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathDoesContain = {
+ format = "[i]rel=~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathDoesEndWith = {
+ format = "[i]rel=$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathDoesNotContain = {
+ format = "[i]rel!~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathDoesNotEndWith = {
+ format = "[i]rel!$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathDoesNotStartWith = {
+ format = "[i]rel!^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathDoesStartWith = {
+ format = "[i]rel=^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathIs = {
+ format = "[i]rel==",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ IRelativePathIsNot = {
+ format = "[i]rel!=",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathDoesContain = {
+ format = "rel=~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathDoesEndWith = {
+ format = "rel=$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathDoesNotContain = {
+ format = "rel!~",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathDoesNotEndWith = {
+ format = "rel!$",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathDoesNotStartWith = {
+ format = "rel!^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathDoesStartWith = {
+ format = "rel=^",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathIs = {
+ format = "rel==",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ RelativePathIsNot = {
+ format = "rel!=",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+}
+
+-------- Sort direction identifiers
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.format =
+ "↓"
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.style.add_modifiers =
+ nil
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.style.bg =
+ nil
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.style.fg =
+ nil
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.forward.style.sub_modifiers =
+ nil
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.format =
+ "↑"
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.style.add_modifiers =
+ nil
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.style.bg =
+ nil
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.style.fg =
+ nil
+xplr.config.general.sort_and_filter_ui.sort_direction_identifiers.reverse.style.sub_modifiers =
+ nil
+
+-------- Sorter identifiers
+xplr.config.general.sort_and_filter_ui.sorter_identifiers = {
+ ByCanonicalAbsolutePath = {
+ format = "[c]abs",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByCanonicalExtension = {
+ format = "[c]ext",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByCanonicalIsDir = {
+ format = "[c]dir",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByCanonicalIsFile = {
+ format = "[c]file",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByCanonicalIsReadonly = {
+ format = "[c]ro",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByCanonicalMimeEssence = {
+ format = "[c]mime",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByCanonicalSize = {
+ format = "[c]size",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByExtension = {
+ format = "ext",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByICanonicalAbsolutePath = {
+ format = "[ci]abs",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByIRelativePath = {
+ format = "[i]rel",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByISymlinkAbsolutePath = {
+ format = "[si]abs",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByIsBroken = {
+ format = "⨯",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByIsDir = {
+ format = "dir",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByIsFile = {
+ format = "file",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByIsReadonly = {
+ format = "ro",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByIsSymlink = {
+ format = "sym",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByMimeEssence = {
+ format = "mime",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ ByRelativePath = {
+ format = "rel",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySize = {
+ format = "size",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySymlinkAbsolutePath = {
+ format = "[s]abs",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySymlinkExtension = {
+ format = "[s]ext",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySymlinkIsDir = {
+ format = "[s]dir",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySymlinkIsFile = {
+ format = "[s]file",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySymlinkIsReadonly = {
+ format = "[s]ro",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySymlinkMimeEssence = {
+ format = "[s]mime",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ BySymlinkSize = {
+ format = "[s]size",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+}
+
+------ Panel UI
+-------- Default
+xplr.config.general.panel_ui.default.borders = {
+ "Top",
+ "Right",
+ "Bottom",
+ "Left",
+}
+xplr.config.general.panel_ui.default.style.add_modifiers = nil
+xplr.config.general.panel_ui.default.style.bg = nil
+xplr.config.general.panel_ui.default.style.fg = nil
+xplr.config.general.panel_ui.default.style.sub_modifiers = nil
+xplr.config.general.panel_ui.default.title.format = nil
+xplr.config.general.panel_ui.default.title.style.add_modifiers = nil
+xplr.config.general.panel_ui.default.title.style.bg = nil
+xplr.config.general.panel_ui.default.title.style.fg = nil
+xplr.config.general.panel_ui.default.title.style.sub_modifiers = nil
+
+-------- Help menu
+xplr.config.general.panel_ui.help_menu.borders = nil
+xplr.config.general.panel_ui.help_menu.style.add_modifiers = nil
+xplr.config.general.panel_ui.help_menu.style.bg = nil
+xplr.config.general.panel_ui.help_menu.style.fg = nil
+xplr.config.general.panel_ui.help_menu.style.sub_modifiers = nil
+xplr.config.general.panel_ui.help_menu.title.format = nil
+xplr.config.general.panel_ui.help_menu.title.style.add_modifiers = nil
+xplr.config.general.panel_ui.help_menu.title.style.bg = nil
+xplr.config.general.panel_ui.help_menu.title.style.fg = nil
+xplr.config.general.panel_ui.help_menu.title.style.sub_modifiers = nil
+
+-------- Input & log
+xplr.config.general.panel_ui.input_and_logs.borders = nil
+xplr.config.general.panel_ui.input_and_logs.style.add_modifiers = nil
+xplr.config.general.panel_ui.input_and_logs.style.bg = nil
+xplr.config.general.panel_ui.input_and_logs.style.fg = nil
+xplr.config.general.panel_ui.input_and_logs.style.sub_modifiers = nil
+xplr.config.general.panel_ui.input_and_logs.title.format = nil
+xplr.config.general.panel_ui.input_and_logs.title.style.add_modifiers = nil
+xplr.config.general.panel_ui.input_and_logs.title.style.bg = nil
+xplr.config.general.panel_ui.input_and_logs.title.style.fg = nil
+xplr.config.general.panel_ui.input_and_logs.title.style.sub_modifiers = nil
+
+-------- Selection
+xplr.config.general.panel_ui.selection.borders = nil
+xplr.config.general.panel_ui.selection.style.add_modifiers = nil
+xplr.config.general.panel_ui.selection.style.bg = nil
+xplr.config.general.panel_ui.selection.style.fg = nil
+xplr.config.general.panel_ui.selection.style.sub_modifiers = nil
+xplr.config.general.panel_ui.selection.title.format = nil
+xplr.config.general.panel_ui.selection.title.style.add_modifiers = nil
+xplr.config.general.panel_ui.selection.title.style.bg = nil
+xplr.config.general.panel_ui.selection.title.style.fg = nil
+xplr.config.general.panel_ui.selection.title.style.sub_modifiers = nil
+
+-------- Sort and filter
+xplr.config.general.panel_ui.sort_and_filter.borders = nil
+xplr.config.general.panel_ui.sort_and_filter.style.add_modifiers = nil
+xplr.config.general.panel_ui.sort_and_filter.style.bg = nil
+xplr.config.general.panel_ui.sort_and_filter.style.fg = nil
+xplr.config.general.panel_ui.sort_and_filter.style.sub_modifiers = nil
+xplr.config.general.panel_ui.sort_and_filter.title.format = nil
+xplr.config.general.panel_ui.sort_and_filter.title.style.add_modifiers = nil
+xplr.config.general.panel_ui.sort_and_filter.title.style.bg = nil
+xplr.config.general.panel_ui.sort_and_filter.title.style.fg = nil
+xplr.config.general.panel_ui.sort_and_filter.title.style.sub_modifiers = nil
+
+-------- Table
+xplr.config.general.panel_ui.table.borders = nil
+xplr.config.general.panel_ui.table.style.add_modifiers = nil
+xplr.config.general.panel_ui.table.style.bg = nil
+xplr.config.general.panel_ui.table.style.fg = nil
+xplr.config.general.panel_ui.table.style.sub_modifiers = nil
+xplr.config.general.panel_ui.table.title.format = nil
+xplr.config.general.panel_ui.table.title.style.add_modifiers = nil
+xplr.config.general.panel_ui.table.title.style.bg = nil
+xplr.config.general.panel_ui.table.title.style.fg = nil
+xplr.config.general.panel_ui.table.title.style.sub_modifiers = nil
+
+------ Table
+xplr.config.general.table.style.add_modifiers = nil
+xplr.config.general.table.style.bg = nil
+xplr.config.general.table.style.fg = nil
+xplr.config.general.table.style.sub_modifiers = nil
+
+-------- Col spacing
+xplr.config.general.table.col_spacing = 1
+
+-------- Col widths
+xplr.config.general.table.col_widths = {
+ { Percentage = 10 },
+ { Percentage = 50 },
+ { Percentage = 10 },
+ { Percentage = 10 },
+ { Percentage = 20 },
+}
+
+-------- Header
+xplr.config.general.table.header.cols = {
+ {
+ format = " index",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "╭──── path",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "permissions",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "size",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "type",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+}
+xplr.config.general.table.header.height = 1
+xplr.config.general.table.header.style.add_modifiers = { "Bold" }
+xplr.config.general.table.header.style.sub_modifiers = nil
+xplr.config.general.table.header.style.bg = nil
+xplr.config.general.table.header.style.fg = nil
+
+-------- Row
+xplr.config.general.table.row.cols = {
+ {
+ format = "builtin.fmt_general_table_row_cols_0",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "builtin.fmt_general_table_row_cols_1",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "builtin.fmt_general_table_row_cols_2",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "builtin.fmt_general_table_row_cols_3",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "builtin.fmt_general_table_row_cols_4",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+}
+xplr.config.general.table.row.height = 0
+xplr.config.general.table.row.style.add_modifiers = nil
+xplr.config.general.table.row.style.bg = nil
+xplr.config.general.table.row.style.fg = nil
+xplr.config.general.table.row.style.sub_modifiers = nil
+
+-------- Tree
+xplr.config.general.table.tree = {
+ {
+ format = "├─",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "├─",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+ {
+ format = "╰─",
+ style = { add_modifiers = nil, bg = nil, fg = nil, sub_modifiers = nil },
+ },
+}
+
+---- Node types
+------ Directory
+xplr.config.node_types.directory.meta.icon = "ð"
+xplr.config.node_types.directory.style.add_modifiers = { "Bold" }
+xplr.config.node_types.directory.style.sub_modifiers = nil
+xplr.config.node_types.directory.style.bg = nil
+xplr.config.node_types.directory.style.fg = "Cyan"
+
+------ File
+xplr.config.node_types.file.meta.icon = "ƒ"
+xplr.config.node_types.file.style.add_modifiers = nil
+xplr.config.node_types.file.style.sub_modifiers = nil
+xplr.config.node_types.file.style.bg = nil
+xplr.config.node_types.file.style.fg = nil
+
+------ Symlink
+xplr.config.node_types.symlink.meta.icon = "§"
+xplr.config.node_types.symlink.style.add_modifiers = { "Italic" }
+xplr.config.node_types.symlink.style.sub_modifiers = nil
+xplr.config.node_types.symlink.style.bg = nil
+xplr.config.node_types.symlink.style.fg = "Magenta"
+
+------ Mime essence
+xplr.config.node_types.mime_essence = {}
+
+------ Extension
+xplr.config.node_types.extension = {}
+
+------ Special
+xplr.config.node_types.special = {}
+
+-- Layouts
+---- Builtin
+------ Default
+xplr.config.layouts.builtin.default = {
+ Horizontal = {
+ config = {
+ margin = nil,
+ horizontal_margin = 0,
+ vertical_margin = 0,
+ constraints = {
+ {
+ Percentage = 70,
+ },
+ {
+ Percentage = 30,
+ },
+ },
+ },
+ splits = {
+ {
+ Vertical = {
+ config = {
+ margin = 0,
+ horizontal_margin = nil,
+ vertical_margin = nil,
+ constraints = {
+ {
+ Length = 3,
+ },
+ {
+ Min = 1,
+ },
+ {
+ Length = 3,
+ },
+ },
+ },
+ splits = {
+ "SortAndFilter",
+ "Table",
+ "InputAndLogs",
+ },
+ },
+ },
+ {
+ Vertical = {
+ config = {
+ margin = 0,
+ horizontal_margin = nil,
+ vertical_margin = nil,
+ constraints = {
+ {
+ Percentage = 50,
+ },
+ {
+ Percentage = 50,
+ },
+ },
+ },
+ splits = {
+ "Selection",
+ "HelpMenu",
+ },
+ },
+ },
+ },
+ },
+}
+
+------ No help
+xplr.config.layouts.builtin.no_help = {
+ Horizontal = {
+ config = {
+ margin = nil,
+ horizontal_margin = nil,
+ vertical_margin = nil,
+ constraints = {
+ {
+ Percentage = 70,
+ },
+ {
+ Percentage = 30,
+ },
+ },
+ },
+ splits = {
+ {
+ Vertical = {
+ config = {
+ margin = nil,
+ horizontal_margin = nil,
+ vertical_margin = nil,
+ constraints = {
+ {
+ Length = 3,
+ },
+ {
+ Min = 1,
+ },
+ {
+ Length = 3,
+ },
+ },
+ },
+ splits = {
+ "SortAndFilter",
+ "Table",
+ "InputAndLogs",
+ },
+ },
+ },
+ "Selection",
+ },
+ },
+}
+
+------ No selection
+xplr.config.layouts.builtin.no_selection = {
+ Horizontal = {
+ config = {
+ margin = nil,
+ horizontal_margin = nil,
+ vertical_margin = nil,
+ constraints = {
+ {
+ Percentage = 70,
+ },
+ {
+ Percentage = 30,
+ },
+ },
+ },
+ splits = {
+ {
+ Vertical = {
+ config = {
+ margin = nil,
+ horizontal_margin = nil,
+ vertical_margin = nil,
+ constraints = {
+ {
+ Length = 3,
+ },
+ {
+ Min = 1,
+ },
+ {
+ Length = 3,
+ },
+ },
+ },
+ splits = {
+ "SortAndFilter",
+ "Table",
+ "InputAndLogs",
+ },
+ },
+ },
+ "HelpMenu",
+ },
+ },
+}
+
+------ No help, no selection
+xplr.config.layouts.builtin.no_help_no_selection = {
+ Vertical = {
+ config = {
+ margin = nil,
+ horizontal_margin = nil,
+ vertical_margin = nil,
+ constraints = {
+ {
+ Length = 3,
+ },
+ {
+ Min = 1,
+ },
+ {
+ Length = 3,
+ },
+ },
+ },
+ splits = {
+ "SortAndFilter",
+ "Table",
+ "InputAndLogs",
+ },
+ },
+}
+
+---- Custom
+xplr.config.layouts.custom = {}
+
+-- Modes
+---- Builtin
+------ Default
+xplr.config.modes.builtin.default = {
+ name = "default",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["#"] = {
+ help = nil,
+ messages = { "PrintAppStateAndQuit" },
+ },
+ ["."] = {
+ help = "show hidden",
+ messages = {
+ {
+ ToggleNodeFilter = {
+ filter = "RelativePathDoesNotStartWith",
+ input = ".",
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ [":"] = {
+ help = "action",
+ messages = {
+ "PopMode",
+ {
+ SwitchModeBuiltin = "action",
+ },
+ },
+ },
+ ["?"] = {
+ help = "global help menu",
+ messages = {
+ {
+ BashExec = [===[
+ [ -z "$PAGER" ] && PAGER="less -+F"
+ cat -- "${XPLR_PIPE_GLOBAL_HELP_MENU_OUT}" | ${PAGER:?}
+ ]===],
+ },
+ },
+ },
+ ["G"] = {
+ help = "go to bottom",
+ messages = { "PopMode", "FocusLast" },
+ },
+ ["ctrl-a"] = {
+ help = "select/unselect all",
+ messages = { "ToggleSelectAll" },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-f"] = {
+ help = "search",
+ messages = {
+ "PopMode",
+ { SwitchModeBuiltin = "search" },
+ { SetInputBuffer = "" },
+ "ExplorePwdAsync",
+ },
+ },
+ ["ctrl-i"] = {
+ help = "next visited path",
+ messages = { "NextVisitedPath" },
+ },
+ ["ctrl-o"] = {
+ help = "last visited path",
+ messages = { "LastVisitedPath" },
+ },
+ ["ctrl-r"] = {
+ help = "refresh screen",
+ messages = { "ClearScreen" },
+ },
+ ["ctrl-u"] = {
+ help = "clear selection",
+ messages = { "ClearSelection" },
+ },
+ ["ctrl-w"] = {
+ help = "switch layout",
+ messages = {
+ {
+ SwitchModeBuiltin = "switch_layout",
+ },
+ },
+ },
+ ["d"] = {
+ help = "delete",
+ messages = {
+ "PopMode",
+ {
+ SwitchModeBuiltin = "delete",
+ },
+ },
+ },
+ down = {
+ help = "down",
+ messages = { "FocusNext" },
+ },
+ enter = {
+ help = "quit with result",
+ messages = { "PrintResultAndQuit" },
+ },
+ esc = {
+ help = nil,
+ messages = {},
+ },
+ ["f"] = {
+ help = "filter",
+ messages = {
+ "PopMode",
+ { SwitchModeBuiltin = "filter" },
+ },
+ },
+ ["g"] = {
+ help = "go to",
+ messages = {
+ "PopMode",
+ { SwitchModeBuiltin = "go_to" },
+ },
+ },
+ left = {
+ help = "back",
+ messages = { "Back" },
+ },
+ ["q"] = {
+ help = "quit",
+ messages = { "Quit" },
+ },
+ ["r"] = {
+ help = "rename",
+ messages = {
+ "PopMode",
+ { SwitchModeBuiltin = "rename" },
+ {
+ BashExecSilently = [===[
+ echo SetInputBuffer: "'"$(basename "${XPLR_FOCUS_PATH}")"'" >> "${XPLR_PIPE_MSG_IN:?}"
+ ]===],
+ },
+ },
+ },
+ right = {
+ help = "enter",
+ messages = { "Enter" },
+ },
+ ["s"] = {
+ help = "sort",
+ messages = {
+ "PopMode",
+ { SwitchModeBuiltin = "sort" },
+ },
+ },
+ space = {
+ help = "toggle selection",
+ messages = { "ToggleSelection", "FocusNext" },
+ },
+ up = {
+ help = "up",
+ messages = { "FocusPrevious" },
+ },
+ ["~"] = {
+ help = "go home",
+ messages = {
+ {
+ BashExecSilently = [===[
+ echo ChangeDirectory: "'"${HOME:?}"'" >> "${XPLR_PIPE_MSG_IN:?}"
+ ]===],
+ },
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = {
+ help = "input",
+ messages = {
+ "PopMode",
+ { SwitchModeBuiltin = "number" },
+ "BufferInputFromKey",
+ },
+ },
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+xplr.config.modes.builtin.default.key_bindings.on_key["tab"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-i"]
+
+xplr.config.modes.builtin.default.key_bindings.on_key["v"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key.space
+
+xplr.config.modes.builtin.default.key_bindings.on_key["V"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-a"]
+
+xplr.config.modes.builtin.default.key_bindings.on_key["/"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-f"]
+
+xplr.config.modes.builtin.default.key_bindings.on_key["h"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key.left
+
+xplr.config.modes.builtin.default.key_bindings.on_key["j"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key.down
+
+xplr.config.modes.builtin.default.key_bindings.on_key["k"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key.up
+
+xplr.config.modes.builtin.default.key_bindings.on_key["l"] =
+ xplr.config.modes.builtin.default.key_bindings.on_key.right
+
+------ Recover
+xplr.config.modes.builtin.recover = {
+ name = "recover",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ esc = {
+ help = "escape",
+ messages = { "PopMode" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = {
+ help = nil,
+ messages = {},
+ },
+ },
+}
+
+------ Selection ops
+xplr.config.modes.builtin.selection_ops = {
+ name = "selection ops",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["c"] = {
+ help = "copy here",
+ messages = {
+ {
+ BashExec = [===[
+ (while IFS= read -r line; do
+ if cp -vr -- "${line:?}" ./; then
+ echo LogSuccess: $line copied to $PWD >> "${XPLR_PIPE_MSG_IN:?}"
+ else
+ echo LogError: Failed to copy $line to $PWD >> "${XPLR_PIPE_MSG_IN:?}"
+ fi
+ done < "${XPLR_PIPE_SELECTION_OUT:?}")
+ echo ExplorePwdAsync >> "${XPLR_PIPE_MSG_IN:?}"
+ echo ClearSelection >> "${XPLR_PIPE_MSG_IN:?}"
+ read -p "[enter to continue]"
+ ]===],
+ },
+ "PopMode",
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ ["m"] = {
+ help = "move here",
+ messages = {
+ {
+ BashExec = [===[
+ (while IFS= read -r line; do
+ if mv -v -- "${line:?}" ./; then
+ echo LogSuccess: $line moved to $PWD >> "${XPLR_PIPE_MSG_IN:?}"
+ else
+ echo LogError: Failed to move $line to $PWD >> "${XPLR_PIPE_MSG_IN:?}"
+ fi
+ done < "${XPLR_PIPE_SELECTION_OUT:?}")
+ echo ExplorePwdAsync >> "${XPLR_PIPE_MSG_IN:?}"
+ read -p "[enter to continue]"
+ ]===],
+ },
+ "PopMode",
+ },
+ },
+ ["x"] = {
+ help = "open in gui",
+ messages = {
+ {
+ BashExecSilently = [===[
+ if [ -z "$OPENER" ]; then
+ if command -v xdg-open; then
+ OPENER=xdg-open
+ elif command -v open; then
+ OPENER=open
+ else
+ echo 'LogError: $OPENER not found' >> "${XPLR_PIPE_MSG_IN:?}"
+ exit 1
+ fi
+ fi
+ (while IFS= read -r line; do
+ $OPENER "${line:?}" > /dev/null 2>&1
+ done < "${XPLR_PIPE_RESULT_OUT:?}")
+ ]===],
+ },
+ "ClearScreen",
+ "PopMode",
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+------ Create
+xplr.config.modes.builtin.create = {
+ name = "create",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["d"] = {
+ help = "create directory",
+ messages = {
+ "PopMode",
+ {
+ SwitchModeBuiltin = "create directory",
+ },
+ {
+ SetInputBuffer = "",
+ },
+ },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ ["f"] = {
+ help = "create file",
+ messages = {
+ "PopMode",
+ {
+ SwitchModeBuiltin = "create file",
+ },
+ {
+ SetInputBuffer = "",
+ },
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+------ Create directory
+xplr.config.modes.builtin.create_directory = {
+ name = "create directory",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ backspace = {
+ help = "remove last character",
+ messages = { "RemoveInputBufferLastCharacter" },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-u"] = {
+ help = "remove line",
+ messages = {
+ {
+ SetInputBuffer = "",
+ },
+ },
+ },
+ ["ctrl-w"] = {
+ help = "remove last word",
+ messages = { "RemoveInputBufferLastWord" },
+ },
+ enter = {
+ help = "create directory",
+ messages = {
+ {
+ BashExecSilently = [===[
+ PTH="$XPLR_INPUT_BUFFER"
+ if [ "${PTH}" ]; then
+ mkdir -p -- "${PTH:?}" \
+ && echo "SetInputBuffer: ''" >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo ExplorePwd >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo LogSuccess: $PTH created >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo FocusByFileName: "'"$PTH"'" >> "${XPLR_PIPE_MSG_IN:?}"
+ else
+ echo PopMode >> "${XPLR_PIPE_MSG_IN:?}"
+ fi
+ ]===],
+ },
+ },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = {
+ help = nil,
+ messages = { "BufferInputFromKey" },
+ },
+ },
+}
+
+------ Create file
+xplr.config.modes.builtin.create_file = {
+ name = "create file",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ backspace = {
+ help = "remove last character",
+ messages = { "RemoveInputBufferLastCharacter" },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-u"] = {
+ help = "remove line",
+ messages = {
+ {
+ SetInputBuffer = "",
+ },
+ },
+ },
+ ["ctrl-w"] = {
+ help = "remove last word",
+ messages = { "RemoveInputBufferLastWord" },
+ },
+ enter = {
+ help = "create file",
+ messages = {
+ {
+ BashExecSilently = [===[
+ PTH="$XPLR_INPUT_BUFFER"
+ if [ "${PTH}" ]; then
+ touch -- "${PTH:?}" \
+ && echo "SetInputBuffer: ''" >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo LogSuccess: $PTH created >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo ExplorePwd >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo FocusByFileName: "'"$PTH"'" >> "${XPLR_PIPE_MSG_IN:?}"
+ else
+ echo PopMode >> "${XPLR_PIPE_MSG_IN:?}"
+ fi
+ ]===],
+ },
+ },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = {
+ help = nil,
+ messages = { "BufferInputFromKey" },
+ },
+ },
+}
+
+------ Number
+xplr.config.modes.builtin.number = {
+ name = "number",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ backspace = {
+ help = "remove last character",
+ messages = { "RemoveInputBufferLastCharacter" },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-u"] = {
+ help = "remove line",
+ messages = {
+ {
+ SetInputBuffer = "",
+ },
+ },
+ },
+ ["ctrl-w"] = {
+ help = "remove last word",
+ messages = { "RemoveInputBufferLastWord" },
+ },
+ down = {
+ help = "to down",
+ messages = { "FocusNextByRelativeIndexFromInput", "PopMode" },
+ },
+ enter = {
+ help = "to index",
+ messages = { "FocusByIndexFromInput", "PopMode" },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ up = {
+ help = "to up",
+ messages = { "FocusPreviousByRelativeIndexFromInput", "PopMode" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = {
+ help = "input",
+ messages = { "BufferInputFromKey" },
+ },
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+xplr.config.modes.builtin.number.key_bindings.on_key["j"] =
+ xplr.config.modes.builtin.number.key_bindings.on_key.down
+xplr.config.modes.builtin.number.key_bindings.on_key["k"] =
+ xplr.config.modes.builtin.number.key_bindings.on_key.up
+
+------ Go to
+xplr.config.modes.builtin.go_to = {
+ name = "go to",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ ["f"] = {
+ help = "follow symlink",
+ messages = { "FollowSymlink", "PopMode" },
+ },
+ ["g"] = {
+ help = "top",
+ messages = { "FocusFirst", "PopMode" },
+ },
+ ["x"] = {
+ help = "open in gui",
+ messages = {
+ {
+ BashExecSilently = [===[
+ if [ -z "$OPENER" ]; then
+ if command -v xdg-open; then
+ OPENER=xdg-open
+ elif command -v open; then
+ OPENER=open
+ else
+ echo 'LogError: $OPENER not found' >> "${XPLR_PIPE_MSG_IN:?}"
+ exit 1
+ fi
+ fi
+ $OPENER "${XPLR_FOCUS_PATH:?}" > /dev/null 2>&1
+ ]===],
+ },
+ "ClearScreen",
+ "PopMode",
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+------ Rename
+xplr.config.modes.builtin.rename = {
+ name = "rename",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ backspace = {
+ help = "remove last character",
+ messages = { "RemoveInputBufferLastCharacter" },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-u"] = {
+ help = "remove line",
+ messages = {
+ {
+ SetInputBuffer = "",
+ },
+ },
+ },
+ ["ctrl-w"] = {
+ help = "remove last word",
+ messages = { "RemoveInputBufferLastWord" },
+ },
+ enter = {
+ help = "rename",
+ messages = {
+ {
+ BashExecSilently = [===[
+ SRC="${XPLR_FOCUS_PATH:?}"
+ TARGET="${XPLR_INPUT_BUFFER:?}"
+ mv -- "${SRC:?}" "${TARGET:?}" \
+ && echo ExplorePwd >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo FocusByFileName: "'"$TARGET"'" >> "${XPLR_PIPE_MSG_IN:?}" \
+ && echo LogSuccess: $SRC renamed to $TARGET >> "${XPLR_PIPE_MSG_IN:?}"
+ ]===],
+ },
+ "PopMode",
+ },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = {
+ help = nil,
+ messages = { "BufferInputFromKey" },
+ },
+ },
+}
+
+------ Delete
+xplr.config.modes.builtin.delete = {
+ name = "delete",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["D"] = {
+ help = "force delete",
+ messages = {
+ {
+ BashExec = [===[
+ (while IFS= read -r line; do
+ if rm -rfv -- "${line:?}"; then
+ echo LogSuccess: $line deleted >> "${XPLR_PIPE_MSG_IN:?}"
+ else
+ echo LogError: Failed to delete $line >> "${XPLR_PIPE_MSG_IN:?}"
+ fi
+ done < "${XPLR_PIPE_RESULT_OUT:?}")
+ echo ExplorePwdAsync >> "${XPLR_PIPE_MSG_IN:?}"
+ read -p "[enter to continue]"
+ ]===],
+ },
+ "PopMode",
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["d"] = {
+ help = "delete",
+ messages = {
+ {
+ BashExec = [===[
+ (while IFS= read -r line; do
+ if [ -d "$line" ] && [ ! -L "$line" ]; then
+ if rmdir -v -- "${line:?}"; then
+ echo LogSuccess: $line deleted >> "${XPLR_PIPE_MSG_IN:?}"
+ else
+ echo LogError: Failed to delete $line >> "${XPLR_PIPE_MSG_IN:?}"
+ fi
+ else
+ if rm -v -- "${line:?}"; then
+ echo LogSuccess: $line deleted >> "${XPLR_PIPE_MSG_IN:?}"
+ else
+ echo LogError: Failed to delete $line >> "${XPLR_PIPE_MSG_IN:?}"
+ fi
+ fi
+ done < "${XPLR_PIPE_RESULT_OUT:?}")
+ echo ExplorePwdAsync >> "${XPLR_PIPE_MSG_IN:?}"
+ read -p "[enter to continue]"
+ ]===],
+ },
+ "PopMode",
+ },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+------ Action
+xplr.config.modes.builtin.action = {
+ name = "action to",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["!"] = {
+ help = "shell",
+ messages = {
+ {
+ Call = {
+ command = "zsh",
+ args = { "-i" },
+ },
+ },
+ "ExplorePwdAsync",
+ "PopMode",
+ },
+ },
+ ["c"] = {
+ help = "create",
+ messages = {
+ "PopMode",
+ {
+ SwitchModeBuiltin = "create",
+ },
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["e"] = {
+ help = "open in editor",
+ messages = {
+ {
+ BashExec = [===[
+ ${EDITOR:-vi} "${XPLR_FOCUS_PATH:?}"
+ ]===],
+ },
+ "PopMode",
+ },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ ["l"] = {
+ help = "logs",
+ messages = {
+ {
+ BashExec = [===[
+ [ -z "$PAGER" ] && PAGER="less -+F"
+ cat -- "${XPLR_PIPE_LOGS_OUT}" | ${PAGER:?}
+ ]===],
+ },
+ "PopMode",
+ },
+ },
+ ["s"] = {
+ help = "selection operations",
+ messages = {
+ "PopMode",
+ {
+ SwitchModeBuiltin = "selection_ops",
+ },
+ },
+ },
+ ["m"] = {
+ help = "toggle mouse",
+ messages = {
+ "PopMode",
+ "ToggleMouse",
+ },
+ },
+ ["q"] = {
+ help = "quit options",
+ messages = {
+ "PopMode",
+ { SwitchModeBuiltin = "quit" },
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = {
+ help = "go to index",
+ messages = {
+ "PopMode",
+ {
+ SwitchModeBuiltin = "number",
+ },
+ "BufferInputFromKey",
+ },
+ },
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+------ Quit
+xplr.config.modes.builtin.quit = {
+ name = "quit",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ enter = {
+ help = "just quit",
+ messages = {
+ "Quit",
+ },
+ },
+ p = {
+ help = "quit printing pwd",
+ messages = {
+ "PrintPwdAndQuit",
+ },
+ },
+ f = {
+ help = "quit printing focus",
+ messages = {
+ "PrintFocusPathAndQuit",
+ },
+ },
+ s = {
+ help = "quit printing selection",
+ messages = {
+ "PrintSelectionAndQuit",
+ },
+ },
+ r = {
+ help = "quit printing result",
+ messages = {
+ "PrintResultAndQuit",
+ },
+ },
+ esc = {
+ help = "cancel",
+ messages = {
+ "PopMode",
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = {
+ "Terminate",
+ },
+ },
+ },
+ },
+}
+
+------ Search
+xplr.config.modes.builtin.search = {
+ name = "search",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ backspace = {
+ help = "remove last character",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "RemoveInputBufferLastCharacter",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-u"] = {
+ help = "remove line",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ {
+ SetInputBuffer = "",
+ },
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["ctrl-w"] = {
+ help = "remove last word",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "RemoveInputBufferLastWord",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ down = {
+ help = "down",
+ messages = { "FocusNext" },
+ },
+ enter = {
+ help = "focus",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "PopMode",
+ "ExplorePwdAsync",
+ },
+ },
+ left = {
+ help = "back",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "Back",
+ {
+ SetInputBuffer = "",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ right = {
+ help = "enter",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "Enter",
+ {
+ SetInputBuffer = "",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ tab = {
+ help = "toggle selection",
+ messages = { "ToggleSelection", "FocusNext" },
+ },
+ up = {
+ help = "up",
+ messages = { "FocusPrevious" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = {
+ help = nil,
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "BufferInputFromKey",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ },
+}
+
+xplr.config.modes.builtin.search.key_bindings.on_key["esc"] =
+ xplr.config.modes.builtin.search.key_bindings.on_key.enter
+xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-n"] =
+ xplr.config.modes.builtin.search.key_bindings.on_key.down
+xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-p"] =
+ xplr.config.modes.builtin.search.key_bindings.on_key.up
+
+------ Filter
+xplr.config.modes.builtin.filter = {
+ name = "filter",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["R"] = {
+ help = "relative does not contain",
+ messages = {
+ {
+ SwitchModeBuiltin = "relative_path_does_not_contain",
+ },
+ {
+ SetInputBuffer = "",
+ },
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ backspace = {
+ help = "remove last filter",
+ messages = { "RemoveLastNodeFilter", "ExplorePwdAsync" },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-r"] = {
+ help = "reset filters",
+ messages = { "ResetNodeFilters", "ExplorePwdAsync" },
+ },
+ ["ctrl-u"] = {
+ help = "clear filters",
+ messages = { "ClearNodeFilters", "ExplorePwdAsync" },
+ },
+ enter = {
+ help = "done",
+ messages = { "PopMode" },
+ },
+ ["r"] = {
+ help = "relative does contain",
+ messages = {
+ {
+ SwitchModeBuiltin = "relative_path_does_contain",
+ },
+ {
+ SetInputBuffer = "",
+ },
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+xplr.config.modes.builtin.filter.key_bindings.on_key["esc"] =
+ xplr.config.modes.builtin.filter.key_bindings.on_key.enter
+
+------ Relative path does contain
+xplr.config.modes.builtin.relative_path_does_contain = {
+ name = "relative path does contain",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ backspace = {
+ help = "remove last character",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "RemoveInputBufferLastCharacter",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-u"] = {
+ help = "remove line",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ {
+ SetInputBuffer = "",
+ },
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["ctrl-w"] = {
+ help = "remove last word",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "RemoveInputBufferLastWord",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ enter = {
+ help = "apply filter",
+ messages = { "PopMode" },
+ },
+ esc = {
+ help = "cancel",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "PopMode",
+ "ExplorePwdAsync",
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = {
+ help = nil,
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "BufferInputFromKey",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ },
+}
+
+------ Relative path does not contain
+xplr.config.modes.builtin.relative_path_does_not_contain = {
+ name = "relative path does not contain",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ backspace = {
+ help = "remove last character",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "RemoveInputBufferLastCharacter",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-u"] = {
+ help = "remove line",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ {
+ SetInputBuffer = "",
+ },
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["ctrl-w"] = {
+ help = "remove last word",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "RemoveInputBufferLastWord",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ enter = {
+ help = "apply filter",
+ messages = { "PopMode" },
+ },
+ esc = {
+ help = "cancel",
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "PopMode",
+ "ExplorePwdAsync",
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = {
+ help = nil,
+ messages = {
+ {
+ RemoveNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "BufferInputFromKey",
+ {
+ AddNodeFilterFromInput = "IRelativePathDoesNotContain",
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ },
+}
+
+------ Sort
+xplr.config.modes.builtin.sort = {
+ name = "sort",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["!"] = {
+ help = "reverse sorters",
+ messages = { "ReverseNodeSorters", "ExplorePwdAsync" },
+ },
+ ["E"] = {
+ help = "by canonical extension reverse",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalExtension",
+ reverse = true,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["M"] = {
+ help = "by canonical mime essence reverse",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalMimeEssence",
+ reverse = true,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["N"] = {
+ help = "by node type reverse",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalIsDir",
+ reverse = true,
+ },
+ },
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalIsFile",
+ reverse = true,
+ },
+ },
+ {
+ AddNodeSorter = {
+ sorter = "ByIsSymlink",
+ reverse = true,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["R"] = {
+ help = "by relative path reverse",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByIRelativePath",
+ reverse = true,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["S"] = {
+ help = "by size reverse",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "BySize",
+ reverse = true,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ backspace = {
+ help = "remove last sorter",
+ messages = { "RemoveLastNodeSorter", "ExplorePwdAsync" },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ ["ctrl-r"] = {
+ help = "reset sorters",
+ messages = { "ResetNodeSorters", "ExplorePwdAsync" },
+ },
+ ["ctrl-u"] = {
+ help = "clear sorters",
+ messages = { "ClearNodeSorters", "ExplorePwdAsync" },
+ },
+ ["e"] = {
+ help = "by canonical extension",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalExtension",
+ reverse = false,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ enter = {
+ help = "done",
+ messages = { "PopMode" },
+ },
+ ["m"] = {
+ help = "by canonical mime essence",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalMimeEssence",
+ reverse = false,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["n"] = {
+ help = "by node type",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalIsDir",
+ reverse = false,
+ },
+ },
+ {
+ AddNodeSorter = {
+ sorter = "ByCanonicalIsFile",
+ reverse = false,
+ },
+ },
+ {
+ AddNodeSorter = {
+ sorter = "ByIsSymlink",
+ reverse = false,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["r"] = {
+ help = "by relative path",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "ByIRelativePath",
+ reverse = false,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ ["s"] = {
+ help = "by size",
+ messages = {
+ {
+ AddNodeSorter = {
+ sorter = "BySize",
+ reverse = false,
+ },
+ },
+ "ExplorePwdAsync",
+ },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+xplr.config.modes.builtin.sort.key_bindings.on_key["esc"] =
+ xplr.config.modes.builtin.sort.key_bindings.on_key.enter
+
+------ Switch layout
+xplr.config.modes.builtin.switch_layout = {
+ name = "switch layout",
+ help = nil,
+ extra_help = nil,
+ key_bindings = {
+ on_key = {
+ ["1"] = {
+ help = "default",
+ messages = {
+ {
+ SwitchLayoutBuiltin = "default",
+ },
+ "PopMode",
+ },
+ },
+ ["2"] = {
+ help = "no help menu",
+ messages = {
+ {
+ SwitchLayoutBuiltin = "no_help",
+ },
+ "PopMode",
+ },
+ },
+ ["3"] = {
+ help = "no selection panel",
+ messages = {
+ {
+ SwitchLayoutBuiltin = "no_selection",
+ },
+ "PopMode",
+ },
+ },
+ ["4"] = {
+ help = "no help or selection",
+ messages = {
+ {
+ SwitchLayoutBuiltin = "no_help_no_selection",
+ },
+ "PopMode",
+ },
+ },
+ ["ctrl-c"] = {
+ help = "terminate",
+ messages = { "Terminate" },
+ },
+ esc = {
+ help = "cancel",
+ messages = { "PopMode" },
+ },
+ },
+ on_alphabet = nil,
+ on_number = nil,
+ on_special_character = nil,
+ default = nil,
+ },
+}
+
+---- Custom
+xplr.config.modes.custom = {}
+
+-- Function
+---- Builtin
+------ Formaters
+-------- Format index column
+xplr.fn.builtin.fmt_general_table_row_cols_0 = function(m)
+ local r = ""
+ if m.is_before_focus then
+ r = r .. " -"
+ else
+ r = r .. " "
+ end
+
+ r = r .. m.relative_index .. "│" .. m.index
+
+ return r
+end
+
+-------- Format path column
+xplr.fn.builtin.fmt_general_table_row_cols_1 = function(m)
+ local r = m.tree .. m.prefix
+
+ if m.meta.icon == nil then
+ r = r .. ""
+ else
+ r = r .. m.meta.icon .. " "
+ end
+
+ r = r .. m.relative_path
+
+ if m.is_dir then
+ r = r .. "/"
+ end
+
+ r = r .. m.suffix .. " "
+
+ if m.is_symlink then
+ r = r .. "-> "
+
+ if m.is_broken then
+ r = r .. "×"
+ else
+ r = r .. m.symlink.absolute_path
+
+ if m.symlink.is_dir then
+ r = r .. "/"
+ end
+ end
+ end
+
+ return r
+end
+
+-------- Format permissions column
+xplr.fn.builtin.fmt_general_table_row_cols_2 = function(m)
+ local no_color = os.getenv("NO_COLOR")
+
+ local function green(x)
+ if no_color == nil then
+ return "\x1b[32m" .. x .. "\x1b[0m"
+ else
+ return x
+ end
+ end
+
+ local function yellow(x)
+ if no_color == nil then
+ return "\x1b[33m" .. x .. "\x1b[0m"
+ else
+ return x
+ end
+ end
+
+ local function red(x)
+ if no_color == nil then
+ return "\x1b[31m" .. x .. "\x1b[0m"
+ else
+ return x
+ end
+ end
+
+ local function bit(x, color, cond)
+ if cond then
+ return color(x)
+ else
+ return color("-")
+ end
+ end
+
+ local p = m.permissions
+
+ local r = ""
+
+ -- User
+ r = r .. bit("r", green, p.user_read)
+ r = r .. bit("w", yellow, p.user_write)
+
+ if p.user_execute == false and p.setuid == false then
+ r = r .. bit("-", red, p.user_execute)
+ elseif p.user_execute == true and p.setuid == false then
+ r = r .. bit("x", red, p.user_execute)
+ elseif p.user_execute == false and p.setuid == true then
+ r = r .. bit("S", red, p.user_execute)
+ else
+ r = r .. bit("s", red, p.user_execute)
+ end
+
+ -- Group
+ r = r .. bit("r", green, p.group_read)
+ r = r .. bit("w", yellow, p.group_write)
+
+ if p.group_execute == false and p.setuid == false then
+ r = r .. bit("-", red, p.group_execute)
+ elseif p.group_execute == true and p.setuid == false then
+ r = r .. bit("x", red, p.group_execute)
+ elseif p.group_execute == false and p.setuid == true then
+ r = r .. bit("S", red, p.group_execute)
+ else
+ r = r .. bit("s", red, p.group_execute)
+ end
+
+ -- Other
+ r = r .. bit("r", green, p.other_read)
+ r = r .. bit("w", yellow, p.other_write)
+
+ if p.other_execute == false and p.setuid == false then
+ r = r .. bit("-", red, p.other_execute)
+ elseif p.other_execute == true and p.setuid == false then
+ r = r .. bit("x", red, p.other_execute)
+ elseif p.other_execute == false and p.setuid == true then
+ r = r .. bit("T", red, p.other_execute)
+ else
+ r = r .. bit("t", red, p.other_execute)
+ end
+
+ return r
+end
+
+-------- Format size column
+xplr.fn.builtin.fmt_general_table_row_cols_3 = function(m)
+ if not m.is_dir then
+ return m.human_size
+ else
+ return ""
+ end
+end
+
+-------- Format mime column
+xplr.fn.builtin.fmt_general_table_row_cols_4 = function(m)
+ if m.is_symlink and not m.is_broken then
+ return m.symlink.mime_essence
+ else
+ return m.mime_essence
+ end
+end
+
+---- Custom
+xplr.fn.custom = {}
diff --git a/xplr/plugins/dragon/LICENSE b/xplr/plugins/dragon/LICENSE
new file mode 100644
index 0000000..03b3d59
--- /dev/null
+++ b/xplr/plugins/dragon/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Arijit Basu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/xplr/plugins/dragon/README.md b/xplr/plugins/dragon/README.md
new file mode 100644
index 0000000..8a74a12
--- /dev/null
+++ b/xplr/plugins/dragon/README.md
@@ -0,0 +1,49 @@
+[![xplr-dragon.gif](https://s6.gifyu.com/images/xplr-dragon.gif)](https://gifyu.com/image/A8N1)
+
+Drag and drop files using [dragon](https://github.com/mwh/dragon).
+
+
+Requirements
+------------
+
+- [dragon](https://github.com/mwh/dragon)
+- [curl](https://github.com/curl/curl)
+
+
+Installation
+------------
+
+### Install manually
+
+- Add the following line in `~/.config/xplr/init.lua`
+
+ ```lua
+ package.path = os.getenv("HOME") .. '/.config/xplr/plugins/?/src/init.lua'
+ ```
+
+- Clone the plugin
+
+ ```bash
+ mkdir -p ~/.config/xplr/plugins
+
+ git clone https://github.com/sayanarijit/dragon.xplr ~/.config/xplr/plugins/dragon
+ ```
+
+- Require the module in `~/.config/xplr/init.lua`
+
+ ```lua
+ require("dragon").setup()
+
+ -- Or
+
+ require("dragon").setup{
+ mode = "selection_ops",
+ key = "D",
+ drag_args = "",
+ drop_args = "",
+ keep_selection = false,
+ }
+
+ -- Select files and type `:sD` to drag
+ -- Type `:sD` without selecting anything to drop
+ ```
diff --git a/xplr/plugins/dragon/src/init.lua b/xplr/plugins/dragon/src/init.lua
new file mode 100644
index 0000000..f0fdc9f
--- /dev/null
+++ b/xplr/plugins/dragon/src/init.lua
@@ -0,0 +1,62 @@
+local function setup(args)
+ local xplr = xplr
+
+ if args == nil then
+ args = {}
+ end
+
+ if args.mode == nil then
+ args.mode = "selection_ops"
+ end
+
+ if args.key == nil then
+ args.key = "D"
+ end
+
+ if args.keep_selection == nil then
+ args.keep_selection = false
+ end
+
+ if args.drag_args == nil then
+ args.drag_args = ""
+ end
+
+ if args.drop_args == nil then
+ args.drop_args = ""
+ end
+
+ xplr.fn.custom.dragon_drag_n_drop = function(app)
+ local files = {}
+ local count = 0
+ local cmd = nil
+
+ for i, node in ipairs(app.selection) do
+ table.insert(files, node.absolute_path)
+ count = i
+ end
+
+ if count == 0 then
+ cmd = "(dragon --target " .. args.drop_args .. " 2> /dev/null | xargs -rl curl -sLO) &\ntrue"
+ elseif count == 1 then
+ cmd = "dragon --and-exit " .. args.drag_args .. " '" .. files[1] .. "' > /dev/null 2>&1 &\ntrue"
+ else
+ cmd = "dragon " .. args.drag_args .. " '" .. table.concat(files, "' '") .. "' > /dev/null 2>&1 &\ntrue"
+ end
+
+ os.execute(cmd)
+
+ if not args.keep_selection then
+ return { "ClearSelection" }
+ end
+ end
+
+ xplr.config.modes.builtin[args.mode].key_bindings.on_key[args.key] = {
+ help = "drag & drop",
+ messages = {
+ { CallLuaSilently = "custom.dragon_drag_n_drop" },
+ "PopMode",
+ },
+ }
+end
+
+return { setup = setup }
diff --git a/yay/config.json b/yay/config.json
new file mode 100644
index 0000000..21bab87
--- /dev/null
+++ b/yay/config.json
@@ -0,0 +1,43 @@
+{
+ "aururl": "https://aur.archlinux.org",
+ "buildDir": "$HOME/.cache/yay",
+ "absdir": "$HOME/.cache/yay/abs",
+ "editor": "nvim",
+ "editorflags": "",
+ "makepkgbin": "makepkg",
+ "makepkgconf": "",
+ "pacmanbin": "pacman",
+ "pacmanconf": "/etc/pacman.conf",
+ "redownload": "no",
+ "rebuild": "no",
+ "answerclean": "",
+ "answerdiff": "",
+ "answeredit": "",
+ "answerupgrade": "",
+ "gitbin": "git",
+ "gpgbin": "gpg",
+ "gpgflags": "",
+ "mflags": "",
+ "sortby": "votes",
+ "searchby": "name-desc",
+ "gitflags": "",
+ "removemake": "ask",
+ "sudobin": "doas",
+ "sudoflags": "",
+ "requestsplitn": 150,
+ "sortmode": 0,
+ "completionrefreshtime": 7,
+ "sudoloop": false,
+ "timeupdate": false,
+ "devel": false,
+ "cleanAfter": false,
+ "provides": true,
+ "pgpfetch": true,
+ "upgrademenu": true,
+ "cleanmenu": true,
+ "diffmenu": true,
+ "editmenu": true,
+ "combinedupgrade": false,
+ "useask": false,
+ "batchinstall": false
+}
diff --git a/ytfzf/conf.sh b/ytfzf/conf.sh
new file mode 100644
index 0000000..d715a7e
--- /dev/null
+++ b/ytfzf/conf.sh
@@ -0,0 +1,9 @@
+YTFZF_EXTMENU=' bemenu -i -l 30 -p "Search:" '
+
+YTFZF_PLAYER='mpv --save-position-on-quit'
+YTFZF_PLAYER_FORMAT='mpv --save-position-on-quit --ytdl-format='
+
+cache_dir="$XDG_CACHE_HOME/ytfzf"
+history_file="$cache_dir/ytfzf_hst"
+current_file="$cache_dir/ytfzf_cur"
+thumbnail_viewer="catimg"
diff --git a/zsh/.zlogout b/zsh/.zlogout
new file mode 100644
index 0000000..55a747a
--- /dev/null
+++ b/zsh/.zlogout
@@ -0,0 +1,2 @@
+killall pipewire
+rm -rf /tmp/xorg-awake
diff --git a/zsh/.zprofile b/zsh/.zprofile
new file mode 100644
index 0000000..1eae5e7
--- /dev/null
+++ b/zsh/.zprofile
@@ -0,0 +1,6 @@
+#export GDK_DPI_SCALE=0.7
+
+#gnome_schema=org.gnome.desktop.interface
+#
+#gsettings set $gnome_schema gtk-theme 'Plata-Noir-Compact'
+#gsettings set $gnome_schema icon-theme 'Papirus-Dark'
diff --git a/zsh/.zshenv b/zsh/.zshenv
new file mode 100644
index 0000000..e48fa2b
--- /dev/null
+++ b/zsh/.zshenv
@@ -0,0 +1,78 @@
+typeset -U PATH path
+
+unset HISTFILE
+
+# Other XDG paths
+export XDG_DATA_HOME=${XDG_DATA_HOME:="$HOME/.local/share"}
+export XDG_CACHE_HOME=${XDG_CACHE_HOME:="$HOME/.cache"}
+export XDG_CONFIG_HOME=${XDG_CONFIG_HOME:="$HOME/.config"}
+
+# Doesn't seem to work
+export ANDROID_SDK_HOME="$XDG_CONFIG_HOME"/android
+export ANDROID_AVD_HOME="$XDG_DATA_HOME"/android/
+export ANDROID_EMULATOR_HOME="$XDG_DATA_HOME"/android/
+export ADB_VENDOR_KEY="$XDG_CONFIG_HOME"/android
+
+# Disable files
+export LESSHISTFILE=-
+
+# Fixing Paths
+export ATOM_HOME="$XDG_DATA_HOME"/atom
+export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc
+export XSERVERRC="$XDG_CONFIG_HOME"/X11/xserverrc
+export GEM_SPEC_CACHE="$XDG_DATA_HOME/ruby/specs"
+export GEM_HOME="$XDG_DATA_HOME/ruby/gems"
+export NPM_CONFIG_USERCONFIG=$XDG_CONFIG_HOME/npm/npmrc
+export GOPATH="$XDG_DATA_HOME"/go
+export GNUPGHOME="$XDG_DATA_HOME"/gnupg
+export GRADLE_USER_HOME="$XDG_DATA_HOME"/gradle
+export NUGET_PACKAGES="$XDG_CACHE_HOME"/NuGetPackages
+export RXVT_SOCKET="$XDG_RUNTIME_DIR"/urxvtd
+export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME"/java
+export GTK2_RC_FILES="$XDG_CONFIG_HOME"/gtk-2.0/gtkrc
+export ZDOTDIR=$HOME/.config/zsh
+#export HISTFILE="$XDG_DATA_HOME"/zsh/history
+export CARGO_HOME="$XDG_DATA_HOME"/cargo
+export WEECHAT_HOME="$XDG_CONFIG_HOME"/weechat
+export PASSWORD_STORE_DIR="$XDG_DATA_HOME"/pass
+export NOTMUCH_CONFIG="$XDG_CONFIG_HOME"/notmuch/notmuchrc
+export NMBGIT="$XDG_DATA_HOME"/notmuch/nmbug
+export WINEROOT="$XDG_DATA_HOME"/wineprefixes
+export WINEPREFIX="$WINEROOT"/default
+
+export MPD_HOST="$XDG_CONFIG_HOME/mpd/socket"
+
+# Scaling
+export QT_AUTO_SCREEN_SCALE_FACTOR=0
+export QT_SCALE_FACTOR=1
+export QT_SCREEN_SCALE_FACTORS="1;1;1"
+export GDK_SCALE=1
+export GDK_DPI_SCALE=1
+
+# Theming
+export QT_QPA_PLATFORMTHEME=qt5ct
+export GTK_THEME=Sweet-mars-v40
+
+# Configure apps
+export BEMENU_OPTS="-H 24"
+
+# Fix wayland stuff
+export MOZ_ENABLE_WAYLAND=1
+export XKB_DEFAULT_OPTIONS=caps:escape
+export XDG_CURRENT_DESKTOP=Unity
+
+# Default Apps
+export EDITOR="nvim"
+export READER="zathura"
+export VISUAL="nvim"
+export TERMINAL="st"
+export BROWSER="browser"
+export VIDEO="mpv"
+export IMAGE="sxiv"
+export OPENER="xdg-open"
+export PAGER="less"
+
+# KSH
+export ENV="$XDG_CONFIG_HOME/kshrc"
+
+export PATH="$HOME/.local/volsv:$HOME/.local/bin/scripts:$HOME/.local/bin/dwmblocks:$HOME/.local/bin/testing:$CARGO_HOME/bin:$GOPATH/bin:$HOME/.local/bin:/opt/REAPER:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin"
diff --git a/zsh/.zshrc b/zsh/.zshrc
new file mode 100644
index 0000000..1c13e80
--- /dev/null
+++ b/zsh/.zshrc
@@ -0,0 +1,79 @@
+HISTFILE="$ZDOTDIR"/hist
+SAVEHIST=1000
+HISTSIZE=1000
+setopt APPEND_HISTORY
+setopt HIST_FIND_NO_DUPS
+setopt HIST_EXPIRE_DUPS_FIRST
+setopt HIST_VERIFY
+setopt HIST_IGNORE_DUPS
+setopt INC_APPEND_HISTORY
+setopt HIST_REDUCE_BLANKS
+
+if [ -f "$XDG_CONFIG_HOME"/sh/aliases ]; then
+ source "$XDG_CONFIG_HOME"/sh/aliases
+fi
+if [ -f "$XDG_CONFIG_HOME"/sh/functions ]; then
+ source "$XDG_CONFIG_HOME"/sh/functions
+fi
+
+bindkey "^?" backward-delete-char
+
+# bindkey -v
+
+if [ "$TERM" = "st-256color" ] || [ "$TERM" = "xterm-256color" ]; then
+ function zle-line-init () { echoti smkx }
+ function zle-line-finish () { echoti rmkx }
+
+ zle -N zle-line-init
+ zle -N zle-line-finish
+fi
+
+which pacman >/dev/null && COLOR1="cyan"
+which apt >/dev/null && COLOR1="green"
+which syspatch >/dev/null && COLOR1="red"
+
+MYPROMPT='%B%F{'"$COLOR1"'}[%n@%m]:%f%F{white}%~%f%F{'"$COLOR1"'}%#%f%b '
+function zle-line-init zle-keymap-select {
+ VIM_PROMPT="%B%F{blue}[%n@%m]:%f%F{white}%~%f%F{blue}%#%f%b "
+ PS1="${${KEYMAP/vicmd/$VIM_PROMPT}/main/$MYPROMPT}"
+ #PS1="$PROMPT $KEYMAP"
+ zle reset-prompt
+}
+
+zle -N zle-line-init
+zle -N zle-keymap-select
+export KEYTIMEOUT=1
+
+autoload -Uz compinit promptinit
+compinit -d $CONFIG/zcompdump
+promptinit
+autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
+zle -N up-line-or-beginning-search
+zle -N down-line-or-beginning-search
+
+zstyle ':completion:*' menu select
+zstyle ':completion::complete:*' gain-privileges 1
+zstyle ':completion:*' rehash true
+
+setopt COMPLETE_ALIASES
+setopt AUTO_CD
+
+typeset -g -A key
+
+key[Up]="${terminfo[kcuu1]}"
+key[Down]="${terminfo[kcud1]}"
+key[Left]="${terminfo[kcub1]}"
+key[Right]="${terminfo[kcuf1]}"
+key[Shift-Tab]="${terminfo[kcbt]}"
+key[Delete]="${terminfo[kdch1]}"
+
+[[ -n "${key[Up]}" ]] && bindkey -- "${key[Up]}" up-line-or-beginning-search
+bindkey -- '^[[A' up-line-or-beginning-search
+bindkey -- '^[[B' down-line-or-beginning-search
+[[ -n "${key[Down]}" ]] && bindkey -- "${key[Down]}" down-line-or-beginning-search
+[[ -n "${key[Left]}" ]] && bindkey -- "${key[Left]}" backward-char
+[[ -n "${key[Right]}" ]] && bindkey -- "${key[Right]}" forward-char
+[[ -n "${key[Shift-Tab]}" ]] && bindkey -- "${key[Shift-Tab]}" reverse-menu-complete
+[[ -n "${key[Delete]}" ]] && bindkey -- "${key[Delete]}" delete-char
+
+#eval "$(starship init zsh)"