Dotfiles bankruptcy and rewrite! All hail, v2.0

This commit is contained in:
Henrik Lissner 2017-12-06 01:39:10 -05:00
parent d2da342f62
commit bd9e49aa09
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
640 changed files with 7650 additions and 6206 deletions

View file

@ -1,12 +0,0 @@
case $OSTYPE in
darwin*)
alias dkm='docker-machine'
alias dki='eval $(docker-machine env)'
;;
linux*)
alias docker='sudo docker'
;;
esac
alias dk='docker'
alias dkc='docker-compose'

View file

@ -1,12 +0,0 @@
#!/usr/bin/env bash
case $OSTYPE in
darwin*)
brew cask install virtualbox
brew install docker docker-compose docker-machine
;;
linux*)
if [[ -f /etc/arch-release ]]; then
sudo pacman --needed --noconfirm -S docker docker-compose
fi
esac

View file

@ -1,28 +0,0 @@
#!/usr/bin/env bash
# Pipes input to the weechat fifo (strips commented lines
# and prepends * to commands).
fifos=$(echo "$HOME/.weechat/weechat_fifo_*")
if [[ -z "$fifos" ]]; then
>&2 echo "No FIFOs. Is weechat running?"
exit 1
fi
rd() {
if [ -t 0 ]; then
cat $@
else
while read -r line; do
echo $line
done
fi | sed '/^ *\(#\|$\)/ d;s/^/*/g'
}
if [[ "$1" = "-d" ]]; then
shift
rd $@
else
rd $@ > $HOME/.weechat/weechat_fifo_*
fi

View file

@ -1,17 +0,0 @@
#!/usr/bin/env bash
case $OSTYPE in
darwin*)
brew install weechat
;;
linux*)
if [[ -d /etc/arch-release ]]; then
sudo pacman --needed --noconfirm -S weechat
elif [[ -d /etc/debian_version ]]; then
# TODO Untested
sudo apt-get install -y weechat
fi
esac
# NOTE: init.sh needs to be run separately, afterward
echo "Don't forget to run weechat/scripts/init.sh while weechat is open"

View file

@ -1,27 +0,0 @@
#!/usr/bin/env bash
if ! pgrep weechat >/dev/null; then
>&2 echo "Weechat isn't running, or fifo is off: /fifo enable"
exit 1
fi
if [[ -f ~/.private/config/irc.conf ]]; then
# ...otherwise, configure it!
CWD=$(cd $(dirname $0) && pwd -P)
wee "/secure passphrase $(pass irc/master)"
wee "/secure set username vnought"
wee "/secure set freenode $(pass irc/freenode.net | head -n1)"
wee "/secure set snoonet $(pass irc/snoonet.org | head -n1)"
wee "/secure set oftc $(pass irc/oftc.net | head -n1)"
wee "/secure set afternet $(pass irc/afternet.net | head -n1)"
wee "/secure set pushover_key $(pass api/pushover/key)"
wee "/secure set pushover_api $(pass api/pushover/api)"
wee "$CWD/../plugins.txt"
wee "$CWD/../settings.txt"
wee "$CWD/../servers.txt"
else
>&2 echo "Couldn't find secrets!"
exit 1
fi

12
.gitignore vendored
View file

