box
This commit is contained in:
parent
fa53788c7a
commit
31e15f38d2
22
LICENSE
22
LICENSE
|
@ -1,22 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2016-2021 Henrik Lissner.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
128
README.md
128
README.md
|
@ -1,128 +0,0 @@
|
||||||
[![Made with Doom Emacs](https://img.shields.io/badge/Made_with-Doom_Emacs-blueviolet.svg?style=flat-square&logo=GNU%20Emacs&logoColor=white)](https://github.com/hlissner/doom-emacs)
|
|
||||||
[![NixOS Unstable](https://img.shields.io/badge/NixOS-unstable-blue.svg?style=flat-square&logo=NixOS&logoColor=white)](https://nixos.org)
|
|
||||||
|
|
||||||
**Hey,** you. You're finally awake. You were trying to configure your OS declaratively, right? Walked right into that NixOS ambush, same as us, and those dotfiles over there.
|
|
||||||
|
|
||||||
<img src="/../screenshots/alucard/fakebusy.png" width="100%" />
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<span><img src="/../screenshots/alucard/desktop.png" height="178" /></span>
|
|
||||||
<span><img src="/../screenshots/alucard/rofi.png" height="178" /></span>
|
|
||||||
<span><img src="/../screenshots/alucard/tiling.png" height="178" /></span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
------
|
|
||||||
|
|
||||||
| | |
|
|
||||||
|-|-|
|
|
||||||
| **Shell:** | zsh + zgen |
|
|
||||||
| **DM:** | lightdm + lightdm-mini-greeter |
|
|
||||||
| **WM:** | bspwm + polybar |
|
|
||||||
| **Editor:** | [Doom Emacs][doom-emacs] (and occasionally [vim]) |
|
|
||||||
| **Terminal:** | st |
|
|
||||||
| **Launcher:** | rofi |
|
|
||||||
| **Browser:** | firefox |
|
|
||||||
| **GTK Theme:** | [Ant Dracula](https://github.com/EliverLara/Ant-Dracula) |
|
|
||||||
|
|
||||||
-----
|
|
||||||
|
|
||||||
## Quick start
|
|
||||||
|
|
||||||
1. Yoink the latest build of [NixOS 21.05][nixos].
|
|
||||||
2. Boot into the installer.
|
|
||||||
3. Do your partitions and mount your root to `/mnt` ([for example](hosts/kuro/README.org))
|
|
||||||
4. Install these dotfiles:
|
|
||||||
5. `nix-shell -p git nixFlakes`
|
|
||||||
6. `git clone https://github.com/hlissner/dotfiles /mnt/etc/nixos`
|
|
||||||
7. Install NixOS: `nixos-install --root /mnt --flake /mnt/etc/nixos#XYZ`, where
|
|
||||||
`XYZ` is [the host you want to install](hosts/). Use `#generic` for a
|
|
||||||
simple, universal config, or create a sub-directory in `hosts/` for your device. See [host/kuro] for an example.
|
|
||||||
8. Reboot!
|
|
||||||
9. Change your `root` and `$USER` passwords!
|
|
||||||
|
|
||||||
## Management
|
|
||||||
|
|
||||||
And I say, `bin/hey`. [What's going on?](http://hemansings.com/)
|
|
||||||
|
|
||||||
```
|
|
||||||
Usage: hey [global-options] [command] [sub-options]
|
|
||||||
|
|
||||||
Available Commands:
|
|
||||||
check Run 'nix flake check' on your dotfiles
|
|
||||||
gc Garbage collect & optimize nix store
|
|
||||||
generations Explore, manage, diff across generations
|
|
||||||
help [SUBCOMMAND] Show usage information for this script or a subcommand
|
|
||||||
rebuild Rebuild the current system's flake
|
|
||||||
repl Open a nix-repl with nixpkgs and dotfiles preloaded
|
|
||||||
rollback Roll back to last generation
|
|
||||||
search Search nixpkgs for a package
|
|
||||||
show [ARGS...]
|
|
||||||
ssh HOST [COMMAND] Run a bin/hey command on a remote NixOS system
|
|
||||||
swap PATH [PATH...] Recursively swap nix-store symlinks with copies (or back).
|
|
||||||
test Quickly rebuild, for quick iteration
|
|
||||||
theme THEME_NAME Quickly swap to another theme module
|
|
||||||
update [INPUT...] Update specific flakes or all of them
|
|
||||||
upgrade Update all flakes and rebuild system
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-d, --dryrun Don't change anything; preform dry run
|
|
||||||
-D, --debug Show trace on nix errors
|
|
||||||
-f, --flake URI Change target flake to URI
|
|
||||||
-h, --help Display this help, or help for a specific command
|
|
||||||
-i, -A, -q, -e, -p Forward to nix-env
|
|
||||||
```
|
|
||||||
|
|
||||||
## Frequently asked questions
|
|
||||||
|
|
||||||
+ **Why NixOS?**
|
|
||||||
|
|
||||||
Because declarative, generational, and immutable configuration is a godsend
|
|
||||||
when you have a fleet of computers to manage.
|
|
||||||
|
|
||||||
+ **How do you manage secrets?**
|
|
||||||
|
|
||||||
With [agenix].
|
|
||||||
|
|
||||||
+ **How do I change the default username?**
|
|
||||||
|
|
||||||
1. Set the `USER` environment variable the first time you run `nixos-install`:
|
|
||||||
`USER=myusername nixos-install --root /mnt --flake /path/to/dotfiles#XYZ`
|
|
||||||
2. Or change `"hlissner"` in modules/options.nix.
|
|
||||||
|
|
||||||
+ **Why did you write bin/hey?**
|
|
||||||
|
|
||||||
I envy Guix's CLI and want similar for NixOS, but its toolchain is spread
|
|
||||||
across many commands, none of which are as intuitive: `nix`,
|
|
||||||
`nix-collect-garbage`, `nixos-rebuild`, `nix-env`, `nix-shell`.
|
|
||||||
|
|
||||||
I don't claim `hey` is the answer, but everybody likes their own brew.
|
|
||||||
|
|
||||||
+ **How 2 flakes?**
|
|
||||||
|
|
||||||
Would it be the NixOS experience if I gave you all the answers in one,
|
|
||||||
convenient place?
|
|
||||||
|
|
||||||
No. Suffer my pain:
|
|
||||||
|
|
||||||
+ [A three-part tweag article that everyone's read.](https://www.tweag.io/blog/2020-05-25-flakes/)
|
|
||||||
+ [An overengineered config to scare off beginners.](https://github.com/nrdxp/nixflk)
|
|
||||||
+ [A minimalistic config for scared beginners.](https://github.com/colemickens/nixos-flake-example)
|
|
||||||
+ [A nixos wiki page that spells out the format of flake.nix.](https://nixos.wiki/wiki/Flakes)
|
|
||||||
+ [Official documentation that nobody reads.](https://nixos.org/learn.html)
|
|
||||||
+ [Some great videos on general nixOS tooling and hackery.](https://www.youtube.com/channel/UC-cY3DcYladGdFQWIKL90SQ)
|
|
||||||
+ A couple flake configs that I
|
|
||||||
[may](https://github.com/LEXUGE/nixos)
|
|
||||||
[have](https://github.com/bqv/nixrc)
|
|
||||||
[shamelessly](https://git.sr.ht/~dunklecat/nixos-config/tree)
|
|
||||||
[rummaged](https://github.com/utdemir/dotfiles)
|
|
||||||
[through](https://github.com/purcell/dotfiles).
|
|
||||||
+ [Some notes about using Nix](https://github.com/justinwoo/nix-shorts)
|
|
||||||
+ [What helped me figure out generators (for npm, yarn, python and haskell)](https://myme.no/posts/2020-01-26-nixos-for-development.html)
|
|
||||||
+ [What y'all will need when Nix drives you to drink.](https://www.youtube.com/watch?v=Eni9PPPPBpg)
|
|
||||||
|
|
||||||
|
|
||||||
[doom-emacs]: https://github.com/hlissner/doom-emacs
|
|
||||||
[vim]: https://github.com/hlissner/.vim
|
|
||||||
[nixos]: https://releases.nixos.org/?prefix=nixos/unstable/
|
|
||||||
[host/kuro]: https://github.com/hlissner/dotfiles/tree/master/hosts/kuro
|
|
||||||
[agenix]: https://github.com/ryantm/agenix
|
|
34
backup.nix
Normal file
34
backup.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
# Assumes the remote borg backup server has already been initialized
|
||||||
|
# borg init --encryption-key=repokey-blake2 -rsh 'ssh -i /run/keys/id_ed25519_borgbase' 20779@hk-s020.rsync.net:<borg-archive>
|
||||||
|
services.borgbackup.jobs = {
|
||||||
|
backupTaskwarriorRsync = {
|
||||||
|
paths = [ "/var/lib/taskserver" ];
|
||||||
|
doInit = true;
|
||||||
|
repo = "20779@hk-s020.rsync.net:taskwarrior" ;
|
||||||
|
encryption = {
|
||||||
|
mode = "repokey-blake2";
|
||||||
|
passCommand = "cat /run/keys/rsync";
|
||||||
|
};
|
||||||
|
environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
|
||||||
|
compression = "auto,lzma";
|
||||||
|
startAt = "weekly";
|
||||||
|
extraArgs = "--remote-path=borg1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.borgbackup.jobs = {
|
||||||
|
backupShaarliRsync = {
|
||||||
|
paths = [ "/var/www/shaarli-config/data/datastore.php" "/var/www/shaarli-config/config" "/var/www/shaarli-config/.json.config" ];
|
||||||
|
doInit = true;
|
||||||
|
repo = "20779@hk-s020.rsync.net:shaarli" ;
|
||||||
|
encryption = {
|
||||||
|
mode = "repokey-blake2";
|
||||||
|
passCommand = "cat /run/keys/rsync";
|
||||||
|
};
|
||||||
|
environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
|
||||||
|
compression = "auto,lzma";
|
||||||
|
startAt = "weekly";
|
||||||
|
extraArgs = "--remote-path=borg1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
xdotool mousedown 1
|
|
||||||
sleep 0.01
|
|
||||||
xdotool mouseup 1
|
|
||||||
sleep 0.01
|
|
||||||
done
|
|
|
@ -1,47 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Script: bspc-focus
|
|
||||||
# Author: Henrik Lissner
|
|
||||||
# Usage:
|
|
||||||
# bspc-focus [-m] (west|south|north|east)
|
|
||||||
# bspc-focus south
|
|
||||||
# bspc-focus -m west
|
|
||||||
#
|
|
||||||
# Focus the next window in direction. If -m is supplied, jump to the next
|
|
||||||
# monitor in that direction.
|
|
||||||
#
|
|
||||||
# The behavior of the base 'bspc node -f' is odd when crossing screens. It will
|
|
||||||
# focus the last selected window on that screen, rather than the window on the
|
|
||||||
# connecting edge, which is unintuitive.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
leap=
|
|
||||||
if [[ $1 == -m ]]; then
|
|
||||||
leap=1; shift
|
|
||||||
fi
|
|
||||||
dir=$1
|
|
||||||
opposite=
|
|
||||||
|
|
||||||
case $dir in
|
|
||||||
west) opposite=east ;;
|
|
||||||
east) opposite=west ;;
|
|
||||||
north) opposite=north ;;
|
|
||||||
south) opposite=south ;;
|
|
||||||
*) >&2 echo "Not a valid direction: $dir"
|
|
||||||
exit 1
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ -n $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"
|
|
||||||
# Ensure we start at the edge of the window we arrived from
|
|
||||||
while bspc node -f "$opposite.local"; do :; done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -i zsh -p jshon
|
|
||||||
|
|
||||||
# Script: bspc-presel
|
|
||||||
# Author: Henrik Lissner
|
|
||||||
# Usage:
|
|
||||||
# bspc-presel RATIO
|
|
||||||
# bspc-presel 0.2
|
|
||||||
#
|
|
||||||
# Wrote this to invert the ratio on east/south-bound preselections. In English
|
|
||||||
# that means bspc node -p 0.2 should resize the preselection to 20%, whether or
|
|
||||||
# not it's on the west or east side of the window (or north or south side),
|
|
||||||
# which isn't the case by default.
|
|
||||||
#
|
|
||||||
# NOTE: We use zsh for this because bash chokes on float arithmetic.
|
|
||||||
|
|
||||||
ratio="$1"
|
|
||||||
case "$(bspc query -T -n focused | jshon -e presel -e splitDir | tr -d \")" in
|
|
||||||
west|north) bspc node -o $ratio ;;
|
|
||||||
east|south) bspc node -o $(( 1.0 - ratio )) ;;
|
|
||||||
esac
|
|
|
@ -1,101 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -i zsh -p jshon wmutils-core
|
|
||||||
|
|
||||||
# Script: bspc-subtract-presel
|
|
||||||
# Author: Henrik Lissner (w/ credit to @Chrysostomus)
|
|
||||||
# Usage:
|
|
||||||
# bspc-resize-to-presel
|
|
||||||
#
|
|
||||||
# (Adapted from Chrysostomus/bspwm-scripts/bin/resizetopresel.sh)
|
|
||||||
#
|
|
||||||
# This script resizes the current window by "subtracting" the bspwm preselection
|
|
||||||
# on the current node. In English, that means this will reduce the window's
|
|
||||||
# width by 20%:
|
|
||||||
#
|
|
||||||
# bspc node -p east -o 0.2 && bspc-subtract-presel
|
|
||||||
#
|
|
||||||
# NOTE: We use zsh for this because bash chokes on float arithmetic.
|
|
||||||
|
|
||||||
# Check if the brother node is a receptacle
|
|
||||||
if [[ $(bspc query -T -n @brother/ | jshon -e client) = null ]]; then
|
|
||||||
# Yep, it's a receptacle. Get the real dimensions
|
|
||||||
eval $(grep "window_gap" ~/.config/bspwm/rc.d/theme | tr -cd [0-9])
|
|
||||||
# Get orientation
|
|
||||||
wattr xywh $(pfw) | read focused_x focused_y focused_width focused_height
|
|
||||||
receptacle_y=$(bspc query -T -n @brother/ | jshon -e rectangle -e y)
|
|
||||||
if [[ "$focused_y" -eq "$receptacle_y" ]]; then
|
|
||||||
receptacle_width=$(bspc query -T -n @brother/ | jshon -e rectangle -e width)
|
|
||||||
receptacle_x=$(bspc query -T -n @brother/ | jshon -e rectangle -e x)
|
|
||||||
# receptacle and window have the same height, so they are side by side
|
|
||||||
if [[ receptacle_x -gt focused_x ]]; then
|
|
||||||
echo "receptacle is right of the window"
|
|
||||||
# get the true window dimension
|
|
||||||
true_dim=$(( receptacle_width + gap ))
|
|
||||||
# kill the repectacle
|
|
||||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
|
||||||
# resize the window
|
|
||||||
bspc node @east -r -$true_dim || bspc node @west -r +$true_dim
|
|
||||||
else
|
|
||||||
echo "receptacle is left of the window"
|
|
||||||
# get the true window dimension
|
|
||||||
true_dim=$(( receptacle_width + gap ))
|
|
||||||
# kill the repectacle
|
|
||||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
|
||||||
# resize the window
|
|
||||||
bspc node @west -r +$true_dim || bspc node @east -r -$true_dim
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
receptacle_height=$(bspc query -T -n @brother/ | jshon -e rectangle -e height)
|
|
||||||
# width is necessarily equal if height is not, because the nodes are
|
|
||||||
# brothers Window are on the top of each other
|
|
||||||
if [[ receptacle_y -gt focused_y ]]; then
|
|
||||||
echo "receptacle is below the window"
|
|
||||||
# get the true window dimension
|
|
||||||
true_dim=$(( receptacle_height + gap))
|
|
||||||
# kill the repectacle
|
|
||||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
|
||||||
# resize the window
|
|
||||||
bspc node @south -r -$true_dim || bspc node @north -r +$true_dim
|
|
||||||
else
|
|
||||||
echo "receptacle is above the window"
|
|
||||||
# get the true window dimension
|
|
||||||
true_dim=$(( receptacle_height + gap))
|
|
||||||
# kill the repectacle
|
|
||||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
|
||||||
# resize the window
|
|
||||||
bspc node @north -r +$true_dim || bspc node @south -r -$true_dim
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo $true_dim
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If the focused window is not preselected, do nothing
|
|
||||||
[[ "$(bspc query -T -n focused | jshon -e presel)" == null ]] && exit 0
|
|
||||||
|
|
||||||
dir=$(bspc query -T -n focused | jshon -e presel -e splitDir | tr -d \")
|
|
||||||
ratio=$(bspc query -T -n focused | jshon -e presel -e splitRatio)
|
|
||||||
case "$dir" in
|
|
||||||
west)
|
|
||||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e width)
|
|
||||||
bspc node @west -r +$((${cur}*${ratio})) || \
|
|
||||||
bspc node @east -r -$((${cur}*${ratio}))
|
|
||||||
;;
|
|
||||||
east)
|
|
||||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e width)
|
|
||||||
bspc node @east -r -$((${cur}*(1.0-${ratio}))) || \
|
|
||||||
bspc node @west -r +$((${cur}*${ratio}))
|
|
||||||
;;
|
|
||||||
|
|
||||||
north)
|
|
||||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e height)
|
|
||||||
bspc node @north -r +$((${cur}*${ratio})) || \
|
|
||||||
bspc node @south -r -$((${cur}*${ratio}))
|
|
||||||
;;
|
|
||||||
south)
|
|
||||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e height)
|
|
||||||
bspc node @south -r -$(( ${cur} * (1.0 - ${ratio}) )) || \
|
|
||||||
bspc node @north -r +$(( ${cur} * ${ratio} ))
|
|
||||||
esac
|
|
||||||
|
|
||||||
bspc node -p cancel
|
|
|
@ -1,48 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Script: bspc-swap
|
|
||||||
# Author: Henrik Lissner
|
|
||||||
# Usage:
|
|
||||||
# bspc-swap [-m] (west|south|north|east)
|
|
||||||
# bspc-swap south
|
|
||||||
# bspc-swap -m west
|
|
||||||
#
|
|
||||||
# Swaps current window with the window in a direction. If -m is set, move window
|
|
||||||
# to the next monitor in that direction.
|
|
||||||
#
|
|
||||||
# The behavior of the base 'bspc node -s' is odd when crossing screens. It will
|
|
||||||
# swaps with the last selected window on that screen, rather than the window on
|
|
||||||
# the connecting edge, which is unintuitive.
|
|
||||||
|
|
||||||
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 [[ -n $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 [[ -n $(bspc query -M -m "$dir") ]]; then
|
|
||||||
bspc node -m "$dir"
|
|
||||||
bspc node -f "$old_id"
|
|
||||||
fi
|
|
||||||
fi
|
|
385
bin/hey
385
bin/hey
|
@ -1,385 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -p ruby_2_7 -i "ruby -S" --quiet
|
|
||||||
|
|
||||||
DESC = <<~DESC
|
|
||||||
Nix's CLI has a poor user story, in my opinion. It could be better; Guix is a
|
|
||||||
good role model here. I wrote this script to abstract the more common
|
|
||||||
workflows, like rebuilding (nixos-rebuild), cleaning up (nix-collect-garbage),
|
|
||||||
package/env management (nix-env), updating, rolling back, etc. As well as some
|
|
||||||
utility operations (like managing generations, building remotely, or swapping
|
|
||||||
themes on the fly).
|
|
||||||
|
|
||||||
Because I can go months without shaving yaks in NixOS, exact flags or details
|
|
||||||
are often and easily forgotten. This spares me that fumbling phase and also
|
|
||||||
serves as a reference.
|
|
||||||
|
|
||||||
Note: `hey` can also be used as a shortcut for nix-env:
|
|
||||||
|
|
||||||
hey -q
|
|
||||||
hey -iA nixos.htop
|
|
||||||
hey -e htop
|
|
||||||
DESC
|
|
||||||
|
|
||||||
require 'shellwords'
|
|
||||||
require 'optparse'
|
|
||||||
|
|
||||||
module Hey
|
|
||||||
extend self
|
|
||||||
Command = Struct.new(:name, :desc, :args, :opts, :fn)
|
|
||||||
|
|
||||||
@@opts = {}
|
|
||||||
@@alias = {}
|
|
||||||
@@commands = {}
|
|
||||||
@@cli = nil
|
|
||||||
def self.defcmd names, &block
|
|
||||||
names = (names.kind_of?(Array) ? names : [names]).map(&:to_s)
|
|
||||||
names.drop(1).each { |n| @@alias[n] = names.first }
|
|
||||||
cli = Command.new names.first, [], []
|
|
||||||
cli.opts = OptionParser.new do |opt|
|
|
||||||
opt.banner = "Usage: #{opt.program_name} #{cli.name} [options]"
|
|
||||||
opt.separator "\nOptions:"
|
|
||||||
opt.on_tail('-h', '--help', 'Prints this help') { puts opt; exit }
|
|
||||||
end
|
|
||||||
@@cli = cli
|
|
||||||
fn = block.call cli
|
|
||||||
cli.fn = lambda do |args|
|
|
||||||
begin
|
|
||||||
cli.opts.banner +=
|
|
||||||
(cli.args ? " #{cli.args.join ' '}" : "") +
|
|
||||||
(cli.desc ? "\n\n#{cli.desc[0]}\n\n#{cli.desc[1..].join "\n"}" : "")
|
|
||||||
cli.opts.order!(args, into: @@opts)
|
|
||||||
fn.call args
|
|
||||||
ensure @@cli = nil end
|
|
||||||
end
|
|
||||||
@@commands[cli.name] = @@cli
|
|
||||||
end
|
|
||||||
def self.opts(*args) @@cli.opts.on(*args) end
|
|
||||||
def self.args(*args) @@cli.args = args end
|
|
||||||
def self.desc(*args) @@cli.desc = args end
|
|
||||||
def self.sh(args, sudo: false, noerror: false)
|
|
||||||
raise ArgumentError unless args.kind_of?(Array)
|
|
||||||
args.unshift('sudo') if sudo
|
|
||||||
args.compact!
|
|
||||||
if @@opts[:dryrun]
|
|
||||||
print "#{args}\n"
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
result = system "#{args.shelljoin} 2>&1"
|
|
||||||
exit($?.exitstatus) unless noerror or result
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
def self.rebuild(*args, sudo: false, host: nil)
|
|
||||||
host ||= ENV['HOST'] || `hostname`.rstrip
|
|
||||||
sh ["nixos-rebuild",
|
|
||||||
"--flake", "#{@@opts[:flake]}##{host}",
|
|
||||||
"--option", "pure-eval", "no",
|
|
||||||
*args], sudo: sudo
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
defcmd :repl do
|
|
||||||
desc "Open a nix-repl with nixpkgs and dotfiles preloaded"
|
|
||||||
lambda do |args|
|
|
||||||
tempfile = '/tmp/dotfiles-repl.nix'
|
|
||||||
File.write('/tmp/dotfiles-repl.nix', "(builtins.getFlake \"#{@@opts[:flake]}\")")
|
|
||||||
begin
|
|
||||||
sh ["nix", "repl", "<nixpkgs>", tempfile, *args]
|
|
||||||
ensure
|
|
||||||
File.delete tempfile
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd [:check, :ch] do
|
|
||||||
desc "Run 'nix flake check' on your dotfiles"
|
|
||||||
lambda do |args|
|
|
||||||
sh ["nix", "flake", "check", @@opts[:flake]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd :show do
|
|
||||||
desc "[ARGS...]", "Run 'nix flake show' on your dotfiles"
|
|
||||||
lambda do |args|
|
|
||||||
sh ["nix", "flake", "show", @@opts[:flake]]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd :theme do
|
|
||||||
desc 'Quickly swap to another theme module'
|
|
||||||
args "THEME_NAME"
|
|
||||||
lambda do |args|
|
|
||||||
ENV["THEME"] = args.shift
|
|
||||||
rebuild "--fast", "test"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd [:test, :t] do
|
|
||||||
desc "Quickly rebuild, for quick iteration"
|
|
||||||
lambda do |args|
|
|
||||||
rebuild "--fast", "test", *args
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd [:rebuild, :re] do
|
|
||||||
desc "Rebuild the current system's flake"
|
|
||||||
opts '--build-host HOST', "Where to build the flake"
|
|
||||||
opts '--target-host HOST', "Where to deploy the built derivations"
|
|
||||||
opts '--host HOST', "The target nixosConfiguration to build"
|
|
||||||
opts '--user', "Rebuild as user, rather than root"
|
|
||||||
opts '--fast', "Equivalent to --no-build-nix --show-trace for quick rebuilding"
|
|
||||||
lambda do |args|
|
|
||||||
Dir.chdir(@@opts[:flake]) do
|
|
||||||
args = ["switch"] unless args.length > 0
|
|
||||||
rebuild(*(@@opts[:"build-host"] ? ["--build-host", @@opts[:"build-host"]] : []),
|
|
||||||
*(@@opts[:"target-host"] ? ["--target-host", @@opts[:"target-host"]] : []),
|
|
||||||
@@opts[:fast] ? "--fast" : nil,
|
|
||||||
@@opts[:debug] ? "--show-trace" : nil,
|
|
||||||
*args,
|
|
||||||
sudo: !@@opts[:user],
|
|
||||||
host: @@opts[:host])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd :rollback do
|
|
||||||
desc "Roll back to last generation"
|
|
||||||
lambda do |_args|
|
|
||||||
rebuild "--rollback", "switch"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd [:update, :u] do
|
|
||||||
desc "Update specific flakes or all of them"
|
|
||||||
args "[INPUT...]"
|
|
||||||
lambda do |args|
|
|
||||||
if args.empty?
|
|
||||||
puts "Updating all flakes.."
|
|
||||||
sh ["nix", "flake", "update", @@opts[:flake]]
|
|
||||||
else
|
|
||||||
puts "Trying to update flakes: #{args.join ' '}"
|
|
||||||
sh ["nix", "flake", "lock"]
|
|
||||||
.concat(args.map { |f| [ "--update-input", f ]}.flatten)
|
|
||||||
.concat([@@opts[:flake]])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd [:upgrade, :up] do
|
|
||||||
desc "Update all flakes and rebuild system"
|
|
||||||
lambda do |_args|
|
|
||||||
update
|
|
||||||
rebuild :switch
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd [:search, :s] do
|
|
||||||
desc "Search nixpkgs for a package"
|
|
||||||
lambda do |args|
|
|
||||||
sh ["nix", "search", "nixpkgs", *args]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd :swap do
|
|
||||||
desc "Recursively swap nix-store symlinks with copies (or back).",
|
|
||||||
"The purpose is so you can have copies of your dotfiles that can be modified in",
|
|
||||||
"place (so you can iterate on them quickly instead of 'hey re'ing between",
|
|
||||||
"changes). Run again to restore the old link(s).\n",
|
|
||||||
"Warning: backup your copies, or they will be destroyed when restored!"
|
|
||||||
args "PATH", "[PATH...]"
|
|
||||||
lambda do |args|
|
|
||||||
for target in args
|
|
||||||
if File.directory? target
|
|
||||||
files = Dir.glob("#{target}/**/*.nix-store-backup")
|
|
||||||
if files.length > 0
|
|
||||||
puts "There are swapped files here. Unswapping!"
|
|
||||||
call :swap, *files
|
|
||||||
else
|
|
||||||
puts "Swapping files in #{target}"
|
|
||||||
call :swap, *(Dir.glob("#{target}/**/*")
|
|
||||||
.select { |f| File.symlink? f }
|
|
||||||
.select { |l| File.readlink(l).match '^/nix/store/' })
|
|
||||||
end
|
|
||||||
elsif File.file? "#{target}.nix-store-backup"
|
|
||||||
puts "Unswapping #{target}"
|
|
||||||
sh [:mv, '-i', "#{target}.nix-store-backup", target]
|
|
||||||
elsif File.file? target
|
|
||||||
puts "Swapping #{target}"
|
|
||||||
sh [:mv, target, "#{target}.nix-store-backup"]
|
|
||||||
sh [:cp, "#{target}.nix-store-backup", target]
|
|
||||||
else
|
|
||||||
puts "Not a valid target: #{target}"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd :gc do
|
|
||||||
desc "Garbage collect & optimize nix store"
|
|
||||||
opts "-a", "--all", "GC both the user and system profiles"
|
|
||||||
opts "-s", "--system", "Only GC the system profile"
|
|
||||||
lambda do |_args|
|
|
||||||
if @@opts[:all] or @@opts[:system]
|
|
||||||
puts "Cleaning up your system profile..."
|
|
||||||
sh %w{nix-collect-garbage -d}, sudo: true
|
|
||||||
sh %w{nix-store --optimise}, sudo: true
|
|
||||||
# Clear out left-over secrets. The switch-to-configuration call below will
|
|
||||||
# regenerate them.
|
|
||||||
if File.exists?("/run/secrets/*")
|
|
||||||
sh %w{rm -rf /run/secrets/*}, sudo: true
|
|
||||||
end
|
|
||||||
# nix-collect-garbage is a Nix tool, not a NixOS tool. It won't delete old
|
|
||||||
# boot entries until you do a nixos-rebuild (which means we'll always have
|
|
||||||
# 2 boot entries at any time). Instead, we properly delete them by
|
|
||||||
# reloading the current environment.
|
|
||||||
sh %w{nix-env --delete-generations old --profile /nix/var/nix/profiles/system}, sudo: true
|
|
||||||
sh %w{/nix/var/nix/profiles/system/bin/switch-to-configuration switch}, sudo: true
|
|
||||||
end
|
|
||||||
if @@opts[:all] or not @@opts[:system]
|
|
||||||
puts "Cleaning up your user profile..."
|
|
||||||
sh %w{nix-collect-garbage -d}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defcmd :ssh do
|
|
||||||
desc "Run a bin/hey command on a remote NixOS system",
|
|
||||||
"If COMMAND is one of switch, test, or boot (if omitted, 'test' is assumed),",
|
|
||||||
"that host's config is built locally and then copied to the remote over ssh.",
|
|
||||||
"This will prompt you for your root password, as it temporarily opens root ssh",
|
|
||||||
"access (via your existing ssh key) to the remote -- which is immediately removed",
|
|
||||||
"upon completion.",
|
|
||||||
"",
|
|
||||||
"If COMMAND is anything else, it merely runs 'nix run github:hlissner/dotfiles",
|
|
||||||
"-- COMMAND' on the rmeote."
|
|
||||||
args "HOST", "[COMMAND]"
|
|
||||||
opts '--host HOST', "The nixos config to build and deploy to HOST"
|
|
||||||
lambda do |args|
|
|
||||||
target, command = args.take(2)
|
|
||||||
command ||= "test"
|
|
||||||
if command.match(/switch|test|boot/)
|
|
||||||
puts "Enabling root ssh access on #{target}. Enter root password for remote system:"
|
|
||||||
if sh ["ssh", "-t", target,
|
|
||||||
"sudo mkdir -p /root/.ssh && sudo cp -f ~/.ssh/authorized_keys /root/.ssh/"],
|
|
||||||
noerror: true
|
|
||||||
begin
|
|
||||||
puts "Building #{@@opts[:flake]}##{@@opts[:host] || target} for #{target}"
|
|
||||||
call "rebuild", ["--user",
|
|
||||||
"--host", @@opts[:host] || target,
|
|
||||||
"--build-host", "localhost",
|
|
||||||
"--target-host", "root@#{target}",
|
|
||||||
command]
|
|
||||||
ensure
|
|
||||||
puts "Undoing root ssh access on #{target}"
|
|
||||||
sh ["ssh", "-t", "root@#{target}", "rm -f /root/.ssh/authorized_keys"]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
command = "nix run github:hlissner/dotfiles -- #{command}"
|
|
||||||
puts "Running '#{command}' on #{target}"
|
|
||||||
sh ["ssh", "-t", target, command]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO Generalize this to nix profiles
|
|
||||||
defcmd [:generations, :gen] do
|
|
||||||
desc "Explore, manage, diff across generations"
|
|
||||||
opts '--diff FROM TO', "Diff profiles FROM with TO (numbers)"
|
|
||||||
opts '-r', '--remove PROFILE', "Delete PROFILE from history"
|
|
||||||
lambda do |args|
|
|
||||||
profile = "/nix/var/nix/profiles/system"
|
|
||||||
case args.shift
|
|
||||||
when "diff"
|
|
||||||
from, to = *args
|
|
||||||
if from == to
|
|
||||||
puts "Comparing the same profile! Aborting..."
|
|
||||||
exit 1
|
|
||||||
elsif [from, to].compact.select do |gen|
|
|
||||||
File.exists? "#{profile}-#{gen}-link" or
|
|
||||||
puts "Generation #{gen} does not exist!"
|
|
||||||
end.length != [from, to].compact.length
|
|
||||||
exit 2
|
|
||||||
end
|
|
||||||
from = from ? "#{profile}-#{from}-link" : profile
|
|
||||||
to = to ? "#{profile}-#{to}-link" : profile
|
|
||||||
fromDevs = `nix-store -q --references #{from}`.split
|
|
||||||
toDevs = `nix-store -q --references #{to}`.split
|
|
||||||
puts (fromDevs - toDevs).map { |d| "\e[31m-#{d}\e[0m" }
|
|
||||||
puts (toDevs - fromDevs).map { |d| "\e[32m+#{d}\e[0m" }
|
|
||||||
when /ls|list/
|
|
||||||
sh ["nix-env", "--list-generations", "--profile", profile], sudo: true
|
|
||||||
when "remove"
|
|
||||||
sh ["nix-env", "--delete-generations", "--profile", profile, *args], sudo: true
|
|
||||||
when "switch"
|
|
||||||
puts "Targeted rollback not supported yet" # TODO Is this true?
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class UsageError < StandardError; end
|
|
||||||
defcmd [:help, :h] do
|
|
||||||
desc "Show usage information for this script or a subcommand"
|
|
||||||
args "[SUBCOMMAND]"
|
|
||||||
lambda do |args|
|
|
||||||
raise UsageError unless args.first
|
|
||||||
call args.first, ["-h", *args.drop(1)]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
def self.call command, args
|
|
||||||
cmd = command.to_s
|
|
||||||
cmd = @@alias[cmd] while cmd and not @@commands.key?(cmd)
|
|
||||||
if cmd
|
|
||||||
@@commands[cmd].fn.call args
|
|
||||||
elsif command
|
|
||||||
puts "Couldn't recognize command '#{command}'"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
raise UsageError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.run args=[]
|
|
||||||
opts = OptionParser.new do |opt|
|
|
||||||
opt.banner = "Usage: hey [global-options] [command] [sub-options]\n\n" + DESC
|
|
||||||
opt.separator "\n\nAvailable Commands:"
|
|
||||||
opt.separator (@@commands.values
|
|
||||||
.reject { |c| c.desc.empty? }
|
|
||||||
.sort { |a,b| a.name <=> b.name }
|
|
||||||
.map { |c| " %-22s %s\n" % ["#{c.name} #{c.args.join ' '}",
|
|
||||||
c.desc[0]]})
|
|
||||||
opt.separator "\nOptions:"
|
|
||||||
opt.on '-d', '--dryrun', "Don't change anything; preform dry run"
|
|
||||||
opt.on '-D', '--debug', "Show trace on nix errors"
|
|
||||||
opt.on '-f', '--flake URI', "Change target flake to URI"
|
|
||||||
opt.on '-h', '--help', "Display this help, or help for a specific command"
|
|
||||||
opt.on(*%w{-i -A -q -e -p}, "Forward to nix-env") { sh ["nix-env", *ARGV]; exit }
|
|
||||||
end
|
|
||||||
opts.order!(args, into: @@opts)
|
|
||||||
if @@opts[:flake] and @@opts[:flake].include? "#"
|
|
||||||
@@opts[:flake], @@opts[:host] = @@opts[:flake].split '#'
|
|
||||||
end
|
|
||||||
if not @@opts[:flake] or @@opts[:flake].empty?
|
|
||||||
@@opts[:flake] = File.expand_path('../', File.dirname(__FILE__))
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
args.unshift("help") if @@opts[:help]
|
|
||||||
if args.length == 0
|
|
||||||
puts "Error: No command specified!"
|
|
||||||
puts
|
|
||||||
raise UsageError
|
|
||||||
else
|
|
||||||
call args.first, args.drop(1)
|
|
||||||
end
|
|
||||||
rescue UsageError
|
|
||||||
puts opts
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Hey.run ARGV.dup
|
|
72
bin/mov2gif
72
bin/mov2gif
|
@ -1,72 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -i bash -p ffmpeg gifsicle
|
|
||||||
|
|
||||||
# Uses ffmpeg to convert a video file to a gif file. Optimizes the final result
|
|
||||||
# with gifsicle.
|
|
||||||
#
|
|
||||||
# Requires: ffmpeg gifsicle
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# mov2gif some-vid.mp4 output.gif
|
|
||||||
# mov2gif -f 10 -s 00:00:10 -t 00:00:05 some-vid.mp4 output.gif
|
|
||||||
|
|
||||||
set -e
|
|
||||||
PALETTE="/tmp/palette.png"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<EOL
|
|
||||||
Usage: ${0##*/} [-fsSth] SOURCE_FILE [destfile]
|
|
||||||
|
|
||||||
-f [FPS] set frames per second
|
|
||||||
-s [hh:mm:ss] set starting time (like -ss in ffmpeg)
|
|
||||||
-S [W:H] set width/height (either can be -1 for auto)
|
|
||||||
-t [hh:mm:ss] set the duration to capture (like -t in ffmpeg)
|
|
||||||
-h this help
|
|
||||||
EOL
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() { rm -f "$PALETTE"; }
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
#
|
|
||||||
fps=30
|
|
||||||
while getopts hf:s:t:S: opt; do
|
|
||||||
case $opt in
|
|
||||||
f) fps="$OPTARG" ;;
|
|
||||||
s) start="-ss $OPTARG" ;;
|
|
||||||
S) scale=",scale=$OPTARG:flags=lanczos" ;;
|
|
||||||
t) duration="-t $OPTARG" ;;
|
|
||||||
h) usage
|
|
||||||
exit
|
|
||||||
;;
|
|
||||||
:) >&2 echo "$OPTARG requires an argument"
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
*) >&2 echo "Not a valid arg: $opt"
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $((OPTIND-1))
|
|
||||||
|
|
||||||
#
|
|
||||||
if (($# == 0)); then
|
|
||||||
>&2 echo "No movie file specified"
|
|
||||||
exit
|
|
||||||
elif [[ ! -f $1 ]]; then
|
|
||||||
>&2 echo "$1 does not exist"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
src="$1"
|
|
||||||
dest="${2:-${src%.*}.gif}"
|
|
||||||
flags="fps=${fps}$scale"
|
|
||||||
|
|
||||||
# stats_mode=full favors motion, causing the resulting palette to better
|
|
||||||
# accomodate fades and transitions.
|
|
||||||
ffmpeg -v warning $start $duration -i "file:$src" -vf "$flags,palettegen=stats_mode=full" -y "$PALETTE"
|
|
||||||
ffmpeg -v warning $start $duration -i "file:$src" -i "$PALETTE" -lavfi "$flags [x]; [x][1:v] paletteuse" -y "$dest"
|
|
||||||
|
|
||||||
gifsicle -O3 "$dest" -o "$dest"
|
|
21
bin/myip
21
bin/myip
|
@ -1,21 +0,0 @@
|
||||||
#!/usr/bin/env zsh
|
|
||||||
# Echos your local or WAN IP
|
|
||||||
|
|
||||||
if [[ $1 == -w ]]; then
|
|
||||||
wan=1
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n $wan ]]; then
|
|
||||||
dig +short myip.opendns.com @resolver1.opendns.com
|
|
||||||
else
|
|
||||||
IF=$(netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}')
|
|
||||||
if command -v ifconfig >/dev/null; then
|
|
||||||
ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'
|
|
||||||
elif command -v ip >/dev/null; then
|
|
||||||
ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'
|
|
||||||
else
|
|
||||||
>&2 echo "No easy way to grab your IP"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
86
bin/optimimg
86
bin/optimimg
|
@ -1,86 +0,0 @@
|
||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
# Optimize image files (losslessly by default)
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# imgoptim image.jpg image.png image.gif
|
|
||||||
# imgoptim directory_of_images/
|
|
||||||
# imgoptim directory_of_images/*.png
|
|
||||||
#
|
|
||||||
# Requires:
|
|
||||||
# PNGs: optipng, pngquant (lossy)
|
|
||||||
# JPGs: jpegtran, jpegoptim (lossy)
|
|
||||||
# GIFs: gifsicle
|
|
||||||
#
|
|
||||||
# Packages (same name on homebrew & arch linux)
|
|
||||||
# optipng [pngquant] libjpeg-turbo [jpegoptim] gifsicle
|
|
||||||
|
|
||||||
set -e
|
|
||||||
unset CDPATH
|
|
||||||
|
|
||||||
_usage() {
|
|
||||||
cat <<EOL
|
|
||||||
Usage: ${0:A:t} [-lh] IMAGE [IMAGE2 [IMAGE3 [...]]]
|
|
||||||
|
|
||||||
-l enable lossy compression
|
|
||||||
-h this help
|
|
||||||
EOL
|
|
||||||
}
|
|
||||||
|
|
||||||
_filesize() {
|
|
||||||
case $OSTYPE in
|
|
||||||
darwin*) stat -c%s "$1" ;;
|
|
||||||
*) stat --printf="%s" "$1" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
while getopts hl opt; do
|
|
||||||
case $opt in
|
|
||||||
h) _usage; exit;;
|
|
||||||
l) lossy=1;;
|
|
||||||
:) >&2 echo "$OPTARG requires an argument"; _usage; exit 1;;
|
|
||||||
*) >&2 echo "Not a valid arg: $opt"; _usage; exit 1;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $((OPTIND-1))
|
|
||||||
|
|
||||||
cmds=( optipng jpegtran gifsicle )
|
|
||||||
[[ -n $lossy ]] && cmds=( $cmds pngquant jpegoptim )
|
|
||||||
for cmd in ${cmds[@]}; do
|
|
||||||
if ! command -v $cmd >/dev/null; then
|
|
||||||
>&2 echo "$cmd isn't installed"
|
|
||||||
error=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ -n $error ]]; then
|
|
||||||
>&2 echo "There were errors, aborting"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
for file in $@; do
|
|
||||||
if [[ -d $file ]]; then
|
|
||||||
imgoptim $file/*
|
|
||||||
elif [[ -f $file ]]; then
|
|
||||||
pre_size=$(_filesize "$file")
|
|
||||||
case ${file##*.} in
|
|
||||||
png)
|
|
||||||
[[ -n $lossy ]] && pngquant $file
|
|
||||||
optipng -nc -nb -o7 $file
|
|
||||||
;;
|
|
||||||
gif)
|
|
||||||
gifsicle --batch --optimize=3 "$file"
|
|
||||||
;;
|
|
||||||
jpg|jpeg)
|
|
||||||
[[ -n $lossy ]] && jpegoptim --max=90 "$file"
|
|
||||||
jpegtran -copy none -optimize -progressive -outfile "$file" "$file"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
printf "Unrecognized file '$file': ignored"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
post_size=$(_filesize "$file")
|
|
||||||
perc=$(echo "((${pre_size} - ${post_size}) / ${pre_size}) * 100" | bc -l)
|
|
||||||
printf "* %s: %d => %d (%.2f%% reduction)\n" "$file" "${pre_size}" "${post_size}" "$perc"
|
|
||||||
fi
|
|
||||||
done
|
|
36
bin/optimpdf
36
bin/optimpdf
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Compress pdf files using ghostscript.
|
|
||||||
#
|
|
||||||
# Defaults to 72 dpi.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# pdfoptim SRC [TARGET] [DPI]
|
|
||||||
#
|
|
||||||
# Requires: ghostscript (gs)
|
|
||||||
|
|
||||||
optimize() {
|
|
||||||
# Adapted from Alfred Klomp's shrinkpdf script
|
|
||||||
# <http://alfredklomp.com/programming/shrinkpdf/>
|
|
||||||
gs -q -dNOPAUSE -dBATCH -dSAFER \
|
|
||||||
-sDEVICE=pdfwrite \
|
|
||||||
-dPDFSETTINGS=/screen \
|
|
||||||
-dCompatibilityLevel=1.3 \
|
|
||||||
-dEmbedAllFonts=true \
|
|
||||||
-dSubsetFonts=true \
|
|
||||||
-dAutoRotatePages=/None \
|
|
||||||
-dMonoImageResolution=$3 \
|
|
||||||
-dMonoImageDownsampleType=/Bicubic \
|
|
||||||
-dGrayImageResolution=$3 \
|
|
||||||
-dGrayImageDownsampleType=/Bicubic \
|
|
||||||
-dColorImageResolution=$3 \
|
|
||||||
-dColorImageDownsampleType=/Bicubic \
|
|
||||||
-sOutputFile="$2" \
|
|
||||||
"$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
src="$1"
|
|
||||||
dest="${2:--}"
|
|
||||||
dpi="${3:-72}"
|
|
||||||
|
|
||||||
optimize "$src" "$dest" "$dpi" || exit $?
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
rofi -show drun \
|
|
||||||
-modi drun,run \
|
|
||||||
-show-icons \
|
|
||||||
-theme theme/appmenu.rasi
|
|
|
@ -1,137 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -p ruby_2_7 rubyPackages_2_7.sqlite3 -i "ruby -S" --quiet
|
|
||||||
|
|
||||||
# Open your browser bookmarks or history in your default browser. Currently
|
|
||||||
# works with Firefox, Brave, and qutebrowser.
|
|
||||||
|
|
||||||
require 'shellwords'
|
|
||||||
require 'sqlite3'
|
|
||||||
require 'json'
|
|
||||||
require 'fileutils'
|
|
||||||
require 'cgi'
|
|
||||||
|
|
||||||
def rofi items, *args
|
|
||||||
cmd = [*%w{rofi -dmenu -theme theme/bookmarkmenu.rasi -markup-rows -multi-select -p browser -i}, *args]
|
|
||||||
IO.popen(cmd.compact.shelljoin, "r+") do |pipe|
|
|
||||||
pipe.puts items.keys.join "\n"
|
|
||||||
pipe.close_write
|
|
||||||
(pipe.gets || "").split "\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def db file, command
|
|
||||||
copy = "/tmp/browsermenu-db-#{File.basename(file)}"
|
|
||||||
begin
|
|
||||||
# Copy the sqlite database because history/bookmark info is usually small
|
|
||||||
# and may be locked by an open browser.
|
|
||||||
unless File.exists? copy
|
|
||||||
FileUtils.cp file, copy
|
|
||||||
FileUtils.chmod 0400, copy, verbose: true
|
|
||||||
end
|
|
||||||
results = []
|
|
||||||
db = SQLite3::Database.open copy
|
|
||||||
db.execute(command).each { |r| results.push r }
|
|
||||||
results
|
|
||||||
ensure
|
|
||||||
File.delete copy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def walk_json children
|
|
||||||
result = []
|
|
||||||
for c in children
|
|
||||||
if c['children']
|
|
||||||
result += walk_json c['children']
|
|
||||||
else
|
|
||||||
result.push [ c['name'], c['url'] ]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_bookmarks browser
|
|
||||||
bookmarks = []
|
|
||||||
case browser
|
|
||||||
when :firefox
|
|
||||||
# In my nixos dotfiles I hardcode the default profile to $USER.profile,
|
|
||||||
# which makes this lookup easier, but means this script won't work on any
|
|
||||||
# other system.
|
|
||||||
user = ENV['USER']
|
|
||||||
["#{ENV['HOME']}/.mozilla/firefox/#{user}.default",
|
|
||||||
"#{ENV['XDG_CONFIG_HOME']}/firefox/.mozilla/firefox/#{user}.default",
|
|
||||||
"#{ENV['XDG_DATA_HOME']}/mozilla/firefox/#{user}.default"].each do |dir|
|
|
||||||
if Dir.exists? dir
|
|
||||||
db "#{dir}/places.sqlite",
|
|
||||||
["SELECT DISTINCT mb.title, mp.url FROM moz_bookmarks mb",
|
|
||||||
"INNER JOIN moz_places mp ON mp.id = mb.fk",
|
|
||||||
"WHERE mb.type = 1 AND mb.title IS NOT NULL",
|
|
||||||
"ORDER BY mp.frecency DESC",
|
|
||||||
"LIMIT 200"].join(' ')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
when :brave
|
|
||||||
f = File.read "#{ENV['XDG_CONFIG_HOME']}/BraveSoftware/Brave-Browser/Default/Bookmarks"
|
|
||||||
data = JSON.parse f
|
|
||||||
walk_json data["roots"]["bookmark_bar"]["children"]
|
|
||||||
when :qutebrowser
|
|
||||||
bookmarks = File.readlines "#{ENV['XDG_CONFIG_HOME']}/qutebrowser/bookmarks/urls"
|
|
||||||
bookmarks.map { |s| s.strip.split(' ', 2).reverse }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_history browser
|
|
||||||
case browser
|
|
||||||
when :firefox
|
|
||||||
# In my nixos dotfiles I hardcode the default profile to $USER.profile,
|
|
||||||
# which makes this lookup easier, but means this script won't work on any
|
|
||||||
# other system.
|
|
||||||
user = ENV['USER']
|
|
||||||
["#{ENV['HOME']}/.mozilla/firefox/#{user}.default",
|
|
||||||
"#{ENV['XDG_CONFIG_HOME']}/firefox/.mozilla/firefox/#{user}.default",
|
|
||||||
"#{ENV['XDG_DATA_HOME']}/mozilla/firefox/#{user}.default"].each do |dir|
|
|
||||||
if Dir.exists? dir
|
|
||||||
return db "#{dir}/places.sqlite",
|
|
||||||
["SELECT title, url",
|
|
||||||
"FROM moz_places",
|
|
||||||
"WHERE title<>''",
|
|
||||||
"ORDER BY last_visit_date DESC"].join(' ')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return []
|
|
||||||
when :brave
|
|
||||||
db "#{ENV['XDG_CONFIG_HOME']}/BraveSoftware/Brave-Browser/Default/History",
|
|
||||||
"SELECT title, url FROM urls GROUP BY url ORDER BY last_visit_time DESC LIMIT 200"
|
|
||||||
when :qutebrowser
|
|
||||||
db "#{ENV['XDG_DATA_HOME']}/qutebrowser/history.sqlite",
|
|
||||||
["SELECT title, url FROM History",
|
|
||||||
"WHERE title != ''",
|
|
||||||
"GROUP BY url",
|
|
||||||
"ORDER BY atime DESC"].join(' ')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def list urls
|
|
||||||
items = urls.map do |x|
|
|
||||||
x.map! { |x| CGI.escapeHTML x }
|
|
||||||
[x[0].empty? ?
|
|
||||||
"<b>#{x[1]}</b>" :
|
|
||||||
"<b>#{x[0]}</b> <span size=\"x-small\">#{x[1]}</span>",
|
|
||||||
x[1]]
|
|
||||||
end.to_h
|
|
||||||
selected = rofi items
|
|
||||||
selected.map { |key| items[key] }
|
|
||||||
end
|
|
||||||
|
|
||||||
type, browser = *ARGV
|
|
||||||
browser = (browser || ENV['BROWSER']).to_sym
|
|
||||||
urls = if type == 'history'
|
|
||||||
get_history browser
|
|
||||||
else
|
|
||||||
get_bookmarks browser
|
|
||||||
end
|
|
||||||
urls = list urls
|
|
||||||
if urls.empty?
|
|
||||||
puts "No URL selected. Aborting..."
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
Process.detach fork { exec ENV['BROWSER'], *urls }
|
|
260
bin/rofi/bwmenu
260
bin/rofi/bwmenu
|
@ -1,260 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -p ruby_2_7 -i "ruby -S"
|
|
||||||
|
|
||||||
# A rofi client for vaultwarden. Similar to passmenu, but uses rofi. (Badly)
|
|
||||||
# written in ruby because data persistence and frontend logic would be a pain to
|
|
||||||
# write in bash or zsh. I'll refactor this later perhaps. Maybe.
|
|
||||||
|
|
||||||
require 'shellwords'
|
|
||||||
require 'json'
|
|
||||||
require 'optparse'
|
|
||||||
require 'uri'
|
|
||||||
require 'base64'
|
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
PersistentData = Struct.new(:path, :ttl, :pid, :data) do
|
|
||||||
DATADIR = "#{ENV['XDG_DATA_HOME']}/bwmenu"
|
|
||||||
|
|
||||||
def self.load name, ttl: nil
|
|
||||||
path = "#{DATADIR}/#{name}"
|
|
||||||
data = JSON::load(Base64.decode64(File.read(path))) if File.exists?(path)
|
|
||||||
d = PersistentData.new *(data || {}).values
|
|
||||||
d.path = path
|
|
||||||
d.ttl = ttl
|
|
||||||
d
|
|
||||||
end
|
|
||||||
|
|
||||||
def expire
|
|
||||||
File.delete(self.path) if File.exists?(self.path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def save data = nil, onfinish = nil
|
|
||||||
self.data = data if data
|
|
||||||
FileUtils.mkdir_p DATADIR unless File.directory?(DATADIR)
|
|
||||||
File.open(self.path, 'w') do |f|
|
|
||||||
f.chmod 0600
|
|
||||||
f.write Base64.encode64(self.to_h.to_json)
|
|
||||||
end
|
|
||||||
if self.pid and system("ps -f p #{self.pid}")
|
|
||||||
Process.kill self.pid
|
|
||||||
end
|
|
||||||
if self.ttl
|
|
||||||
self.pid = fork do
|
|
||||||
Signal.trap('TERM') { throw :terminate }
|
|
||||||
catch :terminate do
|
|
||||||
sleep self.ttl
|
|
||||||
end
|
|
||||||
onfinish.call(self, data) if onfinish.respond_to? :call
|
|
||||||
self.expire
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module BW
|
|
||||||
extend self
|
|
||||||
|
|
||||||
EXE = {}
|
|
||||||
def self.bin exe
|
|
||||||
EXE[exe] = `which #{exe} 2>/dev/null`.rstrip unless EXE[exe]
|
|
||||||
raise "Couldn't find #{exe} in PATH" if EXE[exe].empty?
|
|
||||||
EXE[exe]
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.sh *args, input: nil, sudo: false, nooutput: false
|
|
||||||
exe, *args = args.flatten.compact.map(&:to_s)
|
|
||||||
bin exe
|
|
||||||
cmd = [sudo ? "sudo" : nil, exe, *args.shelljoin].compact.join(' ')
|
|
||||||
$stderr.puts "$ #{cmd}"
|
|
||||||
if input
|
|
||||||
IO.popen(cmd, "r+") do |pipe|
|
|
||||||
pipe.puts input
|
|
||||||
pipe.close_write
|
|
||||||
(pipe.gets || "").rstrip unless nooutput
|
|
||||||
end
|
|
||||||
else
|
|
||||||
(`#{cmd}` || "").rstrip
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.rofi items, *args
|
|
||||||
input = items.keys.join("\n") if items
|
|
||||||
result = sh(['rofi', '-dmenu', '-markup-rows',
|
|
||||||
'-theme', 'theme/passmenu.rasi',
|
|
||||||
*args],
|
|
||||||
input: input)
|
|
||||||
if items
|
|
||||||
items[result]
|
|
||||||
else
|
|
||||||
result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.notify message, title: nil, urgency: "normal"
|
|
||||||
sh 'notify-send', '-u', urgency, '-a', "Vaultwarden", *[title, message].compact
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.error message
|
|
||||||
$stderr.puts message
|
|
||||||
notify message, urgency: 'low'
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.bw *args
|
|
||||||
sh [:bw, '--session', @@session_id, *args]
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.xclip *args, **opts
|
|
||||||
sh :xclip, '-selection', 'clipboard', *args, **opts
|
|
||||||
end
|
|
||||||
|
|
||||||
@@session = nil
|
|
||||||
@@session_id = nil
|
|
||||||
def self.run argv
|
|
||||||
opts = {}
|
|
||||||
OptionParser.new do |opt|
|
|
||||||
opt.banner = "Usage: bwmenu [options] [URL]"
|
|
||||||
opt.on '--autolock TTL', "How long to keep the vault open"
|
|
||||||
opt.on '--autoclear TTL' "How long to keep secrets in the clipboard"
|
|
||||||
opt.on '--debug', "Be more verbose"
|
|
||||||
opt.on '-f', '--field FIELD', "Extract specific field from selected entry; accepts 'whole' for whole entry"
|
|
||||||
opt.on '-o', '--output', "Write output to stdout rather than the clipboard"
|
|
||||||
opt.on '--select', "Select first entry"
|
|
||||||
opt.on '--select-if-only', "Select first entry if only entry"
|
|
||||||
opt.on '--default ID', "Highlight item with ID by default"
|
|
||||||
opt.on '-r', "Resume where you last left off"
|
|
||||||
end.parse! argv, into: opts
|
|
||||||
|
|
||||||
clipboard_ttl = opts[:autoclear] || 20
|
|
||||||
vault_ttl = opts[:autolock] || 900
|
|
||||||
|
|
||||||
@@session = PersistentData.load :session, ttl: vault_ttl
|
|
||||||
if @@session.data
|
|
||||||
sid, data = @@session.data
|
|
||||||
@@session_id = sid
|
|
||||||
else
|
|
||||||
pass = rofi nil, %w{-p Master\ Password -password -lines 0}
|
|
||||||
error "No password given. Aborting..." if pass.empty?
|
|
||||||
sid = sh [:bw, :unlock, '--raw', pass]
|
|
||||||
error "Failed to unlock vault. Aborting..." unless $?.success?
|
|
||||||
@@session_id = sid
|
|
||||||
data = JSON.parse(bw(:list, :items))
|
|
||||||
@@session.save [sid, data]
|
|
||||||
end
|
|
||||||
raise "No session ID" unless @@session_id
|
|
||||||
|
|
||||||
last = PersistentData.load :last_id
|
|
||||||
last_id, last_field = last.data if last
|
|
||||||
if opts[:r] and last_id.data
|
|
||||||
selected = data.find { |u| u['id'] == last_id }
|
|
||||||
else
|
|
||||||
select_type = opts[:"select-if-only"] ? :if_only : opts[:select]
|
|
||||||
selected = list_items data, argv.first,
|
|
||||||
default: opts[:default],
|
|
||||||
select: select_type
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
error "Nothing selected. Aborting..." if selected.empty?
|
|
||||||
last_id = selected['id']
|
|
||||||
item = show_item selected, field: opts[:field]
|
|
||||||
if not item
|
|
||||||
error "Nothing selected. Aborting..." if selected.empty?
|
|
||||||
elsif item.respond_to? :call
|
|
||||||
item.call
|
|
||||||
elsif opts[:output]
|
|
||||||
puts item.rstrip
|
|
||||||
else
|
|
||||||
notify "Copied to clipboard for #{clipboard_ttl} seconds"
|
|
||||||
xclip '-in', input: item.rstrip, nooutput: true
|
|
||||||
clipboard = PersistentData.load :clipboard, ttl: clipboard_ttl
|
|
||||||
clipboard.save(
|
|
||||||
item.rstrip,
|
|
||||||
lambda { |_, data| xclip('-in', '/dev/null') if item.rstrip == xclip('-out') }
|
|
||||||
)
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
last.save [ last_id, last_field ]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
def list_items data, query = nil, default: nil, select: false
|
|
||||||
rofiData = {}
|
|
||||||
rofiData["Sync Vault"] = lambda { notify "Sync vault", bw(:sync) },
|
|
||||||
rofiData["Open Vault in Browser"] = lambda { sh ENV['BROWSER'], bw(:config, :server) }
|
|
||||||
data = data.map do |i|
|
|
||||||
default_id = i['id'] if i['id'] == default
|
|
||||||
icon = ["", "", "", ""][i['type'] - 1]
|
|
||||||
case i['type']
|
|
||||||
when 1 # logins
|
|
||||||
urls = (i['login']['uris'] || []).filter_map do |u|
|
|
||||||
return unless u['uri']
|
|
||||||
uri = URI(u['uri'])
|
|
||||||
not i['name'].include?((uri.hostname || uri.path).downcase) and
|
|
||||||
uri.hostname || uri.path
|
|
||||||
end
|
|
||||||
subtitle = urls.join ", " if i['type'] == 1
|
|
||||||
subtitle = " <span size=\"x-small\">(#{subtitle})</span>" unless urls.empty?
|
|
||||||
when 2 # secure notes
|
|
||||||
when 3 # cards
|
|
||||||
subtitle = " <span size=\"x-small\">(#{i['card']['brand'].downcase})</span>"
|
|
||||||
when 4 # identities
|
|
||||||
end
|
|
||||||
["<span font_desc=\"Fira Code\" font_weight=\"bold\">#{icon} </span> <b>#{i['name']}</b>#{subtitle}", i]
|
|
||||||
end
|
|
||||||
case select
|
|
||||||
when :if_only
|
|
||||||
return data[0][1] if data.length == 1
|
|
||||||
when true
|
|
||||||
return data[0][1]
|
|
||||||
end
|
|
||||||
rofi rofiData.merge(data.to_h), '-p', 'Vaultwarden', '-filter', (query || "")
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_item item, field: nil
|
|
||||||
return item.to_json if field == 'whole'
|
|
||||||
preamble = {}
|
|
||||||
data = {}
|
|
||||||
case item['type']
|
|
||||||
when 1 # logins
|
|
||||||
url = item['login']['uris'][0]['uri']
|
|
||||||
preamble[" Launch #{url}"] = lambda { sh ENV['BROWSER'], url }
|
|
||||||
data['Username'] = item['login']['username']
|
|
||||||
data['Password'] = item['login']['password']
|
|
||||||
data['TOTP'] = bw :get, :totp, url if item['login']['totp']
|
|
||||||
return (data[field.capitalize] || item[field]) if field
|
|
||||||
when 2 # secure notes
|
|
||||||
data['Notes'] = item['notes']
|
|
||||||
return item[field] if field
|
|
||||||
when 3 # cards
|
|
||||||
cardInfo = item['card']
|
|
||||||
data['Card Type'] = cardInfo['brand']
|
|
||||||
data['Card Name'] = cardInfo['cardholderName']
|
|
||||||
data['Card Number'] = cardInfo['number']
|
|
||||||
data['Expiry Date'] = "#{cardInfo['expMonth']}/#{cardInfo['expYear']}"
|
|
||||||
data['Security Code'] = cardInfo['code']
|
|
||||||
return cardInfo[field] if field
|
|
||||||
when 4 # identities
|
|
||||||
item['identity'].each { |k,v| data[k] = v if v }
|
|
||||||
return item['identity'][field] if field
|
|
||||||
end
|
|
||||||
(item['fields'] || []).each do |field|
|
|
||||||
data[field['name']] = field['value']
|
|
||||||
end
|
|
||||||
maxLength = data.keys.map(&:length).max + 5
|
|
||||||
rofiData = {}
|
|
||||||
preamble.merge(data).each do |label, value|
|
|
||||||
if value.kind_of? String
|
|
||||||
valueLabel = value
|
|
||||||
valueLabel = value.gsub /./, '*' if label == 'Password'
|
|
||||||
rofiData["<span font_desc=\"Fira Code\" font_weight=\"bold\">%-#{maxLength}s</span> %s" % [label, valueLabel]] = value
|
|
||||||
else
|
|
||||||
rofiData[label] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rofi rofiData, '-p', item['name']
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
BW.run ARGV.dup
|
|
|
@ -1,11 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
cd $HOME
|
|
||||||
DIR="$(fd -L -d 4 --type d . | rofi -dmenu -i -p "~/" -theme theme/filemenu.rasi)"
|
|
||||||
if [ -d "$DIR" ]; then
|
|
||||||
cd "$DIR"
|
|
||||||
if [[ $1 == "-x" ]]; then
|
|
||||||
scratch
|
|
||||||
else
|
|
||||||
xst
|
|
||||||
fi
|
|
||||||
fi
|
|
|
@ -1,68 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Prompts for a pass entry, then for a specific field. Similar to passmenu, but
|
|
||||||
# uses rofi, and can resume from a previous session.
|
|
||||||
#
|
|
||||||
# Example: passmenu [RESUME]
|
|
||||||
|
|
||||||
ROFI_CMD='rofi -dmenu -theme theme/passmenu.rasi'
|
|
||||||
MSG_CMD='notify-send'
|
|
||||||
set -e
|
|
||||||
shopt -s nullglob globstar
|
|
||||||
|
|
||||||
for prog in xclip pass; do
|
|
||||||
if ! command -v "$prog" >/dev/null; then
|
|
||||||
>&2 echo "$prog not installed, aborting"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ $1 == -r ]]; then
|
|
||||||
resume=1; shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
url=
|
|
||||||
# Get qutebrowser's current url
|
|
||||||
win=$(xdotool getactivewindow)
|
|
||||||
if [[ -n $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
|
|
||||||
|
|
||||||
LAST_ENTRY_FILE=/tmp/_upm
|
|
||||||
if [[ -n $resume && -f $LAST_ENTRY_FILE ]]; then
|
|
||||||
entry="$(<$LAST_ENTRY_FILE)"
|
|
||||||
else
|
|
||||||
prefix=${PASSWORD_STORE_DIR-~/.password-store}
|
|
||||||
password_files=( "$prefix"/**/*.gpg )
|
|
||||||
password_files=( "${password_files[@]#"$prefix"/}" )
|
|
||||||
password_files=( "${password_files[@]%.gpg}" )
|
|
||||||
entry=$(printf "%s\n" "${password_files[@]}" | $ROFI_CMD -p "..." -filter "$url")
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z $entry ]]; then
|
|
||||||
$MSG_CMD "Error!" "Failed to select $entry"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$entry" >/tmp/_upm
|
|
||||||
secrets="$(pass show "$entry")"
|
|
||||||
if [[ -n $secrets ]]; then
|
|
||||||
fields=$(awk -F': ' 'NR>1 && !/^otpauth:/ {print $1}' <<<"$secrets")
|
|
||||||
field=$(printf "password\n%s\notp\n" "${fields[@]}" | $ROFI_CMD -p "$entry")
|
|
||||||
case $field in
|
|
||||||
password) pass -c "$entry" ;;
|
|
||||||
otp) printf "%s" "$(pass otp -c "$entry")" ;;
|
|
||||||
*) printf "%s" "$(awk -v "key=$field:" '$1 == key {print $2}' <<<"$secrets")" | xclip -selection clipboard -in ;;
|
|
||||||
esac
|
|
||||||
$MSG_CMD "Success!" "Copied <b>$entry/$field</b> to clipboard for 45s"
|
|
||||||
else
|
|
||||||
$MSG_CMD "Error!" "Failed to retrieve $entry"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
rofi_command="rofi -theme theme/powermenu.rasi"
|
|
||||||
|
|
||||||
### Options ###
|
|
||||||
power_off="\tShutdown"
|
|
||||||
reboot="\tReboot"
|
|
||||||
lock="\tLock"
|
|
||||||
suspend="鈴\tSleep"
|
|
||||||
log_out="\tLogout"
|
|
||||||
# Variable passed to rofi
|
|
||||||
options="$power_off\n$reboot\n$lock\n$suspend\n$log_out"
|
|
||||||
|
|
||||||
case "$(echo -e "$options" | $rofi_command -dmenu -selected-row 2)" in
|
|
||||||
$power_off)
|
|
||||||
systemctl poweroff
|
|
||||||
;;
|
|
||||||
$reboot)
|
|
||||||
systemctl reboot
|
|
||||||
;;
|
|
||||||
$lock)
|
|
||||||
zzz
|
|
||||||
;;
|
|
||||||
$suspend)
|
|
||||||
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause
|
|
||||||
systemctl suspend
|
|
||||||
;;
|
|
||||||
$log_out)
|
|
||||||
bspc quit
|
|
||||||
;;
|
|
||||||
esac
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
rofi -show window \
|
|
||||||
-show-icons \
|
|
||||||
-theme theme/windowmenu.rasi
|
|
26
bin/scratch
26
bin/scratch
|
@ -1,26 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Toggle a scratch terminal window. A scratch terminal is a disposable terminal
|
|
||||||
# for one-off, quick commands that don't warrant a dedicated terminal.
|
|
||||||
|
|
||||||
SCRID=scratch
|
|
||||||
CMD=${1:-'tmux new-session -A -s scratch -n scratch'}
|
|
||||||
focused=$(xdotool getactivewindow)
|
|
||||||
scratch=$(xdotool search --onlyvisible --classname $SCRID)
|
|
||||||
if [[ -n $scratch ]]; then
|
|
||||||
if [[ $focused == $scratch ]]; then
|
|
||||||
xdotool windowkill $scratch
|
|
||||||
else
|
|
||||||
xdotool windowactivate $scratch
|
|
||||||
fi
|
|
||||||
elif command -v urxvt >/dev/null; then
|
|
||||||
urxvt -name $SCRID \
|
|
||||||
-e $SHELL -c "$CMD"
|
|
||||||
elif command -v xst >/dev/null; then
|
|
||||||
xst -t $SCRID -n $SCRID -c $SCRID \
|
|
||||||
-f "$(xrdb -query | grep 'scratch\.font' | cut -f2)" \
|
|
||||||
-e $SHELL -c "$CMD"
|
|
||||||
else
|
|
||||||
>&2 echo "No shell to launch the scratch terminal with"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
16
bin/scrcap
16
bin/scrcap
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -i bash -p maim slop
|
|
||||||
|
|
||||||
# A script that takes a screenshot (prompts you for what region/window to
|
|
||||||
# capture) and stores it in the clipboard.
|
|
||||||
|
|
||||||
tmp=$(mktemp)
|
|
||||||
trap "rm -f '$tmp'" EXIT
|
|
||||||
|
|
||||||
# Delay for long enough that we can refocus the targeted window
|
|
||||||
if maim --delay=${2:-1} -us >"$tmp"; then
|
|
||||||
xclip -selection clipboard -t image/png "$tmp" &&
|
|
||||||
notify-send "Screenshot saved" "Copied image to clipboard"
|
|
||||||
else
|
|
||||||
notify-send -u low "Aborted screenshot"
|
|
||||||
fi
|
|
99
bin/scrrec
99
bin/scrrec
|
@ -1,99 +0,0 @@
|
||||||
#!/usr/bin/env cached-nix-shell
|
|
||||||
#! nix-shell -i bash -p ffmpeg slop
|
|
||||||
|
|
||||||
# Select a region and record it.
|
|
||||||
#
|
|
||||||
# If given a gif, it will record an mp4 and convert it afterwards using the
|
|
||||||
# mov2gif script included in this repo (which is powered by gifsicle and
|
|
||||||
# ffmpeg).
|
|
||||||
#
|
|
||||||
# Usage: scrrec somefile.mp4
|
|
||||||
# scrrec another.gif
|
|
||||||
|
|
||||||
is_script=
|
|
||||||
geom=
|
|
||||||
delay=1
|
|
||||||
count=3
|
|
||||||
fps=30
|
|
||||||
stopfile=/tmp/_stop
|
|
||||||
while getopts c:d:f:g:ps opt; do
|
|
||||||
case $opt in
|
|
||||||
c) count=$OPTARG ;;
|
|
||||||
d) delay="$OPTARG" ;;
|
|
||||||
f) fps=$OPTARG ;;
|
|
||||||
g) geom="$OPTARG" ;;
|
|
||||||
p) picom= ;;
|
|
||||||
s) is_script=1 ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $((OPTIND-1))
|
|
||||||
|
|
||||||
##
|
|
||||||
select-region() {
|
|
||||||
if [[ $geom ]]; then
|
|
||||||
echo "${geom//[x+]/ }"
|
|
||||||
else
|
|
||||||
slop -nof "%w %h %x %y"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
countdown() {
|
|
||||||
if (( count > 0 )); then
|
|
||||||
for ((i=count;i>0;i--)); do
|
|
||||||
if [[ $is_script ]]; then
|
|
||||||
notify-send -u critical -t 1000 "Recording in $i"
|
|
||||||
else
|
|
||||||
echo "Recording in $i"
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
elif [[ $is_script ]]; then
|
|
||||||
notify-send -u critical "Starting recording..."
|
|
||||||
else
|
|
||||||
echo "Started recording..."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
recording-start() {
|
|
||||||
local ffmpeg_opts="-y -f x11grab -show_region 1 -ss $delay -s ${4}x${5} -i :0.0+${2},${3} -framerate ${fps}"
|
|
||||||
local dest=${1:-./rec.mp4}
|
|
||||||
local mp4dest=
|
|
||||||
[[ $dest == *.gif ]] && mp4dest="${dest%.*}.mp4"
|
|
||||||
countdown
|
|
||||||
ffmpeg $ffmpeg_opts "${mp4dest:-$dest}" &
|
|
||||||
pid=$!
|
|
||||||
echo $pid >$stopfile
|
|
||||||
wait $pid
|
|
||||||
rm -f $stopfile
|
|
||||||
if [[ -f "$mp4dest" ]]; then
|
|
||||||
mov2gif "$mp4dest" "$dest" && rm -fv "$mp4dest"
|
|
||||||
fi
|
|
||||||
echo -n "$dest" | xclip -selection clipboard -in
|
|
||||||
notify-send "Screencast successful" "Saved to $dest\nAnd copied to your clipboard!"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# If a recording session is already active, stop that one.
|
|
||||||
if [[ -n "$is_script" && -f "$stopfile" ]]; then
|
|
||||||
kill $(cat $stopfile)
|
|
||||||
echo "Stopped previous recording"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -r W H X Y < <(select-region)
|
|
||||||
[[ -z "$W$H$X$Y" ]] && exit 1
|
|
||||||
|
|
||||||
# picom with blur and/or transparencies cause unbearable flickering in
|
|
||||||
# recordings, so temporarily disable it.
|
|
||||||
picom=
|
|
||||||
if systemctl is-enabled --user picom >/dev/null; then
|
|
||||||
systemctl --user stop picom
|
|
||||||
picom=1
|
|
||||||
fi
|
|
||||||
cleanup() { [[ $picom ]] && systemctl --user start picom; }
|
|
||||||
trap cleanup EXIT
|
|
||||||
|
|
||||||
# Let 'er rip
|
|
||||||
recording-start "$1" "$X" "$Y" "$W" "$H"
|
|
||||||
|
|
||||||
# vim:set ft=sh shiftwidth=2:
|
|
38
bin/since
38
bin/since
|
@ -1,38 +0,0 @@
|
||||||
#!/usr/bin/env zsh
|
|
||||||
set -e
|
|
||||||
(( $# > 0 )) || exit
|
|
||||||
|
|
||||||
# Displays the time since $1 in a human readable format (e.g. 4h 25m 55s). If
|
|
||||||
# given a file, the modified time is used. If $1 == "--", then this script acts
|
|
||||||
# as a converter, converting $2 into human a readable format, e.g. since -- 72
|
|
||||||
# #=> 1m 12s
|
|
||||||
|
|
||||||
# TODO: A help fallback
|
|
||||||
# TODO: Options parsing?
|
|
||||||
|
|
||||||
# If given a file, give time since last modification
|
|
||||||
(( $# == 1 )) && [[ -f $1 ]] && arg=reference || arg=date
|
|
||||||
|
|
||||||
if [[ $1 == -- ]]; then
|
|
||||||
t="$2"
|
|
||||||
else
|
|
||||||
now=$(date +%s)
|
|
||||||
then=$(date --$arg="$*" +%s)
|
|
||||||
|
|
||||||
t=$(( now - then ))
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Bash doesn't support floating point arithmetic like zsh does, so use bc to do
|
|
||||||
# our arithmetic.
|
|
||||||
zmodload zsh/mathfunc
|
|
||||||
t=$(( abs(t) ))
|
|
||||||
weeks=$(( t / 60 / 60 / 24 / 7 ))
|
|
||||||
days=$(( t / 60 / 60 / 24 % 7 ))
|
|
||||||
hours=$(( t / 60 / 60 % 24 ))
|
|
||||||
minutes=$(( t / 60 % 60 ))
|
|
||||||
seconds=$(( t % 60 ))
|
|
||||||
(( weeks > 0 )) && echo -n "${weeks}w "
|
|
||||||
(( days > 0 )) && echo -n "${days}d "
|
|
||||||
(( hours > 0 )) && echo -n "${hours}h "
|
|
||||||
(( minutes > 0 )) && echo -n "${minutes}m "
|
|
||||||
echo -n "${seconds}s"
|
|
21
bin/spell
21
bin/spell
|
@ -1,21 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Find the correct spelling of a word. Uses (and requires) fzf to select the
|
|
||||||
# correct word. This output can be piped to something like dict to find
|
|
||||||
# definitions/synonyms.
|
|
||||||
#
|
|
||||||
# Requires: aspell, fzf
|
|
||||||
# Usage: spell mispeling
|
|
||||||
# Example: dict $(spell mispeling)
|
|
||||||
|
|
||||||
result=$(echo "$@" | aspell -a | tail -n-2)
|
|
||||||
if [[ "$result" == '*' ]]; then
|
|
||||||
echo "$@"
|
|
||||||
else
|
|
||||||
words=$(echo "$result" | sed $'s/[:,] /\\\n/g' | tail -n +2)
|
|
||||||
if (( $(wc -l <<< "$words") > 1 )) && command -v sk >/dev/null; then
|
|
||||||
fzf <<< "$words"
|
|
||||||
else
|
|
||||||
echo "$words"
|
|
||||||
fi
|
|
||||||
fi
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
open=open
|
|
||||||
[[ $OSTYPE == linux* ]] && open=xdg-open
|
|
||||||
|
|
||||||
$open https://time.is/$1 2>/dev/null &
|
|
22
bin/zzz
22
bin/zzz
|
@ -1,22 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# If -f, then put computer to sleep.
|
|
||||||
# Otherwise, lock screen and turn off monitor.
|
|
||||||
|
|
||||||
if [[ $1 == -h ]]; then
|
|
||||||
bin=${0##*/}
|
|
||||||
echo "Usage: $bin [-f]"
|
|
||||||
echo
|
|
||||||
echo " $bin # put display to sleep"
|
|
||||||
echo " $bin -f # put computer to sleep"
|
|
||||||
elif [[ $1 == -f ]]; then
|
|
||||||
echo "Going to sleep..."
|
|
||||||
systemctl suspend
|
|
||||||
else
|
|
||||||
echo "Shutting my eyes..."
|
|
||||||
if command -v slock >/dev/null; then
|
|
||||||
pgrep slock >/dev/null || slock &
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
xset dpms force off
|
|
||||||
fi
|
|
28
box.nix
Normal file
28
box.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./common.nix
|
||||||
|
./mossnet.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
users.extraUsers."anish".extraGroups = [ "jackaudio" ];
|
||||||
|
|
||||||
|
# services.xserver = {
|
||||||
|
# enable = true;
|
||||||
|
# displayManager.gdm.enable = true;
|
||||||
|
# desktopManager.gnome3.enable = true;
|
||||||
|
# };
|
||||||
|
|
||||||
|
# task whisperer broken
|
||||||
|
#nixpkgs.config.allowBroken = true;
|
||||||
|
|
||||||
|
# virtual box
|
||||||
|
virtualisation.virtualbox.host.enable = true;
|
||||||
|
|
||||||
|
# ErgoDox Firmware (doesn't compile)
|
||||||
|
# environment.systemPackages = with pkgs; [
|
||||||
|
# qmk_firmware
|
||||||
|
# ];
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# imports = [
|
imports = [
|
||||||
# ./nvim.nix
|
./nvim.nix
|
||||||
# ./unstable.nix
|
# ./unstable.nix
|
||||||
# ];
|
];
|
||||||
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
|
tailscale
|
||||||
htop
|
htop
|
||||||
|
fzf
|
||||||
iftop
|
iftop
|
||||||
wget
|
wget
|
||||||
curl
|
curl
|
||||||
|
@ -16,6 +18,7 @@
|
||||||
bat
|
bat
|
||||||
fd
|
fd
|
||||||
ag
|
ag
|
||||||
|
wpa_supplicant
|
||||||
tcpdump
|
tcpdump
|
||||||
whois
|
whois
|
||||||
mtr
|
mtr
|
||||||
|
@ -27,51 +30,52 @@
|
||||||
zip
|
zip
|
||||||
unzip
|
unzip
|
||||||
rsync
|
rsync
|
||||||
#tmux
|
tmux
|
||||||
pwgen
|
pwgen
|
||||||
glow
|
glow
|
||||||
|
jq
|
||||||
gitAndTools.gitFull
|
gitAndTools.gitFull
|
||||||
#neovim defined in ./nvim.nix
|
#neovim defined in ./nvim.nix
|
||||||
#firefox
|
# wofi
|
||||||
#fractal
|
# firefox
|
||||||
#pinentry_gnome
|
# fractal
|
||||||
|
# pinentry_gnome
|
||||||
|
pinentry_curses
|
||||||
pass
|
pass
|
||||||
gcc
|
gcc
|
||||||
less
|
less
|
||||||
mpv
|
# mpv
|
||||||
zathura
|
# zathura
|
||||||
#qmk_firmware
|
#qmk_firmware
|
||||||
|
python3
|
||||||
gdb
|
gdb
|
||||||
vcv-rack
|
# vcv-rack
|
||||||
#xdotool
|
#xdotool
|
||||||
#neofetch
|
#neofetch
|
||||||
#calibre
|
#calibre
|
||||||
#openvpn
|
#openvpn
|
||||||
gimp
|
#gimp
|
||||||
xxd
|
xxd
|
||||||
kitty
|
# tilix
|
||||||
|
# kitty
|
||||||
taskwarrior
|
taskwarrior
|
||||||
#gnupg
|
gnupg
|
||||||
openjdk
|
openjdk
|
||||||
glslviewer
|
glslviewer
|
||||||
filezilla
|
#filezilla
|
||||||
signal-desktop
|
# signal-desktop
|
||||||
#wire-desktop
|
# wire-desktop
|
||||||
#tdesktop
|
# tdesktop
|
||||||
#feedreader
|
# feedreader
|
||||||
newsflash
|
#newsflash
|
||||||
syncthing
|
# syncthing
|
||||||
dijo
|
dijo
|
||||||
#kdeconnect
|
|
||||||
#ssb-patchwork
|
#ssb-patchwork
|
||||||
#gnome3.gnome-tweaks
|
|
||||||
#gnome3.pomodoro
|
|
||||||
#gnomeExtensions.gsconnect
|
|
||||||
#gnomeExtensions.taskwhisperer
|
#gnomeExtensions.taskwhisperer
|
||||||
#gnome3.networkmanager-openvpn
|
#gnome3.networkmanager-openvpn
|
||||||
#python3Packages.youtube-dl
|
#python3Packages.youtube-dl
|
||||||
#appimage-run
|
#appimage-run
|
||||||
#home-manager
|
home-manager
|
||||||
libreoffice
|
libreoffice
|
||||||
fontconfig
|
fontconfig
|
||||||
#hugo
|
#hugo
|
||||||
|
@ -82,14 +86,18 @@
|
||||||
supercollider
|
supercollider
|
||||||
haskellPackages.tidal
|
haskellPackages.tidal
|
||||||
pandoc
|
pandoc
|
||||||
|
# calibre
|
||||||
];
|
];
|
||||||
|
|
||||||
programs.bash.enableCompletion = true;
|
programs.bash.enableCompletion = true;
|
||||||
|
|
||||||
|
programs.gnupg.agent.enable = true;
|
||||||
|
programs.gnupg.agent.pinentryFlavor = "curses";
|
||||||
|
programs.gnupg.agent.enableSSHSupport = true;
|
||||||
# needed for vcv-rack
|
# needed for vcv-rack
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
#system.copySystemConfiguration = true;
|
system.copySystemConfiguration = true;
|
||||||
#services.syncthing = {
|
#services.syncthing = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
# openDefaultPorts = true;
|
# openDefaultPorts = true;
|
||||||
|
@ -99,12 +107,14 @@
|
||||||
#};
|
#};
|
||||||
|
|
||||||
#zsh powerlevel10k
|
#zsh powerlevel10k
|
||||||
programs.zsh.enable = true;
|
#programs.zsh.enable = true;
|
||||||
programs.zsh.promptInit = "source ${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
|
#programs.zsh.promptInit = "source ${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
|
||||||
users.users.anish.shell = pkgs.zsh;
|
users.users.anish.shell = pkgs.bash;
|
||||||
|
|
||||||
#android
|
#android
|
||||||
programs.adb.enable = true;
|
programs.adb.enable = true;
|
||||||
users.users.anish.extraGroups = ["adbusers"];
|
users.users.anish.extraGroups = ["adbusers"];
|
||||||
|
|
||||||
|
#ssh
|
||||||
|
services.sshd.enable = true;
|
||||||
}
|
}
|
2
config/.gitignore
vendored
2
config/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
result
|
|
||||||
result/*
|
|
|
@ -1,111 +0,0 @@
|
||||||
(local gears (require :gears))
|
|
||||||
(local awful (require :awful))
|
|
||||||
(local naughty (require :naughty))
|
|
||||||
(require :awful.autofocus)
|
|
||||||
|
|
||||||
(local wincmd (require :commands.window))
|
|
||||||
(local tagcmd (require :commands.tag))
|
|
||||||
(local pa (require :utils.pulseaudio))
|
|
||||||
(local input (require :utils.input))
|
|
||||||
|
|
||||||
|
|
||||||
(fn initialize [bindings]
|
|
||||||
;; Error handling
|
|
||||||
;; Check if awesome encountered an error during startup and fell back to
|
|
||||||
;; another config (This code will only ever execute for the fallback config)
|
|
||||||
(let [preset { :timeout 0 :bg "#000000" :fg "#ff0000" :max_height 1080 }]
|
|
||||||
(when awesome.startup_errors
|
|
||||||
(naughty.notify {:preset preset
|
|
||||||
:title "Oops, there were errors during startup!"
|
|
||||||
:text awesome.startup_errors}))
|
|
||||||
|
|
||||||
(var in-error false)
|
|
||||||
(awesome.connect_signal
|
|
||||||
"debug::error"
|
|
||||||
(fn []
|
|
||||||
;; Make sure we don't go into an endless error loop
|
|
||||||
(when (not in-error)
|
|
||||||
(set in-error true)
|
|
||||||
(naughty.notify {:preset preset
|
|
||||||
:title "Oops, an error happened!"
|
|
||||||
:text (tostring err)})
|
|
||||||
(naughty.notify {:preset preset
|
|
||||||
:title "Oops, an error happened!"
|
|
||||||
:text (tostring err)})
|
|
||||||
(set in-error false)))))
|
|
||||||
|
|
||||||
(root.keys bindings.global-keys)
|
|
||||||
|
|
||||||
(naughty.notify {:text "Glorious fennel"})
|
|
||||||
(gears.wallpaper.set "#282c34"))
|
|
||||||
|
|
||||||
|
|
||||||
(local
|
|
||||||
bindings
|
|
||||||
{
|
|
||||||
:global-keys
|
|
||||||
(gears.table.join
|
|
||||||
|
|
||||||
(input.key-group
|
|
||||||
"awesome"
|
|
||||||
[[:mod] :s hotkeys_popup.show_help "show help"]
|
|
||||||
[[:mod :shift] :r awesome.restart "reload config"]
|
|
||||||
)
|
|
||||||
|
|
||||||
(input.key-group
|
|
||||||
"exec"
|
|
||||||
[[:mod] :space (fn [] (awful.util.spawn "rofi -show run")) "app launcher"]
|
|
||||||
[[:mod] :e (fn [] (awful.util.spawn "emacsclient -c -n -e '(switch-to-buffer nil)'")) "emacs"]
|
|
||||||
[[:mod] :v (fn []
|
|
||||||
(let [option "gopass ls --flat"
|
|
||||||
prompt "rofi -dmenu -p pass"
|
|
||||||
action "xargs --no-run-if-empty gopass show -c"
|
|
||||||
cmd (.. option " | " prompt " | " action)]
|
|
||||||
(awful.spawn.easy_async_with_shell cmd (fn []))))
|
|
||||||
"secret vault"]
|
|
||||||
[[:mod] :Return (fn [] (awful.spawn "xst")) "open terminal"]
|
|
||||||
[[] :XF86AudioMute pa.toggle-muted "⏼ audio muted"]
|
|
||||||
[[] :XF86AudioMicMute pa.toggle-mic-mute "⏼ mic muted"]
|
|
||||||
[[] :XF86AudioRaiseVolume (fn [] (pa.adjust-volume 5)) "raise volume"]
|
|
||||||
[[] :XF86AudioLowerVolume (fn [] (pa.adjust-volume -5)) "lower volume"]
|
|
||||||
)
|
|
||||||
|
|
||||||
(input.key-group
|
|
||||||
"client"
|
|
||||||
[[:mod] :h (fn [] (awful.client.focus.bydirection :left)) "focus left"]
|
|
||||||
[[:mod] :j (fn [] (awful.client.focus.bydirection :down)) "focus down"]
|
|
||||||
[[:mod] :k (fn [] (awful.client.focus.bydirection :up)) "focus up"]
|
|
||||||
[[:mod] :l (fn [] (awful.client.focus.bydirection :right)) "focus right"]
|
|
||||||
[[:mod] :n (fn [] (awful.client.focus.byidx 1)) "focus next"]
|
|
||||||
[[:mod] :p (fn [] (awful.client.focus.byidx -1)) "focus previous"]
|
|
||||||
[[:mod :shift] :j (fn [] (awful.client.swap.byidx 1)) "swap next with previous"]
|
|
||||||
[[:mod :shift] :k (fn [] (awful.client.swap.byidx -1)) "swap next with previous"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:client-keys
|
|
||||||
(gears.table.join
|
|
||||||
(input.key-group
|
|
||||||
"client"
|
|
||||||
[[:mod] :n wincmd.minimize "minimize"]
|
|
||||||
[[:mod] :t wincmd.toggle-ontop "⏼ keep on top"]
|
|
||||||
[[:mod] :m wincmd.toggle-maximized "⏼ maximize"]
|
|
||||||
[[:mod] :f wincmd.toggle-fullscreen "⏼ fullscreen"]
|
|
||||||
[[:mod :ctrl] :space awful.client.floating.toggle "⏼ floating"]
|
|
||||||
[[:mod :ctrl] :Return wincmd.move-to-master "move to master"]
|
|
||||||
[[:mod :ctrl] :m wincmd.toggle-maximize-vertical "⏼ max vertically"]
|
|
||||||
[[:mod :shift] :m wincmd.toggle-maximize-horizontal "⏼ max horizontally"]
|
|
||||||
[[:mod :shift] :c wincmd.close "close"]
|
|
||||||
))
|
|
||||||
|
|
||||||
:client-buttons
|
|
||||||
(gears.table.join
|
|
||||||
(input.mousebind [] input.left-click client.mouse-raise)
|
|
||||||
(input.mousebind [:mod] input.left-click client.mouse-drag-move)
|
|
||||||
(input.mousebind [:mod] input.right-click client.mouse-drag-resize)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
(initialize bindings)
|
|
|
@ -1,34 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# case $HOSTNAME in
|
|
||||||
# kuro) export LAN=eno1 ;;
|
|
||||||
# shiro) export LAN=wlp3s0 ;;
|
|
||||||
# esac
|
|
||||||
|
|
||||||
export MONITOR=$(xrandr -q | grep primary | cut -d' ' -f1)
|
|
||||||
export MONITORS=( $(xrandr -q | grep ' connected' | cut -d' ' -f1) )
|
|
||||||
MONITOR=${MONITOR:-${MONITORS[0]}}
|
|
||||||
|
|
||||||
# Only have workspaces for primary monitor
|
|
||||||
bspc monitor $MONITOR -d {1,2,3,4,5}
|
|
||||||
|
|
||||||
bspc config remove_disabled_monitors true
|
|
||||||
bspc config remove_unplugged_monitors true
|
|
||||||
|
|
||||||
|
|
||||||
# Rules
|
|
||||||
bspc rule -r '*'
|
|
||||||
|
|
||||||
bspc rule -a Pinentry state=floating center=on
|
|
||||||
bspc rule -a Emacs split_ratio=0.28 state=tiled
|
|
||||||
bspc rule -a Firefox split_ratio=0.32
|
|
||||||
bspc rule -a feh state=fullscreen
|
|
||||||
bspc rule -a 'Emacs:org*' state=floating
|
|
||||||
bspc rule -a 'Emacs:scratch' state=floating
|
|
||||||
bspc rule -a 'Emacs:emacs-everywhere' state=floating sticky=on
|
|
||||||
bspc rule -a '*:scratch' state=floating sticky=on center=on border=off rectangle=1000x800+0+0
|
|
||||||
|
|
||||||
#
|
|
||||||
for file in $XDG_CONFIG_HOME/bspwm/rc.d/*; do
|
|
||||||
source "$file"
|
|
||||||
done
|
|
|
@ -1,14 +0,0 @@
|
||||||
alias dk=docker
|
|
||||||
alias dkc=docker-compose
|
|
||||||
alias dkm=docker-machine
|
|
||||||
alias dkl='dk logs'
|
|
||||||
alias dkcl='dkc logs'
|
|
||||||
|
|
||||||
dkclr() {
|
|
||||||
dk stop $(docker ps -a -q)
|
|
||||||
dk rm $(docker ps -a -q)
|
|
||||||
}
|
|
||||||
|
|
||||||
dke() {
|
|
||||||
dk exec -it "$1" "${@:1}"
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
e() { pgrep emacs && emacsclient -n "$@" || emacs -nw "$@" }
|
|
||||||
ediff() { emacs -nw --eval "(ediff-files \"$1\" \"$2\")"; }
|
|
||||||
eman() { emacs -nw --eval "(switch-to-buffer (man \"$1\"))"; }
|
|
||||||
ekill() { emacsclient --eval '(kill-emacs)'; }
|
|
1344
config/gimp/menurc
1344
config/gimp/menurc
File diff suppressed because it is too large
Load diff
|
@ -1,29 +0,0 @@
|
||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
g() { [[ $# = 0 ]] && git status --short . || git $*; }
|
|
||||||
|
|
||||||
alias git='noglob git'
|
|
||||||
alias ga='git add'
|
|
||||||
alias gap='git add --patch'
|
|
||||||
alias gb='git branch -av'
|
|
||||||
alias gop='git open'
|
|
||||||
alias gbl='git blame'
|
|
||||||
alias gc='git commit'
|
|
||||||
alias gcm='git commit -m'
|
|
||||||
alias gca='git commit --amend'
|
|
||||||
alias gcf='git commit --fixup'
|
|
||||||
alias gcl='git clone'
|
|
||||||
alias gco='git checkout'
|
|
||||||
alias gcoo='git checkout --'
|
|
||||||
alias gf='git fetch'
|
|
||||||
alias gi='git init'
|
|
||||||
alias gl='git log --graph --pretty="format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset"'
|
|
||||||
alias gll='git log --pretty="format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset"'
|
|
||||||
alias gL='gl --stat'
|
|
||||||
alias gp='git push'
|
|
||||||
alias gpl='git pull --rebase --autostash'
|
|
||||||
alias gs='git status --short .'
|
|
||||||
alias gss='git status'
|
|
||||||
alias gst='git stash'
|
|
||||||
alias gr='git reset HEAD'
|
|
||||||
alias grv='git rev-parse'
|
|
|
@ -1,3 +0,0 @@
|
||||||
*.lisp diff=lisp
|
|
||||||
*.el diff=lisp
|
|
||||||
*.org diff=org
|
|
|
@ -1,46 +0,0 @@
|
||||||
[user]
|
|
||||||
name = Henrik Lissner
|
|
||||||
email = henrik@lissner.net
|
|
||||||
[core]
|
|
||||||
whitespace = trailing-space
|
|
||||||
[init]
|
|
||||||
defaultBranch = main
|
|
||||||
[github]
|
|
||||||
user = chickensoupwithrice
|
|
||||||
[gitlab]
|
|
||||||
user =
|
|
||||||
[rebase]
|
|
||||||
autosquash = true
|
|
||||||
[push]
|
|
||||||
default = current
|
|
||||||
[pull]
|
|
||||||
rebase = true
|
|
||||||
[alias]
|
|
||||||
unadd = reset HEAD
|
|
||||||
# data analysis
|
|
||||||
ranked-authors = !git authors | sort | uniq -c | sort -n
|
|
||||||
emails = !git log --format="%aE" | sort -u
|
|
||||||
email-domains = !git log --format="%aE" | awk -F'@' '{print $2}' | sort -u
|
|
||||||
[filter "lfs"]
|
|
||||||
required = true
|
|
||||||
smudge = git-lfs smudge -- %f
|
|
||||||
process = git-lfs filter-process
|
|
||||||
clean = git-lfs clean -- %f
|
|
||||||
[url "https://github.com/"]
|
|
||||||
insteadOf = gh:
|
|
||||||
[url "git@github.com:"]
|
|
||||||
insteadOf = ssh+gh:
|
|
||||||
[url "git@github.com:chickensoupwithrice/"]
|
|
||||||
insteadOf = gh:/
|
|
||||||
[url "https://gitlab.com/"]
|
|
||||||
insteadOf = gl:
|
|
||||||
[url "https://gist.github.com/"]
|
|
||||||
insteadOf = gist:
|
|
||||||
[url "https://bitbucket.org/"]
|
|
||||||
insteadOf = bb:
|
|
||||||
[url "https://git.v0.com"]
|
|
||||||
insteadOf = v0:
|
|
||||||
[diff "lisp"]
|
|
||||||
xfuncname = "^(((;;;+ )|\\(|([ \t]+\\(((cl-|el-patch-)?def(un|var|macro|method|custom)|gb/))).*)$"
|
|
||||||
[diff "org"]
|
|
||||||
xfuncname = "^(\\*+ +.*)$"
|
|
|
@ -1,36 +0,0 @@
|
||||||
# For emacs:
|
|
||||||
*~
|
|
||||||
*.*~
|
|
||||||
\#*
|
|
||||||
.\#*
|
|
||||||
|
|
||||||
# For vim:
|
|
||||||
*.swp
|
|
||||||
.*.sw[a-z]
|
|
||||||
*.un~
|
|
||||||
.netrwhist
|
|
||||||
|
|
||||||
# OS generated files #
|
|
||||||
######################
|
|
||||||
.DS_Store?
|
|
||||||
.DS_Store
|
|
||||||
.CFUserTextEncoding
|
|
||||||
.Trash
|
|
||||||
.Xauthority
|
|
||||||
thumbs.db
|
|
||||||
Thumbs.db
|
|
||||||
Icon?
|
|
||||||
|
|
||||||
# Code stuffs #
|
|
||||||
###############
|
|
||||||
.ccls-cache/
|
|
||||||
.sass-cache/
|
|
||||||
__pycache__/
|
|
||||||
|
|
||||||
# Compiled thangs #
|
|
||||||
###################
|
|
||||||
*.class
|
|
||||||
*.exe
|
|
||||||
*.o
|
|
||||||
*.pyc
|
|
||||||
*.elc
|
|
|
@ -1,3 +0,0 @@
|
||||||
alias rate=mpd-rate
|
|
||||||
alias mpcs='mpc search any'
|
|
||||||
alias mpcsp='mpc searchplay any'
|
|
|
@ -1,424 +0,0 @@
|
||||||
def_key "k"
|
|
||||||
scroll_up
|
|
||||||
|
|
||||||
def_key "j"
|
|
||||||
scroll_down
|
|
||||||
|
|
||||||
def_key "K"
|
|
||||||
select_item
|
|
||||||
scroll_up
|
|
||||||
|
|
||||||
def_key "J"
|
|
||||||
select_item
|
|
||||||
scroll_down
|
|
||||||
|
|
||||||
def_key "h"
|
|
||||||
previous_column
|
|
||||||
|
|
||||||
def_key "l"
|
|
||||||
next_column
|
|
||||||
|
|
||||||
def_key "L"
|
|
||||||
show_lyrics
|
|
||||||
|
|
||||||
def_key "up"
|
|
||||||
volume_up
|
|
||||||
|
|
||||||
def_key "down"
|
|
||||||
volume_down
|
|
||||||
|
|
||||||
#def_key "right"
|
|
||||||
# next_column
|
|
||||||
#
|
|
||||||
#def_key "left"
|
|
||||||
# previous_column
|
|
||||||
#
|
|
||||||
#def_key "mouse"
|
|
||||||
# mouse_event
|
|
||||||
#
|
|
||||||
#def_key "up"
|
|
||||||
# scroll_up
|
|
||||||
#
|
|
||||||
#def_key "shift-up"
|
|
||||||
# select_item
|
|
||||||
# scroll_up
|
|
||||||
#
|
|
||||||
#def_key "down"
|
|
||||||
# scroll_down
|
|
||||||
#
|
|
||||||
#def_key "shift-down"
|
|
||||||
# select_item
|
|
||||||
# scroll_down
|
|
||||||
#
|
|
||||||
#def_key "["
|
|
||||||
# scroll_up_album
|
|
||||||
#
|
|
||||||
#def_key "]"
|
|
||||||
# scroll_down_album
|
|
||||||
#
|
|
||||||
#def_key "{"
|
|
||||||
# scroll_up_artist
|
|
||||||
#
|
|
||||||
#def_key "}"
|
|
||||||
# scroll_down_artist
|
|
||||||
#
|
|
||||||
#def_key "page_up"
|
|
||||||
# page_up
|
|
||||||
#
|
|
||||||
#def_key "page_down"
|
|
||||||
# page_down
|
|
||||||
#
|
|
||||||
#def_key "home"
|
|
||||||
# move_home
|
|
||||||
#
|
|
||||||
#def_key "end"
|
|
||||||
# move_end
|
|
||||||
#
|
|
||||||
#def_key "insert"
|
|
||||||
# select_item
|
|
||||||
#
|
|
||||||
#def_key "enter"
|
|
||||||
# enter_directory
|
|
||||||
#
|
|
||||||
#def_key "enter"
|
|
||||||
# toggle_output
|
|
||||||
#
|
|
||||||
#def_key "enter"
|
|
||||||
# run_action
|
|
||||||
#
|
|
||||||
#def_key "enter"
|
|
||||||
# play_item
|
|
||||||
#
|
|
||||||
#def_key "space"
|
|
||||||
# add_item_to_playlist
|
|
||||||
#
|
|
||||||
#def_key "space"
|
|
||||||
# toggle_lyrics_update_on_song_change
|
|
||||||
#
|
|
||||||
#def_key "space"
|
|
||||||
# toggle_visualization_type
|
|
||||||
#
|
|
||||||
#def_key "delete"
|
|
||||||
# delete_playlist_items
|
|
||||||
#
|
|
||||||
#def_key "delete"
|
|
||||||
# delete_browser_items
|
|
||||||
#
|
|
||||||
#def_key "delete"
|
|
||||||
# delete_stored_playlist
|
|
||||||
#
|
|
||||||
#def_key "right"
|
|
||||||
# next_column
|
|
||||||
#
|
|
||||||
#def_key "right"
|
|
||||||
# slave_screen
|
|
||||||
#
|
|
||||||
#def_key "right"
|
|
||||||
# volume_up
|
|
||||||
#
|
|
||||||
#def_key "+"
|
|
||||||
# volume_up
|
|
||||||
#
|
|
||||||
#def_key "left"
|
|
||||||
# previous_column
|
|
||||||
#
|
|
||||||
#def_key "left"
|
|
||||||
# master_screen
|
|
||||||
#
|
|
||||||
#def_key "left"
|
|
||||||
# volume_down
|
|
||||||
#
|
|
||||||
#def_key "-"
|
|
||||||
# volume_down
|
|
||||||
#
|
|
||||||
#def_key ":"
|
|
||||||
# execute_command
|
|
||||||
#
|
|
||||||
#def_key "tab"
|
|
||||||
# next_screen
|
|
||||||
#
|
|
||||||
#def_key "shift-tab"
|
|
||||||
# previous_screen
|
|
||||||
#
|
|
||||||
#def_key "f1"
|
|
||||||
# show_help
|
|
||||||
#
|
|
||||||
#def_key "1"
|
|
||||||
# show_playlist
|
|
||||||
#
|
|
||||||
#def_key "2"
|
|
||||||
# show_browser
|
|
||||||
#
|
|
||||||
#def_key "2"
|
|
||||||
# change_browse_mode
|
|
||||||
#
|
|
||||||
#def_key "3"
|
|
||||||
# show_search_engine
|
|
||||||
#
|
|
||||||
#def_key "3"
|
|
||||||
# reset_search_engine
|
|
||||||
#
|
|
||||||
#def_key "4"
|
|
||||||
# show_media_library
|
|
||||||
#
|
|
||||||
#def_key "4"
|
|
||||||
# toggle_media_library_columns_mode
|
|
||||||
#
|
|
||||||
#def_key "5"
|
|
||||||
# show_playlist_editor
|
|
||||||
#
|
|
||||||
#def_key "6"
|
|
||||||
# show_tag_editor
|
|
||||||
#
|
|
||||||
#def_key "7"
|
|
||||||
# show_outputs
|
|
||||||
#
|
|
||||||
#def_key "8"
|
|
||||||
# show_visualizer
|
|
||||||
#
|
|
||||||
#def_key "="
|
|
||||||
# show_clock
|
|
||||||
#
|
|
||||||
#def_key "@"
|
|
||||||
# show_server_info
|
|
||||||
#
|
|
||||||
#def_key "s"
|
|
||||||
# stop
|
|
||||||
#
|
|
||||||
#def_key "p"
|
|
||||||
# pause
|
|
||||||
#
|
|
||||||
#def_key ">"
|
|
||||||
# next
|
|
||||||
#
|
|
||||||
#def_key "<"
|
|
||||||
# previous
|
|
||||||
#
|
|
||||||
#def_key "ctrl-h"
|
|
||||||
# jump_to_parent_directory
|
|
||||||
#
|
|
||||||
#def_key "ctrl-h"
|
|
||||||
# replay_song
|
|
||||||
#
|
|
||||||
#def_key "backspace"
|
|
||||||
# jump_to_parent_directory
|
|
||||||
#
|
|
||||||
#def_key "backspace"
|
|
||||||
# replay_song
|
|
||||||
#
|
|
||||||
#def_key "f"
|
|
||||||
# seek_forward
|
|
||||||
#
|
|
||||||
#def_key "b"
|
|
||||||
# seek_backward
|
|
||||||
#
|
|
||||||
#def_key "r"
|
|
||||||
# toggle_repeat
|
|
||||||
#
|
|
||||||
#def_key "z"
|
|
||||||
# toggle_random
|
|
||||||
#
|
|
||||||
#def_key "y"
|
|
||||||
# save_tag_changes
|
|
||||||
#
|
|
||||||
#def_key "y"
|
|
||||||
# start_searching
|
|
||||||
#
|
|
||||||
#def_key "y"
|
|
||||||
# toggle_single
|
|
||||||
#
|
|
||||||
#def_key "R"
|
|
||||||
# toggle_consume
|
|
||||||
#
|
|
||||||
#def_key "Y"
|
|
||||||
# toggle_replay_gain_mode
|
|
||||||
#
|
|
||||||
#def_key "T"
|
|
||||||
# toggle_add_mode
|
|
||||||
#
|
|
||||||
#def_key "|"
|
|
||||||
# toggle_mouse
|
|
||||||
#
|
|
||||||
#def_key "#"
|
|
||||||
# toggle_bitrate_visibility
|
|
||||||
#
|
|
||||||
#def_key "Z"
|
|
||||||
# shuffle
|
|
||||||
#
|
|
||||||
#def_key "x"
|
|
||||||
# toggle_crossfade
|
|
||||||
#
|
|
||||||
#def_key "X"
|
|
||||||
# set_crossfade
|
|
||||||
#
|
|
||||||
#def_key "u"
|
|
||||||
# update_database
|
|
||||||
#
|
|
||||||
#def_key "ctrl-s"
|
|
||||||
# sort_playlist
|
|
||||||
#
|
|
||||||
#def_key "ctrl-s"
|
|
||||||
# toggle_browser_sort_mode
|
|
||||||
#
|
|
||||||
#def_key "ctrl-s"
|
|
||||||
# toggle_media_library_sort_mode
|
|
||||||
#
|
|
||||||
#def_key "ctrl-r"
|
|
||||||
# reverse_playlist
|
|
||||||
#
|
|
||||||
#def_key "ctrl-_"
|
|
||||||
# select_found_items
|
|
||||||
#
|
|
||||||
#def_key "/"
|
|
||||||
# find
|
|
||||||
#
|
|
||||||
#def_key "/"
|
|
||||||
# find_item_forward
|
|
||||||
#
|
|
||||||
#def_key "?"
|
|
||||||
# find
|
|
||||||
#
|
|
||||||
#def_key "?"
|
|
||||||
# find_item_backward
|
|
||||||
#
|
|
||||||
#def_key "."
|
|
||||||
# next_found_item
|
|
||||||
#
|
|
||||||
#def_key ","
|
|
||||||
# previous_found_item
|
|
||||||
#
|
|
||||||
#def_key "w"
|
|
||||||
# toggle_find_mode
|
|
||||||
#
|
|
||||||
#def_key "e"
|
|
||||||
# edit_song
|
|
||||||
#
|
|
||||||
#def_key "e"
|
|
||||||
# edit_library_tag
|
|
||||||
#
|
|
||||||
#def_key "e"
|
|
||||||
# edit_library_album
|
|
||||||
#
|
|
||||||
#def_key "e"
|
|
||||||
# edit_directory_name
|
|
||||||
#
|
|
||||||
#def_key "e"
|
|
||||||
# edit_playlist_name
|
|
||||||
#
|
|
||||||
#def_key "e"
|
|
||||||
# edit_lyrics
|
|
||||||
#
|
|
||||||
#def_key "i"
|
|
||||||
# show_song_info
|
|
||||||
#
|
|
||||||
#def_key "I"
|
|
||||||
# show_artist_info
|
|
||||||
#
|
|
||||||
#def_key "g"
|
|
||||||
# jump_to_position_in_song
|
|
||||||
#
|
|
||||||
#def_key "l"
|
|
||||||
# show_lyrics
|
|
||||||
#
|
|
||||||
#def_key "ctrl-v"
|
|
||||||
# select_range
|
|
||||||
#
|
|
||||||
#def_key "v"
|
|
||||||
# reverse_selection
|
|
||||||
#
|
|
||||||
#def_key "V"
|
|
||||||
# remove_selection
|
|
||||||
#
|
|
||||||
#def_key "B"
|
|
||||||
# select_album
|
|
||||||
#
|
|
||||||
#def_key "a"
|
|
||||||
# add_selected_items
|
|
||||||
#
|
|
||||||
#def_key "c"
|
|
||||||
# clear_playlist
|
|
||||||
#
|
|
||||||
#def_key "c"
|
|
||||||
# clear_main_playlist
|
|
||||||
#
|
|
||||||
#def_key "C"
|
|
||||||
# crop_playlist
|
|
||||||
#
|
|
||||||
#def_key "C"
|
|
||||||
# crop_main_playlist
|
|
||||||
#
|
|
||||||
#def_key "m"
|
|
||||||
# move_sort_order_up
|
|
||||||
#
|
|
||||||
#def_key "m"
|
|
||||||
# move_selected_items_up
|
|
||||||
#
|
|
||||||
#def_key "m"
|
|
||||||
# set_visualizer_sample_multiplier
|
|
||||||
#
|
|
||||||
#def_key "n"
|
|
||||||
# move_sort_order_down
|
|
||||||
#
|
|
||||||
#def_key "n"
|
|
||||||
# move_selected_items_down
|
|
||||||
#
|
|
||||||
#def_key "M"
|
|
||||||
# move_selected_items_to
|
|
||||||
#
|
|
||||||
#def_key "A"
|
|
||||||
# add
|
|
||||||
#
|
|
||||||
#def_key "S"
|
|
||||||
# save_playlist
|
|
||||||
#
|
|
||||||
#def_key "o"
|
|
||||||
# jump_to_playing_song
|
|
||||||
#
|
|
||||||
#def_key "G"
|
|
||||||
# jump_to_browser
|
|
||||||
#
|
|
||||||
#def_key "G"
|
|
||||||
# jump_to_playlist_editor
|
|
||||||
#
|
|
||||||
#def_key "~"
|
|
||||||
# jump_to_media_library
|
|
||||||
#
|
|
||||||
#def_key "E"
|
|
||||||
# jump_to_tag_editor
|
|
||||||
#
|
|
||||||
#def_key "U"
|
|
||||||
# toggle_playing_song_centering
|
|
||||||
#
|
|
||||||
#def_key "P"
|
|
||||||
# toggle_display_mode
|
|
||||||
#
|
|
||||||
#def_key "\\"
|
|
||||||
# toggle_interface
|
|
||||||
#
|
|
||||||
#def_key "!"
|
|
||||||
# toggle_separators_between_albums
|
|
||||||
#
|
|
||||||
#def_key "L"
|
|
||||||
# toggle_lyrics_fetcher
|
|
||||||
#
|
|
||||||
#def_key "F"
|
|
||||||
# toggle_fetching_lyrics_in_background
|
|
||||||
#
|
|
||||||
#def_key "ctrl-l"
|
|
||||||
# toggle_screen_lock
|
|
||||||
#
|
|
||||||
#def_key "`"
|
|
||||||
# toggle_library_tag_type
|
|
||||||
#
|
|
||||||
#def_key "`"
|
|
||||||
# refetch_lyrics
|
|
||||||
#
|
|
||||||
#def_key "`"
|
|
||||||
# add_random_items
|
|
||||||
#
|
|
||||||
#def_key "ctrl-p"
|
|
||||||
# set_selected_items_priority
|
|
||||||
#
|
|
||||||
#def_key "q"
|
|
||||||
# quit
|
|
||||||
#
|
|
|
@ -1,433 +0,0 @@
|
||||||
##### directories ######
|
|
||||||
ncmpcpp_directory = ~/.config/ncmpcpp
|
|
||||||
|
|
||||||
## Directory for storing downloaded lyrics.
|
|
||||||
lyrics_directory = ~/music/.db/lyrics
|
|
||||||
|
|
||||||
##### connection settings #####
|
|
||||||
mpd_host = "~/.config/mpd/mpd.sock"
|
|
||||||
#mpd_host = "127.0.0.1"
|
|
||||||
#mpd_port = 6600
|
|
||||||
#mpd_connection_timeout = 5
|
|
||||||
|
|
||||||
## Needed for tag editor and file operations to work.
|
|
||||||
mpd_music_dir = ~/music
|
|
||||||
mpd_crossfade_time = 5
|
|
||||||
|
|
||||||
##### music visualizer #####
|
|
||||||
##
|
|
||||||
## Note: In order to make music visualizer work you'll
|
|
||||||
## need to use mpd fifo output, whose format parameter
|
|
||||||
## has to be set to 44100:16:1 for mono visualization
|
|
||||||
## or 44100:16:2 for stereo visualization. Example
|
|
||||||
## configuration (it has to be put into mpd.conf):
|
|
||||||
##
|
|
||||||
## audio_output {
|
|
||||||
## type "fifo"
|
|
||||||
## name "Visualizer feed"
|
|
||||||
## path "/tmp/mpd.fifo"
|
|
||||||
## format "44100:16:2"
|
|
||||||
## }
|
|
||||||
##
|
|
||||||
#visualizer_fifo_path = /tmp/mpd.fifo
|
|
||||||
|
|
||||||
##
|
|
||||||
## Note: Below parameter is needed for ncmpcpp
|
|
||||||
## to determine which output provides data for
|
|
||||||
## visualizer and thus allow syncing between
|
|
||||||
## visualization and sound as currently there
|
|
||||||
## are some problems with it.
|
|
||||||
##
|
|
||||||
#visualizer_output_name = Visualizer feed
|
|
||||||
|
|
||||||
##
|
|
||||||
## If you set format to 44100:16:2, make it 'yes'.
|
|
||||||
##
|
|
||||||
visualizer_in_stereo = no
|
|
||||||
|
|
||||||
##
|
|
||||||
## Multiply received samples by given value. Very
|
|
||||||
## useful for proper visualization of quiet music.
|
|
||||||
##
|
|
||||||
#visualizer_sample_multiplier = 1.0
|
|
||||||
|
|
||||||
##
|
|
||||||
## Note: Below parameter defines how often ncmpcpp
|
|
||||||
## has to "synchronize" visualizer and audio outputs.
|
|
||||||
## 30 seconds is optimal value, but if you experience
|
|
||||||
## synchronization problems, set it to lower value.
|
|
||||||
## Keep in mind that sane values start with >=10.
|
|
||||||
##
|
|
||||||
visualizer_sync_interval = 30
|
|
||||||
|
|
||||||
##
|
|
||||||
## Note: To enable spectrum frequency visualization
|
|
||||||
## you need to compile ncmpcpp with fftw3 support.
|
|
||||||
##
|
|
||||||
#
|
|
||||||
## Available values: spectrum, wave, wave_filled, ellipse.
|
|
||||||
visualizer_type = spectrum
|
|
||||||
## Alternative subset of 256 colors for terminals that support it.
|
|
||||||
#visualizer_color = 41, 83, 119, 155, 185, 215, 209, 203, 197, 161
|
|
||||||
visualizer_color = blue, cyan, green, yellow, magenta, red
|
|
||||||
#visualizer_look = ●▮
|
|
||||||
#
|
|
||||||
##### system encoding #####
|
|
||||||
##
|
|
||||||
## ncmpcpp should detect your charset encoding
|
|
||||||
## but if it failed to do so, you can specify
|
|
||||||
## charset encoding you are using here.
|
|
||||||
##
|
|
||||||
## Note: You can see whether your ncmpcpp build
|
|
||||||
## supports charset detection by checking output
|
|
||||||
## of `ncmpcpp --version`.
|
|
||||||
##
|
|
||||||
## Note: Since MPD uses UTF-8 by default, setting
|
|
||||||
## this option makes sense only if your encoding
|
|
||||||
## is different.
|
|
||||||
##
|
|
||||||
#system_encoding = ""
|
|
||||||
#
|
|
||||||
##### delays #####
|
|
||||||
#
|
|
||||||
## Time of inactivity (in seconds) after playlist
|
|
||||||
## highlighting will be disabled (0 = always on).
|
|
||||||
##
|
|
||||||
#playlist_disable_highlight_delay = 5
|
|
||||||
#
|
|
||||||
## Defines how long messages are supposed to be visible.
|
|
||||||
##
|
|
||||||
message_delay_time = 2
|
|
||||||
#
|
|
||||||
##### song format #####
|
|
||||||
##
|
|
||||||
## For a song format you can use:
|
|
||||||
##
|
|
||||||
## %l - length
|
|
||||||
## %f - filename
|
|
||||||
## %D - directory
|
|
||||||
## %a - artist
|
|
||||||
## %A - album artist
|
|
||||||
## %t - title
|
|
||||||
## %b - album
|
|
||||||
## %y - date
|
|
||||||
## %n - track number (01/12 -> 01)
|
|
||||||
## %N - full track info (01/12 -> 01/12)
|
|
||||||
## %g - genre
|
|
||||||
## %c - composer
|
|
||||||
## %p - performer
|
|
||||||
## %d - disc
|
|
||||||
## %C - comment
|
|
||||||
## %P - priority
|
|
||||||
## $R - begin right alignment
|
|
||||||
##
|
|
||||||
## If you want to make sure that a part of the format is displayed
|
|
||||||
## only when certain tags are present, you can archieve it by
|
|
||||||
## grouping them with brackets, e.g. '{%a - %t}' will be evaluated
|
|
||||||
## to 'ARTIST - TITLE' if both tags are present or '' otherwise.
|
|
||||||
## It is also possible to define a list of alternatives by providing
|
|
||||||
## several groups and separating them with '|', e.g. '{%t}|{%f}'
|
|
||||||
## will be evaluated to 'TITLE' or 'FILENAME' if the former is not
|
|
||||||
## present.
|
|
||||||
##
|
|
||||||
## Note: If you want to set limit on maximal length of a tag, just
|
|
||||||
## put the appropriate number between % and character that defines
|
|
||||||
## tag type, e.g. to make album take max. 20 terminal cells, use '%20b'.
|
|
||||||
##
|
|
||||||
## In addition, formats support markers used for text attributes.
|
|
||||||
## They are followed by character '$'. After that you can put:
|
|
||||||
##
|
|
||||||
## - 0 - default window color (discards all other colors)
|
|
||||||
## - 1 - black
|
|
||||||
## - 2 - red
|
|
||||||
## - 3 - green
|
|
||||||
## - 4 - yellow
|
|
||||||
## - 5 - blue
|
|
||||||
## - 6 - magenta
|
|
||||||
## - 7 - cyan
|
|
||||||
## - 8 - white
|
|
||||||
## - 9 - end of current color
|
|
||||||
## - b - bold text
|
|
||||||
## - u - underline text
|
|
||||||
## - r - reverse colors
|
|
||||||
## - a - use alternative character set
|
|
||||||
##
|
|
||||||
## If you don't want to use a non-color attribute anymore, just put it
|
|
||||||
## again, but this time insert character '/' between '$' and attribute
|
|
||||||
## character, e.g. {$b%t$/b}|{$r%f$/r} will display bolded title tag
|
|
||||||
## or filename with reversed colors.
|
|
||||||
##
|
|
||||||
## If you want to use 256 colors and/or background colors in formats
|
|
||||||
## (the naming scheme is described below in section about color
|
|
||||||
## definitions), it can be done with the syntax $(COLOR), e.g. to set
|
|
||||||
## the artist tag to one of the non-standard colors and make it have
|
|
||||||
## yellow background, you need to write $(197_yellow)%a$(end). Note
|
|
||||||
## that for standard colors this is interchangable with attributes
|
|
||||||
## listed above.
|
|
||||||
##
|
|
||||||
## Note: colors can be nested.
|
|
||||||
##
|
|
||||||
#
|
|
||||||
# song_list_format = {%a }$2%t$9 %C $R{%b }$2%25l$9
|
|
||||||
#song_list_format = {{$5%a$9 }{$7%A$9 }}{%n }$(16)%t$(end) $R{$8%l$9}
|
|
||||||
# song_status_format = {{%a{ $3%b{ (%y)}$9} }{$8%t$9}}|{%f}
|
|
||||||
#song_library_format = {%n - }{%t}|{%f}
|
|
||||||
song_list_format = "{$2%a$9} {$5%t$9} $R {$3%b$3} $9({$9%l$9})"
|
|
||||||
song_library_format = "%n %t"
|
|
||||||
song_status_format = "$b{$6%a$9 $1|$9} {$7%t$9} $1|$9 {$2%b$9} $1|$9 {$6%y$9} $1|$9"
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#alternative_header_first_line_format = $b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b
|
|
||||||
#alternative_header_second_line_format = {{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D}
|
|
||||||
#
|
|
||||||
now_playing_prefix = "$(3_236)> "
|
|
||||||
now_playing_suffix = $0
|
|
||||||
#
|
|
||||||
#browser_playlist_prefix = "$2playlist$9 "
|
|
||||||
#
|
|
||||||
selected_item_prefix = "$(6_237)+ "
|
|
||||||
selected_item_suffix = $9
|
|
||||||
#
|
|
||||||
# modified_item_prefix = $3> $9
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: attributes are not supported for the following variables.
|
|
||||||
##
|
|
||||||
#song_window_title_format = {%a - }{%t}|{%f}
|
|
||||||
##
|
|
||||||
## Note: Below variables are used for sorting songs in browser.
|
|
||||||
## The sort mode determines how songs are sorted, and can be used
|
|
||||||
## in combination with a sort format to specify a custom sorting format.
|
|
||||||
## Available values for browser_sort_mode are "name", "mtime", "format"
|
|
||||||
## and "noop".
|
|
||||||
##
|
|
||||||
#
|
|
||||||
#browser_sort_mode = name
|
|
||||||
#browser_sort_format = {%a - }{%t}|{%f} {(%l)}
|
|
||||||
#
|
|
||||||
##### columns settings #####
|
|
||||||
##
|
|
||||||
## syntax of song columns list format is "column column etc."
|
|
||||||
##
|
|
||||||
## - syntax for each column is:
|
|
||||||
##
|
|
||||||
## (width of the column)[color of the column]{displayed tag}
|
|
||||||
##
|
|
||||||
## Note: Width is by default in %, if you want a column to
|
|
||||||
## have fixed size, add 'f' after the value, e.g. (10)[white]{a}
|
|
||||||
## will be the column that take 10% of screen (so the real width
|
|
||||||
## will depend on actual screen size), whereas (10f)[white]{a}
|
|
||||||
## will take 10 terminal cells, no matter how wide the screen is.
|
|
||||||
##
|
|
||||||
## - color is optional (if you want the default one,
|
|
||||||
## leave the field empty).
|
|
||||||
##
|
|
||||||
## Note: You can give a column additional attributes by putting appropriate
|
|
||||||
## character after displayed tag character. Available attributes are:
|
|
||||||
##
|
|
||||||
## - r - column will be right aligned
|
|
||||||
## - E - if tag is empty, empty tag marker won't be displayed
|
|
||||||
##
|
|
||||||
## You can also:
|
|
||||||
##
|
|
||||||
## - give a column custom name by putting it after attributes,
|
|
||||||
## separated with character ':', e.g. {lr:Length} gives you
|
|
||||||
## right aligned column of lengths named "Length".
|
|
||||||
##
|
|
||||||
## - define sequence of tags, that have to be displayed in case
|
|
||||||
## predecessor is empty in a way similar to the one in classic
|
|
||||||
## song format, i.e. using '|' character, e.g. {a|c|p:Owner}
|
|
||||||
## creates column named "Owner" that tries to display artist
|
|
||||||
## tag and then composer and performer if previous ones are
|
|
||||||
## not available.
|
|
||||||
##
|
|
||||||
song_columns_list_format = (3f)[241]{NEr:#} (8f)[5]{l} (22)[6]{a|A:Artist} (40)[9]{t|f:Title} (30)[13]{b}
|
|
||||||
#
|
|
||||||
##### various settings #####
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: Custom command that will be executed each
|
|
||||||
## time song changes. Useful for notifications etc.
|
|
||||||
##
|
|
||||||
execute_on_song_change = "mpd-notify-song"
|
|
||||||
#playlist_show_mpd_host = no
|
|
||||||
playlist_show_remaining_time = yes
|
|
||||||
playlist_shorten_total_times = yes
|
|
||||||
#playlist_separate_albums = no
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: Possible display modes: classic, columns.
|
|
||||||
##
|
|
||||||
playlist_display_mode = classic
|
|
||||||
browser_display_mode = columns
|
|
||||||
#search_engine_display_mode = classic
|
|
||||||
#playlist_editor_display_mode = classic
|
|
||||||
discard_colors_if_item_is_selected = yes
|
|
||||||
incremental_seeking = yes
|
|
||||||
seek_time = 2
|
|
||||||
volume_change_step = 10
|
|
||||||
#autocenter_mode = no
|
|
||||||
#centered_cursor = no
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: You can specify third character which will
|
|
||||||
## be used to build 'empty' part of progressbar.
|
|
||||||
##
|
|
||||||
progressbar_look = "─╼ "
|
|
||||||
#progressbar_boldness
|
|
||||||
progressbar_color = 1
|
|
||||||
progressbar_elapsed_color = 4
|
|
||||||
#
|
|
||||||
## Available values: database, playlist.
|
|
||||||
##
|
|
||||||
#default_place_to_search_in = database
|
|
||||||
#
|
|
||||||
## Available values: classic, alternative.
|
|
||||||
##
|
|
||||||
user_interface = alternative
|
|
||||||
#data_fetching_delay = yes
|
|
||||||
#
|
|
||||||
## Available values: artist, album_artist, date, genre, composer, performer.
|
|
||||||
##
|
|
||||||
#media_library_primary_tag = artist
|
|
||||||
#
|
|
||||||
## Available values: wrapped, normal.
|
|
||||||
##
|
|
||||||
#default_find_mode = wrapped
|
|
||||||
#default_tag_editor_pattern = %n - %t
|
|
||||||
header_visibility = yes
|
|
||||||
statusbar_visibility = yes
|
|
||||||
titles_visibility = no
|
|
||||||
#header_text_scrolling = yes
|
|
||||||
#cyclic_scrolling = no
|
|
||||||
#lines_scrolled = 2
|
|
||||||
#follow_now_playing_lyrics = no
|
|
||||||
#fetch_lyrics_for_current_song_in_background = no
|
|
||||||
#store_lyrics_in_song_dir = no
|
|
||||||
#generate_win32_compatible_filenames = yes
|
|
||||||
allow_for_physical_item_deletion = yes
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: If you set this variable, ncmpcpp will try to
|
|
||||||
## get info from last.fm in language you set and if it
|
|
||||||
## fails, it will fall back to english. Otherwise it will
|
|
||||||
## use english the first time.
|
|
||||||
##
|
|
||||||
## Note: Language has to be expressed as an ISO 639 alpha-2 code.
|
|
||||||
##
|
|
||||||
#lastfm_preferred_language = en
|
|
||||||
#show_hidden_files_in_local_browser = no
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## How shall screen switcher work?
|
|
||||||
##
|
|
||||||
## - "previous" - switch between the current and previous screen.
|
|
||||||
## - "screen1,...,screenN" - switch between given sequence of screens.
|
|
||||||
##
|
|
||||||
## Screens available for use: help, playlist, browser, search_engine,
|
|
||||||
## media_library, playlist_editor, tag_editor, outputs, visualizer, clock.
|
|
||||||
##
|
|
||||||
#screen_switcher_mode = playlist, browser
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: You can define startup screen
|
|
||||||
## by choosing screen from the list above.
|
|
||||||
##
|
|
||||||
#startup_screen = playlist
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: You can define startup slave screen
|
|
||||||
## by choosing screen from the list above or
|
|
||||||
## an empty value for no slave screen.
|
|
||||||
##
|
|
||||||
#startup_slave_screen = ""
|
|
||||||
#startup_slave_screen_focus = no
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Default width of locked screen (in %).
|
|
||||||
## Acceptable values are from 20 to 80.
|
|
||||||
##
|
|
||||||
#
|
|
||||||
#locked_screen_width_part = 50
|
|
||||||
#ask_for_locked_screen_width_part = yes
|
|
||||||
jump_to_now_playing_song_at_start = yes
|
|
||||||
#ask_before_clearing_playlists = yes
|
|
||||||
#clock_display_seconds = no
|
|
||||||
#display_volume_level = no
|
|
||||||
#display_bitrate = yes
|
|
||||||
display_remaining_time = no
|
|
||||||
#
|
|
||||||
## Available values: none, basic, extended, perl.
|
|
||||||
##
|
|
||||||
#regular_expressions = perl
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: If below is enabled, ncmpcpp will ignore leading
|
|
||||||
## "The" word while sorting items in browser, tags in
|
|
||||||
## media library, etc.
|
|
||||||
##
|
|
||||||
#ignore_leading_the = no
|
|
||||||
#block_search_constraints_change_if_items_found = yes
|
|
||||||
#mouse_support = yes
|
|
||||||
#mouse_list_scroll_whole_page = yes
|
|
||||||
empty_tag_marker = <empty>
|
|
||||||
#tags_separator = " | "
|
|
||||||
tag_editor_extended_numeration = yes
|
|
||||||
#media_library_sort_by_mtime = no
|
|
||||||
enable_window_title = yes
|
|
||||||
#
|
|
||||||
##
|
|
||||||
## Note: You can choose default search mode for search
|
|
||||||
## engine. Available modes are:
|
|
||||||
##
|
|
||||||
## - 1 - use mpd built-in searching (no regexes, pattern matching)
|
|
||||||
## - 2 - use ncmpcpp searching (pattern matching with support for regexes,
|
|
||||||
## but if your mpd is on a remote machine, downloading big database
|
|
||||||
## to process it can take a while
|
|
||||||
## - 3 - match only exact values (this mode uses mpd function for searching
|
|
||||||
## in database and local one for searching in current playlist)
|
|
||||||
##
|
|
||||||
search_engine_default_search_mode = 2
|
|
||||||
external_editor = vim
|
|
||||||
|
|
||||||
## Note: set to yes if external editor is a console application.
|
|
||||||
use_console_editor = yes
|
|
||||||
|
|
||||||
##### colors definitions #####
|
|
||||||
##
|
|
||||||
## It is possible to set a background color by setting a color
|
|
||||||
## value "<foreground>_<background>", e.g. red_black will set
|
|
||||||
## foregound color to red and background color to black.
|
|
||||||
##
|
|
||||||
## In addition, for terminals that support 256 colors it
|
|
||||||
## is possible to set one of them by using a number in range
|
|
||||||
## [1, 256] instead of color name, e.g. numerical value
|
|
||||||
## corresponding to red_black is 2_1. To find out if the
|
|
||||||
## terminal supports 256 colors, run ncmpcpp and check out
|
|
||||||
## the bottom of the help screen for list of available colors
|
|
||||||
## and their numerical values.
|
|
||||||
##
|
|
||||||
## Note: due to technical limitations of ncurses, if 256 colors
|
|
||||||
## are used, it is possible to either use only the colors with
|
|
||||||
## default background color, or all pairs from 1_1 up to 254_127,
|
|
||||||
## depending on the ncurses version used.
|
|
||||||
##
|
|
||||||
colors_enabled = yes
|
|
||||||
empty_tag_color = 13
|
|
||||||
header_window_color = 241
|
|
||||||
volume_color = 239
|
|
||||||
state_line_color = 13
|
|
||||||
state_flags_color = 13
|
|
||||||
main_window_color = green
|
|
||||||
color1 = white
|
|
||||||
color2 = blue
|
|
||||||
# main_window_highlight_color = yellow
|
|
||||||
statusbar_color = 13
|
|
||||||
statusbar_time_color = 6
|
|
||||||
player_state_color = 14
|
|
||||||
alternative_ui_separator_color = 2
|
|
||||||
current_item_prefix = $(9_238)
|
|
||||||
current_item_suffix = $(end)
|
|
||||||
# active_column_color = red
|
|
||||||
window_border_color = 13
|
|
||||||
active_window_border = 13
|
|
|
@ -1,349 +0,0 @@
|
||||||
import os
|
|
||||||
import glob
|
|
||||||
|
|
||||||
## Load settings applied with :set
|
|
||||||
config.load_autoconfig()
|
|
||||||
|
|
||||||
## General config
|
|
||||||
c.content.default_encoding = 'utf-8'
|
|
||||||
c.content.javascript.enabled = True
|
|
||||||
c.content.local_storage = True
|
|
||||||
c.content.plugins = True
|
|
||||||
|
|
||||||
c.editor.encoding = 'utf-8'
|
|
||||||
|
|
||||||
## Security & privacy
|
|
||||||
c.content.autoplay = False # don't autoplay videos
|
|
||||||
|
|
||||||
## Adblocking
|
|
||||||
# Use (superior) Brave adblock if available, or fall back to host blocking
|
|
||||||
c.content.blocking.method = "auto"
|
|
||||||
c.content.blocking.hosts.lists = [
|
|
||||||
'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts',
|
|
||||||
'https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext'
|
|
||||||
# 'https://www.malwaredomainlist.com/hostslist/hosts.txt',
|
|
||||||
# 'http://someonewhocares.org/hosts/hosts',
|
|
||||||
# 'http://winhelp2002.mvps.org/hosts.zip',
|
|
||||||
# 'http://malwaredomains.lehigh.edu/files/justdomains.zip',
|
|
||||||
]
|
|
||||||
# c.content.blocking.whitelist = []
|
|
||||||
|
|
||||||
## Options
|
|
||||||
c.downloads.position = 'bottom'
|
|
||||||
c.downloads.location.directory = os.path.expanduser("~/dl")
|
|
||||||
c.downloads.location.prompt = False
|
|
||||||
c.input.insert_mode.auto_leave = True
|
|
||||||
c.input.insert_mode.auto_load = False
|
|
||||||
c.input.links_included_in_focus_chain = False
|
|
||||||
c.new_instance_open_target = 'tab-silent'
|
|
||||||
c.prompt.filebrowser = False
|
|
||||||
c.prompt.radius = 0
|
|
||||||
c.spellcheck.languages = ['en-US']
|
|
||||||
c.session.lazy_restore = True
|
|
||||||
c.tabs.show = 'multiple'
|
|
||||||
c.tabs.title.format = '{audio}{current_title} - {host}'
|
|
||||||
c.tabs.title.format_pinned = ''
|
|
||||||
c.window.title_format = '{current_title} - {host} - qutebrowser'
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
## Keybindings
|
|
||||||
|
|
||||||
# Universal Emacsien C-g alias for Escape
|
|
||||||
config.bind('<Ctrl-g>', 'clear-keychain ;; search ;; fullscreen --leave')
|
|
||||||
for mode in ['caret', 'command', 'hint', 'insert', 'passthrough', 'prompt', 'register']:
|
|
||||||
config.bind('<Ctrl-g>', 'mode-leave', mode=mode)
|
|
||||||
|
|
||||||
# ...
|
|
||||||
config.bind('zz', 'close')
|
|
||||||
config.bind('tm', 'tab-mute')
|
|
||||||
config.bind('wi', 'devtools bottom')
|
|
||||||
config.bind(';;', 'hint inputs --first') # easier to reach than ;t
|
|
||||||
config.bind(';e', 'hint inputs --first ;; fake-key <Ctrl+a> ;; :spawn nohup bspc rule -a "Emacs:*" -o state=floating sticky=on && emacsclient --eval "(emacs-everywhere)"')
|
|
||||||
# ;v already bound to 'spawn mpv {url}'
|
|
||||||
config.bind(';V', 'hint links spawn mpv {hint-url}')
|
|
||||||
|
|
||||||
# Use external editor
|
|
||||||
c.editor.command = ['emacsclient', '-c', '-F', '((name . "qutebrowser-editor"))', '+{line}:{column}', '{}']
|
|
||||||
# Though we set it, I use the more specialzied emacs-everywhere instead
|
|
||||||
config.bind('<Ctrl+E>', 'edit-text', mode='insert')
|
|
||||||
config.bind('<Ctrl+E>', 'hint inputs --first ;; edit-text', mode='normal')
|
|
||||||
config.bind('<Shift+Ins>', 'fake-key <Ctrl+V>', mode='insert')
|
|
||||||
|
|
||||||
# Vaultwarden integration
|
|
||||||
config.bind(";pp", 'spawn -u qute-bwmenu')
|
|
||||||
config.bind(";pu", 'spawn -u qute-bwmenu --field username')
|
|
||||||
config.bind(";ps", 'spawn -u qute-bwmenu --field password')
|
|
||||||
config.bind(";po", 'spawn -u qute-bwmenu --field otp')
|
|
||||||
config.bind(";pl", 'spawn -u qute-bwmenu --last')
|
|
||||||
|
|
||||||
## Ex-commands
|
|
||||||
|
|
||||||
|
|
||||||
## Bindings for normal mode
|
|
||||||
# config.bind("'", 'enter-mode jump_mark')
|
|
||||||
# config.bind('+', 'zoom-in')
|
|
||||||
# config.bind('-', 'zoom-out')
|
|
||||||
# config.bind('.', 'repeat-command')
|
|
||||||
# config.bind('/', 'set-cmd-text /')
|
|
||||||
# config.bind(':', 'set-cmd-text :')
|
|
||||||
# config.bind(';I', 'hint images tab')
|
|
||||||
# config.bind(';O', 'hint links fill :open -t -r {hint-url}')
|
|
||||||
# config.bind(';R', 'hint --rapid links window')
|
|
||||||
# config.bind(';Y', 'hint links yank-primary')
|
|
||||||
# config.bind(';b', 'hint all tab-bg')
|
|
||||||
# config.bind(';d', 'hint links download')
|
|
||||||
# config.bind(';f', 'hint all tab-fg')
|
|
||||||
# config.bind(';h', 'hint all hover')
|
|
||||||
# config.bind(';i', 'hint images')
|
|
||||||
# config.bind(';o', 'hint links fill :open {hint-url}')
|
|
||||||
# config.bind(';r', 'hint --rapid links tab-bg')
|
|
||||||
# config.bind(';t', 'hint inputs')
|
|
||||||
# config.bind(';y', 'hint links yank')
|
|
||||||
# config.bind('<Alt-1>', 'tab-focus 1')
|
|
||||||
# config.bind('<Alt-2>', 'tab-focus 2')
|
|
||||||
# config.bind('<Alt-3>', 'tab-focus 3')
|
|
||||||
# config.bind('<Alt-4>', 'tab-focus 4')
|
|
||||||
# config.bind('<Alt-5>', 'tab-focus 5')
|
|
||||||
# config.bind('<Alt-6>', 'tab-focus 6')
|
|
||||||
# config.bind('<Alt-7>', 'tab-focus 7')
|
|
||||||
# config.bind('<Alt-8>', 'tab-focus 8')
|
|
||||||
# config.bind('<Alt-9>', 'tab-focus -1')
|
|
||||||
# config.bind('<Ctrl-A>', 'navigate increment')
|
|
||||||
# config.bind('<Ctrl-Alt-p>', 'print')
|
|
||||||
# config.bind('<Ctrl-B>', 'scroll-page 0 -1')
|
|
||||||
# config.bind('<Ctrl-D>', 'scroll-page 0 0.5')
|
|
||||||
# config.bind('<Ctrl-F5>', 'reload -f')
|
|
||||||
# config.bind('<Ctrl-F>', 'scroll-page 0 1')
|
|
||||||
# config.bind('<Ctrl-N>', 'open -w')
|
|
||||||
# config.bind('<Ctrl-PgDown>', 'tab-next')
|
|
||||||
# config.bind('<Ctrl-PgUp>', 'tab-prev')
|
|
||||||
# config.bind('<Ctrl-Q>', 'quit')
|
|
||||||
# config.bind('<Ctrl-Return>', 'follow-selected -t')
|
|
||||||
# config.bind('<Ctrl-Shift-N>', 'open -p')
|
|
||||||
# config.bind('<Ctrl-Shift-T>', 'undo')
|
|
||||||
# config.bind('<Ctrl-Shift-W>', 'close')
|
|
||||||
# config.bind('<Ctrl-T>', 'open -t')
|
|
||||||
# config.bind('<Ctrl-Tab>', 'tab-focus last')
|
|
||||||
# config.bind('<Ctrl-U>', 'scroll-page 0 -0.5')
|
|
||||||
# config.bind('<Ctrl-V>', 'enter-mode passthrough')
|
|
||||||
# config.bind('<Ctrl-W>', 'tab-close')
|
|
||||||
# config.bind('<Ctrl-X>', 'navigate decrement')
|
|
||||||
# config.bind('<Ctrl-^>', 'tab-focus last')
|
|
||||||
# config.bind('<Ctrl-h>', 'home')
|
|
||||||
# config.bind('<Ctrl-p>', 'tab-pin')
|
|
||||||
# config.bind('<Ctrl-s>', 'stop')
|
|
||||||
# config.bind('<Escape>', 'clear-keychain ;; search ;; fullscreen --leave')
|
|
||||||
# config.bind('<F11>', 'fullscreen')
|
|
||||||
# config.bind('<F5>', 'reload')
|
|
||||||
# config.bind('<Return>', 'follow-selected')
|
|
||||||
# config.bind('<back>', 'back')
|
|
||||||
# config.bind('<forward>', 'forward')
|
|
||||||
# config.bind('=', 'zoom')
|
|
||||||
# config.bind('?', 'set-cmd-text ?')
|
|
||||||
# config.bind('@', 'run-macro')
|
|
||||||
# config.bind('B', 'set-cmd-text -s :quickmark-load -t')
|
|
||||||
# config.bind('D', 'tab-close -o')
|
|
||||||
# config.bind('F', 'hint all tab')
|
|
||||||
# config.bind('G', 'scroll-to-perc')
|
|
||||||
# config.bind('H', 'back')
|
|
||||||
# config.bind('J', 'tab-next')
|
|
||||||
# config.bind('K', 'tab-prev')
|
|
||||||
# config.bind('L', 'forward')
|
|
||||||
# config.bind('M', 'bookmark-add')
|
|
||||||
# config.bind('N', 'search-prev')
|
|
||||||
# config.bind('O', 'set-cmd-text -s :open -t')
|
|
||||||
# config.bind('PP', 'open -t -- {primary}')
|
|
||||||
# config.bind('Pp', 'open -t -- {clipboard}')
|
|
||||||
# config.bind('R', 'reload -f')
|
|
||||||
# config.bind('Sb', 'open qute://bookmarks#bookmarks')
|
|
||||||
# config.bind('Sh', 'open qute://history')
|
|
||||||
# config.bind('Sq', 'open qute://bookmarks')
|
|
||||||
# config.bind('Ss', 'open qute://settings')
|
|
||||||
# config.bind('T', 'tab-focus')
|
|
||||||
# config.bind('ZQ', 'quit')
|
|
||||||
# config.bind('ZZ', 'quit --save')
|
|
||||||
# config.bind('[[', 'navigate prev')
|
|
||||||
# config.bind(']]', 'navigate next')
|
|
||||||
# config.bind('`', 'enter-mode set_mark')
|
|
||||||
# config.bind('ad', 'download-cancel')
|
|
||||||
# config.bind('b', 'set-cmd-text -s :quickmark-load')
|
|
||||||
# config.bind('cd', 'download-clear')
|
|
||||||
# config.bind('co', 'tab-only')
|
|
||||||
# config.bind('d', 'tab-close')
|
|
||||||
# config.bind('f', 'hint')
|
|
||||||
# config.bind('g$', 'tab-focus -1')
|
|
||||||
# config.bind('g0', 'tab-focus 1')
|
|
||||||
# config.bind('gB', 'set-cmd-text -s :bookmark-load -t')
|
|
||||||
# config.bind('gC', 'tab-clone')
|
|
||||||
# config.bind('gO', 'set-cmd-text :open -t -r {url:pretty}')
|
|
||||||
# config.bind('gU', 'navigate up -t')
|
|
||||||
# config.bind('g^', 'tab-focus 1')
|
|
||||||
# config.bind('ga', 'open -t')
|
|
||||||
# config.bind('gb', 'set-cmd-text -s :bookmark-load')
|
|
||||||
# config.bind('gd', 'download')
|
|
||||||
# config.bind('gf', 'view-source')
|
|
||||||
# config.bind('gg', 'scroll-to-perc 0')
|
|
||||||
# config.bind('gl', 'tab-move -')
|
|
||||||
# config.bind('gm', 'tab-move')
|
|
||||||
# config.bind('go', 'set-cmd-text :open {url:pretty}')
|
|
||||||
# config.bind('gr', 'tab-move +')
|
|
||||||
# config.bind('gt', 'set-cmd-text -s :buffer')
|
|
||||||
# config.bind('gu', 'navigate up')
|
|
||||||
# config.bind('h', 'scroll left')
|
|
||||||
# config.bind('i', 'enter-mode insert')
|
|
||||||
# config.bind('j', 'scroll down')
|
|
||||||
# config.bind('k', 'scroll up')
|
|
||||||
# config.bind('l', 'scroll right')
|
|
||||||
# config.bind('m', 'quickmark-save')
|
|
||||||
# config.bind('n', 'search-next')
|
|
||||||
# config.bind('o', 'set-cmd-text -s :open')
|
|
||||||
# config.bind('pP', 'open -- {primary}')
|
|
||||||
# config.bind('pp', 'open -- {clipboard}')
|
|
||||||
# config.bind('q', 'record-macro')
|
|
||||||
# config.bind('r', 'reload')
|
|
||||||
# config.bind('sf', 'save')
|
|
||||||
# config.bind('sk', 'set-cmd-text -s :bind')
|
|
||||||
# config.bind('sl', 'set-cmd-text -s :set -t')
|
|
||||||
# config.bind('ss', 'set-cmd-text -s :set')
|
|
||||||
# config.bind('th', 'back -t')
|
|
||||||
# config.bind('tl', 'forward -t')
|
|
||||||
# config.bind('u', 'undo')
|
|
||||||
# config.bind('v', 'enter-mode caret')
|
|
||||||
# config.bind('wB', 'set-cmd-text -s :bookmark-load -w')
|
|
||||||
# config.bind('wO', 'set-cmd-text :open -w {url:pretty}')
|
|
||||||
# config.bind('wP', 'open -w -- {primary}')
|
|
||||||
# config.bind('wb', 'set-cmd-text -s :quickmark-load -w')
|
|
||||||
# config.bind('wf', 'hint all window')
|
|
||||||
# config.bind('wh', 'back -w')
|
|
||||||
# config.bind('wi', 'inspector')
|
|
||||||
# config.bind('wl', 'forward -w')
|
|
||||||
# config.bind('wo', 'set-cmd-text -s :open -w')
|
|
||||||
# config.bind('wp', 'open -w -- {clipboard}')
|
|
||||||
# config.bind('xO', 'set-cmd-text :open -b -r {url:pretty}')
|
|
||||||
# config.bind('xb', 'config-cycle statusbar.hide')
|
|
||||||
# config.bind('xo', 'set-cmd-text -s :open -b')
|
|
||||||
# config.bind('xt', 'config-cycle tabs.show always switching')
|
|
||||||
# config.bind('xx', 'config-cycle statusbar.hide ;; config-cycle tabs.show always switching')
|
|
||||||
# config.bind('yD', 'yank domain -s')
|
|
||||||
# config.bind('yP', 'yank pretty-url -s')
|
|
||||||
# config.bind('yT', 'yank title -s')
|
|
||||||
# config.bind('yY', 'yank -s')
|
|
||||||
# config.bind('yd', 'yank domain')
|
|
||||||
# config.bind('yp', 'yank pretty-url')
|
|
||||||
# config.bind('yt', 'yank title')
|
|
||||||
# config.bind('yy', 'yank')
|
|
||||||
# config.bind('{{', 'navigate prev -t')
|
|
||||||
# config.bind('}}', 'navigate next -t')
|
|
||||||
|
|
||||||
## Bindings for caret mode
|
|
||||||
# config.bind('$', 'move-to-end-of-line', mode='caret')
|
|
||||||
# config.bind('0', 'move-to-start-of-line', mode='caret')
|
|
||||||
# config.bind('<Ctrl-Space>', 'drop-selection', mode='caret')
|
|
||||||
# config.bind('<Escape>', 'leave-mode', mode='caret')
|
|
||||||
# config.bind('<Return>', 'yank selection', mode='caret')
|
|
||||||
# config.bind('<Space>', 'toggle-selection', mode='caret')
|
|
||||||
# config.bind('G', 'move-to-end-of-document', mode='caret')
|
|
||||||
# config.bind('H', 'scroll left', mode='caret')
|
|
||||||
# config.bind('J', 'scroll down', mode='caret')
|
|
||||||
# config.bind('K', 'scroll up', mode='caret')
|
|
||||||
# config.bind('L', 'scroll right', mode='caret')
|
|
||||||
# config.bind('Y', 'yank selection -s', mode='caret')
|
|
||||||
# config.bind('[', 'move-to-start-of-prev-block', mode='caret')
|
|
||||||
# config.bind(']', 'move-to-start-of-next-block', mode='caret')
|
|
||||||
# config.bind('b', 'move-to-prev-word', mode='caret')
|
|
||||||
# config.bind('c', 'enter-mode normal', mode='caret')
|
|
||||||
# config.bind('e', 'move-to-end-of-word', mode='caret')
|
|
||||||
# config.bind('gg', 'move-to-start-of-document', mode='caret')
|
|
||||||
# config.bind('h', 'move-to-prev-char', mode='caret')
|
|
||||||
# config.bind('j', 'move-to-next-line', mode='caret')
|
|
||||||
# config.bind('k', 'move-to-prev-line', mode='caret')
|
|
||||||
# config.bind('l', 'move-to-next-char', mode='caret')
|
|
||||||
# config.bind('v', 'toggle-selection', mode='caret')
|
|
||||||
# config.bind('w', 'move-to-next-word', mode='caret')
|
|
||||||
# config.bind('y', 'yank selection', mode='caret')
|
|
||||||
# config.bind('{', 'move-to-end-of-prev-block', mode='caret')
|
|
||||||
# config.bind('}', 'move-to-end-of-next-block', mode='caret')
|
|
||||||
|
|
||||||
## Bindings for command mode
|
|
||||||
# config.bind('<Alt-B>', 'rl-backward-word', mode='command')
|
|
||||||
# config.bind('<Alt-Backspace>', 'rl-backward-kill-word', mode='command')
|
|
||||||
# config.bind('<Alt-D>', 'rl-kill-word', mode='command')
|
|
||||||
# config.bind('<Alt-F>', 'rl-forward-word', mode='command')
|
|
||||||
# config.bind('<Ctrl-?>', 'rl-delete-char', mode='command')
|
|
||||||
# config.bind('<Ctrl-A>', 'rl-beginning-of-line', mode='command')
|
|
||||||
# config.bind('<Ctrl-B>', 'rl-backward-char', mode='command')
|
|
||||||
# config.bind('<Ctrl-D>', 'completion-item-del', mode='command')
|
|
||||||
# config.bind('<Ctrl-E>', 'rl-end-of-line', mode='command')
|
|
||||||
# config.bind('<Ctrl-F>', 'rl-forward-char', mode='command')
|
|
||||||
config.bind('<Ctrl-B>', 'rl-backward-word', mode='command')
|
|
||||||
config.bind('<Ctrl-F>', 'rl-forward-word', mode='command')
|
|
||||||
# config.bind('<Ctrl-H>', 'rl-backward-delete-char', mode='command')
|
|
||||||
# config.bind('<Ctrl-K>', 'rl-kill-line', mode='command')
|
|
||||||
# config.bind('<Ctrl-N>', 'command-history-next', mode='command')
|
|
||||||
# config.bind('<Ctrl-P>', 'command-history-prev', mode='command')
|
|
||||||
# config.bind('<Ctrl-Shift-Tab>', 'completion-item-focus prev-category', mode='command')
|
|
||||||
# config.bind('<Ctrl-Tab>', 'completion-item-focus next-category', mode='command')
|
|
||||||
# config.bind('<Ctrl-U>', 'rl-unix-line-discard', mode='command')
|
|
||||||
# config.bind('<Ctrl-W>', 'rl-unix-word-rubout', mode='command')
|
|
||||||
# config.bind('<Ctrl-Y>', 'rl-yank', mode='command')
|
|
||||||
# config.bind('<Down>', 'command-history-next', mode='command')
|
|
||||||
# config.bind('<Escape>', 'leave-mode', mode='command')
|
|
||||||
# config.bind('<Return>', 'command-accept', mode='command')
|
|
||||||
# config.bind('<Shift-Delete>', 'completion-item-del', mode='command')
|
|
||||||
# config.bind('<Shift-Tab>', 'completion-item-focus prev', mode='command')
|
|
||||||
# config.bind('<Tab>', 'completion-item-focus next', mode='command')
|
|
||||||
# config.bind('<Up>', 'command-history-prev', mode='command')
|
|
||||||
|
|
||||||
## Bindings for hint mode
|
|
||||||
# config.bind('<Ctrl-B>', 'hint all tab-bg', mode='hint')
|
|
||||||
# config.bind('<Ctrl-F>', 'hint links', mode='hint')
|
|
||||||
# config.bind('<Ctrl-R>', 'hint --rapid links tab-bg', mode='hint')
|
|
||||||
# config.bind('<Escape>', 'mode-leave', mode='hint')
|
|
||||||
# config.bind('<Return>', 'follow-hint', mode='hint')
|
|
||||||
|
|
||||||
## Bindings for insert mode
|
|
||||||
# config.bind('<Ctrl-E>', 'open-editor', mode='insert')
|
|
||||||
# config.bind('<Escape>', 'leave-mode', mode='insert')
|
|
||||||
# config.bind('<Shift-Ins>', 'insert-text {primary}', mode='insert')
|
|
||||||
|
|
||||||
## Bindings for passthrough mode
|
|
||||||
# config.bind('<Ctrl-V>', 'leave-mode', mode='passthrough')
|
|
||||||
|
|
||||||
## Bindings for prompt mode
|
|
||||||
# config.bind('<Alt-B>', 'rl-backward-word', mode='prompt')
|
|
||||||
# config.bind('<Alt-Backspace>', 'rl-backward-kill-word', mode='prompt')
|
|
||||||
# config.bind('<Alt-D>', 'rl-kill-word', mode='prompt')
|
|
||||||
# config.bind('<Alt-F>', 'rl-forward-word', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-?>', 'rl-delete-char', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-A>', 'rl-beginning-of-line', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-B>', 'rl-backward-char', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-E>', 'rl-end-of-line', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-F>', 'rl-forward-char', mode='prompt')
|
|
||||||
config.bind('<Ctrl-B>', 'rl-backward-word', mode='prompt')
|
|
||||||
config.bind('<Ctrl-F>', 'rl-forward-word', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-H>', 'rl-backward-delete-char', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-K>', 'rl-kill-line', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-U>', 'rl-unix-line-discard', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-W>', 'rl-unix-word-rubout', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-X>', 'prompt-open-download', mode='prompt')
|
|
||||||
# config.bind('<Ctrl-Y>', 'rl-yank', mode='prompt')
|
|
||||||
# config.bind('<Down>', 'prompt-item-focus next', mode='prompt')
|
|
||||||
# config.bind('<Escape>', 'leave-mode', mode='prompt')
|
|
||||||
# config.bind('<Return>', 'prompt-accept', mode='prompt')
|
|
||||||
# config.bind('<Shift-Tab>', 'prompt-item-focus prev', mode='prompt')
|
|
||||||
# config.bind('<Tab>', 'prompt-item-focus next', mode='prompt')
|
|
||||||
# config.bind('<Up>', 'prompt-item-focus prev', mode='prompt')
|
|
||||||
# config.bind('n', 'prompt-accept no', mode='prompt')
|
|
||||||
# config.bind('y', 'prompt-accept yes', mode='prompt')
|
|
||||||
|
|
||||||
## Bindings for register mode
|
|
||||||
# config.bind('<Escape>', 'leave-mode', mode='register')
|
|
||||||
|
|
||||||
## Per-domain settings
|
|
||||||
c.content.user_stylesheets = glob.glob(os.path.expanduser('~/.local/share/qutebrowser/userstyles.css'))
|
|
||||||
|
|
||||||
|
|
||||||
## Load theme
|
|
||||||
for path in glob.glob(os.path.expanduser('~/.config/qutebrowser/extra/*.py')):
|
|
||||||
config.source(path)
|
|
|
@ -1,23 +0,0 @@
|
||||||
// ==UserScript==
|
|
||||||
// @name Let there be Light
|
|
||||||
// @description Change page background to white.
|
|
||||||
// @version 0.1
|
|
||||||
// @author Ingvix
|
|
||||||
// @include *
|
|
||||||
// ==/UserScript==
|
|
||||||
|
|
||||||
// Needed to counterbalance my colors.webpage.bg hack to prevent the blinding
|
|
||||||
// flash of white between page loads.
|
|
||||||
(function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function _bg(element) {
|
|
||||||
return window.getComputedStyle(element).backgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_bg(document.documentElement) === "rgba(0, 0, 0, 0)" &&
|
|
||||||
_bg(document.body) === "rgba(0, 0, 0, 0)") {
|
|
||||||
var sheet = window.document.styleSheets[0];
|
|
||||||
sheet.insertRule('body { background-color: white; }', sheet.cssRules.length);
|
|
||||||
}
|
|
||||||
})();
|
|
|
@ -1,21 +0,0 @@
|
||||||
// ==UserScript==
|
|
||||||
// @name DomainStyles
|
|
||||||
// @namespace https://github.com/hlissner
|
|
||||||
// @description Make it possible to use per-domain stylesheets.
|
|
||||||
// @include *
|
|
||||||
// @run-at document-start
|
|
||||||
// @version 1
|
|
||||||
// @author Henrik Lissner
|
|
||||||
// ==/UserScript==
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
document.addEventListener('readystatechange', function onReadyStateChange() {
|
|
||||||
if (document.readyState == 'interactive') {
|
|
||||||
const doc = document.documentElement;
|
|
||||||
doc.setAttribute('qb-url', window.location.href);
|
|
||||||
doc.setAttribute('qb-domain', window.location.host);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
|
@ -1,124 +0,0 @@
|
||||||
;; -*- lisp -*-
|
|
||||||
;;
|
|
||||||
;; Author: Henrik Lissner <henrik@lissner.net>
|
|
||||||
;; URL: https://github.com/hlissner/doom-emacs
|
|
||||||
;;
|
|
||||||
;;;
|
|
||||||
(in-package :stumpwm)
|
|
||||||
;; (swank:create-server
|
|
||||||
;; :dont-close t
|
|
||||||
;; :port swank::default-server-port)
|
|
||||||
|
|
||||||
;;;
|
|
||||||
(defvar *config-dir* "~/.config/dotfiles/config/stumpwm")
|
|
||||||
|
|
||||||
(defcommand reload-dotfiles () ()
|
|
||||||
(load (concat *config-dir* "/config"))
|
|
||||||
(message "Config reloaded"))
|
|
||||||
(define-key *top-map* (kbd "s-r") "reload-dotfiles")
|
|
||||||
|
|
||||||
;; (load (concat *config-dir* "/core/core.lisp"))
|
|
||||||
|
|
||||||
|
|
||||||
(defun show-key-seq (key seq val)
|
|
||||||
(message (print-key-seq (reverse seq))))
|
|
||||||
(add-hook *key-press-hook* 'show-key-seq)
|
|
||||||
|
|
||||||
|
|
||||||
;;; Config
|
|
||||||
(setf *mouse-focus-policy* :click)
|
|
||||||
(set-font "-CTDB-Fira Sans-normal-normal-normal-*-12-*-*-*-m-0-iso10646-1")
|
|
||||||
|
|
||||||
|
|
||||||
;;; Keybinds
|
|
||||||
(set-prefix-key (kbd "C-z"))
|
|
||||||
(define-key *top-map* (kbd "C-RET") "exec urxvt")
|
|
||||||
|
|
||||||
(let ((map *top-map*))
|
|
||||||
;; (gnew "a")
|
|
||||||
;; (gnew "b")
|
|
||||||
;; (gnew "c")
|
|
||||||
(dotimes (i 9)
|
|
||||||
(define-key map (kbd (format nil "s-~D" i))
|
|
||||||
(format nil "gselect ~D" i))
|
|
||||||
(define-key map (kbd (format nil "s-S-~D" i))
|
|
||||||
(format nil "gmove ~D" i))))
|
|
||||||
|
|
||||||
;; Window management
|
|
||||||
(define-key *top-map* (kbd "s-f") "float-this")
|
|
||||||
(define-key *top-map* (kbd "s-F") "unfloat-this")
|
|
||||||
|
|
||||||
(define-key *top-map* (kbd "s-h") "move-focus left")
|
|
||||||
(define-key *top-map* (kbd "s-j") "move-focus down")
|
|
||||||
(define-key *top-map* (kbd "s-k") "move-focus up")
|
|
||||||
(define-key *top-map* (kbd "s-l") "move-focus right")
|
|
||||||
|
|
||||||
(define-key *top-map* (kbd "s-H") "move-window left")
|
|
||||||
(define-key *top-map* (kbd "s-J") "move-window down")
|
|
||||||
(define-key *top-map* (kbd "s-K") "move-window up")
|
|
||||||
(define-key *top-map* (kbd "s-L") "move-window right")
|
|
||||||
|
|
||||||
(define-key *top-map* (kbd "s-RET") "exec xst")
|
|
||||||
(define-key *top-map* (kbd "s-SPC") "exec rofi/appmenu")
|
|
||||||
|
|
||||||
(define-key *top-map* (kbd "s-TAB") "next-in-frame")
|
|
||||||
(define-key *top-map* (kbd "s-ISO_Left_Tab") "prev-in-frame")
|
|
||||||
|
|
||||||
(define-key *top-map* (kbd "s-`") "exec scratch")
|
|
||||||
|
|
||||||
|
|
||||||
(defvar *window-manipulation-map* (make-sparse-keymap))
|
|
||||||
|
|
||||||
(defcommand kill-or-delete-window () ()
|
|
||||||
(and (delete-window)
|
|
||||||
(remove-split)))
|
|
||||||
|
|
||||||
(define-key *top-map* (kbd "s-q") "delete-window")
|
|
||||||
(define-key *top-map* (kbd "s-Q") "kill-or-delete-window")
|
|
||||||
(define-key *top-map* (kbd "s-w") *window-manipulation-map*)
|
|
||||||
(let ((map *window-manipulation-map*))
|
|
||||||
(define-key map (kbd "s-c") "remove-split")
|
|
||||||
(define-key map (kbd "s-s") "hsplit")
|
|
||||||
(define-key map (kbd "s-v") "vsplit"))
|
|
||||||
|
|
||||||
|
|
||||||
;;; Modeline
|
|
||||||
(setf *bar-med-color* "^B^3")
|
|
||||||
(setf *bar-hi-color* "^B^3")
|
|
||||||
(setf *bar-crit-color* "^B^1")
|
|
||||||
|
|
||||||
(setf *colors*
|
|
||||||
'("#101216" ; fg
|
|
||||||
"#f9a03f" ; orange
|
|
||||||
"#8BD49C" ; green
|
|
||||||
"#8abeb7" ; cyan
|
|
||||||
"#5EC4FF" ; blue
|
|
||||||
"#cc6666" ; red
|
|
||||||
"#E27E8D" ; magenta
|
|
||||||
"#f0c674" ; yellow
|
|
||||||
))
|
|
||||||
|
|
||||||
(update-color-map (current-screen))
|
|
||||||
|
|
||||||
(setf *group-format* " %t ")
|
|
||||||
(setf *window-format* "%m%s%20t ")
|
|
||||||
(setf *mode-line-timeout* 1)
|
|
||||||
|
|
||||||
(setf *time-modeline-string* "^B^3 %e %b %H:%M ^n")
|
|
||||||
|
|
||||||
(set-focus-color (elt *colors* 6))
|
|
||||||
(set-unfocus-color (elt *colors* 0))
|
|
||||||
|
|
||||||
(setf *screen-mode-line-format*
|
|
||||||
(list "^B^3%g ^n^b %W ^> "
|
|
||||||
" %B %d"
|
|
||||||
))
|
|
||||||
|
|
||||||
(setf *mode-line-border-width* 0)
|
|
||||||
(setf *mode-line-pad-x* 0)
|
|
||||||
(setf *mode-line-pad-y* 0)
|
|
||||||
(setf *mode-line-background-color* (elt *colors* 0))
|
|
||||||
(setf *mode-line-foreground-color* (elt *colors* 1))
|
|
||||||
|
|
||||||
(unless (head-mode-line (current-head))
|
|
||||||
(toggle-mode-line (current-screen) (current-head)))
|
|
|
@ -1,129 +0,0 @@
|
||||||
super + alt + Escape
|
|
||||||
bspc quit
|
|
||||||
|
|
||||||
super + {_,shift + }q
|
|
||||||
bspc node -{c,k}
|
|
||||||
|
|
||||||
super + t
|
|
||||||
bspc desktop -l next
|
|
||||||
|
|
||||||
super + apostrophe
|
|
||||||
bspc window -s last
|
|
||||||
|
|
||||||
# Attach to a detached session. If none is available create a new one, rather
|
|
||||||
# than attach to one that is already attached to elsewhere.
|
|
||||||
super + Return
|
|
||||||
kitty
|
|
||||||
|
|
||||||
ctrl + super + Return
|
|
||||||
xst -e bash -c "(tmux ls | grep -qEv 'attached|scratch' && tmux at) || tmux"
|
|
||||||
|
|
||||||
# Open a disposable, floating terminal window, for quick shell commands.
|
|
||||||
super + grave
|
|
||||||
scratch
|
|
||||||
|
|
||||||
# Open a disposable scratch buffer in a floating Emacs window, to run arbitrary
|
|
||||||
# code or quickly note something down.
|
|
||||||
super + shift + grave
|
|
||||||
emacsclient --eval "(open-scratch-frame)"
|
|
||||||
|
|
||||||
# Invoke emacs-everywhere at point.
|
|
||||||
super + e
|
|
||||||
emacsclient --eval "(emacs-everywhere)"
|
|
||||||
|
|
||||||
super + space
|
|
||||||
$DOTFILES_BIN/rofi/appmenu
|
|
||||||
|
|
||||||
super + Tab
|
|
||||||
$DOTFILES_BIN/rofi/windowmenu
|
|
||||||
|
|
||||||
super + p
|
|
||||||
$DOTFILES_BIN/rofi/bwmenu
|
|
||||||
|
|
||||||
super + shift + p
|
|
||||||
$DOTFILES_BIN/rofi/bwmenu -r
|
|
||||||
|
|
||||||
super + slash
|
|
||||||
$DOTFILES_BIN/rofi/filemenu -x
|
|
||||||
|
|
||||||
super + Escape
|
|
||||||
pkill -USR1 -x sxhkd
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
##
|
|
||||||
|
|
||||||
## Toggle floating/fullscreen
|
|
||||||
super + {_,ctrl + }f
|
|
||||||
bspc node -t ~{floating,fullscreen}
|
|
||||||
|
|
||||||
|
|
||||||
super + {_,ctrl +}{h,j,k,l}
|
|
||||||
$DOTFILES_BIN/bspwm/focus {_,-m }{west,south,north,east}
|
|
||||||
|
|
||||||
super + shift + {_,ctrl +}{h,j,k,l}
|
|
||||||
$DOTFILES_BIN/bspwm/swap {_,-m }{west,south,north,east}
|
|
||||||
|
|
||||||
## Resize by preselection
|
|
||||||
super + alt + {1-9}
|
|
||||||
$DOTFILES/bin/bspwm/presel 0.{1-9}
|
|
||||||
|
|
||||||
super + alt + {h,j,k,l}
|
|
||||||
bspc node -p {west,south,north,east}
|
|
||||||
|
|
||||||
super + alt + Return
|
|
||||||
$DOTFILES/bin/bspwm/subtract-presel
|
|
||||||
|
|
||||||
super + alt + Delete
|
|
||||||
bspc node -p cancel
|
|
||||||
|
|
||||||
super + {_,shift +}{1-9,0}
|
|
||||||
bspc {desktop -f,node -d} {1-9,10};
|
|
||||||
|
|
||||||
# expand a window by moving one of its side outward
|
|
||||||
super + {Left,Down,Up,Right}
|
|
||||||
bspc node -z {left -40 0,bottom 0 40,top 0 -40,right 40 0}
|
|
||||||
|
|
||||||
# contract a window by moving one of its side inward
|
|
||||||
super + ctrl + {Left,Down,Up,Right}
|
|
||||||
bspc node -z {right -40 0,top 0 40,bottom 0 -40,left 40 0}
|
|
||||||
|
|
||||||
# move a floating window
|
|
||||||
super + shift + {Left,Down,Up,Right}
|
|
||||||
bspc node -v {-40 0,0 40,0 -40,40 0}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
## Media keys
|
|
||||||
|
|
||||||
# screenshot region
|
|
||||||
Print
|
|
||||||
scrcap
|
|
||||||
# screencast region to mp4
|
|
||||||
super + Print
|
|
||||||
scrrec -s ~/recordings/$(date +%F-%T).mp4
|
|
||||||
# screencast region to gif
|
|
||||||
super + ctrl + Print
|
|
||||||
scrrec -s ~/recordings/$(date +%F-%T).gif
|
|
||||||
|
|
||||||
XF86MonBrightnessUp
|
|
||||||
light -A 5
|
|
||||||
XF86MonBrightnessDown
|
|
||||||
light -U 5
|
|
||||||
|
|
||||||
XF86AudioMute
|
|
||||||
amixer -q set Master toggle
|
|
||||||
XF86AudioLowerVolume
|
|
||||||
amixer -q set Master 10%- unmute
|
|
||||||
XF86AudioRaiseVolume
|
|
||||||
amixer -q set Master 10%+ unmute
|
|
||||||
|
|
||||||
XF86Audio{Play,Pause}
|
|
||||||
spt-send toggle
|
|
||||||
XF86AudioNext
|
|
||||||
spt-send next
|
|
||||||
XF86AudioPrev
|
|
||||||
spt-send prev
|
|
||||||
|
|
||||||
# X86Search
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
alias ta='tmux attach'
|
|
||||||
alias tl='tmux ls'
|
|
||||||
|
|
||||||
if [[ -n $TMUX ]]; then # From inside tmux
|
|
||||||
alias tf='tmux find-window'
|
|
||||||
# Detach all other clients to this session
|
|
||||||
alias mine='tmux detach -a'
|
|
||||||
# Send command to other tmux window
|
|
||||||
tt() {
|
|
||||||
tmux send-keys -t .+ C-u && \
|
|
||||||
tmux set-buffer "$*" && \
|
|
||||||
tmux paste-buffer -t .+ && \
|
|
||||||
tmux send-keys -t .+ Enter;
|
|
||||||
}
|
|
||||||
# Create new session (from inside one)
|
|
||||||
tn() {
|
|
||||||
local name="${1:-`basename $PWD`}"
|
|
||||||
TMUX= tmux new-session -d -s "$name"
|
|
||||||
tmux switch-client -t "$name"
|
|
||||||
tmux display-message "Session #S created"
|
|
||||||
}
|
|
||||||
else # From outside tmux
|
|
||||||
# Start grouped session so I can be in two different windows in one session
|
|
||||||
tdup() { tmux new-session -t "${1:-`tmux display-message -p '#S'`}"; }
|
|
||||||
fi
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
CONF="$TMUX_PLUGINS_PATH/lastpane"
|
|
||||||
swap() { tmux swap-pane -s"$1" -t"$2"; }
|
|
||||||
|
|
||||||
target=
|
|
||||||
case $1 in
|
|
||||||
up) target="U" ;;
|
|
||||||
down) target="D" ;;
|
|
||||||
left) target="L" ;;
|
|
||||||
right) target="R" ;;
|
|
||||||
master) target="M" ;;
|
|
||||||
*) exit 1 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
src_pane=$(tmux display-message -p "#P")
|
|
||||||
tmux select-pane -${target}
|
|
||||||
|
|
||||||
dst_pane=$(tmux display-message -p "#P")
|
|
||||||
tmux select-pane -${src_pane}
|
|
||||||
|
|
||||||
[[ "$target" == M ]] && dst_pane=0
|
|
||||||
swap "$src_pane" "$dst_pane"
|
|
||||||
tmux select-pane -t"$dst_pane"
|
|
|
@ -1,124 +0,0 @@
|
||||||
# tmux.conf
|
|
||||||
# By Henrik Lissner <henrik@lissner.net>
|
|
||||||
# https://github.com/hlissner/dotfiles
|
|
||||||
########################################
|
|
||||||
|
|
||||||
set -g default-terminal "xterm-256color"
|
|
||||||
|
|
||||||
new-session # spawn session if attaching when none are running
|
|
||||||
|
|
||||||
setw -g automatic-rename on # rename window after current program
|
|
||||||
set -g renumber-windows on # renumber windows when one is closed
|
|
||||||
# Zero-based indexing is fine in programming languages, but not so much in a
|
|
||||||
# multiplexer when zero is on the other side of the keyboard.
|
|
||||||
set -g base-index 1
|
|
||||||
setw -g pane-base-index 1
|
|
||||||
# display tmux messages longer
|
|
||||||
set -g display-time 1500
|
|
||||||
set -g display-panes-time 800
|
|
||||||
# Address vim-mode switching delay (http://superuser.com/a/252717/65504)
|
|
||||||
set -s escape-time 0
|
|
||||||
set -sg repeat-time 600
|
|
||||||
set -g history-limit 10000
|
|
||||||
# Rather than constraining window size to the maximum size of any client
|
|
||||||
# connected to the *session*, constrain window size to the maximum size of any
|
|
||||||
# client connected to *that window*. Much more reasonable.
|
|
||||||
setw -g aggressive-resize off
|
|
||||||
# For terminals that support them, propagate these events to programs that
|
|
||||||
# understand them.
|
|
||||||
set -s focus-events on
|
|
||||||
# Enable mouse + mouse wheel
|
|
||||||
set -g mouse on
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Keybinds #
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# Rebind prefix to C-c. Press twice to send literal C-c.
|
|
||||||
unbind C-b
|
|
||||||
set -g prefix C-c
|
|
||||||
bind C-c send-prefix
|
|
||||||
|
|
||||||
# Vi-style keybinds
|
|
||||||
set -g status-keys vi
|
|
||||||
set -g mode-keys vi
|
|
||||||
|
|
||||||
bind c new-window -c "#{pane_current_path}"
|
|
||||||
bind v split-window -h -c "#{pane_current_path}"
|
|
||||||
bind s split-window -v -c "#{pane_current_path}"
|
|
||||||
|
|
||||||
bind h select-pane -L
|
|
||||||
bind j select-pane -D
|
|
||||||
bind k select-pane -U
|
|
||||||
bind l select-pane -R
|
|
||||||
bind H run '$TMUX_HOME/swap-pane.sh left'
|
|
||||||
bind J run '$TMUX_HOME/swap-pane.sh down'
|
|
||||||
bind K run '$TMUX_HOME/swap-pane.sh up'
|
|
||||||
bind L run '$TMUX_HOME/swap-pane.sh right'
|
|
||||||
bind M run '$TMUX_HOME/swap-pane.sh master'
|
|
||||||
|
|
||||||
bind o resize-pane -Z
|
|
||||||
bind S choose-session
|
|
||||||
bind W choose-window
|
|
||||||
bind / choose-session
|
|
||||||
bind . choose-window
|
|
||||||
|
|
||||||
# bind = select-layout tiled
|
|
||||||
bind | select-layout even-horizontal
|
|
||||||
bind _ select-layout even-vertical
|
|
||||||
|
|
||||||
# Disable confirmation
|
|
||||||
bind x kill-pane
|
|
||||||
bind X kill-window
|
|
||||||
bind q kill-session
|
|
||||||
bind Q kill-server
|
|
||||||
|
|
||||||
# Smart pane switching with awareness of vim splits
|
|
||||||
# See: https://github.com/christoomey/vim-tmux-navigator
|
|
||||||
is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?x?)(diff)?$"'
|
|
||||||
bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
|
|
||||||
bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
|
|
||||||
bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
|
|
||||||
bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
|
|
||||||
bind -n C-\\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"
|
|
||||||
bind C-w last-pane
|
|
||||||
bind C-n next-window
|
|
||||||
bind C-p previous-window
|
|
||||||
|
|
||||||
# break pane into a window
|
|
||||||
bind = select-layout even-vertical
|
|
||||||
bind + select-layout even-horizontal
|
|
||||||
bind - break-pane
|
|
||||||
bind _ join-pane
|
|
||||||
|
|
||||||
# reload config without killing server
|
|
||||||
bind r source-file $DOTFILES/config/tmux/tmux.conf \; display-message " Config reloaded..".
|
|
||||||
bind ^r refresh-client
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Copy mode #
|
|
||||||
########################################
|
|
||||||
|
|
||||||
bind Enter copy-mode # enter copy mode
|
|
||||||
bind b list-buffers # list paster buffers
|
|
||||||
bind B choose-buffer # choose which buffer to paste from
|
|
||||||
bind p paste-buffer # paste from the top paste buffer
|
|
||||||
bind P run "xclip -selection clipboard -o | tmux load-buffer - ; tmux paste-buffer"
|
|
||||||
|
|
||||||
bind -T copy-mode-vi v send-keys -X begin-selection
|
|
||||||
bind -T copy-mode-vi C-v send-keys -X rectangle-toggle
|
|
||||||
bind -T copy-mode-vi Escape send-keys -X cancel
|
|
||||||
bind -T copy-mode-vi C-g send-keys -X cancel
|
|
||||||
bind -T copy-mode-vi H send-keys -X start-of-line
|
|
||||||
bind -T copy-mode-vi L send-keys -X end-of-line
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Local config #
|
|
||||||
########################################
|
|
||||||
set -g @open-editor 'C-e'
|
|
||||||
set -g @open-S 'https://www.duckduckgo.com/'
|
|
||||||
|
|
||||||
source $TMUX_HOME/extraInit
|
|
||||||
if '[ -f ~/.tmux.conf ]' 'source ~/.tmux.conf'
|
|
|
@ -1,5 +0,0 @@
|
||||||
## Auto-generated by my nix config
|
|
||||||
[ -f "${0:a:h}/extra.zshenv" ] && source "${0:a:h}/extra.zshenv"
|
|
||||||
|
|
||||||
# If you have host-local configuration, this is where you'd put it
|
|
||||||
[ -f ~/.zshenv ] && source ~/.zshenv
|
|
|
@ -1,51 +0,0 @@
|
||||||
[ -d "$ZGEN_DIR" ] || git clone https://github.com/tarjoilija/zgen "$ZGEN_DIR"
|
|
||||||
source $ZGEN_SOURCE
|
|
||||||
if ! zgen saved; then
|
|
||||||
echo "Initializing zgen"
|
|
||||||
zgen load hlissner/zsh-autopair autopair.zsh
|
|
||||||
zgen load zsh-users/zsh-history-substring-search
|
|
||||||
zgen load zdharma/history-search-multi-word
|
|
||||||
zgen load zsh-users/zsh-completions src
|
|
||||||
zgen load junegunn/fzf shell
|
|
||||||
[ -z "$SSH_CONNECTION" ] && zgen load zdharma/fast-syntax-highlighting
|
|
||||||
zgen save
|
|
||||||
fi
|
|
||||||
|
|
||||||
source $ZDOTDIR/config.zsh
|
|
||||||
if [[ $TERM != dumb ]]; then
|
|
||||||
source $ZDOTDIR/keybinds.zsh
|
|
||||||
source $ZDOTDIR/completion.zsh
|
|
||||||
source $ZDOTDIR/aliases.zsh
|
|
||||||
|
|
||||||
##
|
|
||||||
function _cache {
|
|
||||||
command -v "$1" >/dev/null || return 1
|
|
||||||
local cache_dir="$XDG_CACHE_HOME/${SHELL##*/}"
|
|
||||||
local cache="$cache_dir/$1"
|
|
||||||
if [[ ! -f $cache || ! -s $cache ]]; then
|
|
||||||
echo "Caching $1"
|
|
||||||
mkdir -p $cache_dir
|
|
||||||
"$@" >$cache
|
|
||||||
fi
|
|
||||||
source $cache || rm -f $cache
|
|
||||||
}
|
|
||||||
|
|
||||||
# fd > find
|
|
||||||
if command -v fd >/dev/null; then
|
|
||||||
export FZF_DEFAULT_OPTS="--reverse --ansi"
|
|
||||||
export FZF_DEFAULT_COMMAND="fd ."
|
|
||||||
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
|
|
||||||
export FZF_ALT_C_COMMAND="fd -t d . $HOME"
|
|
||||||
fi
|
|
||||||
_cache fasd --init posix-alias zsh-{hook,{c,w}comp{,-install}}
|
|
||||||
|
|
||||||
## Auto-generated by my nix config
|
|
||||||
source $ZDOTDIR/extra.zshrc
|
|
||||||
|
|
||||||
##
|
|
||||||
autoload -Uz compinit && compinit -u -d $ZSH_CACHE/zcompdump
|
|
||||||
autopair-init
|
|
||||||
|
|
||||||
# If you have host-local configuration, this is where you'd put it
|
|
||||||
[ -f ~/.zshrc ] && source ~/.zshrc
|
|
||||||
fi
|
|
|
@ -1,74 +0,0 @@
|
||||||
alias ..='cd ..'
|
|
||||||
alias ...='cd ../..'
|
|
||||||
alias ....='cd ../../..'
|
|
||||||
alias -- -='cd -'
|
|
||||||
alias cdg='cd `git rev-parse --show-toplevel`'
|
|
||||||
|
|
||||||
alias q=exit
|
|
||||||
alias clr=clear
|
|
||||||
alias sudo='sudo '
|
|
||||||
alias rm='rm -i'
|
|
||||||
alias cp='cp -i'
|
|
||||||
alias mv='mv -i'
|
|
||||||
alias mkdir='mkdir -pv'
|
|
||||||
alias wget='wget -c'
|
|
||||||
alias path='echo -e ${PATH//:/\\n}'
|
|
||||||
alias ports='netstat -tulanp'
|
|
||||||
|
|
||||||
alias mk=make
|
|
||||||
alias gurl='curl --compressed'
|
|
||||||
|
|
||||||
alias shutdown='sudo shutdown'
|
|
||||||
alias reboot='sudo reboot'
|
|
||||||
|
|
||||||
# An rsync that respects gitignore
|
|
||||||
rcp() {
|
|
||||||
# -a = -rlptgoD
|
|
||||||
# -r = recursive
|
|
||||||
# -l = copy symlinks as symlinks
|
|
||||||
# -p = preserve permissions
|
|
||||||
# -t = preserve mtimes
|
|
||||||
# -g = preserve owning group
|
|
||||||
# -o = preserve owner
|
|
||||||
# -z = use compression
|
|
||||||
# -P = show progress on transferred file
|
|
||||||
# -J = don't touch mtimes on symlinks (always errors)
|
|
||||||
rsync -azPJ \
|
|
||||||
--include=.git/ \
|
|
||||||
--filter=':- .gitignore' \
|
|
||||||
--filter=":- $XDG_CONFIG_HOME/git/ignore" \
|
|
||||||
"$@"
|
|
||||||
}; compdef rcp=rsync
|
|
||||||
alias rcpd='rcp --delete --delete-after'
|
|
||||||
alias rcpu='rcp --chmod=go='
|
|
||||||
alias rcpdu='rcpd --chmod=go='
|
|
||||||
|
|
||||||
alias y='xclip -selection clipboard -in'
|
|
||||||
alias p='xclip -selection clipboard -out'
|
|
||||||
|
|
||||||
alias jc='journalctl -xe'
|
|
||||||
alias sc=systemctl
|
|
||||||
alias ssc='sudo systemctl'
|
|
||||||
|
|
||||||
if command -v exa >/dev/null; then
|
|
||||||
alias exa="exa --group-directories-first --git";
|
|
||||||
alias l="exa -1";
|
|
||||||
alias ll="exa -lg";
|
|
||||||
alias la="LC_COLLATE=C exa -la";
|
|
||||||
fi
|
|
||||||
|
|
||||||
autoload -U zmv
|
|
||||||
|
|
||||||
take() {
|
|
||||||
mkdir "$1" && cd "$1";
|
|
||||||
}; compdef take=mkdir
|
|
||||||
|
|
||||||
zman() {
|
|
||||||
PAGER="less -g -I -s '+/^ "$1"'" man zshall;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a reminder with human-readable durations, e.g. 15m, 1h, 40s, etc
|
|
||||||
r() {
|
|
||||||
local time=$1; shift
|
|
||||||
sched "$time" "notify-send --urgency=critical 'Reminder' '$@'; ding";
|
|
||||||
}; compdef r=sched
|
|
|
@ -1,174 +0,0 @@
|
||||||
fpath+=( $ZDOTDIR/completions )
|
|
||||||
|
|
||||||
## Options
|
|
||||||
setopt COMPLETE_IN_WORD # Complete from both ends of a word.
|
|
||||||
setopt PATH_DIRS # Perform path search even on command names with slashes.
|
|
||||||
setopt AUTO_MENU # Show completion menu on a successive tab press.
|
|
||||||
setopt AUTO_LIST # Automatically list choices on ambiguous completion.
|
|
||||||
setopt AUTO_PARAM_SLASH # If completed parameter is a directory, add a trailing slash.
|
|
||||||
setopt AUTO_PARAM_KEYS
|
|
||||||
setopt FLOW_CONTROL # Disable start/stop characters in shell editor.
|
|
||||||
unsetopt MENU_COMPLETE # Do not autoselect the first completion entry.
|
|
||||||
unsetopt COMPLETE_ALIASES # Completion for aliases
|
|
||||||
unsetopt ALWAYS_TO_END # Move cursor to the end of a completed word.
|
|
||||||
unsetopt CASE_GLOB
|
|
||||||
|
|
||||||
# Use caching to make completion for commands such as dpkg and apt usable.
|
|
||||||
zstyle ':completion::complete:*' use-cache on
|
|
||||||
zstyle ':completion::complete:*' cache-path "$ZSH_CACHE/zcompcache"
|
|
||||||
|
|
||||||
# Case-insensitive (all), partial-word, and then substring completion.
|
|
||||||
zstyle ':completion:*' matcher-list '' \
|
|
||||||
'm:{a-z\-}={A-Z\_}' \
|
|
||||||
'r:[^[:alpha:]]||[[:alpha:]]=** r:|=* m:{a-z\-}={A-Z\_}' \
|
|
||||||
'r:[[:ascii:]]||[[:ascii:]]=** r:|=* m:{a-z\-}={A-Z\_}'
|
|
||||||
|
|
||||||
# Group matches and describe.
|
|
||||||
zstyle ':completion:*:*:*:*:*' menu select
|
|
||||||
zstyle ':completion:*:matches' group 'yes'
|
|
||||||
zstyle ':completion:*:options' description 'yes'
|
|
||||||
zstyle ':completion:*:options' auto-description '%d'
|
|
||||||
zstyle ':completion:*:corrections' format ' %F{green}-- %d (errors: %e) --%f'
|
|
||||||
zstyle ':completion:*:descriptions' format ' %F{yellow}-- %d --%f'
|
|
||||||
zstyle ':completion:*:messages' format ' %F{purple} -- %d --%f'
|
|
||||||
zstyle ':completion:*:warnings' format ' %F{red}-- no matches found --%f'
|
|
||||||
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
|
|
||||||
zstyle ':completion:*' format ' %F{yellow}-- %d --%f'
|
|
||||||
zstyle ':completion:*' group-name ''
|
|
||||||
zstyle ':completion:*' verbose yes
|
|
||||||
|
|
||||||
# Fuzzy match mistyped completions.
|
|
||||||
zstyle ':completion:*' completer _complete _list _match _approximate
|
|
||||||
zstyle ':completion:*:match:*' original only
|
|
||||||
zstyle ':completion:*:approximate:*' max-errors 1 numeric
|
|
||||||
|
|
||||||
# Increase the number of errors based on the length of the typed word.
|
|
||||||
zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
|
|
||||||
|
|
||||||
# Don't complete unavailable commands.
|
|
||||||
zstyle ':completion:*:functions' ignored-patterns '(_*|pre(cmd|exec))'
|
|
||||||
|
|
||||||
# Array completion element sorting.
|
|
||||||
zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
|
|
||||||
|
|
||||||
# Directories
|
|
||||||
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
|
|
||||||
zstyle ':completion:*:*:cd:*' ignore-parents parent pwd
|
|
||||||
zstyle ':completion:*:*:cd:*' tag-order local-directories directory-stack path-directories
|
|
||||||
zstyle ':completion:*:*:cd:*:directory-stack' menu yes select
|
|
||||||
zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand'
|
|
||||||
zstyle ':completion:*' squeeze-slashes true
|
|
||||||
zstyle ':completion:*' special-dirs true
|
|
||||||
|
|
||||||
# History
|
|
||||||
zstyle ':completion:*:history-words' stop yes
|
|
||||||
zstyle ':completion:*:history-words' remove-all-dups yes
|
|
||||||
zstyle ':completion:*:history-words' list false
|
|
||||||
zstyle ':completion:*:history-words' menu yes
|
|
||||||
|
|
||||||
# Environmental Variables
|
|
||||||
zstyle ':completion::*:(-command-|export):*' fake-parameters ${${${_comps[(I)-value-*]#*,}%%,*}:#-*-}
|
|
||||||
|
|
||||||
# Populate hostname completion.
|
|
||||||
zstyle -e ':completion:*:hosts' hosts 'reply=(
|
|
||||||
${=${=${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) 2>/dev/null)"}%%[#| ]*}//\]:[0-9]*/ }//,/ }//\[/ }
|
|
||||||
${=${${${${(@M)${(f)"$(cat ~/.ssh/config 2>/dev/null)"}:#Host *}#Host }:#*\**}:#*\?*}}
|
|
||||||
)'
|
|
||||||
|
|
||||||
# Don't complete uninteresting users...
|
|
||||||
zstyle ':completion:*:*:*:users' ignored-patterns \
|
|
||||||
adm amanda apache avahi beaglidx bin cacti canna clamav daemon \
|
|
||||||
dbus distcache dovecot fax ftp games gdm gkrellmd gopher \
|
|
||||||
hacluster haldaemon halt hsqldb ident junkbust ldap lp mail \
|
|
||||||
mailman mailnull mldonkey mysql nagios \
|
|
||||||
named netdump news nfsnobody nobody nscd ntp nut nx openvpn \
|
|
||||||
operator pcap postfix postgres privoxy pulse pvm quagga radvd \
|
|
||||||
rpc rpcuser rpm shutdown squid sshd sync uucp vcsa xfs '_*'
|
|
||||||
|
|
||||||
# ... unless we really want to.
|
|
||||||
zstyle '*' single-ignored show
|
|
||||||
|
|
||||||
# Ignore multiple entries.
|
|
||||||
zstyle ':completion:*:(rm|kill|diff):*' ignore-line other
|
|
||||||
zstyle ':completion:*:rm:*' file-patterns '*:all-files'
|
|
||||||
|
|
||||||
# Kill
|
|
||||||
zstyle ':completion:*:*:*:*:processes' command 'ps -u $LOGNAME -o pid,user,command -w'
|
|
||||||
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;36=0=01'
|
|
||||||
zstyle ':completion:*:*:kill:*' menu yes select
|
|
||||||
zstyle ':completion:*:*:kill:*' force-list always
|
|
||||||
zstyle ':completion:*:*:kill:*' insert-ids single
|
|
||||||
|
|
||||||
# Man
|
|
||||||
zstyle ':completion:*:manuals' separate-sections true
|
|
||||||
zstyle ':completion:*:manuals.(^1*)' insert-sections true
|
|
||||||
|
|
||||||
# Media Players
|
|
||||||
zstyle ':completion:*:*:mpg123:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories'
|
|
||||||
zstyle ':completion:*:*:mpg321:*' file-patterns '*.(mp3|MP3):mp3\ files *(-/):directories'
|
|
||||||
zstyle ':completion:*:*:ogg123:*' file-patterns '*.(ogg|OGG|flac):ogg\ files *(-/):directories'
|
|
||||||
zstyle ':completion:*:*:mocp:*' file-patterns '*.(wav|WAV|mp3|MP3|ogg|OGG|flac):ogg\ files *(-/):directories'
|
|
||||||
|
|
||||||
# SSH/SCP/RSYNC
|
|
||||||
zstyle ':completion:*:(scp|rsync):*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
|
|
||||||
zstyle ':completion:*:(scp|rsync):*' group-order users files all-files hosts-domain hosts-host hosts-ipaddr
|
|
||||||
zstyle ':completion:*:ssh:*' tag-order 'hosts:-host:host hosts:-domain:domain hosts:-ipaddr:ip\ address *'
|
|
||||||
zstyle ':completion:*:ssh:*' group-order users hosts-domain hosts-host users hosts-ipaddr
|
|
||||||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost
|
|
||||||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-domain' ignored-patterns '<->.<->.<->.<->' '^[-[:alnum:]]##(.[-[:alnum:]]##)##' '*@*'
|
|
||||||
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*'
|
|
||||||
|
|
||||||
# fzf
|
|
||||||
if command -v fzf >/dev/null; then
|
|
||||||
# fuzzy completion with 'z' when called without args
|
|
||||||
unalias z 2> /dev/null
|
|
||||||
z() {
|
|
||||||
[ $# -gt 0 ] && _z "$*" && return
|
|
||||||
cd "$(_z -l 2>&1 | fzf --height 40% --nth 2.. --reverse --inline-info +s --tac --query "${*##-* }" | sed 's/^[0-9,.]* *//')"
|
|
||||||
}
|
|
||||||
|
|
||||||
__git_log () {
|
|
||||||
# format str implies:
|
|
||||||
# --abbrev-commit
|
|
||||||
# --decorate
|
|
||||||
git log \
|
|
||||||
--color=always \
|
|
||||||
--graph \
|
|
||||||
--all \
|
|
||||||
--date=short \
|
|
||||||
--format="%C(bold blue)%h%C(reset) %C(green)%ad%C(reset) | %C(white)%s %C(red)[%an] %C(bold yellow)%d"
|
|
||||||
}
|
|
||||||
|
|
||||||
_fzf_complete_git() {
|
|
||||||
ARGS="$@"
|
|
||||||
|
|
||||||
# these are commands I commonly call on commit hashes.
|
|
||||||
# cp->cherry-pick, co->checkout
|
|
||||||
|
|
||||||
if [[ $ARGS == 'git cp'* || \
|
|
||||||
$ARGS == 'git cherry-pick'* || \
|
|
||||||
$ARGS == 'git co'* || \
|
|
||||||
$ARGS == 'git checkout'* || \
|
|
||||||
$ARGS == 'git reset'* || \
|
|
||||||
$ARGS == 'git show'* || \
|
|
||||||
$ARGS == 'git log'* ]]; then
|
|
||||||
_fzf_complete "--reverse --multi" "$@" < <(__git_log)
|
|
||||||
else
|
|
||||||
eval "zle ${fzf_default_completion:-expand-or-complete}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_fzf_complete_git_post() {
|
|
||||||
sed -e 's/^[^a-z0-9]*//' | awk '{print $1}'
|
|
||||||
}
|
|
||||||
|
|
||||||
# pass completion suggested by @d4ndo (#362) (slightly modified)
|
|
||||||
_fzf_complete_pass() {
|
|
||||||
_fzf_complete '+m' "$@" < <(
|
|
||||||
local pwdir=${PASSWORD_STORE_DIR-~/.password-store/}
|
|
||||||
find "$pwdir" -name "*.gpg" -print |
|
|
||||||
sed -e "s#${pwdir}/\{0,1\}##" |
|
|
||||||
sed -e 's/\(.*\)\.gpg/\1/'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fi
|
|
|
@ -1,36 +0,0 @@
|
||||||
#compdef hey
|
|
||||||
|
|
||||||
_hey_dispatch () {
|
|
||||||
local cmd="$@"
|
|
||||||
local offset=$#
|
|
||||||
CURRENT=$((CURRENT-$offset))
|
|
||||||
words=($cmd "${words[$((2 + offset)),-1]}")
|
|
||||||
_$cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
_hey_command_list () {
|
|
||||||
hey | sed '1,/Available commands:/d' | awk '{ print $1 }'
|
|
||||||
}
|
|
||||||
|
|
||||||
_hey () {
|
|
||||||
local -a commands
|
|
||||||
IFS=$'\n' commands=($(_hey_command_list))
|
|
||||||
|
|
||||||
if (( CURRENT == 2 )); then
|
|
||||||
_describe -t commands "hey commands" commands
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
integer ret=1
|
|
||||||
case ${words[2]} in
|
|
||||||
ch|channel) _hey_dispatch nix-channel ;;
|
|
||||||
b|build) _hey_dispatch nix-build ;;
|
|
||||||
ch|check) _hey_dispatch nix flake check ;;
|
|
||||||
sh|show) _hey_dispatch nix flake show ;;
|
|
||||||
s|search) _hey_dispatch nix search nixpkgs ;;
|
|
||||||
-*) _hey_dispatch nix-env ;;
|
|
||||||
*) _message "Command not found: ${words[2]}" ;;
|
|
||||||
esac
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
_hey
|
|
|
@ -1,64 +0,0 @@
|
||||||
# Stop TRAMP (in Emacs) from hanging or term/shell from echoing back commands
|
|
||||||
if [[ $TERM == dumb || -n $INSIDE_EMACS ]]; then
|
|
||||||
unsetopt zle prompt_cr prompt_subst
|
|
||||||
whence -w precmd >/dev/null && unfunction precmd
|
|
||||||
whence -w preexec >/dev/null && unfunction preexec
|
|
||||||
PS1='$ '
|
|
||||||
fi
|
|
||||||
|
|
||||||
## General
|
|
||||||
export _FASD_DATA="$XDG_CACHE_HOME/fasd"
|
|
||||||
export _FASD_VIMINFO="$XDG_CACHE_HOME/viminfo"
|
|
||||||
|
|
||||||
# Treat these characters as part of a word.
|
|
||||||
WORDCHARS='_-*?[]~&.;!#$%^(){}<>'
|
|
||||||
|
|
||||||
unsetopt BRACE_CCL # Allow brace character class list expansion.
|
|
||||||
setopt COMBINING_CHARS # Combine zero-length punc chars (accents) with base char
|
|
||||||
setopt RC_QUOTES # Allow 'Henry''s Garage' instead of 'Henry'\''s Garage'
|
|
||||||
setopt HASH_LIST_ALL
|
|
||||||
unsetopt CORRECT_ALL
|
|
||||||
unsetopt NOMATCH
|
|
||||||
unsetopt MAIL_WARNING # Don't print a warning message if a mail file has been accessed.
|
|
||||||
unsetopt BEEP # Hush now, quiet now.
|
|
||||||
setopt IGNOREEOF
|
|
||||||
|
|
||||||
## Jobs
|
|
||||||
setopt LONG_LIST_JOBS # List jobs in the long format by default.
|
|
||||||
setopt AUTO_RESUME # Attempt to resume existing job before creating a new process.
|
|
||||||
setopt NOTIFY # Report status of background jobs immediately.
|
|
||||||
unsetopt BG_NICE # Don't run all background jobs at a lower priority.
|
|
||||||
unsetopt HUP # Don't kill jobs on shell exit.
|
|
||||||
unsetopt CHECK_JOBS # Don't report on jobs when shell exit.
|
|
||||||
|
|
||||||
## History
|
|
||||||
HISTFILE="$XDG_CACHE_HOME/zhistory"
|
|
||||||
HISTSIZE=1000 # Max events to store in internal history.
|
|
||||||
SAVEHIST=1000 # Max events to store in history file.
|
|
||||||
|
|
||||||
setopt BANG_HIST # Don't treat '!' specially during expansion.
|
|
||||||
setopt EXTENDED_HISTORY # Write the history file in the ':start:elapsed;command' format.
|
|
||||||
setopt APPEND_HISTORY # Appends history to history file on exit
|
|
||||||
setopt INC_APPEND_HISTORY # Write to the history file immediately, not when the shell exits.
|
|
||||||
setopt SHARE_HISTORY # Share history between all sessions.
|
|
||||||
setopt HIST_EXPIRE_DUPS_FIRST # Expire a duplicate event first when trimming history.
|
|
||||||
setopt HIST_IGNORE_DUPS # Do not record an event that was just recorded again.
|
|
||||||
setopt HIST_IGNORE_ALL_DUPS # Delete an old recorded event if a new event is a duplicate.
|
|
||||||
setopt HIST_FIND_NO_DUPS # Do not display a previously found event.
|
|
||||||
setopt HIST_IGNORE_SPACE # Do not record an event starting with a space.
|
|
||||||
setopt HIST_SAVE_NO_DUPS # Do not write a duplicate event to the history file.
|
|
||||||
setopt HIST_VERIFY # Do not execute immediately upon history expansion.
|
|
||||||
setopt HIST_BEEP # Beep when accessing non-existent history.
|
|
||||||
|
|
||||||
## Directories
|
|
||||||
DIRSTACKSIZE=9
|
|
||||||
setopt AUTO_CD # Auto changes to a directory without typing cd.
|
|
||||||
setopt AUTO_PUSHD # Push the old directory onto the stack on cd.
|
|
||||||
setopt PUSHD_IGNORE_DUPS # Do not store duplicates in the stack.
|
|
||||||
setopt PUSHD_SILENT # Do not print the directory stack after pushd or popd.
|
|
||||||
setopt PUSHD_TO_HOME # Push to home directory when no argument is given.
|
|
||||||
setopt CDABLE_VARS # Change directory to a path stored in a variable.
|
|
||||||
setopt MULTIOS # Write to multiple descriptors.
|
|
||||||
setopt EXTENDED_GLOB # Use extended globbing syntax.
|
|
||||||
unsetopt GLOB_DOTS
|
|
||||||
unsetopt AUTO_NAME_DIRS # Don't add variable-stored paths to ~ list
|
|
|
@ -1,127 +0,0 @@
|
||||||
# The surround module wasn't working if KEYTIMEOUT was <= 10. Specifically,
|
|
||||||
# (delete|change)-surround immediately abort into insert mode if KEYTIMEOUT <=
|
|
||||||
# 8. If <= 10, then add-surround does the same. At 11, all these issues vanish.
|
|
||||||
# Very strange!
|
|
||||||
export KEYTIMEOUT=15
|
|
||||||
|
|
||||||
autoload -U is-at-least
|
|
||||||
|
|
||||||
## vi-mode ###############
|
|
||||||
bindkey -v
|
|
||||||
bindkey -M viins 'jk' vi-cmd-mode
|
|
||||||
bindkey -M viins ' ' magic-space
|
|
||||||
# bindkey -M viins '^I' expand-or-complete-prefix
|
|
||||||
|
|
||||||
# surround
|
|
||||||
autoload -Uz surround
|
|
||||||
zle -N delete-surround surround
|
|
||||||
zle -N add-surround surround
|
|
||||||
zle -N change-surround surround
|
|
||||||
bindkey -a cs change-surround
|
|
||||||
bindkey -a ds delete-surround
|
|
||||||
bindkey -a ys add-surround
|
|
||||||
|
|
||||||
# <5.0.8 doesn't have visual map
|
|
||||||
if is-at-least 5.0.8; then
|
|
||||||
bindkey -M visual S add-surround
|
|
||||||
|
|
||||||
# add vimmish text-object support to zsh
|
|
||||||
autoload -U select-quoted; zle -N select-quoted
|
|
||||||
for m in visual viopp; do
|
|
||||||
for c in {a,i}{\',\",\`}; do
|
|
||||||
bindkey -M $m $c select-quoted
|
|
||||||
done
|
|
||||||
done
|
|
||||||
autoload -U select-bracketed; zle -N select-bracketed
|
|
||||||
for m in visual viopp; do
|
|
||||||
for c in {a,i}${(s..)^:-'()[]{}<>bB'}; do
|
|
||||||
bindkey -M $m $c select-bracketed
|
|
||||||
done
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Open current prompt in external editor
|
|
||||||
autoload -Uz edit-command-line; zle -N edit-command-line
|
|
||||||
bindkey '^ ' edit-command-line
|
|
||||||
|
|
||||||
bindkey -M viins '^n' history-substring-search-down
|
|
||||||
bindkey -M viins '^p' history-substring-search-up
|
|
||||||
bindkey -M viins '^s' history-incremental-pattern-search-backward
|
|
||||||
bindkey -M viins '^u' backward-kill-line
|
|
||||||
bindkey -M viins '^w' backward-kill-word
|
|
||||||
bindkey -M viins '^b' backward-word
|
|
||||||
bindkey -M viins '^f' forward-word
|
|
||||||
bindkey -M viins '^g' push-line-or-edit
|
|
||||||
bindkey -M viins '^a' beginning-of-line
|
|
||||||
bindkey -M viins '^e' end-of-line
|
|
||||||
bindkey -M viins '^d' push-line-or-edit
|
|
||||||
|
|
||||||
bindkey -M vicmd '^k' kill-line
|
|
||||||
bindkey -M vicmd 'H' run-help
|
|
||||||
|
|
||||||
# Shift + Tab
|
|
||||||
bindkey -M viins '^[[Z' reverse-menu-complete
|
|
||||||
|
|
||||||
# bind UP and DOWN arrow keys
|
|
||||||
bindkey '^[[A' history-substring-search-up
|
|
||||||
bindkey '^[[B' history-substring-search-down
|
|
||||||
|
|
||||||
# C-z to toggle current process (background/foreground)
|
|
||||||
fancy-ctrl-z () {
|
|
||||||
if [[ $#BUFFER -eq 0 ]]; then
|
|
||||||
BUFFER="fg"
|
|
||||||
zle accept-line
|
|
||||||
else
|
|
||||||
zle push-input
|
|
||||||
zle clear-screen
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
zle -N fancy-ctrl-z
|
|
||||||
bindkey '^Z' fancy-ctrl-z
|
|
||||||
|
|
||||||
# Omni-Completion
|
|
||||||
bindkey -M viins '^x^f' fasd-complete-f # C-x C-f to do fasd-complete-f (only files)
|
|
||||||
bindkey -M viins '^x^d' fasd-complete-d # C-x C-d to do fasd-complete-d (only directories)
|
|
||||||
# Completing words in buffer in tmux
|
|
||||||
if [ -n "$TMUX" ]; then
|
|
||||||
_tmux_pane_words() {
|
|
||||||
local expl
|
|
||||||
local -a w
|
|
||||||
if [[ -z "$TMUX_PANE" ]]; then
|
|
||||||
_message "not running inside tmux!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
w=( ${(u)=$(tmux capture-pane \; show-buffer \; delete-buffer)} )
|
|
||||||
_wanted values expl 'words from current tmux pane' compadd -a w
|
|
||||||
}
|
|
||||||
|
|
||||||
zle -C tmux-pane-words-prefix complete-word _generic
|
|
||||||
zle -C tmux-pane-words-anywhere complete-word _generic
|
|
||||||
|
|
||||||
bindkey -M viins '^x^n' tmux-pane-words-prefix
|
|
||||||
bindkey -M viins '^x^o' tmux-pane-words-anywhere
|
|
||||||
|
|
||||||
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' completer _tmux_pane_words
|
|
||||||
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' ignore-line current
|
|
||||||
zstyle ':completion:tmux-pane-words-anywhere:*' matcher-list 'b:=* m:{A-Za-z}={a-zA-Z}'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Vim's C-x C-l in zsh
|
|
||||||
history-beginning-search-backward-then-append() {
|
|
||||||
zle history-beginning-search-backward
|
|
||||||
zle vi-add-eol
|
|
||||||
}
|
|
||||||
zle -N history-beginning-search-backward-then-append
|
|
||||||
bindkey -M viins '^x^l' history-beginning-search-backward-then-append
|
|
||||||
|
|
||||||
# Fix the DEL key
|
|
||||||
bindkey -M vicmd "^[[3~" delete-char
|
|
||||||
bindkey "^[[3~" delete-char
|
|
||||||
|
|
||||||
# Fix vimmish ESC
|
|
||||||
bindkey -sM vicmd '^[' '^G'
|
|
||||||
bindkey -rM viins '^X'
|
|
||||||
bindkey -M viins '^X,' _history-complete-newer \
|
|
||||||
'^X/' _history-complete-older \
|
|
||||||
'^X`' _bash_complete-word
|
|
||||||
|
|
143
configuration.nix
Normal file
143
configuration.nix
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
# Edit this configuration file to define what should be installed on
|
||||||
|
# your system. Help is available in the configuration.nix(5) man page
|
||||||
|
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||||
|
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ # Include the results of the hardware scan.
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./common.nix
|
||||||
|
./box.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = [ pkgs.wpa_supplicant ];
|
||||||
|
# Use the GRUB 2 boot loader.
|
||||||
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
|
boot.loader.efi.efiSysMountPoint = "/boot/efi";
|
||||||
|
boot.loader.grub = {
|
||||||
|
enable = true;
|
||||||
|
device = "nodev";
|
||||||
|
version = 2;
|
||||||
|
efiSupport = true;
|
||||||
|
enableCryptodisk = true;
|
||||||
|
efiInstallAsRemovable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.initrd.secrets = {
|
||||||
|
"/keyfile0.bin" = /etc/secrets/initrd/keyfile0.bin;
|
||||||
|
"/keyfile1.bin" = /etc/secrets/initrd/keyfile1.bin;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.initrd.luks.devices = {
|
||||||
|
"root" = {
|
||||||
|
#name = "root";
|
||||||
|
device = "/dev/disk/by-uuid/f37f3222-47d7-42d8-b400-363320a31853"; # UUID for /dev/nvme01np2
|
||||||
|
preLVM = true;
|
||||||
|
allowDiscards = true;
|
||||||
|
keyFile = "/keyfile0.bin";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Data mount
|
||||||
|
fileSystems."/data" = {
|
||||||
|
device = "/dev/disk/by-uuid/3276a297-9ee4-4998-b262-1ed100366c06"; # UUID for /dev/mapper/crypted-data
|
||||||
|
encrypted = {
|
||||||
|
enable = true;
|
||||||
|
label = "crypted-data";
|
||||||
|
blkDev = "/dev/disk/by-uuid/8a317bf4-fe13-4334-a6df-5fe5a5048b5e"; # UUID for /dev/sda1
|
||||||
|
keyFile = "/keyfile1.bin";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# boot.loader.grub.efiInstallAsRemovable = true;
|
||||||
|
# boot.loader.efi.efiSysMountPoint = "/boot/efi";
|
||||||
|
# Define on which hard drive you want to install Grub.
|
||||||
|
# boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
|
||||||
|
|
||||||
|
networking.hostName = "box"; # Define your hostname.
|
||||||
|
networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
||||||
|
|
||||||
|
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
|
||||||
|
# Per-interface useDHCP will be mandatory in the future, so this generated config
|
||||||
|
# replicates the default behaviour.
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.interfaces.wlp3s0.useDHCP = true;
|
||||||
|
networking.interfaces.enp2s0.useDHCP = false;
|
||||||
|
|
||||||
|
# Configure network proxy if necessary
|
||||||
|
# networking.proxy.default = "http://user:password@proxy:port/";
|
||||||
|
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||||
|
|
||||||
|
# Select internationalisation properties.
|
||||||
|
# i18n = {
|
||||||
|
# consoleFont = "Lat2-Terminus16";
|
||||||
|
# consoleKeyMap = "us";
|
||||||
|
# defaultLocale = "en_US.UTF-8";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# Set your time zone.
|
||||||
|
# time.timeZone = "Europe/Amsterdam";
|
||||||
|
|
||||||
|
# List packages installed in system profile. To search, run:
|
||||||
|
# $ nix search wget
|
||||||
|
# environment.systemPackages = with pkgs; [
|
||||||
|
# wget vim
|
||||||
|
# ];
|
||||||
|
|
||||||
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
|
# started in user sessions.
|
||||||
|
# programs.mtr.enable = true;
|
||||||
|
# programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
|
||||||
|
|
||||||
|
# List services that you want to enable:
|
||||||
|
|
||||||
|
# Enable the OpenSSH daemon.
|
||||||
|
services.openssh.enable = true;
|
||||||
|
services.openssh.permitRootLogin = "yes";
|
||||||
|
|
||||||
|
# Open ports in the firewall.
|
||||||
|
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||||
|
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||||
|
# Or disable the firewall altogether.
|
||||||
|
# networking.firewall.enable = false;
|
||||||
|
|
||||||
|
# Enable CUPS to print documents.
|
||||||
|
# services.printing.enable = true;
|
||||||
|
|
||||||
|
# Enable sound.
|
||||||
|
sound.enable = false;
|
||||||
|
# hardware.pulseaudio.enable = true;
|
||||||
|
|
||||||
|
# Enable the X11 windowing system.
|
||||||
|
# services.xserver.enable = true;
|
||||||
|
# services.xserver.layout = "us";
|
||||||
|
# services.xserver.xkbOptions = "eurosign:e";
|
||||||
|
|
||||||
|
# Enable touchpad support.
|
||||||
|
# services.xserver.libinput.enable = true;
|
||||||
|
|
||||||
|
# Enable the KDE Desktop Environment.
|
||||||
|
# services.xserver.displayManager.sddm.enable = true;
|
||||||
|
# services.xserver.desktopManager.plasma5.enable = true;
|
||||||
|
|
||||||
|
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||||
|
users.users.anish = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
|
||||||
|
hashedPassword = "MO0Pbd2O4eIlA";
|
||||||
|
openssh.authorizedKeys.keys = ["
|
||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCeWQsf9rbE+KBrWLkLkg1PMKx0jPfDP8xyv+XtddIQzAskRTN+JSSQp1GpoRgfQij7bx6f6DfjkwSQK5NWDQNQ+klGhcdEwEdptWUzpRAvKHMImjyIwFHmRKKEgcfH8+DSHVM93nRSQKrLezX4PzPkHF9f3TLxFdGeQDeY0J2oP2Oa97hRtuTJZW9BwUojyvDYUbg7F3fxf+pdFCvIAFaayiLkhOYdTXnjLt1Ks6NOhSzM78ZibHv4pFYI9r6dhflkFP/SzyLeSSm1aVAtxqE7vF5HnnORAg0byDsiOv/9RXxiDx7gkAAw3xENDSpp9TRj54M7iz1OSsRMhmD6orHjZFIRejlE4DIn+PBPm3PH+U5ILKTogE6n5MfPT28V0QdtHuqq3b5tSWiDcFpnjxbIUmEIo5hLzMR0tXZoNLQhBCSNfxjE8CYzpk7mHbvhSs2GPfG+NI1vvldbw2EF8beJFQHNYTqJw8y7p8RXpCwZqqpSitJX6v9DiYdLVG1hWvE= nix-on-droid@localhost
|
||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDM0Zvei46x/yZl/IeBCq6+IYQQ0avulzVyBysF9cPigZMCybWRV7IEU+E3k9t6JrbdbdGfJkcZIWmsWDdKS8W8mBnZpVoT0ffLynu8JQ/TKdGm4Qv6bgUeKNrGsNv0ZPs2CDaGSLj0oJfRF7Ko10tcLP0vW+yujrh+y6TH/vVzJioaV4TGvtCUpn+wEQah9ROwPQLUUofsSWdnRsDJ/gp37zXWs4l5wyjSKtP3O9RZUP7kBekbSqEgSXiTk0oUQSVqIWl9NDiP6onk/gSOjXsR/JPqsSN/XI/c/yj6gyY0f51Ru2D7iBxuMJIJcWV+rU6coIj+ULcQWLzt/7TI8jq5AOOzI/ll4zbL24Eo84Rz+TP9tvMMhDZ0VaMN22AJ8qQEjc5P09tWKsX7Jg39XelyV1jHXncE4yvIE9F4RSCHzWCeKeXakizQNuzSaxTxIExRFYHjNW5bR6+3MTGwVrEIXU+qML+0yFTR86MT+tdY5AreAJQLwbog79O1NupeXJE= anish@curve
|
||||||
|
"];
|
||||||
|
};
|
||||||
|
|
||||||
|
# This value determines the NixOS release with which your system is to be
|
||||||
|
# compatible, in order to avoid breaking some software such as database
|
||||||
|
# servers. You should change this only after NixOS release notes say you
|
||||||
|
# should.
|
||||||
|
system.stateVersion = "19.09"; # Did you read the comment?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
10
cron.nix
Normal file
10
cron.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.cron = {
|
||||||
|
enable = true;
|
||||||
|
systemCronJobs = [
|
||||||
|
"* */24 * * * * anish ~/get-music.sh"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
67
default.nix
67
default.nix
|
@ -1,67 +0,0 @@
|
||||||
{ inputs, config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
with lib.my;
|
|
||||||
{
|
|
||||||
imports =
|
|
||||||
# I use home-manager to deploy files to $HOME; little else
|
|
||||||
[ inputs.home-manager.nixosModules.home-manager ]
|
|
||||||
# All my personal modules
|
|
||||||
++ (mapModulesRec' (toString ./modules) import);
|
|
||||||
|
|
||||||
# Common config for all nixos machines; and to ensure the flake operates
|
|
||||||
# soundly
|
|
||||||
environment.variables.DOTFILES = config.dotfiles.dir;
|
|
||||||
environment.variables.DOTFILES_BIN = config.dotfiles.binDir;
|
|
||||||
|
|
||||||
# Configure nix and nixpkgs
|
|
||||||
environment.variables.NIXPKGS_ALLOW_UNFREE = "1";
|
|
||||||
nix =
|
|
||||||
let filteredInputs = filterAttrs (n: _: n != "self") inputs;
|
|
||||||
nixPathInputs = mapAttrsToList (n: v: "${n}=${v}") filteredInputs;
|
|
||||||
registryInputs = mapAttrs (_: v: { flake = v; }) filteredInputs;
|
|
||||||
in {
|
|
||||||
package = pkgs.nixFlakes;
|
|
||||||
extraOptions = "experimental-features = nix-command flakes";
|
|
||||||
nixPath = nixPathInputs ++ [
|
|
||||||
"nixpkgs-overlays=${config.dotfiles.dir}/overlays"
|
|
||||||
"dotfiles=${config.dotfiles.dir}"
|
|
||||||
];
|
|
||||||
binaryCaches = [
|
|
||||||
"https://nix-community.cachix.org"
|
|
||||||
];
|
|
||||||
binaryCachePublicKeys = [
|
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
|
||||||
];
|
|
||||||
registry = registryInputs // { dotfiles.flake = inputs.self; };
|
|
||||||
autoOptimiseStore = true;
|
|
||||||
};
|
|
||||||
system.configurationRevision = with inputs; mkIf (self ? rev) self.rev;
|
|
||||||
system.stateVersion = "21.05";
|
|
||||||
|
|
||||||
## Some reasonable, global defaults
|
|
||||||
# This is here to appease 'nix flake check' for generic hosts with no
|
|
||||||
# hardware-configuration.nix or fileSystem config.
|
|
||||||
fileSystems."/".device = mkDefault "/dev/disk/by-label/nixos";
|
|
||||||
|
|
||||||
# Use the latest kernel
|
|
||||||
boot = {
|
|
||||||
kernelPackages = mkDefault pkgs.linuxPackages_5_12;
|
|
||||||
loader = {
|
|
||||||
efi.canTouchEfiVariables = mkDefault true;
|
|
||||||
systemd-boot.configurationLimit = 10;
|
|
||||||
systemd-boot.enable = mkDefault true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Just the bear necessities...
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
bind
|
|
||||||
cached-nix-shell
|
|
||||||
git
|
|
||||||
vim
|
|
||||||
wget
|
|
||||||
gnumake
|
|
||||||
unzip
|
|
||||||
];
|
|
||||||
}
|
|
10
dev.nix
Normal file
10
dev.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{config, pkgs, ...}:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Database
|
||||||
|
services.postgresql.enable = true;
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
users.users."anish".extraGroups = [ "docker" ];
|
||||||
|
}
|
16
dns.nix
Normal file
16
dns.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
services.dnsmasq.enable = true;
|
||||||
|
services.dnsmasq.extraConfig = ''
|
||||||
|
domain-needed
|
||||||
|
no-resolv
|
||||||
|
local=/lan/
|
||||||
|
local=/moss/
|
||||||
|
cache-size=5000
|
||||||
|
addn-hosts=/ec/adblock.hosts
|
||||||
|
'';
|
||||||
|
services.dnsmasq.servers = [ "45.90.30.49" "45.90.28.49" "1.1.1.1" "8.8.8.8" ];
|
||||||
|
networking.hosts = {"192.168.1.240" = ["mossnet.lan" "links.mossnet.lan" "read.mossnet.lan" "stats.mossnet.lan" "music.moss" "tasks.moss" "headphones.moss" "cloud.moss" "links.moss" "read.moss" "stats.moss" "rss.moss"];};
|
||||||
|
networking.firewall.allowedTCPPorts = [ 53 ];
|
||||||
|
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||||
|
}
|
117
flake.lock
117
flake.lock
|
@ -1,117 +0,0 @@
|
||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"agenix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1626960455,
|
|
||||||
"narHash": "sha256-N3+qOtsADo59UcG8PxqNMhT94wqTQ73k08gpy1dLaWU=",
|
|
||||||
"owner": "ryantm",
|
|
||||||
"repo": "agenix",
|
|
||||||
"rev": "fb00f178b3a49a39cc964049075439b575d36d60",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "ryantm",
|
|
||||||
"repo": "agenix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"emacs-overlay": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1627320437,
|
|
||||||
"narHash": "sha256-1HGXjkm7kElz3VsGSciaQlZclUhyvfIXVl+FOooBTJo=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "emacs-overlay",
|
|
||||||
"rev": "9da066d11fbedda841cae9d06c5391e1ebd65801",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "emacs-overlay",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"home-manager": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1627312560,
|
|
||||||
"narHash": "sha256-h2mpDJIu/rd4nZX4i5U1AFA/3MGXrmFRFy04FDxnvhE=",
|
|
||||||
"owner": "rycee",
|
|
||||||
"repo": "home-manager",
|
|
||||||
"rev": "f6f6990fc811454cb3082ba3662b711488fd0554",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "rycee",
|
|
||||||
"ref": "master",
|
|
||||||
"repo": "home-manager",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixos-hardware": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1627212500,
|
|
||||||
"narHash": "sha256-KMUQCT3JSqznp+dR6BTvbwLqPFErjNlotVpkp/P/ZmM=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixos-hardware",
|
|
||||||
"rev": "03e7686c72345f237405c0b46b153dccd3ec9913",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixos-hardware",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1627128856,
|
|
||||||
"narHash": "sha256-yw3lA8zyNFhj309lmxvNByEEymRT1rRy5oE+jEPnsP4=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "dd14e5d78e90a2ccd6007e569820de9b4861a6c2",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-unstable": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1627170405,
|
|
||||||
"narHash": "sha256-6t7ISnt0Iqc2jxIf5+/su6eFmZNWnPAOA1JeOv9lLRE=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "ecaf3da9340231e5493eccc3db87604a3705da42",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"agenix": "agenix",
|
|
||||||
"emacs-overlay": "emacs-overlay",
|
|
||||||
"home-manager": "home-manager",
|
|
||||||
"nixos-hardware": "nixos-hardware",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
85
flake.nix
85
flake.nix
|
@ -1,85 +0,0 @@
|
||||||
# flake.nix --- the heart of my dotfiles
|
|
||||||
#
|
|
||||||
# Author: Henrik Lissner <henrik@lissner.net>
|
|
||||||
# URL: https://github.com/hlissner/dotfiles
|
|
||||||
# License: MIT
|
|
||||||
#
|
|
||||||
# Welcome to ground zero. Where the whole flake gets set up and all its modules
|
|
||||||
# are loaded.
|
|
||||||
|
|
||||||
{
|
|
||||||
description = "A grossly incandescent nixos config.";
|
|
||||||
|
|
||||||
inputs =
|
|
||||||
{
|
|
||||||
# Core dependencies.
|
|
||||||
nixpkgs.url = "nixpkgs/nixos-unstable"; # primary nixpkgs
|
|
||||||
nixpkgs-unstable.url = "nixpkgs/nixpkgs-unstable"; # for packages on the edge
|
|
||||||
home-manager.url = "github:rycee/home-manager/master";
|
|
||||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
agenix.url = "github:ryantm/agenix";
|
|
||||||
agenix.inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
|
|
||||||
# Extras
|
|
||||||
emacs-overlay.url = "github:nix-community/emacs-overlay";
|
|
||||||
nixos-hardware.url = "github:nixos/nixos-hardware";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = inputs @ { self, nixpkgs, nixpkgs-unstable, ... }:
|
|
||||||
let
|
|
||||||
inherit (lib.my) mapModules mapModulesRec mapHosts;
|
|
||||||
|
|
||||||
system = "x86_64-linux";
|
|
||||||
|
|
||||||
mkPkgs = pkgs: extraOverlays: import pkgs {
|
|
||||||
inherit system;
|
|
||||||
config.allowUnfree = true; # forgive me Stallman senpai
|
|
||||||
overlays = extraOverlays ++ (lib.attrValues self.overlays);
|
|
||||||
};
|
|
||||||
pkgs = mkPkgs nixpkgs [ self.overlay ];
|
|
||||||
pkgs' = mkPkgs nixpkgs-unstable [ ];
|
|
||||||
|
|
||||||
lib = nixpkgs.lib.extend
|
|
||||||
(self: super: { my = import ./lib { inherit pkgs inputs; lib = self; }; });
|
|
||||||
in {
|
|
||||||
lib = lib.my;
|
|
||||||
|
|
||||||
overlay =
|
|
||||||
final: prev: {
|
|
||||||
unstable = pkgs';
|
|
||||||
my = self.packages."${system}";
|
|
||||||
};
|
|
||||||
|
|
||||||
overlays =
|
|
||||||
mapModules ./overlays import;
|
|
||||||
|
|
||||||
packages."${system}" =
|
|
||||||
mapModules ./packages (p: pkgs.callPackage p {});
|
|
||||||
|
|
||||||
nixosModules =
|
|
||||||
{ dotfiles = import ./.; } // mapModulesRec ./modules import;
|
|
||||||
|
|
||||||
nixosConfigurations =
|
|
||||||
mapHosts ./hosts {};
|
|
||||||
|
|
||||||
devShell."${system}" =
|
|
||||||
import ./shell.nix { inherit pkgs; };
|
|
||||||
|
|
||||||
templates = {
|
|
||||||
full = {
|
|
||||||
path = ./.;
|
|
||||||
description = "A grossly incandescent nixos config";
|
|
||||||
};
|
|
||||||
minimal = {
|
|
||||||
path = ./templates/minimal;
|
|
||||||
description = "A grossly incandescent and minimal nixos config";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
defaultTemplate = self.templates.minimal;
|
|
||||||
|
|
||||||
defaultApp."${system}" = {
|
|
||||||
type = "app";
|
|
||||||
program = ./bin/hey;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
20
ftp.nix
Normal file
20
ftp.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
networking.firewall.allowedTCPPorts = [ 20 21 ];
|
||||||
|
networking.firewall.allowedTCPPortRanges = [ { from = 51000; to = 51999; } ];
|
||||||
|
services.vsftpd = {
|
||||||
|
enable = true;
|
||||||
|
writeEnable = true;
|
||||||
|
anonymousUser = true;
|
||||||
|
anonymousUserNoPassword = true;
|
||||||
|
anonymousUploadEnable = true;
|
||||||
|
anonymousMkdirEnable = true;
|
||||||
|
anonymousUserHome = "/home/ftp";
|
||||||
|
extraConfig = ''
|
||||||
|
pasv_enable=Yes
|
||||||
|
pasv_min_port=51000
|
||||||
|
pasv_max_port=51999
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
12
gonic.nix
Normal file
12
gonic.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
services.gonic.enable = true;
|
||||||
|
services.gonic.settings = ''
|
||||||
|
music-path /data/music
|
||||||
|
podcast-path /data/music
|
||||||
|
cache-path /data/cache
|
||||||
|
'';
|
||||||
|
services.gonic.group = "audio";
|
||||||
|
services.gonic.user = "headphones";
|
||||||
|
networking.firewall.allowedTCPPorts = [ 4747 ];
|
||||||
|
}
|
|
@ -8,30 +8,30 @@
|
||||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
|
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
||||||
boot.kernelModules = [ ];
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" =
|
||||||
{ device = "/dev/disk/by-uuid/6ee9d430-1b1b-4e39-bced-606145570a78";
|
{ device = "/dev/disk/by-uuid/ade0752d-84d3-4e39-865b-9027ba2d5c67";
|
||||||
fsType = "btrfs";
|
fsType = "ext4";
|
||||||
options = [ "subvol=root" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/home" =
|
fileSystems."/boot/efi" =
|
||||||
{ device = "/dev/disk/by-uuid/6ee9d430-1b1b-4e39-bced-606145570a78";
|
{ device = "/dev/disk/by-uuid/1715-278E";
|
||||||
fsType = "btrfs";
|
|
||||||
options = [ "subvol=home" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" =
|
|
||||||
{ device = "/dev/disk/by-uuid/AD0C-92EF";
|
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fileSystems."/data" =
|
||||||
|
{ device = "/dev/disk/by-uuid/3276a297-9ee4-4998-b262-1ed100366c06";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
boot.initrd.luks.devices."crypted-data".device = "/dev/disk/by-uuid/8a317bf4-fe13-4334-a6df-5fe5a5048b5e";
|
||||||
|
|
||||||
swapDevices =
|
swapDevices =
|
||||||
[ { device = "/dev/disk/by-uuid/5486bd9f-6826-4ac7-b09b-8768a35c331f"; }
|
[ { device = "/dev/disk/by-uuid/b790abb4-ba5f-4476-8f09-b0fc575414aa"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
12
headphones.nix
Normal file
12
headphones.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{config, lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
services.headphones = {
|
||||||
|
enable = true;
|
||||||
|
host = "172.16.11.240";
|
||||||
|
port = 8181;
|
||||||
|
user = "headphones";
|
||||||
|
group = "audio";
|
||||||
|
dataDir = "/data/music";
|
||||||
|
};
|
||||||
|
networking.firewall.allowedTCPPorts = [ 8181 ];
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
#+TITLE: Host Configurations
|
|
||||||
|
|
||||||
* Systems
|
|
||||||
+ kuro
|
|
||||||
+ shiro
|
|
||||||
+ ao
|
|
||||||
+ aka
|
|
||||||
+ aijiro
|
|
||||||
+ unlisted: 100+ linodes, 7 VMs
|
|
|
@ -1,30 +0,0 @@
|
||||||
#+TITLE: Aijiro
|
|
||||||
#+DATE: September 3, 2021
|
|
||||||
|
|
||||||
* Overview
|
|
||||||
...
|
|
||||||
|
|
||||||
* Specs
|
|
||||||
+ Intel i5-6400
|
|
||||||
+ 8GB
|
|
||||||
|
|
||||||
* Installation
|
|
||||||
** Set up root file system
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
parted /dev/sda -- mklabel gpt
|
|
||||||
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
|
|
||||||
parted /dev/sda -- mkpart primary linux-swap 512MiB 8.5GiB
|
|
||||||
parted /dev/sda -- mkpart primary 8.5GiB 100%
|
|
||||||
parted /dev/sda -- set 1 boot on
|
|
||||||
mkfs.fat -F32 -n BOOT /dev/sda1
|
|
||||||
mkswap -L swap /dev/sda2
|
|
||||||
mkfs.ext4 -L nixos /dev/sda3
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Mount drives
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
mount /dev/sda3 /mnt
|
|
||||||
mkdir -p /mnt/boot
|
|
||||||
mount /dev/sda1 /mnt/boot
|
|
||||||
swapon /dev/sda2
|
|
||||||
#+END_SRC
|
|
|
@ -1,86 +0,0 @@
|
||||||
# Shiro -- my laptop
|
|
||||||
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../home.nix
|
|
||||||
./hardware-configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
modules = {
|
|
||||||
desktop = {
|
|
||||||
bspwm.enable = true;
|
|
||||||
apps = {
|
|
||||||
discord.enable = true;
|
|
||||||
rofi.enable = true;
|
|
||||||
# godot.enable = true;
|
|
||||||
};
|
|
||||||
browsers = {
|
|
||||||
default = "brave";
|
|
||||||
brave.enable = true;
|
|
||||||
# firefox.enable = true;
|
|
||||||
# qutebrowser.enable = true;
|
|
||||||
};
|
|
||||||
gaming = {
|
|
||||||
# steam.enable = true;
|
|
||||||
# emulators.enable = true;
|
|
||||||
# emulators.psx.enable = true;
|
|
||||||
};
|
|
||||||
media = {
|
|
||||||
daw.enable = true;
|
|
||||||
documents.enable = true;
|
|
||||||
graphics.enable = true;
|
|
||||||
mpv.enable = true;
|
|
||||||
recording.enable = true;
|
|
||||||
spotify.enable = true;
|
|
||||||
};
|
|
||||||
term = {
|
|
||||||
default = "xst";
|
|
||||||
st.enable = true;
|
|
||||||
};
|
|
||||||
vm = {
|
|
||||||
qemu.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
dev = {
|
|
||||||
node.enable = true;
|
|
||||||
rust.enable = true;
|
|
||||||
python.enable = true;
|
|
||||||
};
|
|
||||||
editors = {
|
|
||||||
default = "nvim";
|
|
||||||
emacs.enable = true;
|
|
||||||
vim.enable = true;
|
|
||||||
};
|
|
||||||
shell = {
|
|
||||||
# adl.enable = true;
|
|
||||||
vaultwarden.enable = true;
|
|
||||||
direnv.enable = true;
|
|
||||||
git.enable = true;
|
|
||||||
gnupg.enable = true;
|
|
||||||
tmux.enable = true;
|
|
||||||
zsh.enable = true;
|
|
||||||
};
|
|
||||||
services = {
|
|
||||||
ssh.enable = true;
|
|
||||||
docker.enable = true;
|
|
||||||
# Needed occasionally to help the parental units with PC problems
|
|
||||||
# teamviewer.enable = true;
|
|
||||||
};
|
|
||||||
theme.active = "alucard";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
## Local config
|
|
||||||
programs.ssh.startAgent = true;
|
|
||||||
services.openssh.startWhenNeeded = true;
|
|
||||||
|
|
||||||
networking.wireless.enable = true;
|
|
||||||
# The global useDHCP flag is deprecated, therefore explicitly set to false
|
|
||||||
# here. Per-interface useDHCP will be mandatory in the future, so this
|
|
||||||
# generated config replicates the default behaviour.
|
|
||||||
networking.useDHCP = false;
|
|
||||||
|
|
||||||
time.timeZone = "Europe/Copenhagen";
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
{ config, lib, pkgs, inputs, modulesPath, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot = {
|
|
||||||
initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "sr_mod" "nvme" ];
|
|
||||||
initrd.kernelModules = [ "dm-snapshot" ];
|
|
||||||
kernelModules = [ "kvm-intel" ];
|
|
||||||
extraModulePackages = [ ];
|
|
||||||
kernelParams = [
|
|
||||||
# HACK Disables fixes for spectre, meltdown, L1TF and a number of CPU
|
|
||||||
# vulnerabilities. Don't copy this blindly! And especially not for
|
|
||||||
# mission critical or server/headless builds exposed to the world.
|
|
||||||
"mitigations=off"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Refuse ICMP echo requests on my desktop/laptop; nobody has any business
|
|
||||||
# pinging them, unlike my servers.
|
|
||||||
kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Modules
|
|
||||||
modules.hardware = {
|
|
||||||
audio.enable = true;
|
|
||||||
fs = {
|
|
||||||
enable = true;
|
|
||||||
ssd.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# CPU
|
|
||||||
nix.maxJobs = lib.mkDefault 4;
|
|
||||||
hardware.cpu.intel.updateMicrocode = true;
|
|
||||||
# performance gives better battery life/perf than ondemand on sandy bridge and
|
|
||||||
# newer because of intel pstates.
|
|
||||||
powerManagement.cpuFreqGovernor = "performance";
|
|
||||||
# Without this wpa_supplicant may fail to auto-discover wireless interfaces at
|
|
||||||
# startup (and must be restarted).
|
|
||||||
networking.wireless.interfaces = [ "wlp3s0" ];
|
|
||||||
|
|
||||||
# Storage
|
|
||||||
fileSystems = {
|
|
||||||
"/" = {
|
|
||||||
device = "/dev/disk/by-label/nixos";
|
|
||||||
fsType = "ext4";
|
|
||||||
options = [ "noatime" ];
|
|
||||||
};
|
|
||||||
"/boot" = {
|
|
||||||
device = "/dev/disk/by-label/BOOT";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
swapDevices = [ { device = "/dev/disk/by-label/swap"; }];
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
#+TITLE: Ao
|
|
||||||
#+DATE: December 16, 2014
|
|
||||||
|
|
||||||
* Overview
|
|
||||||
Mac Mini 2014. Used as a low-power home server.
|
|
||||||
|
|
||||||
* Specs
|
|
||||||
https://support.apple.com/kb/SP710?locale=en_CA
|
|
||||||
|
|
||||||
* Installation
|
|
||||||
** Set up root file system
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
parted /dev/sda -- mklabel gpt
|
|
||||||
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
|
|
||||||
parted /dev/sda -- mkpart primary 512MiB 100%
|
|
||||||
parted /dev/sda -- set 1 boot on
|
|
||||||
mkfs.fat -F32 -n BOOT /dev/sda1
|
|
||||||
mkfs.ext4 -L nixos /dev/sda2
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Mount drives
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
mount /dev/sda2 /mnt
|
|
||||||
mkdir -p /mnt/boot
|
|
||||||
mount /dev/sda1 /mnt/boot
|
|
||||||
#+END_SRC
|
|
|
@ -1,61 +0,0 @@
|
||||||
# Ao -- my home development and user-facing server
|
|
||||||
|
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
with lib.my;
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../server.nix
|
|
||||||
../home.nix
|
|
||||||
./hardware-configuration.nix
|
|
||||||
|
|
||||||
./modules/backup.nix
|
|
||||||
./modules/gitea.nix
|
|
||||||
./modules/vaultwarden.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
modules = {
|
|
||||||
shell = {
|
|
||||||
direnv.enable = true;
|
|
||||||
git.enable = true;
|
|
||||||
zsh.enable = true;
|
|
||||||
};
|
|
||||||
services = {
|
|
||||||
fail2ban.enable = true;
|
|
||||||
ssh.enable = true;
|
|
||||||
nginx.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
theme.active = "alucard";
|
|
||||||
};
|
|
||||||
|
|
||||||
## Local config
|
|
||||||
networking.networkmanager.enable = true;
|
|
||||||
|
|
||||||
# nginx hosts
|
|
||||||
services.nginx.virtualHosts."v0.io" = {
|
|
||||||
default = true;
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = {
|
|
||||||
"~* \.(?:ico|css|map|js|gif|jpe?g|png|ttf|woff)$".extraConfig = ''
|
|
||||||
access_log off;
|
|
||||||
expires 30d;
|
|
||||||
add_header Pragma public;
|
|
||||||
add_header Cache-Control "public, mustrevalidate, proxy-revalidate";
|
|
||||||
proxy_pass http://kiiro:8000;
|
|
||||||
proxy_buffering off;
|
|
||||||
'';
|
|
||||||
"/".extraConfig = ''
|
|
||||||
client_max_body_size 10m;
|
|
||||||
proxy_pass http://kiiro:8000;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_redirect off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
security.acme.email = "henrik@lissner.net";
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
{ config, lib, modulesPath, ... }:
|
|
||||||
{
|
|
||||||
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
|
||||||
|
|
||||||
boot = {
|
|
||||||
initrd.availableKernelModules = [ "ohci_pci" "ehci_pci" "ahci" "firewire_ohci" "usb_storage" "usbhid" "sd_mod" "sr_mod" "sdhci_pci" ];
|
|
||||||
initrd.kernelModules = [ ];
|
|
||||||
kernelModules = [ "kvm-intel" "wl" ];
|
|
||||||
extraModulePackages = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
## CPU
|
|
||||||
nix.maxJobs = lib.mkDefault 2;
|
|
||||||
powerManagement.cpuFreqGovernor = "ondemand";
|
|
||||||
|
|
||||||
## Harddrives
|
|
||||||
fileSystems = {
|
|
||||||
"/" = {
|
|
||||||
device = "/dev/disk/by-label/nixos";
|
|
||||||
fsType = "ext4";
|
|
||||||
options = [ "noatime" ];
|
|
||||||
};
|
|
||||||
"/boot" = {
|
|
||||||
device = "/dev/disk/by-label/boot";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
"/usr/drive" = {
|
|
||||||
device = "kiiro:/volume1/homes/hlissner/Drive/backup/ao";
|
|
||||||
fsType = "nfs";
|
|
||||||
options = [
|
|
||||||
"nofail" "noauto" "noatime" "x-systemd.automount" "x-systemd.idle-timeout=5min"
|
|
||||||
"nodev" "nosuid" "noexec"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
swapDevices = [{ device = "/dev/disk/by-label/swap"; }];
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
services.vaultwarden.backupDir = "/backups/vaultwarden";
|
|
||||||
services.gitea.dump.enable = true;
|
|
||||||
services.gitea.dump.backupDir = "/backups/gitea";
|
|
||||||
system.activationScripts.createBackupDir = ''
|
|
||||||
mkdir -m 750 -p "${config.services.vaultwarden.backupDir}" || true
|
|
||||||
mkdir -m 750 -p "${config.services.gitea.dump.backupDir}" || true
|
|
||||||
chown vaultwarden:vaultwarden "${config.services.vaultwarden.backupDir}"
|
|
||||||
chown git:gitea "${config.services.gitea.dump.backupDir}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# systemd = {
|
|
||||||
# services.backups = {
|
|
||||||
# description = "Backup /backups to NAS";
|
|
||||||
# wants = [ "usr-drive.mount" ];
|
|
||||||
# path = [ pkgs.rsync ];
|
|
||||||
# environment = {
|
|
||||||
# SRC_DIR = "/backups";
|
|
||||||
# DEST_DIR = "/usr/drive";
|
|
||||||
# };
|
|
||||||
# script = ''
|
|
||||||
# if [[ -d "$1" && -d "$2" ]]; then
|
|
||||||
# echo "---- BACKUPING UP $1 TO $2 ----"
|
|
||||||
# rsync -rlptPJ --delete --delete-after \
|
|
||||||
# --chmod=go= \
|
|
||||||
# --chown=hlissner:users \
|
|
||||||
# --exclude=lost+found/ \
|
|
||||||
# --exclude=@eaDir/ \
|
|
||||||
# --include=.git/ \
|
|
||||||
# --filter=':- .gitignore' \
|
|
||||||
# --filter=':- $XDG_CONFIG_HOME/git/ignore' \
|
|
||||||
# "$SRC_DIR/" "$DEST_DIR"
|
|
||||||
# fi
|
|
||||||
# '';
|
|
||||||
# serviceConfig = {
|
|
||||||
# Type = "oneshot";
|
|
||||||
# Nice = 19;
|
|
||||||
# IOSchedulingClass = "idle";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# timers.backups = {
|
|
||||||
# wantedBy = [ "timers.target" ];
|
|
||||||
# partOf = [ "backups.service" ];
|
|
||||||
# timerConfig.OnCalendar = "*-*-* 03:00:00";
|
|
||||||
# timerConfig.Persistent = true;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
modules.services.gitea.enable = true;
|
|
||||||
|
|
||||||
services.gitea = {
|
|
||||||
appName = "V-NOUGHT";
|
|
||||||
domain = "v0.io";
|
|
||||||
rootUrl = "https://git.v0.io/";
|
|
||||||
disableRegistration = true;
|
|
||||||
settings = {
|
|
||||||
server.SSH_DOMAIN = "v0.io";
|
|
||||||
mailer = {
|
|
||||||
ENABLED = true;
|
|
||||||
FROM = "mail@v0.io";
|
|
||||||
HOST = "mail.gmail.com:465";
|
|
||||||
USER = "hlissner@gmail.com";
|
|
||||||
MAILER_TYPE = "smtp";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
mailerPasswordFile = config.age.secrets.gitea-smtp.path;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."git.v0.io" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
root = "/srv/www/git.v0.io";
|
|
||||||
locations."/".proxyPass = "http://127.0.0.1:3000";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
modules.services.vaultwarden.enable = true;
|
|
||||||
|
|
||||||
services.vaultwarden.config = {
|
|
||||||
signupsAllowed = false;
|
|
||||||
invitationsAllowed = true;
|
|
||||||
domain = "https://p.v0.io";
|
|
||||||
httpPort = 8002;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Inject secrets at runtime
|
|
||||||
systemd.services.vaultwarden.serviceConfig = {
|
|
||||||
EnvironmentFile = [ config.age.secrets.vaultwarden-smtp-env.path ];
|
|
||||||
Restart = "on-failure";
|
|
||||||
RestartSec = "2s";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."p.v0.io" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
root = "/srv/www/p.v0.io";
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 128M;
|
|
||||||
'';
|
|
||||||
locations = {
|
|
||||||
"/".proxyPass = "http://127.0.0.1:8000";
|
|
||||||
"/notifications/hub".proxyWebsockets = true;
|
|
||||||
"/notifications/hub/negotiate".proxyPass = "http://127.0.0.1:8001";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 4+kR2g aFztrZ7QN3Odj4EbFwuaRn+1VSuTFSUZ1Gwtgf5ELmw
|
|
||||||
H2s3EFMm4cRnFw5AbeOmX+OdADnEuMW5KqR4erH8Rv0
|
|
||||||
-> (-grease 10P|_2X
|
|
||||||
JP9WDuBVhwq8P4B/QTPM/UFVgEM
|
|
||||||
--- IV78E3ztrIne6HidhqvOUfg//H77bnXQlXvEtqmpkBA
|
|
||||||
‹,æûS"™2(·*b×<>zš‚=C•IÂPm¹¯gÜ…íäÂg¹éø4tΑog!ÕDJm
|
|
|
@ -1,5 +0,0 @@
|
||||||
let key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINd+4ijlEHI98NLpgP/El73BmpBUfzka9ovdt8FoaVAG hlissner@home";
|
|
||||||
in {
|
|
||||||
"vaultwarden-smtp-env.age".publicKeys = [key];
|
|
||||||
"gitea-smtp.age".publicKeys = [key];
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,85 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports =
|
|
||||||
[ # Include the results of the hardware scan.
|
|
||||||
./hardware-configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.loader.grub.enable = true;
|
|
||||||
boot.loader.grub.version = 2;
|
|
||||||
# Define on which hard drive you want to install Grub.
|
|
||||||
boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
|
|
||||||
|
|
||||||
# Minimal list of modules to use the EFI system partition and the YubiKey
|
|
||||||
boot.initrd.kernelModules = [ "vfat" "nls_cp437" "nls_iso8859-1" "usbhid" ];
|
|
||||||
|
|
||||||
# Enable support for the YubiKey PBA
|
|
||||||
boot.initrd.luks.yubikeySupport = true;
|
|
||||||
|
|
||||||
# Configuration to use your Luks device
|
|
||||||
boot.initrd.luks.devices = {
|
|
||||||
"crypthome" = {
|
|
||||||
device = "/dev/sda2";
|
|
||||||
preLVM = true; # You may want to set this to false if you need to start a network service first
|
|
||||||
yubikey = {
|
|
||||||
slot = 2;
|
|
||||||
twoFactor = true; # Set to false if you did not set up a user password.
|
|
||||||
storage = {
|
|
||||||
device = "/dev/sda1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.udev.extraRules = ''
|
|
||||||
SUBSYSTEMS=="usb", ATTRS{manufacturer}=="NVIDIA Corp.", ATTRS{product}=="APX", GROUP="switch"
|
|
||||||
'';
|
|
||||||
services.udev.packages = [ pkgs.android-udev-rules ];
|
|
||||||
|
|
||||||
# nix = {
|
|
||||||
# package = pkgs.nixUnstable;
|
|
||||||
# extraOptions = "experimental-features = nix-command flakes";
|
|
||||||
# };
|
|
||||||
|
|
||||||
networking.hostName = "curve"; # Define your hostname.
|
|
||||||
networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
|
||||||
|
|
||||||
time.timeZone = "Australia/Brisbane";
|
|
||||||
|
|
||||||
networking.useDHCP = false;
|
|
||||||
networking.interfaces.enp0s31f6.useDHCP = true;
|
|
||||||
networking.interfaces.wlp3s0.useDHCP = true;
|
|
||||||
|
|
||||||
# Select internationalisation properties.
|
|
||||||
i18n.defaultLocale = "en_US.UTF-8";
|
|
||||||
# console = {
|
|
||||||
# font = "Lat2-Terminus16";
|
|
||||||
# keyMap = "us";
|
|
||||||
# };
|
|
||||||
|
|
||||||
services.xserver.layout = "us,dvorak";
|
|
||||||
|
|
||||||
sound.enable = true;
|
|
||||||
hardware.pulseaudio.enable = true;
|
|
||||||
|
|
||||||
services.xserver.libinput.enable = true;
|
|
||||||
programs.adb.enable = true;
|
|
||||||
|
|
||||||
users.users.anish = {
|
|
||||||
isNormalUser = true;
|
|
||||||
extraGroups = [ "wheel" "video" "switch" "adbusers" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Enable the OpenSSH daemon.
|
|
||||||
# services.openssh.enable = true;
|
|
||||||
|
|
||||||
# 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.05"; # Did you read the comment?
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
{ pkgs, config, lib, ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../home.nix
|
|
||||||
../common.nix
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
modules = {
|
|
||||||
desktop = {
|
|
||||||
bspwm.enable = true;
|
|
||||||
apps = {
|
|
||||||
discord.enable = true;
|
|
||||||
rofi.enable = true;
|
|
||||||
# godot.enable = true;
|
|
||||||
# signal.enable = true;
|
|
||||||
};
|
|
||||||
browsers = {
|
|
||||||
default = "firefox";
|
|
||||||
brave.enable = false;
|
|
||||||
firefox.enable = true;
|
|
||||||
qutebrowser.enable = true;
|
|
||||||
};
|
|
||||||
gaming = {
|
|
||||||
# steam.enable = true;
|
|
||||||
# emulators.enable = true;
|
|
||||||
# emulators.psx.enable = true;
|
|
||||||
};
|
|
||||||
media = {
|
|
||||||
daw.enable = true;
|
|
||||||
documents.enable = true;
|
|
||||||
graphics.enable = true;
|
|
||||||
mpv.enable = true;
|
|
||||||
recording.enable = true;
|
|
||||||
spotify.enable = false;
|
|
||||||
};
|
|
||||||
term = {
|
|
||||||
default = "xst";
|
|
||||||
st.enable = true;
|
|
||||||
};
|
|
||||||
vm = {
|
|
||||||
qemu.enable = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
dev = {
|
|
||||||
node.enable = false;
|
|
||||||
rust.enable = false;
|
|
||||||
python.enable = true;
|
|
||||||
};
|
|
||||||
editors = {
|
|
||||||
default = "vim";
|
|
||||||
#emacs.enable = true;
|
|
||||||
#vim.enable = true;
|
|
||||||
};
|
|
||||||
shell = {
|
|
||||||
adl.enable = true;
|
|
||||||
vaultwarden.enable = false;
|
|
||||||
direnv.enable = true;
|
|
||||||
git.enable = true;
|
|
||||||
gnupg.enable = true;
|
|
||||||
tmux.enable = false;
|
|
||||||
zsh.enable = false;
|
|
||||||
};
|
|
||||||
services = {
|
|
||||||
ssh.enable = true;
|
|
||||||
docker.enable = false;
|
|
||||||
# Needed occasionally to help the parental units with PC problems
|
|
||||||
# teamviewer.enable = true;
|
|
||||||
};
|
|
||||||
theme.active = "alucard";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
## Local config
|
|
||||||
programs.ssh.startAgent = true;
|
|
||||||
# services.openssh.startWhenNeeded = true;
|
|
||||||
|
|
||||||
# networking.networkmanager.enable = true;
|
|
||||||
# The global useDHCP flag is deprecated, therefore explicitly set to false
|
|
||||||
# here. Per-interface useDHCP will be mandatory in the future, so this
|
|
||||||
# generated config replicates the default behaviour.
|
|
||||||
networking.useDHCP = false;
|
|
||||||
programs.neovim.enable = true;
|
|
||||||
|
|
||||||
programs.light.enable = true;
|
|
||||||
|
|
||||||
## Personal backups
|
|
||||||
# Syncthing is a bit heavy handed for my needs, so rsync to my NAS instead.
|
|
||||||
# systemd = {
|
|
||||||
# services.backups = {
|
|
||||||
# description = "Backup /usr/store to NAS";
|
|
||||||
# wants = [ "usr-drive.mount" ];
|
|
||||||
# path = [ pkgs.rsync ];
|
|
||||||
# environment = {
|
|
||||||
# SRC_DIR = "/usr/store";
|
|
||||||
# DEST_DIR = "/usr/drive";
|
|
||||||
# };
|
|
||||||
# script = ''
|
|
||||||
# rcp() {
|
|
||||||
# if [[ -d "$1" && -d "$2" ]]; then
|
|
||||||
# echo "---- BACKUPING UP $1 TO $2 ----"
|
|
||||||
# rsync -rlptPJ --chmod=go= --delete --delete-after \
|
|
||||||
# --exclude=lost+found/ \
|
|
||||||
# --exclude=@eaDir/ \
|
|
||||||
# --include=.git/ \
|
|
||||||
# --filter=':- .gitignore' \
|
|
||||||
# --filter=':- $XDG_CONFIG_HOME/git/ignore' \
|
|
||||||
# "$1" "$2"
|
|
||||||
# fi
|
|
||||||
# }
|
|
||||||
# rcp "$HOME/projects/" "$DEST_DIR/projects"
|
|
||||||
# rcp "$SRC_DIR/" "$DEST_DIR"
|
|
||||||
# '';
|
|
||||||
# serviceConfig = {
|
|
||||||
# Type = "oneshot";
|
|
||||||
# Nice = 19;
|
|
||||||
# IOSchedulingClass = "idle";
|
|
||||||
# User = config.user.name;
|
|
||||||
# Group = config.user.group;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# timers.backups = {
|
|
||||||
# wantedBy = [ "timers.target" ];
|
|
||||||
# partOf = [ "backups.service" ];
|
|
||||||
# timerConfig.OnCalendar = "*-*-* 00,12:00:00";
|
|
||||||
# timerConfig.Persistent = true;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
{
|
|
||||||
# networking.hosts =
|
|
||||||
# let hostConfig = {
|
|
||||||
# "192.168.1.2" = [ "ao" ];
|
|
||||||
# "192.168.1.3" = [ "kiiro" ];
|
|
||||||
# "192.168.1.10" = [ "kuro" ];
|
|
||||||
# "192.168.1.11" = [ "shiro" ];
|
|
||||||
# "192.168.1.12" = [ "midori" ];
|
|
||||||
# };
|
|
||||||
# hosts = flatten (attrValues hostConfig);
|
|
||||||
# hostName = config.networking.hostName;
|
|
||||||
# in mkIf (builtins.elem hostName hosts) hostConfig;
|
|
||||||
|
|
||||||
## Location config -- since Toronto is my 127.0.0.1
|
|
||||||
time.timeZone = mkDefault "Australia/Brisbane";
|
|
||||||
i18n.defaultLocale = mkDefault "en_US.UTF-8";
|
|
||||||
# For redshift, mainly
|
|
||||||
location = (if config.time.timeZone == "Australia/Brisbane" then {
|
|
||||||
latitude = 27.470;
|
|
||||||
longitude = 153.0260;
|
|
||||||
} else if config.time.timeZone == "Europe/Copenhagen" then {
|
|
||||||
latitude = 55.88;
|
|
||||||
longitude = 12.5;
|
|
||||||
} else {});
|
|
||||||
|
|
||||||
# So the vaultwarden CLI knows where to find my server.
|
|
||||||
# modules.shell.vaultwarden.config.server = "p.v0.io";
|
|
||||||
|
|
||||||
|
|
||||||
## Not using syncthing atm
|
|
||||||
# services.syncthing.declarative = {
|
|
||||||
# # Purge folders not declaratively configured!
|
|
||||||
# overrideFolders = true;
|
|
||||||
# overrideDevices = true;
|
|
||||||
# devices = {
|
|
||||||
# kuro.id = "4UJSUBN-V7LCISG-6ZE7SBN-YPXM5FQ-CE7CD2U-W4KZC7O-4HUZZSW-6DXAGQQ";
|
|
||||||
# shiro.id = "G4DUO25-AMQQIWS-SRZE5TJ-43CCQZJ-5ULEZBS-P2LMZZU-V5JA5CS-6X7RLQK";
|
|
||||||
# kiiro.id = "3A6G2NR-WQMASWG-7EFUX6G-GJB6WYX-HYGDA7N-EYZYANY-NDRKI3W-32RQ4QG";
|
|
||||||
# };
|
|
||||||
# folders =
|
|
||||||
# let mkShare = devices: type: paths: attrs: (rec {
|
|
||||||
# inherit devices type;
|
|
||||||
# path = if lib.isAttrs paths
|
|
||||||
# then paths."${config.networking.hostName}"
|
|
||||||
# else paths;
|
|
||||||
# watch = false;
|
|
||||||
# rescanInterval = 3600; # every hour
|
|
||||||
# enable = lib.elem config.networking.hostName devices;
|
|
||||||
# } // attrs);
|
|
||||||
# in {
|
|
||||||
# projects = mkShare [ "kuro" "shiro" ] "sendreceive" # "${config.user.home}/projects"
|
|
||||||
# { watch = true;
|
|
||||||
# rescanInterval = 3600 * 4; }; # every 4 hours
|
|
||||||
# serverBackup = mkShare [ "ao" "kiiro" ] "sendonly" "/run/backups"
|
|
||||||
# mainBackup = mkShare [ "kuro" "kiiro" ] "sendreceive" # "/usr/store"
|
|
||||||
# { versioning = {
|
|
||||||
# type = "staggered";
|
|
||||||
# params.maxAge = "356";
|
|
||||||
# }; };
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
#+TITLE: Kuro
|
|
||||||
#+DATE: September 13, 2020
|
|
||||||
|
|
||||||
* Overview
|
|
||||||
My main driver for work on Linux.
|
|
||||||
|
|
||||||
Have a separate Windows rig for gaming/adobe (Midori).
|
|
||||||
|
|
||||||
* Specs
|
|
||||||
| CASE | [[https://www.amazon.com/Fractal-Design-Define-Cases-FD-CA-DEF-R4-BL/dp/B008HD3CTI][Fractal Design Define R4 ATX Tower Case Black Pearl]] |
|
|
||||||
| CPU | [[https://www.newegg.ca/amd-ryzen-9-3900x/p/N82E16819113103][AMD Ryzen 9 3900X 12-core, 24-thread]] |
|
|
||||||
| MOBO | [[https://www.newegg.ca/gigabyte-b550-aorus-elite/p/N82E16813145214?Item=N82E16813145214&IsFeedbackTab=true#scrollFullInfo][GIGABYTE B550 AORUS Elite]] |
|
|
||||||
| COOL | [[https://www.newegg.ca/cooler-master-hyper-212-evo-rr-212e-20pk-r2/p/N82E16835103099][Cooler Master Hyper 212 Evo]] |
|
|
||||||
| GPU | EVGA GeForce 680 GTX SC |
|
|
||||||
| RAM | [[https://www.newegg.ca/g-skill-64gb-288-pin-ddr4-sdram/p/N82E16820374003?Description=G.SKILL%20Ripjaws%20V%20Series%2064gb&cm_re=G.SKILL_Ripjaws%20V%20Series%2064gb-_-20-374-003-_-Product][G.SKILL Ripjaws V Series 64GB (2x 32GB)]] |
|
|
||||||
| HDD | [[https://www.newegg.ca/samsung-970-evo-plus-500gb/p/N82E16820147742?Description=samsung%20970%20evo%20plus&cm_re=samsung_970%20evo%20plus-_-20-147-742-_-Product][Samsung 970 EVO Plus 500GB NVMe M2]] |
|
|
||||||
| KBD | [[https://ergodox-ez.com/][ErgoDox-EZ]] |
|
|
||||||
| MOUSE | [[https://www.anker.com/products/variant/anker-24g-wireless-vertical-ergonomic-optical-mouse/A7852011][Anker Wireless Vertical Mouse]] |
|
|
||||||
|
|
||||||
* Installation
|
|
||||||
** Set up root file system
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
# EVO Plus 500gb
|
|
||||||
parted /dev/nvme0n1 -- mklabel gpt
|
|
||||||
parted /dev/nvme0n1 -- mkpart ESP fat32 1MiB 512MiB
|
|
||||||
parted /dev/nvme0n1 -- mkpart primary 512MiB 200GiB
|
|
||||||
parted /dev/nvme0n1 -- mkpart primary 200GiB 100%
|
|
||||||
parted /dev/nvme0n1 -- set 1 boot on
|
|
||||||
mkfs.fat -F32 -n BOOT /dev/nvme0n1p1
|
|
||||||
mkfs.ext4 -L nixos /dev/nvme0n1p2
|
|
||||||
mkfs.ext4 -L home /dev/nvme0n1p3
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Set up VM SSDs
|
|
||||||
#+BEGIN_SRC shell
|
|
||||||
# 2x SSDs for VMs
|
|
||||||
parted /dev/sda -- mklabel gpt
|
|
||||||
parted -a optimal /dev/sda -- mkpart primary 0% 100%
|
|
||||||
parted /dev/sdb -- mklabel gpt
|
|
||||||
parted -a optimal /dev/sdb -- mkpart primary 0% 100%
|
|
||||||
mkfs.ext4 -L vm1 /dev/sda1
|
|
||||||
mkfs.ext4 -L vm2 /dev/sdb1
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Set up backup file system
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
parted /dev/sdc -- mklabel gpt
|
|
||||||
parted /dev/sdc -- mkpart primary ext4 0% 100%
|
|
||||||
mkfs.ext4 -L store /dev/sdc
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** +Set up backup file system+
|
|
||||||
Backup was moved to an NAS, so this is no longer needed. It's kept as a
|
|
||||||
reference.
|
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
# 2x 1TB mirrored backup
|
|
||||||
zpool create -R /mnt \
|
|
||||||
-O mountpoint=none \
|
|
||||||
-O xattr=sa \
|
|
||||||
-O atime=off \
|
|
||||||
-O compression=lz4 \
|
|
||||||
-O recordsize=1M \
|
|
||||||
-o ashift=9 \
|
|
||||||
usr mirror /dev/sdc /dev/sdd
|
|
||||||
|
|
||||||
# aux
|
|
||||||
zfs create -o mountpoint=legacy usr/media
|
|
||||||
zfs create -o mountpoint=legacy usr/backup
|
|
||||||
zfs create -o mountpoint=legacy -o recordsize=128K usr/share
|
|
||||||
zfs create -o mountpoint=legacy -o recordsize=128K usr/local
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Mount drives
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
mount /dev/nvme0n1p2 /mnt
|
|
||||||
|
|
||||||
mkdir -p /mnt/{home,boot,usr/store}
|
|
||||||
mount /dev/nvme0n1p1 /mnt/boot
|
|
||||||
mount /dev/nvme0n1p3 /mnt/home
|
|
||||||
# mount -t zfs {usr,/mnt/usr}/backup
|
|
||||||
# mount -t zfs {usr,/mnt/usr}/media
|
|
||||||
# mount -t zfs {usr,/mnt/usr}/share
|
|
||||||
# mount -t zfs {usr,/mnt/usr}/local
|
|
||||||
mount /dev/sda1 /usr/vm/windows
|
|
||||||
mount /dev/sdb1 /usr/vm/macos
|
|
||||||
mount /dev/sdc2 /usr/store
|
|
||||||
#+END_SRC
|
|
|
@ -1,127 +0,0 @@
|
||||||
{ pkgs, config, lib, ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../home.nix
|
|
||||||
./hardware-configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
modules = {
|
|
||||||
desktop = {
|
|
||||||
bspwm.enable = true;
|
|
||||||
apps = {
|
|
||||||
discord.enable = true;
|
|
||||||
rofi.enable = true;
|
|
||||||
# godot.enable = true;
|
|
||||||
signal.enable = true;
|
|
||||||
};
|
|
||||||
browsers = {
|
|
||||||
default = "brave";
|
|
||||||
brave.enable = true;
|
|
||||||
firefox.enable = true;
|
|
||||||
qutebrowser.enable = true;
|
|
||||||
};
|
|
||||||
gaming = {
|
|
||||||
steam.enable = true;
|
|
||||||
# emulators.enable = true;
|
|
||||||
# emulators.psx.enable = true;
|
|
||||||
};
|
|
||||||
media = {
|
|
||||||
daw.enable = true;
|
|
||||||
documents.enable = true;
|
|
||||||
graphics.enable = true;
|
|
||||||
mpv.enable = true;
|
|
||||||
recording.enable = true;
|
|
||||||
spotify.enable = true;
|
|
||||||
};
|
|
||||||
term = {
|
|
||||||
default = "xst";
|
|
||||||
st.enable = true;
|
|
||||||
};
|
|
||||||
vm = {
|
|
||||||
qemu.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
dev = {
|
|
||||||
node.enable = true;
|
|
||||||
rust.enable = true;
|
|
||||||
python.enable = true;
|
|
||||||
};
|
|
||||||
editors = {
|
|
||||||
default = "nvim";
|
|
||||||
emacs.enable = true;
|
|
||||||
vim.enable = true;
|
|
||||||
};
|
|
||||||
shell = {
|
|
||||||
adl.enable = true;
|
|
||||||
vaultwarden.enable = true;
|
|
||||||
direnv.enable = true;
|
|
||||||
git.enable = true;
|
|
||||||
gnupg.enable = true;
|
|
||||||
tmux.enable = true;
|
|
||||||
zsh.enable = true;
|
|
||||||
};
|
|
||||||
services = {
|
|
||||||
ssh.enable = true;
|
|
||||||
docker.enable = true;
|
|
||||||
# Needed occasionally to help the parental units with PC problems
|
|
||||||
# teamviewer.enable = true;
|
|
||||||
};
|
|
||||||
theme.active = "alucard";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
## Local config
|
|
||||||
programs.ssh.startAgent = true;
|
|
||||||
services.openssh.startWhenNeeded = true;
|
|
||||||
|
|
||||||
networking.networkmanager.enable = true;
|
|
||||||
# The global useDHCP flag is deprecated, therefore explicitly set to false
|
|
||||||
# here. Per-interface useDHCP will be mandatory in the future, so this
|
|
||||||
# generated config replicates the default behaviour.
|
|
||||||
networking.useDHCP = false;
|
|
||||||
|
|
||||||
|
|
||||||
## Personal backups
|
|
||||||
# Syncthing is a bit heavy handed for my needs, so rsync to my NAS instead.
|
|
||||||
systemd = {
|
|
||||||
services.backups = {
|
|
||||||
description = "Backup /usr/store to NAS";
|
|
||||||
wants = [ "usr-drive.mount" ];
|
|
||||||
path = [ pkgs.rsync ];
|
|
||||||
environment = {
|
|
||||||
SRC_DIR = "/usr/store";
|
|
||||||
DEST_DIR = "/usr/drive";
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
rcp() {
|
|
||||||
if [[ -d "$1" && -d "$2" ]]; then
|
|
||||||
echo "---- BACKUPING UP $1 TO $2 ----"
|
|
||||||
rsync -rlptPJ --chmod=go= --delete --delete-after \
|
|
||||||
--exclude=lost+found/ \
|
|
||||||
--exclude=@eaDir/ \
|
|
||||||
--include=.git/ \
|
|
||||||
--filter=':- .gitignore' \
|
|
||||||
--filter=':- $XDG_CONFIG_HOME/git/ignore' \
|
|
||||||
"$1" "$2"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
rcp "$HOME/projects/" "$DEST_DIR/projects"
|
|
||||||
rcp "$SRC_DIR/" "$DEST_DIR"
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
Nice = 19;
|
|
||||||
IOSchedulingClass = "idle";
|
|
||||||
User = config.user.name;
|
|
||||||
Group = config.user.group;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
timers.backups = {
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
partOf = [ "backups.service" ];
|
|
||||||
timerConfig.OnCalendar = "*-*-* 00,12:00:00";
|
|
||||||
timerConfig.Persistent = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ "${modulesPath}/installer/scan/not-detected.nix" ];
|
|
||||||
|
|
||||||
boot = {
|
|
||||||
initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
|
|
||||||
initrd.kernelModules = [];
|
|
||||||
extraModulePackages = [];
|
|
||||||
kernelModules = [ "kvm-amd" ];
|
|
||||||
kernelParams = [
|
|
||||||
# HACK Disables fixes for spectre, meltdown, L1TF and a number of CPU
|
|
||||||
# vulnerabilities. Don't copy this blindly! And especially not for
|
|
||||||
# mission critical or server/headless builds exposed to the world.
|
|
||||||
"mitigations=off"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Refuse ICMP echo requests on my desktop/laptop; nobody has any business
|
|
||||||
# pinging them, unlike my servers.
|
|
||||||
kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Modules
|
|
||||||
modules.hardware = {
|
|
||||||
audio.enable = true;
|
|
||||||
ergodox.enable = true;
|
|
||||||
fs = {
|
|
||||||
enable = true;
|
|
||||||
ssd.enable = true;
|
|
||||||
};
|
|
||||||
nvidia.enable = true;
|
|
||||||
sensors.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# CPU
|
|
||||||
nix.maxJobs = lib.mkDefault 16;
|
|
||||||
powerManagement.cpuFreqGovernor = "performance";
|
|
||||||
hardware.cpu.amd.updateMicrocode = true;
|
|
||||||
|
|
||||||
# Displays
|
|
||||||
services.xserver = {
|
|
||||||
# This must be done manually to ensure my screen spaces are arranged exactly
|
|
||||||
# as I need them to be *and* the correct monitor is "primary". Using
|
|
||||||
# xrandrHeads does not work.
|
|
||||||
monitorSection = ''
|
|
||||||
VendorName "Unknown"
|
|
||||||
ModelName "DELL U2515H"
|
|
||||||
HorizSync 30.0 - 113.0
|
|
||||||
VertRefresh 56.0 - 86.0
|
|
||||||
Option "DPMS"
|
|
||||||
'';
|
|
||||||
screenSection = ''
|
|
||||||
Option "metamodes" "HDMI-0: nvidia-auto-select +1920+0, DVI-I-1: nvidia-auto-select +0+180, DVI-D-0: nvidia-auto-select +4480+180"
|
|
||||||
Option "SLI" "Off"
|
|
||||||
Option "MultiGPU" "Off"
|
|
||||||
Option "BaseMosaic" "off"
|
|
||||||
Option "Stereo" "0"
|
|
||||||
Option "nvidiaXineramaInfoOrder" "DFP-1"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Storage
|
|
||||||
fileSystems = {
|
|
||||||
"/" = {
|
|
||||||
device = "/dev/disk/by-label/nixos";
|
|
||||||
fsType = "ext4";
|
|
||||||
options = [ "noatime" ];
|
|
||||||
};
|
|
||||||
"/boot" = {
|
|
||||||
device = "/dev/disk/by-label/BOOT";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
"/home" = {
|
|
||||||
device = "/dev/disk/by-label/home";
|
|
||||||
fsType = "ext4";
|
|
||||||
options = [ "noatime" ];
|
|
||||||
};
|
|
||||||
"/usr/drive" = {
|
|
||||||
device = "kiiro:/volume1/homes/hlissner/Drive";
|
|
||||||
fsType = "nfs";
|
|
||||||
options = [
|
|
||||||
"nofail" "noauto" "noatime" "x-systemd.automount" "x-systemd.idle-timeout=5min"
|
|
||||||
"nodev" "nosuid" "noexec"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"/usr/store" = {
|
|
||||||
device = "/dev/disk/by-label/store";
|
|
||||||
fsType = "ext4";
|
|
||||||
options = [
|
|
||||||
"noauto" "noatime" "x-systemd.automount" "x-systemd.idle-timeout=5min"
|
|
||||||
"nodev" "nosuid" "noexec"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
swapDevices = [];
|
|
||||||
}
|
|
117
hosts/linode.nix
117
hosts/linode.nix
|
@ -1,117 +0,0 @@
|
||||||
# 1. Create three (3) disk images:
|
|
||||||
# - Installer: 1024mb
|
|
||||||
# - Swap: 512mb
|
|
||||||
# - NixOS: rest
|
|
||||||
#
|
|
||||||
# 2. Boot in rescue mode with:
|
|
||||||
# - /dev/sda -> Installer
|
|
||||||
# - /dev/sdb -> Swap
|
|
||||||
# - /dev/sdc -> NixOS
|
|
||||||
#
|
|
||||||
# 3. Once booted into Finnix (step 2) pipe this script to sh:
|
|
||||||
# iso=https://channels.nixos.org/nixos-20.09/latest-nixos-minimal-x86_64-linux.iso
|
|
||||||
# update-ca-certificates
|
|
||||||
# curl -k $iso | dd bs=1M of=/dev/sda
|
|
||||||
#
|
|
||||||
# 4. Create two configuration profiles:
|
|
||||||
# - Installer
|
|
||||||
# - Kernel: Direct Disk
|
|
||||||
# - /dev/sda -> NixOS
|
|
||||||
# - /dev/sdb -> Swap
|
|
||||||
# - /dev/sdc -> Installer
|
|
||||||
# - Helpers: distro and auto network helpers = off
|
|
||||||
# - Boot
|
|
||||||
# - Kernel: GRUB 2
|
|
||||||
# - /dev/sda -> NixOS
|
|
||||||
# - /dev/sdb -> Swap
|
|
||||||
# - Helpers: distro and auto network helpers = off
|
|
||||||
#
|
|
||||||
# 5. Boot into installer profile.
|
|
||||||
#
|
|
||||||
# 6. Generate hardware-configuration.nix
|
|
||||||
# e2label /dev/sda nixos
|
|
||||||
# swaplabel -L swap /dev/sdb
|
|
||||||
# mount /dev/disk/by-label/nixos /mnt
|
|
||||||
# swapon /dev/disk/by-label/swap
|
|
||||||
# nixos-generate-config --root /mnt
|
|
||||||
# vim /mnt/etc/nixos/hardware-configuration.nix # change uuids to labels
|
|
||||||
#
|
|
||||||
# 7. Install dotfiles:
|
|
||||||
# nix-env -iA nixos.git nixos.nixFlakes
|
|
||||||
# mkdir -p /mnt/home/hlissner/.config
|
|
||||||
# cd /mnt/home/hlissner/.config
|
|
||||||
# git clone https://github.com/hlissner/dotfiles
|
|
||||||
# nixos-install --root /mnt --flake .#linode --impure
|
|
||||||
# OR (on older versions of nixos)
|
|
||||||
# nixos-install --root /mnt --flake .#linode --option pure-eval false
|
|
||||||
#
|
|
||||||
# 8. Reboot into "Boot" profile.
|
|
||||||
|
|
||||||
{ modulesPath, config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
"${modulesPath}/profiles/qemu-guest.nix"
|
|
||||||
./server.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.systemPackages =
|
|
||||||
with pkgs; [ inetutils mtr sysstat git ];
|
|
||||||
|
|
||||||
modules = {
|
|
||||||
editors = {
|
|
||||||
default = "nvim";
|
|
||||||
vim.enable = true;
|
|
||||||
};
|
|
||||||
shell = {
|
|
||||||
git.enable = true;
|
|
||||||
zsh.enable = true;
|
|
||||||
};
|
|
||||||
services.ssh.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# GRUB
|
|
||||||
boot = {
|
|
||||||
kernelModules = [];
|
|
||||||
# Needed for LISH (part 1)
|
|
||||||
kernelParams = [ "console=ttyS0" ];
|
|
||||||
extraModulePackages = [];
|
|
||||||
initrd = {
|
|
||||||
availableKernelModules = [ "virtio_pci" "ahci" "sd_mod" ];
|
|
||||||
kernelModules = [];
|
|
||||||
};
|
|
||||||
loader = {
|
|
||||||
timeout = 10;
|
|
||||||
grub = {
|
|
||||||
enable = true;
|
|
||||||
version = 2;
|
|
||||||
device = "/dev/sda";
|
|
||||||
copyKernels = true;
|
|
||||||
fsIdentifier = "provided";
|
|
||||||
# Needed for LISH (part 2)
|
|
||||||
extraConfig = "serial; terminal_input serial; terminal_output serial";
|
|
||||||
# GRUB will complain about blocklists when trying to install grub on a
|
|
||||||
# partition-less disk. This tells it to ignore the warning and carry on.
|
|
||||||
forceInstall = true;
|
|
||||||
};
|
|
||||||
# Disable globals
|
|
||||||
systemd-boot.enable = false;
|
|
||||||
efi.canTouchEfiVariables = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
useDHCP = false;
|
|
||||||
usePredictableInterfaceNames = false;
|
|
||||||
interfaces.eth0 = {
|
|
||||||
useDHCP = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "/dev/sda";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
swapDevices = [ { device = "/dev/sdb"; } ];
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
# hosts/server.nix
|
|
||||||
#
|
|
||||||
# Only to be used for headless servers, at home or abroad, with more
|
|
||||||
# security/automation-minded configuration.
|
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages_latest_hardened;
|
|
||||||
|
|
||||||
nix.gc = {
|
|
||||||
automatic = true;
|
|
||||||
dates = "weekly";
|
|
||||||
options = "--delete-older-than 30d";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd = {
|
|
||||||
services.clear-log = {
|
|
||||||
description = "Clear >1 month-old logs every week";
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStart = "${pkgs.systemd}/bin/journalctl --vacuum-time=30d";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
timers.clear-log = {
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
partOf = [ "clear-log.service" ];
|
|
||||||
timerConfig.OnCalendar = "weekly UTC";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#+TITLE: Shiro
|
|
||||||
#+DATE: December 29, 2018
|
|
||||||
|
|
||||||
* Overview
|
|
||||||
For work on the go. Dual boots Windows and NixOS.
|
|
||||||
|
|
||||||
* Specs
|
|
||||||
| MAKE | [[https://www.dell.com/support/manuals/en-ca/xps-13-9370-laptop/xps-13-9370-setupandspecs/specifications-for-xps-13-9370?guid=guid-c3a6ce65-b23d-41b2-b9c9-244850da6393&lang=en-us][Dell 13" 9370]] |
|
|
||||||
| CPU | Intel i7-8550U |
|
|
||||||
| RAM | 16gb |
|
|
||||||
| HDD | 500gb NVMe |
|
|
||||||
|
|
||||||
* Installation
|
|
||||||
The primary partition needs to be shrunk on the Windows side, then:
|
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
# TODO
|
|
||||||
#+END_SRC
|
|
|
@ -1,67 +0,0 @@
|
||||||
# Shiro -- my laptop
|
|
||||||
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../home.nix
|
|
||||||
./hardware-configuration.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
modules = {
|
|
||||||
desktop = {
|
|
||||||
bspwm.enable = true;
|
|
||||||
apps = {
|
|
||||||
discord.enable = true;
|
|
||||||
rofi.enable = true;
|
|
||||||
# skype.enable = true;
|
|
||||||
};
|
|
||||||
browsers = {
|
|
||||||
default = "firefox";
|
|
||||||
firefox.enable = true;
|
|
||||||
};
|
|
||||||
media = {
|
|
||||||
# daw.enable = true;
|
|
||||||
documents.enable = true;
|
|
||||||
graphics.enable = true;
|
|
||||||
mpv.enable = true;
|
|
||||||
recording.enable = true;
|
|
||||||
spotify.enable = true;
|
|
||||||
};
|
|
||||||
term = {
|
|
||||||
default = "xst";
|
|
||||||
st.enable = true;
|
|
||||||
};
|
|
||||||
vm = {};
|
|
||||||
};
|
|
||||||
editors = {
|
|
||||||
default = "nvim";
|
|
||||||
emacs.enable = true;
|
|
||||||
vim.enable = true;
|
|
||||||
};
|
|
||||||
dev = {};
|
|
||||||
shell = {
|
|
||||||
vaultwarden.enable = true;
|
|
||||||
direnv.enable = true;
|
|
||||||
git.enable = true;
|
|
||||||
gnupg.enable = true;
|
|
||||||
tmux.enable = true;
|
|
||||||
zsh.enable = true;
|
|
||||||
};
|
|
||||||
services = {
|
|
||||||
# syncthing.enable = true;
|
|
||||||
ssh.enable = true;
|
|
||||||
};
|
|
||||||
theme.active = "alucard";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
## Local config
|
|
||||||
programs.ssh.startAgent = true;
|
|
||||||
services.openssh.startWhenNeeded = true;
|
|
||||||
|
|
||||||
networking.wireless.enable = true;
|
|
||||||
hardware.opengl.enable = true;
|
|
||||||
|
|
||||||
# time.timeZone = "Europe/Copenhagen";
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
{ config, lib, pkgs, inputs, modulesPath, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
inputs.nixos-hardware.nixosModules.dell-xps-13-9370
|
|
||||||
];
|
|
||||||
|
|
||||||
boot = {
|
|
||||||
initrd.availableKernelModules = [ "xhci_pci" "nvme" "rtsx_pci_sdmmc" ];
|
|
||||||
initrd.kernelModules = [ "dm-snapshot" ];
|
|
||||||
kernelModules = [ "kvm-intel" ];
|
|
||||||
extraModulePackages = [ ];
|
|
||||||
kernelParams = [
|
|
||||||
# HACK Disables fixes for spectre, meltdown, L1TF and a number of CPU
|
|
||||||
# vulnerabilities. Don't copy this blindly! And especially not for
|
|
||||||
# mission critical or server/headless builds exposed to the world.
|
|
||||||
"mitigations=off"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Refuse ICMP echo requests on my desktop/laptop; nobody has any business
|
|
||||||
# pinging them, unlike my servers.
|
|
||||||
kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Modules
|
|
||||||
modules.hardware = {
|
|
||||||
audio.enable = true;
|
|
||||||
fs = {
|
|
||||||
enable = true;
|
|
||||||
ssd.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# CPU
|
|
||||||
nix.maxJobs = lib.mkDefault 8;
|
|
||||||
hardware.cpu.intel.updateMicrocode = true;
|
|
||||||
# performance gives better battery life/perf than ondemand on sandy bridge and
|
|
||||||
# newer because of intel pstates.
|
|
||||||
powerManagement.cpuFreqGovernor = "performance";
|
|
||||||
# Without this wpa_supplicant may fail to auto-discover wireless interfaces at
|
|
||||||
# startup (and must be restarted).
|
|
||||||
networking.wireless.interfaces = [ "wlp2s0" ];
|
|
||||||
|
|
||||||
# Power management
|
|
||||||
environment.systemPackages = [ pkgs.acpi ];
|
|
||||||
powerManagement.powertop.enable = true;
|
|
||||||
# Monitor backlight control
|
|
||||||
programs.light.enable = true;
|
|
||||||
user.extraGroups = [ "video" ];
|
|
||||||
|
|
||||||
# Storage
|
|
||||||
fileSystems = {
|
|
||||||
"/" = {
|
|
||||||
device = "/dev/disk/by-label/nixos";
|
|
||||||
fsType = "ext4";
|
|
||||||
options = [ "noatime" ];
|
|
||||||
};
|
|
||||||
"/boot" = {
|
|
||||||
device = "/dev/disk/by-label/BOOT";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
"/home" = {
|
|
||||||
device = "/dev/disk/by-label/home";
|
|
||||||
fsType = "ext4";
|
|
||||||
options = [ "noatime" ];
|
|
||||||
};
|
|
||||||
"/usr/drive" = {
|
|
||||||
device = "kiiro:/volume1/homes/hlissner/Drive";
|
|
||||||
fsType = "nfs";
|
|
||||||
options = [
|
|
||||||
"nofail" "noauto" "noatime" "x-systemd.automount" "x-systemd.idle-timeout=5min"
|
|
||||||
"nodev" "nosuid" "noexec"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
swapDevices = [ { device = "/dev/disk/by-label/swap"; }];
|
|
||||||
|
|
||||||
boot.initrd.luks.devices.home = {
|
|
||||||
device = "/dev/nvme0n1p8";
|
|
||||||
preLVM = true;
|
|
||||||
allowDiscards = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
{ lib, ... }:
|
|
||||||
|
|
||||||
with builtins;
|
|
||||||
with lib;
|
|
||||||
rec {
|
|
||||||
# attrsToList
|
|
||||||
attrsToList = attrs:
|
|
||||||
mapAttrsToList (name: value: { inherit name value; }) attrs;
|
|
||||||
|
|
||||||
# mapFilterAttrs ::
|
|
||||||
# (name -> value -> bool)
|
|
||||||
# (name -> value -> { name = any; value = any; })
|
|
||||||
# attrs
|
|
||||||
mapFilterAttrs = pred: f: attrs: filterAttrs pred (mapAttrs' f attrs);
|
|
||||||
|
|
||||||
# Generate an attribute set by mapping a function over a list of values.
|
|
||||||
genAttrs' = values: f: listToAttrs (map f values);
|
|
||||||
|
|
||||||
# anyAttrs :: (name -> value -> bool) attrs
|
|
||||||
anyAttrs = pred: attrs:
|
|
||||||
any (attr: pred attr.name attr.value) (attrsToList attrs);
|
|
||||||
|
|
||||||
# countAttrs :: (name -> value -> bool) attrs
|
|
||||||
countAttrs = pred: attrs:
|
|
||||||
count (attr: pred attr.name attr.value) (attrsToList attrs);
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
{ inputs, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
inherit (lib) makeExtensible attrValues foldr;
|
|
||||||
inherit (modules) mapModules;
|
|
||||||
|
|
||||||
modules = import ./modules.nix {
|
|
||||||
inherit lib;
|
|
||||||
self.attrs = import ./attrs.nix { inherit lib; self = {}; };
|
|
||||||
};
|
|
||||||
|
|
||||||
mylib = makeExtensible (self:
|
|
||||||
with self; mapModules ./.
|
|
||||||
(file: import file { inherit self lib pkgs inputs; }));
|
|
||||||
in
|
|
||||||
mylib.extend
|
|
||||||
(self: super:
|
|
||||||
foldr (a: b: a // b) {} (attrValues super))
|
|
|
@ -1,30 +0,0 @@
|
||||||
{ lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with builtins;
|
|
||||||
with lib;
|
|
||||||
{
|
|
||||||
toCSSFile = file:
|
|
||||||
let fileName = removeSuffix ".scss" (baseNameOf file);
|
|
||||||
compiledStyles =
|
|
||||||
pkgs.runCommand "compileScssFile"
|
|
||||||
{ buildInputs = [ pkgs.sass ]; } ''
|
|
||||||
mkdir "$out"
|
|
||||||
scss --sourcemap=none \
|
|
||||||
--no-cache \
|
|
||||||
--style compressed \
|
|
||||||
--default-encoding utf-8 \
|
|
||||||
"${file}" \
|
|
||||||
>>"$out/${fileName}.css"
|
|
||||||
'';
|
|
||||||
in "${compiledStyles}/${fileName}.css";
|
|
||||||
|
|
||||||
toFilteredImage = imageFile: options:
|
|
||||||
let result = "result.png";
|
|
||||||
filteredImage =
|
|
||||||
pkgs.runCommand "filterWallpaper"
|
|
||||||
{ buildInputs = [ pkgs.imagemagick ]; } ''
|
|
||||||
mkdir "$out"
|
|
||||||
convert ${options} ${imageFile} $out/${result}
|
|
||||||
'';
|
|
||||||
in "${filteredImage}/${result}";
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
{ self, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
inherit (builtins) attrValues readDir pathExists concatLists;
|
|
||||||
inherit (lib) id mapAttrsToList filterAttrs hasPrefix hasSuffix nameValuePair removeSuffix;
|
|
||||||
inherit (self.attrs) mapFilterAttrs;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
mapModules = dir: fn:
|
|
||||||
mapFilterAttrs
|
|
||||||
(n: v:
|
|
||||||
v != null &&
|
|
||||||
!(hasPrefix "_" n))
|
|
||||||
(n: v:
|
|
||||||
let path = "${toString dir}/${n}"; in
|
|
||||||
if v == "directory" && pathExists "${path}/default.nix"
|
|
||||||
then nameValuePair n (fn path)
|
|
||||||
else if v == "regular" &&
|
|
||||||
n != "default.nix" &&
|
|
||||||
hasSuffix ".nix" n
|
|
||||||
then nameValuePair (removeSuffix ".nix" n) (fn path)
|
|
||||||
else nameValuePair "" null)
|
|
||||||
(readDir dir);
|
|
||||||
|
|
||||||
mapModules' = dir: fn:
|
|
||||||
attrValues (mapModules dir fn);
|
|
||||||
|
|
||||||
mapModulesRec = dir: fn:
|
|
||||||
mapFilterAttrs
|
|
||||||
(n: v:
|
|
||||||
v != null &&
|
|
||||||
!(hasPrefix "_" n))
|
|
||||||
(n: v:
|
|
||||||
let path = "${toString dir}/${n}"; in
|
|
||||||
if v == "directory"
|
|
||||||
then nameValuePair n (mapModulesRec path fn)
|
|
||||||
else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n
|
|
||||||
then nameValuePair (removeSuffix ".nix" n) (fn path)
|
|
||||||
else nameValuePair "" null)
|
|
||||||
(readDir dir);
|
|
||||||
|
|
||||||
mapModulesRec' = dir: fn:
|
|
||||||
let
|
|
||||||
dirs =
|
|
||||||
mapAttrsToList
|
|
||||||
(k: _: "${dir}/${k}")
|
|
||||||
(filterAttrs
|
|
||||||
(n: v: v == "directory" && !(hasPrefix "_" n))
|
|
||||||
(readDir dir));
|
|
||||||
files = attrValues (mapModules dir id);
|
|
||||||
paths = files ++ concatLists (map (d: mapModulesRec' d id) dirs);
|
|
||||||
in map fn paths;
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
{ inputs, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
with lib.my;
|
|
||||||
let sys = "x86_64-linux";
|
|
||||||
in {
|
|
||||||
mkHost = path: attrs @ { system ? sys, ... }:
|
|
||||||
nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
specialArgs = { inherit lib inputs system; };
|
|
||||||
modules = [
|
|
||||||
{
|
|
||||||
nixpkgs.pkgs = pkgs;
|
|
||||||
networking.hostName = mkDefault (removeSuffix ".nix" (baseNameOf path));
|
|
||||||
}
|
|
||||||
(filterAttrs (n: v: !elem n [ "system" ]) attrs)
|
|
||||||
../. # /default.nix
|
|
||||||
(import path)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
mapHosts = dir: attrs @ { system ? system, ... }:
|
|
||||||
mapModules dir
|
|
||||||
(hostPath: mkHost hostPath attrs);
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
{ lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
mkOpt = type: default:
|
|
||||||
mkOption { inherit type default; };
|
|
||||||
|
|
||||||
mkOpt' = type: default: description:
|
|
||||||
mkOption { inherit type default description; };
|
|
||||||
|
|
||||||
mkBoolOpt = default: mkOption {
|
|
||||||
inherit default;
|
|
||||||
type = types.bool;
|
|
||||||
example = true;
|
|
||||||
};
|
|
||||||
}
|
|
12
mod-grasp.nix
Normal file
12
mod-grasp.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ config, lib, pkgs, ...}:
|
||||||
|
|
||||||
|
{
|
||||||
|
systemd.services.grasp = {
|
||||||
|
description = "grasp server";
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "{$pkgs.grasp}/server/grasp_server.py --path /data/grasp/capture.org";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue