all repos — dotfiles @ f32f507400d14c2fbaac570b600beaef602ad56a

my *nix dotfiles

nix: switch to nixos
Anirudh Oppiliappan x@icyphox.sh
Mon, 14 Mar 2022 10:13:00 +0530
commit

f32f507400d14c2fbaac570b600beaef602ad56a

parent

495f841eb3c8278bcf6b1e3e2101c0d6440f24d6

M .gitignore.gitignore

@@ -1,1 +1,3 @@

-prompt/prompt+prompt/prompt +result +config/nvim/init.vim
D acme/editinacme/editinacme.go

@@ -1,68 +0,0 @@

-// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Editinacme can be used as $EDITOR in a Unix environment. -// -// Usage: -// -// editinacme <file> -// -// Editinacme uses the plumber to ask acme to open the file, -// waits until the file's acme window is deleted, and exits. - -package main - -import ( - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - - "9fans.net/go/acme" -) - -func main() { - log.SetFlags(0) - log.SetPrefix("editinacme: ") - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "usage: editinacme file\n") - os.Exit(2) - } - flag.Parse() - if flag.NArg() != 1 { - flag.Usage() - } - - file := flag.Arg(0) - - fullpath, err := filepath.Abs(file) - if err != nil { - log.Fatal(err) - } - file = fullpath - - r, err := acme.Log() - if err != nil { - log.Fatal(err) - } - - log.Printf("editing %s", file) - - out, err := exec.Command("plumb", "-d", "edit", file).CombinedOutput() - if err != nil { - log.Fatalf("executing plumb: %v\n%s", err, out) - } - - for { - ev, err := r.Read() - if err != nil { - log.Fatalf("reading acme log: %v", err) - } - if ev.Op == "del" && ev.Name == file { - break - } - } -}
D acme/editinacme/go.mod

@@ -1,5 +0,0 @@

-module git.icyphox.sh/dotfiles/acme/editinacme - -go 1.16 - -require 9fans.net/go v0.0.4
D acme/editinacme/go.sum

@@ -1,2 +0,0 @@

-9fans.net/go v0.0.4 h1:g7K+b5I1PlSBFLnjuco3LAx5boK39UUl0Gsrmw6Gl2U= -9fans.net/go v0.0.4/go.mod h1:lfPdxjq9v8pVQXUMBCx5EO5oLXWQFlKRQgs1kEkjoIM=
D bash/.bashrc

@@ -1,58 +0,0 @@

-# better history syncing -shopt -s histappend -export HISTCONTROL=ignoreboth:erasedups -HISTSIZE=40000 -HISTFILESIZE=40000 - -# cool options for cool kids -shopt -s \ - autocd \ - globstar \ - checkwinsize \ - cdspell \ - dirspell \ - expand_aliases \ - dotglob \ - gnu_errfmt \ - histreedit \ - nocasematch - -bind 'set completion-ignore-case on' -bind 'set show-all-if-ambiguous on' -bind 'set colored-stats on' -bind 'set completion-display-width 1' -bind 'TAB:menu-complete' - -# Ctrl+W kills word -stty werase undef -bind '"\C-w": backward-kill-word' - -# fzy reverse search -__fzy_history() { - ch="$(fc -l 1 | awk -F'\t' '{print $2}' | sort -u | fzy)" - : "${ch#"${ch%%[![:space:]]*}"}" - printf "$_" -} - -bind -x '"\C-r": READLINE_LINE=$(__fzy_history); READLINE_POINT="${#READLINE_LINE}"' - -complete -cf doas - -# z (darwin) -[[ -f /usr/local/etc/profile.d/z.sh ]] && -. /usr/local/etc/profile.d/z.sh - -# z (bsd) -[[ -f ~/bin/z.sh ]] && -. ~/bin/z.sh - -for i in ~/.bashrc.d/[0-9]*; do - . "$i" -done - -export NVM_DIR="$HOME/.nvm" -[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm -[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion - -[[ -f /usr/local/share/bash-completion/bash_completion ]] && - . /usr/local/share/bash-completion/bash_completion
D bash/.bashrc.d/04-exports.bash

@@ -1,34 +0,0 @@

-# export thingys -export EDITOR=nvim -export BROWSER=firefox -export SSH_KEY_PATH="~/.ssh/id_rsa" -export GPG_TTY=$(tty) -export INPUTRC=~/.inputrc -export PATH=$PATH:$HOME/.local/bin:/usr/local/go/bin:$HOME/go/bin:/usr/local/pgsql/bin -export PW_DIR=~/.pw -export PW_KEY=x@icyphox.sh -export _Z_CMD="n" -export MOZ_ACCELERATED=1 -export CFLAGS="-O3 -pipe -march=native" -export CXXFLAGS="-O3 -pipe -march=native" -export MAKEFLAGS="-j4" -export LC_ALL="en_US.UTF-8" -# not this time elgoog -export GOPROXY=direct - -# gpg-agent -[[ -f "$HOME/.gpg-agent-info" ]] && { - . "$HOME/.gpg-agent-info" - export GPG_AGENT_INFO - export SSH_AUTH_SOCK - export SSH_AGENT_PID -} - -PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games -export PATH=$PATH:$HOME/bin -export PATH=$PATH:$HOME/.local/bin -export PATH=$PATH:/usr/local/go/bin -export PATH=$PATH:$HOME/go/bin -export PATH=$PATH:/usr/local/pgsql/bin -export PATH=$PATH:/usr/local/plan9/bin -
M bash/.bashrc.d/90-aliases.bashbash/.bashrc.d/90-aliases.bash

@@ -1,28 +1,3 @@

-alias o="xdg-open" -alias gc="git commit -v -S" -alias gst="git status --short" -alias ga="git add" -alias gd="git diff --minimal" -alias gl="git log --oneline --decorate --graph" -alias vim="nvim" -alias k="kubectl" - -nvmon() { - source ~/.nvm/nvm.sh -} - -envac() { - source .env/bin/activate -} - -vpn() { - ~/bin/vpnon.sh -} - -dt() { - time.sh -n -} - ggp() { [[ "$1" == "-f" ]] && { git push "$(git remote show)" -f "$(git branch --show-current)"

@@ -48,28 +23,3 @@ else

git checkout -b "$1" fi } - -ls() { - case "$OSTYPE" in - "linux"*) - /bin/ls "$@" - ;; - "darwin"*) - /bin/ls -G "$@" - ;; - *"bsd"*) - colorls -G "$@" - ;; - esac -} - -m() { - case "$OSTYPE" in - "darwin"*) - s-nail "$@" - ;; - *"bsd"*) - nail "$@" - ;; - esac -}
M bash/.bashrc.d/99-prompt.bashbash/.bashrc.d/99-prompt.bash

@@ -2,5 +2,5 @@ refresh_tmux() {

tmux refresh-client -S } PROMPT_COMMAND=refresh_tmux -PS1='\n▲ ' +PS1="\n\001\e[0;36m\002▲\001\e[0m\002 "; PS2="> "
D bin/a

@@ -1,16 +0,0 @@

-#!/bin/sh - -export NO_COLOR=1 -export PAGER=nobs - -if ! pgrep -x plumber > /dev/null -then - plumber -fi - -if ! pgrep -x acme > /dev/null -then - ~/code/acme/o.acme -a -f /mnt/font/SFMonoLigaturized-Regular/12a/font $1 -else - editinacme $1 -fi
D bin/bar

@@ -1,20 +0,0 @@

-#!/bin/sh - -dt() { - date +"%a, %d %b" | tr A-Z a-z -} - -vol() { - v="$(sndioctl -n output.level)" - echo $(echo "$v"*100 / 1 | bc)% -} - -pad="%{015}" - -while :; do - bat="$(bat -q)" - time="$(date +"%H:%M")" - echo "$pad $(dt) $pad $time %{r}bat $bat %{O14}vol $(vol) $pad" - sleep 0.5 -done | lemonbar-xft -n bar -f 'Input:style=Regular:size=12:antialias=true' -g x30 \ - -F '#f4f4f4' -B '#222'
D bin/bat

@@ -1,27 +0,0 @@

-#!/usr/bin/env bash - -if [[ "$(uname)" == "Darwin" ]]; then - cap="$(pmset -g batt | grep -Eo "\d+%" | cut -d% -f1)" - is_charging="" -else - cap="$(apm -l)" - is_charging="$(apm -a)" - - status="discharging" -fi - -tmux_bat() { - if [[ "$is_charging" -eq 1 ]]; then - printf '%s%%' "+$cap" - else - printf '%s%%' "$cap" - fi -} - -if [[ "$1" == "-q" ]]; then - tmux_bat -else - [[ "$is_charging" -eq 1 ]] && - status="charging" - printf '%s%% [%s]\n' $cap $status -fi
D bin/c+

@@ -1,7 +0,0 @@

-#!/bin/sh - -symbol="$1" - -[ ! "$symbol" ] && symbol='// ' - -sed "s!^!$symbol!"
D bin/c-

@@ -1,8 +0,0 @@

-#!/bin/sh - -symbol="$1" - -[ ! "$symbol" ] && symbol="// " - - -sed "s!^$symbol*!!"
D bin/coltest

@@ -1,9 +0,0 @@

-#!/usr/bin/env bash - -printf '\n' - -for (( i=0; i<7; i++ )); do - printf '\033[4%sm \033[m ' "$i" -done - -printf '\n'
D bin/diff

@@ -1,7 +0,0 @@

-#!/bin/sh - -[[ "$#" = 0 ]] && { - printf '%s\n' "usage: file1 file2 ... fileN" - exit -} -nvim -d "$@"
D bin/git-new-push-remote

@@ -1,12 +0,0 @@

-#!/bin/sh -# git new-push-remote: adds a new push-only remote to a repository -# without removing the existing push remote. - -[[ "$@" == "" ]] && { - printf '%s\n' "usage: git new-push-remote <remote url>" - exit -} - -old_push_remote="$(git remote -v | grep '(push)' | awk '{print $2}')" -git remote set-url "$(git remote show)" --add --push "$1" -git remote set-url "$(git remote show)" --add --push "$old_push_remote"
D bin/git-new-repo

@@ -1,8 +0,0 @@

-#!/usr/bin/env bash - -repo="$1" -[[ "$1" == "" ]] && repo="$(basename "$PWD")" -ssh git@jade git init --bare "$repo" -read -p "descripton: " desc -printf '%s' "$desc" > .git/description -rsync .git/description git@jade:"$repo"
D bin/i+

@@ -1,3 +0,0 @@

-#!/bin/sh - -sed s'/^'/' '/
D bin/i-

@@ -1,3 +0,0 @@

-#!/bin/sh - -sed s'/^ '//
D bin/log

@@ -1,7 +0,0 @@

-#!/bin/sh -# life log - -date="$(date "+%Y-%m-%d %H:%M:%S")" -l="$(cat)" -[ "$l" = "" ] && exit -printf '%s\t%s\n' "$date" "$l" >> ~/log
D bin/mailsync

@@ -1,10 +0,0 @@

-#!/bin/sh -# mailsync: sync email using mbsync and notify on new mail - -mbsync -qa &>/dev/null - -new="$HOME/mail/personal/Inbox/new/" -count="$(find $new -type f | wc -l)" - -[[ "$count" -gt 0 ]] && - printf 'SEC:5\tTAG:mail\tMail\t%s new mail\n' "$count" > "$XNOTIFY_FIFO"
D bin/notify-send

@@ -1,12 +0,0 @@

-#!/bin/sh -# mimic notify-send using xnotify - -[[ $(pgrep xnotify) == "" ]] && { - XNOTIFY_FIFO="$HOME/.cache/xnotify$DISPLAY.fifo" - export XNOTIFY_FIFO - rm -f $XNOTIFY_FIFO - mkfifo $XNOTIFY_FIFO - xnotify <$XNOTIFY_FIFO 3<>$XNOTIFY_FIFO & -} - -printf '%s\n' "$*" > $XNOTIFY_FIFO
D bin/np.sh

@@ -1,26 +0,0 @@

-#!/usr/bin/env bash - -stripnl() { - printf '%s' "${1##"\n"}" -} - -check_playing() { - status="$(cmus-remote -Q | grep status | cut -d ' ' -f 2)" - [[ "$status" == "paused" ]] && exit -} - -check_playing -mapfile np < <(cmus-remote -Q | grep tag | head -n3 | sort -r | cut -d ' ' -f 3-) -track="$(stripnl "${np[0]}")" -artist="$(stripnl "${np[1]}")" - -case "$1" in - "-a") - printf '%s' "$artist" - ;; - "-t") - printf '%s' "$track" - ;; - *) - printf '%s - %s\n' "$artist" "$track" -esac
D bin/pkg

@@ -1,20 +0,0 @@

-#!/bin/sh -# pkg - a wrapper around pkg_* - -case "$1" in - add*) - shift - doas pkg_add "$@" - ;; - del*) - shift - doas pkg_delete "$@" - ;; - info*) - shift - doas pkg_info -Q "$@" - ;; - upd*) - doas pkg_add -u - ;; -esac
D bin/pwmenu.sh