@ -1,12 +0,0 @@
.enabled.d/*
*.log
*.pid
*.db
shell/+tmux/.tmux/plugins/
shell/+tmux/.tmuxifier/
shell/+mpd/.config/mpd/mpd.*
shell/+mpd/.config/mpd/mpdstate
+weechat/.weechat/*

105
README.md
View file

@ -1,69 +1,72 @@
[![MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat-square)](./LICENSE) # Mein dotfiles
# Henrik's dotfiles A tidy `$HOME` is a tidy mind.
<img src="http://i.giphy.com/ZHlGzvZb130nm.gif" align="right" /> ![Oct-2017 Screenshot of Arch Linux](assets/screenshots/OCT2017.png)
Fuel for my madness. Designed for Arch Linux, MacOS, and various remotes I My dotfiles are organized into 2-level topics (e.g. `shell/zsh`), and strive for
frequent. minimum `$HOME` presence (adhering to XDG standards as much as possible).
It is organized into topics, some with their own READMEs. Check them out for + Arch Linux
more targeted information. The `./bootstrap` script is used to deploy and update + wm: bspwm
them. + shell: zsh
+ font: kakwafont
+ bar: polybar
## Bootstrap ## Quick start
`bootstrap` is my idempotent dotfile deployment script. `bash <(curl -s https://raw.githubusercontent.com/hlissner/dotfiles/master/bootstrap.sh)`
e.g. `./bootstrap os/+arch shell/+{zsh,tmux} dev/+pyenv` ## Overview
``` ```sh
Usage: bootstrap [-iuldypLSU] [topic1[ topic2[ ...]]] # general
bin/ # global scripts
assets/ # wallpapers, sounds, screenshots, etc
Options: # categories
-i Don't run install scripts base/ # provisions my system with the bare essentials
-u Don't run update scripts dev/ # relevant to software development & programming in general
-l Don't symlink dotfiles editor/ # configuration for my text editors
-d Do a dry run (only output commands, no changes) misc/ # for various apps & tools
-y Overwrite conflicts (no prompts) shell/ # shell utilities, including zsh + bash
-p Prompt on file conflict (to overwrite)
-L Refresh links; the same as -ui
-S Server mode; only install the bare minimum
-U Update mode; run update scripts only
``` ```
Here's a simplified break down of what it does: ## Dotfile management
```bash ```
# 1. Symlinks dotfiles to $HOME Usage: deploy [-acdlLit] [TOPIC...]
ln -sfv $topic/.* ~/
ln -sfv $topic/.{config,local}/* ~/.{config,local}/
# 2. Track enabled topics in ~/.dotfiles/.enabled.d. -a Target all enabled topics (ignores TOPIC args)
if [[ -e ~/.dotfiles/.enabled.d/$topic ]]; then -c Afterwards, remove dead symlinks & empty dot-directories in $HOME.
# 3a. If topic is already enabled, run update script Can be used alone.
$topic/update -d Unlink and run `./_init clean` for topic(s)
-l Only relink topic(s) (implies -i)
-L List enabled topics
-i Inhibit install/update/clean init scripts
-t Do a test run; do not actually do anything
```
e.g.
+ `deploy base/arch shell/{zsh,tmux}`: enables base/arch, shell/zsh, & shell/tmux
+ `deploy -d shell/zsh`: disables shell/zsh & cleans up after it
+ `deploy -l shell/zsh`: refresh links for shell/zsh (inhibits init script)
Here's a breakdown of what the script does:
``` sh
cd $topic
if [[ -L $DOTFILES_DATA/${topic//\//.}.topic ]]; then
./_init update
else else
# 3b. Otherwise, run install script ln -sfv $DOTFILES/$topic $DOTFILES_DATA/${topic//\//.}.topic
ln -sfv $topic ~/.dotfiles/.enabled.d/
$topic/install ./_init install
./_init link
fi fi
``` ```
## Clean ## Relevant projects
`clean` deletes broken symlinks in `$HOME`. If passed `-u`, it will remove all + [doom-emacs](https://github.com/hlissner/doom-emacs) (pulled by `editor/emacs`)
symlinks in `.enabled.d/`, marking all topics as "disabled". + [.vim](https://github.com/hlissner/.vim) (pulled by `editor/{neo,}vim`)
```
Usage: clean [-du]
Options:
-d Do a dry run (only output commands, no changes)
-u Uninstall all enabled topics
```
## Other Relevant Configs
+ [Vim](https://github.com/hlissner/.vim) (pulled in by the `editor/vim` topic)
+ [Emacs](https://github.com/hlissner/.emacs.d) (pulled in by the `editor/emacs` topic)

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 KiB

BIN
assets/sounds/ding.ogg Normal file

Binary file not shown.

BIN
assets/sounds/startup.ogg Normal file

Binary file not shown.

BIN
assets/sounds/updates.ogg Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 KiB

111
base/arch/Xresources Normal file
View file

@ -0,0 +1,111 @@
!! OCT-2017
!! Colors
#define blk #141517
#define bblk #969896
#define red #cc6666
#define bred #de935f
#define grn #b5bd68
#define bgrn #757d28
#define ylw #f0c674
#define bylw #f9a03f
#define blu #81a2be
#define bblu #2a8fed
#define mag #b294bb
#define bmag #bc77a8
#define cyn #8abeb7
#define bcyn #a3685a
#define wht #c5c8c6
#define bwht #ffffff
#define bg blk
#define fg wht
*.foreground: fg
*.background: bg
*.cursorColor: mag
*.color0: blk
*.color8: bblk
*.color1: red
*.color9: bred
*.color2: grn
*.color10: bgrn
*.color3: ylw
*.color11: bylw
*.color4: blu
*.color12: bblu
*.color5: mag
*.color13: bmag
*.color6: cyn
*.color14: bcyn
*.color7: wht
*.color15: bwht
! greys
*.color234: #1d2021
*.color235: #282828
*.color236: #32302f
*.color237: #3c3836
*.color239: #504945
*.color240: #544c49
*.color241: #665c54
!! Settings
! font rendering
Xft.hinting: 0
Xft.antialias: 1
Xft.autohint: 1
Xft.hintstyle: hintslight
Xft.lcdfilter: lcddefault
Xft.rgba: rgb
! cursor
Xcursor.theme: default
Xcursor.size: 32
! emacs
Emacs.toolBar: 0
Emacs.menuBar: 0
Emacs.verticalScrollBars: off
! urxvt
URxvt*.background: [96]blk
URxvt*.termName: xterm-256color
URxvt*.geometry: 81x20
URxvt*.buffered: true
URxvt*.cursorBlink: true
URxvt*.underlineColor: grey
URxvt*.depth: 32
URxvt*.borderless: 1
URxvt*.lineSpace: 1
URxvt*.letterSpace: 0
URxvt.iso14755: false
URxvt.iso14755_52: false
URxvt*.internalBorder: 14
URxvt*.scrollBar: false
URxvt*.saveLines: 5000
URxvt*.loginShell: false
URxvt.perl-ext-common: default,matcher
URxvt*.matcher.button: 1
URxvt*.matcher.rend.0: Uline Bold fg5
URxvt*.url-launcher: firefox
!URxvt.keysym.Shift-Control-C: perl:clipboard:copy
!URxvt.keysym.Shift-Control-V: perl:clipboard:paste
URxvt.clipboard.autocopy: true
URxvt*.font: xft:kakwa kakwafont:pixelsize=12
urxvt-scratch.font: xft:Misc Tamsyn:pixelsize=16
urxvt-fuzzy.font: xft:Misc Tamsyn:pixelsize=18
urxvt-fuzzy.boldFont: xft:Misc Tamsyn:pixelsize=18
urxvt-fuzzy.lineSpace: 4
urxvt-stream.lineSpace: 0
urxvt-stream.letterSpace: -1
urxvt-stream.font: xft:Fira Mono:pixelsize=17
! URxvt*.lineSpace: 0
! URxvt*.letterSpace: -1
! URxvt*.font: xft:Fira Mono:pixelsize=14
! urxvt-scratch.font: xft:Fira Mono:pixelsize=18
! urxvt-fuzzy.font: xft:Fira Mono:pixelsize=20

84
base/arch/_init Executable file
View file

@ -0,0 +1,84 @@
#!/usr/bin/env zsh
source ${0:A:h}/../../deploy
install() {
if ! nc -z 8.8.8.8 53 >/dev/null 2>&1; then
>&2 echo "No internet connection"
return 1
elif ! sudo pacman -Syu --noconfirm; then
>&2 echo "Could not update pacman"
return 2
fi
# Core essentials
sudo pacman --needed --noconfirm -S wget git curl tree rsync dnsutils
# Set up pacaur (AUR helper)
if ! _is_callable pacaur; then
TEMP="$(mktemp -d)"
pushd $TEMP
for pkg in cower pacaur; do
if [[ ! "$(pacman -Qs $pkg)" ]]; then
curl -o PKGBUILD https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=$pkg && \
makepkg PKGBUILD --needed --noconfirm --skippgpcheck -sri
fi
done
popd
rm -rf $TEMP
if ! _is_callable pacaur; then
>&2 echo "Pacaur was not successfully installed"
return 3
fi
fi
pacaur --needed --noconfirm --noedit -S \
wget curl ripgrep the_silver_searcher bc cronie youtube-dl \
xorg-server xorg-xinit xorg-xlsfonts xorg-xfd xdotool \
lightdm lightdm-mini-greeter \
bspwm sxhkd compton dunst xcb-proto polybar libnotify \
rvxt-unicode rvxt-unicode-terminfo \
slop feh maim ffmpeg zbar \
keybase-bin pass pass-otp \
neofetch glances inxi dfc \
ttf-fira-{mono,sans} ttf-font-awesome tamsym-font siji-git \
adwaita-icon-theme adwaita-slim-gtk-theme
# install crontab
sudo systemctl enable cronie
crontab ./crontab
# raise inotify limit
sudo tee -a /etc/sysctl.d/99-sysctl.conf <<<"fs.inotify.max_user_watches=524288"
# set up lightdm + minigreeter
sudo systemctl enable lightdm
sudo sed -i \
-e "s@^#?\(greeter-session=\).+@\1lightdm-mini-greeter@" \
-e "s@^#?\(user-session=\).+@\1bspwm@" \
/etc/lightdm/lightdm.conf
sudo sed -i \
-e "s@^\(user = \).+@\1${USER}@" \
-e "s@^\(show-password-label = \).+@\1false@" \
-e "s@^\(background-color = \).+@\1\"#000000\"@;" \
/etc/lightdm/lightdm-mini-greeter.conf
}
update() {
_is_callable pacaur && local pac=pacaur
${pac:-sudo pacman} -Syu --noconfirm
}
link() {
mklink xprofile ~/.xprofile
mklink config/* $XDG_CONFIG_HOME/
mklink fonts/* $XDG_DATA_HOME/fonts/
mklink -s pacman/*.hook /etc/pacman.d/hooks/
}
clean() {
rm -fv $XDG_DATA_HOME/fonts/*(@N)
sudo rm -fv /etc/pacman.d/hooks/*(@N)
}
init "$@"

22
base/arch/aliases.zsh Normal file
View file

@ -0,0 +1,22 @@
alias ls="${aliases[ls]:-ls} --color=auto --group-directories-first"
alias kb=keybase
alias sc=systemctl
alias ssc='sudo systemctl'
alias pac=pacaur
alias pacu='pacaur -Syu' # upgrade
alias pacc='pacaur -Sc' # clean pacman
alias paco='pacaur -Qtdq' # orphaned packages
alias reboot='sudo systemctl reboot'
alias shutdown='sudo systemctl poweroff'
# Clipboard pipes
if _is_callable xclip; then
alias y='xclip -selection clipboard -in'
alias p='xclip -selection clipboard -out'
elif _is_callable xsel; then
alias y='xsel -i --clipboard'
alias p='xsel -o --clipboard'
fi

37
base/arch/bin/bspc-focus Executable file
View file

@ -0,0 +1,37 @@
#!/usr/bin/env bash
# bspc-focus
# Jump to the next window in a direction. If -m is supplied, jump to the next
# monitor in that direction.
#
# Makes switching nodes more intuitive.
#
# Usage: bspc-focus [-m] (west|south|north|east)
# Example:
# + bspc-focus south
# + bspc-focus -m west
set -e
leap=
if [[ $1 == -m ]]; then
leap=1; shift
fi
dir=$1
case $dir in west|south|north|east) ;;
*) >&2 echo "Not a valid direction: $dir"
exit 1
esac
if [[ $leap ]]; then
# jump to monitor in direction
bspc monitor -f "$dir"
else
# jump to window in direction (unless at edge of last monitor)
if ! bspc node -f "$dir.local"; then
if [[ $(bspc query -M -m "$dir") ]]; then
bspc monitor -f "$dir"
fi
fi
fi

45
base/arch/bin/bspc-swap Executable file
View file

@ -0,0 +1,45 @@
#!/usr/bin/env bash
# bspc-swap
# swaps current window with the next window in a direction. If -m is set, moves
# window to the next monitor in that direction.
#
# Makes swapping nodes more intuitive.
#
# Usage: bspc-swap (west|south|north|east) (1|0)
# Example:
# + bspc-swap south
# + bspc-swap -m west
set -e
leap=
if [[ $1 == -m ]]; then
leap=1
dir=$2
else
dir=$1
fi
case $dir in west|south|north|east) ;;
*) >&2 echo "Not a valid direction: $dir"
exit 1
esac
if [[ $leap ]]; then
# move window to monitor in direction
old_id=$(bspc query -N -n focused)
if [[ $(bspc query -M -m "$dir") ]]; then
bspc node -m "$dir"
bspc node -f "$old_id"
fi
else
# move window in direction
old_id=$(bspc query -N -n focused)
if bspc node -s "$dir.local"; then
bspc node -f "$old_id"
elif [[ $(bspc query -M -m "$dir") ]]; then
bspc node -m "$dir"
bspc node -f "$old_id"
fi
fi

3
base/arch/bin/firefox Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
# A shim to make firefox believe HOME is elsewhere
HOME="$XDG_DATA_HOME/mozilla" exec /usr/bin/firefox "$@"

View file

@ -0,0 +1,2 @@
#!/usr/bin/env bash
DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus /usr/bin/notify-send "$@"

12
base/arch/bin/inject-xcolors Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
xcolor() {
xrdb -query | awk "/^\*\.$1:/ {print \$2}" | sed -E 's/^[^#]+//'
}
COLOR_FG=$(xcolor foreground)
COLOR_BG=$(xcolor background)
for ((i=0;i<=15;i++)); do
eval "COLOR_$i=\$(xcolor color$i)"
done

View file

@ -1,5 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# A script run by devmon/udevil when a device is mounted or unmounted, notifying me. # A script run by devmon/udevil when a device is mounted or unmounted, notifying me.
DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send -a "devmon" "Device change" "$2" DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send -a "devmon" "Device change" "$2"

View file

@ -7,4 +7,8 @@ dest=${1:-$(mktemp -t recXXX.webm)}
ffmpeg -f x11grab -s "$W"x"$H" -i :0.0+$X,$Y "$dest" ffmpeg -f x11grab -s "$W"x"$H" -i :0.0+$X,$Y "$dest"
# vim:set ft=sh: if [[ -f $dest ]]; then
mv $dest .
fi
# vim:set ft=sh shiftwidth=2:

22
base/arch/bin/rsl Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Run resilio (bittorrent sync) from $HOME if it isn't running. Otherwise, open
# its gui in the browser.
if command -v xdg-open >/dev/null; then
open=xdg-open
elif command -v open >/dev/null; then
open=open
elif [[ $BROWSER ]]; then
open=firefox
else
>&2 echo "No program to open urls with"
fi
if ! pgrep rslsync >/dev/null; then
pushd $HOME >/dev/null
rslsync &
popd >/dev/null
fi
[[ -t 0 ]] && $open http://localhost:8888/gui/

View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
xdotool search --onlyvisible --classname urxvt-fuzzy windowkill
xdotool search --classname urxvt-fuzzy windowmap \
|| urxvt -name urxvt-fuzzy -geometry 100x16 -e $SHELL -c fzf-apps

View file

@ -0,0 +1,29 @@
#!/usr/bin/env zsh
#
# Opens fzf-pass in a transient popup window and temporary tmux session,
# recreating this window if necessary.
#
# Get firefox's current url; requires "Hostname in title" plugin for firefox
win=$(xdotool getactivewindow)
if [[ $win ]]; then
winname=$(xdotool getwindowname $win)
if [[ $winname =~ " - Mozilla Firefox$" ]]; then
url=${winname% - Mozilla*}
url=${url##* - }
while (( ${#url//[^.]/} > 1 )); do
url=${url#*.}
done
fi
fi
# Present the popup
xdotool search --onlyvisible --classname urxvt-fuzzy windowkill
bspc monitor -f primary
urxvt -name urxvt-fuzzy \
-geometry 100x16 \
-e $SHELL \
-c "fzf-pass $@ $url"
[[ $win ]] && xdotool windowactivate $win

View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
SCRID=urxvt-scratch
focused=$(xdotool getactivewindow)
scratch=$(xdotool search --onlyvisible --classname $SCRID)
if [[ $scratch ]]; then
if [[ $focused == $scratch ]]; then
tmux kill-session -t scratch
else
xdotool windowactivate $scratch
fi
else
bspc monitor -f primary
urxvt -name $SCRID \
-geometry 100x26 \
-e bash \
-c 'tmux new-session -A -s scratch -n scratch'
fi

25
base/arch/bin/vol Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env bash
if (($# == 0)); then
data=$(amixer get Master)
vol=$(echo "$data" | sed -n 's/^.*\[\([0-9]\+\)%.*$/\1/p' | uniq)
state=$(echo "$data" | grep '\[on\]')
[[ $state ]] && echo $vol || echo 0
exit
fi
case $1 in
[0-9]*) amixer set Master $1 ;;
[+-]) amixer set Master 5%$1 ;;
*mute) amixer set Master $1 ;;
toggle) amixer set Master toggle ;;
*) >&2 echo "Invalid command"
exit 1
;;
esac
# community/xosd
if command -v osd_cat >/dev/null; then
killall -9 -q osd_cat &>/dev/null
osd_cat --font="10x20" --delay=2 --color=white --align=center --pos=bottom --barmode=percentage --percentage $($0) &
fi

View file

@ -0,0 +1,8 @@
#!/usr/bin/env zsh
export MONITOR=$(xrandr -q | grep 'primary' | cut -d' ' -f1)
bspc config -m $MONITOR window_gap 4
bspc config -m $MONITOR bottom_padding 158
bspc config -m $MONITOR top_padding 0
bspc config -m $MONITOR left_padding 0
bspc config -m $MONITOR right_padding 0

View file

@ -1,18 +1,27 @@
#!/usr/bin/bash #!/usr/bin/env zsh
# #
# Appearance # Displays
# #
declare -A COLOR export MONITOR=$(xrandr -q | grep 'primary' | cut -d' ' -f1)
END=15 export MONITORS=( $(xrandr -q | grep ' connected' | cut -d' ' -f1) )
for ((i=0;i<=END;i++)); do MONITOR=${MONITOR:-${MONITORS[0]}}
COLOR[$i]=$(xrdb -query | awk "/^\*\.color$i:/ {print \$2}") # Multiple workspaces for main monitor, but only one for others
bspc monitor $MONITOR -d {1,2,3,4,5}
for mon in ${MONITORS[@]/${MONITOR}}; do
bspc monitor $mon -d $mon/1
done done
bspc config normal_border_color "${COLOR[0]}" if ! pgrep polybar >/dev/null; then
bspc config active_border_color "${COLOR[0]}" $XDG_CONFIG_HOME/polybar/run.sh
bspc config focused_border_color "${COLOR[4]}" fi
#
# Aesthetics
#
bspc config split_ratio 0.50 bspc config split_ratio 0.50
bspc config gapless_monocle true bspc config gapless_monocle true
@ -28,57 +37,33 @@ bspc config pointer_action3 resize_corner
bspc config remove_disabled_monitors false bspc config remove_disabled_monitors false
bspc config remove_unplugged_monitors true bspc config remove_unplugged_monitors true
# bspc config normal_border_color "$COLOR_0"
# bspc config active_border_color "$COLOR_0"
# bspc config focused_border_color "$COLOR_0"
bspc config border_width 0 bspc config border_width 0
# bspc config window_gap 16 bspc config window_gap 8
# bspc config top_padding 32
# bspc config bottom_padding 34
# bspc config left_padding 32
# bspc config right_padding 32
bspc config window_gap 1
bspc config top_padding 0 bspc config top_padding 0
bspc config bottom_padding 0 bspc config bottom_padding 0
bspc config left_padding 0 bspc config left_padding 0
bspc config right_padding 0 bspc config right_padding 0
bspc config -m $MONITOR window_gap 22
bspc config -m $MONITOR bottom_padding 36
bspc config -m $MONITOR top_padding 0
bspc config -m $MONITOR left_padding 0
bspc config -m $MONITOR right_padding 0
#
# Displays
#
nmon=$(bspc query -M | wc -l)
primary=$(bspc query -M -m prmary)
host=$(hostname)
case $host in
triton*)
MONITOR=DVI-I-1
[[ $nmon > 1 ]] && bspc monitor HDMI-0 -d HDMI-0/1
[[ $nmon > 2 ]] && bspc monitor DVI-D-0 -d DVI-D-0/1
;;
proteus*)
MONITOR=LVDS-0
;;
halimede*)
MONITOR=DVI-I-1
[[ $nmon > 1 ]] && bspc monitor DVI-D-0 -d DVI-D-0/1
;;
esac
if [[ $MONITOR ]]; then
export MONITOR
bspc config -m $MONITOR top_padding 25
bspc monitor $MONITOR -d {1,2,3,4,5}
. ~/.config/polybar/run.sh
fi
# #
# Rules # Rules
# #
# Reset
bspc rule -r '*' bspc rule -r '*'
# Floating fixes # Floating fixes
bspc rule -a Emacs:org* state=floating bspc rule -a 'Emacs:org*' state=floating
bspc rule -a mplayer2 state=floating bspc rule -a mplayer2 state=floating
bspc rule -a mpv state=floating center=on bspc rule -a mpv state=floating center=on
bspc rule -a Vlc state=floating monitor=C center=on bspc rule -a Vlc state=floating monitor=C center=on

View file

@ -1,8 +1,9 @@
backend = "xrender"; backend = "glx";
# backend = "xrender";
glx-no-stencil = true; glx-no-stencil = true;
glx-copy-from-front = false; glx-copy-from-front = false;
glx-no-rebind-pixmap = true; glx-no-rebind-pixmap = true;
glx-swap-method = "undefined"; # glx-swap-method = "undefined";
# Set VSync method. VSync methods currently available: # Set VSync method. VSync methods currently available:
# + none: No VSync # + none: No VSync
@ -18,7 +19,8 @@ glx-swap-method = "undefined";
# + opengl-mswc: Try to VSync with MESA_swap_control OpenGL extension. Basically the # + opengl-mswc: Try to VSync with MESA_swap_control OpenGL extension. Basically the
# same as opengl-swc above, except the extension we use. # same as opengl-swc above, except the extension we use.
# (Note some VSync methods may not be enabled at compile time.) # (Note some VSync methods may not be enabled at compile time.)
vsync = "none"; vsync = "opengl-mswc";
# vsync = "none";
# Limit compton to repaint at most once every 1 / refresh_rate second to boost # Limit compton to repaint at most once every 1 / refresh_rate second to boost
# performance. This should not be used with --vsync drm/opengl/opengl-oml as they # performance. This should not be used with --vsync drm/opengl/opengl-oml as they
@ -55,19 +57,20 @@ detect-client-leader = false;
# #
######################################## ########################################
shadow = false; shadow = true;
no-dock-shadow = true; no-dock-shadow = true;
no-dnd-shadow = true; no-dnd-shadow = true;
clear-shadow = true; clear-shadow = true;
shadow-radius = 4; shadow-radius = 4;
shadow-offset-x = -3; shadow-offset-x = -3;
shadow-offset-y = -3; shadow-offset-y = 0;
shadow-opacity = 0.6; shadow-opacity = 0.15;
# shadow-red # shadow-red
# shadow-green # shadow-green
# shadow-blue # shadow-blue
shadow-exclude = [ shadow-exclude = [
"n:e:Notification", "n:e:Notification",
"class_i = 'Dunst'",
"class_i = 'presel_feedback'", "class_i = 'presel_feedback'",
"g:e:Conky" "g:e:Conky"
]; ];
@ -83,13 +86,12 @@ shadow-ignore-shaped = true;
menu-opacity = 1; menu-opacity = 1;
active-opacity = 1; active-opacity = 1;
inactive-opacity = 1.0; inactive-opacity = 1;
# frame-opacity = 1.0; # frame-opacity = 1.0;
inactive-dim = 0.15; inactive-dim = 0.15;
inactive-opacity-override = false; inactive-opacity-override = false;
opacity-rule = [ opacity-rule = [
"80:class_g = 'Bspwm' && class_i = 'presel_feedback'", "80:class_g = 'Bspwm' && class_i = 'presel_feedback'"
"96:class_g = 'URxvt'"
]; ];
alpha-step = 0.06 alpha-step = 0.06

View file

@ -1,40 +1,39 @@
[global] [global]
alignment = left alignment = left
allow_markup = yes markup = full
bounce_freq = 0 bounce_freq = 0
browser = /usr/bin/firefox -new-tab browser = /usr/bin/firefox -new-tab
dmenu = /usr/bin/rofi -dmenu -p dunst: dmenu = /usr/bin/rofi -dmenu -p dunst:
follow = none follow = none
font = Fira Sans 12 font = UW Ttyp0 10
format = "<b>%s</b>\n%b" # font = Misc Tamsyn 12
format = "%s\n%b"
# geometry [{width}]x{height}][+/-{x}+/-{y}] # geometry [{width}]x{height}][+/-{x}+/-{y}]
geometry = "375x22-10+36" geometry = "345x15-21+21"
history_length = 20 history_length = 20
horizontal_padding = 20 horizontal_padding = 16
idle_threshold = 120 idle_threshold = 120
ignore_newline = no ignore_newline = no
indicate_hidden = yes indicate_hidden = yes
line_height = 0 line_height = 0
monitor = 0 monitor = 0
padding = 18 padding = 12
separator_color = frame separator_color = "#18191b"
separator_height = 1 separator_height = 2
show_age_threshold = 60 show_age_threshold = 60
show_indicators = yes show_indicators = yes
shrink = no shrink = no
sort = yes sort = yes
startup_notification = false startup_notification = false
sticky_history = yes sticky_history = yes
transparency = 0 transparency = 1
word_wrap = yes word_wrap = yes
# Align icons left/right/off # Align icons left/right/off
icon_position = right icon_position = right
# Paths to default icons. # Paths to default icons.
icon_folders = /usr/share/icons/hicolor/32x32/apps/:/usr/share/icons/Adwaita/32x32/actions/ icon_folders = /usr/share/icons/hicolor/32x32/apps/:/usr/share/icons/Adwaita/32x32/actions/
frame_width = 0
[frame] frame_color = "#131416"
width = 4
color = "#98C379"
[shortcuts] [shortcuts]
context = ctrl+shift+period context = ctrl+shift+period
@ -42,17 +41,17 @@
[urgency_low] [urgency_low]
# IMPORTANT: colors have to be defined in quotation marks. # IMPORTANT: colors have to be defined in quotation marks.
# Otherwise the "#" and following would be interpreted as a comment. # Otherwise the "#" and following would be interpreted as a comment.
background = "#282c34" background = "#0a0b0c"
foreground = "#bbc2cf" foreground = "#b5bd68"
timeout = 10 timeout = 8
[urgency_normal] [urgency_normal]
background = "#282c34" background = "#b5bd68"
foreground = "#bbc2cf" foreground = "#131416"
timeout = 20 timeout = 14
[urgency_critical] [urgency_critical]
background = "#2B0000" background = "#cc6666"
foreground = "#bbc2cf" foreground = "#131416"
timeout = 0 timeout = 0

View file

@ -0,0 +1,11 @@
[Filechooser Settings]
LocationMode=path-bar
ShowHidden=false
ShowSizeColumn=true
GeometryX=1200
GeometryY=0
GeometryWidth=1010
GeometryHeight=664
SortColumn=name
SortOrder=ascending
StartupMode=recent

View file

@ -0,0 +1,2 @@
include "/usr/share/themes/Adwaita-Slim-Dark/gtk-2.0/gtkrc"
# include "/usr/share/themes/Arc-Dark/gtk-2.0/gtkrc"

View file

@ -0,0 +1,2 @@
file:///home/hlissner
file:///home/hlissner/work

View file

@ -0,0 +1,4 @@
[Settings]
gtk-theme-name = Adwaita-Slim-Dark
gtk-icon-theme-name = Adwaita-Slim-Dark
gtk-application-prefer-dark-theme = true

View file

@ -0,0 +1,342 @@
;=====================================================
;
; To learn more about how to configure Polybar
; go to https://github.com/jaagr/polybar
;
; The README contains alot of information
;
;=====================================================
[colors]
bg = ${xrdb:background}
fg = ${xrdb:foreground}
black = ${xrdb:color0}
bblack = ${xrdb:color8}
red = ${xrdb:color1}
bred = ${xrdb:color9}
green = ${xrdb:color2}
bgreen = ${xrdb:color10}
yellow = ${xrdb:color3}
byellow = ${xrdb:color11}
blue = ${xrdb:color4}
bblue = ${xrdb:color12}
magenta = ${xrdb:color5}
bmagenta = ${xrdb:color13}
cyan = ${xrdb:color6}
bcyan = ${xrdb:color14}
white = ${xrdb:color7}
bwhite = ${xrdb:color15}
bg-alt = #0F1013
fg-alt = #25282a
icons = #555856
alert = ${colors.red}
[global/wm]
margin-top = 0
margin-bottom = 35
[bar/main]
monitor = ${env:MONITOR}
enable-ipc = true
wm-restack = bspwm
# REQUIRED to move the window with hideit.sh
override-redirect = true
background =
foreground = ${colors.fg}
width = 100%
height = 24
offset-x = 0
offset-y = 16
bottom = 1
overline-size = 0
overline-color = #f00
underline-size = 0
underline-color = #00f
border-bottom-size = 0
padding-left = 4
padding-right = 4
module-margin-left = 0
module-margin-right = 0
font-0 = "Misc Tamsyn:pixelsize=12;2"
font-1 = "Wuncon Siji:pixelsize=12;2"
font-2 = "siji:pixelsize=10;2"
modules-left = volume pad cpu memory pad pkg mail
modules-center = bspwm
modules-right = battery wlan app-rslsync app-redshift pad date
;tray-position = center
;tray-padding = 2
;tray-transparent = true
;tray-background = #0063ff
[module/bspwm]
type = internal/bspwm
pin-workspaces = true
enable-click = true
ws-icon-0 = 1;
ws-icon-1 = 2;
ws-icon-2 = 3;
ws-icon-3 = 4;
ws-icon-4 = 5;
ws-icon-default = x
format = <label-state> <label-mode>
label-padding = 1
label-focused = %icon%
label-focused-background = #33000000
label-focused-foreground = ${colors.green}
; label-focused-underline = ${colors.magenta}
; label-focused-foreground = ${xrdb:color2}
label-focused-padding = 1
label-occupied = %icon%
label-occupied-foreground = ${colors.icons}
label-occupied-padding = 1
; label-urgent = %icon%
label-urgent-foreground = ${colors.red}
; label-urgent-background = ${colors.alert}
label-urgent-padding = 1
label-empty = %icon%
label-empty-foreground = ${colors.fg-alt}
label-empty-padding = 1
[module/date]
type = internal/date
interval = 5
label = %date% %time%
date = %A, %h %d
date-alt = %Y-%m-%d
time = %I:%M %p
time-alt = %H:%M:%S
format-prefix = ""
format-prefix-padding = 1
; format-prefix-background = ${colors.bg-alt}
format-prefix-foreground = ${colors.icons}
; format-underline = ${xrdb:color4}
[module/xwindow]
type = internal/xwindow
label = %title:0:80:...%
label-padding-left = 2
; [module/mpd]
; type = internal/mpd
; host = /home/hlissner/.config/mpd/mpd.sock
;
; format-online = <label-song> <toggle>
; format-padding = 5
;
; label-song-maxlen = 45
; label-song-ellipsis = true
;
; icon-prev = 
; icon-seekb = 
; icon-stop = 
; icon-play = 
; icon-pause = 
; icon-next = 
; icon-seekf = 
;
; icon-random = 
; icon-repeat = 
;
; toggle-on-foreground = ${colors.fg}
; toggle-off-foreground = #66
[module/cpu]
type = internal/cpu
interval = 2
format = <bar-load>
format-prefix = ""
format-foreground = ${colors.icons}
; format-underline = #f90000
; label = %percentage%%
format-padding = 1
bar-load-indicator =
bar-load-width = 6
bar-load-foreground-0 = ${colors.green}
bar-load-foreground-1 = ${colors.green}
bar-load-foreground-2 = ${colors.yellow}
bar-load-foreground-3 = ${colors.red}
bar-load-foreground-4 = ${colors.red}
bar-load-fill = |
bar-load-empty = ¦
bar-load-empty-foreground = ${colors.fg-alt}
[module/memory]
type = internal/memory
interval = 3
format = <bar-used>
format-prefix = ""
format-prefix-foreground = ${colors.icons}
; format-underline = #4bffdc
; label = %percentage_used%%
format-padding-left = 1
; Only applies if <bar-used> is used
bar-used-indicator =
bar-used-width = 6
bar-used-foreground-0 = ${colors.green}
bar-used-foreground-1 = ${colors.green}
bar-used-foreground-2 = ${colors.yellow}
bar-used-foreground-3 = ${colors.red}
bar-used-foreground-4 = ${colors.red}
bar-used-fill = |
bar-used-empty = ¦
bar-used-empty-foreground = ${colors.fg-alt}
[module/wlan]
type = internal/network
interface = ${env:WLP:wlp3s0}
interval = 3.0
format-connected = <ramp-signal>
format-disconnected = !
format-disconnected-foreground = ${colors.red}
; label-connected =
; label-disconnected = !
; label-disconnected-foreground = ${colors.red}
ramp-signal-0 = 
ramp-signal-0-foreground = ${colors.yellow}
ramp-signal-1 = 
ramp-signal-1-foreground = ${colors.yellow}
ramp-signal-2 = 
ramp-signal-2-foreground = ${colors.yellow}
ramp-signal-3 = 
ramp-signal-3-foreground = ${colors.icons}
ramp-signal-4 = 
ramp-signal-4-foreground = ${colors.icons}
; [module/eth]
; type = internal/network
; interface = ${env:ETH:enp2s0}
; interval = 4.0
;
; ; format-connected-underline = #55aa55
; ; format-connected-prefix = " "
; format-connected-foreground-foreground = ${colors.fg-alt}
; label-connected = %local_ip%
;
; format-disconnected-underline = ${self.format-connected-underline}
; label-disconnected = %ifname% disconnected
; label-disconnected-foreground = ${colors.fg-alt}
[module/volume]
type = internal/volume
; format-volume = <label-volume> <bar-volume>
format-volume = <ramp-volume> <bar-volume>
; label-volume = " "
label-volume-foreground = ${colors.fg}
; format-muted-prefix = " "
format-muted-foreground = ${colors.red}
label-muted = 
bar-volume-width = 8
bar-volume-foreground-0 = ${colors.blue}
bar-volume-foreground-1 = ${colors.blue}
bar-volume-foreground-2 = ${colors.blue}
bar-volume-foreground-3 = ${colors.blue}
bar-volume-foreground-4 = ${colors.blue}
bar-volume-foreground-5 = ${colors.blue}
bar-volume-foreground-6 = ${colors.blue}
bar-volume-gradient = false
bar-volume-indicator = |
bar-volume-indicator-font = 2
bar-volume-indicator-foreground = #ff
bar-volume-fill = ─
bar-volume-fill-font = 2
bar-volume-empty = ─
bar-volume-empty-font = 2
bar-volume-empty-foreground = ${colors.fg-alt}
; Only applies if <ramp-volume> is used
ramp-volume-0 = 
ramp-volume-1 = 
ramp-volume-2 = 
[module/battery]
type = internal/battery
battery = BAT0
adapter = ADP1
full-at = 98
format-charging = <animation-charging> <label-charging>
format-charging-underline = #ffb52a
format-discharging = <ramp-capacity> <label-discharging>
format-discharging-underline = ${self.format-charging-underline}
format-full-prefix = " "
format-full-prefix-foreground = ${colors.fg-alt}
format-full-underline = ${self.format-charging-underline}
ramp-capacity-0 = 
ramp-capacity-1 = 
ramp-capacity-2 = 
ramp-capacity-foreground = ${colors.fg-alt}
animation-charging-0 = 
animation-charging-1 = 
animation-charging-2 = 
animation-charging-foreground = ${colors.fg-alt}
animation-charging-framerate = 750
;=====================================================
; Custom scripts
;=====================================================
[module/pad]
type = custom/text
content = " "
content-foreground = ${colors.fg-alt}
[module/pkg]
type = custom/ipc
hook-0 = ~/.config/polybar/modules/updates
initial = 1
click-left = polybar-msg -p %pid% hook pkg 1
format-padding = 1
[module/mail]
type = custom/ipc
hook-0 = ~/.config/polybar/modules/mail
initial = 1
click-left = polybar-msg -p %pid% hook mail 1
format-padding-right = 1
[module/app-redshift]
type = custom/script
exec = echo 1
exec-if = pgrep -x redshift
format = ""
format-foreground = ${colors.icons}
interval = 2
[module/app-rslsync]
type = custom/script
exec = echo 1
exec-if = pgrep -x rslsync
format = ""
format-foreground = ${colors.icons}
interval = 60
; vim:ft=dosini

View file

@ -2,8 +2,6 @@
# Specifying the icon(s) in the script # Specifying the icon(s) in the script
# This allows us to change its appearance conditionally # This allows us to change its appearance conditionally
icon=""
pgrep -x redshift &> /dev/null pgrep -x redshift &> /dev/null
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
temp=$(redshift -p 2>/dev/null | grep temp | cut -d' ' -f3) temp=$(redshift -p 2>/dev/null | grep temp | cut -d' ' -f3)

View file

@ -0,0 +1,92 @@
#!/usr/bin/env python3
import imaplib
import os
import sys
import socket
from subprocess import Popen
CONFIG_FILE = os.path.expanduser("~/.secrets/email")
CACHE_FILE = "/tmp/polybar-mail"
ICON = ""
try:
import gnupg
from pathlib import Path
except ImportError:
print("%{{F{}}}*".format("#555856", ICON))
sys.exit(1)
#
def internet_is_on():
try:
host = socket.gethostbyname("www.google.com")
socket.create_connection((host, 80), 2)
return True
except:
pass
return False
def unread_count(address, password):
imap = imaplib.IMAP4_SSL('imap.gmail.com', 993)
imap.login(address, password)
imap.select('INBOX')
status, resp = imap.search(None, 'UNSEEN')
imap.close()
imap.logout()
return len(resp[0].split())
def ding():
Popen(["{}/bin/ding".format(os.getenv("DOTFILES", os.expanduser("~/.dotfiles")))])
#
def main():
try:
if not internet_is_on():
raise IOError("Internet is off")
secrets = Path(CONFIG_FILE)
if not secrets.exists():
raise IOError("Can't find secrets")
gpg = gnupg.GPG()
gpgdata = gpg.decrypt(secrets.read_bytes())
if not gpgdata.ok:
raise IOError("Couldn't decrypt secrets")
accounts = [line.split(':') for line in gpgdata.data.decode('utf-8').strip().split('\n')]
last_total = 0
cache = Path(CACHE_FILE)
if cache.exists():
cache_text = cache.read_text()
last_total = int(cache.read_text())
total = 0
for addr, pwd in accounts:
total += unread_count(addr, pwd)
if total != last_total:
ding()
if total != 0:
print("%{{F{}}}{}{}".format("#f0c674", ICON, total))
else:
print("%{{F{}}}{}".format("#555856", ICON))
cache.write_text(str(total))
except IOError as e:
print("ERROR: {}".format(e), file=sys.stderr)
print("%{{F{}}}{}!".format("#cc6666", ICON))
sys.exit(1)
#
if __name__ == '__main__':
if sys.argv[1:]:
print("%{{F{}}}{}".format("#555856", ICON))
else:
main()

View file

@ -0,0 +1,22 @@
#!/usr/bin/env zsh
icon=""
if [[ $1 == "1" ]]; then
echo "%{F#555856}${icon}%{F-}"
exit
fi
pac=$(checkupdates | wc -l)
aur=$(cower -u | wc -l)
[[ -f /tmp/polybar-updates ]] && last=$(</tmp/polybar-updates)
check=$((pac + aur))
if [[ "$check" != "0" ]]; then
echo "%{F#b5bd68}${icon}$pac+$aur%{F-}"
if [[ $last != "$pac$aur" ]]; then
notify-send "$((pac+aur)) updates available"
aplay -N -q $DOTFILES_ASSETS/sounds/updates.ogg
echo "$pac$aur" >/tmp/polybar-updates
fi
else
echo "%{F#555856}${icon}%{F-}"
fi

11
base/arch/config/polybar/run.sh Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env zsh
killall -q polybar
while _is_running polybar; do sleep 1; done
source "${0:A:h}/../../bin/inject-xcolors"
pushd ~ >/dev/null
polybar main >>$XDG_DATA_HOME/polybar.log 2>&1 &
popd >/dev/null
echo "Polybar launched..."

View file

@ -0,0 +1,141 @@
#
# wm independent hotkeys
#
# terminal emulator
mod4 + ctrl + Return
urxvt
mod4 + ctrl + shift + Return
urxvt -name urxvt-stream
mod4 + grave
urxvt-scratch-window
mod4 + space
urxvt-app-launcher
mod4 + backslash
urxvt-pass-manager
mod4 + mod1 + backslash
firefox-current
# urxvt-pass-manager -r
# reload sxhkd
mod4 + ctrl + shift + Escape
ding; pkill -USR1 -x sxhkd
#
# Media keys
#
Print
maim -s ~/screenshots/$(date +%F-%T).png && notify-send "Screenshot saved"
mod4 + Print
maim ~/screenshots/$(date +%F-%T).png && notify-send "Fullscreen screenshot saved"
mod4 + shift + Print
maim -d 3 ~/screenshots/$(date +%F-%T).png && notify-send "Screenshot saved"
Pause
mpc -q toggle # play/pause music
mod4 + {Pause,XF86Eject}
zzz # sleep display
mod4 + shift + Pause
zzz -f # sleep computer
# Media Keys
XF86Audio{Play,Pause}
mpc -q toggle
XF86Audio{Prev,Next}
mpc -q {prev,next}
XF86Audio{LowerVolume,RaiseVolume}
vol {-,+}
XF86AudioMute
vol toggle
mod4 + {Down,Up}
vol {-,+}
mod4 + {Left,Right}
mpc {prev,next}
#
# bspwm hotkeys
#
# quit bspwm normally
mod4 + alt + Escape
bspc quit
# close and kill
mod4 + {_,shift + }q
bspc node -{c,k}
#
# state/flags
#
mod4 + {ctrl,shift + } f
{bspc desktop -l next,bspc node -t \~floating}
mod4 + shift + p
bspc node -t \~pseudo_tiled
# set the node flags
mod4 + ctrl + {x,y,z}
bspc node -g {locked,sticky,private}
#
# focus/swap
#
# focus/swap the node in the given direction
mod4 + {_,ctrl +}{h,j,k,l}
bspc-focus {_,-m }{west,south,north,east}
mod4 + shift + {_,ctrl +}{h,j,k,l}
bspc-swap {_,-m }{west,south,north,east}
# focus the node for the given path jump
mod4 + {p,b,comma,period}
bspc node -f @{parent,brother,first,second}
# focus monitor or send to the given desktop
mod4 + bracket{left,right}
bspc desktop -f focused#{prev,next}.local
mod4 + ctrl + {_,shift +}{1-9,0}
bspc {desktop -f,node -d} {1-9,10}
#
# preselect
#
# preselect the direction
mod4 + mod1 + ctrl + {h,j,k,l}
bspc node -p {west,south,north,east}
# preselect the ratio
mod4 + mod1 + ctrl + {1-9}
bspc node -o 0.{1-9}5
# cancel the preselection for the focused node
mod4 + mod1 + ctrl + space
bspc node -p cancel
# cancel the preselection for the focused desktop
#mod4 + alt + shift + space
# bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel
# expand the tiled space in the given direction
#mod4 + alt + {h,j,k,l}
# bspc node {@west -r -,@south -r +,@north -r -,@east -r +}64
#
## contract the tiled space in the given direction
#mod4 + alt + ctrl + {h,j,k,l}
# bspc node {@east -r -,@north -r +,@south -r -,@west -r +}64
# move a floating window
#mod4 + alt + {Left,Down,Up,Right}
# xdo move {-x -,-y +,-y -,-x +}40
#mod4 + alt + ctrl + {Left,Down,Up,Right}
# xdo resize {-w -,-h -,-h -,-w -}40

View file

@ -9,9 +9,9 @@
# m hr d m w cmd # m hr d m w cmd
# 0 * * * * ... # 0 * * * * ...
# Lemonbar
# 0,30 * * * * DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus ~/.config/panel/panel-notify :updates
# */2 * * * * DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus ~/.config/panel/panel-notify :mail
# Polybar # Polybar
0,30 * * * * polybar-msg hook pkg 1 0 * * * * polybar-msg hook pkg 1
*/5 * * * * polybar-msg hook mail 1
# Personal
0 * * * * DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send "It is $(date +\%H:\%M)"

