initial commit

This commit is contained in:
Jakob Lechner 2025-07-17 00:45:59 +02:00
commit 3289e23566
22 changed files with 1037 additions and 0 deletions

1
.envrc Normal file
View file

@ -0,0 +1 @@
use flake

9
.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
# Nix
result*
.direnv
# automatically generated
.pre-commit-config.yaml
# mdBook
/book/*

2
book.toml Normal file
View file

@ -0,0 +1,2 @@
[book]
src = "docs"

2
docs/SUMMARY.md Normal file
View file

@ -0,0 +1,2 @@
# Weinturm Open Air Infrastructure

283
flake.lock generated Normal file
View file

@ -0,0 +1,283 @@
{
"nodes": {
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1752541678,
"narHash": "sha256-dyhGzkld6jPqnT/UfGV2oqe7tYn7hppAqFvF3GZTyXY=",
"owner": "nix-community",
"repo": "disko",
"rev": "2bf3421f7fed5c84d9392b62dcb9d76ef09796a7",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"fieldpoc": {
"inputs": {
"mitel-ommclient2": "mitel-ommclient2",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1711287766,
"narHash": "sha256-2roymGPfsQZC1Lg/i3iffBQ8c86DLEXmuoKQIlbOg5o=",
"ref": "refs/heads/main",
"rev": "f707f212378f9d8de103ac96abcd9d377a2605a8",
"revCount": 56,
"type": "git",
"url": "https://git.clerie.de/clerie/fieldpoc.git"
},
"original": {
"type": "git",
"url": "https://git.clerie.de/clerie/fieldpoc.git"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"nix-pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1752544374,
"narHash": "sha256-ReX0NG6nIAEtQQjLqeu1vUU2jjZuMlpymNtb4VQYeus=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "2e00ed310c218127e02ffcf28ddd4e0f669fde3e",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-25.05",
"repo": "home-manager",
"type": "github"
}
},
"impermanence": {
"locked": {
"lastModified": 1737831083,
"narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "impermanence",
"type": "github"
}
},
"krops": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1644957911,
"narHash": "sha256-ggie/j7pdBqzDs4W7OiPmhqH9IGbXAbJxGqBdVxA8jA=",
"owner": "Mic92",
"repo": "krops",
"rev": "86fb3d2ee94fd8306231853b323ed8804edf26ec",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "krops",
"type": "github"
}
},
"mitel-ommclient2": {
"inputs": {
"nixpkgs": [
"fieldpoc",
"nixpkgs"
]
},
"locked": {
"lastModified": 1687019250,
"narHash": "sha256-cN9ZuQ/1irnoYg013v1ZDn15MHcFXhxILGhRNDGd794=",
"ref": "refs/heads/main",
"rev": "a11629f543a8b43451cecc46600a78cbb6af015a",
"revCount": 70,
"type": "git",
"url": "https://git.clerie.de/clerie/mitel_ommclient2.git"
},
"original": {
"type": "git",
"url": "https://git.clerie.de/clerie/mitel_ommclient2.git"
}
},
"nix-pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1750779888,
"narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d",
"type": "github"
},
"original": {
"owner": "cachix",
"ref": "master",
"repo": "git-hooks.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1665732960,
"narHash": "sha256-WBZ+uSHKFyjvd0w4inbm0cNExYTn8lpYFcHEes8tmec=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4428e23312933a196724da2df7ab78eb5e67a88e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1752620740,
"narHash": "sha256-f3pO+9lg66mV7IMmmIqG4PL3223TYMlnlw+pnpelbss=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "32a4e87942101f1c9f9865e04dc3ddb175f5f32e",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"disko": "disko",
"fieldpoc": "fieldpoc",
"flake-utils": "flake-utils",
"home-manager": "home-manager",
"impermanence": "impermanence",
"krops": "krops",
"nix-pre-commit-hooks": "nix-pre-commit-hooks",
"nixpkgs": "nixpkgs_2",
"sops-nix": "sops-nix"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1752544651,
"narHash": "sha256-GllP7cmQu7zLZTs9z0J2gIL42IZHa9CBEXwBY9szT0U=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "2c8def626f54708a9c38a5861866660395bb3461",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

217
flake.nix Normal file
View file

@ -0,0 +1,217 @@
{
inputs = {
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
fieldpoc.url = "git+https://git.clerie.de/clerie/fieldpoc.git";
flake-utils.url = "github:numtide/flake-utils";
home-manager = {
url = "github:nix-community/home-manager/release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
impermanence.url = "github:nix-community/impermanence";
krops = {
url = "github:Mic92/krops";
inputs.flake-utils.follows = "flake-utils";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-pre-commit-hooks = {
url = "github:cachix/git-hooks.nix/master";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
flake-utils,
home-manager,
krops,
nix-pre-commit-hooks,
nixpkgs,
...
} @ inputs:
flake-utils.lib.eachDefaultSystem
(system: let
pkgs = import nixpkgs {inherit system;};
inherit (pkgs) lib;
in {
checks = {
pre-commit-check = nix-pre-commit-hooks.lib.${system}.run {
src = ./.;
hooks = {
alejandra.enable = true;
black.enable = true;
deadnix.enable = true;
markdownlint = {
enable = true;
settings.configuration = {
MD013.code_blocks = false; # Ignore line length in code blocks.
};
};
shellcheck.enable = true;
statix = {
enable = true;
settings.ignore = [".direnv"];
};
tflint.enable = true;
terraform-format.enable = true;
};
};
};
packages.docs = pkgs.stdenvNoCC.mkDerivation {
name = "infrastructure-documentation";
src = builtins.path {
name = "docs-src";
path = ./.;
filter = path: _type: let
relPath = lib.removePrefix (toString ./.) path;
in
lib.hasPrefix "/docs" relPath
|| lib.hasPrefix "/assets" relPath
|| relPath == "/book.toml";
};
nativeBuildInputs = with pkgs; [
mdbook
];
buildPhase = "mdbook build -d $out";
dontInstall = true;
};
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
alejandra
aws-vault
awscli2
black
jq
just
markdownlint-cli2
mdbook
opentofu
shellcheck
sops
ssh-to-age
(
writeShellScriptBin "repl" ''
exec nix repl --expr "
let flake = builtins.getFlake \"$(git rev-parse --show-toplevel)\";
in
flake // {
lib = flake.inputs.nixpkgs.lib;
pkgs = flake.inputs.nixpkgs.legacyPackages."\''${builtins.currentSystem}";
}
"
''
)
];
shellHook = ''
${self.checks.${system}.pre-commit-check.shellHook}
'';
};
apps =
lib.mapAttrs
(_name: program: {
type = "app";
program = toString program;
})
(flake-utils.lib.flattenTree {
deploy = lib.recurseIntoAttrs (lib.mapAttrs
(
hostname: machine: let
inherit (krops.packages.${system}) writeCommand;
inherit (krops) lib;
in
writeCommand "deploy-${hostname}" {
target =
lib.mkTarget "root@${machine.config.deployment.targetHost}"
// {
extraOptions = [
# force allocation of tty to allow aborting with ^C and to show build progress
"-t"
];
};
source = lib.evalSource (lib.singleton {
config.file = {
path = toString ./.;
useChecksum = true;
};
});
command = targetPath: ''
nixos-rebuild switch --flake ${targetPath}/config -L --keep-going
'';
force = true;
}
)
self.nixosConfigurations);
});
})
// {
overlays.default = import ./pkgs inputs;
nixosConfigurations = let
domain = "lan.weinturm-open-air.net";
in
nixpkgs.lib.mapAttrs
(hostname: {
system,
extraModules ? [],
targetHost ? "${hostname}.${domain}",
}:
nixpkgs.lib.nixosSystem {
inherit system;
modules =
[
(./hosts + "/${hostname}/configuration.nix")
./modules
{
_module.args = {inherit inputs domain;};
}
# deployment settings
({lib, ...}: {
options.deployment = {
targetHost = lib.mkOption {
type = lib.types.str;
readOnly = true;
internal = true;
};
};
config.deployment = {
inherit targetHost;
};
})
]
++ [
home-manager.nixosModules.home-manager
]
++ (with inputs; [
disko.nixosModules.disko
fieldpoc.nixosModules.default
impermanence.nixosModules.impermanence
sops-nix.nixosModules.sops
])
++ extraModules;
})
(import ./hosts inputs);
};
}

9
justfile Normal file
View file

@ -0,0 +1,9 @@
repl:
nix repl --expr "\
let \
flake = builtins.getFlake \"$(git rev-parse --show-toplevel)\"; in \
flake // (with flake; { \
lib = inputs.nixpkgs.lib; \
pkgs = inputs.nixpkgs.legacyPackages."\${builtins.currentSystem}".extend(import ./pkgs inputs); \
}) \
"

3
modules/cli-tools.nix Normal file
View file

@ -0,0 +1,3 @@
{
programs.tmux.enable = true;
}

19
modules/default.nix Normal file
View file

@ -0,0 +1,19 @@
{domain, ...}: {
options.weinturm = {
};
imports = [
./cli-tools.nix
./fish.nix
./impermanence.nix
./networking.nix
./nix.nix
./security.nix
./sshd.nix
./zram.nix
];
config = {
networking.domain = domain;
};
}

3
modules/fish.nix Normal file
View file

@ -0,0 +1,3 @@
{
programs.fish.enable = true;
}

49
modules/impermanence.nix Normal file
View file

@ -0,0 +1,49 @@
{
config,
lib,
...
}: {
options.weinturm = with lib; {
impermanence = {
enable = mkOption {
type = types.bool;
default = true;
description = "Whether to enable impermanence";
};
rootDevice = with types;
mkOption {
type = nullOr str;
default = null;
description = ''
The device which contains the btrfs root subvolume
'';
};
};
};
config = let
cfg = config.weinturm.impermanence;
in
lib.mkIf cfg.enable {
fileSystems."/persist".neededForBoot = true;
environment.persistence."/persist".directories = [
"/var/lib/nixos"
];
boot.initrd.postDeviceCommands = let
rootDevice =
if cfg.rootDevice == null
then ""
else cfg.rootDevice;
in
lib.mkAfter ''
mkdir /mnt
mount -t btrfs "${rootDevice}" /mnt
btrfs subvolume list -o /mnt/root | cut -f9 -d' ' | while read subvolume; do
btrfs subvolume delete "/mnt/$subvolume"
done
btrfs subvolume delete /mnt/root
btrfs subvolume snapshot /mnt/root-blank /mnt/root
'';
};
}

3
modules/networking.nix Normal file
View file

@ -0,0 +1,3 @@
{
networking.nftables.enable = true;
}

52
modules/nix.nix Normal file
View file

@ -0,0 +1,52 @@
{
lib,
pkgs,
inputs,
...
}: {
nix = {
package = pkgs.nixVersions.stable;
extraOptions = ''
experimental-features = nix-command flakes
'';
daemonCPUSchedPolicy = "idle";
daemonIOSchedClass = "idle";
daemonIOSchedPriority = 7;
nixPath = [
"nixpkgs=${inputs.nixpkgs}"
];
settings = {
trusted-users = ["@wheel"];
auto-optimise-store = true;
allowed-users = ["@wheel"];
log-lines = lib.mkDefault 25;
# Avoid disk full issues
max-free = lib.mkDefault (3000 * 1024 * 1024);
min-free = lib.mkDefault (512 * 1024 * 10);
download-buffer-size = lib.mkDefault (512 * 1024 * 1024);
};
gc = {
automatic = true;
options = "--delete-older-than 30d";
randomizedDelaySec = "60 min";
};
};
systemd.services.nix-daemon.serviceConfig.OOMScoreAdjust = 250;
nixpkgs.overlays = with inputs; [
self.overlays.default
];
environment.systemPackages = with pkgs; [
cached-nix-shell
git
];
}

18
modules/security.nix Normal file
View file

@ -0,0 +1,18 @@
{
boot = {
tmp.cleanOnBoot = true;
kernel.sysctl = {
"kernel.kptr_restrict" = 1;
"kernel.yama.ptrace_scope" = 1;
"kernel.kexec_load_disabled" = 1;
};
kernelParams = [
"lockdown=integrity"
];
};
security = {
polkit.enable = true;
sudo.wheelNeedsPassword = false;
};
}

67
modules/sshd.nix Normal file
View file

@ -0,0 +1,67 @@
{
lib,
config,
...
}: {
services.openssh = {
enable = true;
settings = {
KbdInteractiveAuthentication = false;
Ciphers = [
"aes256-gcm@openssh.com"
];
# Use key exchange algorithms recommended by `nixpkgs#ssh-audit`
KexAlgorithms = [
"curve25519-sha256"
"curve25519-sha256@libssh.org"
"diffie-hellman-group16-sha512"
"diffie-hellman-group18-sha512"
"sntrup761x25519-sha512@openssh.com"
];
PasswordAuthentication = false;
StreamLocalBindUnlink = true; # unbind gnupg sockets if they exists
UseDns = false;
X11Forwarding = false;
};
hostKeys =
if config.weinturm.impermanence.enable
then [
{
type = "ed25519";
path = "/persist/etc/ssh/ssh_host_ed25519_key";
}
]
else [
{
type = "ed25519";
path = "/etc/ssh/ssh_host_ed25519_key";
}
];
authorizedKeysFiles = lib.mkIf (!config.services.gitlab.enable) (lib.mkForce ["/etc/ssh/authorized_keys.d/%u"]);
};
networking.nftables.tables."nixos-fw".content = lib.mkOrder 20 ''
set ssh-ratelimit-v4 {
type ipv4_addr
timeout 60s
flags dynamic
}
set ssh-ratelimit-v6 {
type ipv6_addr
timeout 60s
flags dynamic
}
'';
# Implement connection rate limit
services.openssh.openFirewall = false;
networking.firewall.extraInputRules = lib.mkOrder 5 (
let
ports = builtins.concatStringsSep ", " (map builtins.toString config.services.openssh.ports);
in ''
tcp dport { ${ports} } update @ssh-ratelimit-v4 { ip saddr limit rate 1/second burst 10 packets } accept
tcp dport { ${ports} } update @ssh-ratelimit-v6 { ip6 saddr limit rate 1/second burst 10 packets } accept
''
);
}

25
modules/zram.nix Normal file
View file

@ -0,0 +1,25 @@
{
config,
lib,
...
}: let
cfg = config.weinturm.zram;
in {
options.weinturm = with lib; {
zram = {
enable = mkOption {
type = types.bool;
default = true;
description = "Whether to enable zram swap";
};
};
};
config = {
zramSwap = {
inherit (cfg) enable;
algorithm = "zstd";
memoryPercent = 60;
priority = 1;
};
};
}

4
pkgs/default.nix Normal file
View file

@ -0,0 +1,4 @@
inputs: _final: prev: let
inherit (prev) callPackage system;
in {
}

41
users/jalr/default.nix Normal file
View file

@ -0,0 +1,41 @@
{
config,
pkgs,
...
}: let
sshKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3l+Yixrsjhze20CSjvUK4Qj/BNqbTNitgk20vuzPej cardno:25_750_479"
];
in {
users.users.jalr = {
isNormalUser = true;
extraGroups = [
"adbusers"
"audio"
"dialout"
"libvirtd"
"lp"
"networkmanager"
"scanner"
"video"
"wheel"
"wireshark"
];
shell = pkgs.fish;
openssh.authorizedKeys.keys = sshKeys;
};
users.users.root.openssh.authorizedKeys.keys = sshKeys;
home-manager = {
useUserPackages = true;
useGlobalPkgs = true;
users.jalr = {...}: {
imports = [./modules];
config = {
home.stateVersion = config.system.stateVersion;
};
};
};
}

View file

@ -0,0 +1,12 @@
{pkgs, ...}: {
home.packages = with pkgs; [
cached-nix-shell
file
htop
inetutils
jq
lsof
ncdu
ripgrep
];
}

View file

@ -0,0 +1,9 @@
{...}: {
imports = [
./cli.nix
./fish.nix
./neovim.nix
];
programs.nix-index.enable = true;
}

200
users/jalr/modules/fish.nix Normal file
View file

@ -0,0 +1,200 @@
{pkgs, ...}: {
home.packages = with pkgs; [
fzf
];
programs.fish = {
enable = true;
plugins = [
{
name = "theme-agnoster";
src = pkgs.fetchFromGitHub {
owner = "oh-my-fish";
repo = "theme-agnoster";
rev = "c142e802983bd1b34b4d91efac2126fc5913126d";
sha256 = "0PLx626BWoBp/L6wgkB4o+53q8PymiEE/rTu2mfzHhg=";
fetchSubmodules = true;
};
}
{
name = "fzf";
src = pkgs.fetchFromGitHub {
owner = "jethrokuan";
repo = "fzf";
rev = "479fa67d7439b23095e01b64987ae79a91a4e283";
sha256 = "0k6l21j192hrhy95092dm8029p52aakvzis7jiw48wnbckyidi6v";
fetchSubmodules = true;
};
}
];
shellAliases = {
ls = "ls --color=auto";
crontab = "crontab -i";
};
shellAbbrs = {
lessr = "less -R";
jqc = "jq -C";
};
#interactiveShellInit = ''
# echo "programs.fish.interactiveShellInit"
#'';
shellInit = ''
# key bindings
bind \cr '__fzf_reverse_isearch'
# PATH
set -U fish_user_paths $HOME/.local/bin $HOME/.local/bin/pio
# pass
#set -x PASSWORD_STORE_ENABLE_EXTENSIONS true
set -x AWS_VAULT_BACKEND pass
set -x AWS_VAULT_PASS_PREFIX aws
complete -c pw --no-files -a '(__fish_pass_print_entries)'
# colors
set -x GCC_COLORS 'error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
abbr --add v vim
#alias cal='ncal -b -M'
alias myip='dig +short myip.opendns.com @resolver1.opendns.com'
function hm -d 'merge history and delete failed commands'
history --merge
if test -z "$fish_private_mode" && test -e "$__fish_user_data_dir/successful_commands" && test -e "$__fish_user_data_dir/failed_commands"
while read line;
if ! grep -qFx $line "$__fish_user_data_dir/successful_commands"
set hist_command (echo $line | base64 -d)
echo "deleting command: $hist_command"
echo "."
history delete --exact --case-sensitive $hist_command
end
end < "$__fish_user_data_dir/failed_commands"
echo -n > "$__fish_user_data_dir/successful_commands"
echo -n > "$__fish_user_data_dir/failed_commands"
end
end
hm
# fancy tools
if which eza > /dev/null 2>&1
alias l=eza
alias ll='eza -l --time-style=long-iso --git'
alias la='eza -la --time-style=long-iso --git'
alias tree='eza --tree'
alias llt='eza -s modified -l'
else
alias l=ls
alias ll='ls -l'
alias la='ls -la'
alias llt='ls -trl'
end
if which rg > /dev/null 2>&1
alias g=rg
complete -c g -w rg
else if which ag > /dev/null 2>&1
alias g=ag
complete -c g -w ag
else
alias g='grep --color=auto'
complete -c g -w grep
end
function jqless -d 'jq -C [args] | less -R'
jq -C $argv | less -R
end
# NixOS direnv
if which direnv > /dev/null
eval (direnv hook fish)
end
function __cut_commandline -d 'cut commandline and paste it later'
set -g commandline_buffer (commandline)
commandline ""
end
function __postexec --on-event fish_postexec
if test $status -ne 0
if test -z "$hist_cmd"
if test -z "$fish_private_mode"
echo $argv[1] | base64 >> "$__fish_user_data_dir/failed_commands"
end
end
else
if test -z "$fish_private_mode"
echo $argv[1] | base64 >> "$__fish_user_data_dir/successful_commands"
end
commandline $commandline_buffer
set -e commandline_buffer
end
end
function dirh-nocolor --description "Print the current directory history (the prev and next lists)"
set -l options h/help
argparse -n dirh --max-args=0 $options -- $argv
or return
if set -q _flag_help
__fish_print_help dirh
return 0
end
set -l dirc (count $dirprev)
if test $dirc -gt 0
set -l dirprev_rev $dirprev[-1..1]
# This can't be (seq $dirc -1 1) because of BSD.
set -l dirnum (seq 1 $dirc)
for i in $dirnum[-1..1]
printf '%s\n' $dirprev_rev[$i]
end
end
echo $PWD
set -l dirc (count $dirnext)
if test $dirc -gt 0
set -l dirnext_rev $dirnext[-1..1]
for i in (seq $dirc)
printf '%s\n' $dirnext_rev[$i]
end
end
end
function dirh-fzf -d 'directory history fuzzy finder'
builtin cd (dirh-nocolor | uniq | fzf)
end
bind \ed 'dirh-fzf'
'';
};
xdg.configFile."fish/completions/mycli.fish".text = ''
complete -e -c mycli
complete -c mycli -f -s h -l host -d "Host address of the database."
complete -c mycli -f -s P -l port -d "Port number to use for connection."
complete -c mycli -f -s u -l user -d "User name to connect to the database."
complete -c mycli -f -s S -l socket -d "The socket file to use for connection."
complete -c mycli -f -s p -l pass \
-l password -d "Password to connect to the database."
complete -c mycli -f -s V -l version -d "Output mycli's version."
complete -c mycli -f -s v -l verbose -d "Verbose output."
complete -c mycli -f -s d -l dsn -d "Use DSN configured into the [alias_dsn] section of myclirc file."
complete -c mycli -f -l list-dsn -d "list of DSN configured into the [alias_dsn] section of myclirc file."
complete -c mycli -f -s t -l table -d "Display batch output in table format."
complete -c mycli -f -l csv -d "Display batch output in CSV format."
complete -c mycli -f -l warn \
-l no-warn -d "Warn before running a destructive query."
complete -c mycli -f -s e -l execute -d "Execute command and quit."
complete -c mycli -f -s h -l host -r -a '(__fish_print_hostnames)'
complete -c mycli -f -s d -l dsn -r -a '(mycli --list-dsn)'
'';
}

View file

@ -0,0 +1,9 @@
{
home.sessionVariables = {
EDITOR = "nvim";
};
programs.neovim = {
enable = true;
vimAlias = true;
};
}