@@ -1,5 +0,0 @@

-#!/bin/sh - -p="$(pw -l | xprompt pw)" -[[ "$p" == "" ]] && exit -pw -c "$p"
D bin/record

@@ -1,96 +0,0 @@

-#!/bin/sh -# stolen from mitch weaver - -: "${RECORD_FRAMERATE:=30}" -: "${RECORD_OUTPUT_DIR:=$PWD}" - -mkdir -p /tmp/record -sock=/tmp/record/sock -pidfile=/tmp/record/pidfile - -msg() { printf '* %s\n' "$*" ; } -die() { >&2 msg "$*" ; exit 1 ; } - -usage() { - die "Usage: ${0##*/} [-o output dir] [-r rate] [-f foreground]" -} - -isrunning() { kill -0 "$(getpid)" 2>/dev/null ; return $? ; } - -getpid() { - [ -s $pidfile ] && read -r pid <$pidfile - echo "${pid:-?}" -} - -start() { - isrunning && die "Another instance already exists: $(getpid)" - - file="$RECORD_OUTPUT_DIR/record-$(date "+%Y.%m.%d-%H:%M:%S").mp4" - :>$sock - - if command -v xrectsel >/dev/null ; then - xrectsel -f '%x %y %w %h' - elif command -v slop >/dev/null ; then - slop -f '%x %y %w %h' - else - die 'Needs xrectsel or slop' - fi | { - read -r x y w h - - <$sock ffmpeg -y -f x11grab -s "${w}x${h}" -r $RECORD_FRAMERATE \ - -i "${DISPLAY:-:0}+${x},${y}" -vcodec libx264 \ - -pix_fmt yuv420p -filter:v "crop=iw-mod(iw\\,2):ih-mod(ih\\,2)" \ - "$file" >/tmp/record/log 2>&1 & - - msg "recording on pid $!" - - if ${FOREGROUND:-false} ; then - trap 'rm "$sock" /tmp/record/log 2>/dev/null ||: ; rmdir /tmp/record 2>/dev/null ||:' EXIT INT TERM - wait - else - echo $! >$pidfile - echo "$file" >/tmp/record/file - fi - } -} - -end() { - if isrunning ; then - echo q >>$sock - read -r name </tmp/record/file - msg "Success! Saved as $name" - rm /tmp/record/* 2>/dev/null ||: - rmdir /tmp/record 2>/dev/null ||: - exit - else - die 'Nothing being recorded.' - fi -} - -toggle() { - if isrunning ; then - end - else - start - fi -} - -while [ "$1" ] ; do - case $1 in - -f) - FOREGROUND=true - ;; - -r) - RECORD_FRAMERATE=$1 - ;; - -o) - [ -d "$2" ] || usage - RECORD_OUTPUT_DIR=$2 - shift - ;; - *) usage - esac - shift -done - -toggle
D bin/scr

@@ -1,42 +0,0 @@

-#!/usr/bin/env bash -# scr: screenshot tool - -scr_path=~/pics/scrots -output="$(tr -dc 'a-zA-Z0-9' < /dev/random | fold -w 5 | head -n 1)" - -usage() { - echo "usage:" - echo " scr [option]" - echo "options:" - echo " -f full screenshot" - echo " -w window screenshot" - echo " -s selection screenshot" -} - -while getopts fws option -do - case $option in - f) - import -window root "$scr_path/$output.png" - ;; - w) - import -window "$(xdotool getwindowfocus)" "$scr_path/$output.png" - ;; - s) - import "$scr_path/$output.png" - ;; - * | ?) - usage - exit;; - esac -done - -if [ $OPTIND -eq 1 ]; then - echo "scr: missing argument" - usage - exit -fi - - -xclip -selection clipboard -t image/png -i "$scr_path/$output.png" -cp "$scr_path/$output.png" "$scr_path/latest.png"
D bin/setup-gpg

@@ -1,9 +0,0 @@

-#!/bin/sh -# unlock gpg key on login - -pw="$(ssh-askpass 'Unlock your GPG key')" -keygrip=$(gpg-connect-agent -q 'keyinfo --list' /bye | awk '/KEYINFO/ { print $3 }') - -for k in $keygrip; do - echo "$pw" | /usr/local/libexec/gpg-preset-passphrase --preset $k -done
D bin/signal

@@ -1,10 +0,0 @@

-#!/bin/sh -# signal: launch signal-desktop via a vm (vmm(4)) - -status="$(vmctl status 1 | grep running)" -[[ "$status" == "" ]] && { - vmctl start pantwo - sleep 10 -} - -ssh -Y pantwo signal-desktop &> /dev/null
D bin/up

@@ -1,24 +0,0 @@

-#!/usr/bin/env bash - -LATEST_SCROT="$HOME/pics/scrots/latest.png" - -upload() { - out="$(curl -s -F "file=@$1" -F "key=$(pw -s fsrv)" https://x.icyphox.sh)" - [[ ! "$NO_CP" -eq 1 ]] && { - case "$OSTYPE" in - darwin*) - printf "$out" | pbcopy - ;; - *) - printf "$out" | xclip -sel c - ;; - esac - } - printf "$out\n" -} - -if [ "$1" == "l" ]; then - upload "$LATEST_SCROT" -elif [ "$1" != "l" ]; then - upload "$1" -fi
D bin/w

@@ -1,3 +0,0 @@

-#!/bin/sh - -fmt -72
D bin/x

@@ -1,92 +0,0 @@

-#!/usr/bin/env bash -# icyinfo, but better - -export BLK="\e[30m" -export RED="\e[31m" -export GRN="\e[32m" -export YLW="\e[33m" -export BLU="\e[34m" -export PUR="\e[35m" -export CYN="\e[36m" -export BRED="\e[31m" -export BGRN="\e[32m" -export BYLW="\e[33m" -export BBLU="\e[34m" -export BPUR="\e[35m" -export BCYN="\e[36m" -export WHT="\e[37m" -export RST="\e[0m" - -#BAR="████" -#((LEN = ${#BAR} * 6)) -#COLOR_BARS="$RED$BAR$GRN$BAR$YLW$BAR$BLU$BAR$PUR$BAR$CYN$BAR$RST" - -basename() { - # Usage: basename "path" ["suffix"] - local tmp - - tmp=${1%"${1##*[!/]}"} - tmp=${tmp##*/} - tmp=${tmp%"${2/"$tmp"}"} - - printf '%s\n' "${tmp:-/}" -} - -prinfo() { - # 1 - field - # 2 - info - # 3 - prev line - prev_line="$1$2" - export prev_line - - - printf '\e[%sD\e[B' "${#3}" - printf '%b' "${BLU}$1${RST}$2" -} - -user="$USER" -host="$HOSTNAME" -kernel="$(uname -r)" -shell="$(basename "$SHELL")" - -# cactus art -#art=" -#${GRN} -# o -#.oo.Oo. -# O. -# Ooo'${RST} -# ${RED}___${RST}${GRN}O${RST}${RED}___ -# \ / -# \___/${RST} -#" - -# blowfish - -printf '\e[?25l' -art=" -${YLW} \.-----./ - / ^ ^ ^ \ ${RST} - (${PUR}o${RST})(${PUR}o${RST})${YLW} ^ ^ |_/|${RST} - ${RED}{}${RST} ${YLW}^ ^ > ^| \| - \^ ^ ^ ^/ - /-----\\ ${RST} - -" - -printf '%b' "$art" -os="$(uname)" -pkgs="$(pkg_info | wc -l)" - -printf '%b\n' "${CYN}$user${RST}@${CYN}$host${RST}" - -prinfo "os" " $os" -prinfo "kernel" " $kernel" "$prev_line" -prinfo "pkgs" " $pkgs" "$prev_line" -prinfo "shell" " $shell" "$prev_line" - - -# Pause -read -rsn1 _ -printf '\n' -printf '\e[?25h'
D bin/xres

@@ -1,4 +0,0 @@

-#!/bin/sh -# stolen from nerdy - -xrdb -query | grep -w $1 | awk '{print $2}'
D bin/xurls

@@ -1,20 +0,0 @@

-#!/usr/bin/env bash -# extract urls in current tmux pane and pass it to fzy - -content="$(tmux capture-pane -J -p)" - -mapfile -t urls < <(echo "$content" | grep -oE '(https?|ftp|file):/?//[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]') -mapfile -t wwws < <(echo "$content" | grep -oE '(http?s://)?www\.[a-zA-Z](-?[a-zA-Z0-9])+\.[a-zA-Z]{2,}(/\S+)*' | grep -vE '^https?://' |sed 's/^\(.*\)$/http:\/\/\1/') -mapfile -t ips < <(echo "$content" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(:[0-9]{1,5})?(/\S+)*' |sed 's/^\(.*\)$/http:\/\/\1/') -mapfile -t gits < <(echo "$content" | grep -oE '(ssh://)?git@\S*' | sed 's/:/\//g' | sed 's/^\(ssh\/\/\/\)\{0,1\}git@\(.*\)$/https:\/\/\2/') - -items="$(printf '%s\n' "${urls[@]}" "${wwws[@]}" "${ips[@]}" "${gits[@]}" | - grep -v '^$' | - sort -u | - nl -w3 -s ' ' -)" - -[ -z "$items" ] && exit - -u="$(fzy <<< "$items" | awk '{ print $2 }')" -luakit "$u"
D bin/z.sh

@@ -1,213 +0,0 @@

-#!/usr/bin/env bash -[ -d "${_Z_DATA:-$HOME/.z}" ] && { - echo "ERROR: z.sh's datafile (${_Z_DATA:-$HOME/.z}) is a directory." -} - -_z() { - - local datafile="${_Z_DATA:-$HOME/.z}" - - # if symlink, dereference - [ -h "$datafile" ] && datafile=$(readlink "$datafile") - - # bail if we don't own ~/.z and $_Z_OWNER not set - [ -z "$_Z_OWNER" -a -f "$datafile" -a ! -O "$datafile" ] && return - - _z_dirs () { - [ -f "$datafile" ] || return - - local line - while read line; do - # only count directories - [ -d "${line%%\|*}" ] && echo "$line" - done < "$datafile" - return 0 - } - - # add entries - if [ "$1" = "--add" ]; then - shift - - # $HOME and / aren't worth matching - [ "$*" = "$HOME" -o "$*" = '/' ] && return - - # don't track excluded directory trees - if [ ${#_Z_EXCLUDE_DIRS[@]} -gt 0 ]; then - local exclude - for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do - case "$*" in "$exclude"*) return;; esac - done - fi - - # maintain the data file - local tempfile="$datafile.$RANDOM" - local score=${_Z_MAX_SCORE:-9000} - _z_dirs | awk -v path="$*" -v now="$(date +%s)" -v score=$score -F"|" ' - BEGIN { - rank[path] = 1 - time[path] = now - } - $2 >= 1 { - # drop ranks below 1 - if( $1 == path ) { - rank[$1] = $2 + 1 - time[$1] = now - } else { - rank[$1] = $2 - time[$1] = $3 - } - count += $2 - } - END { - if( count > score ) { - # aging - for( x in rank ) print x "|" 0.99*rank[x] "|" time[x] - } else for( x in rank ) print x "|" rank[x] "|" time[x] - } - ' 2>/dev/null >| "$tempfile" - # do our best to avoid clobbering the datafile in a race condition. - if [ $? -ne 0 -a -f "$datafile" ]; then - env rm -f "$tempfile" - else - [ "$_Z_OWNER" ] && chown $_Z_OWNER:"$(id -ng $_Z_OWNER)" "$tempfile" - env mv -f "$tempfile" "$datafile" || env rm -f "$tempfile" - fi - - # tab completion - elif [ "$1" = "--complete" -a -s "$datafile" ]; then - _z_dirs | awk -v q="$2" -F"|" ' - BEGIN { - q = substr(q, 3) - if( q == tolower(q) ) imatch = 1 - gsub(/ /, ".*", q) - } - { - if( imatch ) { - if( tolower($1) ~ q ) print $1 - } else if( $1 ~ q ) print $1 - } - ' 2>/dev/null - - else - # list/go - local echo fnd last list opt typ - while [ "$1" ]; do case "$1" in - --) while [ "$1" ]; do shift; fnd="$fnd${fnd:+ }$1";done;; - -*) opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in - c) fnd="^$PWD $fnd";; - e) echo=1;; - h) echo "${_Z_CMD:-z} [-cehlrtx] args" >&2; return;; - l) list=1;; - r) typ="rank";; - t) typ="recent";; - x) sed -i -e "\:^${PWD}|.*:d" "$datafile";; - esac; opt=${opt:1}; done;; - *) fnd="$fnd${fnd:+ }$1";; - esac; last=$1; [ "$#" -gt 0 ] && shift; done - [ "$fnd" -a "$fnd" != "^$PWD " ] || list=1 - - # if we hit enter on a completion just go there - case "$last" in - # completions will always start with / - /*) [ -z "$list" -a -d "$last" ] && builtin cd "$last" && return;; - esac - - # no file yet - [ -f "$datafile" ] || return - - local cd - cd="$( < <( _z_dirs ) awk -v t="$(date +%s)" -v list="$list" -v typ="$typ" -v q="$fnd" -F"|" ' - function frecent(rank, time) { - # relate frequency and time - dx = t - time - return int(10000 * rank * (3.75/((0.0001 * dx + 1) + 0.25))) - } - function output(matches, best_match, common) { - # list or return the desired directory - if( list ) { - if( common ) { - printf "%-10s %s\n", "common:", common > "/dev/stderr" - } - cmd = "sort -n >&2" - for( x in matches ) { - if( matches[x] ) { - printf "%-10s %s\n", matches[x], x | cmd - } - } - } else { - if( common && !typ ) best_match = common - print best_match - } - } - function common(matches) { - # find the common root of a list of matches, if it exists - for( x in matches ) { - if( matches[x] && (!short || length(x) < length(short)) ) { - short = x - } - } - if( short == "/" ) return - for( x in matches ) if( matches[x] && index(x, short) != 1 ) { - return - } - return short - } - BEGIN { - gsub(" ", ".*", q) - hi_rank = ihi_rank = -9999999999 - } - { - if( typ == "rank" ) { - rank = $2 - } else if( typ == "recent" ) { - rank = $3 - t - } else rank = frecent($2, $3) - if( $1 ~ q ) { - matches[$1] = rank - } else if( tolower($1) ~ tolower(q) ) imatches[$1] = rank - if( matches[$1] && matches[$1] > hi_rank ) { - best_match = $1 - hi_rank = matches[$1] - } else if( imatches[$1] && imatches[$1] > ihi_rank ) { - ibest_match = $1 - ihi_rank = imatches[$1] - } - } - END { - # prefer case sensitive - if( best_match ) { - output(matches, best_match, common(matches)) - exit - } else if( ibest_match ) { - output(imatches, ibest_match, common(imatches)) - exit - } - exit(1) - } - ')" - - if [ "$?" -eq 0 ]; then - if [ "$cd" ]; then - if [ "$echo" ]; then echo "$cd"; else builtin cd "$cd"; fi - fi - else - return $? - fi - fi -} - -alias ${_Z_CMD:-z}='_z 2>&1' - -[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P" - -if type complete >/dev/null 2>&1; then - # bash - # tab completion - complete -o filenames -C '_z --complete "$COMP_LINE"' ${_Z_CMD:-z} - [ "$_Z_NO_PROMPT_COMMAND" ] || { - # populate directory list. avoid clobbering other PROMPT_COMMANDs. - grep "_z --add" <<< "$PROMPT_COMMAND" >/dev/null || { - PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''(_z --add "$(command pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null &);' - } - } -fi
D bin/zatheme.sh