14
base/arch/env.zsh Normal file
View file

@ -0,0 +1,14 @@
export GNUPGHOME="$XDG_CONFIG_HOME/gpg"
export GTK2_RC_FILES="${0:A:h}/config/gtk-2.0/gtkrc"
export TERMINFO="$XDG_CONFIG_HOME/terminfo"
export BROWSER=firefox
export URXVT_PERL_LIB="$XDG_CONFIG_HOME/urxvt"
_is_running ssh-agent || {
ssh-agent -s >"$XDG_RUNTIME_DIR/ssh-agent-env"
}
_is_running gpg-agent || {
gpg-agent --daemon >"$XDG_RUNTIME_DIR/gpg-agent-env"
}
_source "$XDG_RUNTIME_DIR/ssh-agent-env" >/dev/null
_source "$XDG_RUNTIME_DIR/gpg-agent-env" >/dev/null

View file

@ -0,0 +1,3 @@
2
kakwafont-12-b.pcf.gz -kakwa-kakwafont-medium-r-bold--12-120-72-72-c-60-iso8859-1
kakwafont-12-n.pcf.gz -kakwa-kakwafont-medium-r-normal--12-120-72-72-c-60-iso8859-1

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
if command -v aseprite >/dev/null; then
echo "Aseprite is already installed"
exit 1
fi
set -e
pacaur --needed --noconfirm --noedit -S ninja cmake libxcursor
rm -rf /tmp/aseprite
if git clone --recursive https://github.com/aseprite/aseprite /tmp/aseprite; then
mkdir /tmp/aseprite/build && cd /tmp/aseprite/build
cmake -DCMAKE_INSTALL_PREFIX=/usr -G Ninja ..
ninja aseprite
ninja install
fi

