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 @@ | |||
| [](https://github.com/hlissner/doom-emacs) | ||||
| [](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, ... }: | ||||
| 
 | ||||
| { | ||||
| #	imports = [ | ||||
| #		./nvim.nix | ||||
| 	imports = [ | ||||
| 		./nvim.nix | ||||
| #	  ./unstable.nix | ||||
| #	]; | ||||
| 	]; | ||||
| 
 | ||||
| 
 | ||||
| 	environment.systemPackages = with pkgs; [ | ||||
|     tailscale | ||||
| 		htop | ||||
|     fzf | ||||
| 		iftop | ||||
| 		wget | ||||
| 		curl | ||||
|  | @ -16,6 +18,7 @@ | |||
|     bat | ||||
|     fd | ||||
|     ag | ||||
|     wpa_supplicant | ||||
| 		tcpdump | ||||
| 		whois | ||||
| 		mtr | ||||
|  | @ -27,51 +30,52 @@ | |||
| 		zip | ||||
| 		unzip | ||||
| 		rsync | ||||
|     #tmux | ||||
| 		tmux | ||||
| 		pwgen | ||||
| 	  glow | ||||
|     jq | ||||
| 		gitAndTools.gitFull | ||||
| 	  #neovim defined in ./nvim.nix | ||||
|     #firefox | ||||
|     #fractal | ||||
| 	  #pinentry_gnome | ||||
| 	 # wofi | ||||
| 	#	firefox | ||||
| 	#	fractal | ||||
| 	 # pinentry_gnome | ||||
|    pinentry_curses | ||||
| 		pass | ||||
| 		gcc | ||||
| 		less | ||||
| 		mpv | ||||
| 		zathura | ||||
| 	#	mpv | ||||
| 	#	zathura | ||||
| 	  #qmk_firmware | ||||
| 		python3 | ||||
| 	  gdb | ||||
| 	  vcv-rack | ||||
| 	 # vcv-rack | ||||
| 	  #xdotool | ||||
| 	  #neofetch | ||||
| 	  #calibre | ||||
| 		#openvpn | ||||
| 	  gimp | ||||
| 	  #gimp | ||||
| 	  xxd | ||||
| 	  kitty | ||||
| 	#	tilix | ||||
| 	 # kitty | ||||
| 		taskwarrior | ||||
|     #gnupg | ||||
| 		gnupg | ||||
| 	  openjdk | ||||
| 		glslviewer | ||||
| 	  filezilla | ||||
| 		signal-desktop | ||||
|     #wire-desktop | ||||
|     #tdesktop | ||||
|     #feedreader | ||||
|     newsflash | ||||
| 		syncthing | ||||
|     #filezilla | ||||
| 	#	signal-desktop | ||||
| 	 # wire-desktop | ||||
| 	#	tdesktop | ||||
| 	#	feedreader | ||||
|     #newsflash | ||||
| #		syncthing | ||||
| 	  dijo | ||||
| 	  #kdeconnect | ||||
| 	  #ssb-patchwork | ||||
|     #gnome3.gnome-tweaks | ||||
| 	  #gnome3.pomodoro | ||||
| 		#gnomeExtensions.gsconnect | ||||
| 		#gnomeExtensions.taskwhisperer | ||||
|     #gnomeExtensions.taskwhisperer | ||||
| 	  #gnome3.networkmanager-openvpn | ||||
| 		#python3Packages.youtube-dl | ||||
|     #appimage-run | ||||
| 	  #home-manager | ||||
| 	  home-manager | ||||
| 		libreoffice | ||||
| 		fontconfig | ||||
|     #hugo | ||||
|  | @ -82,14 +86,18 @@ | |||
| 	  supercollider | ||||
| 	  haskellPackages.tidal | ||||
| 	  pandoc | ||||
|    # calibre | ||||
| 	]; | ||||
| 
 | ||||
| 	programs.bash.enableCompletion = true; | ||||
| 
 | ||||
|   programs.gnupg.agent.enable = true; | ||||
|   programs.gnupg.agent.pinentryFlavor = "curses"; | ||||
|   programs.gnupg.agent.enableSSHSupport = true; | ||||
| 	# needed for vcv-rack | ||||
| 	nixpkgs.config.allowUnfree = true;  | ||||
| 
 | ||||
|   #system.copySystemConfiguration = true; | ||||
| 	system.copySystemConfiguration = true; | ||||
|   #services.syncthing = { | ||||
| 	#  enable = true; | ||||
| 	#  openDefaultPorts = true; | ||||
|  | @ -99,12 +107,14 @@ | |||
| 	#}; | ||||
| 
 | ||||
| 	#zsh powerlevel10k | ||||
| 	programs.zsh.enable = true; | ||||
| 	programs.zsh.promptInit = "source ${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/powerlevel10k.zsh-theme"; | ||||
| 	users.users.anish.shell = pkgs.zsh; | ||||
|   #programs.zsh.enable = true; | ||||
| 	#programs.zsh.promptInit = "source ${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/powerlevel10k.zsh-theme"; | ||||
| 	users.users.anish.shell = pkgs.bash; | ||||
| 
 | ||||
| 	#android  | ||||
| 	programs.adb.enable = true; | ||||
| 	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") | ||||
|     ]; | ||||
| 
 | ||||
|   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.kernelModules = [ ]; | ||||
|   boot.kernelModules = [ "kvm-intel" ]; | ||||
|   boot.extraModulePackages = [ ]; | ||||
| 
 | ||||
|   fileSystems."/" = | ||||
|     { device = "/dev/disk/by-uuid/6ee9d430-1b1b-4e39-bced-606145570a78"; | ||||
|       fsType = "btrfs"; | ||||
|       options = [ "subvol=root" ]; | ||||
|     { device = "/dev/disk/by-uuid/ade0752d-84d3-4e39-865b-9027ba2d5c67"; | ||||
|       fsType = "ext4"; | ||||
|     }; | ||||
| 
 | ||||
|   fileSystems."/home" = | ||||
|     { device = "/dev/disk/by-uuid/6ee9d430-1b1b-4e39-bced-606145570a78"; | ||||
|       fsType = "btrfs"; | ||||
|       options = [ "subvol=home" ]; | ||||
|     }; | ||||
| 
 | ||||
|   fileSystems."/boot" = | ||||
|     { device = "/dev/disk/by-uuid/AD0C-92EF"; | ||||
|   fileSystems."/boot/efi" = | ||||
|     { device = "/dev/disk/by-uuid/1715-278E"; | ||||
|       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 = | ||||
|     [ { 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"; | ||||
							
								
								
									
										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