@@ -1,37 +0,0 @@

-#!/usr/bin/env bash - -# stolen from @nerdypepper - -echo 'set incremental-search true - -set recolor "true" - -set default-bg "'$( xres color0 )'" -set default-fg "'$( xres color7 )'" - -set completion-bg "'$( xres color0 )'" -set completion-fg "'$( xres color7 )'" -set completion-highlight-bg "'$( xres color4 )'" -set completion-highlight-fg "'$( xres color7 )'" - -set statusbar-bg "'$( xres color4 )'" -set statusbar-fg "'$( xres color0 )'" - -set inputbar-bg "'$( xres color0 )'" -set inputbar-fg "'$( xres color7 )'" - -set recolor-darkcolor "'$( xres color7 )'" -set recolor-lightcolor "'$( xres color0 )'" - -set window-height "800" -set window-width "600" - -set adjust-open "width" -set statusbar-home-tilde "true" -set statusbar-h-padding "50" -set statusbar-v-padding "50" - -set font "SF Mono 12" - -' > ~/.config/zathura/zathurarc -
D config/cmus/nerdz.theme

@@ -1,57 +0,0 @@

-# Directory colors -set color_win_dir=default - -# Normal text -set color_win_fg=242 - -# Window background color. -set color_win_bg=default - -# Command line color. -set color_cmdline_bg=default -set color_cmdline_fg=default - -# Color of error messages displayed on the command line. -set color_error=lightred - -# Color of informational messages displayed on the command line. -set color_info=lightyellow - -# Color of currently playing track. -set color_win_cur=6 - -# Color of the separator line between windows in view (1). -set color_separator=black - -# Color of window titles (topmost line of the screen). -set color_win_title_bg=default -set color_win_title_fg=black - -# Status line color. -set color_statusline_bg=default -set color_statusline_fg=default - -# Color of the line displaying currently playing track. -set color_titleline_bg=0 -set color_titleline_fg=6 - -# Color of the selected row which is also the currently playing track in active window. -set color_win_cur_sel_bg=250 -set color_win_cur_sel_fg=0 - -# Color of the selected row which is also the currently playing track in inactive window. -set color_win_inactive_cur_sel_bg=0 -set color_win_inactive_cur_sel_fg=6 - -# Color of selected row in inactive window. -set color_win_inactive_sel_bg=0 -set color_win_inactive_sel_fg=250 - -# Color of selected row in active window. -set color_win_sel_bg=253 -set color_win_sel_fg=gray - -# Command line color. -set color_cmdline_bg=default -set color_cmdline_fg=default -
D config/compton.conf

@@ -1,25 +0,0 @@

-backend = "glx"; -glx-no-stencil = true; -glx-copy-from-front = false; - -# rounded corners -# corner-radius = 5; - -shadow = true; -shadow-radius = 40; -shadow-opacity = 0.10; -shadow-offset-x = -20; -shadow-offset-y = -25; - -# corner-radius = 10; - - -shadow-exclude = [ - "window_type = 'dock'", - "window_type = 'desktop'", - "window_type = 'dnd'", - "window_type *= 'menu'", - "window_type = 'utility'", -] - -shadow-ignore-shaped = false;
D config/luakit/rc.lua

@@ -1,211 +0,0 @@

------------------------------------------------------------------------------- --- luakit configuration file, more information at https://luakit.github.io/ -- ------------------------------------------------------------------------------- - -require "lfs" - --- Check for lua configuration files that will never be loaded because they are --- shadowed by builtin modules. -table.insert(package.loaders, 2, function (modname) - if not package.searchpath then return end - local f = package.searchpath(modname, package.path) - if not f or f:find(luakit.install_paths.install_dir .. "/", 0, true) ~= 1 then - return - end - local lf = luakit.config_dir .. "/" .. modname:gsub("%.","/") .. ".lua" - if f == lf then - msg.warn("Loading local version of '" .. modname .. "' module: " .. lf) - elseif lfs.attributes(lf) then - msg.warn("Found local version " .. lf - .. " for core module '" .. modname - .. "', but it won't be used, unless you update 'package.path' accordingly.") - end -end) - -require "unique_instance" - --- Set the number of web processes to use. A value of 0 means 'no limit'. This --- has no effect since WebKit 2.26 -luakit.process_limit = 4 --- Set the cookie storage location -soup.cookies_storage = luakit.data_dir .. "/cookies.db" - --- Load library of useful functions for luakit -local lousy = require "lousy" - --- Load users theme --- ("$XDG_CONFIG_HOME/luakit/theme.lua" or "/etc/xdg/luakit/theme.lua") -lousy.theme.init(lousy.util.find_config("theme.lua")) -assert(lousy.theme.get(), "failed to load theme") - --- Load users window class --- ("$XDG_CONFIG_HOME/luakit/window.lua" or "/etc/xdg/luakit/window.lua") -local window = require "window" - --- Load users webview class --- ("$XDG_CONFIG_HOME/luakit/webview.lua" or "/etc/xdg/luakit/webview.lua") -local webview = require "webview" - --- Add luakit;//log/ chrome page -local log_chrome = require "log_chrome" - -window.add_signal("build", function (w) - local widgets, l, r = require "lousy.widget", w.sbar.l, w.sbar.r - - -- Left-aligned status bar widgets - l.layout:pack(widgets.uri()) - l.layout:pack(widgets.hist()) - l.layout:pack(widgets.progress()) - - -- Right-aligned status bar widgets - r.layout:pack(widgets.buf()) - r.layout:pack(log_chrome.widget()) - r.layout:pack(widgets.ssl()) - r.layout:pack(widgets.tabi()) - r.layout:pack(widgets.scroll()) -end) - --- Load luakit binds and modes -local modes = require "modes" -local binds = require "binds" - -local settings = require "settings" -require "settings_chrome" - ----------------------------------- --- Optional user script loading -- ----------------------------------- - --- Add adblock -local adblock = require "adblock" -local adblock_chrome = require "adblock_chrome" - -local webinspector = require "webinspector" - --- Add uzbl-like form filling -local formfiller = require "formfiller" - --- Add proxy support & manager -local proxy = require "proxy" - --- Add cache control (clear-data, clear-favicon-db) -local clear_data = require "clear_data" - --- Add quickmarks support & manager -local quickmarks = require "quickmarks" - --- Add session saving/loading support -local session = require "session" - --- Add command to list closed tabs & bind to open closed tabs -local undoclose = require "undoclose" - --- Add command to list tab history items -local tabhistory = require "tabhistory" - --- Add command to list open tabs -local tabmenu = require "tabmenu" - --- Add gopher protocol support (this module needs luasocket) --- local gopher = require "gopher" - --- Add greasemonkey-like javascript userscript support -local userscripts = require "userscripts" - --- Add bookmarks support -local bookmarks = require "bookmarks" -local bookmarks_chrome = require "bookmarks_chrome" - --- Add download support -local downloads = require "downloads" -local downloads_chrome = require "downloads_chrome" - --- Add automatic PDF downloading and opening -local viewpdf = require "viewpdf" - --- Example using xdg-open for opening downloads / showing download folders -downloads.add_signal("open-file", function (file) - luakit.spawn(string.format("xdg-open %q", file)) - return true -end) - --- Add vimperator-like link hinting & following -local follow = require "follow" - --- Add command history -local cmdhist = require "cmdhist" - --- Add search mode & binds -local search = require "search" - --- Add ordering of new tabs -local taborder = require "taborder" - --- Save web history -local history = require "history" -local history_chrome = require "history_chrome" - -local help_chrome = require "help_chrome" -local binds_chrome = require "binds_chrome" - --- Add command completion -local completion = require "completion" - --- Press Control-E while in insert mode to edit the contents of the currently --- focused <textarea> or <input> element, using `xdg-open` -local open_editor = require "open_editor" - --- NoScript plugin, toggle scripts and or plugins on a per-domain basis. --- `,ts` to toggle scripts, `,tp` to toggle plugins, `,tr` to reset. --- If you use this module, don't use any site-specific `enable_scripts` or --- `enable_plugins` settings, as these will conflict. ---require "noscript" - -local follow_selected = require "follow_selected" -local go_input = require "go_input" -local go_next_prev = require "go_next_prev" -local go_up = require "go_up" - --- Filter Referer HTTP header if page domain does not match Referer domain -require_web_module("referer_control_wm") - -local error_page = require "error_page" - --- Add userstyles loader -local styles = require "styles" - --- Add a stylesheet when showing images -local image_css = require "image_css" - --- Add a new tab page -local newtab_chrome = require "newtab_chrome" - --- Add tab favicons mod -local tab_favicons = require "tab_favicons" - --- Add :view-source command -local view_source = require "view_source" - --- Put "userconf.lua" in your Luakit config dir with your own tweaks; if this is --- permanent, no need to copy/paste/modify the default rc.lua whenever you --- update Luakit. -if pcall(function () lousy.util.find_config("userconf.lua") end) then - require "userconf" -end - ------------------------------ --- End user script loading -- ------------------------------ - --- Restore last saved session -local w = (not luakit.nounique) and (session and session.restore()) -if w then - for i, uri in ipairs(uris) do - w:new_tab(uri, { switch = i == 1 }) - end -else - -- Or open new window - window.new(uris) -end - --- vim: et:sw=4:ts=8:sts=4:tw=80
D config/luakit/theme.lua

@@ -1,108 +0,0 @@

