diff --git a/.bashrc b/.bashrc
index 0fc9eae..4a2754f 100644
--- a/.bashrc
+++ b/.bashrc
@@ -24,5 +24,8 @@ esac
[ -r /usr/share/bash-completion/bash_completion ] && . /usr/share/bash-completion/bash_completion
#export PS1="\[\033[38;5;6m\][\[$(tput sgr0)\]\[\033[38;5;83m\]\u\[$(tput sgr0)\]\[\033[38;5;77m\]@\[$(tput sgr0)\]\[\033[38;5;112m\]\h\[$(tput sgr0)\] \[$(tput sgr0)\]\[\033[38;5;42m\]\W\[$(tput sgr0)\]\[\033[38;5;6m\]]\[$(tput sgr0)\]\[\033[38;5;81m\]\\$\[$(tput sgr0)\] \[$(tput sgr0)\]"
+export PS1="[\W] \\$ "
+set -o vi
source ~/.config/env
+source "/home/dizzy/.local/share/cargo/env"
diff --git a/.config/alacritty.yml b/.config/alacritty.yml
index 8101b22..a7ccc86 100644
--- a/.config/alacritty.yml
+++ b/.config/alacritty.yml
@@ -96,7 +96,7 @@ font:
# - (macOS) Menlo
# - (Linux/BSD) monospace
# - (Windows) Consolas
- family: Terminus
+ family: iosevka
# The `style` can be specified to pick a specific face.
style: Regular
@@ -107,7 +107,7 @@ font:
#
# If the bold family is not specified, it will fall back to the
# value specified for the normal font.
- family: Terminus
+ family: iosevka
# The `style` can be specified to pick a specific face.
style: Bold
@@ -118,7 +118,7 @@ font:
#
# If the italic family is not specified, it will fall back to the
# value specified for the normal font.
- family: Terminus
+ family: iosevka
# The `style` can be specified to pick a specific face.
style: Italic
@@ -129,13 +129,13 @@ font:
#
# If the bold italic family is not specified, it will fall back to the
# value specified for the normal font.
- family: Terminus
+ family: iosevka
# The `style` can be specified to pick a specific face.
style: Bold Italic
# Point size
- size: 11.0
+ size: 9.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.
@@ -163,15 +163,15 @@ font:
colors:
# Default colors
primary:
- background: '#1d1f21'
- foreground: '#c5c8c6'
+ background: '#000000'
+ foreground: '#FFFFFF'
# 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'
+ dim_foreground: '#FFFFFF'
bright_foreground: '#eaeaea'
# Cursor colors
@@ -310,7 +310,7 @@ colors:
#
# Window opacity as a floating point number from `0.0` to `1.0`.
# The value `0.0` is completely transparent and `1.0` is opaque.
-background_opacity: 1.00
+background_opacity: 0.95
#selection:
#semantic_escape_chars: ",│`|:\"' ()[]{}<>\t"
diff --git a/.config/cdm/cdmrc b/.config/cdm/cdmrc
index 1ac2346..d13d87e 100644
--- a/.config/cdm/cdmrc
+++ b/.config/cdm/cdmrc
@@ -11,7 +11,7 @@
binlist=(
#'~/.config/cdm/dwm-cdm' # Launch dwm,
'startx ~/.config/cdm/dwm-xinit' # Launch dwm,
- 'startx ~/.config/cdm/lxde-xinit' # Launch lxde desktop,
+ 'startx ~/.config/cdm/gnome-cdm' # Launch guh-nome desktop,
'startx ~/.config/cdm/mate-xinit' # Launch mate desktop,
'/bin/bash --login' # Execute your Shell,
'reboot' # Reboot
@@ -22,7 +22,7 @@ binlist=(
# Names with whitespaces should be quoted or escaped.
#
# (Continued example:)
-namelist=('dwm' 'LXDE' 'MATE' 'Console' 'Reboot' 'Shutdown')
+namelist=('dwm' 'gnome' 'MATE' 'Console' 'Reboot' 'Shutdown')
# Type of the programs, one-by-one matched with $binlist.
# `C' for *C*onsole programs, which would be `exec'ed.
diff --git a/.config/cdm/dwm-xinit b/.config/cdm/dwm-xinit
index 2cc8d55..e4a23e7 100644
--- a/.config/cdm/dwm-xinit
+++ b/.config/cdm/dwm-xinit
@@ -1,6 +1,5 @@
exec feh --no-fehbg --bg-fill ~/proj/sysconf/wallpapers/wallpaper &
-exec rm -r ~/.cache/wal &
-exec wal -i ~/proj/sysconf/wallpapers/wallpaper &
+exec rm ~/.cache/wal/ &
#exec statusbar &
exec slstatus &
exec picom --config ~/.config/picom.conf &
@@ -10,6 +9,7 @@ exec xrandr --auto --output HDMI1 --mode 1024x768 --right-of eDP1 &
exec /usr/lib/kdeconnectd &
#exec dunst &
exec xmodmap ~/.config/Xmodmap &
-exec xrdb -merge ~/.cache/wal/colors.Xresources &
+exec xrdb ~/.cache/wal/colors.Xresources &
exec source ~/.config/env &
+exec xscreensaver -no-splash &
exec dbus-launch dwm
diff --git a/.config/env b/.config/env
index bd79181..b2643aa 100644
--- a/.config/env
+++ b/.config/env
@@ -4,6 +4,7 @@
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
+export XDG_BIN_HOME="$HOME/.local/bin"
# Default Programs
export EDITOR="nvim"
@@ -12,6 +13,7 @@ export TERMINAL="alacritty"
export BROWSER="firefox"
export PATH="$XDG_DATA_HOME/gem/bin:$PATH"
+export PATH="$XDG_BIN_HOME:$PATH"
export GPG_TTY=$(tty)
diff --git a/.config/firejail/librewolf.profile b/.config/firejail/librewolf.profile
new file mode 100644
index 0000000..591eb19
--- /dev/null
+++ b/.config/firejail/librewolf.profile
@@ -0,0 +1,29 @@
+# Firejail profile for Librewolf
+# Description: Firefox fork based on privacy
+# This file is overwritten after every install/update
+# Persistent local customizations
+include librewolf.local
+# Persistent global definitions
+include globals.local
+
+noblacklist ${HOME}/.cache/librewolf
+noblacklist ${HOME}/.librewolf
+
+mkdir ${HOME}/.cache/librewolf
+mkdir ${HOME}/.librewolf
+whitelist ${HOME}/.cache/librewolf
+whitelist ${HOME}/.librewolf
+whitelist ${HOME}/dl
+
+# Uncomment (or add to librewolf.local) the following lines if you want to
+# use the migration wizard.
+#noblacklist ${HOME}/.mozilla
+#whitelist ${HOME}/.mozilla
+
+# librewolf requires a shell to launch on Arch. We can possibly remove sh though.
+#private-bin bash,dbus-launch,dbus-send,env,librewolf,python*,sh,which
+# private-etc must first be enabled in firefox-common.profile
+#private-etc librewolf
+
+# Redirect
+include firefox-common.profile
diff --git a/.config/firejail/newsboat.profile b/.config/firejail/newsboat.profile
index 242b56b..6dc7aa0 100644
--- a/.config/firejail/newsboat.profile
+++ b/.config/firejail/newsboat.profile
@@ -1,50 +1,72 @@
# Firejail profile for Newsboat
# Description: RSS program
-# This file is overwritten after every install/update
-# Persistent local customizations
-include newsboat.local
-# Persistent global definitions
-include globals.local
-noblacklist ${HOME}/.config/newsboat
+#include default.profile
-include disable-common.inc
-include disable-devel.inc
-include disable-exec.inc
-include disable-interpreters.inc
-include disable-passwdmgr.inc
-include disable-programs.inc
-include disable-xdg.inc
-
-mkdir ${HOME}/.config/newsboat
-whitelist ${HOME}/.config/newsboat
-include whitelist-common.inc
-include whitelist-runuser-common.inc
-include whitelist-var-common.inc
-
-caps.drop all
-ipc-namespace
-netfilter
-no3d
-nodvd
-nogroups
-nonewprivs
-noroot
-notv
-nou2f
-novideo
-protocol inet,inet6
-seccomp
-shell none
-
-disable-mnt
-private-bin newsboat
-private-cache
-private-dev
-private-etc alternatives,ca-certificates,crypto-policies,pki,resolv.conf,ssl,terminfo
-private-tmp
-
-dbus-user none
-dbus-system none
-
-memory-deny-write-execute
+#include newsboat.local
+## Persistent global definitions
+#include globals.local
+#
+#noblacklist ${HOME}/.config/newsboat
+#noblacklist ${HOME}/.cache/newsboat
+#noblacklist ${HOME}/vimwiki/news/
+#whitelist ${HOME}/.config/newsboat
+#whitelist ${HOME}/.cache/newsboat
+#whitelist ${HOME}/vimwiki/news/
+#
+### mpv
+##private-bin mpv
+##whitelist ${HOME}/.config/mpv
+##whitelist ${HOME}/.config/youtube-dl
+##whitelist ${HOME}/.netrc
+##include whitelist-common.inc
+##include whitelist-players.inc
+##whitelist /usr/share/lua
+##whitelist /usr/share/lua*
+##whitelist /usr/share/vulkan
+##include whitelist-usr-share-common.inc
+##include whitelist-var-common.inc
+##private-bin env,mpv,python*,waf,youtube-dl
+#
+## Lynx private-bin sh,gzip,lynx
+##private-etc lynx.cfg,lynx.lss
+#
+#include disable-common.inc
+#include disable-devel.inc
+#include disable-exec.inc
+#include disable-interpreters.inc
+#include disable-passwdmgr.inc
+#include disable-programs.inc
+#include disable-xdg.inc
+#
+##mkdir ${HOME}/.newsboat
+#whitelist ${HOME}/.newsboat
+#include whitelist-common.inc
+#
+#apparmor
+#caps.drop all
+#ipc-namespace
+#netfilter
+#no3d
+#nodvd
+#nogroups
+#nonewprivs
+#noroot
+#notv
+#nou2f
+#novideo
+#protocol unix,inet,inet6,netlink
+#seccomp
+#shell none
+#
+#disable-mnt
+#private-bin newsboat
+#private-cache
+#private-dev
+#private-etc alternatives,ca-certificates,crypto-policies,pki,resolv.conf,ssl,terminfo
+#private-tmp
+#
+#dbus-user none
+#dbus-system none
+#
+#memory-deny-write-execute
diff --git a/.config/firejail/transmission-common.profile b/.config/firejail/transmission-common.profile
deleted file mode 100644
index 95be2c0..0000000
--- a/.config/firejail/transmission-common.profile
+++ /dev/null
@@ -1,56 +0,0 @@
-# Firejail profile for transmission-common
-# Description: Fast, easy and free BitTorrent client
-# This file is overwritten after every install/update
-# Persistent local customizations
-include transmission-common.local
-# Persistent global definitions
-# added by caller profile
-#include globals.local
-
-noblacklist ${HOME}/.cache/transmission
-noblacklist ${HOME}/.config/transmission
-noblacklist ${HOME}/dox/torrents
-
-include disable-common.inc
-include disable-devel.inc
-include disable-exec.inc
-include disable-interpreters.inc
-include disable-passwdmgr.inc
-include disable-programs.inc
-
-mkdir ${HOME}/.cache/transmission
-mkdir ${HOME}/.config/transmission
-mkdir ${HOME}/dox/torrents
-whitelist ${DOWNLOADS}
-whitelist ${HOME}/.cache/transmission
-whitelist ${HOME}/.config/transmission
-whitelist ${HOME}/dox/torrents
-include whitelist-common.inc
-include whitelist-usr-share-common.inc
-include whitelist-var-common.inc
-
-apparmor
-caps.drop all
-machine-id
-netfilter
-nodvd
-nonewprivs
-noroot
-nosound
-notv
-nou2f
-novideo
-protocol unix,inet,inet6
-seccomp
-shell none
-tracelog
-
-private-cache
-private-dev
-private-lib
-private-tmp
-
-dbus-user none
-dbus-system none
-
-memory-deny-write-execute
diff --git a/.config/firejail/virtualbox.profile b/.config/firejail/virtualbox.profile
deleted file mode 100644
index 7a49ad8..0000000
--- a/.config/firejail/virtualbox.profile
+++ /dev/null
@@ -1,50 +0,0 @@
-# Firejail profile for virtualbox
-# Description: x86 virtualization solution
-# This file is overwritten after every install/update
-# Persistent local customizations
-include virtualbox.local
-# Persistent global definitions
-include globals.local
-
-noblacklist ${HOME}/.VirtualBox
-noblacklist ${HOME}/.config/VirtualBox
-noblacklist ${HOME}/VirtualBox VMs
-# noblacklist /usr/bin/virtualbox
-noblacklist /usr/lib/virtualbox
-noblacklist /usr/lib64/virtualbox
-
-include disable-common.inc
-include disable-devel.inc
-include disable-exec.inc
-include disable-interpreters.inc
-include disable-passwdmgr.inc
-include disable-programs.inc
-include disable-xdg.inc
-
-mkdir ${HOME}/.config/VirtualBox
-mkdir ${HOME}/VirtualBox VMs
-whitelist ${HOME}/.config/VirtualBox
-whitelist ${HOME}/VirtualBox VMs
-whitelist ${DOWNLOADS}
-whitelist /usr/share/virtualbox
-include whitelist-common.inc
-include whitelist-runuser-common.inc
-include whitelist-usr-share-common.inc
-include whitelist-var-common.inc
-
-# For host-only network sys_admin is needed. See https://github.com/netblue30/firejail/issues/2868#issuecomment-518647630
-
-caps.keep net_raw,sys_nice
-netfilter
-nodvd
-#nogroups
-notv
-shell none
-tracelog
-
-#disable-mnt
-private-cache
-private-etc alsa,asound.conf,ca-certificates,conf.d,crypto-policies,dconf,fonts,hostname,hosts,ld.so.cache,localtime,machine-id,pki,pulse,resolv.conf,ssl
-
-dbus-user none
-dbus-system none
diff --git a/.config/lynx/lynx.cfg b/.config/lynx/lynx.cfg
index 21d05b5..7d5b66e 100644
--- a/.config/lynx/lynx.cfg
+++ b/.config/lynx/lynx.cfg
@@ -1527,7 +1527,7 @@ SAVE_SPACE:~/dl/
.h2 EMACS_KEYS_ALWAYS_ON
# Vi or Emacs movement keys, i.e. familiar hjkl or ^N^P^F^B .
# These are defaults, which can be changed in the Options Menu or .lynxrc .
-#VI_KEYS_ALWAYS_ON:FALSE
+VI_KEYS_ALWAYS_ON:TRUE
#EMACS_KEYS_ALWAYS_ON:FALSE
.h2 DEFAULT_KEYPAD_MODE
diff --git a/.config/newsboat/config b/.config/newsboat/config
index 8e41e66..a63868b 100644
--- a/.config/newsboat/config
+++ b/.config/newsboat/config
@@ -1,16 +1,43 @@
+# -- feeds
auto-reload yes
-reload-threads 100
-
+reload-threads 4
+download-retries 4
+download-timeout 10
cache-file "~/.config/newsboat/cache.db"
-# unbind keys
-unbind-key j
-unbind-key k
-unbind-key J
-unbind-key K
+# -- display
+text-width 80
-# bind keys - vim style
-bind-key j down
-bind-key k up
-bind-key l open
-bind-key h quit
+# -- navigation
+goto-next-feed no
+
+browser "lynx -nocolor"
+bind-key j down feedlist
+bind-key k up feedlist
+bind-key j next articlelist
+bind-key k prev articlelist
+bind-key J next-feed articlelist
+bind-key K prev-feed articlelist
+bind-key j down article
+bind-key k up article
+
+# -- macros
+macro m set browser "mpv --ytdl %u --profile=360p > /dev/null &"; open-in-browser ; set browser "lynx -nocolor"
+macro a set browser "echo %u | xclip -sel clip"; open-in-browser ; set browser "lynx -nocolor"
+
+# -- podboat
+delete-played-files no
+download-path "~/dox/pod/%h/%n"
+max-downloads 4
+player "play"
+
+# -- color
+color listfocus white black bold
+color listfocus_unread white black bold
+color info white black bold
+#color article white black
+
+# -- misc
+unbind-key C feedlist
+confirm-exit no
+cleanup-on-quit no
diff --git a/.config/newsboat/urls b/.config/newsboat/urls
deleted file mode 100644
index f584f3b..0000000
--- a/.config/newsboat/urls
+++ /dev/null
@@ -1,35 +0,0 @@
------------------------
--------NEWSFEEDS-------
------------------------
-https://xkcd.com/atom.xml "~XKCD"
-https://www.linuxjournal.com/news.rss
-https://itsfoss.com/feed "~ItsFOSS"
-https://archlinux.org/feeds/packages/added/x86_64 "~ArchWiki: Added Packages"
-https://archlinux.org/feeds/packages/removed/x86_64 "~ArchWiki: Removed Packages"
-https://opensource.org/news.xml "~Opensource News"
-https://security.archlinux.org/ "~ArchLinux Security Issues"
-https://www.welivesecurity.com/feed "~WeLiveSecurity RSS"
-
------------------------
--------YOUTUBE---------
------------------------
-
------------------------
--------REDDIT----------
------------------------
-https://www.reddit.com/r/linux.rss "~REDDIT: r/linux"
-https://www.reddit.com/r/archlinux.rss "~REDDIT: r/archlinux"
-https://www.reddit.com/r/Gentoo.rss "~REDDIT: r/gentoo"
-https://www.reddit.com/r/debian.rss "~REDDIT: r/debian"
-https://www.reddit.com/r/freebsd.rss "~REDDIT: r/freebsd"
-https://www.reddit.com/r/privacy.rss "~REDDIT: r/privacy"
-https://www.reddit.com/r/privacytoolsIO.rss "~REDDIT: r/privacytoolsIO"
-https://www.reddit.com/r/encryption.rss "~REDDIT: r/encryption"
-https://www.reddit.com/r/GnuPG.rss "~REDDIT: r/GnuPG"
-https://www.reddit.com/r/rss.rss "~REDDIT: r/rss"
-https://www.reddit.com/r/tryhackme.rss "~REDDIT: r/tryhackme"
-
------------------------
--------GIT-REPOS-------
------------------------
-https://lkml.org/rss.php "~Linux Kernel Mailing Lists"
diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim
index 1504d52..e3439b3 100755
--- a/.config/nvim/init.vim
+++ b/.config/nvim/init.vim
@@ -12,6 +12,10 @@ Plug 'tpope/vim-sleuth'
Plug 'editorconfig/editorconfig'
Plug 'airblade/vim-gitgutter'
Plug 'preservim/nerdcommenter'
+Plug 'Vimjas/vim-python-pep8-indent'
+" Debugging plugins
+Plug 'realaltffour/comprog.nvim', { 'branch': 'test' }
+"Plug '~/.config/nvim/plugged/comprog.nvim'
call plug#end()
filetype plugin indent on
diff --git a/.config/wal/templates/dunstrc b/.config/wal/templates/dunstrc
index a4116f6..2e5a636 100644
--- a/.config/wal/templates/dunstrc
+++ b/.config/wal/templates/dunstrc
@@ -1,147 +1,96 @@
[global]
- ### Display ###
+font = Iosevka Term 9
- # Which monitor should the notifications be displayed on.
- monitor = 0
+markup = yes
+plain_text = no
+format = "%s\n%b"
- follow = mouse
+sort = no
- geometry = "300x5-30+20"
+indicate_hidden = yes
- indicate_hidden = yes
+alignment = center
- shrink = no
+bounce_freq = 0
- transparency = 0
+show_age_threshold = -1
- notification_height = 0
+word_wrap = yes
- separator_height = 2
+ignore_newline = no
- padding = 8
+stack_duplicates = yes
+hide_duplicate_count = yes
- horizontal_padding = 8
+geometry = "300x20-15+20"
- frame_width = 3
+shrink = no
- frame_color = "{color4}"
+transparency = 5
- separator_color = frame
+idle_threshold = 0
- sort = yes
+monitor = 0
- idle_threshold = 120
+follow = none
- ### Text ###
+sticky_history = yes
- font = Monospace 8
+history_length = 15
- line_height = 0
+show_indicators = no
- markup = full
+line_height = 0
- format = "%s\n%b"
+separator_height = 2
- alignment = left
+padding = 0
- vertical_alignment = center
+horizontal_padding = 0
- show_age_threshold = 60
+separator_color = frame
- word_wrap = yes
+startup_notification = false
- ellipsize = middle
+dmenu = /usr/bin/dmenu -p dunst:
- ignore_newline = no
+browser = /usr/bin/firefox -new-tab
- stack_duplicates = true
+icon_position = off
+max_icon_size = 80
- hide_duplicate_count = false
+icon_path = /usr/share/icons/Paper/16x16/mimetypes/:/usr/share/icons/Paper/48x48/status/:/usr/share/icons/Paper/16x16/devices/:/usr/share/icons/Paper/48x48/notifications/:/usr/share/icons/Paper/48x48/emblems/
- show_indicators = yes
-
- icon_position = left
-
- min_icon_size = 0
-
- max_icon_size = 32
-
- icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
-
- sticky_history = yes
-
- history_length = 20
-
- dmenu = /usr/bin/dmenu -p dunst:
-
- browser = /usr/bin/firefox -new-tab
-
- always_run_script = true
-
- title = Dunst
-
- class = Dunst
-
- startup_notification = false
-
- verbosity = mesg
-
- corner_radius = 0
-
- ignore_dbusclose = false
-
- force_xinerama = false
-
- mouse_left_click = close_current
- mouse_middle_click = do_action, close_current
- mouse_right_click = close_all
-
-[experimental]
- per_monitor_dpi = false
+frame_width = 1
+frame_color = "#000000"
[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 = ctrl+space
- # Close all notifications.
- close_all = ctrl+shift+space
+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
+history = ctrl+grave
- # Context menu.
- context = ctrl+shift+period
+context = ctrl+shift+period
+
+frame_color = "{color1}"
[urgency_low]
- # IMPORTANT: colors have to be defined in quotation marks.
- # Otherwise the "#" and following would be interpreted as a comment.
- background = "{background}"
- foreground = "{foreground}"
- timeout = 10
- # Icon for notifications with low urgency, uncomment to enable
- #icon = /path/to/icon
+foreground = "{foreground}"
+background = "{background}"
+timeout = 4
[urgency_normal]
- background = "{background}"
- foreground = "{foreground}"
- timeout = 10
- # Icon for notifications with normal urgency, uncomment to enable
- #icon = /path/to/icon
+foreground = "{foreground}"
+background = "{background}"
+timeout = 6
[urgency_critical]
- background = "{background}"
- foreground = "{foreground}"
- frame_color = "{color4}"
- timeout = 0
- # Icon for notifications with critical urgency, uncomment to enable
- #icon = /path/to/icon
+foreground = "{foreground}"
+background = "{background}"
+timeout = 8
+
+
# vim: ft=cfg
diff --git a/.local/bin/add_wallpaper b/.local/bin/add_wallpaper
new file mode 100755
index 0000000..233175e
--- /dev/null
+++ b/.local/bin/add_wallpaper
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+wallpaper_link=$(xclip -o -sel clipboard)
+notify-send "Downloading wallpaper..."
+curl $wallpaper_link > /tmp/waly
+notify-send "Finished downloading..."
+
+wal_name=(dmenu -p "Name the wallpaper: ")
+
+# Find wallpaper last ID
+wal_ids=$(ls $HOME/pix/wallpapers/)
+max=000
+
+for i in $wal_ids
+do
+ id=$(echo $i | awk 'BEGIN {FS="-"} ; {print $1}')
+ if [ $(echo "$id > $max" | bc) = "1" ]
+ then
+ max=$id
+ fi
+done
+
+# Gen wallpaper new ID
+new_wal_id=$(echo "$max+1" | bc)
+new_wal_id=$(printf %03d $new_wal_id)
+
+# Get name of new wallpaper
+title=$(echo "$wallpaper_link" | dmenu -p "Name of Wallpaper: $new_wal_id-")
+[ -z $title ] && exit
+
+# Generate final location and move
+final_wal_loc=$HOME/pix/wallpapers/$new_wal_id-$title
+mv /tmp/waly $final_wal_loc
+notify-send "Added wallpaper to collection"
diff --git a/.local/bin/protonvpn b/.local/bin/cf-run
similarity index 83%
rename from .local/bin/protonvpn
rename to .local/bin/cf-run
index accab50..1859db9 100755
--- a/.local/bin/protonvpn
+++ b/.local/bin/cf-run
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
import re
import sys
-from protonvpn_cli.cli import main
+from codeforces.cf_run import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
diff --git a/.local/bin/change_wallpaper b/.local/bin/change_wallpaper
new file mode 100755
index 0000000..2f1f2fd
--- /dev/null
+++ b/.local/bin/change_wallpaper
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+removed=$HOME/pix/wallpapers/
+wal_name=$(find $HOME/pix/wallpapers/ -type f | awk 'BEGIN {FS="/"} ; {print $6}' | dmenu -i -l 25)
+cp -f $removed/$wal_name ~/pix/wallpapers/wallpaper
+refresh_wallpaper
diff --git a/.local/bin/dbrowsel b/.local/bin/dbrowsel
new file mode 100755
index 0000000..ee3daca
--- /dev/null
+++ b/.local/bin/dbrowsel
@@ -0,0 +1,20 @@
+#!/usr/bin/env sh
+
+# Dmenu for selecting which browser to open.
+
+Browsers='1. AC
+2. ACB
+3. CB
+4. O'
+
+Chosen=$(printf '%s' "$Browsers" \
+ | dmenu -i -l 20 -p 'Select browser:')
+[ -z "$Chosen" ] && exit 1
+
+case $Chosen in
+ '1. AC') firefox -P AC "$@";;
+ '2. ACB') firefox -P ACB "$@";;
+ '3. CB') firefox -P CB "$@";;
+ '4. O') firefox -P O "$@";;
+ *) eval "$Chosen" "$@";;
+esac
diff --git a/.local/bin/dbuku b/.local/bin/dbuku
new file mode 100755
index 0000000..ce07d47
--- /dev/null
+++ b/.local/bin/dbuku
@@ -0,0 +1,128 @@
+#!/usr/bin/env sh
+
+# Dmenu for saving the currently open website into buku.
+
+# Instructions for saving:
+# Currently works for qutebrowser and chromium based browsers.
+# Press TAB to autocomplete the default so you can edit it.
+# Press ENTER to accept your changes (if you did nothing it'll be the default).
+# Press ESCAPE to go with the default value (in case of tags it'll accept them).
+# To cancel out of adding it, just keep spamming ESCAPE until you reach the
+# last prompt where you're asked to confirm or deny.
+
+### Known problems:
+### * If using this script with 'shift' as part of the hotkey the shift key
+### gets stuck if you let go of it while xdotool is doing its thing.
+### Can be solved by not using the shift key in the hotkey.
+### * Can't figure out why xdotool fails sometimes. Fixed by sleeping a bit.
+### * When you try to open a bookmark the list shows an extra line at the start
+### saying "waiting for input" when the script is run with a hotkey (sxhkd).
+### Can't figure out why.
+
+### Should check if the yanked URL is in buku already before continuing.
+### Though it'll simply give an error even if you try to add it.
+
+ScriptName=${0##*/}
+Version=1.0.0
+
+# Set menu options:
+MenuOpen='1. Open a bookmark.'
+MenuSave='2. Create new bookmark.'
+
+ChosenMenu=$(printf '%s\n%s' \
+ "$MenuOpen" "$MenuSave" \
+ | dmenu -i -l 10 -p "$ScriptName:")
+
+# Open bookmark:
+if [ "$ChosenMenu" = "$MenuOpen" ]; then
+ buku -p -f 5 \
+ | awk -F '\t' '{print $1, "-", $2, "#(" $3 ")"}' \
+ | dmenu -i -l 30 \
+ | awk '{print $1}' \
+ | xargs --no-run-if-empty buku -o
+
+# Create bookmark:
+elif [ "$ChosenMenu" = "$MenuSave" ]; then
+ # Get the name of the active window:
+ ActiveWindow=$(ps -p "$(xdotool getwindowfocus getwindowpid)" -o comm=)
+
+ # Set the name if the active window is a chromium based browser:
+ printf '%s' "$ActiveWindow" | grep -Eq 'chromium|chrome|brave' \
+ && ActiveWindow='chromium-based'
+ ### Haven't actually checked whether Chromium's window name is chromium.
+
+ # Get URL/title based on browser:
+ if [ "$ActiveWindow" = 'qutebrowser' ]; then
+ xdotool search --name qutebrowser key --clearmodifiers y P
+ sleep 0.1
+ URL=$(xclip -o)
+ sleep 0.1
+ xdotool search --name qutebrowser key --clearmodifiers y T
+ sleep 0.1
+ Title=$(xclip -o)
+ elif [ "$ActiveWindow" = 'chromium-based' ]; then
+ xdotool key --clearmodifiers ctrl+l
+ sleep 0.1
+ xdotool key --clearmodifiers ctrl+c
+ sleep 0.1
+ URL=$(xclip -o)
+ sleep 0.1
+ ### Maybe write it to a file in the background to speed it up.
+ ### Doesn't work for some generated sites.
+ Title=$(curl -s "$URL" \
+ | awk -F '
|' '{for(i=2;i<=NF;i+=2){print $i}}' \
+ RS='' \
+ | recode html)
+ fi
+
+ # Prompt user to edit the URL:
+ EditedURL=$(printf "%s" "$URL" | dmenu -l 1 -p "Edit URL:")
+ [ "$EditedURL" ] && URL=$EditedURL
+
+ # Prompt user to edit the title:
+ EditedTitle=$(printf '%s' "$Title" | dmenu -l 1 -p 'Edit title:')
+ [ "$EditedTitle" ] && Title=$EditedTitle
+
+ # Prompt the user to pick tags for the bookmark:
+ BukuTags=$(buku -t)
+ BukuTags=$(printf '%s' "$BukuTags" \
+ | grep '[0-9]\..' \
+ | awk '{print $2}')
+ # awk is POSIX, but means you need to avoid spaces in tags.
+ #| grep -oP '(?<=[0-9]\.\s).+(?=\s\([0-9])')
+ # grep -oP is non-POSIX, but allows for spaces in tags.
+ while true; do
+ SelectedTag=$(printf '%s' "$BukuTags" \
+ | dmenu -i -l 30 \
+ -p "Add tags. SHIFT+ENTER to create a new tag. $Tags")
+ [ -z "$SelectedTag" ] && break
+ Tags="$Tags$SelectedTag,"
+ done
+ Tags=$(printf '%s' "${Tags%?}")
+
+ # Prompt the user to add a comment/description:
+ Comment=$(printf '' | dmenu -p 'Input comment:')
+
+ # Prompt the user whether they want the title and description to not update:
+ Immutability=$(printf 'No\nYes' | dmenu -i -p 'Enable immutability?')
+ [ "$Immutability" = 'Yes' ] && Immutable='--immutable 1'
+ [ "$Immutability" = 'No' ] && Immutable=''
+
+ # Create a preview for the user to see their input:
+ Lock=''
+ [ "$Immutability" = 'Yes' ] && Lock='(L)'
+ Confirmation=$(printf '%s\nIDN. %s %s\n > %s\n + %s\n # %s' \
+ 'This is a preview. Press ENTER to confirm or ESCAPE to cancel.' \
+ "$Title" "$Lock" "$URL" "$Comment" "$Tags" \
+ | dmenu -i -l 5)
+
+ # If the user pressed ENTER, create the bookmark:
+ [ "$Confirmation" ] && \
+ buku $(printf '%s %s %s --title %s -c %s %s' \
+ '-a' "$URL" "$Tags" "$Title" "$Comment" "$Immutable")
+elif [ -z "$ChosenMenu" ]; then
+ exit 1
+else
+ printf 'ERROR: invalid selection.\n'
+ exit 1
+fi
diff --git a/.local/bin/ddiropen b/.local/bin/ddiropen
new file mode 100755
index 0000000..2eb9645
--- /dev/null
+++ b/.local/bin/ddiropen
@@ -0,0 +1,175 @@
+#!/usr/bin/env sh
+
+# Dmenu for opening a program with a specific directory.
+
+# MIT License
+#
+# Copyright (c) 2020 Alexander Chaplin Braz
+#
+# 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.
+
+ScriptName=${0##*/}
+Version=1.0.0
+
+# Set default bookmark if there is none:
+BlankMark='---'
+
+# Compose the help message:
+HelpMessage="$ScriptName - Version: $Version
+Creator: Alexander Chaplin Braz (https://alexchaplinbraz.com)
+License: MIT
+
+Usage: $ScriptName {dirpath | filepath} {programs} [mark]
+
+This script lets the user open a directory with a program
+using dmenu to select them. For this, it requires two arguments.
+
+The first one can either be a directory from which it will find all the
+subdirectories, or a file that holds a list of directories acting as bookmarks.
+It's highly recommended to use absolute paths, but relative paths also work.
+
+The second one has to be a comma separated list of programs which can be
+unquoted, but quoting it gives the user the ability to specify options
+for the programs.
+
+An optional third argument lets the user change the default bookmark name
+when no bookmark name was set in the bookmark file. Default: $BlankMark
+
+The bookmark file must have a format where the path is at the start of a line.
+One optional bookmark name can be set after the path by separating them with a
+tab. Nothing from column 3+ is parsed. So you can use it freely to add comments
+or whatever. You can also comment out lines with any character (other than \"),
+thus breaking the path, so it won't show up as an option.
+
+In the case where there's only one program and/or directory, they will be
+selected automatically.
+
+Usage examples:
+ $ScriptName \$HOME vifm,lf,sxiv
+ $ScriptName \ ranger,vifm
+ $ScriptName \"\$HOME/Pictures\" \"sxiv -t,sxiv -arf\"
+ $ScriptName \"\$HOME/Documents/dir-bookmarks.txt\" lf
+ $ScriptName \"\$HOME/Documents/dir-bookmarks.txt\" lf ###
+
+Example bookmarks file (keep in mind the tab separation):
+
+\$HOME HM
+\"\$HOME/Pictures/Art References\" AR
+\"\$XDG_CONFIG_HOME\" CNF
+#\$COMMENT CM COMMENT: this can be whatever since it's not parsed.
+/mnt MNT
+/etc ETC
+/backup BU
+"
+
+suggest_help_and_exit() {
+ printf "Try '%s --help' for more information.\n" "$ScriptName"
+ exit 1
+}
+
+case $1 in
+ '') printf '%s' "$HelpMessage"; exit 1;;
+ -h|--help) printf '%s' "$HelpMessage"; exit 0;;
+ -v|--version) printf '%s - Version: %s\n' "$ScriptName" "$Version"; exit 0;;
+esac
+
+# Set custom blank mark if it was set by the user:
+[ "$3" ] && BlankMark=$3
+
+# Set a location for the temporary file that holds the found directories:
+TempFile="/tmp/$ScriptName-dirs"
+
+# Set up a function that can be called to run in the background:
+find_directories() {
+ find "$1" -type d 2>/dev/null > "$TempFile"
+ printf '%s' "$ScriptName ENDofSEARCH" >> "$TempFile"
+}
+
+# Parse the passed programs:
+Parsed=$(printf '%s' "$2" | tr -s ',' '\n')
+
+# Count the amount of programs:
+ProgramAmount=$(printf '%s\n' "$Parsed" | wc -l)
+
+# Determine whether the first argument is a directory or a file:
+if [ -d "$1" ]; then
+ Directory=$1
+elif [ "$(file -i "$1" | awk '{printf $2}')" = 'text/plain;' ]; then
+ cat "$1" | while IFS= read -r line; do
+ line=$(printf '%s' "$line" \
+ | awk -F '\t' -v blank=$BlankMark \
+ '{print match($2, /[^ ]/) ? $2 : blank, $1}' OFS='\t')
+ path=$(printf '%s' "$line" | awk -F '\t' '{printf $2}')
+ eval [ -d "$path" ] 2>/dev/null \
+ && printf '%s\n' "$line" >> "$TempFile"
+ done
+ if [ ! -s "$TempFile" ]; then
+ printf 'ERROR: no valid directories in the specified file.\n'
+ suggest_help_and_exit
+ fi
+ [ $ProgramAmount = 1 ] && pn="[$Parsed] "
+ Directory=$(printf '%s' "$(cat "$TempFile")" \
+ | dmenu -i -l 30 -p "${pn}Select parent directory:" \
+ | awk -F '\t' '{printf $2}')
+else
+ printf 'ERROR: invalid first argument.\n'
+ suggest_help_and_exit
+fi
+
+# Delete the temporary file:
+rm "$TempFile" 2>/dev/null
+
+# Exit if no directory was selected:
+[ -z "$Directory" ] && exit 1
+
+# Do the directory search in the background:
+eval find_directories "$Directory" &
+
+# If there's only one program, skip selecting it:
+if [ $ProgramAmount = 1 ]; then
+ Program=$Parsed
+# Else, select the program first to hide the time taken to find the directories:
+else
+ Program=$(printf '%s' "$Parsed" \
+ | dmenu -i -l 30 -p 'Select program:')
+ [ -z "$Program" ] && exit 1
+fi
+
+# Wait until all directories have been found:
+until [ "$(tail -n 1 "$TempFile")" = "$ScriptName ENDofSEARCH" ]; do
+ sleep 0.1
+done
+
+# If there's only the result of the directory itself, select it:
+if [ $(wc -l "$TempFile" | awk '{printf $1}') = 1 ]; then
+ Chosen=$(sed '$d' "$TempFile")
+# Else, choose a directory:
+else
+ Chosen=$(sed '$d' "$TempFile" \
+ | dmenu -i -l 30 -p "[$Program] Select directory:")
+fi
+
+# Delete the temporary file:
+rm "$TempFile" 2>/dev/null
+
+# Exit if no directory was chosen:
+[ -z "$Chosen" ] && exit 1
+
+# Launch the selected program with the selected directory:
+eval "$Program" \""$Chosen"\"
diff --git a/.local/bin/dedit b/.local/bin/dedit
new file mode 100755
index 0000000..6de7677
--- /dev/null
+++ b/.local/bin/dedit
@@ -0,0 +1,29 @@
+#!/usr/bin/env sh
+
+# Dmenu for quickly finding and opening files to edit.
+# If '-r' is passed, it will search root relevant files and edit as root.
+
+# Find the files to be displayed:
+case $1 in
+ -r|--root) Files=$(sudo find '/etc' -type f)
+ AsRoot=' as root';;
+ *) Files1=$(find "$LBIN" -type l)
+ Files2=$(find "$HOME" "$LSHARE" -maxdepth 1 -type f)
+ Files3=$(find "$XDG_DOCUMENTS_DIR/notes" "$XDG_CONFIG_HOME" "$LBIN" -type f)
+ # Exclude some paths:
+ Files=$(printf "%s\n%s\n%s" "$Files1" "$Files2" "$Files3" | grep -Ev \
+ '.tdb|.sql|dump|eb26f4|google-chrome|VirtualBox|BraveSoftware|.config/cargo');;
+esac
+
+# Choose the file to open:
+Prompt="Select a file to edit${AsRoot}:"
+Chosen=$(printf '%s' "$Files" | dmenu -i -l 30 -p "$Prompt")
+[ -z "$Chosen" ] && exit 1
+
+# Open the editor with the selected file:
+if [ "$1" = '-r' ]; then
+ ### If `$EDITOR` is a GUI, permissions will likely get quite messed up.
+ sudo $EDITOR "$Chosen"
+else
+ $EDITOR "$Chosen"
+fi
diff --git a/.local/bin/demoji b/.local/bin/demoji
new file mode 100755
index 0000000..f9665b6
--- /dev/null
+++ b/.local/bin/demoji
@@ -0,0 +1,8 @@
+#!/usr/bin/env sh
+
+# Dmenu for selecting and copying an emoji.
+
+grep -v '#' "$LSHARE/emoji" \
+ | dmenu -i -l 20 -fn Symbola-16 \
+ | awk '{printf $1}' \
+ | xclip -selection clipboard
diff --git a/.local/bin/dkeys b/.local/bin/dkeys
new file mode 100755
index 0000000..d93e2cb
--- /dev/null
+++ b/.local/bin/dkeys
@@ -0,0 +1,28 @@
+#!/usr/bin/env sh
+
+# Dmenu for disabling/enabling keyboard keys.
+
+ScriptName=${0##*/}
+Version=1.0.0
+
+SuperLDisable='Disable Super_L'
+SuperLEnable='Enable Super_L'
+SuperRDisable='Disable Super_R'
+SuperREnable='Enable Super_R'
+
+KeyState=$(printf '%s\n%s\n%s\n%s' \
+ "$SuperLDisable" \
+ "$SuperLEnable" \
+ "$SuperRDisable" \
+ "$SuperREnable" \
+ | dmenu -i -l 10 -p "$ScriptName")
+
+case $KeyState in
+ "$SuperLDisable") Keycode='keycode 133 = 0x0000';;
+ "$SuperLEnable") Keycode='keycode 133 = 0xffeb';;
+ "$SuperRDisable") Keycode='keycode 134 = 0x0000';;
+ "$SuperREnable") Keycode='keycode 134 = 0xffec';;
+ *) exit 1;;
+esac
+
+xmodmap -e "$Keycode"
diff --git a/.local/bin/dlocate b/.local/bin/dlocate
new file mode 100755
index 0000000..92c0700
--- /dev/null
+++ b/.local/bin/dlocate
@@ -0,0 +1,93 @@
+#!/usr/bin/env sh
+
+# Dmenu for locating and opening paths.
+
+# MIT License
+#
+# Copyright (c) 2020 Alexander Chaplin Braz
+#
+# 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.
+
+ScriptName=${0##*/}
+Version=1.0.0
+
+# Compose the help message:
+HelpMessage="$ScriptName - Version: $Version
+Creator: Alexander Chaplin Braz (https://alexchaplinbraz.com)
+License: MIT
+
+Usage: $ScriptName {'programs'}
+
+Quickly find files and directories using 'locate', select one of the results
+and then select a program to open that path with.
+
+This script requires one argument of comma separated programs, which can be
+unquoted, but quoting it gives the user the ability to specify options
+for the programs.
+
+As it depends on 'locate', the database needs to be updated frequently for
+this script to be useful. It's recommended to have a cron job running
+'updatedb' every 15 or 30 minutes.
+
+At the program selection point it's also possible to simply write a
+non-specified program with arguments. If one of the dmenu options is still
+selected, SHIFT+ENTER will ignore it and select exactly what you typed.
+
+Examples:
+ $ScriptName vim,vifm,lf,sxiv
+ $ScriptName 'nvim,lf,vifm,sxiv -ta,sxiv -arf'
+"
+
+# Notify user of how to use the script:
+case $1 in
+ '') printf '%s' "$HelpMessage"; exit 1;;
+ -h|--help) printf '%s' "$HelpMessage"; exit 0;;
+ -f|--version) printf '%s' "$Version"; exit 0;;
+esac
+
+# Prompt user what to locate:
+LocateTarget=$(printf '' | dmenu -p "$ScriptName:")
+
+# Exit if nothing was selected:
+[ -z "$LocateTarget" ] && exit 1
+
+# Do the search:
+Located=$(locate "$LocateTarget")
+
+# Prompt user to select one of the results:
+Path=$(printf '%s' "$Located" | dmenu -i -l 30 -p 'Select path:')
+
+# Exit if nothing was selected:
+[ -z "$Path" ] && exit 1
+
+# Parse the passed programs:
+Parsed=$(printf '%s' "$1" | tr -s ',' '\n')
+
+# If there's only one program, skip selecting it:
+if [ $(printf '%s\n' "$Parsed" | wc -l) -eq 1 ]; then
+ Program=$Parsed
+else # Else, choose one:
+ Program=$(printf '%s' "$Parsed" | dmenu -i -l 10 -p 'Select program:')
+fi
+
+# Exit if nothing was selected:
+[ -z "$Program" ] && exit 1
+
+# Launch the selected program with the selected path:
+eval "$Program" \""$Path"\"
diff --git a/.local/bin/dman b/.local/bin/dman
new file mode 100755
index 0000000..a123a6b
--- /dev/null
+++ b/.local/bin/dman
@@ -0,0 +1,30 @@
+#!/usr/bin/env sh
+
+# Dmenu for easily finding a manual to open from a list of all manuals.
+
+# Set a character width for this script if needed:
+#export MANWIDTH=80
+
+man $(apropos --long . | dmenu -i -l 30 | awk '{print $2, $1}' | tr -d '()')
+
+# Probably the most useful script ever.
+
+# There are some manuals that have the same name but different sections denoted
+# with what's inside (), one useful section to know is the POSIX version of the
+# manuals which are #p or #posix, so adding that to the search shows you the
+# POSIX version of the manual if it exists. For more information read the
+# initial part of the man-pages manual and search 'intro' with this script.
+#
+# Keep in mind that newly installed programs with man pages tend not to appear
+# right away because the manual database hasn't been updated yet (though you
+# can simply write the name of the package if you know it). Depending on the
+# system, it may be updated with a cron job, during boot, etc. If you want
+# to update it manually, run:
+#
+# sudo mandb
+#
+# Ideally it would run every time a program is installed/uninstalled, but it
+# seems a pain to set it up. It takes a few seconds to finish, which is a
+# bummer, because I would have just put it at the start of this script. I could
+# also just make a wrapper script for pacman that runs "sudo mandb" quietly if
+# the un/installation was completed successfully.
diff --git a/.local/bin/dmarks b/.local/bin/dmarks
new file mode 100755
index 0000000..1d99dd4
--- /dev/null
+++ b/.local/bin/dmarks
@@ -0,0 +1,238 @@
+#!/usr/bin/env sh
+
+# Dmenu plain text URL bookmark manager.
+
+# MIT License
+#
+# Copyright (c) 2020 Alexander Chaplin Braz
+#
+# 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.
+
+ScriptName=${0##*/}
+Version=1.0.0
+
+# Compose the help message:
+HelpMessage="$ScriptName - Version: $Version
+Creator: Alexander Chaplin Braz (https://alexchaplinbraz.com)
+License: MIT
+
+Usage: $ScriptName {bookmark}
+
+This script is a simple plain text URL bookmark manager that lets the user
+copy, add, edit and delete bookmark entries. It requires one argument,
+the path to the bookmark file. The URLs are opened with \$BROWSER.
+
+The format of the bookmark file is:
+One bookmark per line with three tab separated fields: URL, title and tags.
+The tags are comma separated and can have spaces.
+"
+
+case $1 in
+ '') printf '%s' "$HelpMessage"; exit 1;;
+ -h|--help) printf '%s' "$HelpMessage"; exit 0;;
+ -v|--version) printf '%s' "$Version"; exit 0;;
+esac
+
+# Temporary file location
+TempFile="/tmp/$ScriptName"
+
+# Load and format the bookmarks:
+Bookmarks=$(cat "$1" | nl -n ln)
+FormattedBookmarks=$(printf '%s' "$Bookmarks" \
+ | sed 's/\t\t/\tBLANK\t/' \
+ | awk -F '\t' '{print $1, $3, "("$4")", $5, "["$2"]"}')
+ ### For some reason setting OFS='\t' makes dmenu lag.
+
+# Set menu options:
+MenuOpen='1. Open a bookmark.'
+MenuCreate='2. Create new bookmark.'
+MenuEdit='3. Edit a bookmark.'
+MenuDelete='4. Delete a bookmark.'
+
+# Prompt user to choose action:
+ChosenMenu=$(printf '%s\n%s\n%s\n%s' \
+ "$MenuOpen" "$MenuCreate" "$MenuEdit" "$MenuDelete" \
+ | dmenu -i -l 10 -p "$ScriptName:")
+
+# Open bookmark:
+if [ "$ChosenMenu" = "$MenuOpen" ]; then
+ # Prompt user for bookmark:
+ Chosen=$(printf '%s' "$FormattedBookmarks" \
+ | dmenu -i -l 30 -p 'Open:' \
+ | awk '{printf $1}')
+ Chosen=$(printf '%s' "$Bookmarks" \
+ | grep -w ^$Chosen \
+ | awk '{printf $2}')
+ [ -z "$Chosen" ] && exit 1
+
+ # Open browser with selected URL.
+ $BROWSER "$Chosen"
+
+# Create bookmark:
+elif [ "$ChosenMenu" = "$MenuCreate" ]; then
+ # Get the name of the active window:
+ ActiveWindow=$(ps -p "$(xdotool getwindowfocus getwindowpid)" -o comm=)
+
+ # Set the name if the active window is a chromium based browser:
+ printf '%s' "$ActiveWindow" | grep -Eq 'chromium|chrome|brave' \
+ && ActiveWindow='chromium-based'
+ ### Haven't actually checked whether Chromium's window name is chromium.
+
+ # Get URL/title based on browser:
+ if [ "$ActiveWindow" = 'qutebrowser' ]; then
+ xdotool search --name qutebrowser key --clearmodifiers y P
+ sleep 0.1
+ URL=$(xclip -o)
+ sleep 0.1
+ xdotool search --name qutebrowser key --clearmodifiers y T
+ sleep 0.1
+ Title=$(xclip -o)
+ elif [ "$ActiveWindow" = 'chromium-based' ]; then
+ xdotool key --clearmodifiers ctrl+l
+ sleep 0.1
+ xdotool key --clearmodifiers ctrl+c
+ sleep 0.1
+ URL=$(xclip -o)
+ sleep 0.1
+ ### Maybe write it to a file in the background to speed it up.
+ ### Doesn't work for some generated sites.
+ Title=$(curl -s "$URL" \
+ | awk -F '|' '{for(i=2;i<=NF;i+=2){print $i}}' \
+ RS='' \
+ | recode html)
+ fi
+
+ # Check if URL already exists.
+ if [ "$URL" ] && grep -q "$URL" "$1" ;then
+ printf '' | dmenu -p 'ERROR: URL already bookmarked.'
+ exit 1
+ fi
+
+ # Prompt user to edit the URL:
+ EditedURL=$(printf '%s' "$URL" | dmenu -l 1 -p 'Edit URL:')
+ [ "$EditedURL" ] && URL=$EditedURL
+
+ # Prompt user to edit the title:
+ EditedTitle=$(printf '%s' "$Title" | dmenu -l 1 -p 'Edit title:')
+ [ "$EditedTitle" ] && Title=$EditedTitle
+
+ # Prompt the user to pick tags for the bookmark:
+ AllTags=$(printf '%s' "$Bookmarks" \
+ | awk -F '\t' '{print $4}' \
+ | tr ',' '\n' \
+ | sort \
+ | uniq)
+ while true; do
+ SelectedTag=$(printf '%s' "$AllTags" \
+ | dmenu -i -l 30 \
+ -p "Add tags. SHIFT+ENTER to create a new tag. $Tags")
+ [ -z "$SelectedTag" ] && break
+ Tags="$Tags$SelectedTag,"
+ done
+ Tags=${Tags%?}
+
+ # Create a preview for the user to see their input:
+ Confirmation=$(printf '%s\nURL: %s\nTitle: %s\nTags: %s' \
+ 'This is a preview. Press ENTER to confirm or ESCAPE to cancel.' \
+ "$URL" "$Title" "$Tags" \
+ | dmenu -i -l 10)
+
+ # If the user pressed ENTER, create the bookmark:
+ [ "$Confirmation" ] && \
+ printf '%s\t%s\t%s' \
+ "$URL" "$Title" "$Tags" >> "$1"
+
+# Edit bookmark:
+elif [ "$ChosenMenu" = "$MenuEdit" ]; then
+ # Prompt user for bookmark:
+ Chosen=$(printf '%s' "$FormattedBookmarks" \
+ | dmenu -i -l 30 -p "Edit:" \
+ | awk '{printf $1}')
+ Chosen=$(printf '%s' "$Bookmarks" \
+ | grep -w ^$Chosen \
+ | awk '{printf $2}')
+ [ -z "$Chosen" ] && exit 1
+
+ # Get the bookmark information:
+ Mark=$(grep "$Chosen" "$1")
+ OldURL=$(printf '%s' "$Mark" | awk -F '\t' '{printf $1}')
+ OldTitle=$(printf '%s' "$Mark" | awk -F '\t' '{printf $2}')
+ OldTags=$(printf '%s' "$Mark" | awk -F '\t' '{printf $3}')
+
+ # Prompt user to edit the URL:
+ EditedURL=$(printf '%s' "$OldURL" | dmenu -l 1 -p 'Edit URL:')
+ [ "$EditedURL" ] && URL=$EditedURL
+
+ # Prompt user to edit the title:
+ EditedTitle=$(printf '%s' "$OldTitle" | dmenu -l 1 -p 'Edit title:')
+ [ "$EditedTitle" ] && Title=$EditedTitle
+
+ # Prompt the user to pick tags for the bookmark:
+ AllTags=$(printf '%s' "$Bookmarks" \
+ | awk -F '\t' '{print $4}' \
+ | tr ',' '\n' \
+ | sort \
+ | uniq)
+ while true; do
+ SelectedTag=$(printf '%s' "$AllTags" \
+ | dmenu -i -l 30 \
+ -p "Old: $OldTags | New: $Tags")
+ [ -z "$SelectedTag" ] && break
+ Tags="$Tags$SelectedTag,"
+ done
+ Tags=${Tags%,}
+
+ # Create a preview for the user to see their input:
+ Confirmation=$(printf \
+ '%s\nNew URL: %s\nOld URL: %s\nNew title: %s\nOld title: %s\
+ \nNew tags: %s\nOld tags: %s' \
+ 'This is a preview. Press ENTER to confirm or ESCAPE to cancel.' \
+ "$URL" "$OldURL" "$Title" "$OldTitle" "$Tags" "$OldTags" \
+ | dmenu -i -l 10)
+
+ # If the user pressed ENTER, edit the bookmark:
+ if [ "$Confirmation" ]; then
+ sed "\|$Chosen|d" "$1" > "$TempFile"
+ mv "$TempFile" "$1"
+ printf '%s\t%s\t%s' "$URL" "$Title" "$Tags" >> "$1"
+ else
+ exit 1
+ fi
+
+# Delete bookmark:
+elif [ "$ChosenMenu" = "$MenuDelete" ]; then
+ # Prompt user for bookmark:
+ Chosen=$(printf '%s' "$FormattedBookmarks" \
+ | dmenu -i -l 30 -p 'Delete:' \
+ | awk '{printf $1}')
+ Chosen=$(printf '%s' "$Bookmarks" \
+ | grep -w ^$Chosen \
+ | awk '{printf $2}')
+ [ -z "$Chosen" ] && exit 1
+
+ # Delete selected bookmark from file:
+ sed "\|$Chosen|d" "$1" > "$TempFile"
+ mv "$TempFile" "$1"
+
+elif [ -z "$ChosenMenu" ]; then
+ exit 1
+else
+ printf 'ERROR: invalid selection.\n'
+ exit 1
+fi
diff --git a/.local/bin/dmnt b/.local/bin/dmnt
new file mode 100755
index 0000000..4d39cbe
--- /dev/null
+++ b/.local/bin/dmnt
@@ -0,0 +1,68 @@
+#!/usr/bin/env sh
+
+# Dmenu to mount/unmount partitions.
+
+ScriptName=${0##*/}
+Version=1.0.0
+
+# Set menu options:
+MenuMount='1. Mount a partition.'
+MenuUnmount='2. Unmount a partition.'
+
+ChosenMenu=$(printf '%s\n%s' \
+ "$MenuMount" "$MenuUnmount" \
+ | dmenu -i -l 10 -p "$ScriptName:")
+
+# Mount a partition:
+if [ "$ChosenMenu" = "$MenuMount" ]; then
+ Mountable=$(lsblk -lp \
+ | grep "part $" \
+ | awk '{print $1, "(" $4 ")"}')
+ [ -z "$Mountable" ] && exit 1
+
+ Chosen=$(printf '%s' "$Mountable" \
+ | dmenu -i -l 10 -p 'Mount which drive?' \
+ | awk '{print $1}')
+ [ -z "$Chosen" ] && exit 1
+
+ # Try to mount directly based on fstab:
+ sudo mount "$Chosen" && exit 0
+ # Otherwise ask for directory.
+
+ ### Implement a way to exclude already mounted locations.
+
+ Directories=$(find /mnt -maxdepth 1 -type d 2>/dev/null)
+ MountPoint=$(printf '%s' "$Directories" \
+ | dmenu -i -l 10 -p 'Type in mount point:')
+ [ -z "$MountPoint" ] && exit 1
+
+ if [ ! -d "$MountPoint" ]; then
+ mkdirprompt=$(printf 'No\\nYes' \
+ | dmenu -i -p "$MountPoint does not exist. Create it?")
+ [ "$mkdirprompt" = 'Yes' ] && sudo mkdir -p "$MountPoint"
+ fi
+
+ sudo mount "$Chosen" "$MountPoint"
+
+# Unmount a partition:
+elif [ "$ChosenMenu" = "$MenuUnmount" ]; then
+ ExclusionRegex='\(/boot\|/home\|/\|/backup\|/backup/extra\)$'
+
+ Drives=$(lsblk -lp \
+ | grep "part /" \
+ | grep -v "$ExclusionRegex" \
+ | awk '{print $1, "(" $4 ")", "on", $7}')
+ [ -z "$Drives" ] && exit 1
+
+ Chosen=$(printf '%s' "$Drives" \
+ | dmenu -i -l 10 -p 'Unmount which drive?' \
+ | awk '{print $1}')
+ [ -z "$Chosen" ] && exit 1
+
+ sudo umount "$Chosen"
+elif [ -z "$ChosenMenu" ]; then
+ exit 1
+else
+ printf 'ERROR: invalid selection.\n'
+ exit 1
+fi
diff --git a/.local/bin/dnewsh b/.local/bin/dnewsh
new file mode 100755
index 0000000..6271ef9
--- /dev/null
+++ b/.local/bin/dnewsh
@@ -0,0 +1,18 @@
+#!/usr/bin/env sh
+
+# Quickly start creating a new script.
+
+Directory=$(find "$HOME/proj" -maxdepth 2 -type d \
+ | dmenu -i -l 30 -p 'Select directory for new script:')
+[ -z "$Directory" ] && exit 1
+
+Name=$(printf '' | dmenu -p 'Name the script:')
+[ -z "$Name" ] && exit 1
+
+Script="$Directory/$Name"
+touch "$Script"
+chmod +x "$Script"
+ln -sf "$Script" "$LBIN"
+printf '%s\n\n# ' '#!/usr/bin/env sh' > "$Script"
+
+$EDITOR "$Script"
diff --git a/.local/bin/dpass b/.local/bin/dpass
new file mode 100755
index 0000000..92c0ae0
--- /dev/null
+++ b/.local/bin/dpass
@@ -0,0 +1,201 @@
+#!/usr/bin/env sh
+
+# Dmenu for managing passwords.
+
+# MIT License
+#
+# Copyright (c) 2020 Alexander Chaplin Braz
+#
+# 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.
+
+ScriptName=${0##*/}
+Version=1.1.0
+
+HelpMessage="$ScriptName - Version: $Version
+Creator: Alexander Chaplin Braz (https://alexchaplinbraz.com)
+License: MIT
+
+Usage: $ScriptName ['genrepass arguments']
+
+This script lets the user copy, add, edit and delete pass entries through a
+series of dmenu prompts.
+
+The script itself requires no arguments, but does require the user to have the
+complimentary genrepass utility by the same creator for password generation.
+In the case of its absense, the password generation simply won't work and the
+user will have to input them manually.
+
+The default argument for genrepass is just to look for text files in the XGD
+environment variable for documents \$XDG_DOCUMENTS_DIR without any options,
+but the user can override that by passing them as the first argument. Do make
+sure to quote the whole block of options and arguments that you would normally
+pass to genrepass with single quotes.
+
+Another way to set the options is to export an environment variable named
+DPASS_OPTS, which takes the same format. This way you can simply run
+$ScriptName without any options. Directly passed arguments still take
+preference though.
+
+IMPORTANT: avoid using the '-c' for copying to clipboard because this script
+ is set up in a way that pipes the stdout of genrepass into dmenu for
+ you to see.
+
+Keep in mind the pinentry program used for entering your passphrase to decrypt
+your .gpg files. If it's set to a terminal one, this script won't work properly.
+I personally recommend pinentry-dmenu to keep with the dmenu theme.
+
+The editor is taken from \$EDITOR as used by pass.
+
+Examples:
+ $ScriptName '-C \"\$HOME/Documents/Journal-2020.md\"'
+ $ScriptName '-L30-50 -n10 \"\$HOME/Documents/notes/\"'
+ export DPASS_OPTS='-C \"\$HOME/Documents/notes\"'
+"
+
+error() { printf 'ERROR: %s\n' "$1" 1>&2; }
+
+suggest_help_and_exit() {
+ printf "Try '%s --help' for more information.\n" "$ScriptName";
+ exit 1
+}
+
+case $1 in
+ -h|--help) printf '%s' "$HelpMessage"; exit 0;;
+ -v|--version) printf '%s - Version: %s\n' "$ScriptName" "$Version"; exit 0;;
+esac
+
+# Get the location of the password store:
+PWStore=$PASSWORD_STORE_DIR
+[ -z "$PWStore" ] && PWStore="$HOME/.password-store"
+
+# Get a list of all entries:
+PassList=$(find $PWStore -name '*.gpg' | sed "s/\.gpg$//; s|$PWStore/||g")
+
+# Set menu options:
+MenuCopy='1. Copy entry to clipboard.'
+MenuCreate='2. Create new entry/Edit existing entry.'
+MenuEdit="3. Edit entry with $EDITOR."
+MenuDelete='4. Delete an entry.'
+FullMenu="$MenuCopy\n$MenuCreate\n$MenuEdit\n$MenuDelete"
+
+# Prompt user to choose action:
+ChosenMenu=$(printf '%b' "$FullMenu" | dmenu -i -l 10 -p "$ScriptName:")
+
+# Copy selected entry to clipboard:
+if [ "$ChosenMenu" = "$MenuCopy" ]; then
+ ChosenPass=$(
+ printf '%s' "$PassList" | dmenu -i -l 30 -p 'Select entry to copy:'
+ )
+
+ pass show -c "$ChosenPass"
+
+# Create new entry/Edit existing entry:
+elif [ "$ChosenMenu" = "$MenuCreate" ]; then
+ ChosenName=$(
+ printf '%s' "$PassList" | dmenu -i -l 30 -p 'Input entry name:'
+ )
+
+ [ -z "$ChosenName" ] && exit 1
+
+ if ! command -v genrepass 1> /dev/null 2>&1; then
+ GenrepassNotFound="ERROR: 'genrepass' not found in PATH."
+ fi
+
+ # Set menu options:
+ TypeSingleLine='1. Write a single line of content.'
+ TypeGenrepass="2. Generate password with genrepass. $GenrepassNotFound"
+
+ # Prompt user to choose content type:
+ ChosenType=$(
+ printf '%s\n%s' "$TypeSingleLine" "$TypeGenrepass" \
+ | dmenu -i -l 10 -p 'Select content type:'
+ )
+
+ # Generate password with genrepass:
+ if [ "$ChosenType" = "$TypeGenrepass" ];then
+
+ # Set genrepass options:
+ if [ -z "$1" ]; then
+ if [ -n "$DPASS_OPTS" ]; then
+ GRPargs=$DPASS_OPTS
+ else
+ GRPargs=$XDG_DOCUMENTS_DIR
+ fi
+ else
+ GRPargs=$1
+ fi
+
+ if [ -z "$GenrepassNotFound" ]; then
+
+ # Keep generating passwords until one is selected:
+ while [ -z "$Content" ]; do
+ Content=$(
+ eval genrepass "$GRPargs" | dmenu -l 10 \
+ -p 'ENTER to select, ESCAPE to generate new password:'
+ )
+ done
+ else
+ Content=$(printf '' | dmenu -p 'Input content:')
+ fi
+
+ # Input custom single line content:
+ elif [ "$ChosenType" = "$TypeSingleLine" ];then
+ Content=$(printf '' | dmenu -p 'Input content:')
+
+ elif [ -z "$ChosenType" ];then
+ exit 1
+ else
+ error 'Invalid selection.'
+ suggest_help_and_exit
+ fi
+
+ # Create a preview for the user to see their input:
+ Confirmation=$(
+ printf '%s\nEntry: %s\nContent: %s' \
+ 'This is a preview. Press ENTER to confirm or ESCAPE to cancel.' \
+ "$ChosenName" "$Content" | dmenu -i -l 10
+ )
+
+ # If the user pressed ENTER, create/edit the entry:
+ if [ "$Confirmation" ]; then
+ printf '%s' "$Content" | pass add --echo --force "$ChosenName"
+ fi
+
+# Open entry with $EDITOR:
+elif [ "$ChosenMenu" = "$MenuEdit" ]; then
+ ChosenPass=$(
+ printf '%s' "$PassList" | dmenu -i -l 30 -p "Select entry to edit:"
+ )
+
+ $TERMINAL -e pass edit "$ChosenPass"
+
+# Delete an entry:
+elif [ "$ChosenMenu" = "$MenuDelete" ]; then
+ ChosenPass=$(
+ printf '%s' "$PassList" | dmenu -i -l 30 -p 'Select entry to delete:'
+ )
+
+ pass delete --force "$ChosenPass"
+
+elif [ -z "$ChosenMenu" ]; then
+ exit 1
+else
+ error 'Invalid selection.'
+ suggest_help_and_exit
+fi
diff --git a/.local/bin/dpower b/.local/bin/dpower
new file mode 100755
index 0000000..e265034
--- /dev/null
+++ b/.local/bin/dpower
@@ -0,0 +1,26 @@
+#!/usr/bin/env sh
+
+# Dmenu power menu.
+# Uses dprompt for confirmation.
+
+Menu='Hybrid-sleep
+Power Off
+Reboot
+Suspend
+Hibernate'
+
+Chosen=$(printf "$Menu" | dmenu -i -l 10 -p 'dpower')
+
+if [ "$Chosen" = 'Hybrid-sleep' ]; then
+ dprompt "Confirm $Chosen?" 'systemctl hybrid-sleep'
+elif [ "$Chosen" = 'Power Off' ]; then
+ dprompt "Confirm $Chosen?" 'poweroff'
+elif [ "$Chosen" = 'Restart' ]; then
+ dprompt "Confirm $Chosen?" 'reboot'
+elif [ "$Chosen" = 'Suspend' ]; then
+ dprompt "Confirm $Chosen?" 'systemctl suspend'
+elif [ "$Chosen" = 'Hibernate' ]; then
+ dprompt "Confirm $Chosen?" 'systemctl hibernate'
+else
+ exit 1
+fi
diff --git a/.local/bin/dprompt b/.local/bin/dprompt
new file mode 100755
index 0000000..8e955f3
--- /dev/null
+++ b/.local/bin/dprompt
@@ -0,0 +1,9 @@
+#!/usr/bin/env sh
+
+# Dmenu binary prompt.
+# Gives a dmenu prompt labled with $1 to perform command $2.
+# Example: dprompt "Suspend?" "sudo systemctl suspend"
+
+[ "$(printf 'No\nYes' \
+ | dmenu -p "$1" \
+ -i -nb darkred -sb red -sf black -nf gray)" = 'Yes' ] && $2
diff --git a/.local/bin/dtimer b/.local/bin/dtimer
new file mode 100755
index 0000000..43ecebd
--- /dev/null
+++ b/.local/bin/dtimer
@@ -0,0 +1,37 @@
+#!/usr/bin/env sh
+
+# Dmenu for starting a timer.
+# Takes one optional argument for a WAV file sound alert.
+# Requires a monospace font for dmenu to display the TIME'S UP text correctly.
+
+Duration=$(printf '' | dmenu -i -l 30 -p "Current time: $(date +"%H:%M - %A %Y/%m/%d") | Timer duration:")
+[ -z "$Duration" ] && exit 1
+
+Name=$(printf '' | dmenu -p 'Name your timer:')
+
+TimesUpMessage="Name: $Name Duration: $Duration
+ ''''''
+TTTTTTTTTTTTTTTTTTTTTTTIIIIIIIIIIMMMMMMMM MMMMMMMMEEEEEEEEEEEEEEEEEEEEEE '::::' SSSSSSSSSSSSSSS UUUUUUUU UUUUUUUUPPPPPPPPPPPPPPPPP
+T:::::::::::::::::::::TI::::::::IM:::::::M M:::::::ME::::::::::::::::::::E '::::' SS:::::::::::::::S U::::::U U::::::UP::::::::::::::::P
+T:::::::::::::::::::::TI::::::::IM::::::::M M::::::::ME::::::::::::::::::::E ':::''S:::::SSSSSS::::::S U::::::U U::::::UP::::::PPPPPP:::::P
+T:::::TT:::::::TT:::::TII::::::IIM:::::::::M M:::::::::MEE::::::EEEEEEEEE::::E':::' S:::::S SSSSSSS UU:::::U U:::::UUPP:::::P P:::::P
+TTTTTT T:::::T TTTTTT I::::I M::::::::::M M::::::::::M E:::::E EEEEEE'''' S:::::S U:::::U U:::::U P::::P P:::::P
+ T:::::T I::::I M:::::::::::M M:::::::::::M E:::::E S:::::S U:::::D D:::::U P::::P P:::::P
+ T:::::T I::::I M:::::::M::::M M::::M:::::::M E::::::EEEEEEEEEE S::::SSSS U:::::D D:::::U P::::PPPPPP:::::P
+ T:::::T I::::I M::::::M M::::M M::::M M::::::M E:::::::::::::::E SS::::::SSSSS U:::::D D:::::U P:::::::::::::PP
+ T:::::T I::::I M::::::M M::::M::::M M::::::M E:::::::::::::::E SSS::::::::SS U:::::D D:::::U P::::PPPPPPPPP
+ T:::::T I::::I M::::::M M:::::::M M::::::M E::::::EEEEEEEEEE SSSSSS::::S U:::::D D:::::U P::::P
+ T:::::T I::::I M::::::M M:::::M M::::::M E:::::E S:::::S U:::::D D:::::U P::::P
+ T:::::T I::::I M::::::M MMMMM M::::::M E:::::E EEEEEE S:::::S U::::::U U::::::U P::::P
+ TT:::::::TT II::::::IIM::::::M M::::::MEE::::::EEEEEEEE:::::E SSSSSSS S:::::S U:::::::UUU:::::::U PP::::::PP
+ T:::::::::T I::::::::IM::::::M M::::::ME::::::::::::::::::::E S::::::SSSSSS:::::S UU:::::::::::::UU P::::::::P
+ T:::::::::T I::::::::IM::::::M M::::::ME::::::::::::::::::::E S:::::::::::::::SS UU:::::::::UU P::::::::P
+ TTTTTTTTTTT IIIIIIIIIIMMMMMMMM MMMMMMMMEEEEEEEEEEEEEEEEEEEEEE SSSSSSSSSSSSSSS UUUUUUUUU PPPPPPPPPP
+"
+
+if Error=$(sleep $Duration 2>&1); then
+ [ "${1##*.}" = 'wav' ] && aplay "$1" &
+ printf '%s' "$TimesUpMessage" | dmenu -l 30
+else
+ printf '%s' "$Error" | dmenu -l 30 -p 'ERROR:'
+fi
diff --git a/.local/bin/dwine b/.local/bin/dwine
new file mode 100755
index 0000000..b0a37d9
--- /dev/null
+++ b/.local/bin/dwine
@@ -0,0 +1,41 @@
+#!/usr/bin/env sh
+
+# Dmenu for choosing which wine bottle to open a program with.
+
+if [ "$2" = 'wg32' ]; then
+ export WINEARCH='win32'
+ export WINEPREFIX='/home/alex/.local/wine/wg32'
+ exec wine "$1"
+ exit 0
+fi
+
+Chosen=$(printf '1. Run with WG32\n2. Run with WG64\n3. winetricks WG32\n4. winetricks WG64\n5. winecfg WG32\n6. winecfg WG64' \
+ | dmenu -i -l 10 -p 'dwine:')
+
+if [ "$Chosen" = '1. Run with WG32' ]; then
+ export WINEARCH='win32'
+ export WINEPREFIX='/home/alex/.local/wine/wg32'
+ exec wine "$1"
+elif [ "$Chosen" = '2. Run with WG64' ]; then
+ export WINEARCH='win64'
+ export WINEPREFIX='/home/alex/.local/wine/wg64'
+ exec wine "$1"
+elif [ "$Chosen" = '3. winetricks WG32' ]; then
+ export WINEARCH='win32'
+ export WINEPREFIX='/home/alex/.local/wine/wg32'
+ exec winetricks
+elif [ "$Chosen" = '4. winetricks WG64' ]; then
+ export WINEARCH='win64'
+ export WINEPREFIX='/home/alex/.local/wine/wg64'
+ exec winetricks
+elif [ "$Chosen" = '5. winecfg WG32' ]; then
+ export WINEARCH='win32'
+ export WINEPREFIX='/home/alex/.local/wine/wg32'
+ exec winecfg
+elif [ "$Chosen" = '6. winecfg WG64' ]; then
+ export WINEARCH='win64'
+ export WINEPREFIX='/home/alex/.local/wine/wg64'
+ exec winecfg
+else
+ exit 1
+fi
diff --git a/.local/bin/dyt b/.local/bin/dyt
new file mode 100755
index 0000000..ad5c555
--- /dev/null
+++ b/.local/bin/dyt
@@ -0,0 +1,149 @@
+#!/usr/bin/env sh
+
+# Dmenu for opening videos with youtube-viewer.
+# MUST HAVE the *ID* at the end of custom_layout_format in youtube-viewer.conf.
+# Example:
+# custom_layout_format => "*TITLE* (*AUTHOR*) [*TIME*] *ID*"
+
+# MIT License
+#
+# Copyright (c) 2020 Alexander Chaplin Braz
+#
+# 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.
+
+### Add subscription system with sxiv for looking through video thumbnails
+### and managing the videos.
+### Set youtube-viewer arguments as variables to be able to select them like
+### tags for a custom search.
+### Implement search history for quickly searching again.
+
+ScriptName=${0##*/}
+Version=0.0.1
+
+# Compose the help message:
+HelpMessage="$ScriptName - Version: $Version
+Creator: Alexander Chaplin Braz (https://alexchaplinbraz.com)
+License: MIT
+
+Usage: $ScriptName
+
+MUST HAVE the *ID* at the end of custom_layout_format in youtube-viewer.conf.
+Example:
+custom_layout_format => \"*TITLE* (*AUTHOR*) [*TIME*] *ID*\"
+"
+
+case $1 in
+ -h|--help) printf '%s' "$HelpMessage"; exit 0;;
+ -v|--version) printf '%s - Version: %s\n' "$ScriptName" "$Version"; exit 0;;
+esac
+
+error() { printf 'ERROR: %s\n' "$1" 1>&2; }
+
+suggest_help_and_exit() {
+ printf "Try '%s --help' for more information.\n" "$ScriptName" 1>&2
+ exit 1
+}
+
+YTURL='https://www.youtube.com/watch?v='
+
+MenuSimple='1. Simple search.'
+MenuHistory='2. History.'
+MenuPlaylist='3. Playlist search.'
+MenuChannel='4. Channel search.'
+
+ChosenMenu=$(printf '%s\n%s\n%s\n%s' \
+ "$MenuSimple" \
+ "$MenuHistory" \
+ "$MenuPlaylist" \
+ "$MenuChannel" \
+ | dmenu -i -l 10 -p "$ScriptName:")
+
+if [ "$ChosenMenu" = "$MenuSimple" ]; then
+ Search=$(printf '' | dmenu -p 'Simple search:')
+ [ -z "$Search" ] && exit 1
+
+ printf '%s\n' "$Search" >> "$LSHARE/dytsearchhistory"
+
+ YTID=$(youtube-viewer --no-interactive "$Search" \
+ | sed '/^$/d' \
+ | nl -n ln \
+ | dmenu -i -l 30 -p 'Select video:')
+ [ -z "$YTID" ] && exit 1
+
+ printf '%s\n' "$YTID" >> "$LSHARE/dytvideohistory"
+
+ mpv "$YTURL${YTID##* }"
+
+elif [ "$ChosenMenu" = "$MenuHistory" ]; then
+ HistoryMenu=$(printf '1. Search history.\n2. Video history.' \
+ | dmenu -i -l 10 -p 'Which history?')
+
+ if [ "$HistoryMenu" = '1. Search history.' ]; then
+ Search=$(cat "$LSHARE/dytsearchhistory" \
+ | awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' \
+ | dmenu -i -l 30 -p 'Select previous search:')
+ [ -z "$Search" ] && exit 1
+
+ printf '%s\n' "$Search" >> "$LSHARE/dytsearchhistory"
+
+ YTID=$(youtube-viewer --no-interactive "$Search" \
+ | sed '/^$/d' \
+ | nl -n ln \
+ | dmenu -i -l 30 -p 'Select video:')
+
+ printf '%s\n' "$YTID" >> "$LSHARE/dytvideohistory"
+
+ elif [ "$HistoryMenu" = '2. Video history.' ]; then
+ YTID=$(cat "$LSHARE/dytvideohistory" \
+ | awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' \
+ | dmenu -i -l 30 -p 'Select previous video:')
+
+ else
+ exit 1
+ fi
+ [ -z "$YTID" ] && exit 1
+
+ mpv "$YTURL${YTID##* }"
+
+elif [ "$ChosenMenu" = "$MenuPlaylist" ]; then
+ ### Can't find how to change the format for anything other than video list
+ ### so it's broken. Can parse it in another way, but it's ugly.
+ ### Can also just open youtube-viewer as intended.
+ exit 1
+
+ Search=$(printf '' | dmenu -p 'Playlist search:')
+ [ -z "$Search" ] && exit 1
+
+ YTID=$(youtube-viewer --no-interactive -sp "$Search" \
+ | sed '/^$/d' \
+ | dmenu -i -l 30 -p 'Select playlist:')
+ [ -z "$YTID" ] && exit 1
+
+ mpv "$YTURL${YTID##* }"
+
+elif [ "$ChosenMenu" = "$MenuChannel" ]; then
+ exit 1
+
+elif [ -z "$ChosenMenu" ]; then
+ exit 1
+else
+ error 'invalid selection.'
+ suggest_help_and_exit
+fi
+nn
diff --git a/.local/bin/emojenu b/.local/bin/emojenu
new file mode 120000
index 0000000..971008e
--- /dev/null
+++ b/.local/bin/emojenu
@@ -0,0 +1 @@
+/home/dizzy/proj/emojenu/emojenu
\ No newline at end of file
diff --git a/.local/bin/refresh_wallpaper b/.local/bin/refresh_wallpaper
new file mode 100755
index 0000000..7e2f271
--- /dev/null
+++ b/.local/bin/refresh_wallpaper
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+pkill -9 feh
+feh --no-fehbg --bg-fill ~/proj/sysconf/wallpapers/wallpaper
+rm -r ~/.cache/wal/
+wal -i ~/proj/sysconf/wallpapers/wallpaper
+xrdb ~/.cache/wal/colors.Xresources
+
+cp ~/.cache/wal/dunstrc ~/.config/dunst/dunstrc
+pkill -9 dunst
diff --git a/.local/bin/upload_file b/.local/bin/upload_file
new file mode 100755
index 0000000..baed407
--- /dev/null
+++ b/.local/bin/upload_file
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+ file=$(find $HOME -type f | dmenu -i -l 25)
+ curl -F "file=@$file" 0x0.st | xclip -selection c
+ notify-send "Your file link is in clipboard"
diff --git a/.local/bin/wal-discord b/.local/bin/wal-discord
new file mode 120000
index 0000000..afb8bff
--- /dev/null
+++ b/.local/bin/wal-discord
@@ -0,0 +1 @@
+/home/dizzy/proj/wal-discord/wal-discord
\ No newline at end of file
diff --git a/.local/bin/yt b/.local/bin/yt
new file mode 100755
index 0000000..35bee1c
--- /dev/null
+++ b/.local/bin/yt
@@ -0,0 +1,69 @@
+#!/bin/bash
+# dependencies: mpv youtube-dl fzf rofi/dmenu
+# search videos and playlists on youtube and play them in mpv, without an API
+# usage:
+# yt asks for input in stdin, prompts using fzf
+# yt search query takes input from the passed arg, prompts using fzf
+# yt -r takes input and prompts using rofi ($guicmd)
+
+defcmd="fzf"
+#guicmd="rofi -dmenu -i" #uncomment next line for dmenu
+guicmd="dmenu -i -l 15"
+promptcmd="$defcmd"
+if [ -z "$*" ]; then
+ echo -n "Search YouTube: "
+ read -r query
+else
+ case "$1" in
+ -r) query=$(echo | $guicmd -p "Search YouTube: ")
+ promptcmd="$guicmd -p Video:";;
+ *) query="$*";;
+ esac
+fi
+if [ -z "$query" ]; then exit; fi
+# sanitise the query
+query=$(sed \
+ -e 's|+|%2B|g'\
+ -e 's|#|%23|g'\
+ -e 's|&|%26|g'\
+ -e 's| |+|g'\
+ <<< "$query")
+# fetch the results with the $query and
+# delete all escaped characters
+response="$(curl -s "https://www.youtube.com/results?search_query=$query" |\
+ sed 's|\\.||g')"
+# if unable to fetch the youtube results page, inform and exit
+if ! grep -q "script" <<< "$response"; then echo "unable to fetch yt"; exit 1; fi
+# regex expression to match video and playlist entries from yt result page
+vgrep='"videoRenderer":{"videoId":"\K.{11}".+?"text":".+?[^\\](?=")'
+pgrep='"playlistRenderer":{"playlistId":"\K.{34}?","title":{"simpleText":".+?[^\"](?=")'
+# grep the id and title
+# return them in format id (type) title
+getresults() {
+ grep -oP "$1" <<< "$response" |\
+ awk -F\" -v p="$2" '{ print $1 "\t" p " " $NF}'
+}
+# get the list of videos/playlists and their ids in videoids and playlistids
+videoids=$(getresults "$vgrep")
+playlistids=$(getresults "$pgrep" "(playlist)")
+# if there are playlists or videos, append them to list
+[ -n "$playlistids" ] && ids="$playlistids\n"
+[ -n "$videoids" ] && ids="$ids$videoids"
+# url prefix for videos and playlists
+videolink="https://youtu.be/"
+playlink="https://youtube.com/playlist?list="
+# prompt the results to user infinitely until they exit (escape)
+while true; do
+ echo "Choose Video/Playlist to play: "
+ choice=$(echo -e "$ids" | cut -d' ' -f2 | $promptcmd) # dont show id
+ if [ -z "$choice" ]; then exit; fi # if esc-ed then exit
+ id=$(echo -e "$ids" | grep -Fwm1 "$choice" | cut -d' ' -f1) # get id of choice
+ echo -e "$choice\t($id)"
+ case $id in
+ # 11 digit id = video
+ ???????????) mpv "$videolink$id";;
+ # 34 digit id = playlist
+ ??????????????????????????????????) mpv "$playlink$id";;
+ *) exit ;;
+ esac
+done