Commit Diff


commit - /dev/null
commit + 7b4d8efbf7235f3466936751530c52382615afb0
blob - /dev/null
blob + 4de1a4ea84f7a428e8af311110ce585f30531a32 (mode 644)
--- /dev/null
+++ .gitignore
@@ -0,0 +1 @@
+Makefile.local
blob - /dev/null
blob + 009f6dcf186d7888a558be5b95c5636355d4a093 (mode 644)
--- /dev/null
+++ Makefile
@@ -0,0 +1,38 @@
+# sed -n 's/^	//p' $? > $@
+
+.PHONY: all install publish
+
+all:
+	@echo "usage:"
+	@echo " - install: install/replace the files in the system"
+	@echo " - publish: generate gemini and www version of the files"
+	@echo " - serve-gem: serve the gem directory"
+	@echo " - serve-www: serve the www directory"
+	@echo " - upload: publish the files on the geminispace and the web"
+	@echo " - clean: undo publish"
+
+include Makefile.local
+
+install: ${DOTFILES}
+
+www: style.css
+	mkdir -p www
+	cp style.css www
+
+gem:
+	mkdir gem
+
+publish: gem ${GEMFILES} www ${WWWFILES}
+
+serve-gem: publish
+	gmid -p 1966 gem
+
+serve-www: publish
+	python3 -m http.server --directory www 8888
+
+upload:
+	rsync --delete -a gem/ op:gemini/dots.omarpolo.com
+	rsync --delete -a www/ op:sites/dots.omarpolo.com
+
+clean:
+	rm -rf gem www
blob - /dev/null
blob + 7fb2bd61bf20fdc022eeaaff4aa91f4763fd9df2 (mode 644)
--- /dev/null
+++ footer.html
@@ -0,0 +1,2 @@
+	</body>
+</html>
blob - /dev/null
blob + 9df578d621d4569af579205413567aab897d2467 (mode 755)
--- /dev/null
+++ gc
@@ -0,0 +1,22 @@
+#!/usr/bin/awk -f
+#
+# gc - gemini-fy code
+
+/^\t/ {
+	if (!pre) {
+		pre = 1
+		print "```"
+	}
+	print substr($0, 2)
+	next
+}
+
+// {
+	if (pre) {
+		pre = 0
+		print "```"
+	}
+	print $0
+}
+
+END { if (pre) print "```" }
blob - /dev/null
blob + 61c3f929155e7eb519489c8869706b0dfc703a5a (mode 755)
--- /dev/null
+++ gem2html
@@ -0,0 +1,102 @@
+#!/usr/bin/env perl
+#
+# Copyright (c) 2022 Omar Polo <op@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use v5.10;
+use strict;
+use warnings;
+
+my $in_pre = 0;
+my $in_list = 0;
+
+while (<>) {
+	chomp;
+	if ($in_pre && m/^```/) {
+		$in_pre = 0;
+		say "</pre>";
+	} elsif (!$in_pre && m/^```/) {
+		if ($in_list) {
+			$in_list = 0;
+			say "</ul>";
+		}
+		$in_pre = 1;
+		print "<pre>";
+	} elsif ($in_pre) {
+		say san($_);
+	} elsif ($in_list && m/^$/) {
+		say "</ul>";
+		$in_list = 0;
+	} elsif (m/^\*\s+(.*)/) { # NB: at least one space
+		if (!$in_list) {
+			$in_list = "item";
+			say "<ul>";
+		} elsif ($in_list eq "link") {
+			$in_list = "item";
+			say "</ul>";
+			say "<ul>";
+		}
+		output("li", $1);
+	} elsif (m/^=>\s*([^\s]*)\s*(.*)$/) {
+		if (!$in_list) {
+			$in_list = "link";
+			say "<ul class='link-list'>";
+		} elsif ($in_list eq "item") {
+			$in_list = "link";
+			say "</ul>";
+			say "<ul class='link-list'>";
+		}
+		my $href = $1;
+		$_ = $2 || $1;
+		say "<li><a href='$href'>". san() ."</a></li>";
+	} elsif (m/^###\s*(.*)$/) {
+		output("h3", $1);
+	} elsif (m/^##\s*(.*)$/) {
+		output("h2", $1);
+	} elsif (m/^#\s*(.*)$/) {
+		output("h1", $1);
+	} elsif (m/^>\s*(.*)$/) {
+		output("blockquote", $1);
+	} else {
+		output("p", $_);
+	}
+}
+
+sub san {
+	s/&/\&amp;/g;
+	s/</\&lt;/g;
+	s/>/\&gt;/g;
+	return $_;
+}
+
+sub output {
+	my ($tn, $content) = @_;
+
+	if (!$in_list && $tn eq "li") {
+		$in_list = 1;
+		say "<ul>";
+	}
+
+	if ($in_list && $tn ne "li") {
+		$in_list = 0;
+		say "</ul>";
+	}
+
+	if ($tn eq "p" && $content eq "") {
+		return;
+	}
+
+	$_ = $content;
+	say "<$tn>". san() ."</$tn>";
+}
blob - /dev/null
blob + c490c57bf6a624d2285856ab1e89ba51ae65d0ab (mode 755)
--- /dev/null
+++ gen
@@ -0,0 +1,43 @@
+#!/bin/sh
+#
+# stuff we should do in the makefile
+# but can't for portability reasons
+
+pair()
+{
+	files="$files $2"
+	dotfiles="\${HOME}/$1 $dotfiles"
+	cat <<EOF >> Makefile.local
+\${HOME}/$1: $2
+	./lpp \$? > \$@
+
+EOF
+}
+
+rm -f Makefile.local
+
+pair .profile	profile.lp
+pair .kshrc	kshrc.lp
+
+for file in $files; do
+	f="${file%.lp}"
+	gemfiles="gem/$f.gmi $gemfiles"
+	wwwfiles="www/$f.html $wwwfiles"
+
+	cat <<EOF >> Makefile.local
+gem/$f.gmi: $file
+	./unpar $file | ./gc > \$@
+
+www/$f.html: gem/$f.gmi header.html footer.html
+	sed 's!TITLE!$f!' header.html > \$@
+	./gem2html gem/$f.gmi >> \$@
+	cat footer.html >> \$@
+
+EOF
+done
+
+cat <<EOF >> Makefile.local
+GEMFILES =	$gemfiles
+WWWFILES =	$wwwfiles
+DOTFILES =	$dotfiles
+EOF
blob - /dev/null
blob + 6644df3cc886584cdb21e2c773a3e8a89eccf003 (mode 644)
--- /dev/null
+++ header.html
@@ -0,0 +1,11 @@
+<!doctype html.
+<html lang="en">
+	<head>
+		<meta charset="utf8" />
+		<title>TITLE | dots</title>
+		<meta	name="viewport"
+			content="width=device-width, initial-scale=1" />
+		<link rel="stylesheet" href="style.css" />
+	</head>
+	<body>
+		
blob - /dev/null
blob + ecec7ff541e4d5e1e41d3a9f80eedffcfcd4fba6 (mode 644)
--- /dev/null
+++ kshrc.lp
@@ -0,0 +1,213 @@
+# ksh
+
+OpenBSD ksh (sometimes called opdksh or oksh) is the default shell on
+OpenBSD, and is generally my go-to choince on other systems too.  It has
+a good ratio of features and simplicity
+
+	if [ "$TERM" = dumb ]; then
+		PS1='$ '
+		return
+	fi
+
+Enable emacs-like command editing regardless of $EDITOR and csh-like
+history expansion with !
+
+	set -o emacs
+	set -o csh-history
+
+Talking about history, by default ksh won't store any, which is
+unfortunate.  I can't live without my C-r working!
+
+	HISTCONTROL=ignoredups:ignorespace
+	HISTFILE=$HOME/.history
+	HISTSIZE=10000
+
+OpenBSD ksh has a limited support for programmed completions through
+static lists.  The completions are provided via an array called
+complete_$progname; or complete_$progname_$nth for the nth argument.
+
+Here's the completions for ssh and scp:
+
+	HOST_LIST=$(awk '/Host / {print $2}' ~/.ssh/config | xargs echo)
+
+	set -A complete_ssh -- $HOST_LIST
+	set -A complete_scp -- $HOST_LIST
+
+and for kill(1) and pkill(1)
+
+	set -A complete_kill_1 -- -9 -HUP -INFO -KILL -TERM
+	set -A complete_pkill_2 -- -SIGHUP -SIGUSR1 -SIGUSR2 -SIGTERM -SIGKILL
+
+and for vmd(8) if available
+
+	if pgrep -fq /usr/sbin/vmd; then
+		set -A complete_vmctl_1 -- console load reload start stop \
+			reset status send receive
+		set -A complete_vmctl -- \
+			$(vmctl status | awk '!/NAME/{printf "%s ", $NF}')
+	fi
+
+and for ifconfig(8)
+
+	set -A complete_ifconfig_1 -- $(ifconfig | grep ^[a-z] | cut -d: -f1)
+
+and for got(1)
+
+	set -A complete_got_1 --	\
+		init			\
+		import im		\
+		clone cl		\
+		fetch fe		\
+		checkout co		\
+		update up		\
+		status st		\
+		log			\
+		diff di			\
+		blame bl		\
+		tree tr			\
+		ref			\
+		branch br		\
+		tag			\
+		add			\
+		remove rm		\
+		revert rv		\
+		commit ci		\
+		send se			\
+		cherrypick cy		\
+		backout bo		\
+		rebase rb		\
+		histedit he		\
+		integrate ig		\
+		merge mg		\
+		stage sg		\
+		unstage ug		\
+		cat			\
+		info
+
+Tweak the output of ls
+
+	alias ls='ls -F'
+
+reset(1) doesn't work as expected inside tmux: the old output can still
+be consulted when scrolling.  If I, lazy as I am, bother to type "reset"
+I want to be sure that the history was cleared!
+
+	if [ -n "$TMUX" ]; then
+		alias reset='reset && tmux clear-history'
+	fi
+
+CDPATH is super useful!  I even wrote a post about it:
+https://www.omarpolo.com/post/enjoying-cdpath.html
+
+	export CDPATH=".:$HOME/w:/usr/ports:/usr/ports/mystuff:$HOME/quicklisp/local-projects"
+
+I love to hate gpg!  It needs some special treatments to work and this
+should also (finger crossed!) fix pinentry over ssh.  I'm not sure it
+works though, it's been a while since I've connected remotely to my
+desktop.
+
+	export GPG_TTY=$(tty)
+	if [ -n "$SSH_CONNECTION" ]; then
+		export PINENTRY_USER_DATA="USE_CURSES=1"
+	fi
+
+The BSDs have this incredibly useful signal available, it's a shame not
+to use it!
+
+	stty status ^T
+
+I really like my prompt to be as minimal as possible.  For some time
+I've used a single colon `;' as prompt, it's really nice!  At the moment
+thought I'm usign a more plan9-esque percent sign:
+
+	PS1='% '
+
+I got tired of trying to remember the set of flags for nc to walk to
+Gemini servers, so here we are:
+
+	# "post" stdin to the gemini server
+	# usage: gem host [port]
+	gem()
+	{
+		host="${1:?missing host}"
+		port="${2:-1965}"
+		nc -c -Tnoverify "${host}" "${port}"
+	}
+
+I think I've stolen these from someone.  It makes a copy of the file and
+launch an editor on the original file, incledibly useful when working
+with ports (that's why doas!)
+
+	mgdiff()
+	{
+		if [ -z "$1" ]; then
+			printf "%s\n" "USAGE: mgdiff file" >&2
+			return
+		fi
+		doas cp -p "$1" "$1.orig"
+		doas mg "$1"
+	}
+
+hist is a quick wrapper around history and grep to quickly search for a
+previous command:
+
+	hist()
+	{
+		if [ -z "$1" ]; then
+			printf "%s\n" "USAGE: hist pattern" >&2
+			return 1
+		fi
+		history 0 | grep "$1"
+	}
+
+Some aliases I use when working with the OpenBSD port tree:
+
+	alias m="make"
+	alias mup="make update-patches"
+	alias mupl="make update-plist"
+	alias build="MAKE_JOBS=5 time make 2>&1 | tee build"
+	alias pclear='make clean="package plist"'
+
+find(1) is an invaluable tool and I use it all the time.  walk is an
+attempt to build a wrapper around some common usages of find that is a
+little bit less verbose to use.  The name is stolen from 9front, but the
+implementation is completely different.
+
+	# usage: walk [dir] [type] [name regexp] [! command to execute]
+	walk()
+	{
+		if [ $# -eq 0 ]; then
+			find .
+			return
+		fi
+
+		local dir=.
+		local type=
+		local name=\*
+
+		if [ -n "$1" -a -d "$1" ]; then
+			dir="$1"
+			shift
+		fi
+
+		case "$1" in
+		b|c|d|f|l|p|s)
+			type="-type $1"
+			shift
+		esac
+
+		if [ -n "$1" -a "x$1" != "x!" ]; then
+			name="$1"
+			shift
+		fi
+
+		if [ "x$1" = x! ]; then
+			shift
+		fi
+
+		if [ $# -eq 0 ]; then
+			find "$dir" $type -iname "$name"
+		else
+			find "$dir" $type -iname "$name" -exec "$@" {} +
+		fi
+	}
blob - /dev/null
blob + 053de1c9cad716f6f9b51ea5c662ab8e550f4c0f (mode 755)
--- /dev/null
+++ lpp
@@ -0,0 +1,18 @@
+#!/usr/bin/awk -f
+#
+# lpp - literate programming processor
+
+/^\t/ {
+	if (!pre) {
+		pre = 1
+		if (did)
+			print ""
+		else
+			did = 1
+	}
+
+	print substr($0, 2)
+	next
+}
+
+// { pre = 0 }
blob - /dev/null
blob + 864a9d7e8ba821ea089805c3667302a804906402 (mode 644)
--- /dev/null
+++ profile.lp
@@ -0,0 +1,126 @@
+# profile
+
+I don't know how "portable" a .profile can be, but let's try!
+
+Althought I'm not using acme as my go-to text editor program, I still
+like to use it and have the rest of the plan9ports at hand.
+
+I manually fetched and installed the ports in /usr/local/plan9, and need
+to define $PLAN9 in order for the various tooling to work.
+
+	PLAN9=/usr/local/plan9
+	export PLAN9
+
+I tend to have an abnormal $PATH
+
+	PATH=$HOME/bin:$HOME/opt/emacs/bin:$HOME/opt/gcc10/bin:$HOME/go/bin:$HOME/opt/unnethack/bin:$HOME/.local/bin:$HOME/.node_modules/bin:/home/ports/infrastructure/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games:/usr/local/jdk-11/bin:$PLAN9/bin
+
+Let's split it:
+
+* $HOME/bin is for my personal scripts, needs to take precedence over anything else
+* $HOME/opt/* contains various stuff I compile from source, like Emacs
+* $HOME/.local/bin is XDG stuff I'm practically forced to use
+* $HOME/.node_modules/bin is for node
+* /usr/ports/infrastructure/bin is for handy port tools
+* the rest is just the usual $PATH on OpenBSD with java and plan9 pushed at the end
+
+Tell npm to install things globally in the right directory
+
+	export npm_config_prefix=~/.node_modules
+
+Just in case I want to play with lua again:
+
+	if which luarocks-5.3 >/dev/null 2>&1; then
+		eval "$(luarocks-5.3 path --bin)"
+	fi
+
+ksh doesn't have a "default" configuration file (like ~/.zshrc or
+~/.bashrc); instead, if called interactively, it loads the file pointed
+by ENV.  Tell ksh to load ~/.kshrc then
+
+	export ENV=$HOME/.kshrc
+
+An UTF-8 locale is mandatory.  I'm using en_US even if english is not my
+main language:
+
+	export LANG=en_US.UTF-8
+
+Got is quickly becoming my favourite version control system.  It should
+be able to load the author data from a config file, but I still keep
+this variable, just in case :)
+
+	export GOT_AUTHOR="Omar Polo <op@omarpolo.com>"
+
+Sometimes I need to do stuff with Docker.  I have a virtual machine
+running alpine with docker configured and this bit here will allow
+docker-cli to transparently talk to the VM:
+
+	export DOCKER_HOST=ssh://op@100.64.2.3:22
+
+I like to use mg as my default editor but under vterm is a bit of a pain
+because emacs keeps eating up all the various C-c and C-x keys.  Thus,
+switch back to vi when INSIDE_EMACS (which sounds strange, I know)
+
+	if [ -z "$INSIDE_EMACS" ]; then
+		VISUAL=mg
+		EDITOR=mg
+	else
+		VISUAL=vi
+		EDITOR=vi
+	fi
+
+	export VISUAL EDITOR
+
+less(1) should be the default pager pretty most everywhere, but ensure
+that!
+
+	export MANPAGER=less
+
+I've found a cool pager for postgresql, pspg.  It's designed explicitly
+for tabular data.  Extra points for having some cool light themes!  Tao
+light theme (number 20) is my favourite.
+
+	export PSQL_PAGER='pspg -s20'
+
+I'm using reposync to manage my local clone of the OpenBSD source tree.
+Technically this isn't needed, because /home/ports is already a checkout
+from /home/cvs, but anyway...
+
+	export CVSROOT=/home/cvs
+
+This is just to make some command outputs a little bit nicer:
+
+	export BLOCKSIZE=1m
+
+I don't particularly like coloured outputs when I'm in front of a
+terminal, so I tend to disable them:
+
+	export NO_COLOR='yes, please'
+	export CMAKE_COLOR_MAKEFILE=OFF
+	export WG_COLOR_MODE=never
+
+...as an exception I'm trying to enable colors in tog(1) (cautiously!)
+and see how it goes:
+
+	export TOG_COLORS=yes
+	export TOG_COLOR_DIFF_MINUS=magenta
+	export TOG_COLOR_DIFF_PLUS=blue
+	export TOG_COLOR_DIFF_CHUNK_HEADER=green
+	export TOG_COLOR_DIFF_META=default
+	export TOG_COLOR_COMMIT=default
+	export TOG_COLOR_AUTHOR=default
+	export TOG_COLOR_DATE=default
+	export TOG_COLOR_REFS_REMOTES=red
+
+On OpenBSD, automake and autoconf requires these variables to be up to
+work.  Otherwise one can run automake-X.Y and autoconf-X.Y, but that's
+ugly:
+
+	export AUTOCONF_VERSION=2.69
+	export AUTOMAKE_VERSION=1.16
+
+Finally, load the specific profile for this machine if it exists:
+
+	if [ -f "$HOME/.profile-local" ]; then
+		. "$HOME/.profile-local"
+	fi
blob - /dev/null
blob + 795b460abb3a3ddc313b30cdd4383ee9679cebb8 (mode 644)
--- /dev/null
+++ style.css
@@ -0,0 +1,81 @@
+body {
+	font-family: monospace;
+	font-size: 14px;
+	max-width: 780px;
+	margin: 0 auto;
+	padding: 20px;
+	padding-bottom: 80px;
+}
+
+h1::before {
+	content: "# ";
+}
+
+h2 {
+	margin-top: 40px;
+}
+
+h2::before {
+	content: "## ";
+}
+
+h3::before {
+	content: "### ";
+}
+
+blockquote {
+	margin: 0;
+	padding: 0;
+}
+
+blockquote::before {
+	content: "> ";
+}
+
+blockquote p {
+	font-style: italic;
+	display: inline;
+}
+
+strong::before { content: "*" }
+strong::after  { content: "*" }
+
+img {
+	border-radius: 5px;
+}
+
+pre {
+	overflow: auto;
+	padding: 1rem;
+	background-color: #f0f0f0;
+	border-radius: 3px;
+}
+
+ul.link-list {
+	list-style: disclosure-closed;
+}
+
+img {
+	display: block;
+	margin: 0 auto;
+	max-width: 100%;
+}
+
+@media (prefers-color-scheme: dark) {
+	body {
+		background-color: #222;
+		color: white;
+	}
+
+	a {
+		color: aqua;
+	}
+
+	hr {
+		background-color: #ddd;
+	}
+
+	pre {
+		background-color: #353535;
+	}
+}
blob - /dev/null
blob + 8eaac4b58cc70ff897568dc201a1f75401fc1c82 (mode 755)
--- /dev/null
+++ unpar
@@ -0,0 +1,46 @@
+#!/usr/bin/awk -f
+#
+# unpar - un-paragraphize text
+
+/^\* / {
+	item = 1
+	if (line != "")
+		print line
+	line = $0
+	next
+}
+
+item && /^ +/ {
+	s = gensub(" +", "", "1", $0)
+	line = sprintf("%s %s", line, s)
+	next
+}
+
+// { item = 0 }
+
+/^$/ {
+	if (line != "")
+		print line
+	line = ""
+	print ""
+}
+
+/^[[:blank:]]+/ {
+	if (line != "")
+		print line
+	line = ""
+	print $0
+	next
+}
+
+// {
+	if (line != "")
+		line = sprintf("%s %s", line, $0)
+	else
+		line = $0
+}
+
+END {
+	if (line)
+		print line
+}