--------------------------- --- Default luakit theme -- --------------------------- - -local fg = "#676767" -local bg = "#f4f4f4" -local green = "#7c9f4b" -local red = "#db7070" -local blue = "#6587BF" -local med_gray = "#aaa" - -local theme = {} - --- Default settings -theme.font = "16px Inter" -theme.fg = fg -theme.bg = bg - --- Genaral colours -theme.success_fg = "#0f0" -theme.loaded_fg = "#33AADD" -theme.error_fg = "#FFF" -theme.error_bg = "#F00" - --- Warning colours -theme.warning_fg = "#F00" -theme.warning_bg = "#FFF" - --- Notification colours -theme.notif_fg = "#444" -theme.notif_bg = "#FFF" - --- Menu colours -theme.menu_fg = fg -theme.menu_bg = bg -theme.menu_selected_fg = bg -theme.menu_selected_bg = fg -theme.menu_title_bg = bg -theme.menu_primary_title_fg = fg -theme.menu_secondary_title_fg = "#666" - -theme.menu_disabled_fg = "#999" -theme.menu_disabled_bg = theme.menu_bg -theme.menu_enabled_fg = theme.menu_fg -theme.menu_enabled_bg = theme.menu_bg -theme.menu_active_fg = "#060" -theme.menu_active_bg = theme.menu_bg - --- Proxy manager -theme.proxy_active_menu_fg = '#000' -theme.proxy_active_menu_bg = '#FFF' -theme.proxy_inactive_menu_fg = '#888' -theme.proxy_inactive_menu_bg = '#FFF' - --- Statusbar specific -theme.sbar_fg = fg -theme.sbar_bg = bg - --- Downloadbar specific -theme.dbar_fg = "#fff" -theme.dbar_bg = "#000" -theme.dbar_error_fg = "#F00" - --- Input bar specific -theme.ibar_fg = fg -theme.ibar_bg = bg - --- Tab label -theme.tab_fg = fg -theme.tab_bg = bg -theme.tab_hover_bg = med_gray -theme.tab_ntheme = "#ddd" -theme.selected_fg = bg -theme.selected_bg = fg -theme.selected_ntheme = "#ddd" -theme.loading_fg = blue -theme.loading_bg = "#000" - -theme.selected_private_tab_bg = "#3d295b" -theme.private_tab_bg = "#22254a" - --- Trusted/untrusted ssl colours -theme.trust_fg = green -theme.notrust_fg = red - --- Follow mode hints -theme.hint_font = "12px SF Mono, courier, sans-serif" -theme.hint_fg = "#fff" -theme.hint_bg = "#000088" -theme.hint_border = "1px dashed #000" -theme.hint_opacity = "0.3" -theme.hint_overlay_bg = "rgba(255,255,153,0.3)" -theme.hint_overlay_border = "1px dotted #000" -theme.hint_overlay_selected_bg = "rgba(0,255,0,0.3)" -theme.hint_overlay_selected_border = theme.hint_overlay_border - --- General colour pairings -theme.ok = { fg = fg, bg = bg } -theme.warn = { fg = "#F00", bg = "#FFF" } -theme.error = { fg = "#FFF", bg = "#F00" } - --- Gopher page style (override defaults) -theme.gopher_light = { bg = "#E8E8E8", fg = "#17181C", link = "#03678D" } -theme.gopher_dark = { bg = "#17181C", fg = "#E8E8E8", link = "#f90" } - -return theme - --- vim: et:sw=4:ts=8:sts=4:tw=80
D config/luakit/userconf.lua

@@ -1,39 +0,0 @@

-local vertical_tabs = require "vertical_tabs" -local editor = require "editor" -local modes = require "modes" -local settings = require "settings" - --- edit in nvim -editor.editor_cmd = "st -e nvim {file} +{line}" - --- ctrl+c to copy -modes.add_binds("normal", { - { "<Control-c>", "Copy selected text.", function () - luakit.selection.clipboard = luakit.selection.primary - end}, -}) - --- b to go back -modes.remap_binds("normal", { - { "b", "<shift-h>", true }, -}) - --- v to play in mpv -modes.add_binds("normal", { - { "v", "Play video in page", - function (w) - local view = w.view - local uri = view.hovered_uri or view.uri - if uri then - luakit.spawn(string.format("mpv --geometry=640x360 %s", uri )) - end - end }, -}) - --- default zoom for sites -local sites = { - "news.ycombinator.com", "lobste.rs", -} -for _, s in ipairs(sites) do - settings.on[s].webview.zoom_level = 120 -end
A config/nvim/_init.lua

@@ -0,0 +1,14 @@

+-- impatient.nvim +-- TODO: remove this once it's merged +require 'impatient' + +require('settings') +require('maps') +require('statusline.line') +require('treesitter') +require('fzy/fzy') + +-- lsp setup +require('lsp.config') +require('lsp.python') +require('lsp.go')
D config/nvim/init.lua

@@ -1,30 +0,0 @@

-require 'paq' { - 'savq/paq-nvim'; - 'lewis6991/impatient.nvim'; - 'tpope/vim-rsi'; - 'tpope/vim-surround'; - 'wellle/targets.vim'; - 'neovim/nvim-lspconfig'; - 'airblade/vim-gitgutter'; - 'lewis6991/impatient.nvim'; - 'nvim-treesitter/nvim-treesitter'; - 'nvim-treesitter/playground'; - { 'ms-jpq/coq_nvim', branch='coq' }; - { 'ms-jpq/coq.artifacts', branch='artifacts' }; - { 'vim/better-text-objs', url='https://git.peppe.rs' }; -} - --- impatient.nvim --- TODO: remove this once it's merged -require 'impatient' - -require('settings') -require('maps') -require('statusline.line') -require('treesitter') -require('fzy/fzy') - --- lsp setup -require('lsp.config') -require('lsp.python') -require('lsp.go')
M config/nvim/lua/settings.luaconfig/nvim/lua/settings.lua

@@ -103,7 +103,6 @@

-- disable built-in plugins local disabled_built_ins = { 'gzip', - 'man', 'shada_plugin', 'tarPlugin', 'tar',

@@ -112,6 +111,6 @@ 'zip',

'netrwPlugin', } -for i = 1, 8 do +for i = 1, 7 do g['loaded_' .. disabled_built_ins[i]] = 1 end
D config/sxhkd/sxhkdrc

@@ -1,11 +0,0 @@

-ctrl + shift + bracketright - scr -s - -XF86AudioPlay - cmus-remote -u - -XF86AudioNext - cmus-remote -n - -XF86AudioPrev - cmus-remote -r
D config/user-dirs.dirs

@@ -1,15 +0,0 @@

-# This file is written by xdg-user-dirs-update -# If you want to change or add directories, just edit the line you're -# interested in. All local changes will be retained on the next run -# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped -# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an -# absolute path. No other format is supported. -# -XDG_DESKTOP_DIR="$HOME/" -XDG_DOWNLOAD_DIR="$HOME/downloads" -XDG_TEMPLATES_DIR="$HOME" -XDG_PUBLICSHARE_DIR="$HOME" -XDG_DOCUMENTS_DIR="$HOME/docs" -XDG_MUSIC_DIR="$HOME/music" -XDG_PICTURES_DIR="$HOME/pics" -XDG_VIDEOS_DIR="$HOME/vids"
D config/zathura/zathurarc

@@ -1,32 +0,0 @@

-set incremental-search true - -set recolor "true" - -set default-bg "#f4f4f4" -set default-fg "#676767" - -set completion-bg "#f4f4f4" -set completion-fg "#676767" -set completion-highlight-bg "#6587bf" -set completion-highlight-fg "#676767" - -set statusbar-bg "#6587bf" -set statusbar-fg "#f4f4f4" - -set inputbar-bg "#f4f4f4" -set inputbar-fg "#676767" - -set recolor-darkcolor "#676767" -set recolor-lightcolor "#f4f4f4" - -set window-height "800" -set window-width "600" - -set adjust-open "width" -set statusbar-home-tilde "true" -set statusbar-h-padding "50" -set statusbar-v-padding "50" - -set font "SF Mono 12" - -
M home/.xmodmaphome/.xmodmap

@@ -52,9 +52,12 @@ keycode 59 = comma less dead_cedilla asciitilde

keycode 60 = period greater ellipsis asciitilde keycode 61 = slash question questiondown asciitilde -keycode 66 = Mode_switch +keycode 66 = Multi_key +keycode 66 = Mode_switch +keycode 64 = Alt_L keycode 94 = minus underscore endash emdash keycode 65 = space space space nobreakspace + clear Lock !clear Shift
A nix/bin/bar.nix

@@ -0,0 +1,26 @@

+{ pkgs, theme, ... }: + +let + name = "bar"; + pamixer = "${pkgs.pamixer}/bin/pamixer"; + lemonbar = "${pkgs.lemonbar-xft}/bin/lemonbar"; +in +pkgs.writeShellScriptBin name + '' + dt() { + date +"%a, %d %b" | tr A-Z a-z + } + + vol() { + ${pamixer} --get-volume + } + + pad="%{015}" + + while :; do + time="$(date +"%H:%M")" + echo "$pad $(dt) $pad $time %{r}bat $(bat) %{O14}vol $(vol)% $pad" + sleep 0.5 + done | ${lemonbar} -n bar -f 'Input:style=Regular:size=12:antialias=true' -g x30 \ + -F '${theme.base00}' -B '${theme.base07}' + ''
A nix/bin/battery.nix

@@ -0,0 +1,59 @@

+{ pkgs, ... }: + +let + name = "bat"; +in +pkgs.writeScriptBin name + '' + red="\e[31m" + grn="\e[32m" + ylw="\e[33m" + cyn="\e[36m" + blu="\e[34m" + prp="\e[35m" + bprp="\e[35;1m" + rst="\e[0m" + + bat_status="" + bat_status=$( cat /sys/class/power_supply/BAT0/capacity ) + charging_status=$( cat /sys/class/power_supply/BAT0/status ) + + health() { + for i in {0..4} + do + if [[ $i -le $(( $bat_status/20 )) ]]; then + echo -ne "#[fg=colour1]· " + else + echo -ne "#[fg=colour8]· " + fi + done + echo + } + + bat_status_small() { + if [[ "$charging_status" = *Charging* ]]; then + echo -ne "+$bat_status%" + else + echo -ne "$bat_status%" + fi + } + + [ -z "$1" ] && { + bat_status_small + } + + while getopts qi options + do + case $options in + i) + bat_status_small + ;; + q) + if [[ "$charging_status" = *Charging* ]]; then + echo -ne "+ $(health)" + else + health + fi + esac + done + ''
A nix/bin/default.nix

@@ -0,0 +1,51 @@

+{ pkgs, theme, ... }: + +let + + # open a window with live video feed from the camera + webcam = pkgs.writeScriptBin "webcam" '' + ${pkgs.mpv}/bin/mpv av://v4l2:/dev/video0 --profile=low-latency --untimed + ''; + + # create new repo on git.icyphox.sh + git-new-repo = pkgs.writeScriptBin "git-new-repo" '' + repo="$1" + [[ "$1" == "" ]] && repo="$(basename "$PWD")" + ssh git@jade git init --bare "$repo" + read -p "descripton: " desc + printf '%s' "$desc" > .git/description + rsync .git/description git@jade:"$repo" + ''; + + # adds a new push-only remote + git-new-push-remote = pkgs.writeScriptBin "git-new-push-remote" '' + [[ "$@" == "" ]] && { + printf '%s\n' "usage: git new-push-remote <remote url>" + exit + } + + old_push_remote="$(git remote -v | grep '(push)' | awk '{print $2}')" + git remote set-url "$(git remote show)" --add --push "$1" + git remote set-url "$(git remote show)" --add --push "$old_push_remote" + ''; + + # screen record with ffmpeg and slop + record = import ./record.nix pkgs; + + # bar + bar = import ./bar.nix { inherit pkgs theme; }; + + # file uploader + # uploader = import ./up.nix pkgs; + + # battery script + battery = import ./battery.nix pkgs; +in +[ + git-new-push-remote + git-new-repo + webcam + record + battery + bar +]
A nix/bin/pw.nix

@@ -0,0 +1,134 @@