View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
if ! grep -e '^[multilib]' /etc/pacman.conf >/dev/null; then
echo "[multilib]\nInclude = /etc/pacman.d/mirrorlist" | \
sudo tee -a /etc/pacman.conf
sudo pacman -Sy
fi
sudo pacman --needed -S steam

View file

@ -0,0 +1,8 @@
#!/usr/bin/env zsh
sudo pacman --noconfirm --needed -S udevil devmon
sudo systemctl enable devmon@$USER
sudo systemctl start devmon@$USER
ARCH=$(cd "${0:A:h}/.." && pwd)
sudo sed -i "s@^# \(success_exec =\)@\1 $ARCH/bin/notify-mount@" /etc/udevil/udevil.conf

43
base/arch/xprofile Normal file
View file

@ -0,0 +1,43 @@
#!/bin/bash
DOTS=~/.dotfiles
source $DOTS/env
# A tidy $HOME is a tidy mind
export XAUTHORITY="$XDG_RUNTIME_DIR/Xauthority"
[[ -e ~/.Xauthority ]] && mv -f ~/.Xauthority "$XAUTHORITY"
#
ARCH=$DOTS/base/arch
[[ -f $ARCH/Xresources ]] && xrdb $ARCH/Xresources
[[ -f $ARCH/Xmodmap ]] && xmodmap $ARCH/Xmodmap
# set wallpaper
[[ -e ~/wallpaper ]] && feh --no-fehbg --image-bg black --bg-center ~/wallpaper
# Let me know
paplay $DOTFILES_ASSETS/sounds/startup.ogg &
# autostart programs
{
run() {
if _is_callable "$1" && ! _is_running "$1"; then
"$@"
fi
}
# essentials
run sxhkd & # keyboard daemon
run dunst & # notifications
# non-essentials
{
sleep 2
run mpd & # music server
run redshift & # screen temperature based on time-of-day
run rslsync & # resilio sync
run compton & # perdy effects + transparency
# If sxhkd isn't running by now, something is wrong
_is_running sxhkd || urxvt &
} &
} 2>&1 >$XDG_DATA_HOME/xsession-errors.log

35
base/macos/_init Executable file
View file

@ -0,0 +1,35 @@
#!/usr/bin/env zsh
source ${0:A:h}/../../deploy
install() {
# Install homebrew
if ! _is_callable brew; then
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
fi
brew install \
wget curl tree coreutils bash \
the_silver_searcher ripgrep ffmpeg keybase \
neofetch youtube-dl
# pass-otp
brew install pass oath-toolkit
if _ensure_repo tadfisher/pass-otp /tmp/pass-otp; then
cd /tmp/pass-otp
make install PREFIX=/usr/local
fi
}
update() {
if _is_callable brew; then
brew update && brew upgrade && brew cleanup
else
echo-fail "homebrew not detected"
fi
}
# link() {}
# clean() {}
init "$@"

View file

@ -1,16 +1,14 @@
alias ls="gls --color=auto --group-directories-first" alias ls="gls --color=auto --group-directories-first"
alias date='gdate' alias date=gdate
alias y='pbcopy' alias y=pbcopy
alias p='pbpaste' alias p=pbpaste
alias br='brew' alias br=brew
alias bru='brew update && brew upgrade && brew cleanup' alias bru='brew update && brew upgrade && brew cleanup'
alias brc='brew cask' alias brc='brew cask'
alias localip="ipconfig getifaddr en1"
# OS X has no `md5sum`, so use `md5` as a fallback # OS X has no `md5sum`, so use `md5` as a fallback
is-callable md5sum || alias md5sum="md5" is-callable md5sum || alias md5sum="md5"
# OS X has no `sha1sum`, so use `shasum` as a fallback # OS X has no `sha1sum`, so use `shasum` as a fallback
is-callable sha1sum || alias sha1sum="shasum" is-callable sha1sum || alias sha1sum="shasum"

0
os/+macos/bin/timelapse → base/macos/bin/timelapse Executable file → Normal file
View file

View file

View file

@ -1,3 +1,4 @@
export GNUPGHOME="$XDG_CONFIG_HOME/gpg"
export BROWSER='open' export BROWSER='open'
# export CC=/usr/bin/clang # export CC=/usr/bin/clang

View file

@ -3,10 +3,10 @@
# Converts a number from one base to another. DEST_RADIX is optional and # Converts a number from one base to another. DEST_RADIX is optional and
# defaults to 10. # defaults to 10.
# #
# Usage: base [SRC_RADIX] [NUMBER] [DEST_RADIX] # Usage: base SRC_RADIX NUMBER DEST_RADIX
# Examples: # Examples:
# + base 2 110 #=> 6 # + base 2 110 #=> 6 (110_2 => 6_10)
# + base 2 110 10 #=> 6 # + base 10 9 8 #=> 11 (9_10 => 11_8)
# + base 16 FF #=> 6 # + base 16 FF #=> 255 (FF_16 => 255_10)
bc <<< "obase=${3:-10};ibase=$1;$2" bc <<< "obase=${3:-10};ibase=$1;$2"

