diff --git a/scripts/.local/bin/0x0 b/scripts/.local/bin/0x0
new file mode 100755
index 0000000000000000000000000000000000000000..a9726984aaf9d8671759db4f26a66d7530508a32
--- /dev/null
+++ b/scripts/.local/bin/0x0
@@ -0,0 +1,22 @@
+#!/bin/sh
+# Original repository
+# https://git.lapacz-kornel.dev/dotfiles
+
+filename=$1
+
+if [ -z "$filename" ]; then
+ echo "usage: 0x0 filename"
+ exit 1
+fi
+
+if [ ! -f "$filename" ]; then
+ echo "file $filename doesn't exist"
+ exit 1
+fi
+
+url=$(curl -F"file=@$filename" https://0x0.st)
+
+[ -z "$url" ] && exit 1
+
+echo "$url"
+echo "$url" | xclip -selection clipboard
diff --git a/scripts/.local/bin/barhide b/scripts/.local/bin/barhide
new file mode 100755
index 0000000000000000000000000000000000000000..46a53062ff29cb578e171e0035aae96ddaf6effe
--- /dev/null
+++ b/scripts/.local/bin/barhide
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+id=$(xdo id -N "Polybar")
+
+if xprop -id $id | grep -q "Normal"; then
+ xdo hide -N "Polybar"
+ else
+ xdo show -N "Polybar"
+fi
diff --git a/scripts/.local/bin/dmenu_run_history b/scripts/.local/bin/dmenu_run_history
new file mode 100755
index 0000000000000000000000000000000000000000..8d436cada6df2b00fd7a270034feab8e199a9e95
--- /dev/null
+++ b/scripts/.local/bin/dmenu_run_history
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+cachedir=${XDG_CACHE_HOME:-"$HOME/.cache"}
+if [ -d "$cachedir" ]; then
+ cache=$cachedir/dmenu_run
+ historyfile=$cachedir/dmenu_history
+else # if no xdg dir, fall back to dotfiles in ~
+ cache=$HOME/.dmenu_cache
+ historyfile=$HOME/.dmenu_history
+fi
+
+IFS=:
+if stest -dqr -n "$cache" $PATH; then
+ stest -flx $PATH | sort -u > "$cache"
+fi
+unset IFS
+
+awk -v histfile=$historyfile '
+ BEGIN {
+ while( (getline < histfile) > 0 ) {
+ sub("^[0-9]+\t","")
+ x[$0]=1
+ }
+ } !x[$0]++ ' "$cache" \
+ | dmenu "$@" \
+ | awk -v histfile=$historyfile '
+ BEGIN {
+ FS=OFS="\t"
+ while ( (getline < histfile) > 0 ) {
+ count=$1
+ sub("^[0-9]+\t","")
+ fname=$0
+ history[fname]=count
+ }
+ close(histfile)
+ }
+
+ {
+ history[$0]++
+ }
+
+ END {
+ if(!NR) exit
+ for (f in history)
+ print history[f],f | "sort -t '\t' -k1rn >" histfile
+ }
+ ' \
+ | while read cmd; do ${SHELL:-"/bin/sh"} -c "$cmd" & done
diff --git a/scripts/.local/bin/gcat b/scripts/.local/bin/gcat
new file mode 100755
index 0000000000000000000000000000000000000000..702da2f3210dbfcc532e039b590e3fa68e40f4e9
--- /dev/null
+++ b/scripts/.local/bin/gcat
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+
+import cgi
+import os
+import socket
+import ssl
+import sys
+import urllib.parse
+
+def absolutise_url(base, relative):
+ # Absolutise relative links
+ if "://" not in relative:
+ # Python's URL tools somehow only work with known schemes?
+ base = base.replace("gemini://","http://")
+ relative = urllib.parse.urljoin(base, relative)
+ relative = relative.replace("http://", "gemini://")
+ return relative
+
+if len(sys.argv) != 2:
+ print("Usage:")
+ print("gcat gemini://gemini.circumlunar.space")
+ sys.exit(1)
+
+url = sys.argv[1]
+parsed_url = urllib.parse.urlparse(url)
+if parsed_url.scheme == "":
+ url = "gemini://"+url
+ parsed_url = urllib.parse.urlparse(url)
+
+if parsed_url.scheme != "gemini":
+ print("Sorry, Gemini links only.")
+ sys.exit(1)
+if parsed_url.port is not None:
+ useport = parsed_url.port
+else:
+ useport = 1965
+# Do the Gemini transaction
+while True:
+ s = socket.create_connection((parsed_url.hostname, useport))
+ context = ssl.SSLContext()
+ context.check_hostname = False
+ context.verify_mode = ssl.CERT_NONE
+ s = context.wrap_socket(s, server_hostname = parsed_url.netloc)
+ s.sendall((url + '\r\n').encode("UTF-8"))
+ # Get header and check for redirects
+ fp = s.makefile("rb")
+ header = fp.readline()
+ print(header.decode("UTF-8"), end="")
+ header = header.decode("UTF-8").strip()
+ status, mime = header.split()[:2]
+ # Handle input requests
+ if status.startswith("1"):
+ # Prompt
+ query = input("INPUT" + mime + "> ")
+ url += "?" + urllib.parse.quote(query) # Bit lazy...
+ # Follow redirects
+ elif status.startswith("3"):
+ url = absolutise_url(url, mime)
+ parsed_url = urllib.parse.urlparse(url)
+ # Otherwise, we're done.
+ else:
+ break
+# Fail if transaction was not successful
+if status.startswith("2"):
+ if mime.startswith("text/"):
+ # Decode according to declared charset
+ mime, mime_opts = cgi.parse_header(mime)
+ body = fp.read()
+ body = body.decode(mime_opts.get("charset","UTF-8"))
+ print(body, end="")
+ else:
+ print(fp.read(), end="")
diff --git a/scripts/.local/bin/md2gemini b/scripts/.local/bin/md2gemini
new file mode 100755
index 0000000000000000000000000000000000000000..f9c3f494acc6aa0f5dcf30222bd3cb5911638f5c
--- /dev/null
+++ b/scripts/.local/bin/md2gemini
@@ -0,0 +1,8 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import re
+import sys
+from md2gemini import main
+if __name__ == '__main__':
+ sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?