+{ pkgs, theme, ... }: + +let + name = "pw"; + pamixer = "${pkgs.pamixer}/bin/pamixer"; + lemonbar = "${pkgs.lemonbar-xft}/bin/lemonbar"; +in +pkgs.writeShellScriptBin name + '' + #!/usr/bin/env bash + # pw - a mnml password manager + command -v gpg >/dev/null 2>&1 && gpg=gpg + command -v gpg2 >/dev/null 2>&1 && gpg=gpg2 + # check if xclip or pbcopy exist + # command -v xclip >/dev/null 2>&1 && copy="xclip -rmlastnl -selection clipboard" + # command -v pbcopy >/dev/null 2>&1 && copy="pbcopy | tr -d '\n'" + # export PW_DIR to your own path + [[ -z "$PW_DIR" ]] && PW_DIR="$HOME/.pw" + init() { + if [[ ! -e "$PW_DIR" ]]; then + mkdir -p "$PW_DIR" + printf "pw: password directory initialized at %s\n" "$PW_DIR" + else + printf "PW_DIR is %s\n" "$PW_DIR" + die "$PW_DIR exists" + fi + } + add() { + # $1: path to file + # $2 [optional]: password text + [[ -z "$PW_KEY" ]] && die "\$PW_KEY not set" + if [[ "$#" -eq 2 ]]; then + pass="$2" + else + # uses default length of 25 chars, unless PW_LEN is set + pass="$(pwgen "${PW_LEN:-25}" 1 -s)" + printf "pw: generated password for %s\n" "$1" + fi + if [[ ! -f "$PW_DIR/$1.gpg" ]]; then + printf "%s" "$pass" | "$gpg" -aer "$PW_KEY" -o "$PW_DIR/$1.gpg" + printf "pw: %s/%s.gpg created\n" "$PW_DIR" "$1" + else + die "the file $PW_DIR/$1.gpg exists" + fi + ( + cd $PW_DIR + git add . + git commit -m "$(date)" + remote="$(git remote show)" + branch="$(git branch --show-current)" + git pull -r "$remote" "$branch" + git push "$remote" "$branch" + ) + } + list() { + (cd "$PW_DIR"; find *.gpg | awk -F '.gpg' '{ print $1 }' ) + } + del() { + checkf "$PW_DIR/$1.gpg" + read -rn 1 -p "pw: are you sure you want to delete $1? [y/n]: " + printf "\n" + [[ "$REPLY" == [yY] ]] && { + rm -f "$PW_DIR/$1.gpg" + printf "pw: deleted %s" "$1" + } + } + show() { + checkf "$PW_DIR/$1.gpg" + "$gpg" --decrypt --quiet --use-agent "$PW_DIR/$1.gpg" + } + # TODO: rework having to checkf twice + copy() { + checkf "$PW_DIR/$1.gpg" + if [[ "$OSTYPE" =~ darwin* ]]; then + show "$1" | head -1 | pbcopy | tr -d '\n' + else + show "$1" | head -1 | xclip -rmlastnl -selection clipboard + fi + printf "pw: copied %s to clipboard\n" "$1" + } + usage() { + usage=" + pw - mnml password manager + usage: pw [options] [NAME] + All options except -i and -h require a NAME argument. + options: + -i Initializes password directory at \$HOME/.pw or at \$PW_DIR, if it exists. + -a Add a password. + -g Generate a password. + -s Print password to STDOUT. + -l List out all passwords. + -c Copy existing password to clipboard. + -d Delete password. + -h Display this help message and exit. + Requires PW_KEY to be set. Optionally, set PW_DIR for custom directory location. + Set PW_LEN to an integer of your choice, to override the default password length of 25. + " + printf "%s" "$usage" + exit 1 + } + checkf() { + [[ ! -f "$1" ]] && + die "$1 does not exist" + } + die() { + printf "error: %s\n" "$1" >&2 + exit 1 + } + main() { + [[ -z "$1" ]] && { + usage + } + while getopts "ila:g:s:c:d:h" options + do + # shellcheck disable=SC2221,SC2222 + case "$options" in + i) init ;; + l) list ;; + g) add "$OPTARG" ;; + a) + read -rsp "enter password: " pass + printf "\n" + add "$OPTARG" "$pass" + ;; + s) show "$OPTARG" ;; + c) copy "$OPTARG" ;; + d) del "$OPTARG" ;; + *|h) usage ;; + esac + done + shift $(( OPTIND -1 )) + } + main "$@" + ''
A nix/bin/record.nix

@@ -0,0 +1,33 @@

+{ pkgs, ... }: + +let + name = "record"; + slop = "${pkgs.slop}/bin/slop"; + ffmpeg = "${pkgs.ffmpeg}/bin/ffmpeg"; +in +pkgs.writeScriptBin name + '' + echo starting recording ... + coords=$(${slop} -f "%x %y %w %h %g %i") || exit 1 + read -r X Y W H G ID < <(echo $coords) + ${ffmpeg} \ + -f x11grab \ + -s "$W"x"$H" \ + -i :0.0+$X,$Y \ + -f alsa \ + -thread_queue_size 512 \ + -ac 2 \ + -ar 48000 \ + -i hw:0 \ + -framerate 60 \ + -vcodec libx264 \ + -threads 4 \ + -y \ + /home/np/tmp/x.mkv + + ${ffmpeg} \ + -i /home/np/tmp/x.mkv \ + -pix_fmt yuv420p \ + -vf scale=-2:1080 \ + "/home/np/vids/rec/$1" + ''
A nix/bin/up.nix

@@ -0,0 +1,24 @@