View file

23
bin/colors Executable file
View file

@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Prints a bunch of color codes to the terminal to demonstrate what's available.
# Each line is the color code of one forground color, out of 17 (default + 16
# escapes), followed by a test use of that color on all nine background colors
# (default + 8 escapes).
T=niX # The test text
echo -e "\n 40m 41m 42m 43m\
44m 45m 46m 47m";
for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \
'1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \
' 36m' '1;36m' ' 37m' '1;37m';
do FG=${FGs// /}
echo -en " $FGs \033[$FG $T "
for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
do echo -en "$EINS \033[$FG\033[$BG $T \033[0m";
done
echo;
done
echo

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env zsh
DEFAULT="$HOME/.dotfiles/sounds/${1:-Titan.ogg}" DEFAULT="$DOTFILES_ASSETS/sounds/${1:-Titan.ogg}"
case $OSTYPE in case $OSTYPE in
darwin*) afplay "$DEFAULT" ;; darwin*) afplay $DEFAULT ;;
linux*) paplay "$DEFAULT" ;; linux*) paplay $DEFAULT ;;
esac esac

View file

@ -1,3 +1,3 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# make sure your .curlrc doesn't set a real useragent # NOTE make sure your .curlrc doesn't set a real useragent
curl http://wttr.in/${1:-toronto} curl http://wttr.in/${1:-toronto}

View file

@ -1,9 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Helper for encrypting/decrypting folders with gpg and tar. # Encrypt/decrypt and compress folders with gpg+tar.
# Usage: # Usage:
# clump foldername # packs # clump foldername # packs
# clump foldername.clump # unpacks # clump foldername.clump # unpacks
set -e set -e
if (($# == 0)); then if (($# == 0)); then

View file

@ -8,7 +8,6 @@ import argparse
import fileinput import fileinput
import html import html
from html.entities import entitydefs from html.entities import entitydefs
from pathlib import Path
ENTITIES = {value: key for key, value in entitydefs.items()} ENTITIES = {value: key for key, value in entitydefs.items()}
@ -28,16 +27,10 @@ def decode(text):
if __name__ == '__main__': if __name__ == '__main__':
opts = argparse.ArgumentParser(description="Encodes (or decodes) HTML entities in text.") opts = argparse.ArgumentParser(description="Encodes (or decodes) HTML entities in text.")
opts.add_argument('file', nargs="?", help="File to encode/decode") opts.add_argument('file', type=str, nargs="*", help="File to encode/decode")
opts.add_argument('-d', '--decode', action='store_true', help="Decode the given files/input") opts.add_argument('-d', '--decode', action='store_true', help="Decode the given files/input")
args = opts.parse_args() args = opts.parse_args()
if "file" in args and args.file: text = [line for line in fileinput.input(args.file)]
text = Path(args.file).read_text() action = decode if args.decode else encode
else: print(action("\n".join(text).strip()))
text = "\n".join([line for line in fileinput.input()]).strip()
if args.decode:
print(decode(text))
else:
print(encode(text))

View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env zsh
# A simple script that losslessly optimizes image files given to it. # A simple script that losslessly optimizes image files given to it.
# #
@ -13,57 +13,59 @@
# GIFs: gifsicle # GIFs: gifsicle
set -e set -e
unset CDPATH
LOSSY= LOSSY=
usage() { usage() {
cat <<EOL cat <<EOL
Usage: ${0##*/} [-lh] IMAGE [IMAGE2 [IMAGE3 [...]]] Usage: ${0:A:t} [-lh] IMAGE [IMAGE2 [IMAGE3 [...]]]
-l enable lossy compression -l enable lossy compression
-h this help -h this help
EOL EOL
} }
while getopts hl opt; do while getopts hl opt; do
case $opt in case $opt in
h) usage; exit;; h) usage; exit;;
l) LOSSY=1;; l) LOSSY=1;;
:) >&2 echo "$OPTARG requires an argument"; usage; exit 1;; :) >&2 echo "$OPTARG requires an argument"; usage; exit 1;;
*) >&2 echo "Not a valid arg: $opt"; usage; exit 1;; *) >&2 echo "Not a valid arg: $opt"; usage; exit 1;;
esac esac
done done
shift $((OPTIND-1)) shift $((OPTIND-1))
_filesize() { _filesize() {
case $OSTYPE in case $OSTYPE in
darwin*) stat -c%s "$1" ;; darwin*) stat -c%s "$1" ;;
*) stat --printf="%s" "$1" ;; *) stat --printf="%s" "$1" ;;
esac esac
} }
for file in $@; do for file in $@; do
if [[ -d $file ]]; then if [[ -d $file ]]; then
imgoptim $file/* imgoptim $file/*
elif [[ -f $file ]]; then elif [[ -f $file ]]; then
pre_size=$(_filesize "$file") pre_size=$(_filesize "$file")
case ${file##*.} in case ${file##*.} in
png) png)
[[ $LOSSY ]] && pngquant $file [[ $LOSSY ]] && pngquant $file
optipng -nc -nb -o7 $file optipng -nc -nb -o7 $file
;; ;;
gif) gif)
gifsicle --batch --optimize=3 "$file" gifsicle --batch --optimize=3 "$file"
;; ;;
jpg|jpeg) jpg|jpeg)
[[ $LOSSY ]] && jpegoptim --max=90 "$file" [[ $LOSSY ]] && jpegoptim --max=90 "$file"
jpegtran -copy none -optimize -progressive -outfile "$file" "$file" jpegtran -copy none -optimize -progressive -outfile "$file" "$file"
;; ;;
*) printf "Unrecognized file '$file': ignored" *)
;; printf "Unrecognized file '$file': ignored"
esac ;;
post_size=$(_filesize "$file") esac
perc=$(echo "((${pre_size} - ${post_size}) / ${pre_size}) * 100" | bc -l) post_size=$(_filesize "$file")
printf "* %s: %d => %d (%.2f%% reduction)\n" "$file" "${pre_size}" "${post_size}" "$perc" perc=$(echo "((${pre_size} - ${post_size}) / ${pre_size}) * 100" | bc -l)
fi printf "* %s: %d => %d (%.2f%% reduction)\n" "$file" "${pre_size}" "${post_size}" "$perc"
fi
done done

View file

@ -1,19 +1,18 @@
#!/bin/sh #!/usr/bin/env bash
# Read a file with possible syntax coloring applied
case "$1" in case "$1" in
*.awk|*.groff|*.java|*.js|*.m4|*.php|*.pl|*.pm|*.pod|*.sh|\ *.awk|*.groff|*.java|*.js|*.m4|*.php|*.pl|*.pm|*.pod|*.sh|\
*.ad[asb]|*.asm|*.inc|*.[ch]|*.[ch]pp|*.[ch]xx|*.cc|*.hh|\ *.ad[asb]|*.asm|*.inc|*.[ch]|*.[ch]pp|*.[ch]xx|*.cc|*.hh|\
*.lsp|*.l|*.pas|*.p|*.xml|*.xps|*.xsl|*.axp|*.ppd|*.pov|\ *.lsp|*.l|*.pas|*.p|*.xml|*.xps|*.xsl|*.axp|*.ppd|*.pov|\
*.diff|*.patch|*.py|*.rb|*.sql|*.ebuild|*.eclass) *.diff|*.patch|*.py|*.rb|*.sql|*.ebuild|*.eclass)
pygmentize -f 256 "$1";; pygmentize -f 256 "$1" ;;
.bashrc|.bash_aliases|.bash_environment) .bashrc|.bash_aliases|.bash_environment)
pygmentize -f 256 -l sh "$1" pygmentize -f 256 -l sh "$1" ;;
;; *)
*) if ! grep "#\!/.+[/ ](ba|z)?sh" "$1" >/dev/null; then
grep "#\!/bin/bash" "$1" > /dev/null exit 1
if [ "$?" -eq "0" ]; then fi
pygmentize -f 256 -l sh "$1" pygmentize -f 256 -l sh "$1"
else
exit 1
fi
esac esac

View file

@ -15,37 +15,37 @@ Report bugs to <sorin.ionescu@gmail.com>.
EOF EOF
fi fi
if [[ $1 = -v || $1 = --verbose ]]; then if [[ $1 == -v || $1 == --verbose ]]; then
verbose=0 verbose=0
shift shift
fi fi
while (($# > 0)); do while (($# > 0)); do
if [[ ! -s $1 ]]; then if [[ ! -s $1 ]]; then
>&2 echo "$0: file not valid: $1" >&2 echo "$0: file not valid: $1"
shift
continue
fi
case ${1:l} in
*.tar.gz|*.tgz) tar t${verbose:+v}vzf "$1" ;;
*.tar.bz2|*.tbz|*.tbz2) tar t${verbose:+v}jf "$1" ;;
*.tar.xz|*.txz) tar --xz --help &> /dev/null \
&& tar --xz -t${verbose:+v}f "$1" \
|| xzcat "$1" | tar t${verbose:+v}f - ;;
*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \
&& tar --lzma -t${verbose:+v}f "$1" \
|| lzcat "$1" | tar x${verbose:+v}f - ;;
*.tar) tar t${verbose:+v}f "$1" ;;
*.zip) unzip -l${verbose:+v} "$1" ;;
*.rar) unrar &> /dev/null \
&& unrar ${${verbose:+v}:-l} "$1" \
|| rar ${${verbose:+v}:-l} "$1" ;;
*.7z) 7za l "$1" ;;
*) >&2 echo "$0: cannot list: $1"
success=1
;;
esac
shift shift
continue
fi
case ${1:l} in
*.tar.gz|*.tgz) tar t${verbose:+v}vzf "$1" ;;
*.tar.bz2|*.tbz|*.tbz2) tar t${verbose:+v}jf "$1" ;;
*.tar.xz|*.txz) tar --xz --help &> /dev/null \
&& tar --xz -t${verbose:+v}f "$1" \
|| xzcat "$1" | tar t${verbose:+v}f - ;;
*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \
&& tar --lzma -t${verbose:+v}f "$1" \
|| lzcat "$1" | tar x${verbose:+v}f - ;;
*.tar) tar t${verbose:+v}f "$1" ;;
*.zip) unzip -l${verbose:+v} "$1" ;;
*.rar) unrar &> /dev/null \
&& unrar ${${verbose:+v}:-l} "$1" \
|| rar ${${verbose:+v}:-l} "$1" ;;
*.7z) 7za l "$1" ;;
*) >&2 echo "$0: cannot list: $1"
success=1
;;
esac
shift
done done

View file

@ -14,7 +14,7 @@ set -e
PALETTE="/tmp/palette.png" PALETTE="/tmp/palette.png"
usage() { usage() {
cat <<EOL cat <<EOL
Usage: ${0##*/} [-fsSth] SOURCE_FILE [destfile] Usage: ${0##*/} [-fsSth] SOURCE_FILE [destfile]
-f [FPS] set frames per second -f [FPS] set frames per second
@ -31,33 +31,33 @@ trap cleanup EXIT
# #
fps=30 fps=30
while getopts hf:s:t:S: opt; do while getopts hf:s:t:S: opt; do
case $opt in case $opt in
f) fps="$OPTARG" ;; f) fps="$OPTARG" ;;
s) start="-ss $OPTARG" ;; s) start="-ss $OPTARG" ;;
S) scale=",scale=$OPTARG:flags=lanczos" ;; S) scale=",scale=$OPTARG:flags=lanczos" ;;
t) duration="-t $OPTARG" ;; t) duration="-t $OPTARG" ;;
h) usage h) usage
exit exit
;; ;;
:) >&2 echo "$OPTARG requires an argument" :) >&2 echo "$OPTARG requires an argument"
usage usage
exit 1 exit 1
;; ;;
*) >&2 echo "Not a valid arg: $opt" *) >&2 echo "Not a valid arg: $opt"
usage usage
exit 1 exit 1
;; ;;
esac esac
done done
shift $((OPTIND-1)) shift $((OPTIND-1))
# #
if (($# == 0)); then if (($# == 0)); then
>&2 echo "No movie file specified" >&2 echo "No movie file specified"
exit exit
elif [[ ! -f $1 ]]; then elif [[ ! -f $1 ]]; then
>&2 echo "$1 does not exist" >&2 echo "$1 does not exist"
exit exit
fi fi
src="$1" src="$1"
@ -70,5 +70,5 @@ ffmpeg -v warning $start $duration -i "$src" -vf "$flags,palettegen=stats_mode=f
ffmpeg -v warning $start $duration -i "$src" -i "$PALETTE" -lavfi "$flags [x]; [x][1:v] paletteuse" -y "$dest" ffmpeg -v warning $start $duration -i "$src" -i "$PALETTE" -lavfi "$flags [x]; [x][1:v] paletteuse" -y "$dest"
if command -v gifsicle >/dev/null; then if command -v gifsicle >/dev/null; then
gifsicle -O3 "$dest" -o "$dest" gifsicle -O3 "$dest" -o "$dest"
fi fi

View file

@ -1,9 +0,0 @@
#!/usr/bin/env bash
case $OSTYPE in
darwin*)
terminal-notifier -title "$1" -message "$2"
;;
linux*)
DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send "$1" "$2"
;;
esac

36
bin/pacman-colors Executable file
View file

