box
This commit is contained in:
parent
fa53788c7a
commit
31e15f38d2
22
LICENSE
22
LICENSE
|
@ -1,22 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2021 Henrik Lissner.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
128
README.md
128
README.md
|
@ -1,128 +0,0 @@
|
|||
[![Made with Doom Emacs](https://img.shields.io/badge/Made_with-Doom_Emacs-blueviolet.svg?style=flat-square&logo=GNU%20Emacs&logoColor=white)](https://github.com/hlissner/doom-emacs)
|
||||
[![NixOS Unstable](https://img.shields.io/badge/NixOS-unstable-blue.svg?style=flat-square&logo=NixOS&logoColor=white)](https://nixos.org)
|
||||
|
||||
**Hey,** you. You're finally awake. You were trying to configure your OS declaratively, right? Walked right into that NixOS ambush, same as us, and those dotfiles over there.
|
||||
|
||||
<img src="/../screenshots/alucard/fakebusy.png" width="100%" />
|
||||
|
||||
<p align="center">
|
||||
<span><img src="/../screenshots/alucard/desktop.png" height="178" /></span>
|
||||
<span><img src="/../screenshots/alucard/rofi.png" height="178" /></span>
|
||||
<span><img src="/../screenshots/alucard/tiling.png" height="178" /></span>
|
||||
</p>
|
||||
|
||||
------
|
||||
|
||||
| | |
|
||||
|-|-|
|
||||
| **Shell:** | zsh + zgen |
|
||||
| **DM:** | lightdm + lightdm-mini-greeter |
|
||||
| **WM:** | bspwm + polybar |
|
||||
| **Editor:** | [Doom Emacs][doom-emacs] (and occasionally [vim]) |
|
||||
| **Terminal:** | st |
|
||||
| **Launcher:** | rofi |
|
||||
| **Browser:** | firefox |
|
||||
| **GTK Theme:** | [Ant Dracula](https://github.com/EliverLara/Ant-Dracula) |
|
||||
|
||||
-----
|
||||
|
||||
## Quick start
|
||||
|
||||
1. Yoink the latest build of [NixOS 21.05][nixos].
|
||||
2. Boot into the installer.
|
||||
3. Do your partitions and mount your root to `/mnt` ([for example](hosts/kuro/README.org))
|
||||
4. Install these dotfiles:
|
||||
5. `nix-shell -p git nixFlakes`
|
||||
6. `git clone https://github.com/hlissner/dotfiles /mnt/etc/nixos`
|
||||
7. Install NixOS: `nixos-install --root /mnt --flake /mnt/etc/nixos#XYZ`, where
|
||||
`XYZ` is [the host you want to install](hosts/). Use `#generic` for a
|
||||
simple, universal config, or create a sub-directory in `hosts/` for your device. See [host/kuro] for an example.
|
||||
8. Reboot!
|
||||
9. Change your `root` and `$USER` passwords!
|
||||
|
||||
## Management
|
||||
|
||||
And I say, `bin/hey`. [What's going on?](http://hemansings.com/)
|
||||
|
||||
```
|
||||
Usage: hey [global-options] [command] [sub-options]
|
||||
|
||||
Available Commands:
|
||||
check Run 'nix flake check' on your dotfiles
|
||||
gc Garbage collect & optimize nix store
|
||||
generations Explore, manage, diff across generations
|
||||
help [SUBCOMMAND] Show usage information for this script or a subcommand
|
||||
rebuild Rebuild the current system's flake
|
||||
repl Open a nix-repl with nixpkgs and dotfiles preloaded
|
||||
rollback Roll back to last generation
|
||||
search Search nixpkgs for a package
|
||||
show [ARGS...]
|
||||
ssh HOST [COMMAND] Run a bin/hey command on a remote NixOS system
|
||||
swap PATH [PATH...] Recursively swap nix-store symlinks with copies (or back).
|
||||
test Quickly rebuild, for quick iteration
|
||||
theme THEME_NAME Quickly swap to another theme module
|
||||
update [INPUT...] Update specific flakes or all of them
|
||||
upgrade Update all flakes and rebuild system
|
||||
|
||||
Options:
|
||||
-d, --dryrun Don't change anything; preform dry run
|
||||
-D, --debug Show trace on nix errors
|
||||
-f, --flake URI Change target flake to URI
|
||||
-h, --help Display this help, or help for a specific command
|
||||
-i, -A, -q, -e, -p Forward to nix-env
|
||||
```
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
+ **Why NixOS?**
|
||||
|
||||
Because declarative, generational, and immutable configuration is a godsend
|
||||
when you have a fleet of computers to manage.
|
||||
|
||||
+ **How do you manage secrets?**
|
||||
|
||||
With [agenix].
|
||||
|
||||
+ **How do I change the default username?**
|
||||
|
||||
1. Set the `USER` environment variable the first time you run `nixos-install`:
|
||||
`USER=myusername nixos-install --root /mnt --flake /path/to/dotfiles#XYZ`
|
||||
2. Or change `"hlissner"` in modules/options.nix.
|
||||
|
||||
+ **Why did you write bin/hey?**
|
||||
|
||||
I envy Guix's CLI and want similar for NixOS, but its toolchain is spread
|
||||
across many commands, none of which are as intuitive: `nix`,
|
||||
`nix-collect-garbage`, `nixos-rebuild`, `nix-env`, `nix-shell`.
|
||||
|
||||
I don't claim `hey` is the answer, but everybody likes their own brew.
|
||||
|
||||
+ **How 2 flakes?**
|
||||
|
||||
Would it be the NixOS experience if I gave you all the answers in one,
|
||||
convenient place?
|
||||
|
||||
No. Suffer my pain:
|
||||
|
||||
+ [A three-part tweag article that everyone's read.](https://www.tweag.io/blog/2020-05-25-flakes/)
|
||||
+ [An overengineered config to scare off beginners.](https://github.com/nrdxp/nixflk)
|
||||
+ [A minimalistic config for scared beginners.](https://github.com/colemickens/nixos-flake-example)
|
||||
+ [A nixos wiki page that spells out the format of flake.nix.](https://nixos.wiki/wiki/Flakes)
|
||||
+ [Official documentation that nobody reads.](https://nixos.org/learn.html)
|
||||
+ [Some great videos on general nixOS tooling and hackery.](https://www.youtube.com/channel/UC-cY3DcYladGdFQWIKL90SQ)
|
||||
+ A couple flake configs that I
|
||||
[may](https://github.com/LEXUGE/nixos)
|
||||
[have](https://github.com/bqv/nixrc)
|
||||
[shamelessly](https://git.sr.ht/~dunklecat/nixos-config/tree)
|
||||
[rummaged](https://github.com/utdemir/dotfiles)
|
||||
[through](https://github.com/purcell/dotfiles).
|
||||
+ [Some notes about using Nix](https://github.com/justinwoo/nix-shorts)
|
||||
+ [What helped me figure out generators (for npm, yarn, python and haskell)](https://myme.no/posts/2020-01-26-nixos-for-development.html)
|
||||
+ [What y'all will need when Nix drives you to drink.](https://www.youtube.com/watch?v=Eni9PPPPBpg)
|
||||
|
||||
|
||||
[doom-emacs]: https://github.com/hlissner/doom-emacs
|
||||
[vim]: https://github.com/hlissner/.vim
|
||||
[nixos]: https://releases.nixos.org/?prefix=nixos/unstable/
|
||||
[host/kuro]: https://github.com/hlissner/dotfiles/tree/master/hosts/kuro
|
||||
[agenix]: https://github.com/ryantm/agenix
|
34
backup.nix
Normal file
34
backup.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
# Assumes the remote borg backup server has already been initialized
|
||||
# borg init --encryption-key=repokey-blake2 -rsh 'ssh -i /run/keys/id_ed25519_borgbase' 20779@hk-s020.rsync.net:<borg-archive>
|
||||
services.borgbackup.jobs = {
|
||||
backupTaskwarriorRsync = {
|
||||
paths = [ "/var/lib/taskserver" ];
|
||||
doInit = true;
|
||||
repo = "20779@hk-s020.rsync.net:taskwarrior" ;
|
||||
encryption = {
|
||||
mode = "repokey-blake2";
|
||||
passCommand = "cat /run/keys/rsync";
|
||||
};
|
||||
environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
|
||||
compression = "auto,lzma";
|
||||
startAt = "weekly";
|
||||
extraArgs = "--remote-path=borg1";
|
||||
};
|
||||
};
|
||||
services.borgbackup.jobs = {
|
||||
backupShaarliRsync = {
|
||||
paths = [ "/var/www/shaarli-config/data/datastore.php" "/var/www/shaarli-config/config" "/var/www/shaarli-config/.json.config" ];
|
||||
doInit = true;
|
||||
repo = "20779@hk-s020.rsync.net:shaarli" ;
|
||||
encryption = {
|
||||
mode = "repokey-blake2";
|
||||
passCommand = "cat /run/keys/rsync";
|
||||
};
|
||||
environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
|
||||
compression = "auto,lzma";
|
||||
startAt = "weekly";
|
||||
extraArgs = "--remote-path=borg1";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
while true; do
|
||||
xdotool mousedown 1
|
||||
sleep 0.01
|
||||
xdotool mouseup 1
|
||||
sleep 0.01
|
||||
done
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Script: bspc-focus
|
||||
# Author: Henrik Lissner
|
||||
# Usage:
|
||||
# bspc-focus [-m] (west|south|north|east)
|
||||
# bspc-focus south
|
||||
# bspc-focus -m west
|
||||
#
|
||||
# Focus the next window in direction. If -m is supplied, jump to the next
|
||||
# monitor in that direction.
|
||||
#
|
||||
# The behavior of the base 'bspc node -f' is odd when crossing screens. It will
|
||||
# focus the last selected window on that screen, rather than the window on the
|
||||
# connecting edge, which is unintuitive.
|
||||
|
||||
set -e
|
||||
|
||||
leap=
|
||||
if [[ $1 == -m ]]; then
|
||||
leap=1; shift
|
||||
fi
|
||||
dir=$1
|
||||
opposite=
|
||||
|
||||
case $dir in
|
||||
west) opposite=east ;;
|
||||
east) opposite=west ;;
|
||||
north) opposite=north ;;
|
||||
south) opposite=south ;;
|
||||
*) >&2 echo "Not a valid direction: $dir"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
if [[ -n $leap ]]; then
|
||||
# jump to monitor in direction
|
||||
bspc monitor -f "$dir"
|
||||
else
|
||||
# jump to window in direction (unless at edge of last monitor)
|
||||
if ! bspc node -f "$dir.local"; then
|
||||
if [[ $(bspc query -M -m "$dir") ]]; then
|
||||
bspc monitor -f "$dir"
|
||||
# Ensure we start at the edge of the window we arrived from
|
||||
while bspc node -f "$opposite.local"; do :; done
|
||||
fi
|
||||
fi
|
||||
fi
|
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -i zsh -p jshon
|
||||
|
||||
# Script: bspc-presel
|
||||
# Author: Henrik Lissner
|
||||
# Usage:
|
||||
# bspc-presel RATIO
|
||||
# bspc-presel 0.2
|
||||
#
|
||||
# Wrote this to invert the ratio on east/south-bound preselections. In English
|
||||
# that means bspc node -p 0.2 should resize the preselection to 20%, whether or
|
||||
# not it's on the west or east side of the window (or north or south side),
|
||||
# which isn't the case by default.
|
||||
#
|
||||
# NOTE: We use zsh for this because bash chokes on float arithmetic.
|
||||
|
||||
ratio="$1"
|
||||
case "$(bspc query -T -n focused | jshon -e presel -e splitDir | tr -d \")" in
|
||||
west|north) bspc node -o $ratio ;;
|
||||
east|south) bspc node -o $(( 1.0 - ratio )) ;;
|
||||
esac
|
|
@ -1,101 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -i zsh -p jshon wmutils-core
|
||||
|
||||
# Script: bspc-subtract-presel
|
||||
# Author: Henrik Lissner (w/ credit to @Chrysostomus)
|
||||
# Usage:
|
||||
# bspc-resize-to-presel
|
||||
#
|
||||
# (Adapted from Chrysostomus/bspwm-scripts/bin/resizetopresel.sh)
|
||||
#
|
||||
# This script resizes the current window by "subtracting" the bspwm preselection
|
||||
# on the current node. In English, that means this will reduce the window's
|
||||
# width by 20%:
|
||||
#
|
||||
# bspc node -p east -o 0.2 && bspc-subtract-presel
|
||||
#
|
||||
# NOTE: We use zsh for this because bash chokes on float arithmetic.
|
||||
|
||||
# Check if the brother node is a receptacle
|
||||
if [[ $(bspc query -T -n @brother/ | jshon -e client) = null ]]; then
|
||||
# Yep, it's a receptacle. Get the real dimensions
|
||||
eval $(grep "window_gap" ~/.config/bspwm/rc.d/theme | tr -cd [0-9])
|
||||
# Get orientation
|
||||
wattr xywh $(pfw) | read focused_x focused_y focused_width focused_height
|
||||
receptacle_y=$(bspc query -T -n @brother/ | jshon -e rectangle -e y)
|
||||
if [[ "$focused_y" -eq "$receptacle_y" ]]; then
|
||||
receptacle_width=$(bspc query -T -n @brother/ | jshon -e rectangle -e width)
|
||||
receptacle_x=$(bspc query -T -n @brother/ | jshon -e rectangle -e x)
|
||||
# receptacle and window have the same height, so they are side by side
|
||||
if [[ receptacle_x -gt focused_x ]]; then
|
||||
echo "receptacle is right of the window"
|
||||
# get the true window dimension
|
||||
true_dim=$(( receptacle_width + gap ))
|
||||
# kill the repectacle
|
||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
||||
# resize the window
|
||||
bspc node @east -r -$true_dim || bspc node @west -r +$true_dim
|
||||
else
|
||||
echo "receptacle is left of the window"
|
||||
# get the true window dimension
|
||||
true_dim=$(( receptacle_width + gap ))
|
||||
# kill the repectacle
|
||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
||||
# resize the window
|
||||
bspc node @west -r +$true_dim || bspc node @east -r -$true_dim
|
||||
fi
|
||||
else
|
||||
receptacle_height=$(bspc query -T -n @brother/ | jshon -e rectangle -e height)
|
||||
# width is necessarily equal if height is not, because the nodes are
|
||||
# brothers Window are on the top of each other
|
||||
if [[ receptacle_y -gt focused_y ]]; then
|
||||
echo "receptacle is below the window"
|
||||
# get the true window dimension
|
||||
true_dim=$(( receptacle_height + gap))
|
||||
# kill the repectacle
|
||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
||||
# resize the window
|
||||
bspc node @south -r -$true_dim || bspc node @north -r +$true_dim
|
||||
else
|
||||
echo "receptacle is above the window"
|
||||
# get the true window dimension
|
||||
true_dim=$(( receptacle_height + gap))
|
||||
# kill the repectacle
|
||||
for i in $(bspc query -N -n .leaf.!window.local); do bspc node $i -k; done
|
||||
# resize the window
|
||||
bspc node @north -r +$true_dim || bspc node @south -r -$true_dim
|
||||
fi
|
||||
fi
|
||||
echo $true_dim
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# If the focused window is not preselected, do nothing
|
||||
[[ "$(bspc query -T -n focused | jshon -e presel)" == null ]] && exit 0
|
||||
|
||||
dir=$(bspc query -T -n focused | jshon -e presel -e splitDir | tr -d \")
|
||||
ratio=$(bspc query -T -n focused | jshon -e presel -e splitRatio)
|
||||
case "$dir" in
|
||||
west)
|
||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e width)
|
||||
bspc node @west -r +$((${cur}*${ratio})) || \
|
||||
bspc node @east -r -$((${cur}*${ratio}))
|
||||
;;
|
||||
east)
|
||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e width)
|
||||
bspc node @east -r -$((${cur}*(1.0-${ratio}))) || \
|
||||
bspc node @west -r +$((${cur}*${ratio}))
|
||||
;;
|
||||
|
||||
north)
|
||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e height)
|
||||
bspc node @north -r +$((${cur}*${ratio})) || \
|
||||
bspc node @south -r -$((${cur}*${ratio}))
|
||||
;;
|
||||
south)
|
||||
cur=$(bspc query -T -n focused | jshon -e rectangle -e height)
|
||||
bspc node @south -r -$(( ${cur} * (1.0 - ${ratio}) )) || \
|
||||
bspc node @north -r +$(( ${cur} * ${ratio} ))
|
||||
esac
|
||||
|
||||
bspc node -p cancel
|
|
@ -1,48 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Script: bspc-swap
|
||||
# Author: Henrik Lissner
|
||||
# Usage:
|
||||
# bspc-swap [-m] (west|south|north|east)
|
||||
# bspc-swap south
|
||||
# bspc-swap -m west
|
||||
#
|
||||
# Swaps current window with the window in a direction. If -m is set, move window
|
||||
# to the next monitor in that direction.
|
||||
#
|
||||
# The behavior of the base 'bspc node -s' is odd when crossing screens. It will
|
||||
# swaps with the last selected window on that screen, rather than the window on
|
||||
# the connecting edge, which is unintuitive.
|
||||
|
||||
set -e
|
||||
|
||||
leap=
|
||||
if [[ $1 == -m ]]; then
|
||||
leap=1
|
||||
dir=$2
|
||||
else
|
||||
dir=$1
|
||||
fi
|
||||
|
||||
case $dir in west|south|north|east) ;;
|
||||
*) >&2 echo "Not a valid direction: $dir"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
if [[ -n $leap ]]; then
|
||||
# move window to monitor in direction
|
||||
old_id=$(bspc query -N -n focused)
|
||||
if [[ $(bspc query -M -m "$dir") ]]; then
|
||||
bspc node -m "$dir"
|
||||
bspc node -f "$old_id"
|
||||
fi
|
||||
else
|
||||
# move window in direction
|
||||
old_id=$(bspc query -N -n focused)
|
||||
if bspc node -s "$dir.local"; then
|
||||
bspc node -f "$old_id"
|
||||
elif [[ -n $(bspc query -M -m "$dir") ]]; then
|
||||
bspc node -m "$dir"
|
||||
bspc node -f "$old_id"
|
||||
fi
|
||||
fi
|
385
bin/hey
385
bin/hey
|
@ -1,385 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -p ruby_2_7 -i "ruby -S" --quiet
|
||||
|
||||
DESC = <<~DESC
|
||||
Nix's CLI has a poor user story, in my opinion. It could be better; Guix is a
|
||||
good role model here. I wrote this script to abstract the more common
|
||||
workflows, like rebuilding (nixos-rebuild), cleaning up (nix-collect-garbage),
|
||||
package/env management (nix-env), updating, rolling back, etc. As well as some
|
||||
utility operations (like managing generations, building remotely, or swapping
|
||||
themes on the fly).
|
||||
|
||||
Because I can go months without shaving yaks in NixOS, exact flags or details
|
||||
are often and easily forgotten. This spares me that fumbling phase and also
|
||||
serves as a reference.
|
||||
|
||||
Note: `hey` can also be used as a shortcut for nix-env:
|
||||
|
||||
hey -q
|
||||
hey -iA nixos.htop
|
||||
hey -e htop
|
||||
DESC
|
||||
|
||||
require 'shellwords'
|
||||
require 'optparse'
|
||||
|
||||
module Hey
|
||||
extend self
|
||||
Command = Struct.new(:name, :desc, :args, :opts, :fn)
|
||||
|
||||
@@opts = {}
|
||||
@@alias = {}
|
||||
@@commands = {}
|
||||
@@cli = nil
|
||||
def self.defcmd names, &block
|
||||
names = (names.kind_of?(Array) ? names : [names]).map(&:to_s)
|
||||
names.drop(1).each { |n| @@alias[n] = names.first }
|
||||
cli = Command.new names.first, [], []
|
||||
cli.opts = OptionParser.new do |opt|
|
||||
opt.banner = "Usage: #{opt.program_name} #{cli.name} [options]"
|
||||
opt.separator "\nOptions:"
|
||||
opt.on_tail('-h', '--help', 'Prints this help') { puts opt; exit }
|
||||
end
|
||||
@@cli = cli
|
||||
fn = block.call cli
|
||||
cli.fn = lambda do |args|
|
||||
begin
|
||||
cli.opts.banner +=
|
||||
(cli.args ? " #{cli.args.join ' '}" : "") +
|
||||
(cli.desc ? "\n\n#{cli.desc[0]}\n\n#{cli.desc[1..].join "\n"}" : "")
|
||||
cli.opts.order!(args, into: @@opts)
|
||||
fn.call args
|
||||
ensure @@cli = nil end
|
||||
end
|
||||
@@commands[cli.name] = @@cli
|
||||
end
|
||||
def self.opts(*args) @@cli.opts.on(*args) end
|
||||
def self.args(*args) @@cli.args = args end
|
||||
def self.desc(*args) @@cli.desc = args end
|
||||
def self.sh(args, sudo: false, noerror: false)
|
||||
raise ArgumentError unless args.kind_of?(Array)
|
||||
args.unshift('sudo') if sudo
|
||||
args.compact!
|
||||
if @@opts[:dryrun]
|
||||
print "#{args}\n"
|
||||
return true
|
||||
else
|
||||
result = system "#{args.shelljoin} 2>&1"
|
||||
exit($?.exitstatus) unless noerror or result
|
||||
return result
|
||||
end
|
||||
end
|
||||
def self.rebuild(*args, sudo: false, host: nil)
|
||||
host ||= ENV['HOST'] || `hostname`.rstrip
|
||||
sh ["nixos-rebuild",
|
||||
"--flake", "#{@@opts[:flake]}##{host}",
|
||||
"--option", "pure-eval", "no",
|
||||
*args], sudo: sudo
|
||||
end
|
||||
|
||||
#
|
||||
defcmd :repl do
|
||||
desc "Open a nix-repl with nixpkgs and dotfiles preloaded"
|
||||
lambda do |args|
|
||||
tempfile = '/tmp/dotfiles-repl.nix'
|
||||
File.write('/tmp/dotfiles-repl.nix', "(builtins.getFlake \"#{@@opts[:flake]}\")")
|
||||
begin
|
||||
sh ["nix", "repl", "<nixpkgs>", tempfile, *args]
|
||||
ensure
|
||||
File.delete tempfile
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defcmd [:check, :ch] do
|
||||
desc "Run 'nix flake check' on your dotfiles"
|
||||
lambda do |args|
|
||||
sh ["nix", "flake", "check", @@opts[:flake]]
|
||||
end
|
||||
end
|
||||
|
||||
defcmd :show do
|
||||
desc "[ARGS...]", "Run 'nix flake show' on your dotfiles"
|
||||
lambda do |args|
|
||||
sh ["nix", "flake", "show", @@opts[:flake]]
|
||||
end
|
||||
end
|
||||
|
||||
defcmd :theme do
|
||||
desc 'Quickly swap to another theme module'
|
||||
args "THEME_NAME"
|
||||
lambda do |args|
|
||||
ENV["THEME"] = args.shift
|
||||
rebuild "--fast", "test"
|
||||
end
|
||||
end
|
||||
|
||||
defcmd [:test, :t] do
|
||||
desc "Quickly rebuild, for quick iteration"
|
||||
lambda do |args|
|
||||
rebuild "--fast", "test", *args
|
||||
end
|
||||
end
|
||||
|
||||
defcmd [:rebuild, :re] do
|
||||
desc "Rebuild the current system's flake"
|
||||
opts '--build-host HOST', "Where to build the flake"
|
||||
opts '--target-host HOST', "Where to deploy the built derivations"
|
||||
opts '--host HOST', "The target nixosConfiguration to build"
|
||||
opts '--user', "Rebuild as user, rather than root"
|
||||
opts '--fast', "Equivalent to --no-build-nix --show-trace for quick rebuilding"
|
||||
lambda do |args|
|
||||
Dir.chdir(@@opts[:flake]) do
|
||||
args = ["switch"] unless args.length > 0
|
||||
rebuild(*(@@opts[:"build-host"] ? ["--build-host", @@opts[:"build-host"]] : []),
|
||||
*(@@opts[:"target-host"] ? ["--target-host", @@opts[:"target-host"]] : []),
|
||||
@@opts[:fast] ? "--fast" : nil,
|
||||
@@opts[:debug] ? "--show-trace" : nil,
|
||||
*args,
|
||||
sudo: !@@opts[:user],
|
||||
host: @@opts[:host])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defcmd :rollback do
|
||||
desc "Roll back to last generation"
|
||||
lambda do |_args|
|
||||
rebuild "--rollback", "switch"
|
||||
end
|
||||
end
|
||||
|
||||
defcmd [:update, :u] do
|
||||
desc "Update specific flakes or all of them"
|
||||
args "[INPUT...]"
|
||||
lambda do |args|
|
||||
if args.empty?
|
||||
puts "Updating all flakes.."
|
||||
sh ["nix", "flake", "update", @@opts[:flake]]
|
||||
else
|
||||
puts "Trying to update flakes: #{args.join ' '}"
|
||||
sh ["nix", "flake", "lock"]
|
||||
.concat(args.map { |f| [ "--update-input", f ]}.flatten)
|
||||
.concat([@@opts[:flake]])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defcmd [:upgrade, :up] do
|
||||
desc "Update all flakes and rebuild system"
|
||||
lambda do |_args|
|
||||
update
|
||||
rebuild :switch
|
||||
end
|
||||
end
|
||||
|
||||
defcmd [:search, :s] do
|
||||
desc "Search nixpkgs for a package"
|
||||
lambda do |args|
|
||||
sh ["nix", "search", "nixpkgs", *args]
|
||||
end
|
||||
end
|
||||
|
||||
defcmd :swap do
|
||||
desc "Recursively swap nix-store symlinks with copies (or back).",
|
||||
"The purpose is so you can have copies of your dotfiles that can be modified in",
|
||||
"place (so you can iterate on them quickly instead of 'hey re'ing between",
|
||||
"changes). Run again to restore the old link(s).\n",
|
||||
"Warning: backup your copies, or they will be destroyed when restored!"
|
||||
args "PATH", "[PATH...]"
|
||||
lambda do |args|
|
||||
for target in args
|
||||
if File.directory? target
|
||||
files = Dir.glob("#{target}/**/*.nix-store-backup")
|
||||
if files.length > 0
|
||||
puts "There are swapped files here. Unswapping!"
|
||||
call :swap, *files
|
||||
else
|
||||
puts "Swapping files in #{target}"
|
||||
call :swap, *(Dir.glob("#{target}/**/*")
|
||||
.select { |f| File.symlink? f }
|
||||
.select { |l| File.readlink(l).match '^/nix/store/' })
|
||||
end
|
||||
elsif File.file? "#{target}.nix-store-backup"
|
||||
puts "Unswapping #{target}"
|
||||
sh [:mv, '-i', "#{target}.nix-store-backup", target]
|
||||
elsif File.file? target
|
||||
puts "Swapping #{target}"
|
||||
sh [:mv, target, "#{target}.nix-store-backup"]
|
||||
sh [:cp, "#{target}.nix-store-backup", target]
|
||||
else
|
||||
puts "Not a valid target: #{target}"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defcmd :gc do
|
||||
desc "Garbage collect & optimize nix store"
|
||||
opts "-a", "--all", "GC both the user and system profiles"
|
||||
opts "-s", "--system", "Only GC the system profile"
|
||||
lambda do |_args|
|
||||
if @@opts[:all] or @@opts[:system]
|
||||
puts "Cleaning up your system profile..."
|
||||
sh %w{nix-collect-garbage -d}, sudo: true
|
||||
sh %w{nix-store --optimise}, sudo: true
|
||||
# Clear out left-over secrets. The switch-to-configuration call below will
|
||||
# regenerate them.
|
||||
if File.exists?("/run/secrets/*")
|
||||
sh %w{rm -rf /run/secrets/*}, sudo: true
|
||||
end
|
||||
# nix-collect-garbage is a Nix tool, not a NixOS tool. It won't delete old
|
||||
# boot entries until you do a nixos-rebuild (which means we'll always have
|
||||
# 2 boot entries at any time). Instead, we properly delete them by
|
||||
# reloading the current environment.
|
||||
sh %w{nix-env --delete-generations old --profile /nix/var/nix/profiles/system}, sudo: true
|
||||
sh %w{/nix/var/nix/profiles/system/bin/switch-to-configuration switch}, sudo: true
|
||||
end
|
||||
if @@opts[:all] or not @@opts[:system]
|
||||
puts "Cleaning up your user profile..."
|
||||
sh %w{nix-collect-garbage -d}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defcmd :ssh do
|
||||
desc "Run a bin/hey command on a remote NixOS system",
|
||||
"If COMMAND is one of switch, test, or boot (if omitted, 'test' is assumed),",
|
||||
"that host's config is built locally and then copied to the remote over ssh.",
|
||||
"This will prompt you for your root password, as it temporarily opens root ssh",
|
||||
"access (via your existing ssh key) to the remote -- which is immediately removed",
|
||||
"upon completion.",
|
||||
"",
|
||||
"If COMMAND is anything else, it merely runs 'nix run github:hlissner/dotfiles",
|
||||
"-- COMMAND' on the rmeote."
|
||||
args "HOST", "[COMMAND]"
|
||||
opts '--host HOST', "The nixos config to build and deploy to HOST"
|
||||
lambda do |args|
|
||||
target, command = args.take(2)
|
||||
command ||= "test"
|
||||
if command.match(/switch|test|boot/)
|
||||
puts "Enabling root ssh access on #{target}. Enter root password for remote system:"
|
||||
if sh ["ssh", "-t", target,
|
||||
"sudo mkdir -p /root/.ssh && sudo cp -f ~/.ssh/authorized_keys /root/.ssh/"],
|
||||
noerror: true
|
||||
begin
|
||||
puts "Building #{@@opts[:flake]}##{@@opts[:host] || target} for #{target}"
|
||||
call "rebuild", ["--user",
|
||||
"--host", @@opts[:host] || target,
|
||||
"--build-host", "localhost",
|
||||
"--target-host", "root@#{target}",
|
||||
command]
|
||||
ensure
|
||||
puts "Undoing root ssh access on #{target}"
|
||||
sh ["ssh", "-t", "root@#{target}", "rm -f /root/.ssh/authorized_keys"]
|
||||
end
|
||||
end
|
||||
else
|
||||
command = "nix run github:hlissner/dotfiles -- #{command}"
|
||||
puts "Running '#{command}' on #{target}"
|
||||
sh ["ssh", "-t", target, command]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO Generalize this to nix profiles
|
||||
defcmd [:generations, :gen] do
|
||||
desc "Explore, manage, diff across generations"
|
||||
opts '--diff FROM TO', "Diff profiles FROM with TO (numbers)"
|
||||
opts '-r', '--remove PROFILE', "Delete PROFILE from history"
|
||||
lambda do |args|
|
||||
profile = "/nix/var/nix/profiles/system"
|
||||
case args.shift
|
||||
when "diff"
|
||||
from, to = *args
|
||||
if from == to
|
||||
puts "Comparing the same profile! Aborting..."
|
||||
exit 1
|
||||
elsif [from, to].compact.select do |gen|
|
||||
File.exists? "#{profile}-#{gen}-link" or
|
||||
puts "Generation #{gen} does not exist!"
|
||||
end.length != [from, to].compact.length
|
||||
exit 2
|
||||
end
|
||||
from = from ? "#{profile}-#{from}-link" : profile
|
||||
to = to ? "#{profile}-#{to}-link" : profile
|
||||
fromDevs = `nix-store -q --references #{from}`.split
|
||||
toDevs = `nix-store -q --references #{to}`.split
|
||||
puts (fromDevs - toDevs).map { |d| "\e[31m-#{d}\e[0m" }
|
||||
puts (toDevs - fromDevs).map { |d| "\e[32m+#{d}\e[0m" }
|
||||
when /ls|list/
|
||||
sh ["nix-env", "--list-generations", "--profile", profile], sudo: true
|
||||
when "remove"
|
||||
sh ["nix-env", "--delete-generations", "--profile", profile, *args], sudo: true
|
||||
when "switch"
|
||||
puts "Targeted rollback not supported yet" # TODO Is this true?
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class UsageError < StandardError; end
|
||||
defcmd [:help, :h] do
|
||||
desc "Show usage information for this script or a subcommand"
|
||||
args "[SUBCOMMAND]"
|
||||
lambda do |args|
|
||||
raise UsageError unless args.first
|
||||
call args.first, ["-h", *args.drop(1)]
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
def self.call command, args
|
||||
cmd = command.to_s
|
||||
cmd = @@alias[cmd] while cmd and not @@commands.key?(cmd)
|
||||
if cmd
|
||||
@@commands[cmd].fn.call args
|
||||
elsif command
|
||||
puts "Couldn't recognize command '#{command}'"
|
||||
exit 1
|
||||
else
|
||||
raise UsageError
|
||||
end
|
||||
end
|
||||
|
||||
def self.run args=[]
|
||||
opts = OptionParser.new do |opt|
|
||||
opt.banner = "Usage: hey [global-options] [command] [sub-options]\n\n" + DESC
|
||||
opt.separator "\n\nAvailable Commands:"
|
||||
opt.separator (@@commands.values
|
||||
.reject { |c| c.desc.empty? }
|
||||
.sort { |a,b| a.name <=> b.name }
|
||||
.map { |c| " %-22s %s\n" % ["#{c.name} #{c.args.join ' '}",
|
||||
c.desc[0]]})
|
||||
opt.separator "\nOptions:"
|
||||
opt.on '-d', '--dryrun', "Don't change anything; preform dry run"
|
||||
opt.on '-D', '--debug', "Show trace on nix errors"
|
||||
opt.on '-f', '--flake URI', "Change target flake to URI"
|
||||
opt.on '-h', '--help', "Display this help, or help for a specific command"
|
||||
opt.on(*%w{-i -A -q -e -p}, "Forward to nix-env") { sh ["nix-env", *ARGV]; exit }
|
||||
end
|
||||
opts.order!(args, into: @@opts)
|
||||
if @@opts[:flake] and @@opts[:flake].include? "#"
|
||||
@@opts[:flake], @@opts[:host] = @@opts[:flake].split '#'
|
||||
end
|
||||
if not @@opts[:flake] or @@opts[:flake].empty?
|
||||
@@opts[:flake] = File.expand_path('../', File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
begin
|
||||
args.unshift("help") if @@opts[:help]
|
||||
if args.length == 0
|
||||
puts "Error: No command specified!"
|
||||
puts
|
||||
raise UsageError
|
||||
else
|
||||
call args.first, args.drop(1)
|
||||
end
|
||||
rescue UsageError
|
||||
puts opts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Hey.run ARGV.dup
|
72
bin/mov2gif
72
bin/mov2gif
|
@ -1,72 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -i bash -p ffmpeg gifsicle
|
||||
|
||||
# Uses ffmpeg to convert a video file to a gif file. Optimizes the final result
|
||||
# with gifsicle.
|
||||
#
|
||||
# Requires: ffmpeg gifsicle
|
||||
#
|
||||
# Example:
|
||||
# mov2gif some-vid.mp4 output.gif
|
||||
# mov2gif -f 10 -s 00:00:10 -t 00:00:05 some-vid.mp4 output.gif
|
||||
|
||||
set -e
|
||||
PALETTE="/tmp/palette.png"
|
||||
|
||||
usage() {
|
||||
cat <<EOL
|
||||
Usage: ${0##*/} [-fsSth] SOURCE_FILE [destfile]
|
||||
|
||||
-f [FPS] set frames per second
|
||||
-s [hh:mm:ss] set starting time (like -ss in ffmpeg)
|
||||
-S [W:H] set width/height (either can be -1 for auto)
|
||||
-t [hh:mm:ss] set the duration to capture (like -t in ffmpeg)
|
||||
-h this help
|
||||
EOL
|
||||
}
|
||||
|
||||
cleanup() { rm -f "$PALETTE"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
#
|
||||
fps=30
|
||||
while getopts hf:s:t:S: opt; do
|
||||
case $opt in
|
||||
f) fps="$OPTARG" ;;
|
||||
s) start="-ss $OPTARG" ;;
|
||||
S) scale=",scale=$OPTARG:flags=lanczos" ;;
|
||||
t) duration="-t $OPTARG" ;;
|
||||
h) usage
|
||||
exit
|
||||
;;
|
||||
:) >&2 echo "$OPTARG requires an argument"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
*) >&2 echo "Not a valid arg: $opt"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#
|
||||
if (($# == 0)); then
|
||||
>&2 echo "No movie file specified"
|
||||
exit
|
||||
elif [[ ! -f $1 ]]; then
|
||||
>&2 echo "$1 does not exist"
|
||||
exit
|
||||
fi
|
||||
|
||||
src="$1"
|
||||
dest="${2:-${src%.*}.gif}"
|
||||
flags="fps=${fps}$scale"
|
||||
|
||||
# stats_mode=full favors motion, causing the resulting palette to better
|
||||
# accomodate fades and transitions.
|
||||
ffmpeg -v warning $start $duration -i "file:$src" -vf "$flags,palettegen=stats_mode=full" -y "$PALETTE"
|
||||
ffmpeg -v warning $start $duration -i "file:$src" -i "$PALETTE" -lavfi "$flags [x]; [x][1:v] paletteuse" -y "$dest"
|
||||
|
||||
gifsicle -O3 "$dest" -o "$dest"
|
21
bin/myip
21
bin/myip
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env zsh
|
||||
# Echos your local or WAN IP
|
||||
|
||||
if [[ $1 == -w ]]; then
|
||||
wan=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ -n $wan ]]; then
|
||||
dig +short myip.opendns.com @resolver1.opendns.com
|
||||
else
|
||||
IF=$(netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}')
|
||||
if command -v ifconfig >/dev/null; then
|
||||
ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'
|
||||
elif command -v ip >/dev/null; then
|
||||
ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'
|
||||
else
|
||||
>&2 echo "No easy way to grab your IP"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
86
bin/optimimg
86
bin/optimimg
|
@ -1,86 +0,0 @@
|
|||
#!/usr/bin/env zsh
|
||||
|
||||
# Optimize image files (losslessly by default)
|
||||
#
|
||||
# Examples:
|
||||
# imgoptim image.jpg image.png image.gif
|
||||
# imgoptim directory_of_images/
|
||||
# imgoptim directory_of_images/*.png
|
||||
#
|
||||
# Requires:
|
||||
# PNGs: optipng, pngquant (lossy)
|
||||
# JPGs: jpegtran, jpegoptim (lossy)
|
||||
# GIFs: gifsicle
|
||||
#
|
||||
# Packages (same name on homebrew & arch linux)
|
||||
# optipng [pngquant] libjpeg-turbo [jpegoptim] gifsicle
|
||||
|
||||
set -e
|
||||
unset CDPATH
|
||||
|
||||
_usage() {
|
||||
cat <<EOL
|
||||
Usage: ${0:A:t} [-lh] IMAGE [IMAGE2 [IMAGE3 [...]]]
|
||||
|
||||
-l enable lossy compression
|
||||
-h this help
|
||||
EOL
|
||||
}
|
||||
|
||||
_filesize() {
|
||||
case $OSTYPE in
|
||||
darwin*) stat -c%s "$1" ;;
|
||||
*) stat --printf="%s" "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
#
|
||||
while getopts hl opt; do
|
||||
case $opt in
|
||||
h) _usage; exit;;
|
||||
l) lossy=1;;
|
||||
:) >&2 echo "$OPTARG requires an argument"; _usage; exit 1;;
|
||||
*) >&2 echo "Not a valid arg: $opt"; _usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
cmds=( optipng jpegtran gifsicle )
|
||||
[[ -n $lossy ]] && cmds=( $cmds pngquant jpegoptim )
|
||||
for cmd in ${cmds[@]}; do
|
||||
if ! command -v $cmd >/dev/null; then
|
||||
>&2 echo "$cmd isn't installed"
|
||||
error=1
|
||||
fi
|
||||
done
|
||||
if [[ -n $error ]]; then
|
||||
>&2 echo "There were errors, aborting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for file in $@; do
|
||||
if [[ -d $file ]]; then
|
||||
imgoptim $file/*
|
||||
elif [[ -f $file ]]; then
|
||||
pre_size=$(_filesize "$file")
|
||||
case ${file##*.} in
|
||||
png)
|
||||
[[ -n $lossy ]] && pngquant $file
|
||||
optipng -nc -nb -o7 $file
|
||||
;;
|
||||
gif)
|
||||
gifsicle --batch --optimize=3 "$file"
|
||||
;;
|
||||
jpg|jpeg)
|
||||
[[ -n $lossy ]] && jpegoptim --max=90 "$file"
|
||||
jpegtran -copy none -optimize -progressive -outfile "$file" "$file"
|
||||
;;
|
||||
*)
|
||||
printf "Unrecognized file '$file': ignored"
|
||||
;;
|
||||
esac
|
||||
post_size=$(_filesize "$file")
|
||||
perc=$(echo "((${pre_size} - ${post_size}) / ${pre_size}) * 100" | bc -l)
|
||||
printf "* %s: %d => %d (%.2f%% reduction)\n" "$file" "${pre_size}" "${post_size}" "$perc"
|
||||
fi
|
||||
done
|
36
bin/optimpdf
36
bin/optimpdf
|
@ -1,36 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Compress pdf files using ghostscript.
|
||||
#
|
||||
# Defaults to 72 dpi.
|
||||
#
|
||||
# Usage:
|
||||
# pdfoptim SRC [TARGET] [DPI]
|
||||
#
|
||||
# Requires: ghostscript (gs)
|
||||
|
||||
optimize() {
|
||||
# Adapted from Alfred Klomp's shrinkpdf script
|
||||
# <http://alfredklomp.com/programming/shrinkpdf/>
|
||||
gs -q -dNOPAUSE -dBATCH -dSAFER \
|
||||
-sDEVICE=pdfwrite \
|
||||
-dPDFSETTINGS=/screen \
|
||||
-dCompatibilityLevel=1.3 \
|
||||
-dEmbedAllFonts=true \
|
||||
-dSubsetFonts=true \
|
||||
-dAutoRotatePages=/None \
|
||||
-dMonoImageResolution=$3 \
|
||||
-dMonoImageDownsampleType=/Bicubic \
|
||||
-dGrayImageResolution=$3 \
|
||||
-dGrayImageDownsampleType=/Bicubic \
|
||||
-dColorImageResolution=$3 \
|
||||
-dColorImageDownsampleType=/Bicubic \
|
||||
-sOutputFile="$2" \
|
||||
"$1"
|
||||
}
|
||||
|
||||
src="$1"
|
||||
dest="${2:--}"
|
||||
dpi="${3:-72}"
|
||||
|
||||
optimize "$src" "$dest" "$dpi" || exit $?
|
|
@ -1,5 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
rofi -show drun \
|
||||
-modi drun,run \
|
||||
-show-icons \
|
||||
-theme theme/appmenu.rasi
|
|
@ -1,137 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -p ruby_2_7 rubyPackages_2_7.sqlite3 -i "ruby -S" --quiet
|
||||
|
||||
# Open your browser bookmarks or history in your default browser. Currently
|
||||
# works with Firefox, Brave, and qutebrowser.
|
||||
|
||||
require 'shellwords'
|
||||
require 'sqlite3'
|
||||
require 'json'
|
||||
require 'fileutils'
|
||||
require 'cgi'
|
||||
|
||||
def rofi items, *args
|
||||
cmd = [*%w{rofi -dmenu -theme theme/bookmarkmenu.rasi -markup-rows -multi-select -p browser -i}, *args]
|
||||
IO.popen(cmd.compact.shelljoin, "r+") do |pipe|
|
||||
pipe.puts items.keys.join "\n"
|
||||
pipe.close_write
|
||||
(pipe.gets || "").split "\n"
|
||||
end
|
||||
end
|
||||
|
||||
def db file, command
|
||||
copy = "/tmp/browsermenu-db-#{File.basename(file)}"
|
||||
begin
|
||||
# Copy the sqlite database because history/bookmark info is usually small
|
||||
# and may be locked by an open browser.
|
||||
unless File.exists? copy
|
||||
FileUtils.cp file, copy
|
||||
FileUtils.chmod 0400, copy, verbose: true
|
||||
end
|
||||
results = []
|
||||
db = SQLite3::Database.open copy
|
||||
db.execute(command).each { |r| results.push r }
|
||||
results
|
||||
ensure
|
||||
File.delete copy
|
||||
end
|
||||
end
|
||||
|
||||
def walk_json children
|
||||
result = []
|
||||
for c in children
|
||||
if c['children']
|
||||
result += walk_json c['children']
|
||||
else
|
||||
result.push [ c['name'], c['url'] ]
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def get_bookmarks browser
|
||||
bookmarks = []
|
||||
case browser
|
||||
when :firefox
|
||||
# In my nixos dotfiles I hardcode the default profile to $USER.profile,
|
||||
# which makes this lookup easier, but means this script won't work on any
|
||||
# other system.
|
||||
user = ENV['USER']
|
||||
["#{ENV['HOME']}/.mozilla/firefox/#{user}.default",
|
||||
"#{ENV['XDG_CONFIG_HOME']}/firefox/.mozilla/firefox/#{user}.default",
|
||||
"#{ENV['XDG_DATA_HOME']}/mozilla/firefox/#{user}.default"].each do |dir|
|
||||
if Dir.exists? dir
|
||||
db "#{dir}/places.sqlite",
|
||||
["SELECT DISTINCT mb.title, mp.url FROM moz_bookmarks mb",
|
||||
"INNER JOIN moz_places mp ON mp.id = mb.fk",
|
||||
"WHERE mb.type = 1 AND mb.title IS NOT NULL",
|
||||
"ORDER BY mp.frecency DESC",
|
||||
"LIMIT 200"].join(' ')
|
||||
end
|
||||
end
|
||||
when :brave
|
||||
f = File.read "#{ENV['XDG_CONFIG_HOME']}/BraveSoftware/Brave-Browser/Default/Bookmarks"
|
||||
data = JSON.parse f
|
||||
walk_json data["roots"]["bookmark_bar"]["children"]
|
||||
when :qutebrowser
|
||||
bookmarks = File.readlines "#{ENV['XDG_CONFIG_HOME']}/qutebrowser/bookmarks/urls"
|
||||
bookmarks.map { |s| s.strip.split(' ', 2).reverse }
|
||||
end
|
||||
end
|
||||
|
||||
def get_history browser
|
||||
case browser
|
||||
when :firefox
|
||||
# In my nixos dotfiles I hardcode the default profile to $USER.profile,
|
||||
# which makes this lookup easier, but means this script won't work on any
|
||||
# other system.
|
||||
user = ENV['USER']
|
||||
["#{ENV['HOME']}/.mozilla/firefox/#{user}.default",
|
||||
"#{ENV['XDG_CONFIG_HOME']}/firefox/.mozilla/firefox/#{user}.default",
|
||||
"#{ENV['XDG_DATA_HOME']}/mozilla/firefox/#{user}.default"].each do |dir|
|
||||
if Dir.exists? dir
|
||||
return db "#{dir}/places.sqlite",
|
||||
["SELECT title, url",
|
||||
"FROM moz_places",
|
||||
"WHERE title<>''",
|
||||
"ORDER BY last_visit_date DESC"].join(' ')
|
||||
end
|
||||
end
|
||||
return []
|
||||
when :brave
|
||||
db "#{ENV['XDG_CONFIG_HOME']}/BraveSoftware/Brave-Browser/Default/History",
|
||||
"SELECT title, url FROM urls GROUP BY url ORDER BY last_visit_time DESC LIMIT 200"
|
||||
when :qutebrowser
|
||||
db "#{ENV['XDG_DATA_HOME']}/qutebrowser/history.sqlite",
|
||||
["SELECT title, url FROM History",
|
||||
"WHERE title != ''",
|
||||
"GROUP BY url",
|
||||
"ORDER BY atime DESC"].join(' ')
|
||||
end
|
||||
end
|
||||
|
||||
def list urls
|
||||
items = urls.map do |x|
|
||||
x.map! { |x| CGI.escapeHTML x }
|
||||
[x[0].empty? ?
|
||||
"<b>#{x[1]}</b>" :
|
||||
"<b>#{x[0]}</b> <span size=\"x-small\">#{x[1]}</span>",
|
||||
x[1]]
|
||||
end.to_h
|
||||
selected = rofi items
|
||||
selected.map { |key| items[key] }
|
||||
end
|
||||
|
||||
type, browser = *ARGV
|
||||
browser = (browser || ENV['BROWSER']).to_sym
|
||||
urls = if type == 'history'
|
||||
get_history browser
|
||||
else
|
||||
get_bookmarks browser
|
||||
end
|
||||
urls = list urls
|
||||
if urls.empty?
|
||||
puts "No URL selected. Aborting..."
|
||||
exit 1
|
||||
end
|
||||
Process.detach fork { exec ENV['BROWSER'], *urls }
|
260
bin/rofi/bwmenu
260
bin/rofi/bwmenu
|
@ -1,260 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -p ruby_2_7 -i "ruby -S"
|
||||
|
||||
# A rofi client for vaultwarden. Similar to passmenu, but uses rofi. (Badly)
|
||||
# written in ruby because data persistence and frontend logic would be a pain to
|
||||
# write in bash or zsh. I'll refactor this later perhaps. Maybe.
|
||||
|
||||
require 'shellwords'
|
||||
require 'json'
|
||||
require 'optparse'
|
||||
require 'uri'
|
||||
require 'base64'
|
||||
require 'fileutils'
|
||||
|
||||
PersistentData = Struct.new(:path, :ttl, :pid, :data) do
|
||||
DATADIR = "#{ENV['XDG_DATA_HOME']}/bwmenu"
|
||||
|
||||
def self.load name, ttl: nil
|
||||
path = "#{DATADIR}/#{name}"
|
||||
data = JSON::load(Base64.decode64(File.read(path))) if File.exists?(path)
|
||||
d = PersistentData.new *(data || {}).values
|
||||
d.path = path
|
||||
d.ttl = ttl
|
||||
d
|
||||
end
|
||||
|
||||
def expire
|
||||
File.delete(self.path) if File.exists?(self.path)
|
||||
end
|
||||
|
||||
def save data = nil, onfinish = nil
|
||||
self.data = data if data
|
||||
FileUtils.mkdir_p DATADIR unless File.directory?(DATADIR)
|
||||
File.open(self.path, 'w') do |f|
|
||||
f.chmod 0600
|
||||
f.write Base64.encode64(self.to_h.to_json)
|
||||
end
|
||||
if self.pid and system("ps -f p #{self.pid}")
|
||||
Process.kill self.pid
|
||||
end
|
||||
if self.ttl
|
||||
self.pid = fork do
|
||||
Signal.trap('TERM') { throw :terminate }
|
||||
catch :terminate do
|
||||
sleep self.ttl
|
||||
end
|
||||
onfinish.call(self, data) if onfinish.respond_to? :call
|
||||
self.expire
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module BW
|
||||
extend self
|
||||
|
||||
EXE = {}
|
||||
def self.bin exe
|
||||
EXE[exe] = `which #{exe} 2>/dev/null`.rstrip unless EXE[exe]
|
||||
raise "Couldn't find #{exe} in PATH" if EXE[exe].empty?
|
||||
EXE[exe]
|
||||
end
|
||||
|
||||
def self.sh *args, input: nil, sudo: false, nooutput: false
|
||||
exe, *args = args.flatten.compact.map(&:to_s)
|
||||
bin exe
|
||||
cmd = [sudo ? "sudo" : nil, exe, *args.shelljoin].compact.join(' ')
|
||||
$stderr.puts "$ #{cmd}"
|
||||
if input
|
||||
IO.popen(cmd, "r+") do |pipe|
|
||||
pipe.puts input
|
||||
pipe.close_write
|
||||
(pipe.gets || "").rstrip unless nooutput
|
||||
end
|
||||
else
|
||||
(`#{cmd}` || "").rstrip
|
||||
end
|
||||
end
|
||||
|
||||
def self.rofi items, *args
|
||||
input = items.keys.join("\n") if items
|
||||
result = sh(['rofi', '-dmenu', '-markup-rows',
|
||||
'-theme', 'theme/passmenu.rasi',
|
||||
*args],
|
||||
input: input)
|
||||
if items
|
||||
items[result]
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
def self.notify message, title: nil, urgency: "normal"
|
||||
sh 'notify-send', '-u', urgency, '-a', "Vaultwarden", *[title, message].compact
|
||||
end
|
||||
|
||||
def self.error message
|
||||
$stderr.puts message
|
||||
notify message, urgency: 'low'
|
||||
exit 1
|
||||
end
|
||||
|
||||
def self.bw *args
|
||||
sh [:bw, '--session', @@session_id, *args]
|
||||
end
|
||||
|
||||
def self.xclip *args, **opts
|
||||
sh :xclip, '-selection', 'clipboard', *args, **opts
|
||||
end
|
||||
|
||||
@@session = nil
|
||||
@@session_id = nil
|
||||
def self.run argv
|
||||
opts = {}
|
||||
OptionParser.new do |opt|
|
||||
opt.banner = "Usage: bwmenu [options] [URL]"
|
||||
opt.on '--autolock TTL', "How long to keep the vault open"
|
||||
opt.on '--autoclear TTL' "How long to keep secrets in the clipboard"
|
||||
opt.on '--debug', "Be more verbose"
|
||||
opt.on '-f', '--field FIELD', "Extract specific field from selected entry; accepts 'whole' for whole entry"
|
||||
opt.on '-o', '--output', "Write output to stdout rather than the clipboard"
|
||||
opt.on '--select', "Select first entry"
|
||||
opt.on '--select-if-only', "Select first entry if only entry"
|
||||
opt.on '--default ID', "Highlight item with ID by default"
|
||||
opt.on '-r', "Resume where you last left off"
|
||||
end.parse! argv, into: opts
|
||||
|
||||
clipboard_ttl = opts[:autoclear] || 20
|
||||
vault_ttl = opts[:autolock] || 900
|
||||
|
||||
@@session = PersistentData.load :session, ttl: vault_ttl
|
||||
if @@session.data
|
||||
sid, data = @@session.data
|
||||
@@session_id = sid
|
||||
else
|
||||
pass = rofi nil, %w{-p Master\ Password -password -lines 0}
|
||||
error "No password given. Aborting..." if pass.empty?
|
||||
sid = sh [:bw, :unlock, '--raw', pass]
|
||||
error "Failed to unlock vault. Aborting..." unless $?.success?
|
||||
@@session_id = sid
|
||||
data = JSON.parse(bw(:list, :items))
|
||||
@@session.save [sid, data]
|
||||
end
|
||||
raise "No session ID" unless @@session_id
|
||||
|
||||
last = PersistentData.load :last_id
|
||||
last_id, last_field = last.data if last
|
||||
if opts[:r] and last_id.data
|
||||
selected = data.find { |u| u['id'] == last_id }
|
||||
else
|
||||
select_type = opts[:"select-if-only"] ? :if_only : opts[:select]
|
||||
selected = list_items data, argv.first,
|
||||
default: opts[:default],
|
||||
select: select_type
|
||||
end
|
||||
|
||||
begin
|
||||
error "Nothing selected. Aborting..." if selected.empty?
|
||||
last_id = selected['id']
|
||||
item = show_item selected, field: opts[:field]
|
||||
if not item
|
||||
error "Nothing selected. Aborting..." if selected.empty?
|
||||
elsif item.respond_to? :call
|
||||
item.call
|
||||
elsif opts[:output]
|
||||
puts item.rstrip
|
||||
else
|
||||
notify "Copied to clipboard for #{clipboard_ttl} seconds"
|
||||
xclip '-in', input: item.rstrip, nooutput: true
|
||||
clipboard = PersistentData.load :clipboard, ttl: clipboard_ttl
|
||||
clipboard.save(
|
||||
item.rstrip,
|
||||
lambda { |_, data| xclip('-in', '/dev/null') if item.rstrip == xclip('-out') }
|
||||
)
|
||||
end
|
||||
ensure
|
||||
last.save [ last_id, last_field ]
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
def list_items data, query = nil, default: nil, select: false
|
||||
rofiData = {}
|
||||
rofiData["Sync Vault"] = lambda { notify "Sync vault", bw(:sync) },
|
||||
rofiData["Open Vault in Browser"] = lambda { sh ENV['BROWSER'], bw(:config, :server) }
|
||||
data = data.map do |i|
|
||||
default_id = i['id'] if i['id'] == default
|
||||
icon = ["", "", "", ""][i['type'] - 1]
|
||||
case i['type']
|
||||
when 1 # logins
|
||||
urls = (i['login']['uris'] || []).filter_map do |u|
|
||||
return unless u['uri']
|
||||
uri = URI(u['uri'])
|
||||
not i['name'].include?((uri.hostname || uri.path).downcase) and
|
||||
uri.hostname || uri.path
|
||||
end
|
||||
subtitle = urls.join ", " if i['type'] == 1
|
||||
subtitle = " <span size=\"x-small\">(#{subtitle})</span>" unless urls.empty?
|
||||
when 2 # secure notes
|
||||
when 3 # cards
|
||||
subtitle = " <span size=\"x-small\">(#{i['card']['brand'].downcase})</span>"
|
||||
when 4 # identities
|
||||
end
|
||||
["<span font_desc=\"Fira Code\" font_weight=\"bold\">#{icon} </span> <b>#{i['name']}</b>#{subtitle}", i]
|
||||
end
|
||||
case select
|
||||
when :if_only
|
||||
return data[0][1] if data.length == 1
|
||||
when true
|
||||
return data[0][1]
|
||||
end
|
||||
rofi rofiData.merge(data.to_h), '-p', 'Vaultwarden', '-filter', (query || "")
|
||||
end
|
||||
|
||||
def show_item item, field: nil
|
||||
return item.to_json if field == 'whole'
|
||||
preamble = {}
|
||||
data = {}
|
||||
case item['type']
|
||||
when 1 # logins
|
||||
url = item['login']['uris'][0]['uri']
|
||||
preamble[" Launch #{url}"] = lambda { sh ENV['BROWSER'], url }
|
||||
data['Username'] = item['login']['username']
|
||||
data['Password'] = item['login']['password']
|
||||
data['TOTP'] = bw :get, :totp, url if item['login']['totp']
|
||||
return (data[field.capitalize] || item[field]) if field
|
||||
when 2 # secure notes
|
||||
data['Notes'] = item['notes']
|
||||
return item[field] if field
|
||||
when 3 # cards
|
||||
cardInfo = item['card']
|
||||
data['Card Type'] = cardInfo['brand']
|
||||
data['Card Name'] = cardInfo['cardholderName']
|
||||
data['Card Number'] = cardInfo['number']
|
||||
data['Expiry Date'] = "#{cardInfo['expMonth']}/#{cardInfo['expYear']}"
|
||||
data['Security Code'] = cardInfo['code']
|
||||
return cardInfo[field] if field
|
||||
when 4 # identities
|
||||
item['identity'].each { |k,v| data[k] = v if v }
|
||||
return item['identity'][field] if field
|
||||
end
|
||||
(item['fields'] || []).each do |field|
|
||||
data[field['name']] = field['value']
|
||||
end
|
||||
maxLength = data.keys.map(&:length).max + 5
|
||||
rofiData = {}
|
||||
preamble.merge(data).each do |label, value|
|
||||
if value.kind_of? String
|
||||
valueLabel = value
|
||||
valueLabel = value.gsub /./, '*' if label == 'Password'
|
||||
rofiData["<span font_desc=\"Fira Code\" font_weight=\"bold\">%-#{maxLength}s</span> %s" % [label, valueLabel]] = value
|
||||
else
|
||||
rofiData[label] = value
|
||||
end
|
||||
end
|
||||
rofi rofiData, '-p', item['name']
|
||||
end
|
||||
end
|
||||
|
||||
BW.run ARGV.dup
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
cd $HOME
|
||||
DIR="$(fd -L -d 4 --type d . | rofi -dmenu -i -p "~/" -theme theme/filemenu.rasi)"
|
||||
if [ -d "$DIR" ]; then
|
||||
cd "$DIR"
|
||||
if [[ $1 == "-x" ]]; then
|
||||
scratch
|
||||
else
|
||||
xst
|
||||
fi
|
||||
fi
|
|
@ -1,68 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Prompts for a pass entry, then for a specific field. Similar to passmenu, but
|
||||
# uses rofi, and can resume from a previous session.
|
||||
#
|
||||
# Example: passmenu [RESUME]
|
||||
|
||||
ROFI_CMD='rofi -dmenu -theme theme/passmenu.rasi'
|
||||
MSG_CMD='notify-send'
|
||||
set -e
|
||||
shopt -s nullglob globstar
|
||||
|
||||
for prog in xclip pass; do
|
||||
if ! command -v "$prog" >/dev/null; then
|
||||
>&2 echo "$prog not installed, aborting"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $1 == -r ]]; then
|
||||
resume=1; shift
|
||||
fi
|
||||
|
||||
url=
|
||||
# Get qutebrowser's current url
|
||||
win=$(xdotool getactivewindow)
|
||||
if [[ -n $win ]]; then
|
||||
winname=$(xdotool getwindowname $win)
|
||||
if [[ $winname =~ " - Mozilla Firefox$" ]]; then
|
||||
url=${winname% - Mozilla*}
|
||||
url=${url##* - }
|
||||
while (( ${#url//[^.]/} > 1 )); do
|
||||
url=${url#*.}
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
LAST_ENTRY_FILE=/tmp/_upm
|
||||
if [[ -n $resume && -f $LAST_ENTRY_FILE ]]; then
|
||||
entry="$(<$LAST_ENTRY_FILE)"
|
||||
else
|
||||
prefix=${PASSWORD_STORE_DIR-~/.password-store}
|
||||
password_files=( "$prefix"/**/*.gpg )
|
||||
password_files=( "${password_files[@]#"$prefix"/}" )
|
||||
password_files=( "${password_files[@]%.gpg}" )
|
||||
entry=$(printf "%s\n" "${password_files[@]}" | $ROFI_CMD -p "..." -filter "$url")
|
||||
fi
|
||||
|
||||
if [[ -z $entry ]]; then
|
||||
$MSG_CMD "Error!" "Failed to select $entry"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$entry" >/tmp/_upm
|
||||
secrets="$(pass show "$entry")"
|
||||
if [[ -n $secrets ]]; then
|
||||
fields=$(awk -F': ' 'NR>1 && !/^otpauth:/ {print $1}' <<<"$secrets")
|
||||
field=$(printf "password\n%s\notp\n" "${fields[@]}" | $ROFI_CMD -p "$entry")
|
||||
case $field in
|
||||
password) pass -c "$entry" ;;
|
||||
otp) printf "%s" "$(pass otp -c "$entry")" ;;
|
||||
*) printf "%s" "$(awk -v "key=$field:" '$1 == key {print $2}' <<<"$secrets")" | xclip -selection clipboard -in ;;
|
||||
esac
|
||||
$MSG_CMD "Success!" "Copied <b>$entry/$field</b> to clipboard for 45s"
|
||||
else
|
||||
$MSG_CMD "Error!" "Failed to retrieve $entry"
|
||||
exit 2
|
||||
fi
|
|
@ -1,31 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
rofi_command="rofi -theme theme/powermenu.rasi"
|
||||
|
||||
### Options ###
|
||||
power_off="\tShutdown"
|
||||
reboot="\tReboot"
|
||||
lock="\tLock"
|
||||
suspend="鈴\tSleep"
|
||||
log_out="\tLogout"
|
||||
# Variable passed to rofi
|
||||
options="$power_off\n$reboot\n$lock\n$suspend\n$log_out"
|
||||
|
||||
case "$(echo -e "$options" | $rofi_command -dmenu -selected-row 2)" in
|
||||
$power_off)
|
||||
systemctl poweroff
|
||||
;;
|
||||
$reboot)
|
||||
systemctl reboot
|
||||
;;
|
||||
$lock)
|
||||
zzz
|
||||
;;
|
||||
$suspend)
|
||||
dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause
|
||||
systemctl suspend
|
||||
;;
|
||||
$log_out)
|
||||
bspc quit
|
||||
;;
|
||||
esac
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
rofi -show window \
|
||||
-show-icons \
|
||||
-theme theme/windowmenu.rasi
|
26
bin/scratch
26
bin/scratch
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Toggle a scratch terminal window. A scratch terminal is a disposable terminal
|
||||
# for one-off, quick commands that don't warrant a dedicated terminal.
|
||||
|
||||
SCRID=scratch
|
||||
CMD=${1:-'tmux new-session -A -s scratch -n scratch'}
|
||||
focused=$(xdotool getactivewindow)
|
||||
scratch=$(xdotool search --onlyvisible --classname $SCRID)
|
||||
if [[ -n $scratch ]]; then
|
||||
if [[ $focused == $scratch ]]; then
|
||||
xdotool windowkill $scratch
|
||||
else
|
||||
xdotool windowactivate $scratch
|
||||
fi
|
||||
elif command -v urxvt >/dev/null; then
|
||||
urxvt -name $SCRID \
|
||||
-e $SHELL -c "$CMD"
|
||||
elif command -v xst >/dev/null; then
|
||||
xst -t $SCRID -n $SCRID -c $SCRID \
|
||||
-f "$(xrdb -query | grep 'scratch\.font' | cut -f2)" \
|
||||
-e $SHELL -c "$CMD"
|
||||
else
|
||||
>&2 echo "No shell to launch the scratch terminal with"
|
||||
exit 1
|
||||
fi
|
16
bin/scrcap
16
bin/scrcap
|
@ -1,16 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -i bash -p maim slop
|
||||
|
||||
# A script that takes a screenshot (prompts you for what region/window to
|
||||
# capture) and stores it in the clipboard.
|
||||
|
||||
tmp=$(mktemp)
|
||||
trap "rm -f '$tmp'" EXIT
|
||||
|
||||
# Delay for long enough that we can refocus the targeted window
|
||||
if maim --delay=${2:-1} -us >"$tmp"; then
|
||||
xclip -selection clipboard -t image/png "$tmp" &&
|
||||
notify-send "Screenshot saved" "Copied image to clipboard"
|
||||
else
|
||||
notify-send -u low "Aborted screenshot"
|
||||
fi
|
99
bin/scrrec
99
bin/scrrec
|
@ -1,99 +0,0 @@
|
|||
#!/usr/bin/env cached-nix-shell
|
||||
#! nix-shell -i bash -p ffmpeg slop
|
||||
|
||||
# Select a region and record it.
|
||||
#
|
||||
# If given a gif, it will record an mp4 and convert it afterwards using the
|
||||
# mov2gif script included in this repo (which is powered by gifsicle and
|
||||
# ffmpeg).
|
||||
#
|
||||
# Usage: scrrec somefile.mp4
|
||||
# scrrec another.gif
|
||||
|
||||
is_script=
|
||||
geom=
|
||||
delay=1
|
||||
count=3
|
||||
fps=30
|
||||
stopfile=/tmp/_stop
|
||||
while getopts c:d:f:g:ps opt; do
|
||||
case $opt in
|
||||
c) count=$OPTARG ;;
|
||||
d) delay="$OPTARG" ;;
|
||||
f) fps=$OPTARG ;;
|
||||
g) geom="$OPTARG" ;;
|
||||
p) picom= ;;
|
||||
s) is_script=1 ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
##
|
||||
select-region() {
|
||||
if [[ $geom ]]; then
|
||||
echo "${geom//[x+]/ }"
|
||||
else
|
||||
slop -nof "%w %h %x %y"
|
||||
fi
|
||||
}
|
||||
|
||||
countdown() {
|
||||
if (( count > 0 )); then
|
||||
for ((i=count;i>0;i--)); do
|
||||
if [[ $is_script ]]; then
|
||||
notify-send -u critical -t 1000 "Recording in $i"
|
||||
else
|
||||
echo "Recording in $i"
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
elif [[ $is_script ]]; then
|
||||
notify-send -u critical "Starting recording..."
|
||||
else
|
||||
echo "Started recording..."
|
||||
fi
|
||||
}
|
||||
|
||||
recording-start() {
|
||||
local ffmpeg_opts="-y -f x11grab -show_region 1 -ss $delay -s ${4}x${5} -i :0.0+${2},${3} -framerate ${fps}"
|
||||
local dest=${1:-./rec.mp4}
|
||||
local mp4dest=
|
||||
[[ $dest == *.gif ]] && mp4dest="${dest%.*}.mp4"
|
||||
countdown
|
||||
ffmpeg $ffmpeg_opts "${mp4dest:-$dest}" &
|
||||
pid=$!
|
||||
echo $pid >$stopfile
|
||||
wait $pid
|
||||
rm -f $stopfile
|
||||
if [[ -f "$mp4dest" ]]; then
|
||||
mov2gif "$mp4dest" "$dest" && rm -fv "$mp4dest"
|
||||
fi
|
||||
echo -n "$dest" | xclip -selection clipboard -in
|
||||
notify-send "Screencast successful" "Saved to $dest\nAnd copied to your clipboard!"
|
||||
}
|
||||
|
||||
|
||||
# If a recording session is already active, stop that one.
|
||||
if [[ -n "$is_script" && -f "$stopfile" ]]; then
|
||||
kill $(cat $stopfile)
|
||||
echo "Stopped previous recording"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
read -r W H X Y < <(select-region)
|
||||
[[ -z "$W$H$X$Y" ]] && exit 1
|
||||
|
||||
# picom with blur and/or transparencies cause unbearable flickering in
|
||||
# recordings, so temporarily disable it.
|
||||
picom=
|
||||
if systemctl is-enabled --user picom >/dev/null; then
|
||||
systemctl --user stop picom
|
||||
picom=1
|
||||
fi
|
||||
cleanup() { [[ $picom ]] && systemctl --user start picom; }
|
||||
trap cleanup EXIT
|
||||
|
||||
# Let 'er rip
|
||||
recording-start "$1" "$X" "$Y" "$W" "$H"
|
||||
|
||||
# vim:set ft=sh shiftwidth=2:
|
38
bin/since
38
bin/since
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env zsh
|
||||
set -e
|
||||
(( $# > 0 )) || exit
|
||||
|
||||
# Displays the time since $1 in a human readable format (e.g. 4h 25m 55s). If
|
||||
# given a file, the modified time is used. If $1 == "--", then this script acts
|
||||
# as a converter, converting $2 into human a readable format, e.g. since -- 72
|
||||
# #=> 1m 12s
|
||||
|
||||
# TODO: A help fallback
|
||||
# TODO: Options parsing?
|
||||
|
||||
# If given a file, give time since last modification
|
||||
(( $# == 1 )) && [[ -f $1 ]] && arg=reference || arg=date
|
||||
|
||||
if [[ $1 == -- ]]; then
|
||||
t="$2"
|
||||
else
|
||||
now=$(date +%s)
|
||||
then=$(date --$arg="$*" +%s)
|
||||
|
||||
t=$(( now - then ))
|
||||
fi
|
||||
|
||||
# Bash doesn't support floating point arithmetic like zsh does, so use bc to do
|
||||
# our arithmetic.
|
||||
zmodload zsh/mathfunc
|
||||
t=$(( abs(t) ))
|
||||
weeks=$(( t / 60 / 60 / 24 / 7 ))
|
||||
days=$(( t / 60 / 60 / 24 % 7 ))
|
||||
hours=$(( t / 60 / 60 % 24 ))
|
||||
minutes=$(( t / 60 % 60 ))
|
||||
seconds=$(( t % 60 ))
|
||||
(( weeks > 0 )) && echo -n "${weeks}w "
|
||||
(( days > 0 )) && echo -n "${days}d "
|
||||
(( hours > 0 )) && echo -n "${hours}h "
|
||||
(( minutes > 0 )) && echo -n "${minutes}m "
|
||||
echo -n "${seconds}s"
|
21
bin/spell
21
bin/spell
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Find the correct spelling of a word. Uses (and requires) fzf to select the
|
||||
# correct word. This output can be piped to something like dict to find
|
||||
# definitions/synonyms.
|
||||
#
|
||||
# Requires: aspell, fzf
|
||||
# Usage: spell mispeling
|
||||
# Example: dict $(spell mispeling)
|
||||
|
||||
result=$(echo "$@" | aspell -a | tail -n-2)
|
||||
if [[ "$result" == '*' ]]; then
|
||||
echo "$@"
|
||||
else
|
||||
words=$(echo "$result" | sed $'s/[:,] /\\\n/g' | tail -n +2)
|
||||
if (( $(wc -l <<< "$words") > 1 )) && command -v sk >/dev/null; then
|
||||
fzf <<< "$words"
|
||||
else
|
||||
echo "$words"
|
||||
fi
|
||||
fi
|
|
@ -1,6 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
open=open
|
||||
[[ $OSTYPE == linux* ]] && open=xdg-open
|
||||
|
||||
$open https://time.is/$1 2>/dev/null &
|
22
bin/zzz
22
bin/zzz
|
@ -1,22 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# If -f, then put computer to sleep.
|
||||
# Otherwise, lock screen and turn off monitor.
|
||||
|
||||
if [[ $1 == -h ]]; then
|
||||
bin=${0##*/}
|
||||
echo "Usage: $bin [-f]"
|
||||
echo
|
||||
echo " $bin # put display to sleep"
|
||||
echo " $bin -f # put computer to sleep"
|
||||
elif [[ $1 == -f ]]; then
|
||||
echo "Going to sleep..."
|
||||
systemctl suspend
|
||||
else
|
||||
echo "Shutting my eyes..."
|
||||
if command -v slock >/dev/null; then
|
||||
pgrep slock >/dev/null || slock &
|
||||
fi
|
||||
sleep 1
|
||||
xset dpms force off
|
||||
fi
|
28
box.nix
Normal file
28
box.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./common.nix
|
||||
./mossnet.nix
|
||||
];
|
||||
|
||||
users.extraUsers."anish".extraGroups = [ "jackaudio" ];
|
||||
|
||||
# services.xserver = {
|
||||
# enable = true;
|
||||
# displayManager.gdm.enable = true;
|
||||
# desktopManager.gnome3.enable = true;
|
||||
# };
|
||||
|
||||
# task whisperer broken
|
||||
#nixpkgs.config.allowBroken = true;
|
||||
|
||||
# virtual box
|
||||
virtualisation.virtualbox.host.enable = true;
|
||||
|
||||
# ErgoDox Firmware (doesn't compile)
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# qmk_firmware
|
||||
# ];
|
||||
}
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
# 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