Introduction
Introduction Statistics Contact Development Disclaimer Help
Purge git history. - dotfiles - These are my dotfiles. There are many like it, …
Log
Files
Refs
README
---
commit 366dbf02ecbf946d03f25f50bf2701dc8400c4ef
Author: Jay Scott <[email protected]>
Date: Thu, 31 Mar 2022 17:04:08 +0100
Purge git history.
Diffstat:
A .gitignore | 26 ++++++++++++++++++++++++++
A Makefile | 42 +++++++++++++++++++++++++++++…
A README | 40 +++++++++++++++++++++++++++++…
A X11/Xresources | 53 ++++++++++++++++++++++++++++++
A X11/xinitrc | 10 ++++++++++
A bashrc | 15 +++++++++++++++
A bin/backup.sh | 57 +++++++++++++++++++++++++++++…
A bin/dwmstatus.sh | 16 ++++++++++++++++
A bin/game_select.sh | 14 ++++++++++++++
A bin/genaccount.sh | 15 +++++++++++++++
A bin/gitreset.sh | 9 +++++++++
A bin/link_handler.sh | 35 +++++++++++++++++++++++++++++…
A bin/old/dmenu_rss | 89 +++++++++++++++++++++++++++++…
A bin/old/download_useragents | 9 +++++++++
A bin/old/fdm_parse_feeds | 15 +++++++++++++++
A bin/old/mbsync_notify | 12 ++++++++++++
A bin/old/update_feeds | 20 ++++++++++++++++++++
A bin/seedclean.sh | 5 +++++
A bin/seedsync.sh | 5 +++++
A bin/seedupload.sh | 9 +++++++++
A bin/yt_dl.sh | 67 +++++++++++++++++++++++++++++…
A bootstrap.sh | 53 ++++++++++++++++++++++++++++++
A crontab | 8 ++++++++
A fdm/fdm.conf | 39 +++++++++++++++++++++++++++++…
A git/config | 14 ++++++++++++++
A isync/mbsyncrc | 25 +++++++++++++++++++++++++
A mpd/mpd.conf | 20 ++++++++++++++++++++
A mutt/mailcap | 1 +
A mutt/muttrc | 106 ++++++++++++++++++++++++++++++
A ncmpcpp/config | 31 +++++++++++++++++++++++++++++…
A newsboat/config | 33 +++++++++++++++++++++++++++++…
A newsboat/urls | 87 +++++++++++++++++++++++++++++…
A pkg/archlinux | 141 +++++++++++++++++++++++++++++…
A pkg/freebsd.txt | 47 +++++++++++++++++++++++++++++…
A pkg/voidlinux.txt | 587 +++++++++++++++++++++++++++++…
A profile | 58 ++++++++++++++++++++++++++++++
A qutebrowser/blank.html | 44 +++++++++++++++++++++++++++++…
A qutebrowser/config.py | 95 ++++++++++++++++++++++++++++++
A qutebrowser/quickmarks | 2 ++
A qutebrowser/scripts/fingerprint.py | 43 ++++++++++++++++++++++++++++++
A qutebrowser/scripts/gruvbox.py | 332 +++++++++++++++++++++++++++++…
A qutebrowser/scripts/redirectors.py | 26 ++++++++++++++++++++++++++
A qutebrowser/scripts/user_agent.py | 31 +++++++++++++++++++++++++++++…
A qutebrowser/useragent_list.json | 93 +++++++++++++++++++++++++++++…
A suckless/dmenu/Makefile | 39 +++++++++++++++++++++++++++++…
A suckless/dmenu/config.h | 13 +++++++++++++
A suckless/dmenu/patches/01-dmenu-bo… | 25 +++++++++++++++++++++++++
A suckless/dmenu/patches/02-dmenu-ce… | 120 +++++++++++++++++++++++++++…
A suckless/dwm/Makefile | 35 +++++++++++++++++++++++++++++…
A suckless/dwm/config.h | 195 +++++++++++++++++++++++++++++…
A suckless/herbe/Makefile | 40 +++++++++++++++++++++++++++++…
A suckless/herbe/config.h | 19 +++++++++++++++++++
A suckless/st/Makefile | 39 +++++++++++++++++++++++++++++…
A suckless/st/config.h | 476 +++++++++++++++++++++++++++++…
A suckless/st/patches/01-st-scrollba… | 351 +++++++++++++++++++++++++++…
A suckless/st/patches/02-st-w3m-hack… | 12 ++++++++++++
A vimrc | 112 +++++++++++++++++++++++++++++…
57 files changed, 3955 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,26 @@
+# mpd
+mpd/playlists/
+mpd/mpd.db
+mpd/mpdstate
+mpd/mpd.pid
+ncmpcpp/error.log
+
+# qutebrowser leftovers
+qutebrowser/qsettings/
+qutebrowser/autoconfig.yml
+qutebrowser/bookmarks
+qutebrowser/quickmarks
+
+# misc
+*.swp
+
+# suckless tools
+suckless/*/src/
+
+# vim
+vim/bundle
+
+# seedbox
+bin/seedsync
+bin/seedclean
+bin/seedupload
diff --git a/Makefile b/Makefile
@@ -0,0 +1,42 @@
+.POSIX:
+
+FILES = bashrc profile vimrc
+ROOT = bin
+CONFIG = git isync mpd mutt ncmpcpp newsboat qutebrowser X11
+
+AUR = paru
+
+all: link restore
+
+restore:
+ crontab $(PWD)/crontab
+
+aur:
+ if [ -f /etc/arch-release ]; then
+ git clone https://aur.archlinux.org/paru.git /tmp/paru
+ cd /tmp/paru && makepkg -si --noconfirm --needed
+ ${AUR} -S --needed - < $(PWD)/pkg/archlinux
+ fi
+
+backup:
+ crontab -l > $(PWD)/crontab
+ ${AUR} -Qqe > $(PWD)/pkg/archlinux
+
+cleanup:
+ ${AUR} -Rs $(${AUR} -Qqtd)
+
+link:
+ for f in ${FILES}; do ln -fs $(PWD)/$$f ${HOME}/.$$f; done
+ for f in ${ROOT}; do ln -fTs $(PWD)/$$f ${HOME}/$$f; done
+ for f in ${CONFIG}; do ln -fTs $(PWD)/$$f ${HOME}/.config/$$f; done
+
+unlink:
+ for f in ${FILES}; do unlink ${HOME}/.$$f; done
+ for f in ${ROOT}; do unlink ${HOME}/$$f; done
+ for f in ${CONFIG}; do unlink ${HOME}/.config/$$f; done
+
+test:
+ shellcheck -s sh $(PWD)/bin/*.sh
+ shfmt -p -w $(PWD)/bin/*.sh
+
+.PHONY: all restore aur backup cleanup link unlink test
diff --git a/README b/README
@@ -0,0 +1,40 @@
+
+|> dotfiles
+
+I am a long time supporter of the Unix philosophy and have been using
+dwm like tools since 2011, as such I mainly use the terminal for
+everything.
+
+Privacy is at the forefront of my mind as such some of my browser
+settings maybe too restrictive for some. I also don't use social media at
+all, the closest I come is using IRC.
+
+
+ operating sys : archlinux / openBSD
+ window manager : dwm
+ terminal : st
+ launcher : dmenu
+ notifications : herbe
+ email : mutt
+ browser : qutebrowser / firefox
+ video : mpv
+ music : mpd / ncmpcpp
+ gaming : gog only
+ password mgt : pass
+ vpn : mullvad
+ news : newsboat
+
+
+dwm, dmenu and herbe are all built with my own Makefiles. This makes
+patching really easy and don't really need to worry about maintaining
+multiple branches etc. It also helps that I don't really have any extra
+patches.
+
+usage:
+
+ $ make
+
+for suckless related tools,
+
+ $ cd suckless/dwm
+ $ make && sudo make install
diff --git a/X11/Xresources b/X11/Xresources
@@ -0,0 +1,53 @@
+! vim:ft=xdefaults
+
+/* COLOURS */
+#define RED0 #cc0403
+#define RED1 #f2201f
+#define GREEN0 #19cb00
+#define GREEN1 #23fd00
+#define YELLOW0 #cecb00
+#define YELLOW1 #fffd00
+#define BLUE0 #0d73cc
+#define BLUE1 #1a8fff
+#define MAGENTA0 #cb1ed1
+#define MAGENTA1 #fd28ff
+#define CYAN0 #0dcdcd
+#define CYAN1 #14ffff
+#define BLACK #000000
+#define GREY1 #767676
+#define GREY2 #dddddd
+#define WHITE #ffffff
+
+#define FONT Hack:size=14
+
+/* XFT */
+Xft.dpi: 96
+Xft.hinting: true
+Xft.rgba: rgb
+Xft.antialias: true
+Xft.autohint: false
+Xft.hintstyle: hintslight
+Xft.lcdfilter: lcddefault
+
+*.foreground: WHITE
+*.background: BLACK
+
+/* NORMAL */
+*.color0: BLACK
+*.color1: RED0
+*.color2: GREEN0
+*.color3: YELLOW0
+*.color4: BLUE0
+*.color5: MAGENTA0
+*.color6: CYAN0
+*.color7: GREY2
+
+/* BRIGHT */
+*.color8: GREY1
+*.color9: RED1
+*.color10: GREEN1
+*.color11: YELLOW1
+*.color12: BLUE1
+*.color13: MAGENTA1
+*.color14: CYAN1
+*.color15: WHITE
diff --git a/X11/xinitrc b/X11/xinitrc
@@ -0,0 +1,10 @@
+# x stuff
+setxkbmap gb
+xset s off -dpms
+xrdb -load ~/.config/X11/Xresources
+~/bin/dwmstatus.sh &
+
+# apps
+mpd &
+
+exec dwm
diff --git a/bashrc b/bashrc
@@ -0,0 +1,15 @@
+if [ -f "$HOME/.profile" ]; then
+ . "$HOME/.profile"
+fi
+
+# correct minor errors in the spelling
+shopt -s cdspell
+
+# append to the history file, don't overwrite it
+shopt -s histappend
+
+# don't put duplicate lines in the history.
+export HISTCONTROL=ignoredups:erasedups
+
+# move bash history out of $HOME
+export HISTFILE="$XDG_STATE_HOME"/bash/history
diff --git a/bin/backup.sh b/bin/backup.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+BORG_PASSPHRASE="$(pass misc/local-backup | head -n1)"
+BORG_REPO='/data/backup'
+
+export BORG_PASSPHRASE
+export BORG_REPO
+
+info() { printf "\n%s %s\n\n" "$(date)" "$*" >&2; }
+
+if pidof -x borg >/dev/null; then
+ info "Backup already running"
+ exit
+fi
+
+trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
+
+info "Starting backup"
+
+borg create \
+ --verbose \
+ --filter AME \
+ --list \
+ --stats \
+ --show-rc \
+ --compression lz4 \
+ --exclude-caches \
+ --exclude '/home/*/.cache/*' \
+ --exclude '/home/*/.local/share/Steam/*' \
+ ::"linux-$(date +%d-%m-%Y)" \
+ /home
+
+backup_exit=$?
+
+info "Pruning repository"
+
+borg prune \
+ --list \
+ --prefix 'linux-' \
+ --show-rc \
+ --keep-daily 7 \
+ --keep-weekly 4 \
+ --keep-monthly 6
+
+prune_exit=$?
+
+global_exit=$((backup_exit > prune_exit ? backup_exit : prune_exit))
+
+if [ ${global_exit} -eq 0 ]; then
+ info "Backup and Prune finished successfully"
+elif [ ${global_exit} -eq 1 ]; then
+ info "Backup and/or Prune finished with warnings"
+else
+ info "Backup and/or Prune finished with errors"
+fi
+
+exit ${global_exit}
diff --git a/bin/dwmstatus.sh b/bin/dwmstatus.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+maildir="$HOME/mail/jay/Inbox/new/"
+
+while true; do
+
+ localtime=$(date +"%T")
+ vol=$(pactl list sinks | tr ' ' '\n' | grep -m1 '%')
+
+ mailcount="$(find "$maildir" -type f | wc -l)"
+ rsscount=$(newsboat -x print-unread | awk '{print $1}')
+
+ xsetroot -name " RSS: $rsscount | MAIL: $mailcount | VOL: $vol | $loca…
+
+ sleep 10
+done
diff --git a/bin/game_select.sh b/bin/game_select.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+games=$(printf "%s\n" "Beneath A Steel Sky" "Enter The Gungeon" | dmenu -p "ga…
+
+[ -z "$games" ] && exit 0
+
+case "$games" in
+"Beneath A Steel Sky")
+ /data/games/beneath_a_steel_sky/start.sh
+ ;;
+"Enter The Gungeon")
+ /data/games/enterthegungeon/start.sh
+ ;;
+esac
diff --git a/bin/genaccount.sh b/bin/genaccount.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# script I use for creating accounts.
+
+username=$(od -An -N3 -x /dev/random | awk '{$1=$1};1' | sed 's/ //g')
+password=$(
+ tr </dev/urandom -dc _A-Z-a-z-0-9 | head -c"${1:-16}"
+ echo
+)
+
+convert -size 200x200 xc:gray +noise random /tmp/avatar.png
+
+echo "username: $username"
+echo "password: $password"
+echo "image : /tmp/avatar.png"
diff --git a/bin/gitreset.sh b/bin/gitreset.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+git checkout --orphan temp_branch
+git add -A
+git commit -am "Purge git history."
+git branch -D master
+git branch -m master
+git push -f origin master
+git push --set-upstream origin master
diff --git a/bin/link_handler.sh b/bin/link_handler.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+launcher="setsid -f st"
+
+# apps
+player="setsid -f mpv --really-quiet --no-terminal"
+gemini="amfora"
+pdf="mupdf"
+images="sxiv"
+torrent="/home/jay/bin/seedupload.sh"
+
+uri="$1"
+uri_lower="$(printf "%s" "$uri" | tr '[:upper:]' '[:lower:]')"
+
+case "$uri_lower" in
+*.mkv | *.mp4 | *.webm | *'youtube.com'*)
+ $player "$uri" &
+ ;;
+*.torrent | 'magnet:'*)
+ herbe "Sending to Seedbox" &
+ $launcher $torrent "$uri" &
+ ;;
+*.gmi | 'gemini:'*)
+ $launcher $gemini "$uri"
+ ;;
+*.pdf | *.ps | *.epub)
+ $launcher $pdf "$uri"
+ ;;
+*.jpg | *.jpe | *.jpeg | *.png | *.gif | *.webp)
+ $launcher $images "$uri"
+ ;;
+*)
+ $launcher rdrview -B "w3m" "$uri"
+ ;;
+esac
diff --git a/bin/old/dmenu_rss b/bin/old/dmenu_rss
@@ -0,0 +1,89 @@
+#!/bin/sh
+#
+# wrapper for sfeed with the following features
+#
+# - default to opening item in browser.
+# - show only new items in feeds.
+# - mpv to play youtube links.
+# - caching to hide already viewed items.
+# - filter items that you dont want to see.
+# - option to show all feeds for searching
+
+# user config
+ignore='parler\|trump\|biden'
+feeds="${HOME}/.config/sfeed/feeds/"
+
+# apps
+player=$(which mpv)
+browser=$(which qutebrowser)
+
+# cache
+cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
+cache_unread="${cachedir}/sfeed_unread"
+cache_read="${cachedir}/sfeed_read"
+tmpfile=/tmp/sfeedtmp.$$
+
+[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
+[ ! -f "$cache_read" ] && touch "$cache_read"
+
+contains() {
+ string="$1"
+ substring="$2"
+ if test "${string#*$substring}" != "$string"
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+mark_read() {
+
+ sfeed_plain "$feeds/"* | grep '^N' | sort -r >> "$cache_unread"
+ awk '!seen[$0]++' "$cache_unread" > "$tmpfile"
+ cat "$tmpfile" > "$cache_read"
+}
+
+show_new() {
+ true > "$cache_unread"
+ sfeed_plain "$feeds/"* | grep '^N' | sort -r >> "$cache_unread"
+ awk '!seen[$0]++' "$cache_unread" > "$tmpfile"
+
+ data=$(grep -vxFf "$cache_read" "$tmpfile" | \
+ grep -iv "$ignore" | dmenu -l 20 -i)
+
+ rm "$tmpfile"
+ url=$(echo "$data" | sed -n 's@^.* \([a-zA-Z]*://\)\(.*\)$@\1\2@p')
+
+ test -n "$data" && echo "$data" >> "$cache_read"
+ show_content "$url"
+}
+
+show_all() {
+ url=$(sfeed_plain "$feeds"/* | sort -r | dmenu -l 20 -i | \
+ sed -n 's@^.* \([a-zA-Z]*://\)\(.*\)$@\1\2@p')
+
+ show_content "$url"
+}
+
+show_content() {
+ if contains "$1" "youtube.com"; then
+ $player "$1" || exit 1
+ fi
+
+ test -n "$1" && $browser "$1"
+}
+
+case $1 in
+ -a)
+ show_all
+ exit
+ ;;
+ -r)
+ mark_read
+ exit
+ ;;
+ *)
+ show_new
+ exit
+esac
diff --git a/bin/old/download_useragents b/bin/old/download_useragents
@@ -0,0 +1,9 @@
+#!/bin/bash
+#
+# download the most common used useragents f or using in qutebrowser.
+#
+
+url='https://raw.githubusercontent.com/Kikobeats/top-user-agents/master/index.…
+path="$HOME/.config/qutebrowser/useragent_list.json"
+
+curl "$url" -o "$path"
diff --git a/bin/old/fdm_parse_feeds b/bin/old/fdm_parse_feeds
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# reads text from stdin containing a url. The url is then parsed
+# by rdrview, https://github.com/eafer/rdrview, and the url content
+# returned appending to the end of the original text.
+#
+# I use this with sfeed and fdm to download feed contents without the
+# need of a browser.
+
+data=$(cat);
+
+url=$(echo "$data" | grep -o -E 'https?://[^"]+')
+content=$(rdrview -H "$url" | lynx -stdin --dump)
+
+printf "%s\n\n%s" "$data" "$content"
diff --git a/bin/old/mbsync_notify b/bin/old/mbsync_notify
@@ -0,0 +1,12 @@
+#!/usr/bin/bash
+
+maildirnew="$HOME/mail/jay/Inbox/new/"
+new="$(find $maildirnew -type f | wc -l)"
+
+export DISPLAY=:0
+export XAUTHORITY="$XDG_RUNTIME_DIR"/Xauthority
+
+if [ $new -gt 0 ]
+then
+ notify-send "New mail: $new"
+fi
diff --git a/bin/old/update_feeds b/bin/old/update_feeds
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# wrapper for managing my feed process.
+# - update new feeds
+# - generate mbox of feeds
+# - parse feeds with fdm and push to Maildir format.
+
+sfeedroot="$HOME/.config/sfeed"
+feedsdir="${sfeedroot}/feeds"
+fdmconfig="$HOME/.config/fdm/config"
+
+if ! test -r "${fdmconfig}"; then
+ echo "fdm configuration file \"${fdmconfig}\" does not exist or is not…
+ exit 1
+fi
+
+/usr/local/bin/sfeed_update
+
+sfeed_mbox "${feedsdir}"/* > ~/.config/sfeed/mbox
+fdm -f "${fdmconfig}" -afeeds fetch
diff --git a/bin/seedclean.sh b/bin/seedclean.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+lftp -u psb54568,4o4nCRi8h6 -e 'rm -rf ~/files/complete' sftp://psb54568.seedb…
+quit 0
+EOF
diff --git a/bin/seedsync.sh b/bin/seedsync.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+lftp -u psb54568,4o4nCRi8h6 -e 'mirror --exclude-glob *.meta -v -c -P1 ~/files…
+quit 0
+EOF
diff --git a/bin/seedupload.sh b/bin/seedupload.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+echo "d10:magnet-uri${#1}:${1}e" >"/tmp/meta-${BASH_REMATCH[1]}.torrent"
+
+lftp -u psb54568,4o4nCRi8h6 -e "cd watch; put /tmp/meta-${BASH_REMATCH[1]}.tor…
+quit 0
+EOF
+
+rm -f "/tmp/meta-${BASH_REMATCH[1]}.torrent"
diff --git a/bin/yt_dl.sh b/bin/yt_dl.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+# instead of using tools like ytcc we can just use youtube-dl directly
+# with a simple shell script without the need for python dependencies
+# etc.
+
+# user config
+savepath="${HOME}/media/youtube"
+cfgdir="${HOME}/.config/yt_dl"
+
+# youtube-dl related settings
+yt="youtube-dl"
+dlflags="-q --restrict-filenames --download-archive"
+idflags="--flat-playlist --get-id"
+
+main() {
+ $1 "mre_steve" "https://www.youtube.com/playlist?list=UU2I6Et1JkidnnbW…
+ $1 "lukesmith" "https://www.youtube.com/playlist?list=UU2eYFnH61tmytIm…
+ $1 "harald_baldr" "https://www.youtube.com/playlist?list=UUKr68ZJ4vv6V…
+ $1 "dale_philip" "https://www.youtube.com/playlist?list=UUKygRpISlqs5T…
+ $1 "simon_wilson" "https://www.youtube.com/playlist?list=UUQCrKxBj5Id7…
+ $1 "hexdsl" "https://www.youtube.com/playlist?list=UURE3NFNtdjR96-H4QG…
+ $1 "distrotube" "https://www.youtube.com/playlist?list=UUVls1GmFKf6WlT…
+ $1 "brodie_robertson" "https://www.youtube.com/playlist?list=UUld68syR…
+ $1 "pppeter" "https://www.youtube.com/playlist?list=UUnHEz9DZ6EAof1-Da…
+ $1 "bald_and_bankrupt" "https://www.youtube.com/playlist?list=UUxDZs_l…
+ $1 "heel_vs_babyface" "https://www.youtube.com/playlist?list=UU_zmPqau…
+ $1 "vagrant_holiday" "https://www.youtube.com/playlist?list=UUgNqlRGqH…
+ $1 "chris_ramsay" "https://www.youtube.com/playlist?list=UUrPUg54jUy1T…
+ $1 "hatedone" "https://www.youtube.com/playlist?list=UUjr2bPAyPV7t35Mv…
+ $1 "c90adventures" "https://www.youtube.com/playlist?list=UUVqpNG1R72i…
+ $1 "abroad_in_japan" "https://www.youtube.com/playlist?list=UUHL9bfHTx…
+ $1 "mental_outlaw" "https://www.youtube.com/playlist?list=UU7YOGHUfC1T…
+ $1 "daily_bald" "https://www.youtube.com/playlist?list=UUB2GbNXOsy3VBk…
+ $1 "dan_sheekoz" "https://www.youtube.com/playlist?list=UUZpOAIs1gWV76…
+}
+
+get_video() {
+ saveloc="${savepath}/${1}"
+ arcfile="${cfgdir}/${1}"
+ lockfile="/tmp/yt_dl.lock"
+
+ # make sure its not already running
+ touch $lockfile
+ exec 9>"$lockfile"
+ flock -n 9 || exit 1
+
+ echo "$1 downloading videos"
+ $yt "${dlflags}" "${arcfile}" "$2" -o "${saveloc}/%(playlist_index)s_%…
+ rm "${lockfile}"
+}
+
+get_ids() {
+ echo "$1 downloading ids"
+ $yt "${idflags}" "${2}" | sed 's/.*/youtube &/' >"${cfgdir}/${1}"
+}
+
+case $1 in
+-m)
+ main get_ids
+ exit
+ ;;
+*)
+ main get_video
+ exit
+ ;;
+esac
diff --git a/bootstrap.sh b/bootstrap.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+DOTFILES=$(pwd)
+
+FILES='bashrc profile vimrc'
+ROOT='bin'
+CONFIG='fdm git mpd mutt ncmpcpp newsboat qutebrowser X11'
+AUR='paru'
+
+link() {
+ for f in $FILES; do ln -fs "$DOTFILES/$f" "$HOME/.$f"; done
+ for f in $ROOT; do ln -fTs "$DOTFILES/$f" "$HOME/$f"; done
+ for f in $CONFIG; do ln -fTs "$DOTFILES/$f" "$HOME/.config/$f"; done
+}
+
+unlink() {
+ for f in $FILES; do unlink "$HOME/.$f"; done
+ for f in $ROOT; do unlink "$HOME/$f"; done
+ for f in $CONFIG; do unlink "$HOME/.config/$f"; done
+}
+
+aur_clean() {
+ $AUR -Rs "$($AUR -Qqtd)"
+}
+
+aur_init() {
+ if [ -f /etc/arch-release ]; then
+ git clone https://aur.archlinux.org/paru.git /tmp/paru
+ cd /tmp/paru && makepkg -si --noconfirm --needed
+ $AUR -S --needed - <"$DOTFILES/pkg/archlinux"
+ fi
+}
+
+backup() {
+ crontab -l >"$DOTFILES/crontab"
+ $AUR -Qqe >"$DOTFILES/pkg/archlinux"
+}
+
+restore() {
+ crontab "$DOTFILES/crontab"
+}
+
+testsh() {
+ shellcheck -s sh "$DOTFILES/bin/*.sh"
+ shfmt -p -w "$DOTFILES/bin/*.sh"
+}
+
+if [ $# -eq 0 ]; then
+ echo "No arguments supplied"
+ exit 1
+fi
+
+$1
diff --git a/crontab b/crontab
@@ -0,0 +1,8 @@
+PATH="$PATH:/usr/local/bin:/usr/bin"
+PASSWORD_STORE_DIR="/home/jay/.config/pass"
+
+*/30 * * * * newsboat -x reload
+*/10 * * * * mbsync -a -c /home/jay/.config/isync/mbsyncrc
+
+# backups
+0 11 * * * /home/jay/bin/backup.sh
diff --git a/fdm/fdm.conf b/fdm/fdm.conf
@@ -0,0 +1,39 @@
+# vim:ft=config
+
+# paths
+$path = "%h/mailtest"
+$obsd = "${path}/openbsd"
+
+# macros
+$host = $(pass tech/mailbox.org | awk '$1 == "incoming:" { print $2}')
+$user = $(pass tech/mailbox.org | awk '$1 == "login:" { print $2}')
+$pass = $(pass tech/mailbox.org | head -n1)
+
+# imap account
+account "main" imaps server ${host} user ${user} pass ${pass}
+folders { "Inbox" "Sent" "House" "Trade" "Keep" }
+
+# actions
+action "inbox" maildir "${path}"
+action "sent" maildir "${path}/sent"
+action "spam" maildir "${path}/spam"
+action "house" maildir "${path}/house"
+action "trade" maildir "${path}/trade"
+action "keep" maildir "${path}/keep"
+action "obsd-misc" maildir "${obsd}/misc"
+action "obsd-ports" maildir "${obsd}/ports"
+action "obsd-tech" maildir "${obsd}/tech"
+
+
+# openbsd mailing list
+match "^Sender:[ \t]*owner-([a-z-]*)@openbsd\\.org" in headers action "obsd-%1"
+
+# general filter
+match string "%[folder]" to "Sent" action "sent"
+match string "%[folder]" to "House" action "house"
+match string "%[folder]" to "Trade" action "trade"
+match string "%[folder]" to "Keep" action "keep"
+match string "%[folder]" to "Inbox" action "inbox"
+
+# match everything else
+match all action "inbox"
diff --git a/git/config b/git/config
@@ -0,0 +1,14 @@
+[user]
+ name = Jay Scott
+ signingkey = C88BBC696A39CCB0
+ email = [email protected]
+[commit]
+ gpgSign = true
+[pull]
+ rebase = false
+[sendemail]
+ annotate = yes
+[core]
+ editor = vim
+[alias]
+ last = log -1 HEAD
diff --git a/isync/mbsyncrc b/isync/mbsyncrc
@@ -0,0 +1,25 @@
+Create Both
+Expunge Both
+Remove Both
+Sync All
+SyncState *
+
+IMAPAccount jay
+Host imap.mailbox.org
+User [email protected]
+PassCmd "pass tech/mailbox.org | head -n1"
+SSLType IMAPS
+CertificateFile /etc/ssl/certs/ca-certificates.crt
+
+IMAPStore jay-remote
+Account jay
+
+MaildirStore jay-local
+SubFolders Verbatim
+Path ~/mail/jay/
+Inbox ~/mail/jay/Inbox
+
+Channel jay
+Far :jay-remote:
+Near :jay-local:
+Patterns *
diff --git a/mpd/mpd.conf b/mpd/mpd.conf
@@ -0,0 +1,20 @@
+music_directory "/data/music"
+playlist_directory "/home/jay/.config/mpd/playlists"
+db_file "/home/jay/.config/mpd/mpd.db"
+log_file "syslog"
+pid_file "/home/jay/.config/mpd/mpd.pid"
+state_file "/home/jay/.config/mpd/mpdstate"
+
+audio_output {
+ type "pulse"
+ name "pulse audio"
+}
+audio_output {
+ type "fifo"
+ name "my_fifo"
+ path "/tmp/mpd.fifo"
+ format "44100:16:2"
+}
+
+bind_to_address "127.0.0.1"
+port "6600"
diff --git a/mutt/mailcap b/mutt/mailcap
@@ -0,0 +1 @@
+text/html; w3m -I %{charset} -T text/html; copiousoutput;
diff --git a/mutt/muttrc b/mutt/muttrc
@@ -0,0 +1,106 @@
+# info
+set my_user = '[email protected]'
+set my_pass = `pass tech/mailbox.org | head -n1`
+set realname = "Jay Scott"
+set from = "[email protected]"
+
+# SMTP settings
+set smtp_pass = $my_pass
+set smtp_url = smtps://[email protected]
+set ssl_force_tls = yes
+
+# general
+set envelope_from = yes
+set use_from = yes
+set editor = "vim"
+set markers = no
+set mark_old = no
+set delete = yes
+set forward_format = "Fwd: %s"
+set fcc_attach = no
+set edit_headers = yes
+
+# html emails
+auto_view text/html
+alternative_order text/plain text/html
+
+# unset
+unset wait_key
+unset allow_8bit
+
+# paths
+set folder = ~/mail
+set header_cache = ~/.config/mutt/cache/headers
+set message_cachedir = ~/.config/mutt/cache/bodies
+set mailcap_path = ~/.config/mutt/mailcap
+set tmpdir = ~/.cache/
+
+set spoolfile = "+jay/Inbox"
+set postponed = "+jay/Drafts"
+set record = "+jay/Sent"
+
+# polling/sidebar
+mailboxes =jay/Inbox =jay/openbsd =jay/openbsd/ports =jay/openbsd/misc =jay/op…
+
+# lists
+lists [email protected] [email protected] [email protected]
+subscribe [email protected] [email protected] [email protected]
+
+# macros
+bind index gg first-entry
+bind index G last-entry
+bind index <space> collapse-thread
+macro index \Cr "T~U<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "…
+macro index o "<shell-escape>mbsync -a -c \"$XDG_CONFIG_HOME\"/isync/mbsyncrc<…
+macro index C "<copy-message>?<toggle-mailboxes>" "copy a message to a mailbox"
+macro index M "<save-message>?<toggle-mailboxes>" "move a message to a mailbox"
+
+# sorting
+set sort = threads
+set sort_aux = reverse-date
+set pager_index_lines = 5
+set pager_context = 1
+set index_format = '%Z | %{%b %d %Y} | %-15.15F | %s'
+
+# sidebar
+set mail_check_stats = yes
+set sidebar_visible = yes
+set sidebar_width = 15
+set sidebar_short_path = yes
+set sidebar_folder_indent = yes
+set sidebar_format = "%B%* [%N]"
+bind index,pager \Ck sidebar-prev
+bind index,pager <tab> sidebar-next
+bind index,pager \Cl sidebar-open
+
+# disable help menu
+set help = no
+
+# status bar
+set status_chars = " *%A"
+set status_format = "───[ Folder: %f ]───[%r%m messages%?n…
+
+color normal color223 color0
+
+# status bar
+color status color8 color0
+
+# highlight bar
+color indicator color223 color237
+
+# replied to
+color index color2 color0 ~Q
+
+# email info header
+color header color11 color0 "^(To:|From:|Date:|^Subject:)"
+
+# web links
+color body color2 color0 "https?://[^ ]+"
+color body color2 color0 "www.[^ ]+"
+
+# email addresss
+color body color2 color0 "[-a-z_0-9.%$]+@[-a-z_0-9.]+\\.[-a-z][-a-z]+"
+color body color2 color0 "mailto:[-a-z_0-9.]+@[-a-z_0-9.]+"
+
+# image links
+color body color2 color0 "\\[image\\ [0-9]+\\]"
diff --git a/ncmpcpp/config b/ncmpcpp/config
@@ -0,0 +1,31 @@
+# visual stuff for 8
+visualizer_data_source = /tmp/mpd.fifo
+visualizer_output_name = my_fifo
+visualizer_in_stereo = no
+visualizer_type = spectrum
+visualizer_look = ∙▋
+visualizer_color = 7,5,8,3
+song_columns_list_format = "(50)[green]{a} (50)[white]{t|f}"
+
+playlist_display_mode = columns
+browser_display_mode = columns
+
+ncmpcpp_directory = ~/.config/ncmpcpp
+lyrics_directory = /tmp
+store_lyrics_in_song_dir = yes
+autocenter_mode = "yes"
+centered_cursor = "yes"
+cyclic_scrolling = "no"
+
+titles_visibility = "no"
+header_visibility = "no"
+statusbar_visibility = "no"
+progressbar_look = "❙❙❙"
+progressbar_color = "white"
+
+user_interface = "classic"
+
+startup_screen = playlist
+startup_slave_screen = visualizer
+startup_slave_screen_focus = no
+locked_screen_width_part = 35
diff --git a/newsboat/config b/newsboat/config
@@ -0,0 +1,33 @@
+# Notify
+notify-program "herbe"
+notify-format "RSS Feeds : %d new articles"
+
+# Default applications
+player mpv
+browser "~/bin/link_handler.sh"
+
+# Reload
+auto-reload no
+reload-time 30
+reload-threads 4
+
+prepopulate-query-feeds yes
+show-read-feeds no
+scrolloff 5
+
+# Feed settings
+show-read-articles no
+show-title-bar no
+download-full-page yes
+text-width 72
+
+articlelist-format "%D %?T?| %-17T | ?%t"
+
+# Maintenace
+confirm-mark-feed-read no
+cleanup-on-quit yes
+
+# Macros
+macro f set browser "firefox %u" ; open-in-browser ; set browser "~/bin/link_h…
+
+include /usr/share/doc/newsboat/contrib/colorschemes/gruvbox
diff --git a/newsboat/urls b/newsboat/urls
@@ -0,0 +1,87 @@
+"query:┌─Unread:unread = \"yes\""
+"query:├─All:tags != \"\""
+"query:│ ├─ Linux:tags # \"linux\""
+"query:│ ├─ Media:tags # \"media\""
+"query:│ ├─ Gaming:tags # \"gaming\""
+"query:│ ├─ Apps:tags # \"apps\""
+"query:│ ├─ People:tags # \"people\""
+"query:│ ├─ Gemini:tags # \"gemini\""
+"query:│ ├─ Videos:tags # \"youtube\""
+
+# LINUX
+https://lobste.rs/newest.rss "!" "~Lobter.rs" linux
+https://tilde.news/newest.rss "!" "~Tilde News" linux
+https://hnrss.org/frontpage "!" "~Hacker News" linux
+
+# MEDIA
+https://showrss.info/other/all.rss "!" "~TV Torrents" media
+http://feed.rutracker.cc/atom/f/1992.atom "!" "~Linux Torrents" media
+https://predb.me/?cats=movies-hd&rss=1 "!" "~PRE-DB Movies" media
+https://www.traileraddict.com/rss "!" "~Trailers" media
+
+# GAMING
+https://boilingsteam.com/feed/ "!" "~Boiling Steam" gaming
+https://www.gamingonlinux.com/article_rss.php "!" "~Gaming On Linux" gaming
+
+# APPS
+https://archlinux.org/feeds/news/ "!" "~Arch Linux" apps
+https://blog.qutebrowser.org/feeds/all.atom.xml "!" "~Qutebrowser" apps
+https://newsboat.org/news.atom "!" "~Newsboat" apps
+https://git.suckless.org/dwm/atom.xml "!" "~dwm" apps
+https://git.suckless.org/st/atom.xml "!" "~st" apps
+https://git.suckless.org/dmenu/atom.xml "!"~dmenu" apps
+https://github.com/dudik/herbe/commits/master.atom "!" "~herbe" apps
+https://github.com/eafer/rdrview/commits/master.atom "!" "~rdrview" apps
+
+
+# PEOPLE
+https://codemadness.org/atom.xml "!" "~CodeMadness" people
+https://drewdevault.com/blog/index.xml "!" "Drew DeVault" people
+http://joeyh.name/blog/index.rss "!" "Joey H" people
+https://unixsheikh.com/feed.rss "!" "Unix Sheikh" people
+https://www.uninformativ.de/blog/feeds/en.atom "!" "~Uninformativ" people
+
+# GEMINI
+"exec:gemget tilde.team/~tomasino/atom.xml --output -" "!" "[email protected]…
+"exec:gemget capsule.usebox.net/gemlog/atom.xml --output -" "!" "~Juans Gemlog…
+"exec:gemget foobucket.xyz/gemlog/atom.xml --output -" "!" "~Foobucket Gemlog"…
+"exec:gemget midnight.pub/feed.xml --output -" "!" "~Midnight Pub" gemini
+
+# YOUTUBE
+https://www.youtube.com/feeds/videos.xml?channel_id=UC2I6Et1JkidnnbWgJFiMeHA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UC7uO9V1Frl_wPd9d1qOm_RQ "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UC5k3Kc0avyDJ2nG9Kxm9JmQ "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCDWIvJwLJsE4LG1Atne2blQ "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCKr68ZJ4vv6VloNdnS2hjhA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCKygRpISlqs5TufcT3JtRng "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCQCrKxBj5Id79syQEsY2Qxg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCRE3NFNtdjR96-H4QG4U1Fg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCRvWwMPr2SmSG7rXXzeEUdA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCVls1GmFKf6WlTraIb_IaJg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCVqpNG1R72i21jh-nAxEk4A "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCXulruMI7BHj3kGyosNa0jA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCnHEz9DZ6EAof1-DaQGD_Xw "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCxDZs_ltFFvn0FDHT6kmoXA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCXJL3ST-O0J3nqzQyPJtpNg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCgNqlRGqHdxNRPR6ycynWhw "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCHL9bfHTxCMi-7vfxQ-AYtg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCB2GbNXOsy3VBksSD58NvhQ "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCwpHKudUkP5tNgmMdexB3ow "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCl7mAGnY4jh4Ps8rhhh8XZg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCpXwMqnXfJzazKS5fJ8nrVw "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCWm__g4cPmX-umorqM8VfWw "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCO8MMsO_XRjO7X4iGCuKdwg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCwMsZgvi4ok7l5hIml1SprA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCWpoyqSBIXtylRLFgP3PFfg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCmSwBBdhuJ39zaA437NaeXA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCeKshd39k29Ipg9sWVaU3-Q "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCqRs-3IcoKCMGXsfLvOgTUg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCpiWxsm9Gt_HK7d-jqkU4MA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCPqdx8N99fs4IDoK_XA1aew "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCI3mQP0kLxdZKhNtcHhExyA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCdVEfdWcNwL5jWmwaNWEf1Q "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UC2O6HDtMOZf9FkUAepz9Atg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCld68syR8Wi-GY_n4CaoJGA "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCmw-QGOHbHA5cDAvwwqUTKQ "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCylGUf9BvQooEFjgdNudoQg "…
+https://www.youtube.com/feeds/videos.xml?channel_id=UCAiiOTio8Yu69c3XnR7nQBQ "…
diff --git a/pkg/archlinux b/pkg/archlinux
@@ -0,0 +1,141 @@
+alsa-utils
+amfora
+aspell
+aspell-en
+autoconf
+automake
+base
+bash-completion
+bc
+beets
+binutils
+bison
+bluez-utils
+borg
+calibre
+checkbashisms
+chrony
+cronie
+dhcpcd
+docker
+docker-compose
+efibootmgr
+fakeroot
+fdm
+firefox
+flex
+fzf
+gcc
+gdb
+gemget
+git
+glu
+gnu-free-fonts
+gnu-netcat
+go
+go-mtpfs-git
+groff
+grub
+htop
+imagemagick
+inetutils
+isync
+iw
+iwd
+jellyfin-bin
+jq
+lf-bin
+lftp
+lib32-alsa-lib
+lib32-alsa-plugins
+lib32-giflib
+lib32-gnutls
+lib32-gst-plugins-base-libs
+lib32-gtk3
+lib32-libpulse
+lib32-libva
+lib32-libxcomposite
+lib32-libxinerama
+lib32-libxslt
+lib32-mesa
+lib32-mpg123
+lib32-ocl-icd
+lib32-openal
+lib32-openssl-1.0
+lib32-pipewire
+lib32-sqlite
+lib32-v4l-utils
+lib32-vulkan-icd-loader
+lib32-vulkan-radeon
+libcurl-gnutls
+libtool
+libva-mesa-driver
+libxft
+libxinerama
+linux
+linux-firmware
+linux-headers
+lynx
+m4
+make
+man-db
+mpd
+mpv
+mullvad-vpn-bin
+mupdf
+mutt
+ncmpcpp
+newsboat
+ntfs-3g
+ntp
+ocl-icd
+openssh
+openssl-1.0
+pacman-contrib
+pamixer
+paru
+pass
+pass-audit-git
+patch
+pipewire-alsa
+pipewire-jack
+pipewire-media-session
+pipewire-pulse
+pkgconf
+poppler
+pulsemixer
+python-adblock
+qutebrowser
+rsync
+rtl88xxau-aircrack-dkms-git
+shellcheck-bin
+shfmt
+sudo
+sxiv
+terminus-font
+texinfo
+tiny-irc-client-bin
+ttf-hack
+ttf-liberation
+unrar
+unzip
+urlview
+usbutils
+vim
+vulkan-radeon
+w3m
+webkit2gtk
+wget
+which
+wtwitch
+xcb-util-errors
+xf86-video-amdgpu
+xorg-server
+xorg-server-common
+xorg-xinit
+xorg-xset
+xorg-xsetroot
+yt-dlp
+yt-dlp-drop-in
+ytfzf
+zip
diff --git a/pkg/freebsd.txt b/pkg/freebsd.txt
@@ -0,0 +1,47 @@
+amfora
+castget
+checkbashisms
+dialog4ports
+doas
+drm-kmod
+fdm
+firefox
+flock
+fusefs-ntfs
+fzf
+gcc
+git-lite
+gmake
+groff
+grub2-bhyve
+hack-font
+hs-ShellCheck
+jq
+lf
+libXft
+libXinerama
+lynx
+mksh
+mpv
+mupdf
+musicpd
+mutt
+ncmpcpp
+password-store
+pkg
+pkgconf
+py37-pip
+qutebrowser
+rsync
+rtorrent
+scummvm
+sxiv
+vim-console
+vm-bhyve
+wireguard
+xauth
+xinit
+xorg
+xorg-fonts
+xorg-server
+xrandr
diff --git a/pkg/voidlinux.txt b/pkg/voidlinux.txt
@@ -0,0 +1,587 @@
+NetworkManager
+SDL2
+acl
+acpid
+adwaita-icon-theme
+alsa-lib
+alsa-plugins-pulseaudio
+alsa-utils
+apulse
+at-spi2-atk
+at-spi2-core
+atk
+atkmm
+attr
+avahi-libs
+base-files
+base-system
+bash
+bash-completion
+binutils
+binutils-doc
+bluez
+btrfs-progs
+bzip2
+bzip2-devel
+c-ares
+ca-certificates
+cairo
+cairomm
+celt
+cmus
+cmus-pulseaudio
+coreutils
+cpio
+cronie
+cryptsetup
+curl
+cyrus-sasl
+cyrus-sasl-modules
+dash
+dbus
+dbus-libs
+dbus-x11
+dejavu-fonts-ttf
+desktop-file-utils
+device-mapper
+dhcpcd
+diffutils
+dnssec-anchors
+dosfstools
+double-conversion
+dracut
+e2fsprogs
+e2fsprogs-libs
+efibootmgr
+encodings
+ethtool
+eudev
+eudev-libudev
+exfat-utils
+expat
+expat-devel
+f2fs-tools
+file
+findutils
+font-adobe-100dpi
+font-adobe-75dpi
+font-adobe-utopia-100dpi
+font-adobe-utopia-75dpi
+font-adobe-utopia-type1
+font-alias
+font-bh-100dpi
+font-bh-75dpi
+font-bh-lucidatypewriter-100dpi
+font-bh-lucidatypewriter-75dpi
+font-bh-ttf
+font-bh-type1
+font-bitstream-100dpi
+font-bitstream-75dpi
+font-bitstream-type1
+font-cursor-misc
+font-daewoo-misc
+font-dec-misc
+font-hack-ttf
+font-ibm-type1
+font-isas-misc
+font-jis-misc
+font-misc-misc
+font-mutt-misc
+font-util
+fontconfig
+fontconfig-devel
+freetype
+freetype-devel
+fribidi
+fuse
+fuse-exfat
+gawk
+gcc
+gdbm
+gdk-pixbuf
+git
+glib
+glibc
+glibc-devel
+glibc-locales
+glibmm
+glslang
+gmp
+gnupg2
+gnutls
+graphite
+grep
+grub
+grub-i386-efi
+grub-x86_64-efi
+gstreamer1
+gtk+3
+gtk-update-icon-cache
+gtkmm
+gzip
+hicolor-icon-theme
+htop
+hwids
+iana-etc
+iceauth
+icu-libs
+iproute2
+iptables
+iputils
+ipw2100-firmware
+ipw2200-firmware
+iw
+jansson
+json-c
+kbd
+kbd-data
+kernel-libc-headers
+kmod
+kpartx
+lame
+lcms2
+less
+libICE
+libSM
+libX11
+libX11-devel
+libXScrnSaver
+libXau
+libXau-devel
+libXaw
+libXcomposite
+libXcursor
+libXdamage
+libXdmcp
+libXdmcp-devel
+libXext
+libXext-devel
+libXfixes
+libXfont2
+libXfontcache
+libXft
+libXft-devel
+libXi
+libXinerama
+libXinerama-devel
+libXmu
+libXpm
+libXrandr
+libXrender
+libXrender-devel
+libXt
+libXtst
+libXv
+libXvMC
+libXxf86misc
+libXxf86vm
+libaio
+libaom
+libarchive
+libargon2
+libass
+libassuan
+libasyncns
+libavcodec
+libavdevice
+libavfilter
+libavformat
+libavresample
+libavutil
+libblkid
+libbluray
+libbs2b
+libcanberra
+libcanberra-gtk3
+libcap
+libcap-ng
+libcap-progs
+libcddb
+libcdio
+libcdio-paranoia
+libcolord
+libcppunit
+libcrypto46
+libcryptsetup
+libcups
+libcurl
+libdatrie
+libdav1d4
+libdb
+libdiscid
+libdmx
+libdrm
+libdvdcss
+libdvdnav
+libdvdread
+libedit
+libefivar
+libelf
+libelogind
+libepoxy
+libev
+libevdev
+libevent
+libfdisk
+libffi
+libfftw
+libflac
+libfontenc
+libfreeglut
+libgbm
+libgcc
+libgcc-devel
+libgcrypt
+libglapi
+libglvnd
+libgomp
+libgpg-error
+libgpgme
+libgsasl
+libgudev
+libgusb
+libharfbuzz
+libical
+libidn
+libidn2
+libinput
+libjack
+libjbig2dec
+libjpeg-turbo
+libkmod
+libksba
+libldap
+libldns
+libllvm10
+libltdl
+liblz4
+liblzma
+libmad
+libmagic
+libmcpp
+libmm-glib
+libmnl
+libmodplug
+libmount
+libndp
+libnetfilter_conntrack
+libnfnetlink
+libnftnl
+libnl3
+libnm
+libogg
+libopenjpeg2
+libpcap
+libpciaccess
+libpcre
+libpcre2
+libplacebo
+libpng
+libpng-devel
+libpostproc
+libpsl
+libpulseaudio
+libreadline8
+libressl
+librsvg
+librtmp
+librubberband
+libsamplerate
+libsasl
+libsensors
+libsigc++
+libsmartcols
+libsndfile
+libsndio
+libsodium
+libsoxr
+libspeex
+libssh2
+libssl48
+libssp
+libssp-devel
+libstdc++
+libstdc++-devel
+libswresample
+libswscale
+libtasn1
+libtdb
+libthai
+libtheora
+libtls20
+libtorrent
+libunbound
+libunistring
+libunwind
+libusb
+libutempter
+libuuid
+libuuid-devel
+libva
+libvamp-plugin-sdk
+libvdpau
+libvidstab
+libvorbis
+libvpx6
+libwacom
+libwebp
+libxatracker
+libxbps
+libxcb
+libxcb-devel
+libxkbcommon
+libxkbcommon-x11
+libxkbfile
+libxml2
+libxshmfence
+libxslt
+libxxHash
+libyaml
+libzstd
+linux
+linux-firmware-amd
+linux-firmware-intel
+linux-firmware-network
+linux-firmware-nvidia
+linux5.8
+lua52
+lua53
+lvm2
+lzo
+make
+man-pages
+mcpp
+mdadm
+mdocml
+mesa
+mesa-dri
+mime-types
+minizip
+mit-krb5-libs
+mkfontscale
+mobile-broadband-provider-info
+mozjs60
+mpv
+msmtp
+mtdev
+mupdf
+mutt
+ncurses
+ncurses-base
+ncurses-libs
+nettle
+newsboat
+newt
+nghttp2
+npth
+nspr
+nss
+ntfs-3g
+ntp
+nvi
+ocl-icd
+oclock
+offlineimap
+oniguruma
+openresolv
+openssh
+opus
+orc
+os-prober
+p11-kit
+pam
+pam-base
+pam-libs
+pango
+pangomm
+pass
+patch
+pavucontrol
+pciutils
+perl
+perl-Authen-SASL
+perl-Convert-BinHex
+perl-IO-Socket-SSL
+perl-IO-stringy
+perl-MIME-tools
+perl-MailTools
+perl-Net-SMTP-SSL
+perl-Net-SSLeay
+perl-TimeDate
+perl-URI
+pinentry
+pixman
+pkg-config
+polkit
+popt
+procps-ng
+pulseaudio
+pulsemixer
+python
+python-rfc6555
+python-selectors2
+python-six
+python3
+python3-Jinja2
+python3-MarkupSafe
+python3-PyQt5
+python3-PyQt5-opengl
+python3-PyQt5-quick
+python3-PyQt5-sql
+python3-PyQt5-webchannel
+python3-PyQt5-webengine
+python3-Pygments
+python3-attrs
+python3-lxml
+python3-pyPEG2
+python3-setuptools
+python3-sip-PyQt5
+python3-yaml
+qt5-core
+qt5-dbus
+qt5-declarative
+qt5-gui
+qt5-location
+qt5-network
+qt5-opengl
+qt5-plugin-sqlite
+qt5-printsupport
+qt5-serialport
+qt5-sql
+qt5-test
+qt5-webchannel
+qt5-webengine
+qt5-widgets
+qt5-xml
+qutebrowser
+rclone
+re2
+rofi
+rsync
+rtkit
+rtorrent
+run-parts
+runit
+runit-void
+sbc
+sed
+sessreg
+setxkbmap
+shaderc
+shadow
+shared-mime-info
+slang
+smproxy
+snappy
+speexdsp
+sqlite
+st-terminfo
+startup-notification
+stfl
+sudo
+tar
+thin-provisioning-tools
+tiff
+topgrade
+traceroute
+transset
+tree
+tslib
+tuxc
+tzdata
+usbutils
+util-linux
+util-linux-libs
+v4l-utils
+vim
+vim-common
+void-artwork
+void-repo-multilib
+vulkan-loader
+wayland
+webrtc-audio-processing
+wget
+which
+wifi-firmware
+wpa_supplicant
+x11perf
+x264
+x265
+xauth
+xbacklight
+xbps
+xbps-triggers
+xcalc
+xcb-proto
+xcb-util
+xcb-util-image
+xcb-util-keysyms
+xcb-util-renderutil
+xcb-util-wm
+xcb-util-xrm
+xclip
+xclipboard
+xclock
+xcmsdb
+xconsole
+xcursorgen
+xdpyinfo
+xev
+xeyes
+xf86-input-evdev
+xf86-input-libinput
+xf86-input-synaptics
+xf86-input-vmmouse
+xf86-input-wacom
+xf86-video-amdgpu
+xf86-video-ati
+xf86-video-dummy
+xf86-video-fbdev
+xf86-video-intel
+xf86-video-nouveau
+xf86-video-vesa
+xf86-video-vmware
+xfontsel
+xfsprogs
+xgamma
+xhost
+xinit
+xinput
+xkbcomp
+xkbevd
+xkbutils
+xkeyboard-config
+xkill
+xload
+xlogo
+xlsatoms
+xlsclients
+xmessage
+xmlrpc-c
+xmodmap
+xorg
+xorg-apps
+xorg-fonts
+xorg-input-drivers
+xorg-server
+xorg-video-drivers
+xorgproto
+xpr
+xprop
+xrandr
+xrdb
+xrefresh
+xset
+xsetroot
+xterm
+xtrans
+xvidcore
+xvinfo
+xwd
+xwininfo
+xwud
+xxd
+youtube-dl
+zd1211-firmware
+zlib
+zlib-devel
diff --git a/profile b/profile
@@ -0,0 +1,58 @@
+# users bin
+if [ -d "$HOME/bin" ]; then
+ PATH="$HOME/bin:$PATH"
+fi
+
+# xdg related exports
+export XDG_CONFIG_HOME="$HOME/.config"
+export XDG_DOWNLOAD_DIR="$HOME/tmp"
+export XDG_CACHE_HOME="$HOME/.cache"
+export XDG_DATA_HOME="$HOME/.local/share"
+export XDG_STATE_HOME="$HOME/.local/state"
+export XDG_DESKTOP_DIR="$HOME/"
+
+# cleanup ~/
+export PASSWORD_STORE_DIR="$XDG_CONFIG_HOME"/pass
+export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc
+export XAUTHORITY="$XDG_RUNTIME_DIR"/Xauthority
+
+# common exports
+GPG_TTY=$(tty)
+export GPG_TTY
+
+BOLD="\[$(tput bold)\]"
+RESET="\[$(tput sgr0)\]"
+export PS1="${BOLD}\w \$ ${RESET}"
+
+export EDITOR="vim"
+export BROWSER=firefox
+export GOPATH="$XDG_DATA_HOME"/go
+export GOPROXY=direct
+
+# enable color support of common commands
+if [ -x /usr/bin/dircolors ]; then
+ alias ls='ls --color=auto'
+ alias grep='grep --color=auto'
+fi
+
+# safety first kids!
+alias cp='cp -i'
+alias mv='mv -i'
+alias rm='rm -i'
+alias xclip='xclip -selection c'
+alias x='startx "$XDG_CONFIG_HOME/X11/xinitrc"'
+
+# random alias
+alias vcheck='curl https://am.i.mullvad.net/connected'
+alias yt-mp3='youtube-dl --extract-audio --audio-format mp3'
+alias voff='mullvad always-require-vpn set off; mullvad disconnect'
+alias von='sudo systemctl restart mullvad-daemon.service && mullvad always-req…
+alias t='wtwitch'
+alias weather='curl wttr.in/?1QF'
+
+# git alias
+alias ga='git add -A'
+alias gs='git status -s'
+alias gl="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset…
+alias gd='git diff'
+alias gma='git commit -am'
diff --git a/qutebrowser/blank.html b/qutebrowser/blank.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html lang="en">
+
+ <head>
+ <style>
+ body {
+ color: #cfba58;
+ background-color: #191919;
+ font-family: monospace;
+ }
+
+ .flex {
+ flex-direction: column;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-top: 450px;
+ }
+
+ input {
+ border: none;
+ border-bottom: 2px solid #959A1C;
+ min-width: 500px;
+ max-width: 750px;
+ width: 75%;
+ padding-bottom: 10px;
+ background-color: transparent;
+ color: #fff;
+ outline: 0;
+ margin-bottom: 20px;
+ font-size: 22px;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div class="flex">
+ <form action="https://html.duckduckgo.com/html" method="get" target="_se…
+ <input type="text" name="q" autofocus="autofocus" onfocus="this.select…
+ </form>
+ </div>
+ </body>
+
+</html>
diff --git a/qutebrowser/config.py b/qutebrowser/config.py
@@ -0,0 +1,95 @@
+config.load_autoconfig(False)
+
+try:
+ from qutebrowser.api import message
+
+ # site redirecting
+ config.source('scripts/redirectors.py')
+ # gruvbox colour theme
+ config.source('scripts/gruvbox.py')
+ # useragent switching
+ # config.source('scripts/user_agent.py')
+
+except ImportError:
+ pass
+
+# default local page
+DEFAULT_PAGE = str(config.configdir / 'blank.html')
+
+# keybinds remapping
+config.bind("xx", "set tabs.show always;; later 5000 set tabs.show switching")
+config.bind("xc", "spawn --userscript password_fill")
+config.bind("zd", "download-open")
+config.bind("xz", "hint links spawn --detach mpv --ytdl-format=\"bestvideo[hei…
+
+# tabbar
+c.tabs.position = "top"
+c.tabs.show = "multiple"
+c.tabs.title.format = ""
+c.tabs.width = 28
+
+# hints
+c.colors.hints.bg = "rgb(207,186,88)" #cfba58
+c.colors.hints.fg = "rgb(34, 34, 34)" #222222
+c.colors.webpage.darkmode.enabled = False
+c.colors.webpage.darkmode.algorithm = "lightness-hsl"
+c.colors.webpage.darkmode.grayscale.all = True
+
+# misc
+c.fonts.hints = "10pt Hack"
+c.fonts.default_size = '11pt'
+c.fonts.default_family = 'Hack'
+c.hints.uppercase = True
+c.scrolling.smooth = True
+c.editor.command = ["st", "-e", "vim '{}'"]
+
+# ad-block
+c.content.blocking.enabled = True
+c.content.blocking.method = "adblock"
+c.content.blocking.adblock.lists = [
+ "https://easylist.to/easylist/easyprivacy.txt",
+ "https://secure.fanboy.co.nz/fanboy-cookiemonster.txt",
+ "https://easylist.to/easylist/easylist.txt"
+ ]
+
+# general privacy
+c.completion.web_history.max_items = 0 # no history
+c.downloads.remove_finished = 800 # clear dl history
+c.downloads.location.directory = '~/tmp'
+c.auto_save.session = False # dont save session
+c.url.default_page = DEFAULT_PAGE
+c.url.start_pages = DEFAULT_PAGE
+c.content.private_browsing = True # always use private browsing
+c.content.register_protocol_handler = False
+c.content.webgl = False
+
+# normally default, lets make sure
+c.content.media.audio_capture = False
+c.content.media.audio_video_capture = False
+c.content.media.video_capture = False
+c.content.desktop_capture = False
+c.content.mouse_lock = False
+c.content.autoplay = False # no autoplay on <video> tags
+
+# fingerprint
+c.content.headers.accept_language = "en-US,en;q=0.5"
+c.content.headers.user_agent = "Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/2…
+c.content.headers.custom = {"accept": "text/html,application/xhtml+xml,applica…
+c.content.headers.referer = "same-domain"
+c.content.cookies.accept = "no-3rdparty"
+c.content.javascript.enabled = False # disable tracking etc
+c.content.canvas_reading = False # canvas blocking
+c.content.geolocation = False # location ident
+c.content.webrtc_ip_handling_policy = "disable-non-proxied-udp"
+c.content.hyperlink_auditing = False # disable pingbacks
+c.content.dns_prefetch = False # disable pre-fetching
+
+# search engine shortneners
+c.url.searchengines = {
+ "DEFAULT": "https://html.duckduckgo.com/html?q={}",
+ "ru": "https://rutracker.org/forum/tracker.php?f=1992&nm={}",
+ "lse": "https://www.lse.co.uk/ShareChat.asp?ShareTicker={}",
+ "reddit": "https://old.reddit.com/r/{}",
+ "wiby": "https://wiby.me/?q={}",
+ "book": "http://libgen.rs/search.php?req={}&lg_topic=libgen&open=0&view=si…
+}
diff --git a/qutebrowser/quickmarks b/qutebrowser/quickmarks
@@ -0,0 +1,2 @@
+seed https://psb54568.seedbox.io/
+jellyfin http://localhost:8096/web/index.html#!/home.html
diff --git a/qutebrowser/scripts/fingerprint.py b/qutebrowser/scripts/fingerpri…
@@ -0,0 +1,43 @@
+import random
+import json
+import datetime
+
+from pathlib import Path
+from qutebrowser.api import message, interceptor
+
+home = str(config.configdir)
+agentfile = Path("{}/useragent_list.json".format(home))
+
+fp_timer = datetime.datetime.now() + datetime.timedelta(minutes=1)
+
+if agentfile.is_file():
+ with open(agentfile, "r") as filehandle:
+ agentList = json.load(filehandle)
+
+
+def fingerprint_getheader(agent):
+
+ FP_HTTP_HEADER = {
+ "Firefox": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;…
+ "Chrome": "text/html,application/xhtml+xml,application/xml;q=0.9,image…
+ "Edge": "text/html, application/xhtml+xml, image/jxr, */*",
+ "Opera": "text/html, application/xml;q=0.9, application/xhtml+xml, ima…
+ "Safari": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q…
+ }
+
+ for a, h in FP_HTTP_HEADER.items():
+ if "{a}" in agent:
+ return h
+
+
+def fingerprint(info: interceptor.Request):
+ global fp_timer
+
+ if fp_timer < datetime.datetime.now():
+ fp_timer = datetime.datetime.now() + datetime.timedelta(minutes=1)
+ agent = random.choice(tuple(agentList))
+ c.content.headers.user_agent = agent
+ c.content.headers.custom = {"accept": fingerprint_getheader(agent)}
+
+
+interceptor.register(fingerprint)
diff --git a/qutebrowser/scripts/gruvbox.py b/qutebrowser/scripts/gruvbox.py
@@ -0,0 +1,332 @@
+# gruvbox dark hard qutebrowser theme by Florian Bruhin <[email protected]>
+#
+# Originally based on:
+# base16-qutebrowser (https://github.com/theova/base16-qutebrowser)
+# Base16 qutebrowser template by theova and Daniel Mulford
+# Gruvbox dark, hard scheme by Dawid Kurek ([email protected]), morhetz (htt…
+
+bg0_hard = "#1d2021"
+bg0_soft = '#32302f'
+bg0_normal = '#282828'
+
+bg0 = bg0_normal
+bg1 = "#3c3836"
+bg2 = "#504945"
+bg3 = "#665c54"
+bg4 = "#7c6f64"
+
+fg0 = "#fbf1c7"
+fg1 = "#ebdbb2"
+fg2 = "#d5c4a1"
+fg3 = "#bdae93"
+fg4 = "#a89984"
+
+bright_red = "#fb4934"
+bright_green = "#b8bb26"
+bright_yellow = "#fabd2f"
+bright_blue = "#83a598"
+bright_purple = "#d3869b"
+bright_aqua = "#8ec07c"
+bright_gray = "#928374"
+bright_orange = "#fe8019"
+
+dark_red = "#cc241d"
+dark_green = "#98971a"
+dark_yellow = "#d79921"
+dark_blue = "#458588"
+dark_purple = "#b16286"
+dark_aqua = "#689d6a"
+dark_gray = "#a89984"
+dark_orange = "#d65d0e"
+
+### Completion
+
+# Text color of the completion widget. May be a single color to use for
+# all columns or a list of three colors, one for each column.
+c.colors.completion.fg = [fg1, bright_aqua, bright_yellow]
+
+# Background color of the completion widget for odd rows.
+c.colors.completion.odd.bg = bg0
+
+# Background color of the completion widget for even rows.
+c.colors.completion.even.bg = c.colors.completion.odd.bg
+
+# Foreground color of completion widget category headers.
+c.colors.completion.category.fg = bright_blue
+
+# Background color of the completion widget category headers.
+c.colors.completion.category.bg = bg1
+
+# Top border color of the completion widget category headers.
+c.colors.completion.category.border.top = c.colors.completion.category.bg
+
+# Bottom border color of the completion widget category headers.
+c.colors.completion.category.border.bottom = c.colors.completion.category.bg
+
+# Foreground color of the selected completion item.
+c.colors.completion.item.selected.fg = fg0
+
+# Background color of the selected completion item.
+c.colors.completion.item.selected.bg = bg4
+
+# Top border color of the selected completion item.
+c.colors.completion.item.selected.border.top = bg2
+
+# Bottom border color of the selected completion item.
+c.colors.completion.item.selected.border.bottom = c.colors.completion.item.sel…
+
+# Foreground color of the matched text in the selected completion item.
+c.colors.completion.item.selected.match.fg = bright_orange
+
+# Foreground color of the matched text in the completion.
+c.colors.completion.match.fg = c.colors.completion.item.selected.match.fg
+
+# Color of the scrollbar handle in the completion view.
+c.colors.completion.scrollbar.fg = c.colors.completion.item.selected.fg
+
+# Color of the scrollbar in the completion view.
+c.colors.completion.scrollbar.bg = c.colors.completion.category.bg
+
+### Context menu
+
+# Background color of disabled items in the context menu.
+c.colors.contextmenu.disabled.bg = bg3
+
+# Foreground color of disabled items in the context menu.
+c.colors.contextmenu.disabled.fg = fg3
+
+# Background color of the context menu. If set to null, the Qt default is used.
+c.colors.contextmenu.menu.bg = bg0
+
+# Foreground color of the context menu. If set to null, the Qt default is used.
+c.colors.contextmenu.menu.fg = fg2
+
+# Background color of the context menu’s selected item. If set to null, the …
+c.colors.contextmenu.selected.bg = bg2
+
+#Foreground color of the context menu’s selected item. If set to null, the Q…
+c.colors.contextmenu.selected.fg = c.colors.contextmenu.menu.fg
+
+### Downloads
+
+# Background color for the download bar.
+c.colors.downloads.bar.bg = bg0
+
+# Color gradient start for download text.
+c.colors.downloads.start.fg = bg0
+
+# Color gradient start for download backgrounds.
+c.colors.downloads.start.bg = bright_blue
+
+# Color gradient end for download text.
+c.colors.downloads.stop.fg = c.colors.downloads.start.fg
+
+# Color gradient stop for download backgrounds.
+c.colors.downloads.stop.bg = bright_aqua
+
+# Foreground color for downloads with errors.
+c.colors.downloads.error.fg = bright_red
+
+### Hints
+
+# Font color for hints.
+c.colors.hints.fg = bg0
+
+# Background color for hints.
+c.colors.hints.bg = 'rgba(250, 191, 47, 200)' # bright_yellow
+
+# Font color for the matched part of hints.
+c.colors.hints.match.fg = bg4
+
+### Keyhint widget
+
+# Text color for the keyhint widget.
+c.colors.keyhint.fg = fg4
+
+# Highlight color for keys to complete the current keychain.
+c.colors.keyhint.suffix.fg = fg0
+
+# Background color of the keyhint widget.
+c.colors.keyhint.bg = bg0
+
+### Messages
+
+# Foreground color of an error message.
+c.colors.messages.error.fg = bg0
+
+# Background color of an error message.
+c.colors.messages.error.bg = bright_red
+
+# Border color of an error message.
+c.colors.messages.error.border = c.colors.messages.error.bg
+
+# Foreground color of a warning message.
+c.colors.messages.warning.fg = bg0
+
+# Background color of a warning message.
+c.colors.messages.warning.bg = bright_purple
+
+# Border color of a warning message.
+c.colors.messages.warning.border = c.colors.messages.warning.bg
+
+# Foreground color of an info message.
+c.colors.messages.info.fg = fg2
+
+# Background color of an info message.
+c.colors.messages.info.bg = bg0
+
+# Border color of an info message.
+c.colors.messages.info.border = c.colors.messages.info.bg
+
+### Prompts
+
+# Foreground color for prompts.
+c.colors.prompts.fg = fg2
+
+# Border used around UI elements in prompts.
+c.colors.prompts.border = f'1px solid {bg1}'
+
+# Background color for prompts.
+c.colors.prompts.bg = bg3
+
+# Background color for the selected item in filename prompts.
+c.colors.prompts.selected.bg = bg2
+
+### Statusbar
+
+# Foreground color of the statusbar.
+c.colors.statusbar.normal.fg = fg2
+
+# Background color of the statusbar.
+c.colors.statusbar.normal.bg = bg0
+
+# Foreground color of the statusbar in insert mode.
+c.colors.statusbar.insert.fg = bg0
+
+# Background color of the statusbar in insert mode.
+c.colors.statusbar.insert.bg = dark_aqua
+
+# Foreground color of the statusbar in passthrough mode.
+c.colors.statusbar.passthrough.fg = bg0
+
+# Background color of the statusbar in passthrough mode.
+c.colors.statusbar.passthrough.bg = dark_blue
+
+# Foreground color of the statusbar in private browsing mode.
+c.colors.statusbar.private.fg = bright_purple
+
+# Background color of the statusbar in private browsing mode.
+c.colors.statusbar.private.bg = bg0
+
+# Foreground color of the statusbar in command mode.
+c.colors.statusbar.command.fg = fg3
+
+# Background color of the statusbar in command mode.
+c.colors.statusbar.command.bg = bg1
+
+# Foreground color of the statusbar in private browsing + command mode.
+c.colors.statusbar.command.private.fg = c.colors.statusbar.private.fg
+
+# Background color of the statusbar in private browsing + command mode.
+c.colors.statusbar.command.private.bg = c.colors.statusbar.command.bg
+
+# Foreground color of the statusbar in caret mode.
+c.colors.statusbar.caret.fg = bg0
+
+# Background color of the statusbar in caret mode.
+c.colors.statusbar.caret.bg = dark_purple
+
+# Foreground color of the statusbar in caret mode with a selection.
+c.colors.statusbar.caret.selection.fg = c.colors.statusbar.caret.fg
+
+# Background color of the statusbar in caret mode with a selection.
+c.colors.statusbar.caret.selection.bg = bright_purple
+
+# Background color of the progress bar.
+c.colors.statusbar.progress.bg = bright_blue
+
+# Default foreground color of the URL in the statusbar.
+c.colors.statusbar.url.fg = fg4
+
+# Foreground color of the URL in the statusbar on error.
+c.colors.statusbar.url.error.fg = dark_red
+
+# Foreground color of the URL in the statusbar for hovered links.
+c.colors.statusbar.url.hover.fg = bright_orange
+
+# Foreground color of the URL in the statusbar on successful load
+# (http).
+c.colors.statusbar.url.success.http.fg = bright_red
+
+# Foreground color of the URL in the statusbar on successful load
+# (https).
+c.colors.statusbar.url.success.https.fg = fg0
+
+# Foreground color of the URL in the statusbar when there's a warning.
+c.colors.statusbar.url.warn.fg = bright_purple
+
+### tabs
+
+# Background color of the tab bar.
+c.colors.tabs.bar.bg = bg0
+
+# Color gradient start for the tab indicator.
+c.colors.tabs.indicator.start = bright_blue
+
+# Color gradient end for the tab indicator.
+c.colors.tabs.indicator.stop = bright_aqua
+
+# Color for the tab indicator on errors.
+c.colors.tabs.indicator.error = bright_red
+
+# Foreground color of unselected odd tabs.
+c.colors.tabs.odd.fg = fg2
+
+# Background color of unselected odd tabs.
+c.colors.tabs.odd.bg = bg2
+
+# Foreground color of unselected even tabs.
+c.colors.tabs.even.fg = c.colors.tabs.odd.fg
+
+# Background color of unselected even tabs.
+c.colors.tabs.even.bg = bg3
+
+# Foreground color of selected odd tabs.
+c.colors.tabs.selected.odd.fg = fg2
+
+# Background color of selected odd tabs.
+c.colors.tabs.selected.odd.bg = bg0
+
+# Foreground color of selected even tabs.
+c.colors.tabs.selected.even.fg = c.colors.tabs.selected.odd.fg
+
+# Background color of selected even tabs.
+c.colors.tabs.selected.even.bg = bg0
+
+# Background color of pinned unselected even tabs.
+c.colors.tabs.pinned.even.bg = bright_green
+
+# Foreground color of pinned unselected even tabs.
+c.colors.tabs.pinned.even.fg = bg2
+
+# Background color of pinned unselected odd tabs.
+c.colors.tabs.pinned.odd.bg = bright_green
+
+# Foreground color of pinned unselected odd tabs.
+c.colors.tabs.pinned.odd.fg = c.colors.tabs.pinned.even.fg
+
+# Background color of pinned selected even tabs.
+c.colors.tabs.pinned.selected.even.bg = bg0
+
+# Foreground color of pinned selected even tabs.
+c.colors.tabs.pinned.selected.even.fg = c.colors.tabs.selected.odd.fg
+
+# Background color of pinned selected odd tabs.
+c.colors.tabs.pinned.selected.odd.bg = c.colors.tabs.pinned.selected.even.bg
+
+# Foreground color of pinned selected odd tabs.
+c.colors.tabs.pinned.selected.odd.fg = c.colors.tabs.selected.odd.fg
+
+# Background color for webpages if unset (or empty to use the theme's
+# color).
+c.colors.webpage.bg = bg4
diff --git a/qutebrowser/scripts/redirectors.py b/qutebrowser/scripts/redirecto…
@@ -0,0 +1,26 @@
+import operator, re, typing
+from urllib.parse import urljoin
+
+from qutebrowser.api import interceptor, message
+from PyQt5.QtCore import QUrl
+
+
+REDIRECT_MAP = {
+ "reddit.com": operator.methodcaller('setHost', 'old.reddit.com'),
+ "www.reddit.com": operator.methodcaller('setHost', 'old.reddit.com'),
+ "twitter.com": operator.methodcaller('setHost', 'nitter.pussthecat.org'),
+ "www.twitter.com": operator.methodcaller('setHost', 'nitter.pussthecat.org…
+}
+
+def int_fn(info: interceptor.Request):
+ if (info.resource_type != interceptor.ResourceType.main_frame or
+ info.request_url.scheme() in {"data", "blob"}):
+ return
+ url = info.request_url
+ redir = REDIRECT_MAP.get(url.host())
+ if redir is not None and redir(url) is not False:
+ message.info("Redirecting to " + url.toString())
+ info.redirect(url)
+
+
+interceptor.register(int_fn)
diff --git a/qutebrowser/scripts/user_agent.py b/qutebrowser/scripts/user_agent…
@@ -0,0 +1,31 @@
+# qutebrowser script to set a random user-agent on launch. Add the following to
+# your qutebrowser config.py file:
+#
+# config.source('scripts/user_agent.py')
+#
+# You can download the most common user-agents with a script like this, I run
+# mine on cron every 3 days. :
+#
+# #!/bin/bash
+#
+# url='https://raw.githubusercontent.com/Kikobeats/top-user-agents/master/inde…
+# path="$HOME/.config/qutebrowser/useragent_list.json"
+#
+# curl "$url" -o "$path"
+# awk '!/Firefox/' "$path" > /tmp/1 && mv /tmp/1 "$path"
+
+import random
+import json
+
+from pathlib import Path
+from qutebrowser.api import message
+
+home = str(config.configdir)
+agentfile = Path("{}/useragent_list.json".format(home))
+
+if agentfile.is_file():
+ with open(agentfile, "r") as filehandle:
+ agentList = json.load(filehandle)
+
+ agent = random.choice(tuple(agentList))
+ c.content.headers.user_agent = agent
diff --git a/qutebrowser/useragent_list.json b/qutebrowser/useragent_list.json
@@ -0,0 +1,93 @@
+[
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Fir…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (X11; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0",
+ "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0",
+ "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firef…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Fir…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:82.0) Gecko/20100101…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0",
+ "Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0",
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Fir…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KH…
+ "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, l…
+ "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:82.0) Gecko/20100101 Fire…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:83.0) Gecko/20100101 Firef…
+ "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, l…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:82.0) Gecko/20100101 Firef…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:83.0) Gecko/20100101…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Fir…
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko…
+ "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, l…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:81.0) Gecko/20100101…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, l…
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Fir…
+ "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, l…
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:82.0) Gecko/20100101…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:82.0) Gecko/20100101 Fire…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:82.0) Gecko/20100101…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KH…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Fir…
+ "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0",
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:82.0) Gecko/20100101…
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0",
+ "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like …
+ "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like …
+ "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko…
+ "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firef…
+ "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firef…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (K…
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, …
+ "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like …
+ "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:83.0) Gecko/20100101 Fire…
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko…
+]
diff --git a/suckless/dmenu/Makefile b/suckless/dmenu/Makefile
@@ -0,0 +1,39 @@
+REPOSITORY = http://git.suckless.org/dmenu
+SRC_DIR = src
+PINNED_REVISION = HEAD
+PATCH_DIR = patches
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ $(MAKE) -C "${SRC_DIR}" -s clean; \
+ git -C "${SRC_DIR}" clean -f; \
+ fi
+
+$(SRC_DIR): clone reset
+ @cp config.h $@
+ $(MAKE) -C "${SRC_DIR}" -s
+
+patch: $(PATCH_DIR)/*
+ @for file in $^ ; do \
+ patch -d "${SRC_DIR}" < $${file}; \
+ done
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
+ fi
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @git -C "${SRC_DIR}" pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/dmenu/config.h b/suckless/dmenu/config.h
@@ -0,0 +1,13 @@
+static int topbar = 1;
+static const char *fonts[] = {
+ "Hack:pixelsize=14"
+};
+static const char *prompt = "run »";
+static const char *colors[SchemeLast][2] = {
+ [SchemeNorm] = { "#ffd7af", "#222222" },
+ [SchemeSel] = { "#eeeeee", "#008000" },
+ [SchemeOut] = { "#000000", "#00ffff" },
+};
+
+static unsigned int lines = 0;
+static const char worddelimiters[] = " ";
diff --git a/suckless/dmenu/patches/01-dmenu-border-4.9.diff b/suckless/dmenu/p…
@@ -0,0 +1,25 @@
+diff -up dmenu-4.9-b/config.def.h dmenu-4.9-a/config.def.h
+--- dmenu-4.9-b/config.def.h 2019-02-02 13:55:02.000000000 +0100
++++ dmenu-4.9-a/config.def.h 2019-05-19 02:10:12.740040403 +0200
+@@ -21,3 +21,6 @@ static unsigned int lines = 0;
+ * for example: " /?\"&[]"
+ */
+ static const char worddelimiters[] = " ";
++
++/* Size of the window border */
++static const unsigned int border_width = 5;
+diff -up dmenu-4.9-b/dmenu.c dmenu-4.9-a/dmenu.c
+--- dmenu-4.9-b/dmenu.c 2019-02-02 13:55:02.000000000 +0100
++++ dmenu-4.9-a/dmenu.c 2019-05-19 02:11:20.966710117 +0200
+@@ -654,9 +654,10 @@ setup(void)
+ swa.override_redirect = True;
+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
+- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
++ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
+ CopyFromParent, CopyFromParent, CopyFromParent,
+ CWOverrideRedirect | CWBackPixel | CWEventMask, &…
++ XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
+ XSetClassHint(dpy, win, &ch);
+
+ /* open input methods */
diff --git a/suckless/dmenu/patches/02-dmenu-center-20200111-8cd37e1.diff b/suc…
@@ -0,0 +1,120 @@
+From 8cd37e1ab9e7cb025224aeb3543f1a5be8bceb93 Mon Sep 17 00:00:00 2001
+From: Nihal Jere <[email protected]>
+Date: Sat, 11 Jan 2020 21:16:08 -0600
+Subject: [PATCH] center patch now has adjustable minimum width
+
+---
+ config.def.h | 2 ++
+ dmenu.1 | 3 +++
+ dmenu.c | 39 ++++++++++++++++++++++++++++++++-------
+ 3 files changed, 37 insertions(+), 7 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 1edb647..88ef264 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -2,6 +2,8 @@
+ /* Default settings; can be overriden by command line. */
+
+ static int topbar = 1; /* -b option; if 0, dmenu appear…
++static int centered = 0; /* -c option; centers dmenu on sc…
++static int min_width = 500; /* minimum width when centered…
+ /* -fn option overrides fonts[0]; default X11 font or font set */
+ static const char *fonts[] = {
+ "monospace:size=10"
+diff --git a/dmenu.1 b/dmenu.1
+index 323f93c..c036baa 100644
+--- a/dmenu.1
++++ b/dmenu.1
+@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result…
+ .B \-b
+ dmenu appears at the bottom of the screen.
+ .TP
++.B \-c
++dmenu appears centered on the screen.
++.TP
+ .B \-f
+ dmenu grabs the keyboard before reading stdin if not reading from a tty. This
+ is faster, but will lock up X until stdin reaches end\-of\-file.
+diff --git a/dmenu.c b/dmenu.c
+index 65f25ce..041c7f8 100644
+--- a/dmenu.c
++++ b/dmenu.c
+@@ -89,6 +89,15 @@ calcoffsets(void)
+ break;
+ }
+
++static int
++max_textw(void)
++{
++ int len = 0;
++ for (struct item *item = items; item && item->text; item++)
++ len = MAX(TEXTW(item->text), len);
++ return len;
++}
++
+ static void
+ cleanup(void)
+ {
+@@ -611,6 +620,7 @@ setup(void)
+ bh = drw->fonts->h + 2;
+ lines = MAX(lines, 0);
+ mh = (lines + 1) * bh;
++ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
+ #ifdef XINERAMA
+ i = 0;
+ if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
+@@ -637,9 +647,16 @@ setup(void)
+ if (INTERSECT(x, y, 1, 1, info[i]))
+ break;
+
+- x = info[i].x_org;
+- y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
+- mw = info[i].width;
++ if (centered) {
++ mw = MIN(MAX(max_textw() + promptw, min_width), info[…
++ x = info[i].x_org + ((info[i].width - mw) / 2);
++ y = info[i].y_org + ((info[i].height - mh) / 2);
++ } else {
++ x = info[i].x_org;
++ y = info[i].y_org + (topbar ? 0 : info[i].height - mh…
++ mw = info[i].width;
++ }
++
+ XFree(info);
+ } else
+ #endif
+@@ -647,11 +664,17 @@ setup(void)
+ if (!XGetWindowAttributes(dpy, parentwin, &wa))
+ die("could not get embedding window attributes: 0x%lx…
+ parentwin);
+- x = 0;
+- y = topbar ? 0 : wa.height - mh;
+- mw = wa.width;
++
++ if (centered) {
++ mw = MIN(MAX(max_textw() + promptw, min_width), wa.wi…
++ x = (wa.width - mw) / 2;
++ y = (wa.height - mh) / 2;
++ } else {
++ x = 0;
++ y = topbar ? 0 : wa.height - mh;
++ mw = wa.width;
++ }
+ }
+- promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
+ inputw = MIN(inputw, mw/3);
+ match();
+
+@@ -709,6 +732,8 @@ main(int argc, char *argv[])
+ topbar = 0;
+ else if (!strcmp(argv[i], "-f")) /* grabs keyboard before r…
+ fast = 1;
++ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen…
++ centered = 1;
+ else if (!strcmp(argv[i], "-i")) { /* case-insensitive item m…
+ fstrncmp = strncasecmp;
+ fstrstr = cistrstr;
+--
+2.24.1
+
diff --git a/suckless/dwm/Makefile b/suckless/dwm/Makefile
@@ -0,0 +1,35 @@
+REPOSITORY = http://git.suckless.org/dwm
+SRC_DIR = src
+PINNED_REVISION = HEAD
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ cd $(SRC_DIR); \
+ $(MAKE) -s clean; \
+ git clean -f; \
+ fi
+
+$(SRC_DIR): clone reset
+ @cp config.h $@
+ @cd $@ && $(MAKE) -s
+
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ cd $(SRC_DIR) && git reset --hard $(PINNED_REVISION); \
+ fi
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @cd $(SRC_DIR) && git pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/dwm/config.h b/suckless/dwm/config.h
@@ -0,0 +1,195 @@
+/* See LICENSE file for copyright and license details. */
+
+/* appearance */
+static const unsigned int borderpx = 2;
+static const unsigned int snap = 32;
+static const int lockfullscreen = 1;
+static const int showbar = 1;
+static const int topbar = 1;
+static const char *fonts[] = { "Hack:size=10" };
+static const char dmenufont[] = "Hack:size=10";
+static const char col_gray1[] = "#222222";
+static const char col_gray2[] = "#444444";
+static const char col_gray3[] = "#bbbbbb";
+static const char col_gray4[] = "#eeeeee";
+static const char col_cyan[] = "#222222";
+static const char *colors[][3] = {
+ /* fg bg border */
+ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+};
+
+
+/* custom functions */
+static void togglefullscreen(const Arg *arg);
+static void bstack(Monitor *m);
+static void centeredfloatingmaster(Monitor *m);
+
+/* custom defines for mouse buttons */
+/* only 1-5 are defined in X11/X.h */
+#define Button8 8
+#define Button9 9
+
+/* tagging */
+static const char *tags[] = { "1", "2", "3", "4", "5" };
+
+static Rule rules[] = {
+ /* class instance title tags mask isfloating monit…
+ { NULL, NULL, NULL, 0, False, -1 },
+};
+
+/* layout(s) */
+static const float mfact = 0.65;
+static const int nmaster = 1;
+static const int resizehints = 0;
+
+static const Layout layouts[] = {
+ { ">M>", centeredfloatingmaster },
+ { "[]=", tile },
+ { "TTT", bstack },
+ { "><>", NULL },
+};
+
+#define MODKEY Mod1Mask
+#define TAGKEYS(KEY,TAG) \
+{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
+{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
+{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
+{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
+
+#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+
+/* commands */
+static char dmenumon[2] = "0";
+static const char *dmenucmd[] = { "dmenu_run", NULL };
+static const char *termcmd[] = { "st", NULL };
+static const char *webcmd[] = { "firefox", NULL };
+static const char *ytcmd[] = { "ytfzf", "-D", NULL };
+static const char *gamecmd[] = { "/home/jay/bin/game_select.sh", NULL };
+static const char *volup[] = { "amixer", "set", "Master", "10%+", NULL };
+static const char *voldown[] = { "amixer", "set", "Master", "10%-", NULL };
+
+
+static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY, XK_p, spawn, {.v = dmenu…
+ { MODKEY, XK_space, spawn, {.v = termc…
+ { MODKEY, XK_f, spawn, {.v = webcm…
+ { MODKEY, XK_y, spawn, {.v = ytcmd…
+ { MODKEY, XK_g, spawn, {.v = gamec…
+ { MODKEY, XK_u, spawn, {.v = volup…
+ { MODKEY, XK_d, spawn, {.v = voldo…
+ { MODKEY, XK_j, focusstack, {.i = +1 } …
+ { MODKEY, XK_k, focusstack, {.i = -1 } …
+ { MODKEY, XK_h, setmfact, {.f = -0.05…
+ { MODKEY, XK_l, setmfact, {.f = +0.05…
+ { MODKEY, XK_Return, zoom, {0} },
+ { MODKEY, XK_Tab, view, {0} },
+ { MODKEY, XK_c, killclient, {0} },
+ { MODKEY, XK_m, togglefullscreen, {0} },
+ { MODKEY, XK_period, focusmon, {.i = +1 } …
+ { MODKEY, XK_comma, tagmon, {.i = +1 }…
+ { MODKEY, XK_b, togglebar, {0} },
+ { MODKEY, XK_x, setlayout, {.v = &layo…
+ { MODKEY|ShiftMask, XK_x, setlayout, {.v = &layo…
+ TAGKEYS( XK_1, 0)
+ TAGKEYS( XK_2, 1)
+ TAGKEYS( XK_3, 2)
+ TAGKEYS( XK_4, 3)
+ TAGKEYS( XK_5, 4)
+ { MODKEY|ShiftMask, XK_q, quit, {0} },
+};
+
+/* button definitions */
+static Button buttons[] = {
+ { ClkRootWin, 0, Button8, spawn, …
+ { ClkRootWin, 0, Button9, spawn, …
+ };
+
+void
+togglefullscreen(const Arg *arg)
+{
+ if (!selmon->sel)
+ return;
+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
+}
+
+static void
+bstack(Monitor *m) {
+ int w, h, mh, mx, tx, ty, tw;
+ unsigned int i, n;
+ Client *c;
+
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (n == 0)
+ return;
+ if (n > m->nmaster) {
+ mh = m->nmaster ? m->mfact * m->wh : 0;
+ tw = m->ww / (n - m->nmaster);
+ ty = m->wy + mh;
+ } else {
+ mh = m->wh;
+ tw = m->ww;
+ ty = m->wy;
+ }
+ for (i = mx = 0, tx = m->wx, c = nexttiled(m->clients); c; c = nexttil…
+ if (i < m->nmaster) {
+ w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx + mx, m->wy, w - (2 * c->bw), mh - (2 …
+ mx += WIDTH(c);
+ } else {
+ h = m->wh - mh;
+ resize(c, tx, ty, tw - (2 * c->bw), h - (2 * c->bw), 0…
+ if (tw != m->ww)
+ tx += WIDTH(c);
+ }
+ }
+}
+
+void
+centeredfloatingmaster(Monitor *m)
+{
+ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
+ Client *c;
+
+ /* count number of clients in the selected monitor */
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (n == 0)
+ return;
+
+ /* initialize nmaster area */
+ if (n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ if (m->ww > m->wh) {
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ mh = m->nmaster ? m->wh * 0.9 : 0;
+ } else {
+ mh = m->nmaster ? m->wh * m->mfact : 0;
+ mw = m->nmaster ? m->ww * 0.9 : 0;
+ }
+ mx = mxo = (m->ww - mw) / 2;
+ my = myo = (m->wh - mh) / 2;
+ } else {
+ /* go fullscreen if all clients are in the master area */
+ mh = m->wh;
+ mw = m->ww;
+ mx = mxo = 0;
+ my = myo = 0;
+ }
+
+ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), …
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked horizontally, in the center
+ * of the screen */
+ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw),
+ mh - (2*c->bw), 0);
+ mx += WIDTH(c);
+ } else {
+ /* stack clients are stacked horizontally */
+ w = (m->ww - tx) / (n - i);
+ resize(c, m->wx + tx, m->wy, w - (2*c->bw),
+ m->wh - (2*c->bw), 0);
+ tx += WIDTH(c);
+ }
+}
diff --git a/suckless/herbe/Makefile b/suckless/herbe/Makefile
@@ -0,0 +1,40 @@
+REPOSITORY = https://github.com/dudik/herbe.git
+SRC_DIR = src
+PINNED_REVISION = HEAD
+PATCH_DIR = patches
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ $(MAKE) -C "${SRC_DIR}" -s clean; \
+ git -C "${SRC_DIR}" clean -f; \
+ fi
+
+$(SRC_DIR): clone reset
+ @cp config.h $@
+ $(MAKE) -C "${SRC_DIR}" -s
+
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
+ fi
+
+patch: $(PATCH_DIR)/*
+ @for file in $^ ; do \
+ patch -d "${SRC_DIR}" < $${file}; \
+ done
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @git -C "${SRC_DIR}" pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/herbe/config.h b/suckless/herbe/config.h
@@ -0,0 +1,19 @@
+static const char *background_color = "#222222";
+static const char *border_color = "#008000";
+static const char *font_color = "#ffd7af";
+static const char *font_pattern = "Hack:pixelsize=12";
+static unsigned line_spacing = 5;
+static unsigned int padding = 12;
+
+static unsigned int width = 300;
+static unsigned int border_size = 3;
+static unsigned int pos_x = 30;
+static unsigned int pos_y = 60;
+
+enum corners { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT };
+enum corners corner = TOP_RIGHT;
+
+static unsigned int duration = 5; /* in seconds */
+
+#define DISMISS_BUTTON Button1
+#define ACTION_BUTTON Button3
diff --git a/suckless/st/Makefile b/suckless/st/Makefile
@@ -0,0 +1,39 @@
+REPOSITORY = http://git.suckless.org/st
+SRC_DIR = src
+PINNED_REVISION = HEAD
+PATCH_DIR = patches
+
+all: $(SRC_DIR)
+
+clean: reset
+ @if test -d $(SRC_DIR); then \
+ $(MAKE) -C "${SRC_DIR}" -s clean; \
+ git -C "${SRC_DIR}" clean -f; \
+ fi
+
+$(SRC_DIR): clone reset patch
+ @cp config.h $@
+ $(MAKE) -C "${SRC_DIR}" -s
+
+patch: $(PATCH_DIR)/*
+ @for file in $^ ; do \
+ patch -d "${SRC_DIR}" < $${file}; \
+ done
+reset:
+ @if [ -n "$(strip $(PINNED_REVISION))" ]; then \
+ git -C "${SRC_DIR}" reset --hard $(PINNED_REVISION); \
+ fi
+
+clone:
+ @if ! test -d $(SRC_DIR); then \
+ git clone $(REPOSITORY) $(SRC_DIR); \
+ fi
+
+update: clean
+ @git -C "${SRC_DIR}" pull
+
+install:
+ $(MAKE) -C "${SRC_DIR}" -s install
+
+
+.PHONY: all clean update install reset clone
diff --git a/suckless/st/config.h b/suckless/st/config.h
@@ -0,0 +1,476 @@
+/* See LICENSE file for copyright and license details. */
+
+/*
+ * appearance
+ *
+ * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
+ */
+static char *font = "Liberation Mono:pixelsize=18:antialias=true:autohint=true…
+static int borderpx = 2;
+
+/*
+ * What program is execed by st depends of these precedence rules:
+ * 1: program passed with -e
+ * 2: scroll and/or utmp
+ * 3: SHELL environment variable
+ * 4: value of shell in /etc/passwd
+ * 5: value of shell in config.h
+ */
+static char *shell = "/bin/sh";
+char *utmp = NULL;
+/* scroll program: to enable use a string like "scroll" */
+char *scroll = NULL;
+char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
+
+/* identification sequence returned in DA and DECID */
+char *vtiden = "\033[?6c";
+
+/* Kerning / character bounding-box multipliers */
+static float cwscale = 1.0;
+static float chscale = 1.0;
+
+/*
+ * word delimiter string
+ *
+ * More advanced example: L" `'\"()[]{}"
+ */
+wchar_t *worddelimiters = L" ";
+
+/* selection timeouts (in milliseconds) */
+static unsigned int doubleclicktimeout = 300;
+static unsigned int tripleclicktimeout = 600;
+
+/* alt screens */
+int allowaltscreen = 1;
+
+/* allow certain non-interactive (insecure) window operations such as:
+ setting the clipboard text */
+int allowwindowops = 0;
+
+/*
+ * draw latency range in ms - from new content/keypress/etc until drawing.
+ * within this range, st draws when content stops arriving (idle). mostly it's
+ * near minlatency, but it waits longer for slow updates to avoid partial draw.
+ * low minlatency will tear/flicker more, as it can "detect" idle too early.
+ */
+static double minlatency = 8;
+static double maxlatency = 33;
+
+/*
+ * blinking timeout (set to 0 to disable blinking) for the terminal blinking
+ * attribute.
+ */
+static unsigned int blinktimeout = 800;
+
+/*
+ * thickness of underline and bar cursors
+ */
+static unsigned int cursorthickness = 2;
+
+/*
+ * bell volume. It must be a value between -100 and 100. Use 0 for disabling
+ * it
+ */
+static int bellvolume = 0;
+
+/* default TERM value */
+char *termname = "st-256color";
+
+/*
+ * spaces per tab
+ *
+ * When you are changing this value, don't forget to adapt the »it« value in
+ * the st.info and appropriately install the st.info in the environment where
+ * you use this st version.
+ *
+ * it#$tabspaces,
+ *
+ * Secondly make sure your kernel is not expanding tabs. When running `stty
+ * -a` »tab0« should appear. You can tell the terminal to not expand tabs by
+ * running following command:
+ *
+ * stty tabs
+ */
+unsigned int tabspaces = 8;
+
+/* Terminal colors (16 first used in escape sequence) */
+static const char *colorname[] = {
+ /* 8 normal colors */
+ "black",
+ "red3",
+ "green3",
+ "yellow3",
+ "blue2",
+ "magenta3",
+ "cyan3",
+ "gray90",
+
+ /* 8 bright colors */
+ "gray50",
+ "red",
+ "green",
+ "yellow",
+ "#5c5cff",
+ "magenta",
+ "cyan",
+ "white",
+
+ [255] = 0,
+
+ /* more colors can be added after 255 to use with DefaultXX */
+ "#cccccc",
+ "#555555",
+ "gray90", /* default foreground colour */
+ "black", /* default background colour */
+};
+
+
+/*
+ * Default colors (colorname index)
+ * foreground, background, cursor, reverse cursor
+ */
+unsigned int defaultfg = 258;
+unsigned int defaultbg = 259;
+unsigned int defaultcs = 256;
+static unsigned int defaultrcs = 257;
+
+/*
+ * Default shape of cursor
+ * 2: Block ("█")
+ * 4: Underline ("_")
+ * 6: Bar ("|")
+ * 7: Snowman ("☃")
+ */
+static unsigned int cursorshape = 2;
+
+/*
+ * Default columns and rows numbers
+ */
+
+static unsigned int cols = 80;
+static unsigned int rows = 24;
+
+/*
+ * Default colour and shape of the mouse cursor
+ */
+static unsigned int mouseshape = XC_xterm;
+static unsigned int mousefg = 7;
+static unsigned int mousebg = 0;
+
+/*
+ * Color used to display font attributes when fontconfig selected a font which
+ * doesn't match the ones requested.
+ */
+static unsigned int defaultattr = 11;
+
+/*
+ * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set).
+ * Note that if you want to use ShiftMask with selmasks, set this to an other
+ * modifier, set to 0 to not use it.
+ */
+static uint forcemousemod = ShiftMask;
+
+/*
+ * Internal mouse shortcuts.
+ * Beware that overloading Button1 will disable the selection.
+ */
+static MouseShortcut mshortcuts[] = {
+ /* mask button function argument releas…
+ { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
+ { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
+ { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
+ { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
+ { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
+};
+
+/* Internal keyboard shortcuts. */
+#define MODKEY Mod1Mask
+#define TERMMOD (ControlMask|ShiftMask)
+
+static Shortcut shortcuts[] = {
+ /* mask keysym function argument */
+ { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
+ { ControlMask, XK_Print, toggleprinter, {.i = 0} },
+ { ShiftMask, XK_Print, printscreen, {.i = 0} },
+ { XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
+ { TERMMOD, XK_Prior, zoom, {.f = +1} },
+ { TERMMOD, XK_Next, zoom, {.f = -1} },
+ { TERMMOD, XK_Home, zoomreset, {.f = 0} },
+ { TERMMOD, XK_C, clipcopy, {.i = 0} },
+ { TERMMOD, XK_V, clippaste, {.i = 0} },
+ { TERMMOD, XK_Y, selpaste, {.i = 0} },
+ { ShiftMask, XK_Insert, selpaste, {.i = 0} },
+ { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
+ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
+ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
+};
+
+/*
+ * Special keys (change & recompile st.info accordingly)
+ *
+ * Mask value:
+ * * Use XK_ANY_MOD to match the key no matter modifiers state
+ * * Use XK_NO_MOD to match the key alone (no modifiers)
+ * appkey value:
+ * * 0: no value
+ * * > 0: keypad application mode enabled
+ * * = 2: term.numlock = 1
+ * * < 0: keypad application mode disabled
+ * appcursor value:
+ * * 0: no value
+ * * > 0: cursor application mode enabled
+ * * < 0: cursor application mode disabled
+ *
+ * Be careful with the order of the definitions because st searches in
+ * this table sequentially, so any XK_ANY_MOD must be in the last
+ * position for a key.
+ */
+
+/*
+ * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
+ * to be mapped below, add them to this array.
+ */
+static KeySym mappedkeys[] = { -1 };
+
+/*
+ * State bits to ignore when matching key or button events. By default,
+ * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
+ */
+static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
+
+/*
+ * This is the huge key array which defines all compatibility to the Linux
+ * world. Please decide about changes wisely.
+ */
+static Key key[] = {
+ /* keysym mask string appkey appcursor */
+ { XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
+ { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
+ { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
+ { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
+ { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
+ { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
+ { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
+ { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
+ { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
+ { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
+ { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
+ { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
+ { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
+ { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
+ { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
+ { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
+ { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
+ { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
+ { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
+ { XK_KP_End, ControlMask, "\033[J", -1, 0},
+ { XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
+ { XK_KP_End, ShiftMask, "\033[K", -1, 0},
+ { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
+ { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
+ { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
+ { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
+ { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
+ { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
+ { XK_KP_Insert, ControlMask, "\033[L", -1, 0},
+ { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
+ { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
+ { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
+ { XK_KP_Delete, ControlMask, "\033[M", -1, 0},
+ { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
+ { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
+ { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
+ { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
+ { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
+ { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
+ { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
+ { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
+ { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
+ { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
+ { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
+ { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
+ { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
+ { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
+ { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
+ { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
+ { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
+ { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
+ { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
+ { XK_Up, ShiftMask, "\033[1;2A", 0, 0},
+ { XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
+ { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
+ { XK_Up, ControlMask, "\033[1;5A", 0, 0},
+ { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
+ { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
+ { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
+ { XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
+ { XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
+ { XK_Down, ShiftMask, "\033[1;2B", 0, 0},
+ { XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
+ { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
+ { XK_Down, ControlMask, "\033[1;5B", 0, 0},
+ { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
+ { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
+ { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
+ { XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
+ { XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
+ { XK_Left, ShiftMask, "\033[1;2D", 0, 0},
+ { XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
+ { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
+ { XK_Left, ControlMask, "\033[1;5D", 0, 0},
+ { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
+ { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
+ { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
+ { XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
+ { XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
+ { XK_Right, ShiftMask, "\033[1;2C", 0, 0},
+ { XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
+ { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
+ { XK_Right, ControlMask, "\033[1;5C", 0, 0},
+ { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
+ { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
+ { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
+ { XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
+ { XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
+ { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
+ { XK_Return, Mod1Mask, "\033\r", 0, 0},
+ { XK_Return, XK_ANY_MOD, "\r", 0, 0},
+ { XK_Insert, ShiftMask, "\033[4l", -1, 0},
+ { XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
+ { XK_Insert, ControlMask, "\033[L", -1, 0},
+ { XK_Insert, ControlMask, "\033[2;5~", +1, 0},
+ { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
+ { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
+ { XK_Delete, ControlMask, "\033[M", -1, 0},
+ { XK_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
+ { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
+ { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
+ { XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
+ { XK_Home, ShiftMask, "\033[2J", 0, -1},
+ { XK_Home, ShiftMask, "\033[1;2H", 0, +1},
+ { XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
+ { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
+ { XK_End, ControlMask, "\033[J", -1, 0},
+ { XK_End, ControlMask, "\033[1;5F", +1, 0},
+ { XK_End, ShiftMask, "\033[K", -1, 0},
+ { XK_End, ShiftMask, "\033[1;2F", +1, 0},
+ { XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
+ { XK_Prior, ControlMask, "\033[5;5~", 0, 0},
+ { XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
+ { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
+ { XK_Next, ControlMask, "\033[6;5~", 0, 0},
+ { XK_Next, ShiftMask, "\033[6;2~", 0, 0},
+ { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
+ { XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
+ { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
+ { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
+ { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
+ { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
+ { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
+ { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
+ { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
+ { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
+ { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
+ { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
+ { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
+ { XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
+ { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
+ { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
+ { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
+ { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
+ { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
+ { XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
+ { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
+ { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
+ { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
+ { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
+ { XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
+ { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
+ { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
+ { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
+ { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
+ { XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
+ { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
+ { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
+ { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
+ { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
+ { XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
+ { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
+ { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
+ { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
+ { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
+ { XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
+ { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
+ { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
+ { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
+ { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
+ { XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
+ { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
+ { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
+ { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
+ { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
+ { XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
+ { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
+ { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
+ { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
+ { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
+ { XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
+ { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
+ { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
+ { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
+ { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
+ { XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
+ { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
+ { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
+ { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
+ { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
+ { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
+ { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
+ { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
+ { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
+ { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
+ { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
+ { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
+ { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
+ { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
+ { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
+ { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
+ { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
+ { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
+ { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
+ { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
+ { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
+ { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
+ { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
+ { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
+ { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
+ { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
+ { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
+ { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
+};
+
+/*
+ * Selection types' masks.
+ * Use the same masks as usual.
+ * Button1Mask is always unset, to make masks match between ButtonPress.
+ * ButtonRelease and MotionNotify.
+ * If no match is found, regular selection is used.
+ */
+static uint selmasks[] = {
+ [SEL_RECTANGULAR] = Mod1Mask,
+};
+
+/*
+ * Printable characters in ASCII, used to estimate the advance width
+ * of single wide characters.
+ */
+static char ascii_printable[] =
+ " !\"#$%&'()*+,-./0123456789:;<=>?"
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
+ "`abcdefghijklmnopqrstuvwxyz{|}~";
diff --git a/suckless/st/patches/01-st-scrollback-20210507-4536f46.diff b/suckl…
@@ -0,0 +1,351 @@
+diff --git a/config.def.h b/config.def.h
+index 6f05dce..93cbcc0 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -199,6 +199,8 @@ static Shortcut shortcuts[] = {
+ { TERMMOD, XK_Y, selpaste, {.i = 0} },
+ { ShiftMask, XK_Insert, selpaste, {.i = 0} },
+ { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
++ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
++ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
+ };
+
+ /*
+diff --git a/st.c b/st.c
+index ebdf360..817cc47 100644
+--- a/st.c
++++ b/st.c
+@@ -35,6 +35,7 @@
+ #define ESC_ARG_SIZ 16
+ #define STR_BUF_SIZ ESC_BUF_SIZ
+ #define STR_ARG_SIZ ESC_ARG_SIZ
++#define HISTSIZE 2000
+
+ /* macros */
+ #define IS_SET(flag) ((term.mode & (flag)) != 0)
+@@ -42,6 +43,9 @@
+ #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f))
+ #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c))
+ #define ISDELIM(u) (u && wcschr(worddelimiters, u))
++#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi…
++ term.scr + HISTSIZE + 1) % HISTSIZE] : \
++ term.line[(y) - term.scr])
+
+ enum term_mode {
+ MODE_WRAP = 1 << 0,
+@@ -115,6 +119,9 @@ typedef struct {
+ int col; /* nb col */
+ Line *line; /* screen */
+ Line *alt; /* alternate screen */
++ Line hist[HISTSIZE]; /* history buffer */
++ int histi; /* history index */
++ int scr; /* scroll back */
+ int *dirty; /* dirtyness of lines */
+ TCursor c; /* cursor */
+ int ocx; /* old cursor col */
+@@ -184,8 +191,8 @@ static void tnewline(int);
+ static void tputtab(int);
+ static void tputc(Rune);
+ static void treset(void);
+-static void tscrollup(int, int);
+-static void tscrolldown(int, int);
++static void tscrollup(int, int, int);
++static void tscrolldown(int, int, int);
+ static void tsetattr(const int *, int);
+ static void tsetchar(Rune, const Glyph *, int, int);
+ static void tsetdirt(int, int);
+@@ -416,10 +423,10 @@ tlinelen(int y)
+ {
+ int i = term.col;
+
+- if (term.line[y][i - 1].mode & ATTR_WRAP)
++ if (TLINE(y)[i - 1].mode & ATTR_WRAP)
+ return i;
+
+- while (i > 0 && term.line[y][i - 1].u == ' ')
++ while (i > 0 && TLINE(y)[i - 1].u == ' ')
+ --i;
+
+ return i;
+@@ -528,7 +535,7 @@ selsnap(int *x, int *y, int direction)
+ * Snap around if the word wraps around at the end or
+ * beginning of a line.
+ */
+- prevgp = &term.line[*y][*x];
++ prevgp = &TLINE(*y)[*x];
+ prevdelim = ISDELIM(prevgp->u);
+ for (;;) {
+ newx = *x + direction;
+@@ -543,14 +550,14 @@ selsnap(int *x, int *y, int direction)
+ yt = *y, xt = *x;
+ else
+ yt = newy, xt = newx;
+- if (!(term.line[yt][xt].mode & ATTR_WRAP))
++ if (!(TLINE(yt)[xt].mode & ATTR_WRAP))
+ break;
+ }
+
+ if (newx >= tlinelen(newy))
+ break;
+
+- gp = &term.line[newy][newx];
++ gp = &TLINE(newy)[newx];
+ delim = ISDELIM(gp->u);
+ if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim
+ || (delim && gp->u != prevgp->u)))
+@@ -571,14 +578,14 @@ selsnap(int *x, int *y, int direction)
+ *x = (direction < 0) ? 0 : term.col - 1;
+ if (direction < 0) {
+ for (; *y > 0; *y += direction) {
+- if (!(term.line[*y-1][term.col-1].mode
++ if (!(TLINE(*y-1)[term.col-1].mode
+ & ATTR_WRAP)) {
+ break;
+ }
+ }
+ } else if (direction > 0) {
+ for (; *y < term.row-1; *y += direction) {
+- if (!(term.line[*y][term.col-1].mode
++ if (!(TLINE(*y)[term.col-1].mode
+ & ATTR_WRAP)) {
+ break;
+ }
+@@ -609,13 +616,13 @@ getsel(void)
+ }
+
+ if (sel.type == SEL_RECTANGULAR) {
+- gp = &term.line[y][sel.nb.x];
++ gp = &TLINE(y)[sel.nb.x];
+ lastx = sel.ne.x;
+ } else {
+- gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0];
++ gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0];
+ lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1;
+ }
+- last = &term.line[y][MIN(lastx, linelen-1)];
++ last = &TLINE(y)[MIN(lastx, linelen-1)];
+ while (last >= gp && last->u == ' ')
+ --last;
+
+@@ -850,6 +857,9 @@ void
+ ttywrite(const char *s, size_t n, int may_echo)
+ {
+ const char *next;
++ Arg arg = (Arg) { .i = term.scr };
++
++ kscrolldown(&arg);
+
+ if (may_echo && IS_SET(MODE_ECHO))
+ twrite(s, n, 1);
+@@ -1061,13 +1071,53 @@ tswapscreen(void)
+ }
+
+ void
+-tscrolldown(int orig, int n)
++kscrolldown(const Arg* a)
++{
++ int n = a->i;
++
++ if (n < 0)
++ n = term.row + n;
++
++ if (n > term.scr)
++ n = term.scr;
++
++ if (term.scr > 0) {
++ term.scr -= n;
++ selscroll(0, -n);
++ tfulldirt();
++ }
++}
++
++void
++kscrollup(const Arg* a)
++{
++ int n = a->i;
++
++ if (n < 0)
++ n = term.row + n;
++
++ if (term.scr <= HISTSIZE-n) {
++ term.scr += n;
++ selscroll(0, n);
++ tfulldirt();
++ }
++}
++
++void
++tscrolldown(int orig, int n, int copyhist)
+ {
+ int i;
+ Line temp;
+
+ LIMIT(n, 0, term.bot-orig+1);
+
++ if (copyhist) {
++ term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE;
++ temp = term.hist[term.histi];
++ term.hist[term.histi] = term.line[term.bot];
++ term.line[term.bot] = temp;
++ }
++
+ tsetdirt(orig, term.bot-n);
+ tclearregion(0, term.bot-n+1, term.col-1, term.bot);
+
+@@ -1077,17 +1127,28 @@ tscrolldown(int orig, int n)
+ term.line[i-n] = temp;
+ }
+
+- selscroll(orig, n);
++ if (term.scr == 0)
++ selscroll(orig, n);
+ }
+
+ void
+-tscrollup(int orig, int n)
++tscrollup(int orig, int n, int copyhist)
+ {
+ int i;
+ Line temp;
+
+ LIMIT(n, 0, term.bot-orig+1);
+
++ if (copyhist) {
++ term.histi = (term.histi + 1) % HISTSIZE;
++ temp = term.hist[term.histi];
++ term.hist[term.histi] = term.line[orig];
++ term.line[orig] = temp;
++ }
++
++ if (term.scr > 0 && term.scr < HISTSIZE)
++ term.scr = MIN(term.scr + n, HISTSIZE-1);
++
+ tclearregion(0, orig, term.col-1, orig+n-1);
+ tsetdirt(orig+n, term.bot);
+
+@@ -1097,7 +1158,8 @@ tscrollup(int orig, int n)
+ term.line[i+n] = temp;
+ }
+
+- selscroll(orig, -n);
++ if (term.scr == 0)
++ selscroll(orig, -n);
+ }
+
+ void
+@@ -1126,7 +1188,7 @@ tnewline(int first_col)
+ int y = term.c.y;
+
+ if (y == term.bot) {
+- tscrollup(term.top, 1);
++ tscrollup(term.top, 1, 1);
+ } else {
+ y++;
+ }
+@@ -1291,14 +1353,14 @@ void
+ tinsertblankline(int n)
+ {
+ if (BETWEEN(term.c.y, term.top, term.bot))
+- tscrolldown(term.c.y, n);
++ tscrolldown(term.c.y, n, 0);
+ }
+
+ void
+ tdeleteline(int n)
+ {
+ if (BETWEEN(term.c.y, term.top, term.bot))
+- tscrollup(term.c.y, n);
++ tscrollup(term.c.y, n, 0);
+ }
+
+ int32_t
+@@ -1735,11 +1797,11 @@ csihandle(void)
+ break;
+ case 'S': /* SU -- Scroll <n> line up */
+ DEFAULT(csiescseq.arg[0], 1);
+- tscrollup(term.top, csiescseq.arg[0]);
++ tscrollup(term.top, csiescseq.arg[0], 0);
+ break;
+ case 'T': /* SD -- Scroll <n> line down */
+ DEFAULT(csiescseq.arg[0], 1);
+- tscrolldown(term.top, csiescseq.arg[0]);
++ tscrolldown(term.top, csiescseq.arg[0], 0);
+ break;
+ case 'L': /* IL -- Insert <n> blank lines */
+ DEFAULT(csiescseq.arg[0], 1);
+@@ -2251,7 +2313,7 @@ eschandle(uchar ascii)
+ return 0;
+ case 'D': /* IND -- Linefeed */
+ if (term.c.y == term.bot) {
+- tscrollup(term.top, 1);
++ tscrollup(term.top, 1, 1);
+ } else {
+ tmoveto(term.c.x, term.c.y+1);
+ }
+@@ -2264,7 +2326,7 @@ eschandle(uchar ascii)
+ break;
+ case 'M': /* RI -- Reverse index */
+ if (term.c.y == term.top) {
+- tscrolldown(term.top, 1);
++ tscrolldown(term.top, 1, 1);
+ } else {
+ tmoveto(term.c.x, term.c.y-1);
+ }
+@@ -2474,7 +2536,7 @@ twrite(const char *buf, int buflen, int show_ctrl)
+ void
+ tresize(int col, int row)
+ {
+- int i;
++ int i, j;
+ int minrow = MIN(row, term.row);
+ int mincol = MIN(col, term.col);
+ int *bp;
+@@ -2511,6 +2573,14 @@ tresize(int col, int row)
+ term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
+ term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
+
++ for (i = 0; i < HISTSIZE; i++) {
++ term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph));
++ for (j = mincol; j < col; j++) {
++ term.hist[i][j] = term.c.attr;
++ term.hist[i][j].u = ' ';
++ }
++ }
++
+ /* resize each row to new width, zero-pad if needed */
+ for (i = 0; i < minrow; i++) {
+ term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
+@@ -2569,7 +2639,7 @@ drawregion(int x1, int y1, int x2, int y2)
+ continue;
+
+ term.dirty[y] = 0;
+- xdrawline(term.line[y], x1, y, x2);
++ xdrawline(TLINE(y), x1, y, x2);
+ }
+ }
+
+@@ -2590,8 +2660,9 @@ draw(void)
+ cx--;
+
+ drawregion(0, 0, term.col, term.row);
+- xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
+- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
++ if (term.scr == 0)
++ xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
++ term.ocx, term.ocy, term.line[term.ocy][term.…
+ term.ocx = cx;
+ term.ocy = term.c.y;
+ xfinishdraw();
+diff --git a/st.h b/st.h
+index fa2eddf..adda2db 100644
+--- a/st.h
++++ b/st.h
+@@ -81,6 +81,8 @@ void die(const char *, ...);
+ void redraw(void);
+ void draw(void);
+
++void kscrolldown(const Arg *);
++void kscrollup(const Arg *);
+ void printscreen(const Arg *);
+ void printsel(const Arg *);
+ void sendbreak(const Arg *);
diff --git a/suckless/st/patches/02-st-w3m-hack.diff b/suckless/st/patches/02-s…
@@ -0,0 +1,12 @@
+diff --git a/x.c b/x.c
+index e5f1737..b6ae162 100644
+--- a/x.c
++++ b/x.c
+@@ -1594,6 +1594,8 @@ xsettitle(char *p)
+ int
+ xstartdraw(void)
+ {
++ if (IS_SET(MODE_VISIBLE))
++ XCopyArea(xw.dpy, xw.win, xw.buf, dc.gc, 0, 0, win.w, win.h, …
+ return IS_SET(MODE_VISIBLE);
+ }
diff --git a/vimrc b/vimrc
@@ -0,0 +1,112 @@
+" vim-plug autoinstall
+if empty(glob('~/.vim/autoload/plug.vim'))
+ silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
+ \ https://raw.githubusercontent.com/junegunn/v…
+ autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
+endif
+
+let mapleader = "\<space>"
+
+call plug#begin()
+Plug 'VundleVim/Vundle.vim'
+
+Plug 'morhetz/gruvbox'
+ autocmd vimenter * ++nested colorscheme gruvbox
+
+Plug 'maximbaz/lightline-ale'
+
+Plug 'itchyny/lightline.vim'
+ let g:lightline = {}
+ set laststatus=2
+
+ let g:lightline.colorscheme = 'wombat'
+ let g:lightline.component_expand = {
+ \ 'linter_checking': 'lightline#ale#checking',
+ \ 'linter_infos': 'lightline#ale#infos',
+ \ 'linter_warnings': 'lightline#ale#warnings',
+ \ 'linter_errors': 'lightline#ale#errors',
+ \ 'linter_ok': 'lightline#ale#ok',
+ \ }
+
+ let g:lightline.component_type = {
+ \ 'linter_checking': 'right',
+ \ 'linter_infos': 'right',
+ \ 'linter_warnings': 'warning',
+ \ 'linter_errors': 'error',
+ \ 'linter_ok': 'right',
+ \ }
+
+ let g:lightline.active = {
+ \ 'right': [ [ 'linter_checking', 'linter_errors', 'linter_war…
+ \ [ 'lineinfo' ],
+ \ [ 'percent' ],
+ \ [ 'fileformat', 'filetype'] ] }
+
+Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
+Plug 'junegunn/fzf.vim'
+ map <leader>f :Files!<CR>
+ nnoremap <Tab> :Buffers<CR>
+
+Plug 'airblade/vim-gitgutter'
+ let g:gitgutter_enabled=1
+
+Plug 'rhysd/vim-grammarous'
+ let g:grammarous#hooks = {}
+ map <leader>d :GrammarousCheck<CR>
+ function! g:grammarous#hooks.on_check(errs) abort
+ nmap <buffer><C-n> <Plug>(grammarous-move-to-next-error)
+ nmap <buffer><C-p> <Plug>(grammarous-move-to-previous-error)
+ endfunction
+
+Plug 'https://tildegit.org/sloum/gemini-vim-syntax'
+
+Plug 'dense-analysis/ale'
+ let g:ale_fixers = {
+ \ '*': ['remove_trailing_lines', 'trim_whitespace'],
+ \ 'sh': ['shfmt']}
+ let g:ale_linters = {
+ \ 'sh': ['shellcheck']}
+ let g:ale_sh_shellcheck_options = '-s sh'
+ let g:ale_sh_shfmt_options = '-p'
+ let g:ale_sign_error = '●'
+ let g:ale_sign_warning = '.'
+ let g:ale_fix_on_save = 1
+ let g:ale_linters_explicit = 1
+ let g:ale_sign_column_always = 1
+
+call plug#end()
+
+filetype plugin indent on
+set background=dark
+
+set mouse=
+set tabstop=8
+set shiftwidth=8
+set autoindent
+set colorcolumn=80
+set encoding=utf-8
+set number
+set ruler
+set nowrap
+set splitbelow
+set hidden
+set incsearch
+set hlsearch
+set ignorecase
+set noswapfile
+set nofoldenable
+set lazyredraw
+
+syntax enable
+
+" remove whitespaces
+autocmd BufWritePre * :%s/\s\+$//e
+
+" spell-check the current buffer
+map <leader>s :setlocal spell! spelllang=en_gb<CR>
+
+" run xrdb whenever xresources are updated
+autocmd BufWritePost *.config/X11/Xresources
+ \ !xrdb -merge ~/.config/X11/Xresources
+
+autocmd BufNewFile,BufRead ~/.cache/mutt* set tw=72
You are viewing proxied material from jay.scot. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.