@ -0,0 +1,36 @@
#!/usr/bin/env bash
# ANSI color scheme script featuring PACMAN
# by pfh
#
# Initializing procedure by lolilolicon
f=3 b=4
for j in f b; do
for i in {0..7}; do
printf -v $j$i %b "\e[${!j}${i}m"
done
done
bld=$'\e[1m'
rst=$'\e[0m'
inv=$'\e[7m'
cat << EOF
$rst
$f3 ▄███████▄ $f1 ▄██████▄ $f2 ▄██████▄ $f4 ▄██████▄ $f5 ▄██████▄ $f6 ▄██████▄
$f3▄█████████▀▀ $f1▄$f7█▀█$f1██$f7█▀█$f1██▄ $f2▄█$f7███$f2██$f7███$f2█▄ $f4▄█$f7███$f4██$f7███$f4█▄ $f5▄█$f7███$f5██$f7███$f5█▄ $f6▄██$f7█▀█$f6██$f7█▀█$f6▄
$f3███████▀ $f7▄▄ ▄▄ ▄▄ $f1█$f7▄▄█$f1██$f7▄▄█$f1███ $f2██$f7█ █$f2██$f7█ █$f2██ $f4██$f7█ █$f4██$f7█ █$f4██ $f5██$f7█ █$f5██$f7█ █$f5██ $f6███$f7█▄▄$f6██$f7█▄▄$f6█
$f3███████▄ $f7▀▀ ▀▀ ▀▀ $f1████████████ $f2████████████ $f4████████████ $f5████████████ $f6████████████
$f3▀█████████▄▄ $f1██▀██▀▀██▀██ $f2██▀██▀▀██▀██ $f4██▀██▀▀██▀██ $f5██▀██▀▀██▀██ $f6██▀██▀▀██▀██
$f3 ▀███████▀ $f1▀ ▀ ▀ ▀ $f2▀ ▀ ▀ ▀ $f4▀ ▀ ▀ ▀ $f5▀ ▀ ▀ ▀ $f6▀ ▀ ▀ ▀
$bld
$f3 ▄███████▄ $f1 ▄██████▄ $f2 ▄██████▄ $f4 ▄██████▄ $f5 ▄██████▄ $f6 ▄██████▄
$f3▄█████████▀▀ $f1▄$f7█▀█$f1██$f7█▀█$f1██▄ $f2▄█$f7█ █$f2██$f7█ █$f2█▄ $f4▄█$f7█ █$f4██$f7█ █$f4█▄ $f5▄█$f7█ █$f5██$f7█ █$f5█▄ $f6▄██$f7█▀█$f6██$f7█▀█$f6▄
$f3███████▀ $f7▄▄ ▄▄ ▄▄ $f1█$f7▄▄█$f1██$f7▄▄█$f1███ $f2██$f7███$f2██$f7███$f2██ $f4██$f7███$f4██$f7███$f4██ $f5██$f7███$f5██$f7███$f5██ $f6███$f7█▄▄$f6██$f7█▄▄$f6█
$f3███████▄ $f7▀▀ ▀▀ ▀▀ $f1████████████ $f2████████████ $f4████████████ $f5████████████ $f6████████████
$f3▀█████████▄▄ $f1██▀██▀▀██▀██ $f2██▀██▀▀██▀██ $f4██▀██▀▀██▀██ $f5██▀██▀▀██▀██ $f6██▀██▀▀██▀██
$f3 ▀███████▀ $f1▀ ▀ ▀ ▀ $f2▀ ▀ ▀ ▀ $f4▀ ▀ ▀ ▀ $f5▀ ▀ ▀ ▀ $f6▀ ▀ ▀ ▀
$rst
EOF

27
bin/pass-get Executable file
View file

@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Fetches the FIELD in ENTRY. It expects pass fields to be colon-delimited.
if (( $# != 2 )); then
>&2 echo "Expected two arguments"
>&2 echo "pass get ENTRY FIELD"
exit 1
fi
entry=$1
field=$2
secrets="$(pass show $entry)"
if [[ ! $secrets ]]; then
notify-send --urgency=critical "Failed to retrieve $entry"
exit 2
fi
if [[ $field == password || -z $field ]]; then
printf "%s" "$(head -n1 <<<"$secrets")"
else
printf "%s" "$(awk -v "key=$field:" '$1 == key {print $2}' <<<"$secrets")"
fi | xsel -i -b -t 15000
#
echo "Copied $entry:$field to clipboard for 15s"

31
bin/pass-otpuri Executable file
View file

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Generates an OTP-auth url (written for pass-otp)
#
# Example: passotpuri LABEL SECRET [QUERYSTRING]
type=totp
issuer=
while getopts tih opt; do
case $opt in
t) type="$OPTARG" ;;
i) issuer="$OPTARG" ;;
h) cat <<EOL
Usage: $0 [-iuldypLSU] [topic1] [topic2] [...]
-t Set type (defaults to totp)
-i Issuer
EOL
exit
;;
*) >&2 echo "Aborted."
exit 1 ;;
esac
done
shift $((OPTIND-1))
label="$1"
secret="$2"
args="${3:+&$3}"
echo "otpauth://$type/$label?secret=$secret&issuer=${issuer:-$label}$args"

View file

@ -10,27 +10,27 @@
# Requires: ghostscript (gs) # Requires: ghostscript (gs)
optimize() { optimize() {
# Adapted from Alfred Klomp's shrinkpdf script # Adapted from Alfred Klomp's shrinkpdf script
# <http://alfredklomp.com/programming/shrinkpdf/> # <http://alfredklomp.com/programming/shrinkpdf/>
gs -q -dNOPAUSE -dBATCH -dSAFER \ gs -q -dNOPAUSE -dBATCH -dSAFER \
-sDEVICE=pdfwrite \ -sDEVICE=pdfwrite \
-dPDFSETTINGS=/screen \ -dPDFSETTINGS=/screen \
-dCompatibilityLevel=1.3 \ -dCompatibilityLevel=1.3 \
-dEmbedAllFonts=true \ -dEmbedAllFonts=true \
-dSubsetFonts=true \ -dSubsetFonts=true \
-dAutoRotatePages=/None \ -dAutoRotatePages=/None \
-dMonoImageResolution=$3 \ -dMonoImageResolution=$3 \
-dMonoImageDownsampleType=/Bicubic \ -dMonoImageDownsampleType=/Bicubic \
-dGrayImageResolution=$3 \ -dGrayImageResolution=$3 \
-dGrayImageDownsampleType=/Bicubic \ -dGrayImageDownsampleType=/Bicubic \
-dColorImageResolution=$3 \ -dColorImageResolution=$3 \
-dColorImageDownsampleType=/Bicubic \ -dColorImageDownsampleType=/Bicubic \
-sOutputFile="$2" \ -sOutputFile="$2" \
"$1" "$1"
} }
SRC="$1" src="$1"
DEST="${2:--}" dest="${2:--}"
DPI="${3:-72}" dpi="${3:-72}"
optimize "$SRC" "$DEST" "$DPI" || exit $? optimize "$src" "$dest" "$dpi" || exit $?

View file

@ -1,39 +1,57 @@
#!/usr/bin/env bash #!/usr/bin/env bash
if [[ ! -f "$HOME/.private/config/pushover.conf" ]]; then #
>&2 echo "No pushover config file found (~/.private/config/pushover.conf)" # Sends a pushover notification.
exit 1 #
# -t [TITLE]
# -m [MESSAGE]
# -p [PRIORITY_LEVEL]
# -u [URL]
# -U [URL_TITLE]
# -d [DEVICE]
#
set -e
unset CDPATH
secret_file=~/.secrets/pushover
if [[ ! -f $secret_file ]]; then
>&2 echo "No pushover config file found"
exit 1
fi fi
message= title=${2:+$1}
title= message=${2:-$1}
priority= # priority=
url= url=
url_title=
device= device=
while getopts t:m:p:u:d: opt; do while getopts t:m:p:u:d: opt; do
case $opt in case $opt in
t) title="$OPTARG" ;; t) title="$OPTARG" ;;
m) message="$OPTARG" ;; m) message="$OPTARG" ;;
p) priority="$OPTARG" ;; # p) priority="$OPTARG" ;;
u) url="$OPTARG" ;; u) url="$OPTARG" ;;
U) url_title="$OPTARG" ;; U) url_title="$OPTARG" ;;
d) device="$OPTARG" ;; d) device="$OPTARG" ;;
*) >&2 echo "Invalid option $OPTARG" *) >&2 echo "Invalid option $OPTARG"
exit 1 exit 1
;; ;;
esac esac
done done
shift $((OPTIND-1)) shift $((OPTIND-1))
. "$HOME/.private/config/pushover.conf" #USER=...
#TOKEN=...
eval "$(gpg --decrypt $secret_file)"
curl -s \ curl -s \
--form-string "token=$TOKEN" \ --form-string "token=$TOKEN" \
--form-string "user=$USER" \ --form-string "user=$USER" \
--form-string "title=$title" \ --form-string "title=$title" \
--form-string "message=$message" \ --form-string "message=$message" \
--form-string "url=$url" \ --form-string "url=$url" \
--form-string "url_title=$url_title" \ --form-string "url_title=$url_title" \
--form-string "device=$device" \ --form-string "device=$device" \
https://api.pushover.net/1/messages.json https://api.pushover.net/1/messages.json

16
bin/qrsnap Executable file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Snaps a screenshot of a QR code and decodes it.
#
# Requires: zbar, maim (on linux)
set -e
unset CDPATH
TMP=$(mktemp _qrXXX)
case $OSTYPE in
darwin*) screencapture -i -x -t png "$TMP" ;;
linux*) maim -s "$TMP" ;;
*) >&2 echo "Help!"; exit 1 ;;
esac
(( $? == 0 )) && zbarimg -q --raw "$TMP"
rm -f "$TMP"

10
bin/rehash Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env zsh
# Rehashes all (rb|py|nod|lua|*)env environments
for env in $XDG_CONFIG_HOME/*env(N); do
local bin=${env##*/}
if _is_callable $bin; then
echo "Rehashing $bin"
$bin rehash
fi
done

View file

@ -1,13 +1,27 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# set -e
unset CDPATH
# Find and replace by a given list of files. # Find and replace by a given list of files.
# #
# replace foo bar **/*.rb # replace foo bar **/*.rb
find_this="$1"; shift main() {
replace_with="$1"; shift local search="$1"
local replace="$2"
shift 2
items=( $(ag -l --nocolor "$find_this" "$@") ) for item in $(ag -l --nocolor "$search" "$@"); do
for item in ${items[@]}; do sed -i "s%${search//%/\\%}%${replace//%/\\%}%g" "$item"
sed -i "s/${find_this}/${replace_with}/g" "$item" done
done }
# Show matches
ag "$1"
# Are you sure?
read -rp "Confirm search+replace? (y/n)?" choice
case $choice in
y|Y) main "$@" ;;
*) >&2 echo "Aborted"; exit ;;
esac

View file

@ -73,10 +73,7 @@ class CurrencyCache():
return None return None
def _set(self, key, value): def _set(self, key, value):
self.cache[key] = { self.cache[key] = {'time': datetime.now().timestamp(), 'value': value}
'time': datetime.now().timestamp(),
'value': value
}
def _request_currency_rate(url=API_URL, *args): def _request_currency_rate(url=API_URL, *args):

View file