+{ pkgs, ... }: +let + name = "up"; + xclip = "${pkgs.xclip}/bin/xclip"; +in +pkgs.writeScriptBin name + '' + id=$( cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 3 | head -n 1 ) + + if [ $# != 1 ]; then + echo "needs an arg" + else + if [ -f "$1" ]; then + ext="''${1##*.}" + id="$id.$ext" + scp "$1" ferrn:~/www/nerd/uploads/"$id" + echo "https://u.peppe.rs/$id" + echo "https://u.peppe.rs/$id" | ${xclip} -selection clipboard + echo "https://u.peppe.rs/$id" | ${xclip} -i + else + echo "file does not exist" + fi + fi + ''
A nix/flake.lock

@@ -0,0 +1,236 @@

+{ + "nodes": { + "fenix": { + "inputs": { + "nixpkgs": [ + "prompt", + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1642141613, + "narHash": "sha256-WFS7T5oOLD8anu/77iz7EPz7zQsJZtP5qVa5485k3dI=", + "owner": "nix-community", + "repo": "fenix", + "rev": "d75ffc9f1d3b60bb597e48ae01f486a6de27d30e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1641205782, + "narHash": "sha256-4jY7RCWUoZ9cKD8co0/4tFARpWB+57+r1bLLvXNJliY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "b7547d3eed6f32d06102ead8991ec52ab0a4f1a7", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "prompt", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1635165013, + "narHash": "sha256-o/BdVjNwcB6jOmzZjOH703BesSkkS5O7ej3xhyO8hAY=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "5b9e0ff9d3b551234b4f3eb3983744fa354b17f1", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1647175256, + "narHash": "sha256-7H+veXPM7IwdN1DoZqliwb9sghlN56koV5dnCu1kpsc=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "a8d00f5c038cf7ec54e7dac9c57b171c1217f008", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-21.11", + "repo": "home-manager", + "type": "github" + } + }, + "neovim": { + "inputs": { + "flake-compat": "flake-compat", + "neovim-flake": "neovim-flake", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1647159229, + "narHash": "sha256-aGawpstqvThlV5OWqCAFIFBc8apYvMT/Qwig111coSo=", + "owner": "nix-community", + "repo": "neovim-nightly-overlay", + "rev": "4cf0e4a5738fb247f191a35c7c3900c4f06caca3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "neovim-nightly-overlay", + "type": "github" + } + }, + "neovim-flake": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "neovim", + "nixpkgs" + ] + }, + "locked": { + "dir": "contrib", + "lastModified": 1647152497, + "narHash": "sha256-KNqAdyM0DQPSqb/low6Py9eUBQjfga0KAHAF6naMd7Y=", + "owner": "neovim", + "repo": "neovim", + "rev": "c9b94188d5f96349566372e8a0ce94e14fd6b549", + "type": "github" + }, + "original": { + "dir": "contrib", + "owner": "neovim", + "repo": "neovim", + "type": "github" + } + }, + "nixos-hardware": { + "locked": { + "lastModified": 1646825982, + "narHash": "sha256-uWvS4UFkdE4Iqk1pXhxkZqPsqI+Z2V9VRmLxGUFejbY=", + "owner": "nixos", + "repo": "nixos-hardware", + "rev": "816a935bf5aa5f77cb1f03ebfe20ab13b112d0f1", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1646939531, + "narHash": "sha256-bxOjVqcsccCNm+jSmEh/bm0tqfE3SdjwS+p+FZja3ho=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "fcd48a5a0693f016a5c370460d0c2a8243b882dc", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1646939531, + "narHash": "sha256-bxOjVqcsccCNm+jSmEh/bm0tqfE3SdjwS+p+FZja3ho=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fcd48a5a0693f016a5c370460d0c2a8243b882dc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "prompt": { + "inputs": { + "fenix": "fenix", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "narHash": "sha256-smj6KAi1MdZxZ67Sxwc/uKop9bZmUaOhp8M6fafAg9Y=", + "path": "/home/icy/code/nerd-prompt", + "type": "path" + }, + "original": { + "path": "/home/icy/code/nerd-prompt", + "type": "path" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "neovim": "neovim", + "nixos-hardware": "nixos-hardware", + "nixpkgs": "nixpkgs_2", + "prompt": "prompt" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1642101527, + "narHash": "sha256-C4zcaWULWlrirpEt/pA85CCMBt+7SWZweMaMJ7EvrXw=", + "owner": "rust-analyzer", + "repo": "rust-analyzer", + "rev": "b4c31481a554d0132003228ba319bd9476fe85ae", + "type": "github" + }, + "original": { + "owner": "rust-analyzer", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +}
A nix/flake.nix

@@ -0,0 +1,62 @@

+{ + description = "icy's nixos config"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + nixos-hardware.url = "github:nixos/nixos-hardware"; + + home-manager = { + url = "github:nix-community/home-manager/release-21.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + neovim.url = "github:nix-community/neovim-nightly-overlay"; + + prompt = { + url = "path:/home/icy/code/nerd-prompt"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + }; + + outputs = + { self + , nixpkgs + , nixos-hardware + , home-manager + , neovim + , prompt + , ... + } @ inputs: { + + overlays = { + nvim-nightly = neovim.overlay; + prompt = prompt.overlay; + }; + + nixosConfigurations = { + lapis = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + { + imports = [ ./hosts/lapis/configuration.nix ]; + _module.args.self = self; + } + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.icy = { + imports = [ ./home.nix ]; + _module.args.self = self; + _module.args.inputs = inputs; + _module.args.theme = import ./theme.nix; + }; + } + ]; + }; + }; + }; + +}
A nix/home.nix

@@ -0,0 +1,73 @@

+{ config +, pkgs +, theme +, self +, ... +}: + +{ + + imports = [ + ./programs + ./services + ./x + ]; + + home.stateVersion = "21.05"; + home.username = "icy"; + home.homeDirectory = "/home/icy"; + home.extraOutputsToInstall = [ "man" ]; + home.packages = with pkgs; [ + + git + unzip + curl + tmux + weechat + firefox + xclip + ripgrep + arandr + imagemagick + ffmpeg + wget + tree + mpv + w3m + noto-fonts-emoji + jq + yq + sxiv + st + fzy + xorg.xmodmap + kubectl + slack + nixpkgs-fmt + libnotify + signal-desktop + + ] ++ (import ./bin { inherit pkgs theme; }); + + xdg = { + userDirs = { + enable = true; + desktop = "\$HOME/desktop"; + documents = "\$HOME/docs"; + download = "\$HOME/downloads"; + pictures = "\$HOME/pics"; + videos = "\$HOME/vids"; + }; + }; + + xsession = { + enable = true; + windowManager.command = "cwm"; + initExtra = '' + xrdb -load $HOME/.Xresources + xmodmap $HOME/.xmodmap + bar & + ''; + }; + +}
A nix/hosts/lapis/configuration.nix

@@ -0,0 +1,134 @@

+{ self, config, pkgs, theme, ... }: + +{ + imports = + [ + ./hardware-configuration.nix + ]; + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + boot.kernel.sysctl."net.ipv4.ip_forward" = 1; + + networking = { + nameservers = [ "1.1.1.1" "1.0.0.1" ]; + hostName = "lapis"; + useDHCP = false; + interfaces.wlan0.useDHCP = true; + wireless.iwd.enable = true; + }; + + i18n.defaultLocale = "en_US.UTF-8"; + time.timeZone = "Asia/Kolkata"; + + nixpkgs.config = { + allowUnfree = true; + st = { + conf = builtins.readFile ../../programs/st/config.h; + extraLibs = with pkgs; [ harfbuzz ]; + patches = [ + ../../patches/st/xres.diff + ../../patches/st/bright.diff + ../../patches/st/ligatures.diff + ]; + }; + }; + + nixpkgs.overlays = with self.overlays; [ + nvim-nightly + prompt + ]; + + environment.systemPackages = with pkgs; [ + cwm + man-pages + git + man-pages-posix + (lib.hiPrio pkgs.bashInteractive_5) + ]; + + documentation = { + dev.enable = true; + man.generateCaches = true; + }; + + users.motd = with config; '' + Host ${networking.hostName} + OS NixOS ${system.nixos.release} (${system.nixos.codeName}) + Version ${system.nixos.version} + Kernel ${boot.kernelPackages.kernel.version} + ''; + + console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + }; + + sound.enable = true; + hardware = { + pulseaudio.enable = true; + bluetooth = { + enable = true; + powerOnBoot = true; + }; + }; + + services = { + xserver = { + enable = true; + layout = "us"; + xkbVariant = "workman"; + displayManager.startx.enable = true; + libinput.enable = true; + }; + tailscale.enable = true; + }; + + virtualisation.docker = { + enable = true; + logDriver = "json-file"; + }; + + security = { + doas.enable = true; + sudo.enable = true; + doas.extraConfig = '' + permit nopass :wheel + ''; + doas.extraRules = [{ + users = [ "icy" ]; + }]; + }; + + + users.users.icy = { + isNormalUser = true; + extraGroups = [ "wheel" "docker" "audio" "video" ]; + }; + + nix = { + package = pkgs.nixUnstable; + extraOptions = '' + experimental-features = nix-command flakes ca-derivations + warn-dirty = false + keep-outputs = false + ''; + settings = { + trusted-users = [ + "root" + "icy" + ]; + }; + }; + + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "21.11"; # Did you read the comment? + +} +
A nix/hosts/lapis/hardware-configuration.nix

@@ -0,0 +1,34 @@

+# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" "alcor" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { + device = "/dev/disk/by-uuid/9b7ae4a9-de63-4972-95d1-d7e5cd63b558"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { + device = "/dev/disk/by-uuid/5780-2835"; + fsType = "vfat"; + }; + + swapDevices = + [{ device = "/dev/disk/by-uuid/1511c1d3-764f-471e-9468-db26bf752020"; }]; + + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +}
A nix/patches/st/bright.diff

@@ -0,0 +1,28 @@

+From e8f3c86d93613eef5af187dfd2dba9ae9919a2ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20Proust?= <code@bnwr.net> +Date: Sun, 27 Jan 2019 13:31:28 +0800 +Subject: [PATCH] Show bold not as bright + +--- + x.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/x.c b/x.c +index 0422421..904e1dc 100644 +--- a/x.c ++++ b/x.c +@@ -1296,10 +1296,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + bg = &dc.col[base.bg]; + } + +- /* Change basic system colors [0-7] to bright system colors [8-15] */ +- if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) +- fg = &dc.col[base.fg + 8]; +- + if (IS_SET(MODE_REVERSE)) { + if (fg == &dc.col[defaultfg]) { + fg = &dc.col[defaultbg]; +-- +2.20.1 + +
A nix/patches/st/ligatures.diff

@@ -0,0 +1,308 @@

+diff --git a/Makefile b/Makefile +index 470ac86..38240da 100644 +--- a/Makefile ++++ b/Makefile +@@ -4,7 +4,7 @@ + + include config.mk + +-SRC = st.c x.c ++SRC = st.c x.c hb.c + OBJ = $(SRC:.c=.o) + + all: options st +@@ -22,7 +22,8 @@ config.h: + $(CC) $(STCFLAGS) -c $< + + st.o: config.h st.h win.h +-x.o: arg.h config.h st.h win.h ++x.o: arg.h config.h st.h win.h hb.h ++hb.o: st.h + + $(OBJ): config.h config.mk + +diff --git a/config.mk b/config.mk +index beafc35..3df5c83 100644 +--- a/config.mk ++++ b/config.mk +@@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config + # includes and libs + INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ +- `$(PKG_CONFIG) --cflags freetype2` ++ `$(PKG_CONFIG) --cflags freetype2` \ ++ `$(PKG_CONFIG) --cflags harfbuzz` + LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ + `$(PKG_CONFIG) --libs fontconfig` \ +- `$(PKG_CONFIG) --libs freetype2` ++ `$(PKG_CONFIG) --libs freetype2` \ ++ `$(PKG_CONFIG) --libs harfbuzz` + + # flags + STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 +diff --git a/hb.c b/hb.c +new file mode 100644 +index 0000000..7df2828 +--- /dev/null ++++ b/hb.c +@@ -0,0 +1,136 @@ ++#include <stdlib.h> ++#include <stdio.h> ++#include <math.h> ++#include <X11/Xft/Xft.h> ++#include <hb.h> ++#include <hb-ft.h> ++ ++#include "st.h" ++ ++void hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length); ++hb_font_t *hbfindfont(XftFont *match); ++ ++typedef struct { ++ XftFont *match; ++ hb_font_t *font; ++} HbFontMatch; ++ ++static int hbfontslen = 0; ++static HbFontMatch *hbfontcache = NULL; ++ ++void ++hbunloadfonts() ++{ ++ for (int i = 0; i < hbfontslen; i++) { ++ hb_font_destroy(hbfontcache[i].font); ++ XftUnlockFace(hbfontcache[i].match); ++ } ++ ++ if (hbfontcache != NULL) { ++ free(hbfontcache); ++ hbfontcache = NULL; ++ } ++ hbfontslen = 0; ++} ++ ++hb_font_t * ++hbfindfont(XftFont *match) ++{ ++ for (int i = 0; i < hbfontslen; i++) { ++ if (hbfontcache[i].match == match) ++ return hbfontcache[i].font; ++ } ++ ++ /* Font not found in cache, caching it now. */ ++ hbfontcache = realloc(hbfontcache, sizeof(HbFontMatch) * (hbfontslen + 1)); ++ FT_Face face = XftLockFace(match); ++ hb_font_t *font = hb_ft_font_create(face, NULL); ++ if (font == NULL) ++ die("Failed to load Harfbuzz font."); ++ ++ hbfontcache[hbfontslen].match = match; ++ hbfontcache[hbfontslen].font = font; ++ hbfontslen += 1; ++ ++ return font; ++} ++ ++void ++hbtransform(XftGlyphFontSpec *specs, const Glyph *glyphs, size_t len, int x, int y) ++{ ++ int start = 0, length = 1, gstart = 0; ++ hb_codepoint_t *codepoints = calloc(len, sizeof(hb_codepoint_t)); ++ ++ for (int idx = 1, specidx = 1; idx < len; idx++) { ++ if (glyphs[idx].mode & ATTR_WDUMMY) { ++ length += 1; ++ continue; ++ } ++ ++ if (specs[specidx].font != specs[start].font || ATTRCMP(glyphs[gstart], glyphs[idx]) || selected(x + idx, y) != selected(x + gstart, y)) { ++ hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length); ++ ++ /* Reset the sequence. */ ++ length = 1; ++ start = specidx; ++ gstart = idx; ++ } else { ++ length += 1; ++ } ++ ++ specidx++; ++ } ++ ++ /* EOL. */ ++ hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length); ++ ++ /* Apply the transformation to glyph specs. */ ++ for (int i = 0, specidx = 0; i < len; i++) { ++ if (glyphs[i].mode & ATTR_WDUMMY) ++ continue; ++ ++ if (codepoints[i] != specs[specidx].glyph) ++ ((Glyph *)glyphs)[i].mode |= ATTR_LIGA; ++ ++ specs[specidx++].glyph = codepoints[i]; ++ } ++ ++ free(codepoints); ++} ++ ++void ++hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length) ++{ ++ hb_font_t *font = hbfindfont(xfont); ++ if (font == NULL) ++ return; ++ ++ Rune rune; ++ ushort mode = USHRT_MAX; ++ hb_buffer_t *buffer = hb_buffer_create(); ++ hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ ++ /* Fill buffer with codepoints. */ ++ for (int i = start; i < (start+length); i++) { ++ rune = string[i].u; ++ mode = string[i].mode; ++ if (mode & ATTR_WDUMMY) ++ rune = 0x0020; ++ hb_buffer_add_codepoints(buffer, &rune, 1, 0, 1); ++ } ++ ++ /* Shape the segment. */ ++ hb_shape(font, buffer, NULL, 0); ++ ++ /* Get new glyph info. */ ++ hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, NULL); ++ ++ /* Write new codepoints. */ ++ for (int i = 0; i < length; i++) { ++ hb_codepoint_t gid = info[i].codepoint; ++ codepoints[start+i] = gid; ++ } ++ ++ /* Cleanup. */ ++ hb_buffer_destroy(buffer); ++} +diff --git a/hb.h b/hb.h +new file mode 100644 +index 0000000..b3e02d0 +--- /dev/null ++++ b/hb.h +@@ -0,0 +1,7 @@ ++#include <X11/Xft/Xft.h> ++#include <hb.h> ++#include <hb-ft.h> ++ ++void hbunloadfonts(); ++void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int); ++ +diff --git a/st.c b/st.c +index 2bf133f..747f7b4 100644 +--- a/st.c ++++ b/st.c +@@ -2599,7 +2599,8 @@ draw(void) + + 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]); ++ term.ocx, term.ocy, term.line[term.ocy][term.ocx], ++ term.line[term.ocy], term.col); + term.ocx = cx; + term.ocy = term.c.y; + xfinishdraw(); +diff --git a/st.h b/st.h +index d978458..c9b279b 100644 +--- a/st.h ++++ b/st.h +@@ -11,7 +11,8 @@ + #define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) + #define DEFAULT(a, b) (a) = (a) ? (a) : (b) + #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) +-#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ ++#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) != ((b).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) || \ ++ (a).fg != (b).fg || \ + (a).bg != (b).bg) + #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ + (t1.tv_nsec-t2.tv_nsec)/1E6) +@@ -33,6 +34,7 @@ enum glyph_attribute { + ATTR_WRAP = 1 << 8, + ATTR_WIDE = 1 << 9, + ATTR_WDUMMY = 1 << 10, ++ ATTR_LIGA = 1 << 11, + ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, + }; + +diff --git a/win.h b/win.h +index a6ef1b9..bc0d180 100644 +--- a/win.h ++++ b/win.h +@@ -25,7 +25,7 @@ enum win_mode { + + void xbell(void); + void xclipcopy(void); +-void xdrawcursor(int, int, Glyph, int, int, Glyph); ++void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int); + void xdrawline(Line, int, int, int); + void xfinishdraw(void); + void xloadcols(void); +diff --git a/x.c b/x.c +index e5f1737..3334a83 100644 +--- a/x.c ++++ b/x.c +@@ -19,6 +19,7 @@ char *argv0; + #include "arg.h" + #include "st.h" + #include "win.h" ++#include "hb.h" + + /* types used in config.h */ + typedef struct { +@@ -1031,6 +1032,9 @@ xunloadfont(Font *f) + void + xunloadfonts(void) + { ++ /* Clear Harfbuzz font cache. */ ++ hbunloadfonts(); ++ + /* Free the loaded fonts in the font cache. */ + while (frclen > 0) + XftFontClose(xw.dpy, frc[--frclen].font); +@@ -1229,7 +1233,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x + mode = glyphs[i].mode; + + /* Skip dummy wide-character spacing. */ +- if (mode == ATTR_WDUMMY) ++ if (mode & ATTR_WDUMMY) + continue; + + /* Determine font for glyph if different from previous glyph. */ +@@ -1336,6 +1340,9 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x + numspecs++; + } + ++ /* Harfbuzz transformation for ligatures. */ ++ hbtransform(specs, glyphs, len, x, y); ++ + return numspecs; + } + +@@ -1485,14 +1492,17 @@ xdrawglyph(Glyph g, int x, int y) + } + + void +-xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) ++xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len) + { + Color drawcol; + + /* remove the old cursor */ + if (selected(ox, oy)) + og.mode ^= ATTR_REVERSE; +- xdrawglyph(og, ox, oy); ++ ++ /* Redraw the line where cursor was previously. ++ * It will restore the ligatures broken by the cursor. */ ++ xdrawline(line, 0, oy, len); + + if (IS_SET(MODE_HIDE)) + return; +
A nix/patches/st/xres.diff

@@ -0,0 +1,185 @@

+From 2752a599ee01305a435729bfacf43b1dde7cf0ef Mon Sep 17 00:00:00 2001 +From: Benji Encalada Mora <benji@encalada.dev> +Date: Thu, 4 Jun 2020 00:41:10 -0500 +Subject: [PATCH] fix: replace xfps and actionfps variables + +--- + config.def.h | 36 ++++++++++++++++++++++++ + x.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 110 insertions(+), 4 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 6f05dce..9b99782 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -168,6 +168,42 @@ static unsigned int defaultattr = 11; + */ + static uint forcemousemod = ShiftMask; + ++/* ++ * Xresources preferences to load at startup ++ */ ++ResourcePref resources[] = { ++ { "font", STRING, &font }, ++ { "color0", STRING, &colorname[0] }, ++ { "color1", STRING, &colorname[1] }, ++ { "color2", STRING, &colorname[2] }, ++ { "color3", STRING, &colorname[3] }, ++ { "color4", STRING, &colorname[4] }, ++ { "color5", STRING, &colorname[5] }, ++ { "color6", STRING, &colorname[6] }, ++ { "color7", STRING, &colorname[7] }, ++ { "color8", STRING, &colorname[8] }, ++ { "color9", STRING, &colorname[9] }, ++ { "color10", STRING, &colorname[10] }, ++ { "color11", STRING, &colorname[11] }, ++ { "color12", STRING, &colorname[12] }, ++ { "color13", STRING, &colorname[13] }, ++ { "color14", STRING, &colorname[14] }, ++ { "color15", STRING, &colorname[15] }, ++ { "background", STRING, &colorname[256] }, ++ { "foreground", STRING, &colorname[257] }, ++ { "cursorColor", STRING, &colorname[258] }, ++ { "termname", STRING, &termname }, ++ { "shell", STRING, &shell }, ++ { "minlatency", INTEGER, &minlatency }, ++ { "maxlatency", INTEGER, &maxlatency }, ++ { "blinktimeout", INTEGER, &blinktimeout }, ++ { "bellvolume", INTEGER, &bellvolume }, ++ { "tabspaces", INTEGER, &tabspaces }, ++ { "borderpx", INTEGER, &borderpx }, ++ { "cwscale", FLOAT, &cwscale }, ++ { "chscale", FLOAT, &chscale }, ++}; ++ + /* + * Internal mouse shortcuts. + * Beware that overloading Button1 will disable the selection. +diff --git a/x.c b/x.c +index 210f184..76f167f 100644 +--- a/x.c ++++ b/x.c +@@ -14,6 +14,7 @@ + #include <X11/keysym.h> + #include <X11/Xft/Xft.h> + #include <X11/XKBlib.h> ++#include <X11/Xresource.h> + + char *argv0; + #include "arg.h" +@@ -45,6 +46,19 @@ typedef struct { + signed char appcursor; /* application cursor */ + } Key; + ++/* Xresources preferences */ ++enum resource_type { ++ STRING = 0, ++ INTEGER = 1, ++ FLOAT = 2 ++}; ++ ++typedef struct { ++ char *name; ++ enum resource_type type; ++ void *dst; ++} ResourcePref; ++ + /* X modifiers */ + #define XK_ANY_MOD UINT_MAX + #define XK_NO_MOD 0 +@@ -828,8 +842,8 @@ xclear(int x1, int y1, int x2, int y2) + void + xhints(void) + { +- XClassHint class = {opt_name ? opt_name : termname, +- opt_class ? opt_class : termname}; ++ XClassHint class = {opt_name ? opt_name : "st", ++ opt_class ? opt_class : "St"}; + XWMHints wm = {.flags = InputHint, .input = 1}; + XSizeHints *sizeh; + +@@ -1104,8 +1118,6 @@ xinit(int cols, int rows) + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; + +- if (!(xw.dpy = XOpenDisplay(NULL))) +- die("can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); + xw.vis = XDefaultVisual(xw.dpy, xw.scr); + +@@ -1964,6 +1976,59 @@ run(void) + } + } + ++int ++resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) ++{ ++ char **sdst = dst; ++ int *idst = dst; ++ float *fdst = dst; ++ ++ char fullname[256]; ++ char fullclass[256]; ++ char *type; ++ XrmValue ret; ++ ++ snprintf(fullname, sizeof(fullname), "%s.%s", ++ opt_name ? opt_name : "st", name); ++ snprintf(fullclass, sizeof(fullclass), "%s.%s", ++ opt_class ? opt_class : "St", name); ++ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0'; ++ ++ XrmGetResource(db, fullname, fullclass, &type, &ret); ++ if (ret.addr == NULL || strncmp("String", type, 64)) ++ return 1; ++ ++ switch (rtype) { ++ case STRING: ++ *sdst = ret.addr; ++ break; ++ case INTEGER: ++ *idst = strtoul(ret.addr, NULL, 10); ++ break; ++ case FLOAT: ++ *fdst = strtof(ret.addr, NULL); ++ break; ++ } ++ return 0; ++} ++ ++void ++config_init(void) ++{ ++ char *resm; ++ XrmDatabase db; ++ ResourcePref *p; ++ ++ XrmInitialize(); ++ resm = XResourceManagerString(xw.dpy); ++ if (!resm) ++ return; ++ ++ db = XrmGetStringDatabase(resm); ++ for (p = resources; p < resources + LEN(resources); p++) ++ resource_load(db, p->name, p->type, p->dst); ++} ++ + void + usage(void) + { +@@ -2037,6 +2102,11 @@ run: + + setlocale(LC_CTYPE, ""); + XSetLocaleModifiers(""); ++ ++ if(!(xw.dpy = XOpenDisplay(NULL))) ++ die("Can't open display\n"); ++ ++ config_init(); + cols = MAX(cols, 1); + rows = MAX(rows, 1); + tnew(cols, rows); +-- +2.26.2 + +
A nix/programs/bash.nix

@@ -0,0 +1,73 @@

+{ config +, pkgs +, ... +}: + +{ + programs.bash = { + enable = true; + historyControl = [ "erasedups" ]; + historyFile = "\$HOME/.bash_history"; + historyFileSize = 40000; + historyIgnore = [ "ls" "exit" "kill" ]; + historySize = 40000; + + shellAliases = { + o = "xdg-open"; + gc = "git commit -v -S"; + gst = "git status --short"; + ga = "git add"; + gd = "git diff --minimal"; + gl = "git log --oneline --decorate --graph"; + k = "kubectl"; + n = "j"; + }; + + shellOptions = [ + "histappend" + "autocd" + "globstar" + "checkwinsize" + "cdspell" + "dirspell" + "expand_aliases" + "dotglob" + "gnu_errfmt" + "histreedit" + "nocasematch" + ]; + + sessionVariables = { + + TERM = "xterm-256color-italic"; + EDITOR = "nvim"; + MANPAGER = "nvim +Man!"; + BROWSER = "firefox"; + PW_DIR = "$HOME/.pw"; + PW_KEY = "x@icyphox.sh"; + PATH = "$PATH:$HOME/bin"; + + }; + + initExtra = '' + # Ctrl+W kills word + stty werase undef + + # fzy reverse search + __fzy_history() { + ch="$(fc -rl 1 | awk -F'\t' '{print $2}' | sort -u | fzy)" + : "''${ch#"''${ch%%[![:space:]]*}"}" + printf "$_" + } + + bind -x '"\C-r": READLINE_LINE=$(__fzy_history); READLINE_POINT="''${#READLINE_LINE}"' + + complete -cf doas + + for i in ~/.bashrc.d/[0-9]*; do + . "$i" + done + ''; + + }; +}
A nix/programs/chromium.nix

@@ -0,0 +1,17 @@

+{ config +, pkgs +, ... +}: + +{ + programs.chromium = { + enable = true; + extensions = [ + "cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin + "aapbdbdomjkkjkaonfhkkikfgjllcleb" # translate + "aghfnjkcakhmadgdomlmlhhaocbkloab" # just black + "pobhoodpcipjmedfenaigbeloiidbflp" # minimal twitter + "ennpfpdlaclocpomkiablnmbppdnlhoh" # rust search extension + ]; + }; +}
A nix/programs/default.nix

@@ -0,0 +1,42 @@

+{ config +, pkgs +, theme +, self +, ... +}: + +{ + + imports = [ + ./bash.nix + ./chromium.nix + ./git.nix + ./neovim.nix + ./readline.nix + ./tmux.nix + ./zathura.nix + ]; + + programs = { + # msmtp.enable = true; + home-manager.enable = true; + mbsync.enable = false; + direnv = { + enable = true; + enableBashIntegration = true; + nix-direnv = { + enable = true; + enableFlakes = true; + }; + }; + autojump = { + enable = true; + enableBashIntegration = true; + }; + nix-index = { + enable = true; + enableBashIntegration = true; + }; + gpg.enable = true; + }; +}
A nix/programs/git.nix

@@ -0,0 +1,24 @@

+{ config +, pkgs +, theme +, ... +}: + +with theme; +{ + programs.git = { + enable = true; + ignores = [ ".envrc" ]; + userEmail = "x@icyphox.sh"; + userName = "Anirudh Oppiliappan"; + signing = { + key = "8A93F96F78C5D4C4"; + signByDefault = true; + }; + extraConfig = { + commit.verbose = true; + init.defaultBranch = "master"; + pull.rebase = "true"; + }; + }; +}
A nix/programs/neovim.nix

@@ -0,0 +1,32 @@

+{ config +, pkgs +, self +, ... +}: + +{ + programs.neovim = { + enable = true; + withNodeJs = false; + vimAlias = true; + withPython3 = true; + extraPackages = with pkgs; [ + gotools + gopls + go + ]; + extraConfig = '' + runtime _init.lua + ''; + plugins = with pkgs.vimPlugins; [ + nvim-lspconfig + (nvim-treesitter.withPlugins (_: pkgs.tree-sitter.allGrammars)) + coq_nvim + playground + vim-surround + targets-vim + vim-gitgutter + vim-rsi + ]; + }; +}
A nix/programs/readline.nix

@@ -0,0 +1,22 @@

+{ config +, pkgs +, ... +}: + +{ + programs.readline = { + enable = true; + bindings = { + "\\t" = "menu-complete"; + "\\e[Z" = "menu-complete-backward"; + "\\C-w" = "backward-kill-word"; + }; + variables = { + "completion-ignore-case" = "on"; + "show-all-if-ambiguous" = "on"; + "colored-stats" = "on"; + "completion-display-width" = 4; + "enable-bracketed-paste" = "on"; + }; + }; +}
A nix/programs/st/config.h

@@ -0,0 +1,507 @@

+ +/* See LICENSE file for copyright and license details. */ + +/* + * appearance + * + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ +static char *font = "Input:size=12:antialias=true:autohint=true"; +static int borderpx = 30; + +/* + * 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 = "/run/current-system/sw/bin/bash"; +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 = 0.9; +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 = "xterm-256color-italic"; + +/* + * 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 = 4; + +/* 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", +}; + + +/* + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +unsigned int defaultfg = 7; +unsigned int defaultbg = 0; +unsigned int defaultcs = 256; +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; + +ResourcePref resources[] = { + { "font", STRING, &font }, + { "color0", STRING, &colorname[0] }, + { "color1", STRING, &colorname[1] }, + { "color2", STRING, &colorname[2] }, + { "color3", STRING, &colorname[3] }, + { "color4", STRING, &colorname[4] }, + { "color5", STRING, &colorname[5] }, + { "color6", STRING, &colorname[6] }, + { "color7", STRING, &colorname[7] }, + { "color8", STRING, &colorname[8] }, + { "color9", STRING, &colorname[9] }, + { "color10", STRING, &colorname[10] }, + { "color11", STRING, &colorname[11] }, + { "color12", STRING, &colorname[12] }, + { "color13", STRING, &colorname[13] }, + { "color14", STRING, &colorname[14] }, + { "color15", STRING, &colorname[15] }, + { "background", STRING, &colorname[0] }, + { "foreground", STRING, &colorname[7] }, + { "cursorColor", STRING, &colorname[7] }, + { "termname", STRING, &termname }, + { "shell", STRING, &shell }, + { "minlatency", INTEGER, &minlatency }, + { "maxlatency", INTEGER, &maxlatency }, + { "blinktimeout", INTEGER, &blinktimeout }, + { "bellvolume", INTEGER, &bellvolume }, + { "tabspaces", INTEGER, &tabspaces }, + { "borderpx", INTEGER, &borderpx }, + { "cwscale", FLOAT, &cwscale }, + { "chscale", FLOAT, &chscale }, +}; + +/* + * Internal mouse shortcuts. + * Beware that overloading Button1 will disable the selection. + */ +static MouseShortcut mshortcuts[] = { + /* mask button function argument release */ + { 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} }, +}; + +/* + * 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{|}~"; +
A nix/programs/tmux.nix

@@ -0,0 +1,96 @@

+{ config +, pkgs +, ... +}: + +{ + programs.tmux = { + enable = true; + plugins = with pkgs; [ + { + plugin = tmuxPlugins.resurrect; + extraConfig = "set -g @resurrect-strategy-nvim 'session'"; + } + ]; + extraConfig = '' + set -g prefix C-q + set -g set-titles on + set-option -g set-titles-string "#T" + unbind-key C-b + bind-key C-q send-prefix + set -g update-environment "KEYBOARD_LAYOUT" + + bind r source-file ~/.config/tmux/tmux.conf + + set-option -g default-terminal xterm-256color-italic + set -as terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[2 q' + set escape-time 20 + + set -g mouse on + + set -g base-index 1 + setw -g pane-base-index 1 + + # pane binds + bind -n M-n select-pane -D + bind -n M-e select-pane -U + bind -n M-y select-pane -L + bind -n M-o select-pane -R + bind -n M-Up resize-pane -U 5 + bind -n M-Down resize-pane -D 5 + bind -n M-Left resize-pane -L 5 + bind -n M-Right resize-pane -R 5 + + # window binds + bind -n C-M-y previous-window + bind -n C-M-o next-window + bind-key c split-window -h -c "#{pane_current_path}" + bind-key v new-window -c "#{pane_current_path}" + bind-key s choose-session + bind-key ) swap-window -t +2 + bind-key ( swap-window -t -1 + + unbind -T copy-mode MouseDragEnd1Pane + bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard" + bind-key -T copy-mode-vi v send-keys -X begin-selection + bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip -i -sel p -f | xclip -i -sel c " + bind-key -T copy-mode-vi r send-keys -X rectangle-toggle + bind P paste-buffer + + # pop-up pane to open urls + bind-key u display-popup -E "xurls" + + # statusline on top + set-option -g status-position top + + # statusline hide / unhide + bind -n C-down set -q status off + bind -n C-up set -q status on + bind P paste-buffer + + set-window-option -g allow-rename off + + set -g pane-border-style fg=colour11 + set -g pane-active-border-style fg=colour8 + + set -g status-justify right + set -g status-right "" + set -g status-left "" + set -g status-style "bg=colour0" + set -ag status-style "fg=colour7" + + set -g window-status-current-format "#[fg=colour15] #W" + set -g window-status-format "#[fg=colour8] #W" + + set -g status-left-length 100 + if-shell '[[ $HOSTNAME != methi ]]' { + set -ag status-left "#[fg=colour8]cwd #[fg=colour15]#(${pkgs.prompt}/bin/prompt cwd #{pane_current_path}) " + set -ag status-left "#[fg=colour8]#(${pkgs.prompt}/bin/prompt vcs #{pane_current_path}) " + } + + # dim inactive pane + set -g window-style 'fg=color8,bg=default' + set -g window-active-style 'fg=color7,bg=default' + ''; + }; +}
A nix/programs/zathura.nix

@@ -0,0 +1,37 @@

+{ config +, pkgs +, theme +, ... +}: + +with theme; +{ + programs.zathura = { + enable = true; + options = { + incremental-search = "true"; + recolor = "true"; + default-bg = base00; + default-fg = base05; + completion-bg = base00; + completion-fg = base05; + completion-highlight-bg = base0E; + completion-highlight-fg = base05; + statusbar-bg = base00; + statusbar-fg = base05; + inputbar-bg = base00; + inputbar-fg = base05; + recolor-darkcolor = base05; + recolor-lightcolor = base00; + window-height = "800"; + window-width = "600"; + adjust-open = "width"; + smooth-scroll = "true"; + statusbar-home-tilde = "true"; + statusbar-h-padding = "50"; + statusbar-v-padding = "50"; + guioptions = "s"; + font = "Input 10"; + }; + }; +}
A nix/services/default.nix

@@ -0,0 +1,26 @@

+{ config +, pkgs +, theme +, ... +}: + +{ + + imports = [ + ./dunst.nix + ./picom.nix + ./redshift.nix + ./sxhkd.nix + ./mbsync.nix + ]; + + services = { + gpg-agent = { + enable = true; + defaultCacheTtl = 60 * 60 * 24 * 7; + maxCacheTtl = 60 * 60 * 24 * 7; + pinentryFlavor = "curses"; + }; + }; + +}
A nix/services/dunst.nix

@@ -0,0 +1,65 @@

+{ config +, pkgs +, theme +, ... +}: + +with theme; +{ + services.dunst = { + enable = true; + settings = { + global = { + font = "Input 10"; + allow_markup = "no"; + format = ''%s\n%b''; + sort = "yes"; + indicate_hidden = "yes"; + alignment = "right"; + bounce_freq = "0"; + show_age_threshold = "60"; + word_wrap = "yes"; + ignore_newline = "no"; + geometry = "300x8-20+20"; + shrink = "yes"; + frame_width = 0; + transparency = "0"; + idle_threshold = "120"; + monitor = "0"; + follow = "mouse"; + sticky_history = "yes"; + history_length = "20"; + icon_folders = "/usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/"; + show_indicators = "yes"; + line_height = "0"; + separator_height = "0"; + padding = "20"; + horizontal_padding = "20"; + separator_color = "auto"; + startup_notification = "false"; + stack_duplicates = "true"; + mouse_left_click = "close_current"; + mouse_middle_click = "do_action, close_current"; + mouse_right_click = "close_all"; + }; + + urgency_normal = { + background = base01; + foreground = base05; + timeout = 10; + }; + + urgency_low = { + background = base01; + foreground = base05; + timeout = 2; + }; + + urgency_critical = { + background = base01; + foreground = base05; + timeout = 0; + }; + }; + }; +}
A nix/services/mbsync.nix

@@ -0,0 +1,11 @@

+{ config +, pkgs +, ... +}: + +{ + services.mbsync = { + enable = true; + frequency = "*:0/15"; + }; +}
A nix/services/picom.nix

@@ -0,0 +1,18 @@

+{ config +, pkgs +, ... +}: + +{ + services.picom = { + enable = true; + backend = "glx"; + fade = true; + fadeDelta = 5; + fadeSteps = [ "0.04" "0.04" ]; + inactiveDim = "0.0"; + shadow = false; + shadowOffsets = [ (-60) (-60) ]; + shadowOpacity = "0.20"; + }; +}
A nix/services/redshift.nix

@@ -0,0 +1,18 @@

+{ config +, pkgs +, ... +}: + +{ + services.redshift = { + enable = true; + temperature = { + day = 5000; + night = 4000; + }; + tray = false; + provider = "manual"; + latitude = "12"; + longitude = "77"; + }; +}
A nix/services/suspend.nix

@@ -0,0 +1,65 @@

+{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.batteryNotifier; +in +{ + options = { + services.batteryNotifier = { + enable = mkOption { + default = false; + description = '' + Whether to enable battery notifier. + ''; + }; + device = mkOption { + default = "BAT0"; + description = '' + Device to monitor. + ''; + }; + notifyCapacity = mkOption { + default = 10; + description = '' + Battery level at which a notification shall be sent. + ''; + }; + suspendCapacity = mkOption { + default = 5; + description = '' + Battery level at which a suspend unless connected shall be sent. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.user.timers."lowbatt" = { + description = "check battery level"; + timerConfig.OnBootSec = "5m"; + timerConfig.OnUnitInactiveSec = "5m"; + timerConfig.Unit = "lowbatt.service"; + wantedBy = [ "timers.target" ]; + }; + systemd.user.services."lowbatt" = { + description = "battery level notifier"; + serviceConfig.PassEnvironment = "DISPLAY"; + script = '' + export battery_capacity=$(${pkgs.coreutils}/bin/cat /sys/class/power_supply/${cfg.device}/capacity) + export battery_status=$(${pkgs.coreutils}/bin/cat /sys/class/power_supply/${cfg.device}/status) + if [[ $battery_capacity -le ${builtins.toString cfg.notifyCapacity} && $battery_status = "Discharging" ]]; then + ${pkgs.libnotify}/bin/notify-send --urgency=critical --hint=int:transient:1 --icon=battery_empty "Battery Low: $battery_capacity%" + fi + if [[ $battery_capacity -le ${builtins.toString cfg.suspendCapacity} && $battery_status = "Discharging" ]]; then + ${pkgs.libnotify}/bin/notify-send --urgency=critical --hint=int:transient:1 --icon=battery_empty "Battery Critically Low: $battery_capacity%" + sleep 60s + battery_status=$(${pkgs.coreutils}/bin/cat /sys/class/power_supply/${cfg.device}/status) + if [[ $battery_status = "Discharging" ]]; then + systemctl suspend + fi + fi + ''; + }; + }; +}
A nix/services/sxhkd.nix

@@ -0,0 +1,17 @@

+{ config +, pkgs +, theme +, ... +}: + +{ + services.sxhkd = { + enable = true; + keybindings = { + "XF86Audio{Lower,Raise}Volume" = "${pkgs.alsaUtils}/bin/amixer sset Master 2%{-,+}"; + "XF86AudioMute" = "${pkgs.alsaUtils}/bin/amixer sset Master toggle"; + "XF86MonBrightness{Down,Up}" = "${pkgs.light}/bin/light -{U,A} 50"; + "super + Escape" = "pkill -USR1 -x sxhkd"; + }; + }; +}
A nix/theme.nix

@@ -0,0 +1,39 @@

+let + day = { + base00 = "#f4f4f4"; + base01 = "#6d8b42"; + base02 = "#e7e7e7"; + base03 = "#aaaaaa"; + base04 = "#8a8a8a"; + base05 = "#676767"; + base06 = "#a262b5"; + base07 = "#252525"; + base08 = "#db7070"; + base09 = "#c66666"; + base0A = "#d69822"; + base0B = "#7c9f4b"; + base0C = "#509c93"; + base0D = "#6587bf"; + base0E = "#b870ce"; + base0F = "#43827b"; + }; + night = { + base00 = "#000000"; + base01 = "#303030"; + base02 = "#353535"; + base03 = "#4A4A4A"; + base04 = "#787878"; + base05 = "#EEFFFF"; + base06 = "#EEFFFF"; + base07 = "#FFFFFF"; + base08 = "#F07178"; + base09 = "#F78C6C"; + base0A = "#FDF200"; + base0B = "#13CA91"; + base0C = "#79ffe1"; + base0D = "#7898FB"; + base0E = "#ff3299"; + base0F = "#FF5370"; + }; +in +day
A nix/x/default.nix

@@ -0,0 +1,12 @@

+{ config +, pkgs +, theme +, ... +}: + +{ + imports = [ + ./xft.nix + ./xresources.nix + ]; +}
A nix/x/xft.nix

@@ -0,0 +1,16 @@

+{ config +, pkgs +, ... +}: + +{ + xresources.properties = { + "Xft.autohint" = 1; + "Xft.antialias" = 1; + "Xft.lcdfilter" = "lcddefault"; + "Xft.hintstyle" = "hintslight"; + "Xft.hinting" = true; + "Xft.rgba" = "rgb"; + "Xft.dpi" = 100; + }; +}
A nix/x/xresources.nix

@@ -0,0 +1,33 @@

+{ config +, pkgs +, theme +, ... +}: + +with theme; +{ + xresources.properties = { + "*foreground" = base05; + "*background" = base00; + "*cursorColor" = base05; + + "*color0" = base00; + "*color1" = base08; + "*color2" = base0B; + "*color3" = base0A; + "*color4" = base0D; + "*color5" = base0E; + "*color6" = base0C; + "*color7" = base05; + + "*color8" = base03; + "*color9" = base09; + "*color10" = base01; + "*color11" = base02; + "*color12" = base04; + "*color13" = base06; + "*color14" = base0F; + "*color15" = base07; + + }; +}
D prompt/git.go

@@ -1,54 +0,0 @@

-package main - -import ( - "os" - "path/filepath" - - git "github.com/libgit2/git2go/v33" -) - -// Recursively traverse up until we find .git -// and return the git repo path. -func getGitDir(cwd string) string { - for { - dirs, _ := os.ReadDir(cwd) - for _, d := range dirs { - if ".git" == d.Name() { - return cwd - } else if cwd == "/" { - return "" - } - } - cwd = filepath.Dir(cwd) - } -} - -// Returns the current git branch or current ref sha. -func getGitBranch(repo *git.Repository) string { - ref, _ := repo.Head() - // Quick hack to fix crash when ref is nil; - // i.e., new repo with no commits. - if ref == nil { - return "no commit" - } - if ref.IsBranch() { - name, _ := ref.Branch().Name() - return name - } else { - return ref.Target().String()[:8] - } -} - -// Returns • if clean, else ×. -func getGitStatus(repo *git.Repository, clean, dirty string) string { - sl, _ := repo.StatusList(&git.StatusOptions{ - Show: git.StatusShowIndexAndWorkdir, - Flags: git.StatusOptIncludeUntracked, - }) - n, _ := sl.EntryCount() - if n != 0 { - return dirty - } else { - return clean - } -}
D prompt/go.mod

@@ -1,9 +0,0 @@

-module git.icyphox.sh/dotfiles/prompt - -go 1.16 - -require ( - github.com/libgit2/git2go/v33 v33.0.4 - golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect - golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79 // indirect -)
D prompt/go.sum

@@ -1,22 +0,0 @@

-github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/libgit2/git2go/v33 v33.0.4 h1:37xovFBzibhDEdQRLbfWwx3a44JhOIY06UICn2teenc= -github.com/libgit2/git2go/v33 v33.0.4/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79 h1:RX8C8PRZc2hTIod4ds8ij+/4RQX3AqhYj3uOHmyaz4E= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
D prompt/prompt.go

@@ -1,58 +0,0 @@

-package main - -import ( - "fmt" - "os" - "strings" - - git "github.com/libgit2/git2go/v33" -) - -// Truncates the current working directory: -// /home/icy/foo/bar -> ~/f/bar -func trimPath(cwd, home string) string { - - var path string - if strings.HasPrefix(cwd, home) { - path = "~" + strings.TrimPrefix(cwd, home) - } else { - // If path doesn't contain $HOME, return the - // entire path as is. - path = cwd - return path - } - return path -} - -func main() { - if len(os.Args) != 3 { - os.Exit(1) - } - - gitDir := getGitDir(os.Args[2]) - switch os.Args[1] { - case "-p": - // current working directory - home := os.Getenv("HOME") - cwd := os.Args[2] - fmt.Print(trimPath(cwd, home)) - case "-gb": - branchCh := make(chan string) - if len(gitDir) > 0 { - repo, _ := git.OpenRepository(gitDir) - go getGitBranch(repo) - fmt.Print(<-branchCh) - } - fmt.Print("") - case "-gs": - statusCh := make(chan string) // git info - if len(gitDir) > 0 { - repo, _ := git.OpenRepository(gitDir) - go getGitStatus(repo, "•", "×") - fmt.Print(<-statusCh) - } - fmt.Print("") - default: - os.Exit(1) - } -}
M readmereadme

@@ -1,12 +1,10 @@

dotfiles -------- -Screenshot: https://x.icyphox.sh/7UVnt.png - -· OS: OpenBSD 7.0 +· OS: NixOS · WM: cwm · Shell: bash · Editor: nvim, with init.lua · IRC: weechat -· Email: s-nail -· Prompt: runs in tmux; see prompt/prompt.go and home/.tmux.conf + +For my old, pre-NixOS configs, look at the 'old' branch.