@ -2,54 +2,54 @@
set -e set -e
(( $# > 0 )) || exit (( $# > 0 )) || exit
# Displays the time since $1 in a human readable format (e.g. 4h 25m 55s). If given a # Displays the time since $1 in a human readable format (e.g. 4h 25m 55s). If
# file, the modified time is used. If $1 == "--", then this script acts as a converter, # given a file, the modified time is used. If $1 == "--", then this script acts
# converting $2 into human a readable format, e.g. since -- 72 #=> 1m 12s # as a converter, converting $2 into human a readable format, e.g. since -- 72
# #=> 1m 12s
# TODO: A help fallback # TODO: A help fallback
# TODO: Options parsing # TODO: Options parsing?
# `date` on OSX does not have the --date parameter # `date` on OSX does not have the --date parameter
date=date date=date
if [[ $OSTYPE == darwin* ]]; then if [[ $OSTYPE == darwin* ]]; then
date=gdate date=gdate
elif ! command -v $date >/dev/null; then elif ! command -v $date >/dev/null; then
echo "Unsupported system" echo "Unsupported system"
exit 1 exit 1
fi fi
# If given a file, give time since last modification # If given a file, give time since last modification
(( $# == 1 )) && [[ -f $@ ]] && arg=reference || arg=date (( $# == 1 )) && [[ -f $1 ]] && arg=reference || arg=date
args="$*"
if [[ $1 == -- ]]; then if [[ $1 == -- ]]; then
t="$2" t="$2"
else else
now=$(${date} +%s) now=$($date +%s)
then=$(${date} --$arg="$*" +%s) then=$($date --$arg="$*" +%s)
t=$(( $now - $then )) t=$(( now - then ))
fi fi
# Bash doesn't support floating point arithmetic like zsh does, therefore: # Bash doesn't support floating point arithmetic like zsh does, therefore:
bc <<EOF bc <<EOF
define abs(i) { define abs(i) {
if (i < 0) return (-i) if (i < 0) return (-i)
return (i) return (i)
} }
t = abs($t) t = abs($t)
weeks = t / 60 / 60 / 24 / 7 weeks = t / 60 / 60 / 24 / 7
days = t / 60 / 60 / 24 % 7 days = t / 60 / 60 / 24 % 7
hours = t / 60 / 60 % 24 hours = t / 60 / 60 % 24
minutes = t / 60 % 60 minutes = t / 60 % 60
seconds = t % 60 seconds = t % 60
if (weeks > 0) print weeks, "w " if (weeks > 0) print weeks, "w "
if (days > 0) print days, "d " if (days > 0) print days, "d "
if (hours > 0) print hours, "h " if (hours > 0) print hours, "h "
if (minutes > 0) print minutes, "m " if (minutes > 0) print minutes, "m "
print seconds, "s" print seconds, "s"
EOF EOF

View file

@ -10,12 +10,12 @@
result=$(echo "$@" | aspell -a | tail -n-2) result=$(echo "$@" | aspell -a | tail -n-2)
if [[ "$result" == '*' ]]; then if [[ "$result" == '*' ]]; then
echo "$@" echo "$@"
else else
words=$(echo "$result" | sed $'s/[:,] /\\\n/g' | tail -n +2) words=$(echo "$result" | sed $'s/[:,] /\\\n/g' | tail -n +2)
if (( $(wc -l <<< "$words") > 1 )) && command -v 'fzf' >/dev/null; then if (( $(wc -l <<< "$words") > 1 )) && command -v 'fzf' >/dev/null; then
fzf <<< "$words" fzf <<< "$words"
else else
echo "$words" echo "$words"
fi fi
fi fi

233
bin/sup Normal file
View file

@ -0,0 +1,233 @@
#!/usr/bin/env zsh
# Upload to various file hosts
# colors
c0=$(tput sgr0)
c1=$(tput setaf 1)
c2=$(tput setaf 2)
# filename to use for screenshots
local_temp=$(mktemp)
# screenshot functions
cap_fullscreen() {
local_file="$local_temp.png"
mv $local_temp $local_file
maim -u $local_file
}
cap_selection() {
local_file="$local_temp.png"
mv $local_temp $local_file
maim -s -u $local_file
}
cap_window() {
mv $local_temp $local_temp.png
maim -i $(xprop -root _NET_ACTIVE_WINDOW | grep -o '0x.*') --hidecursor
}
# delay
delay_seconds='0'
# hosts and shorteners
host='uguu'
shortener=
hosts='uguu teknik 0x0 mixtape ptpb lewd'
shorteners='waaai 0x0'
##
usage() {
cat <<EOF
Upload to various file hosts
Usage: ${0:A:t} [options]
Options:
-d SECS Delay the screenshot by the specified number of seconds.
-f Take a fullscreen screenshot.
-h Show this help message.
-l URL Upload the file at the provided URL.
-o Select a host to use. Can be uguu, teknik, 0x0, ptpb, mixtape or lewd.
-p PATH Custom path to save the image to. Saves the image as "%Y-%m-%d %H-%M-%S.png".
-s Take a selection screenshot.
-S Select a shortener to use. Can be waaai or 0x0.
-u FILE Upload a file.
-w Take a screenshot of the current window.
-x Do not notify dbus, update the log, or modify the clipboard.
EOF
}
delay() {
for (( i=delay_seconds; i>0; --i )); do
echo "$i..."
sleep 1
done
}
screenshot() {
if [[ $doFullscreen ]]; then
cap_fullscreen
elif [[ $doSelection ]]; then
cap_selection &>/dev/null
if ! [[ -s $local_file ]]; then
$(rm "$local_file" 2> /dev/null)
exit
fi
elif [[ $doWindow ]]; then
cap_window
elif [[ $doURL ]]; then
local urlext
if [[ -f /usr/share/mime/globs ]]; then
urlext=$(curl -sf --head "${remoteURL}" | grep 'Content-Type: ' | head -1 | grep -Po '(?<=\ )[^\;]*')
urlext=$(echo "${urlext}" | sed -e "s/\\r//")
urlext=$(cat /usr/share/mime/globs | grep "${urlext}" | sort -r | head -1 | grep -Po '(?<=\.)[^\n]*')
else
urlext="$(basename ${remoteURL})"
urlext=${urlext#*.}
fi
local_file="${local_temp}.${urlext}"
$(curl -sf "${remoteURL}" > "${local_file}")
fi
}
upload() {
for (( i = 1; i <= 3; i++ )); do
echo -n "Try #${i}... "
case "${host}" in
teknik) hostURL='https://api.teknik.io/v1/Upload' ;;
0x0) hostURL='https://0x0.st/' ;;
uguu) hostURL='https://uguu.se/api.php?d=upload-tool' ;;
ptpb) hostURL='https://ptpb.pw/' ;;
mixtape) hostURL='https://mixtape.moe/upload.php' ;;
lewd) hostURL='https://lewd.se/api.php?d=upload-tool' ;;
esac
case "${shortener}" in
waaai) shortenerURL='https://api.waa.ai/shorten' ;;
0x0) shortenerURL='http://0x0.st/' ;;
ptpb) shortenerURL='https://ptpb.pw/u'
esac
if [ "${host}" = 'uguu' ]; then
uploadResult="$(curl -sf -F file="@${local_file}" "${hostURL}")"
elif [ "${host}" = '0x0' ]; then
uploadResult="$(curl -sf -F file="@${local_file}" "${hostURL}")"
elif [ "${host}" = 'teknik' ]; then
uploadResult="$(curl -sf -F file="@${local_file}" "${hostURL}")"
uploadResult="${uploadResult##*url\":\"}"
uploadResult="${uploadResult%%\"*}"
elif [ "${host}" = 'mixtape' ]; then
uploadResult="$(curl -sf -F files[]="@${local_file}" "${hostURL}")"
uploadResult="$(echo "${uploadResult}" | grep -Eo '"url":"[A-Za-z0-9]+.*",' | sed 's/"url":"//;s/",//')"
uploadResult="$(echo "${uploadResult//\\\//\/}")"
elif [ "${host}" = 'ptpb' ]; then
uploadResult="$(curl -sf -F c="@${local_file}" "${hostURL}")"
uploadResult="${uploadResult##*url: }"
uploadResult="${uploadResult%%$'\n'*}"
elif [ "${host}" = 'lewd' ]; then
uploadResult="$(curl -sf -F file="@${local_file}" "${hostURL}")"
fi
if [ "${shortener}" = 'waaai' ]; then
tempResult="$(curl -sf -F url="${uploadResult}" "${shortenerURL}")"
shortCode="${tempResult##*short_code\":\"}"
shortCode="${shortCode%%\"*}"
shortenerResult="https://waa.ai/${shortCode}"
shortenerExtension="${tempResult##*extension\":}"
shortenerExtension="${shortenerExtension%%\}*}"
if [[ $shortenerExtension == true ]]; then
shortenerExtension=${shortenerExtension##\"}
shortenerExtension=${shortenerExtension%%\"}
shortenerResult="${shortenerResult}.${shortenerExtension}"
fi
elif [[ $shortener == '0x0' ]]; then
shortenerResult="$(curl -sf -F shorten="${uploadResult}" "${shortenerURL}")"
elif [[ $shortener == 'ptpb' ]]; then
shortenerResult="$(curl -sf -F c=@- "${shortenerURL}" <<< "${uploadResult}")"
fi
if [[ $shortener ]]; then
finalResult="$shortenerResult"
else
finalResult="$uploadResult"
fi
if [[ $? == 0 ]]; then
# copy to clipboard, log, and notify (unless $noComms is set)
if [ ! "${noComms}" ]; then
echo -n "${finalResult}" | xclip -selection primary
echo -n "${finalResult}" | xclip -selection clipboard
echo "$(date +"%D %R") | "${file}" | "${finalResult}"" >> ~/.uguush.log
notify-send 'uguu~' "${finalResult}"
fi
fi
echo "[${c2}OK${c0}]"
echo "File has been uploaded: ${finalResult}"
# if we took a screenshot, remove the temporary file
if [[ -z $doFile ]]; then
rm $local_file
fi
exit
done
}
path() {
if [[ $saveToPath == true ]]; then
cp $local_file "$pathToSave/$(basename "$local_file")"
fi
}
##
while getopts :d:fho:p:su:wxS:l: opt; do
case $opt in
d) # set delay value
delay_seconds="$OPTARG" ;;
f) # take fullscreen shot
doFullscreen='true' ;;
h) # print help
usage
exit 0 ;;
o) # set host
[[ "${hosts}" =~ "$OPTARG" ]] && host="$OPTARG" || exit 1 ;;
s) # take shot of selection
doSelection='true' ;;
u) # change $file to the specified file with -u
doFile='true'
local_file="$OPTARG" ;;
w) # take shot of current window
doWindow='true' ;;
x) # do not notify dbus, update log, or modify clipboard
noComms='true' ;;
S) # set shortener
[[ $shorteners =~ "$OPTARG" ]] && shortener="$OPTARG" || exit 1 ;;
l) # set url to upload
doURL='true'
remoteURL="${OPTARG}" ;;
p) # set path to save file
saveToPath='true'
pathToSave="${OPTARG}" ;;
*) # print help and EXIT_FAILURE
usage
exit 1 ;;
esac
done
# show usage if no arguments are given
if (( $# < 1 )); then
usage
exit 1
fi
delay
screenshot
path
upload
# if the program doesn't exit at the for-loop, the upload failed
>&2 echo 'File was not uploaded, did you specify a valid filename?'
exit 1

View file

@ -11,6 +11,7 @@ Usage: time-in Copenhagen "Toronto, ON" Vancouver
import sys import sys
import json import json
import os
from base64 import b64encode from base64 import b64encode
from datetime import datetime from datetime import datetime
from urllib import request from urllib import request
@ -23,7 +24,7 @@ URL_BASE = "https://maps.googleapis.com/maps/api/"
URL_TZ = URL_BASE + "timezone/json?location={},{}&timestamp={}" URL_TZ = URL_BASE + "timezone/json?location={},{}&timestamp={}"
URL_GEOCODE = URL_BASE + "geocode/json?address={}" URL_GEOCODE = URL_BASE + "geocode/json?address={}"
CACHE_FILE = "/tmp/time-in" CACHE_FILE = "{}/timein".format(os.environ.get("XDG_CACHE_HOME") or "/tmp")
CACHE = {} CACHE = {}

View file

@ -1,16 +1,16 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Upload file to transfer.sh # Upload file/stdin to transfer.sh
url="https://transfer.sh" url="https://transfer.sh"
tmpfile=$(mktemp -t transferXXX) tmpfile=$(mktemp -t transferXXX)
if [[ -t 0 ]]; then if [[ -t 0 ]]; then
basefile=$(basename "$1" | sed -e 's/[^a-zA-Z0-9._-]/-/g') basefile=$(basename "$1" | sed -e 's/[^a-zA-Z0-9._-]/-/g')
curl --progress-bar --upload-file "$1" "$url/$basefile" >> $tmpfile curl --progress-bar --upload-file "$1" "$url/$basefile" >>"$tmpfile"
else else
curl --progress-bar --upload-file "-" "$url/$1" >> $tmpfile curl --progress-bar --upload-file "-" "$url/$1" >>"$tmpfile"
fi fi
cat $tmpfile cat "$tmpfile"
rm -f $tmpfile rm -f "$tmpfile"
# vim:set ft=sh: # vim:set ft=sh:

48
bin/uri
View file

@ -4,46 +4,34 @@
Encode/decode url strings in stdin or the given file(s). Encode/decode url strings in stdin or the given file(s).
""" """
import getopt import argparse
import fileinput import fileinput
import sys
import os
try: try:
from urllib.parse import quote_plus, quote, unquote_plus, unquote from urllib.parse import quote_plus, quote, unquote_plus, unquote
except ImportError: except ImportError:
from urllib import quote_plus, quote, unquote_plus, unquote from urllib import quote_plus, quote, unquote_plus, unquote
def usage(): def main():
"""Print out help for this script""" opts = argparse.ArgumentParser(description="Make text URI-safe by encoding/decoding input")
print("Usage: {} [-edEDh] file1[ file2[ ...]]".format(os.path.basename(sys.argv[0]))) opts.add_argument('file', type=str, nargs='*', help='File(s) to encode/decode')
opts.add_argument('-e', '--encode', action='store_true', help='Use encoder')
opts.add_argument('-E', '--encode-plus', action='store_true', help='Use encoder, but encode spaces as pluses')
def main(commands): opts.add_argument('-d', '--decode', action='store_true', help='Use decoder')
try: opts.add_argument('-D', '--decode-plus', action='store_true', help='Use decoder, but decode pluses as spaces')
optlist, args = getopt.getopt(sys.argv[1:], 'edEDh') args = opts.parse_args()
sys.argv = [sys.argv[0]] + args
except getopt.GetoptError as err:
print(err)
sys.exit(1)
action = quote action = quote
for flag, _ in optlist: if args.decode:
if flag in commands: action = unquote
action = commands[flag] elif args.decode_plus:
elif flag == '-h': action = unquote_plus
usage() elif args.encode_plus:
sys.exit() action = quote_plus
else:
assert False, "unhandled option"
print(action("\n".join([line for line in fileinput.input()]).strip())) text = [line for line in fileinput.input(args.file)]
print(action("\n".join(text).strip()))
if __name__ == '__main__': if __name__ == '__main__':
main({ main()
"-e": quote,
"-E": quote_plus,
"-d": unquote,
"-D": unquote_plus
})

46
bin/zzz
View file

@ -3,28 +3,28 @@
# If -f, then put computer to sleep. # If -f, then put computer to sleep.
# Otherwise, lock screen and turn off monitor. # Otherwise, lock screen and turn off monitor.
if [[ $1 = -h ]]; then if [[ $1 == -h ]]; then
bin=${0##*/} bin=${0##*/}
echo "Usage: $bin [-f]" echo "Usage: $bin [-f]"
echo echo
echo " $bin # put display to sleep" echo " $bin # put display to sleep"
echo " $bin -f # put computer to sleep" echo " $bin -f # put computer to sleep"
elif [[ $1 = -f ]]; then elif [[ $1 == -f ]]; then
echo "Going to sleep..." echo "Going to sleep..."
case $OSTYPE in case $OSTYPE in
darwin*) pmset sleepnow ;; darwin*) pmset sleepnow ;;
linux*) systemctl suspend ;; linux*) systemctl suspend ;;
esac esac
else else
echo "Shutting my eyes..." echo "Shutting my eyes..."
case $OSTYPE in case $OSTYPE in
darwin*) sleep 1; pmset displaysleepnow ;; darwin*) sleep 1; pmset displaysleepnow ;;
linux*) linux*)
if command -v slock >/dev/null; then if command -v slock >/dev/null; then
pgrep slock >/dev/null || slock & pgrep slock >/dev/null || slock &
fi fi
sleep 1 sleep 1
xset dpms force off xset dpms force off
;; ;;
esac esac
fi fi

143
bootstrap
View file

@ -1,143 +0,0 @@
#!/usr/bin/env bash
# My (idempotent) dotfile deployment script.
#
# You pass the directories of "topics" to it to install them. It will:
# 1. symlink $topic/.* => ~/ and $topic/.(config|local)/* => ~/.\1/
# 2. run $topic/install the first time
# 3. run $topic/update on consecutive runs
CWD="$(cd "$(dirname "$0")" && pwd)"
pushd "$CWD" >/dev/null
set -e
shopt -s nullglob
# shellcheck source=shell/common.sh
source "shell/common.sh"
#
blue="\033[34m"
magenta="\033[35m"
green="\033[32m"
orange="\033[33m"
grey="\033[36m"
red="\033[31m"
nc="\033[0m"
#
_run() {
local cmd="${*//$DOTFILES\//}"
cmd="${cmd//$HOME/~}"
local clr=""
case $cmd in
*~/.bin/) clr="${magenta}" ;;
ln*) clr="" ;;
mkdir*) clr="${blue}" ;;
*) clr="${orange}"
esac
echo -e " $PREFIX$clr$cmd$nc"
[[ $DRYRUN ]] || { $@ 2>&1 | sed 's/^/ => /'; }
}
_link() {
if [[ -f "$2" || ( -d "$2" && -f "$2/${1##*/}" ) ]]; then
if [[ $yes ]]; then
[[ $yes = 1 ]] && choice=y || choice=n
else
read -r -n 1 -p "? ${1##*/} exists in $2 -- overwrite? [y/n] " choice
echo
fi
case $choice in
y|Y) _run rm -rf "$2"
PREFIX="${red}OVERWRITE:${nc} " _run ln -svf "$1" "$2"
;;
*) PREFIX="${red}ABORTED:${nc} " DRYRUN=1 _run ln -svf "$1" "$2"
;;
esac
else
_run ln -svf "$1" "$2"
fi
}
##
export SERVER=
install=1
link=1
update=1
yes=0
while getopts iuldypLSUh opt; do
case $opt in
d) DRYRUN=1 ;;
i) install= ;;
l) link= ;;
p) yes= ;;
u) update= ;;
y) yes=1 ;;
S) SERVER=1 ;;
U) install=
yes=0
;;
L) update=
install=
yes=0
;;
h) cat <<EOL
Usage: $0 [-iuldypLSU] [topic1] [topic2] [...]
-i Don't run install scripts
-u Don't run update scripts
-l Don't symlink dotfiles
-d Do a dry run (only output commands, no changes)
-y Overwrite conflicts (no prompts)
-p Prompt on file conflict (to overwrite)
-L Refresh links; the same as -ui
-S Server mode; only install the bare minimum
-U Update mode; run update scripts only
EOL
exit
;;
*) >&2 echo "Aborted."
exit 1 ;;
esac
done
shift $((OPTIND-1))
#
ENABLED_DIR=".enabled.d"
for topic in "${@:-$(ls -1 "$ENABLED_DIR" | sed 's%_%/%')}"; do
[[ -d $topic ]] || continue
echo -e "${green}${topic}${nc}"
tpath="$CWD/$topic"
if [[ $link ]]; then
# Symlink dotfiles from topics (2 levels deep) + parent (1 level deep)
for file in "$tpath"{,../}/.[a-zA-Z]*; do
if [[ -d "$file" && "${file##*/}" == .@(config|local) ]]; then
for subfile in "$file"/*; do
base="$HOME/${file##*/}/"
[[ -d $base ]] || _run mkdir -p "$base"
_link "$subfile" "$base"
done
elif [[ -e $file ]]; then
_link "$file" "$HOME/"
fi
done
fi
# Link topic to .enabled.d
linkpath="${ENABLED_DIR}/${topic//\//_}"
if [[ -h "$linkpath" ]]; then
[[ "$update" && -x ${linkpath}/update ]] && _run "$tpath/update"
else
# Register topic as 'enabled'
_run ln -svf "$tpath" "$linkpath"
# Run install script
[[ "$install" && -x ${linkpath}/install ]] && _run "$tpath/install"
fi
done
popd >/dev/null
# vim:set ft=sh:

41
bootstrap.sh Executable file
View file

@ -0,0 +1,41 @@
#!/usr/bin/env bash
# dotfiles bootstrapper
#
# Installs zsh & git, then clones this repo to ~/.dotfiles. This script is
# intended to be run remotely, via curl:
#
# bash <(curl -s https://raw.githubusercontent.com/hlissner/dotfiles/master/bootstrap.sh)
export DOTFILES=~/.dotfiles
set -e
_msg() { printf "\r\033[2K\033[0;32m[ .. ] %s\033[0m\n" "$*"; }
_uncallable() { ! command -v "$1" >/dev/null; }
if _uncallable zsh || _uncallable git; then
# NOTE Macos has both already
_msg "Installing git and/or zsh"
if [[ -f /etc/arch-release ]]; then
sudo pacman --needed --noconfirm -S git zsh
elif [[ -f /etc/debian_version ]]; then
sudo apt-get update && sudo apt-get install -y git zsh
fi
fi
if [[ ! -d ~/.dotfiles ]]; then
_msg "Deploying dotfiles repository..."
if [[ $USER == hlissner ]]; then
dfrepo=git@github.com:hlissner/dotfiles.git
else
dfrepo=https://github.com/hlissner/dotfiles
fi
git clone --recursive "$dfrepo" "$DOTFILES"
fi
#
_msg
_msg "And done!"
_msg
_msg "Use $DOTFILES/deploy to install your dotfiles, I suggest you begin"
_msg "with 'base/arch' or 'base/macos'."

45
clean
View file

@ -1,45 +0,0 @@
#!/usr/bin/env bash
# A symlink cleanup script.
#
# Usage: clean [-du]
#
# Options:
# -d Do a dry run (only output commands, no changes)
# -u Uninstall all enabled topics
_run() {
if [[ $DRYRUN ]]; then
echo "$@"
else
$@
fi
}
uninstall=
while getopts du opt; do
case $opt in
d) DRYRUN=1 ;;
u) uninstall=1 ;;
*) >&2 echo "Invalid argument: $OPTARG"
exit 1
;;
esac
done
shift $((OPTIND-1))
# Remove enabled topics
if [[ $uninstall ]]; then
_run rm -v "$(cd "$(dirname "$0")" && pwd -P)"/.enabled.d/*
fi
# Remove dead links
shopt -s nullglob
links=( $HOME/.* $HOME/.*/* )
for link in "${links[@]}"; do
if [[ -h "$link" && ! -e "$link" ]]; then
_run rm -vf "$link"
fi
done
# vim:set ft=sh:

199
deploy Executable file
View file

@ -0,0 +1,199 @@
#!/usr/bin/env zsh
# Dotfile manager
#
# By Henrik Lissner <henrik@lissner.net>
# https://github.com/hlissner/dotfiles
#
# Requires: git, zsh
source "${0:A:h}/env"
SEP='.'
# helpers
function echo-debug { echo "$@" | sed -e "s%$HOME%~%g" -e "s%$DOTFILES%.%g"; }
function echo-info { printf "\r\033[2K\033[0;34m[ .. ]\033[0m %s\n" "$*"; }
function echo-skip { printf "\r\033[2K\033[38;05;240m[SKIP]\033[0m %s\n" "$*"; }
function echo-ok { printf "\r\033[2K\033[0;32m[ OK ]\033[0m %s\n" "$*"; }
function echo-fail { printf "\r\033[2K\033[0;31m[FAIL]\033[0m %s\n" "$*"; }
function _exec { ${DRYRUN:+echo-debug} $@; return ${DRYRUN:+1}; }
function _topic-do {
if [[ -e "$1/_init" ]]; then
if [[ ! -x "$1/_init" ]]; then
echo-fail "$1's init script isn't executable"
return 1
fi
export TOPIC=$1
pushd -q $1
_exec ./_init $2
popd -q
return $?
fi
}
function _topics {
local topics=( "$DOTFILES_DATA"/*.topic(N) )
echo ${${${topics[@]#$DOTFILES_DATA/}%.topic}/$SEP//}
}
# For _init scripts
function topic-enabled-p { [[ -L "$(topic-path $1)" ]] }
function topic-path { echo "$DOTFILES_DATA/${1/\//$SEP}.topic" }
function mklink {
if [[ $1 == '-s' ]]; then
local dosudo=1
shift
fi
local flags="-sv${OVERWRITE:+f}"
local srcs=( ${@:1:-1} )
local dest=${@[-1]}
if [[ $dest == */ && ! -d $dest ]]; then
mkdir -p $dest
elif [[ ! -d ${dest%/*} ]]; then
mkdir -p ${dest%/*}
fi
for lk in ${srcs[@]}; do
local src
case $lk in
/*) src=$lk ;;
.) src="$(topic-path $TOPIC)" ;;
*) src="$(topic-path $TOPIC)/$lk" ;;
esac
if [[ -d $src ]]; then
if [[ $dest != */ && -d $dest && -L $dest ]]; then
${dosudo:+sudo} rm -fv $dest
fi
fi
_exec ${dosudo:+sudo} ln $flags $src $dest
done
}
function init {
declare -f $1 >/dev/null || return 1
echo-info "$TOPIC.init.$1: start"
$1
local retval=$?
echo-ok "$TOPIC.init.$1: done"
return $retval
}
# deploy functions
function topic-init {
for topic in $@; do
if [[ ! -d $topic ]]; then
echo-fail "$topic doesn't exist!"
continue
fi
echo-ok "$topic"
local tpath="$DOTFILES/$topic"
local tsympath="$(topic-path $topic)"
if [[ -d "$topic/bin" ]]; then
export path=( $tpath/bin $path )
echo-ok "$topic: added $topic/bin to PATH, temporarily"
fi
if [[ $LINK ]] || ! topic-enabled-p $topic; then
local op=install
OVERWRITE=1 mklink $tpath $tsympath
_topic-do $topic link
fi
if [[ -z $INHIBIT_INIT ]]; then
_topic-do $topic ${FORCE_OP:-${op:-update}}
if [[ $op == install && $? != 0 ]]; then
topic-remove $topic
fi
fi
done
}
function topic-remove {
for topic in $@; do
if [[ ! -d $topic ]]; then
echo-fail "$topic doesn't exist"
continue
elif ! topic-enabled-p $topic; then
echo-fail "$topic isn't enabled"
continue
fi
[[ $INHIBIT_INIT ]] || _topic-do $topic clean
_exec rm -f "$(topic-path $topic)" && \
echo-ok "Removed $topic" || \
echo-fail "Couldn't remove $topic"
done
}
function clean {
local paths=( $XDG_CACHE_HOME $XDG_CONFIG_HOME $XDG_DATA_HOME $XDG_BIN_HOME )
local links=( ~/.*(-@DN) ${^paths}/**(-@DN))
if [[ ${#links[@]} > 1 ]]; then
echo-info "Removing dead dotfile symlinks..."
for link in "${links[@]}"; do
[[ -e $link ]] || _exec rm -fv "$link"
done
else
echo-ok "No dead symlinks in HOME"
fi
# Remove empty dotfile folders
local dirs=( ${^paths}/**(N/^F) ~/.*(N/^F) )
if [[ ${#dirs[@]} > 1 ]]; then
echo-info "Removing empty dotfile directories..."
for dir in "${dirs[@]}"; do
_exec rmdir "$dir" && echo-ok "Deleted ${dir/$HOME/~}"
done
else
echo-ok "No empty directories in HOME"
fi
}
## Bootstrap
if [[ $ZSH_EVAL_CONTEXT != *:file ]]; then
while getopts acdehlLit opt; do
case $opt in
a) TARGETS="$(_topics)" ;;
c) CLEAN=1 ;;
d) REMOVE=1 ;;
L) LIST=1 ;;
l) export LINK=1 ;&
i) export INHIBIT_INIT=1 ;;
t) export DRYRUN=1 ;;
h) cat <<EOL
Usage: ${0:A:t} [-acdlLit] [TOPIC...]
-a Target all enabled topics (ignores TOPIC args)
-c Afterwards, remove dead symlinks & empty dot-directories in $HOME.
Can be used alone.
-d Disable & unlink topic(s)
-l Only enable & relink topic(s) (implies -i)
-L List enabled topics
-i Do not run install/update/clean init scripts
-t Do a test run; do not actually do anything
EOL
exit ;;
*) >&2 echo-fail "Aborted."
exit 1 ;;
esac
done
shift $((OPTIND-1))
if [[ $LIST ]]; then
_topics | tr ' ' $'\n'
else
pushd -qL "$DOTFILES"
if [[ $REMOVE ]]; then
topic-remove ${TARGETS:-$@}
else
topic-init ${TARGETS:-$@}
fi
[[ $CLEAN ]] && clean
popd -q
fi
fi
# vim:set ft=sh:

25
dev/go/_init Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env zsh
source ${0:A:h}/../../deploy
source env.zsh
install() {
case $(_os) in
macos) brew install go ;;
arch) pacaur --needed --noconfirm -S go ;;
esac
update
}
update() {
go get -u github.com/nsf/gocode
go get -u github.com/motemen/gore
go get -u golang.org/x/tools/cmd/guru
go get -u golang.org/x/tools/cmd/gorename
}
# link() {}
# clean() {}
init "$@"

4
dev/go/env.zsh Normal file
View file

@ -0,0 +1,4 @@
export GOPATH="$XDG_DATA_HOME/go:$HOME/work/go"
# Adds $GOPATH/bin's to PATH
path=( `printf '%s/bin\n' ${(@s/:/)GOPATH}` $path )

22
dev/haskell/_init Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env zsh
source ${0:A:h}/../../deploy
source env.zsh
install() {
case $(_os) in
macos) brew install stack ghc ;;
arch) pacaur --needed --noedit --noconfirm -S ghc stack-static ;;
esac
stack config set system-ghc --global true
stack setup && stack install ShellCheck ghc-mod
}
update() {
stack update
}
# link() {}
# clean() {}
init "$@"

2
dev/haskell/env.zsh Normal file
View file

@ -0,0 +1,2 @@
export STACK_ROOT=$XDG_DATA_HOME/stack
path=( ~/.cabal/bin $path )

19
dev/java/_init Executable file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env zsh
source ${0:A:h}/../../deploy
source env.zsh
install() {
# TODO Install android SDK
case $(_os) in
macos) brew cask install java gradle ;;
arch) pacaur --needed --noedit --noconfirm -S jdk8-openjdk gradle ;;
esac
}
# update() {}
# link() {}
# clean() {}
init "$@"

Some files were not shown because too many files have changed in this diff Show more