feat: add nix config to this repository

This used to live in the old pub-solar/os repository in the `momo/main`
branch. This commit changes that so this repository has all code from
terraform to nix.
pull/2/head
Benjamin Yule Bädorf 2024-02-25 17:41:25 +01:00
parent 0c07720ed8
commit 56ea689de6
Signed by: b12f
GPG Key ID: 729956E1124F8F26
146 changed files with 15416 additions and 2 deletions

13
.envrc Normal file
View File

@ -0,0 +1,13 @@
# reload when these files change
watch_file shell/* flake.nix
use flake || use nix
#watch_file flake.nix
#watch_file shell.nix
#
#{
# # shell gc root dir
# mkdir -p "$(direnv_layout_dir)"
#
# eval "$(nix print-dev-env --profile $(direnv_layout_dir)/flake-profile)"
#} || use nix

View File

@ -0,0 +1,50 @@
name: Flake checks
on: [pull_request]
env:
USER: ci
jobs:
Check:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://github.com/nixbuild/nix-quick-install-action@v26
with:
load_nixConfig: false
nix_conf: |
substituters = https://cache.nixos.org/ https://nix-community.cachix.org
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
keep-outputs = true
- name: Calculate flake.lock hash
id: flake-lock-hash
run: |
echo "hash=$(md5sum flake.lock | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Restore and cache Nix store
uses: https://github.com/nix-community/cache-nix-action@v4
id: nix-store-cache
with:
key: cache-${{ runner.os }}-nix-store-${{ steps.flake-lock-hash.outputs.hash }}
restore-keys: |
cache-${{ runner.os }}-nix-store-
gc-linux: true
gc-max-store-size-linux: 10000000000
purge-caches: true
purge-keys: cache-${{ runner.os }}-nix-store-
purge-created: true
purge-created-max-age: 42
# - name: Prepare cachix
# uses: https://github.com/cachix/cachix-action@v12
# with:
# name: pub-solar
# authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Run flake checks
run: |
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' flake check

15
.gitignore vendored
View File

@ -1,2 +1,13 @@
.terraform
*.plan
result
.direnv
doc/index.html
# Result of bud commands
vm
iso
doi
pkgs/_sources/.shake*
tags
/owners

342
flake.lock Normal file
View File

@ -0,0 +1,342 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": [
"nix-darwin"
],
"home-manager": [
"home-manager"
],
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1703433843,
"narHash": "sha256-nmtA4KqFboWxxoOAA6Y1okHbZh+HsXaMPFkYHsoDRDw=",
"owner": "ryantm",
"repo": "agenix",
"rev": "417caa847f9383e111d1397039c9d4337d024bf0",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"deploy-rs": {
"inputs": {
"flake-compat": [
"flake-compat"
],
"nixpkgs": [
"nixpkgs"
],
"utils": "utils"
},
"locked": {
"lastModified": 1703087360,
"narHash": "sha256-0VUbWBW8VyiDRuimMuLsEO4elGuUw/nc2WDeuO1eN1M=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "b709d63debafce9f5645a5ba550c9e0983b3d1f7",
"type": "github"
},
"original": {
"owner": "serokell",
"repo": "deploy-rs",
"type": "github"
}
},
"devshell": {
"inputs": {
"nixpkgs": [
"erpnext",
"nixpkgs"
],
"systems": [
"erpnext",
"systems"
]
},
"locked": {
"lastModified": 1701787589,
"narHash": "sha256-ce+oQR4Zq9VOsLoh9bZT8Ip9PaMLcjjBUHVPzW5d7Cw=",
"owner": "numtide",
"repo": "devshell",
"rev": "44ddedcbcfc2d52a76b64fb6122f209881bd3e1e",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"erpnext": {
"inputs": {
"agenix": [
"agenix"
],
"devshell": "devshell",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems_3"
},
"locked": {
"lastModified": 1704557841,
"narHash": "sha256-KpAkdJnY1NV21zRRd8Tncw6nBerSv50qmz6pSpjsxLg=",
"ref": "main",
"rev": "7fc327263630e2f5ce693e8569a1072bd0cea67b",
"revCount": 49,
"type": "git",
"url": "https://git.pub.solar/axeman/erpnext-nix"
},
"original": {
"ref": "main",
"type": "git",
"url": "https://git.pub.solar/axeman/erpnext-nix"
}
},
"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-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1704152458,
"narHash": "sha256-DS+dGw7SKygIWf9w4eNBUZsK+4Ug27NwEWmn2tnbycg=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "88a2cd8166694ba0b6cb374700799cec53aef527",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1704099619,
"narHash": "sha256-QRVMkdxLmv+aKGjcgeEg31xtJEIsYq4i1Kbyw5EPS6g=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "7e398b3d76bc1503171b1364c9d4a07ac06f3851",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-23.11",
"repo": "home-manager",
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1704277720,
"narHash": "sha256-meAKNgmh3goankLGWqqpw73pm9IvXjEENJloF0coskE=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "0dd382b70c351f528561f71a0a7df82c9d2be9a4",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"nixos-flake": {
"locked": {
"lastModified": 1702145288,
"narHash": "sha256-apVeRT0kOnDejwwBwbwNccm+qq1l6+qUOiRKE0vK5qk=",
"owner": "srid",
"repo": "nixos-flake",
"rev": "4e422edf6b511f8e214b392cf1a0d4707a0399a4",
"type": "github"
},
"original": {
"owner": "srid",
"repo": "nixos-flake",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1704458188,
"narHash": "sha256-f6BYEuIqnbrs6J/9m1/1VdkJ6d63hO9kUC09kTPuOqE=",
"owner": "nixos",
"repo": "nixos-hardware",
"rev": "172385318068519900a7d71c1024242fa6af75f0",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1704420045,
"narHash": "sha256-C36QmoJd5tdQ5R9MC1jM7fBkZW9zBUqbUCsgwS6j4QU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c1be43e8e837b8dbee2b3665a007e761680f0c3d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1703961334,
"narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9",
"type": "github"
},
"original": {
"dir": "lib",
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"deploy-rs": "deploy-rs",
"erpnext": "erpnext",
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"home-manager": "home-manager",
"nix-darwin": "nix-darwin",
"nixos-flake": "nixos-flake",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"unstable": "unstable"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"unstable": {
"locked": {
"lastModified": 1704194953,
"narHash": "sha256-RtDKd8Mynhe5CFnVT8s0/0yqtWFMM9LmCzXv/YKxnq4=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "bd645e8668ec6612439a9ee7e71f7eac4099d4f6",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

100
flake.nix Normal file
View File

@ -0,0 +1,100 @@
{
description = "Momo infra in nix";
nixConfig.extra-experimental-features = "nix-command flakes";
inputs = {
# Track channels with commits tested and built by hydra
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
unstable.url = "github:nixos/nixpkgs/nixos-unstable";
flake-compat.url = "github:edolstra/flake-compat";
flake-compat.flake = false;
nix-darwin.url = "github:lnl7/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
home-manager.url = "github:nix-community/home-manager/release-23.11";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
flake-parts.url = "github:hercules-ci/flake-parts";
nixos-flake.url = "github:srid/nixos-flake";
deploy-rs.url = "github:serokell/deploy-rs";
deploy-rs.inputs.nixpkgs.follows = "nixpkgs";
deploy-rs.inputs.flake-compat.follows = "flake-compat";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
agenix.inputs.darwin.follows = "nix-darwin";
agenix.inputs.home-manager.follows = "home-manager";
nixos-hardware.url = "github:nixos/nixos-hardware";
erpnext.url = "git+https://git.pub.solar/axeman/erpnext-nix?ref=main";
erpnext.inputs.nixpkgs.follows = "nixpkgs";
erpnext.inputs.agenix.follows = "agenix";
};
outputs = inputs @ {self, ...}:
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
debug = true;
systems = [
"x86_64-linux"
];
imports = [
inputs.nixos-flake.flakeModule
./lib
./modules
./hosts
./users
./overlays
];
perSystem = args @ {
system,
pkgs,
config,
...
}: {
_module.args = {
inherit inputs;
pkgs = import inputs.nixpkgs {
inherit system;
overlays = [
inputs.agenix.overlays.default
];
};
unstable = import inputs.unstable {inherit system;};
};
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
deploy-rs
drone-cli
nixpkgs-fmt
agenix
cachix
editorconfig-checker
nodePackages.prettier
nvfetcher
shellcheck
shfmt
alejandra
treefmt
nixos-generators
];
};
};
flake = {
deploy.nodes = self.lib.deploy.mkDeployNodes self.nixosConfigurations {
pioneer-momo-koeln = {
hostname = "80.244.242.4";
sshUser = "barkeeper";
};
};
};
};
}

19
hosts/default.nix Normal file
View File

@ -0,0 +1,19 @@
{
self,
inputs,
...
}: {
flake = {
nixosConfigurations = {
pioneer-momo-koeln = self.nixos-flake.lib.mkLinuxSystem {
nixpkgs.hostPlatform = "x86_64-linux";
imports = [
self.nixosModules.base
./pioneer-momo-koeln
self.nixosModules.barkeeper
inputs.erpnext.nixosModules.erpnext
];
};
};
};
}

View File

@ -0,0 +1,18 @@
{config, ...}: {
services.caddy = {
enable = true;
email = "wg-tooling@list.momo.koeln";
virtualHosts = {
"auth.momo.koeln" = {
logFormat = ''
output discard
'';
extraConfig = ''
reverse_proxy :8080
'';
};
};
};
networking.firewall.allowedTCPPorts = [80 443];
}

View File

@ -0,0 +1,34 @@
{
config,
latestModulesPath,
lib,
pkgs,
...
}: {
imports = [
./caddy.nix
./keycloak.nix
./erpnext.nix
];
time.timeZone = "Europe/Berlin";
networking = {
useDHCP = false;
interfaces.enp1s0.ipv4.addresses = [
{
address = "80.244.242.4";
prefixLength = 29;
}
];
defaultGateway = "80.244.242.1";
nameservers = ["95.129.51.51" "80.244.244.244"];
};
# Enable the OpenSSH daemon.
services.openssh.enable = true;
system.stateVersion = "22.05";
}

View File

@ -0,0 +1,6 @@
{...}: {
imports = [
./configuration.nix
./hardware-configuration.nix
];
}

View File

@ -0,0 +1,38 @@
{
config,
lib,
inputs,
pkgs,
flake,
...
}: {
age.secrets.erpnext-admin-password = {
file = "${flake.self}/secrets/erpnext-admin-password.age";
mode = "700";
owner = "erpnext";
};
age.secrets.erpnext-db-root-password = {
file = "${flake.self}/secrets/erpnext-db-root-password.age";
mode = "700";
owner = "erpnext";
};
age.secrets.erpnext-db-user-password = {
file = "${flake.self}/secrets/erpnext-db-user-password.age";
mode = "700";
owner = "erpnext";
};
# erpnext
services.erpnext = {
enable = true;
domain = "erp.momo.koeln";
# Secrets
adminPasswordFile = config.age.secrets.erpnext-admin-password.path;
database.rootPasswordFile = config.age.secrets.erpnext-db-root-password.path;
database.userPasswordFile = config.age.secrets.erpnext-db-user-password.path;
# Required to enable caddy
caddy = {};
};
}

View File

@ -0,0 +1,54 @@
{
config,
pkgs,
lib,
...
}: {
boot.loader.systemd-boot.enable = false;
boot.loader.grub = {
enable = true;
devices = ["/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-1"];
};
boot.initrd.availableKernelModules = ["ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
boot.kernelModules = ["kvm-intel"];
boot.extraModulePackages = [];
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-uuid/bf890962-9f43-4c44-a0df-64cabd303662";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/7eb8989a-6ec4-405f-8810-06486f7621c1";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/1fd053f8-725b-418d-aed1-aee71dac2b62";
fsType = "ext4";
};
swapDevices = [
{device = "/dev/disk/by-uuid/2f114633-5b71-46ab-88be-997b27927269";}
];
networking = {
defaultGateway = {
address = "80.244.242.1";
interface = "enp1s0";
};
nameservers = ["95.129.51.51" "80.244.244.244"];
interfaces.enp1s0 = {
useDHCP = false;
ipv4.addresses = [
{
address = "80.244.242.4";
prefixLength = 29;
}
];
};
};
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -0,0 +1,25 @@
{
config,
lib,
inputs,
pkgs,
flake,
...
}: {
age.secrets.keycloak-database-password = {
file = "${flake.self}/secrets/keycloak-database-password.age";
mode = "700";
};
# keycloak
services.keycloak = {
enable = true;
database.passwordFile = config.age.secrets.keycloak-database-password.path;
settings = {
hostname = "auth.momo.koeln";
http-host = "127.0.0.1";
http-port = 8080;
proxy = "edge";
};
};
}

View File

@ -0,0 +1,4 @@
{lib}: hostnames: {
"127.0.0.1" = hostnames;
"::1" = hostnames;
}

21
lib/compat/default.nix Normal file
View File

@ -0,0 +1,21 @@
let
lock = builtins.fromJSON (builtins.readFile builtins.path {
path = ../../flake.lock;
name = "lockPath";
});
flake =
import
(
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{
src = builtins.path {
path = ../../.;
name = "projectRoot";
};
};
in
flake

View File

@ -0,0 +1,9 @@
{...}: let
inherit (default.inputs.nixos) lib;
host = configs.${hostname} or configs.PubSolarOS;
configs = default.nixosConfigurations;
default = (import ../.).defaultNix;
hostname = lib.fileContents /etc/hostname;
in
host

21
lib/default.nix Normal file
View File

@ -0,0 +1,21 @@
{
lib,
inputs,
...
}: {
# Configuration common to all Linux systems
flake = {
lib = let
callLibs = file: import file {inherit lib;};
in rec {
## Define your own library functions here!
#id = x: x;
## Or in files, containing functions that take {lib}
#foo = callLibs ./foo.nix;
## In configs, they can be used under "lib.our"
deploy = import ./deploy.nix {inherit inputs lib;};
addLocalHostname = callLibs ./add-local-hostname.nix;
};
};
}

64
lib/deploy.nix Normal file
View File

@ -0,0 +1,64 @@
/*
* The contents of this file are adapted from digga
* https://github.com/divnix/digga
*
* Licensed under the MIT license
*/
{
lib,
inputs,
}: let
getFqdn = c: let
net = c.config.networking;
fqdn =
if (net ? domain) && (net.domain != null)
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
in {
mkDeployNodes = systemConfigurations: extraConfig:
/*
*
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
Generate the `nodes` attribute expected by deploy-rs
where _systemConfigurations_ are `nodes`.
_systemConfigurations_ should take the form of a flake's
_nixosConfigurations_. Note that deploy-rs does not currently support
deploying to darwin hosts.
_extraConfig_, if specified, will be merged into each of the
nodes' configurations.
Example _systemConfigurations_ input:
```
{
hostname-1 = {
fastConnection = true;
sshOpts = [ "-p" "25" ];
};
hostname-2 = {
sshOpts = [ "-p" "19999" ];
sshUser = "root";
};
}
```
*
*/
lib.recursiveUpdate
(lib.mapAttrs
(
_: c: {
hostname = getFqdn c;
profiles.system = {
user = "root";
path = inputs.deploy-rs.lib.${c.pkgs.stdenv.hostPlatform.system}.activate.nixos c;
};
}
)
systemConfigurations)
extraConfig;
}

15
modules/adb/default.nix Normal file
View File

@ -0,0 +1,15 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
programs.adb.enable = true;
users.users."${psCfg.user.name}" = {
extraGroups = ["adbusers"];
};
}

View File

@ -0,0 +1,17 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
users.users."${psCfg.user.name}" = {
extraGroups = ["dialout"];
packages = with pkgs; [
arduino
arduino-cli
];
};
}

View File

@ -0,0 +1,53 @@
echo Parsing config file
" Set the default tab
set window playlist
" Set the windows to show at startup
set windows playlist,library,browse,help
" Stop playing music when we quit
"set stoponquit
" A silly example of an alias
"alias smiths deleteall; findartist! The Smiths; play 1
" Example maps
" map the F key to change to the browse window, go to the first line and enter search mode
"map F :browse<C-M>gg/
" map @ to switch to add next, add a song, then change back
"map @ :set add next<C-M>a:set add end<C-M>
map i <Up>
map j <Left>
map k <Down>
map h i
map q ZQ
map Q ZQ
map <space>l :tabnext<CR>
map <space>j :tabprevious<CR>
" Turn consume on when we connect
"consume on
" Ensure that the database is up to date each connect
update
" A more complex example, When we start vimpc
" - clear the playlist
" - add all songs
" - shuffle
" - start playling
"deleteall
"addall
"shuffle
"play 1
" Color the statusline and tabs
" highlight status blackbg
" highlight tab blackbg
echo Config File Complete

39
modules/audio/default.nix Normal file
View File

@ -0,0 +1,39 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
xdg = config.home-manager.users."${psCfg.user.name}".xdg;
in {
users.users."${psCfg.user.name}" = {
extraGroups = ["audio"];
packages = with pkgs; [
# easyeffects, e.g. for microphone noise filtering
easyeffects
mu
pavucontrol
pa_applet
playerctl
# Needed for pactl cmd, until pw-cli is more mature (vol up/down hotkeys?)
pulseaudio
vimpc
];
};
home-manager.users."${psCfg.user.name}" = {
xdg.configFile."vimpc/vimpcrc".source = ./.config/vimpc/vimpcrc;
systemd.user.services.easyeffects = import ./easyeffects.service.nix pkgs;
};
# rtkit is optional but recommended
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
}

View File

@ -0,0 +1,7 @@
pkgs: {
Service = {
Type = "dbus";
BusName = "com.github.wwmm.easyeffects";
ExecStart = "${pkgs.easyeffects}/bin/easyeffects --gapplication-service";
};
}

View File

@ -0,0 +1,35 @@
{
lib,
config,
pkgs,
...
}: {
hardware.bluetooth = {
enable = true;
# Disable bluetooth on startup to save battery
powerOnBoot = false;
# Disable useless SIM Access Profile plugin
disabledPlugins = [
"sap"
];
settings = {
General = {
# Enables experimental features and interfaces.
# Makes BlueZ Battery Provider available
Experimental = true;
};
};
};
services.blueman.enable = true;
environment.etc."wireplumber/bluetooth.lua.d/51-bluez-config.lua" = {
text = ''
bluez_monitor.properties = {
["bluez5.enable-sbc-xq"] = true,
["bluez5.enable-msbc"] = true,
["bluez5.enable-hw-volume"] = true,
["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]"
}
'';
};
}

35
modules/core/boot.nix Normal file
View File

@ -0,0 +1,35 @@
{
config,
pkgs,
lib,
...
}:
with lib; let
cfg = config.pub-solar.core;
in {
options.pub-solar.core.disk-encryption-active = mkOption {
type = types.bool;
default = true;
description = "Whether it should be assumed that there is a cryptroot device";
};
config = {
boot = {
# Mount / luks device in initrd
# Allow fstrim to work on it.
initrd = mkIf cfg.disk-encryption-active {
luks.devices."cryptroot" = {
allowDiscards = true;
};
};
loader.systemd-boot.enable = lib.mkDefault true;
# Use latest LTS linux kernel by default
kernelPackages = lib.mkDefault pkgs.linuxPackages_6_6;
# Support ntfs drives
supportedFilesystems = ["ntfs"];
};
};
}

38
modules/core/default.nix Normal file
View File

@ -0,0 +1,38 @@
{
config,
lib,
...
}:
with lib; let
cfg = config.pub-solar.core;
psCfg = config.pub-solar;
in {
imports = [
./boot.nix
./hibernation.nix
./i18n.nix
./networking.nix
./packages.nix
];
# Service that makes Out of Memory Killer more effective
services.earlyoom.enable = true;
services.logind.lidSwitch = "hibernate";
services.tor.settings = {
UseBridges = true;
};
# The options below are directly taken from or inspired by
# https://xeiaso.net/blog/paranoid-nixos-2021-07-18
# Limit the use of sudo to the group wheel
security.sudo.execWheelOnly = true;
# Remove the complete default environment of packages like
# nano, perl and rsync
environment.defaultPackages = lib.mkForce [];
# fileSystems."/".options = [ "noexec" ];
}

View File

@ -0,0 +1,36 @@
{
config,
pkgs,
lib,
...
}:
with lib; let
cfg = config.pub-solar.core.hibernation;
in {
options.pub-solar.core.hibernation = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether the device can hibernate. This creates a swapfile at /swapfile.";
};
resumeDevice = mkOption {
type = types.nullOr types.str;
default = null;
description = "The location of the hibernation resume swap file.";
};
resumeOffset = mkOption {
type = types.nullOr types.int;
default = null;
description = "The swap file offset. Can be found by running `filefrag -v $swap_file_location`. See https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Hibernation_into_swap_file";
};
};
config = {
boot = mkIf cfg.enable {
resumeDevice = mkIf (cfg.resumeDevice != null) cfg.resumeDevice;
kernelParams = mkIf (cfg.resumeOffset != null) ["resume_offset=${builtins.toString cfg.resumeOffset}"];
};
};
}

20
modules/core/i18n.nix Normal file
View File

@ -0,0 +1,20 @@
{
config,
pkgs,
lib,
...
}:
with lib; {
config = {
# Set your time zone.
time.timeZone = "Europe/Berlin";
# Select internationalisation properties.
console = {
font = "Lat2-Terminus16";
};
i18n = {
defaultLocale = "en_US.UTF-8";
};
};
}

View File

@ -0,0 +1,39 @@
{
flake,
config,
pkgs,
lib,
...
}: {
# disable NetworkManager and systemd-networkd -wait-online by default
systemd.services.NetworkManager-wait-online.enable = lib.mkDefault false;
systemd.services.systemd-networkd-wait-online.enable = lib.mkDefault false;
networking.networkmanager = {
# Enable networkmanager. REMEMBER to add yourself to group in order to use nm related stuff.
enable = lib.mkDefault true;
# not as stable as wpa_supplicant yet, also more trouble with 5 GHz networks
#wifi.backend = "iwd";
};
networking.firewall.enable = true;
# For rage encryption, all hosts need a ssh key pair
services.openssh = {
enable = true;
allowSFTP = lib.mkDefault false;
openFirewall = lib.mkDefault false;
settings.PasswordAuthentication = lib.mkDefault false;
settings.KbdInteractiveAuthentication = false;
extraConfig = ''
AllowTcpForwarding yes
X11Forwarding no
AllowAgentForwarding no
AllowStreamLocalForwarding no
AuthenticationMethods publickey
'';
};
}

28
modules/core/packages.nix Normal file
View File

@ -0,0 +1,28 @@
{
config,
pkgs,
lib,
...
}:
with lib; let
psCfg = config.pub-solar;
cfg = config.pub-solar.core;
in {
environment.systemPackages = with pkgs; [
# Core unix utility packages
coreutils-full
dnsutils
inetutils
progress
pciutils
usbutils
diffutils
findutils
exfat
gitMinimal
btop
mtr
];
}

View File

@ -0,0 +1,33 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
services.udev.packages = [pkgs.yubikey-personalization];
services.dbus.packages = [pkgs.gcr];
services.pcscd.enable = true;
services.gnome.gnome-keyring.enable = true;
users.users."${psCfg.user.name}".packages = with pkgs; [
libsecret
];
home-manager.users."${psCfg.user.name}" = {
systemd.user.services.polkit-gnome-authentication-agent = import ./polkit-gnome-authentication-agent.service.nix pkgs;
services.gpg-agent = {
enable = true;
pinentryFlavor = "gnome3";
verbose = true;
};
programs.gpg = {
enable = true;
};
};
}

View File

@ -0,0 +1,15 @@
pkgs: {
Unit = {
Description = "Legacy polkit authentication agent for GNOME";
Documentation = ["https://gitlab.freedesktop.org/polkit/polkit/"];
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,269 @@
{
config,
pkgs,
lib,
...
}: let
cfg = config.services.ddclient;
boolToStr = bool:
if bool
then "yes"
else "no";
dataDir = "/var/lib/ddclient";
StateDirectory = builtins.baseNameOf dataDir;
RuntimeDirectory = StateDirectory;
usev4 =
if cfg.usev4 != ""
then "usev4=${cfg.usev4}"
else "";
usev6 =
if cfg.usev6 != ""
then "usev6=${cfg.usev6}"
else "";
configFile' = pkgs.writeText "ddclient.conf" ''
# This file can be used as a template for configFile or is automatically generated by Nix options.
use=no
${usev4}
${usev6}
cache=${dataDir}/ddclient.cache
foreground=yes
login=${cfg.username}
password=${
if cfg.protocol == "nsupdate"
then "/run/${RuntimeDirectory}/ddclient.key"
else "@password_placeholder@"
}
protocol=${cfg.protocol}
${lib.optionalString (cfg.script != "") "script=${cfg.script}"}
${lib.optionalString (cfg.server != "") "server=${cfg.server}"}
${lib.optionalString (cfg.zone != "") "zone=${cfg.zone}"}
ssl=${boolToStr cfg.ssl}
wildcard=yes
quiet=${boolToStr cfg.quiet}
verbose=${boolToStr cfg.verbose}
${cfg.extraConfig}
${lib.concatStringsSep "," cfg.domains}
'';
configFile =
if (cfg.configFile != null)
then cfg.configFile
else configFile';
preStart = ''
install --mode=600 --owner=$USER ${configFile} /run/${RuntimeDirectory}/ddclient.conf
${lib.optionalString (cfg.configFile == null) (
if (cfg.protocol == "nsupdate")
then ''
install --mode=600 --owner=$USER ${cfg.passwordFile} /run/${RuntimeDirectory}/ddclient.key
''
else if (cfg.passwordFile != null)
then ''
"${pkgs.replace-secret}/bin/replace-secret" "@password_placeholder@" "${cfg.passwordFile}" "/run/${RuntimeDirectory}/ddclient.conf"
''
else ''
sed -i '/^password=@password_placeholder@$/d' /run/${RuntimeDirectory}/ddclient.conf
''
)}
'';
in
with lib; {
disabledModules = [
"services/networking/ddclient.nix"
];
imports = [
(mkChangedOptionModule ["services" "ddclient" "domain"] ["services" "ddclient" "domains"]
(config: let
value = getAttrFromPath ["services" "ddclient" "domain"] config;
in
if value != ""
then [value]
else []))
(mkRemovedOptionModule ["services" "ddclient" "homeDir"] "")
(mkRemovedOptionModule ["services" "ddclient" "password"] "Use services.ddclient.passwordFile instead.")
];
###### interface
options = {
services.ddclient = with lib.types; {
enable = mkOption {
default = false;
type = bool;
description = lib.mdDoc ''
Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org).
'';
};
package = mkOption {
type = package;
default = pkgs.ddclient;
defaultText = lib.literalExpression "pkgs.ddclient";
description = lib.mdDoc ''
The ddclient executable package run by the service.
'';
};
domains = mkOption {
default = [""];
type = listOf str;
description = lib.mdDoc ''
Domain name(s) to synchronize.
'';
};
username = mkOption {
# For `nsupdate` username contains the path to the nsupdate executable
default = lib.optionalString (config.services.ddclient.protocol == "nsupdate") "${pkgs.bind.dnsutils}/bin/nsupdate";
defaultText = "";
type = str;
description = lib.mdDoc ''
User name.
'';
};
passwordFile = mkOption {
default = null;
type = nullOr str;
description = lib.mdDoc ''
A file containing the password or a TSIG key in named format when using the nsupdate protocol.
'';
};
interval = mkOption {
default = "10min";
type = str;
description = lib.mdDoc ''
The interval at which to run the check and update.
See {command}`man 7 systemd.time` for the format.
'';
};
configFile = mkOption {
default = null;
type = nullOr path;
description = lib.mdDoc ''
Path to configuration file.
When set this overrides the generated configuration from module options.
'';
example = "/root/nixos/secrets/ddclient.conf";
};
protocol = mkOption {
default = "dyndns2";
type = str;
description = lib.mdDoc ''
Protocol to use with dynamic DNS provider (see https://sourceforge.net/p/ddclient/wiki/protocols).
'';
};
server = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
Server address.
'';
};
ssl = mkOption {
default = true;
type = bool;
description = lib.mdDoc ''
Whether to use SSL/TLS to connect to dynamic DNS provider.
'';
};
quiet = mkOption {
default = false;
type = bool;
description = lib.mdDoc ''
Print no messages for unnecessary updates.
'';
};
script = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
script as required by some providers.
'';
};
usev4 = mkOption {
default = "webv4, webv4=checkip.dyndns.com/, webv4-skip='Current IP Address: '";
type = str;
description = lib.mdDoc ''
Method to determine the IP address to send to the dynamic DNS provider.
'';
};
usev6 = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
Method to determine the IP address to send to the dynamic DNS provider.
'';
};
verbose = mkOption {
default = false;
type = bool;
description = lib.mdDoc ''
Print verbose information.
'';
};
zone = mkOption {
default = "";
type = str;
description = lib.mdDoc ''
zone as required by some providers.
'';
};
extraConfig = mkOption {
default = "";
type = lines;
description = lib.mdDoc ''
Extra configuration. Contents will be added verbatim to the configuration file.
::: {.note}
`daemon` should not be added here because it does not work great with the systemd-timer approach the service uses.
:::
'';
};
};
};
###### implementation
config = mkIf config.services.ddclient.enable {
systemd.services.ddclient = {
description = "Dynamic DNS Client";
wantedBy = ["multi-user.target"];
after = ["network.target"];
restartTriggers = optional (cfg.configFile != null) cfg.configFile;
serviceConfig = {
DynamicUser = true;
RuntimeDirectoryMode = "0700";
inherit RuntimeDirectory;
inherit StateDirectory;
Type = "oneshot";
ExecStartPre = "!${pkgs.writeShellScript "ddclient-prestart" preStart}";
ExecStart = "${lib.getBin cfg.package}/bin/ddclient -file /run/${RuntimeDirectory}/ddclient.conf";
};
};
systemd.timers.ddclient = {
description = "Run ddclient";
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = cfg.interval;
OnUnitInactiveSec = cfg.interval;
};
};
};
}

42
modules/default.nix Normal file
View File

@ -0,0 +1,42 @@
{
self,
inputs,
...
}: {
flake = {
nixosModules = rec {
audio = import ./audio;
bluetooth = import ./bluetooth;
core = import ./core;
crypto = import ./crypto;
desktop-extended = import ./desktop-extended;
docker = import ./docker;
#email = import ./email;
#gaming = import ./gaming;
graphical = import ./graphical;
#invoiceplane = import ./invoiceplane;
nix = import ./nix;
nextcloud = import ./nextcloud;
office = import ./office;
printing = import ./printing;
terminal-life = import ./terminal-life;
user = import ./user;
virtualisation = import ./virtualisation;
#wireguard-client = import ./wireguard-client;
base.imports = [
self.nixosModules.home-manager
inputs.agenix.nixosModules.default
self.nixosModules.overlays
self.nixosModules.core
self.nixosModules.crypto
self.nixosModules.nix
self.nixosModules.terminal-life
self.nixosModules.root
self.nixosModules.user
];
};
};
}

View File

@ -0,0 +1,49 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
users.users."${psCfg.user.name}".packages = with pkgs; [
ungoogled-chromium
wine
gimp
inkscape
tigervnc
nodejs
signal-desktop
tdesktop
element-desktop
# Nix specific utilities
alejandra
manix
nix-output-monitor
nix-tree
nvd
nixpkgs-review
nix-search-cli
];
fonts = {
packages = with pkgs; [
dejavu_fonts
fira-code
fira-code-symbols
#google-fonts
lato
montserrat
nerdfonts
noto-fonts
noto-fonts-cjk
open-sans
powerline-fonts
source-sans-pro
];
};
}

View File

@ -0,0 +1,20 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
virtualisation.docker.enable = true;
virtualisation.docker.package = pkgs.docker_24;
users.users."${psCfg.user.name}" = {
extraGroups = ["docker"];
};
environment.systemPackages = with pkgs; [
docker-compose
];
}

54
modules/email/default.nix Normal file
View File

@ -0,0 +1,54 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
users.users."${psCfg.user.name}".packages = with pkgs; [
w3m
urlscan
neomutt
offlineimap
msmtp
mailto-mutt
];
home-manager.users."${psCfg.user.name}" = {
programs.offlineimap = {
enable = true;
pythonFile = builtins.readFile ./offlineimap.py;
};
xdg.configFile."mutt/muttrc".source = ./.config/mutt/muttrc;
xdg.configFile."mutt/base16.muttrc".source = ./.config/mutt/base16.muttrc;
xdg.configFile."mutt/mailcap".source = ./.config/mutt/mailcap;
xdg.configFile."offlineimap/functions.py".source = ./.config/offlineimap/functions.py;
xdg.configFile."mutt/accounts.muttrc".text = ''
source ./hello@benjaminbaedorf.eu.muttrc
macro index <f1> '<sync-mailbox><enter-command>source $XDG_CONFIG_HOME/mutt/hello@benjaminbaedorf.eu.muttrc<enter><change-folder>!<enter>'
macro index <f2> '<sync-mailbox><enter-command>source $XDG_CONFIG_HOME/mutt/benjamin.baedorf@rwth-aachen.de.muttrc<enter><change-folder>!<enter>'
macro index <f3> '<sync-mailbox><enter-command>source $XDG_CONFIG_HOME/mutt/byb@miom.space.muttrc<enter><change-folder>!<enter>'
macro index <f4> '<sync-mailbox><enter-command>source $XDG_CONFIG_HOME/mutt/mail@b12f.io.muttrc<enter><change-folder>!<enter>'
macro index <f5> '<sync-mailbox><enter-command>source $XDG_CONFIG_HOME/mutt/admins@pub.solar.muttrc<enter><change-folder>!<enter>'
macro index <f6> '<sync-mailbox><enter-command>source $XDG_CONFIG_HOME/mutt/crew@pub.solar.muttrc<enter><change-folder>!<enter>'
'';
xdg.configFile."mutt/hello@benjaminbaedorf.eu.muttrc".source = ./.config/mutt + "/hello@benjaminbaedorf.eu.muttrc";
xdg.configFile."mutt/benjamin.baedorf@rwth-aachen.de.muttrc".source = ./.config/mutt + "/benjamin.baedorf@rwth-aachen.de.muttrc";
xdg.configFile."mutt/hello@benjaminbaedorf.eu.signature".source = ./.config/mutt + "/hello@benjaminbaedorf.eu.signature";
xdg.configFile."mutt/byb@miom.space.muttrc".source = ./.config/mutt + "/byb@miom.space.muttrc";
xdg.configFile."mutt/byb@miom.space.signature".source = ./.config/mutt + "/byb@miom.space.signature";
xdg.configFile."mutt/mail@b12f.io.muttrc".source = ./.config/mutt + "/mail@b12f.io.muttrc";
xdg.configFile."mutt/mail@b12f.io.signature".source = ./.config/mutt + "/mail@b12f.io.signature";
xdg.configFile."mutt/admins@pub.solar.muttrc".source = ./.config/mutt + "/admins@pub.solar.muttrc";
xdg.configFile."mutt/admins@pub.solar.signature".source = ./.config/mutt + "/admins@pub.solar.signature";
xdg.configFile."mutt/crew@pub.solar.muttrc".source = ./.config/mutt + "/crew@pub.solar.muttrc";
xdg.configFile."mutt/crew@pub.solar.signature".source = ./.config/mutt + "/crew@pub.solar.signature";
xdg.configFile."offlineimap/config".source = ./.config/offlineimap/config;
xdg.configFile."msmtp/config".source = ./.config/msmtp/config;
};
}

View File

@ -0,0 +1,9 @@
#! /usr/bin/env python2
import os
import subprocess
def get_env(key):
return os.getenv(key)
def get_secret(*attributes):
return subprocess.check_output(["secret-tool", "lookup"] + list(attributes))

View File

@ -0,0 +1,21 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
programs.steam.enable = true;
nixpkgs.config.packageOverrides = pkgs: {
steam = pkgs.steam.override {};
};
users.users."${psCfg.user.name}".packages = with pkgs; [
playonlinux
godot
obs-studio
obs-studio-plugins.wlrobs
];
}

View File

@ -0,0 +1,62 @@
Xft.dpi: 96
Xft.antialias: true
Xft.hinting: true
Xft.rgba: rgb
Xft.autohint: false
Xft.hintstyle: hintslight
Xft.lcdfilter: lcddefault
! Base16 Burn
! Scheme: Benjamin Bädorf
#define base00 #1a181a
#define base01 #2d2a2e
#define base02 #303030
#define base03 #949494
#define base04 #d3d1d4
#define base05 #e3e1e4
#define base06 #303030
#define base07 #ff5f5f
#define base08 #f85e84
#define base09 #df5923
#define base0A #e5c463
#define base0B #9ecd6f
#define base0C #ef9062
#define base0D #7accd7
#define base0E #ab9df2
#define base0F #d70000
*foreground: base05
#ifdef background_opacity
*background: [background_opacity]base00
#else
*background: base00
#endif
*cursorColor: base05
*color0: base00
*color1: base08
*color2: base0B
*color3: base0A
*color4: base0D
*color5: base0E
*color6: base0C
*color7: base05
*color8: base03
*color9: base08
*color10: base0B
*color11: base0A
*color12: base0D
*color13: base0E
*color14: base0C
*color15: base07
! Note: colors beyond 15 might not be loaded (e.g., xterm, urxvt),
! use 'shell' template to set these if necessary
*color16: base09
*color17: base0F
*color18: base01
*color19: base02
*color20: base04
*color21: base06

View File

@ -0,0 +1,198 @@
# Configuration file for libinput-gestures.
# Mark Blakeney, Sep 2015
#
# The default configuration file exists at /etc/libinput-gestures.conf
# but a user can create a personal custom configuration file at
# ~/.config/libinput-gestures.conf.
#
# Lines starting with '#' and blank lines are ignored. Currently
# "gesture" and "device" configuration keywords are supported as
# described below. The keyword can optionally be appended with a ":" (to
# maintain compatibility with original format configuration files).
#
# Each gesture line has 3 [or 4] arguments separated by whitespace:
#
# action motion [finger_count] command
#
# where action and motion is either:
# swipe up
# swipe down
# swipe left
# swipe right
# swipe left_up
# swipe left_down
# swipe right_up
# swipe right_down
# pinch in
# pinch out
# pinch clockwise
# pinch anticlockwise
#
# command is the remainder of the line and is any valid shell command +
# arguments.
#
# finger_count is a single numeric digit and is optional (and is
# typically 3 or 4). If specified then the command is executed when
# exactly that number of fingers is used in the gesture. If not
# specified then the command is executed when that gesture is executed
# with any number of fingers. Gesture lines specified with finger_count
# have priority over the same gesture specified without any
# finger_count.
#
# Typically command will be xdotool, or wmctrl. See "man xdotool" for
# the many things you can action with that tool. Note that unfortunately
# xdotool does not work with native Wayland clients.
###############################################################################
# SWIPE GESTURES:
###############################################################################
# Note the default is an "internal" command that uses wmctrl to switch
# workspaces and, unlike xdotool, works on both Xorg and Wayland (via
# XWayland). It also can be configured for vertical and horizontal
# switching over tabular workspaces, as per the example below. You can
# also add "-w" to the internal command to allow wrapping workspaces.
# Move to next workspace (works for GNOME/KDE/etc on Wayland and Xorg)
#gesture swipe up _internal ws_up
# NOTE ABOUT FINGER COUNT:
# The above command will configure this command for all fingers (i.e. 3
# for 4) but to configure it for 3 fingers only, change it to:
# gesture swipe up 3 _internal ws_up
# Then you can configure something else for 4 fingers or leave 4 fingers
# unconfigured. You can configure an explicit finger count like this for
# all example commands in this configuration file.
#
gesture swipe up 3 ydotool key Super_L+Down
gesture swipe up 4 ydotool key Super_L+Ctrl+Right
# Move to prev workspace (works for GNOME/KDE/etc on Wayland and Xorg)
#gesture swipe down _internal ws_down
gesture swipe down 3 ydotool key Super_L+Up
gesture swipe down 4 ydotool key Super_L+Ctrl+Left
# Browser go forward (works only for Xorg, and Xwayland clients)
gesture swipe left 3 ydotool key ctrl+]
# Browser go back (works only for Xorg, and Xwayland clients)
gesture swipe right 3 ydotool key ctrl+[
# NOTE: If you don't use "natural" scrolling direction for your touchpad
# then you may want to swap the above default left/right and up/down
# configurations.
# Optional extended swipe gestures, e.g. for browser tab navigation:
#
# Jump to next open browser tab
#gesture swipe right_up xdotool key control+Tab
#gesture swipe right_up xdotool key control+Next
gesture swipe right_up ydotool key ctrl+PageDown
#
# Jump to previous open browser tab
#gesture swipe left_up xdotool key control+shift+Tab
gesture swipe left_up ydotool key ctrl+PageUp
#
# Close current browser tab
# gesture swipe left_down xdotool key control+w
#
# Reopen and jump to last closed browser tab
# gesture swipe right_down xdotool key control+shift+t
# Example of 8 static workspaces, e.g. using KDE virtual-desktops,
# arranged in 2 rows of 4 columns across using swipe up/down/left/right
# to navigate in fixed planes. You can also add the "-w/--wrap" option
# to allow wrapping in any direction. You must configure your virtual
# desktops with the same column dimension.
# gesture swipe up _internal --cols 4 ws_up
# gesture swipe down _internal --cols 4 ws_down
# gesture swipe left _internal --cols 4 ws_left
# gesture swipe right _internal --cols 4 ws_right
#
# Example of 16 static workspaces, e.g. using KDE virtual-desktops,
# arranged in 4 rows of 4 columns across using swipe up/down/left/right
# to navigate in fixed planes, and also using swipe
# left_up/left_down/right_up/right_down to navigate diagonally. You can
# also add the "-w/--wrap" option to allow wrapping in any direction
# and/or diagonally. You must configure your virtual desktops with the
# same column dimension.
# gesture swipe up _internal --cols 4 ws_up
# gesture swipe down _internal --cols 4 ws_down
# gesture swipe left _internal --cols 4 ws_left
# gesture swipe right _internal --cols 4 ws_right
# gesture swipe left_up _internal --cols 4 ws_left_up
# gesture swipe left_down _internal --cols 4 ws_left_down
# gesture swipe right_up _internal --cols 4 ws_right_up
# gesture swipe right_down _internal --cols 4 ws_right_down
# Example virtual desktop switching for Ubuntu Unity/Compiz. The
# _internal command does not work for Compiz but you can explicitly
# configure the swipe commands to work for a Compiz virtual 2
# dimensional desktop as follows:
# gesture swipe up xdotool key ctrl+alt+Up
# gesture swipe down xdotool key ctrl+alt+Down
# gesture swipe left xdotool key ctrl+alt+Left
# gesture swipe right xdotool key ctrl+alt+Right
# Example to change audio volume:
# Note this only works on an Xorg desktop (not Wayland).
# gesture swipe up xdotool key XF86AudioRaiseVolume
# gesture swipe down xdotool key XF86AudioLowerVolume
###############################################################################
# PINCH GESTURES:
###############################################################################
# GNOME SHELL open/close overview (works for GNOME on Xorg only)
gesture pinch in ydotool key ctrl+-
gesture pinch out ydotool key ctrl+shift+=
# KDE Plasma open/close overview
# gesture pinch in xdotool key ctrl+F9
# gesture pinch out xdotool key ctrl+F9
# GNOME SHELL open/close overview (works for GNOME on Wayland and Xorg)
# Note since GNOME 3.24 on Wayland this is implemented natively so no
# real point configuring for Wayland.
# gesture pinch in dbus-send --session --type=method_call --dest=org.gnome.Shell /org/gnome/Shell org.gnome.Shell.Eval string:'Main.overview.toggle();'
# gesture pinch out dbus-send --session --type=method_call --dest=org.gnome.Shell /org/gnome/Shell org.gnome.Shell.Eval string:'Main.overview.toggle();'
# Optional extended pinch gestures:
# gesture pinch clockwise <whatever command>
# gesture pinch anticlockwise <whatever command>
###############################################################################
# This application normally determines your touchpad device
# automatically. Some users may have multiple touchpads but by default
# we use only the first one found. However, you can choose to specify
# the explicit device name to use. Run "libinput list-devices" to work
# out the name of your device (from the "Device:" field). Then add a
# device line specifying that name, e.g:
#
# device DLL0665:01 06CB:76AD Touchpad
#
# If the device name starts with a '/' then it is instead considered as
# the explicit device path although since device paths can change
# through reboots this is best to be a symlink. E.g. instead of specifying
# /dev/input/event12, use the corresponding full path link under
# /dev/input/by-path/ or /dev/input/by-id/.
#
# You can choose to use ALL touchpad devices by setting the device name
# to "all". E.g. Do this if you have multiple touchpads which you want
# to use in parallel. This reduces performance slightly so only set this
# if you have to.
#
# device all
###############################################################################
# You can set a minimum travel distance threshold before swipe gestures
# are actioned using the swipe_threshold configuration command.
# Specify this value in dots. The default is 0.
# E.g. set it to 100 dots with "swipe_threshold 100".
# swipe_threshold 0
###############################################################################
# You can set a timeout on gestures from start to end. The default is
# the value commented below. It can be any value in float secs >= 0.
# 0 = no timeout. E.g. set it to 2 secs with "timeout 2".
# timeout 1.5

View File

@ -0,0 +1,22 @@
padding=10
margin=5,5,0
default-timeout=5000
## Base16 Burn
# Author: Benjamin Bädorf
#
# You can use these variables anywhere in the mako configuration file.
background-color=#1a181a
text-color=#e3e1e4
border-color=#ff5f5f
[urgency=low]
background-color=#1a181a
text-color=#e3e1e4
border-color=#ff5f5f
[urgency=high]
background-color=#ff5f5f
text-color=#1a181a
border-color=#1a181a

View File

@ -0,0 +1,12 @@
{
"positionX": "right",
"positionY": "top",
"timeout": 10,
"timeout-low": 5,
"timeout-critical": 0,
"notification-window-width": 500,
"keyboard-shortcuts": true,
"image-visibility": "always",
"transition-time": 200,
"hide-on-clear": false
}

View File

@ -0,0 +1,149 @@
/*
* vim: ft=less
*/
@define-color border-color rgb(7, 7, 7);
@define-color bg rgb(58, 58, 58);
@define-color bg-hover rgb(68, 68, 68);
@define-color bg-focus rgba(68, 68, 68, 0.6);
@define-color bg-selected rgb(0, 128, 255);
.notification-row {
outline: none;
}
.notification-row:focus,
.notification-row:hover {
background: @bg-focus;
}
.notification {
border-radius: 10px;
margin: 6px 12px;
box-shadow: 0px 2px 4px 2px rgba(0, 0, 0, 0.3);
padding: 0;
}
.notification-content {
background: transparent;
padding: 6px;
border-radius: 10px;
}
.close-button {
background: black;
color: white;
text-shadow: none;
padding: 0 2px;
box-shadow: 0px 2px 4px 2px rgba(0, 0, 0, 0.3);
border-radius: 100%;
}
.close-button:hover {
background: rgb(30, 30, 30);
transition: all 0.15s ease-in-out;
}
.notification-default-action,
.notification-action {
padding: 4px;
margin: 0;
box-shadow: none;
background: @bg;
border: 1px solid @border-color;
}
.notification-default-action:hover,
.notification-action:hover {
background: @bg-hover;
}
.notification-default-action {
border-radius: 10px;
}
/* When alternative actions are visible */
.notification-default-action:not(:only-child) {
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
.notification-action {
border-radius: 0px;
border-top: none;
border-right: none;
}
/* add bottom border radius to eliminate clipping */
.notification-action:first-child {
border-bottom-left-radius: 10px;
}
.notification-action:last-child {
border-bottom-right-radius: 10px;
border-right: 1px solid @border-color;
}
.image {
}
.body-image {
margin-top: 6px;
background-color: white;
border-radius: 10px;
}
.summary {
color: white;
text-shadow: none;
}
.time {
color: white;
text-shadow: none;
}
.body {
background: transparent;
color: white;
text-shadow: none;
}
.top-action-title {
color: white;
text-shadow: none;
}
.control-center-clear-all {
color: white;
text-shadow: none;
background: @bg;
border: 1px solid @border-color;
box-shadow: none;
border-radius: 10px;
}
.control-center-clear-all:hover {
background: @bg-hover;
}
.control-center-dnd {
border-radius: 10px;
background: @bg;
border: 1px solid @border-color;
box-shadow: none;
}
.control-center-dnd:checked {
background: @bg-selected;
}
.control-center-dnd slider {
background: @bg-hover;
}
.control-center {
background: rgba(0, 0, 0, 0.7);
}
.control-center-list {
background: transparent;
}
.floating-notifications {
background: transparent;
}

View File

@ -0,0 +1,15 @@
# This file is written by xdg-user-dirs-update
# If you want to change or add directories, just edit the line you're
# interested in. All local changes will be retained on the next run.
# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
# absolute path. No other format is supported.
XDG_DESKTOP_DIR="$HOME/"
XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_TEMPLATES_DIR="$HOME/Templates"
XDG_PUBLICSHARE_DIR="$HOME/Public"
XDG_DOCUMENTS_DIR="$HOME/"
XDG_MUSIC_DIR="$HOME/"
XDG_PICTURES_DIR="$HOME/"
XDG_VIDEOS_DIR="$HOME/"

View File

@ -0,0 +1 @@
en_US

View File

@ -0,0 +1,23 @@
/*
*
* Base16 Burn
* Author: Benjamin Bädorf
*
*/
@define-color base00 #1a181a;
@define-color base01 #2d2a2e;
@define-color base02 #303030;
@define-color base03 #949494;
@define-color base04 #d3d1d4;
@define-color base05 #e3e1e4;
@define-color base06 #303030;
@define-color base07 #ff5f5f;
@define-color base08 #f85e84;
@define-color base09 #df5923;
@define-color base0A #e5c463;
@define-color base0B #9ecd6f;
@define-color base0C #ef9062;
@define-color base0D #7accd7;
@define-color base0E #ab9df2;
@define-color base0F #d70000;

View File

@ -0,0 +1,148 @@
{
"layer": "top", // Waybar at top layer
// "position": "bottom", // Waybar position (top|bottom|left|right)
"height": 26, // Waybar height
"modules-left": ["sway/workspaces", "sway/mode"],
"modules-center": ["network"],
"modules-right": [
"sway/language",
"backlight",
"custom/notification",
"pulseaudio",
"idle_inhibitor",
"battery",
"clock",
"tray"
],
"sway/workspaces": {
"disable-scroll": true
},
"sway/mode": {
"tooltip": false,
"format": "{}"
},
"sway/window": {
"tooltip": false,
"max-length": 96
},
"sway/language": {
"format": "{}",
"max-length": 50
},
"tray": {
"icon-size": 21,
"spacing": 10
},
"clock": {
"tooltip-format": "<tt><small>{calendar}</small></tt>",
"format": "{:%H:%M} ",
"format-alt": "{:%a %d. %h %H:%M} ",
//"on-scroll": {
// "calendar": 1
//}
"smooth-scrolling-threshold": 1.0,
"calendar": {
"mode-mon-col" : 3,
"on-scroll": -1,
"on-click-right": "mode",
"format": {
"months": "<span color='#ffead3'><b>{}</b></span>",
"days": "<span color='#ecc6d9'><b>{}</b></span>",
"weekdays": "<span color='#ffcc66'><b>{}</b></span>",
"today": "<span color='#ff6699'><b><u>{}</u></b></span>"
},
},
"actions": {
"on-click-right": "mode",
"on-click-forward": "tz_up",
"on-click-backward": "tz_down",
"on-scroll-up": "shift_up",
"on-scroll-down": "shift_down"
}
},
"backlight": {
"device": "acpi_video0",
"format": "<span font='10'> {percent}%</span> {icon}",
"format-icons": ["", ""]
},
"cpu": {
"format": "{}% "
},
"memory": {
"format": "{}% "
},
"idle_inhibitor": {
"format": "{icon} ",
"format-icons": {
"activated": "",
"deactivated": ""
}
},
"battery": {
"tooltip": false,
"states": {
"critical": 25
},
//"full-at": 84,
"format": "{icon}<span font='10'> {capacity}%</span>",
"format-full": "{icon}",
"format-icons": ["", "", "", "", ""],
},
"network": {
"interval": 3,
"tooltip": true,
//"interface": "wlp4s0", // (Optional) To force the use of this interface   \uF2E7,
"format-wifi": "<span font='10'></span> \uf062 {bandwidthUpBits} | \uf063 {bandwidthDownBits}",
"format-ethernet": "<span font='10'></span> \uf062 {bandwidthUpBits} | \uf063 {bandwidthDownBits}",
"format-disconnected": "",
"tooltip-format-wifi": "{essid} ({signalStrength}%)  {ipaddr}",
"tooltip-format-ethernet": "{ifname}  {ipaddr}"
},
//\ue04f{volume}%
"pulseaudio": {
"tooltip": false,
"format": "<span font='10'>{volume}%</span> {icon}",
"format-bluetooth": "{volume}% <span font='10'>{icon}</span>",
"format-muted": "",
"on-click": "pavucontrol",
"format-alt": "{volume}% <span font='10'>{icon}</span>",
"format-icons": {
"headphones": "",
"handsfree": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["","", ""]
}
},
"mpd": {
"format": "{artist} - {title} <span color=\"#999999\">[<span color=\"#ffffff\">{elapsedTime:%M:%S}</span> / {totalTime:%M:%S}]</span>",
"format-disconnected": "",
"format-stopped": "",
"interval": 1,
"state-icons": {
"paused": "",
"playing": ""
},
"tooltip-format": "MPD (connected)",
"tooltip-format-disconnected": "MPD (disconnected)"
},
"custom/notification": {
"tooltip": false,
"format": " {icon}",
"format-icons": {
"notification": "<span foreground='red'><sup></sup></span>",
"none": "",
"dnd-notification": "<span foreground='red'><sup></sup></span>",
"dnd-none": ""
},
"return-type": "json",
"exec-if": "which swaync-client",
"exec": "swaync-client -swb",
"on-click": "swaync-client -t -sw",
"on-click-right": "swaync-client -d -sw",
"escape": true
},
}

View File

@ -0,0 +1,80 @@
@import "./colorscheme.css";
window#waybar {
font-family: Hack, FontAwesome;
font-weight: 500;
font-size: 14px;
/*background: rgba(11, 12, 13, 0.90);*/
background-color: rgba(0, 0, 0, 0);
border-bottom: 1px solid rgba(0, 0, 2, 0.53);
color: @base04;
}
window#waybar.hidden {
opacity: 0.2;
}
#workspaces button {
font-size: 14px;
box-shadow: none;
text-shadow: none;
padding: 0px 3px 0px 3px;
color: @base04;
}
#workspaces button.focused {
color: #f85e84;
color: @base07;
/* margin: 2px 0px 2px 0px; */
}
#workspaces button:hover {
background: rgba(255, 255, 255, 0.00);
/* margin: 2px 0px 2px 0px; */
}
#clock, #backlight, #battery, #cpu, #memory, #network, #pulseaudio, #custom-spotify, #tray, #mode {
font-size: 14px;
margin: 0px 10px 0px 5px;
}
#pulseaudio {
/* border-top: 1px solid transparent; */
font-size: 12px;
margin-left: 15px;
}
#battery {
font-size: 12px;
}
#battery.critical {
color: @base07;
}
#battery.charging {
color: @base0B;
}
#battery.full {
margin: 0px 0px 0px 0px;
}
#network {
border-top: 1px solid transparent;
color: rgba(255,255,255,0.3);
}
#network.disconnected {
margin: 0px 0px 0px 0px;
color: rgba(75, 81, 98, 0);
}
#pulseaudio.muted {
margin: 0px 0px 0px 0px;
color: rgba(75, 81, 98, 0);
}
#custom-notification {
font-family: "NotoSansMono Nerd Font";
}

View File

@ -0,0 +1,8 @@
! Swap Caps_Lock and Control_L
!
remove Lock = Caps_Lock
remove Control = Control_L
!keysym Control_L = Caps_Lock
keysym Caps_Lock = Control_L
add Lock = Caps_Lock
add Control = Control_L

View File

@ -0,0 +1,18 @@
Gtk/ButtonImages 1
Gtk/CanChangeAccels 1
Gtk/CursorThemeName "default"
Gtk/CursorThemeSize 0
Gtk/EnableEventSounds 0
Gtk/EnableInputFeedbackSounds 0
Gtk/FontName "Lato"
Gtk/ThemeName "Matcha-dark-aliz"
Gtk/IconThemeName "Papirus-Adapta-Nokto-Maia"
Gtk/MenuBarAccel "F10"
Gtk/MenuImages 1
Gtk/ToolbarIconSize 3
Gtk/ToolbarStyle "icons"
Xft/Antialias 1
Xft/DPI 102400
Xft/Hinting 1
Xft/HintStyle "hintslight"
Xft/RGBA "rgb"

View File

@ -0,0 +1,75 @@
#!/bin/sh
#
# ~/.xinitrc
#
# Executed by startx (run your window manager from here)
userresources=$HOME/.Xresources
usermodmap=$HOME/.config/xmodmap
sysresources=/etc/X11/xinit/.Xresources
sysmodmap=/etc/X11/xinit/.Xmodmap
DEFAULT_SESSION='i3 --shmlog-size 0'
xset -b
if [ -d $HOME/.fonts ]; then
xset +fp $HOME/.fonts
xset fp rehash
fi
# merge in defaults and keymaps
if [ -f $sysresources ]; then
xrdb -merge $sysresources
fi
if [ -f $sysmodmap ]; then
xmodmap $sysmodmap
fi
if [ -f "$userresources" ]; then
xrdb -merge "$userresources"
fi
if [ -f "$usermodmap" ]; then
xmodmap "$usermodmap"
fi
# start some nice programs
if [ -d /etc/X11/xinit/xinitrc.d ] ; then
for f in /etc/X11/xinit/xinitrc.d/?*.sh ; do
[ -x "$f" ] && . "$f"
done
unset f
fi
get_session(){
local dbus_args=(--sh-syntax --exit-with-session)
case $1 in
awesome) dbus_args+=(awesome) ;;
bspwm) dbus_args+=(bspwm-session) ;;
budgie) dbus_args+=(budgie-desktop) ;;
cinnamon) dbus_args+=(cinnamon-session) ;;
deepin) dbus_args+=(startdde) ;;
enlightenment) dbus_args+=(enlightenment_start) ;;
fluxbox) dbus_args+=(startfluxbox) ;;
gnome) dbus_args+=(gnome-session) ;;
i3|i3wm) dbus_args+=(i3 --shmlog-size 0) ;;
jwm) dbus_args+=(jwm) ;;
kde) dbus_args+=(startkde) ;;
lxde) dbus_args+=(startlxde) ;;
lxqt) dbus_args+=(lxqt-session) ;;
mate) dbus_args+=(mate-session) ;;
xfce) dbus_args+=(xfce4-session) ;;
openbox) dbus_args+=(openbox-session) ;;
*) dbus_args+=($DEFAULT_SESSION) ;;
esac
echo "dbus-launch ${dbus_args[*]}"
}
exec $(get_session)
xset r rate 660 25

View File

@ -0,0 +1,271 @@
{
env = {
TERM = "xterm-256color";
};
window = {
# Window dimensions in character columns and lines
# Falls back to size specified by window manager if set to 0x0.
# (changes require restart)
dimensions = {
columns = 80;
lines = 24;
};
padding = {
x = 0;
y = 0;
};
decorations = "full";
};
scrolling = {
# How many lines of scrollback to keep,
# "0" will disable scrolling.
history = 100000;
# Number of lines the viewport will move for every line
# scrolled when scrollback is enabled (history > 0).
multiplier = 3;
};
# When true, bold text is drawn using the bright variant of colors.
draw_bold_text_with_bright_colors = true;
font = {
# The normal (roman) font face to use.
normal = {
family = "Hack"; # should be "Menlo" or something on macOS.
# Style can be specified to pick a specific face.
style = "Regular";
};
# The bold font face
bold = {
family = "Hack"; # should be "Menlo" or something on macOS.
# Style can be specified to pick a specific face.
style = "Bold";
};
# The italic font face
italic = {
family = "Hack"; # should be "Menlo" or something on macOS.
# Style can be specified to pick a specific face.
style = "Italic";
};
size = 12.0;
offset = {
x = 0;
y = 0;
};
glyph_offset = {
x = 0;
y = 0;
};
};
key_bindings = [
{
key = "V";
mods = "Control|Super";
action = "Paste";
}
{
key = "C";
mods = "Control|Super";
action = "Copy";
}
{
key = "V";
mods = "Control|Alt";
action = "Paste";
}
{
key = "C";
mods = "Control|Alt";
action = "Copy";
}
{
key = "Paste";
action = "Paste";
}
{
key = "Copy";
action = "Copy";
}
{
key = "Q";
mods = "Command";
action = "Quit";
}
{
key = "W";
mods = "Command";
action = "Quit";
}
{
key = "Insert";
mods = "Shift";
action = "PasteSelection";
}
{
key = "Key0";
mods = "Control";
action = "ResetFontSize";
}
{
key = "Equals";
mods = "Control";
action = "IncreaseFontSize";
}
{
key = "PageUp";
mods = "Shift";
action = "ScrollPageUp";
}
{
key = "PageDown";
mods = "Shift";
action = "ScrollPageDown";
}
{
key = "Minus";
mods = "Control";
action = "DecreaseFontSize";
}
{
key = "H";
mode = "Vi|~Search";
action = "ScrollToBottom";
}
{
key = "H";
mode = "Vi|~Search";
action = "ToggleViMode";
}
{
key = "I";
mode = "Vi|~Search";
action = "Up";
}
{
key = "K";
mode = "Vi|~Search";
action = "Down";
}
{
key = "J";
mode = "Vi|~Search";
action = "Left";
}
{
key = "L";
mode = "Vi|~Search";
action = "Right";
}
];
# Base16 Burn 256 - alacritty color config
# Benjamin Bädorf
colors = {
# Default colors
primary = {
background = "0x1a181a";
foreground = "0xe3e1e4";
};
# Cursor colors
#
# Colors which should be used to draw the terminal cursor.
#
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
cursor = {
text = "CellBackground";
cursor = "CellForeground";
};
# Colors used for the search bar and match highlighting.
search = {
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
matches = {
foreground = "0xe5c463";
background = "0x1a181a";
};
focused_match = {
foreground = "CellBackground";
background = "CellForeground";
};
#bar =
# background = "#c5c8c6";
# foreground = "#1d1f21";
};
# Selection colors
#
# Colors which should be used to draw the selection area.
#
# Allowed values are CellForeground/CellBackground, which reference the
# affected cell, or hexadecimal colors like #ff00ff.
selection = {
text = "0x1a181a";
background = "0xf85e84";
};
# Normal colors
normal = {
black = "0x1a181a";
red = "0xf85e84";
green = "0x9ecd6f";
yellow = "0xe5c463";
blue = "0x7accd7";
magenta = "0xab9df2";
cyan = "0xef9062";
white = "0xe3e1e4";
};
# Bright colors
bright = {
black = "0x949494";
red = "0xf85e84";
green = "0x9ecd6f";
yellow = "0xe5c463";
blue = "0x7accd7";
magenta = "0xab9df2";
cyan = "0xef9062";
white = "0xff5f5f";
};
indexed_colors = [
{
index = 16;
color = "0xdf5923";
}
{
index = 17;
color = "0xd70000";
}
{
index = 18;
color = "0x2d2a2e";
}
{
index = 19;
color = "0x303030";
}
{
index = 20;
color = "0xd3d1d4";
}
{
index = 21;
color = "0x303030";
}
];
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@ -0,0 +1,166 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
yamlFormat = pkgs.formats.yaml {};
sessionVariables = {
WLR_RENDERER =
if psCfg.graphical.wayland.software-renderer.enable
then "pixman"
else "gles2";
# Fix KeepassXC rendering issue
# https://github.com/void-linux/void-packages/issues/23517
QT_AUTO_SCREEN_SCALE_FACTOR = "0";
};
in {
imports = [
./sway
];
options.pub-solar.graphical = {
wayland.software-renderer.enable = mkOption {
type = types.bool;
default = false;
description = "Feature flag enabling wlroots software renderer, useful in VMs";
};
};
config = {
hardware.opengl.enable = true;
environment = {
systemPackages = with pkgs; [
gtk-engine-murrine
gtk_engines
gsettings-desktop-schemas
matcha-gtk-theme
papirus-maia-icon-theme
glib
xdg-utils
];
etc = {
"xdg/PubSolar.conf".text = ''
[Qt]
style=GTK+
'';
};
variables = sessionVariables;
};
services.getty.autologinUser = psCfg.user.name;
qt = {
enable = true;
platformTheme = "gtk2";
style = "gtk2";
};
services.udev.packages = with pkgs; [gnome3.gnome-settings-daemon];
# Enable Sushi, a quick previewer for nautilus
services.gnome.sushi.enable = true;
# Enable GVfs, a userspace virtual filesystem
services.gvfs.enable = true;
services.yubikey-agent.enable = true;
fonts = {
packages = with pkgs; [
dejavu_fonts
powerline-fonts
];
enableDefaultPackages = true;
fontconfig.enable = true;
fontconfig.defaultFonts = {
monospace = ["DejaVu Sans Mono for Powerline"];
sansSerif = ["DejaVu Sans"];
};
};
users.users."${psCfg.user.name}".packages = with pkgs; [
alacritty
firefox-wayland
flameshot
gnome.adwaita-icon-theme
gnome.eog
gnome.nautilus
gnome.seahorse
gnome.yelp
hicolor-icon-theme
keepassxc
qMasterPassword-wayland
libnotify
vlc
];
home-manager.users."${psCfg.user.name}" = {
home.file."xinitrc".source = ./.xinitrc;
xdg.configFile."alacritty/alacritty.yml".source = yamlFormat.generate "alacritty.yml" (import ./alacritty.nix);
xdg.configFile."xmodmap".source = ./.config/xmodmap;
xdg.configFile."user-dirs.dirs".source = ./.config/user-dirs.dirs;
xdg.configFile."user-dirs.locale".source = ./.config/user-dirs.locale;
xdg.configFile."xsettingsd/xsettingsd.conf".source = ./.config/xsettingsd/xsettingsd.conf;
xdg.configFile."mako/config".source = ./.config/mako/config;
xdg.configFile."libinput-gestures.conf".source = ./.config/libinput-gestures.conf;
xdg.configFile."swaync/config.json".source = ./.config/swaync/config.json;
xdg.configFile."swaync/style.css".source = ./.config/swaync/style.css;
xdg.configFile."waybar/config".source = ./.config/waybar/config;
xdg.configFile."waybar/style.css".source = ./.config/waybar/style.css;
xdg.configFile."waybar/colorscheme.css".source = ./.config/waybar/colorscheme.css;
xdg.configFile."wallpaper.jpg".source = ./assets/wallpaper.jpg;
# Required for running Gnome apps outside the Gnome DE, see
# https://nixos.wiki/wiki/GNOME#Running_GNOME_programs_outside_of_GNOME
dconf = {
enable = true;
settings = {
"org/gnome/desktop/interface" = {
color-scheme = "prefer-dark";
};
};
};
gtk = {
enable = true;
font.name = "Lato";
iconTheme = {
package = pkgs.papirus-icon-theme;
name = "Papirus-Adapta-Nokto-Maia";
};
theme = {
package = pkgs.matcha-gtk-theme;
name = "Matcha-dark-aliz";
};
gtk3.extraConfig = {
gtk-xft-antialias = "1";
gtk-xft-hinting = "1";
gtk-xft-hintstyle = "hintfull";
gtk-xft-rgba = "rgb";
gtk-application-prefer-dark-theme = "true";
};
gtk4.extraConfig = {
gtk-xft-antialias = "1";
gtk-xft-hinting = "1";
gtk-xft-hintstyle = "hintfull";
gtk-xft-rgba = "rgb";
gtk-application-prefer-dark-theme = "true";
};
};
xresources.extraConfig = builtins.readFile ./.Xdefaults;
systemd.user.services.network-manager-applet = import ./network-manager-applet.service.nix pkgs;
home.sessionVariables = sessionVariables;
systemd.user.sessionVariables = sessionVariables;
};
};
}

View File

@ -0,0 +1,15 @@
pkgs: {
Unit = {
Description = "Network Manager applet";
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
# ConditionEnvironment requires systemd v247 to work correctly
ConditionEnvironment = ["WAYLAND_DISPLAY"];
};
Service = {
ExecStart = "${pkgs.networkmanagerapplet}/bin/nm-applet --sm-disable --indicator";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,78 @@
# switch to workspace with urgent window automatically
for_window [urgent=latest] focus
for_window [app_id="keepassxc"] floating disable
assign [app_id="keepassxc"] $ws8
for_window [app_id="virt-manager"] floating disable
assign [app_id="virt-manager"] $ws9
assign [instance="element"] $ws4
assign [app_id="Signal"] $ws4
assign [app_id="telegramdesktop"] $ws4
# Launcher
for_window [app_id="launcher" title="Alacritty"] floating enable, border pixel 10, sticky enable
for_window [app_id="pavucontrol"] floating enable, border pixel 10, sticky enable
# Floating menus
for_window [app_id="blueman-manager"] floating enable
# Open specific applications in floating mode
for_window [title="alsamixer"] floating enable border pixel 1
for_window [class="Calamares"] floating enable border normal
for_window [class="Clipgrab"] floating enable
for_window [title="File Transfer*"] floating enable
for_window [class="Galculator"] floating enable border pixel 1
for_window [class="GParted"] floating enable border normal
for_window [title="i3_help"] floating enable sticky enable border normal
for_window [class="Lightdm-gtk-greeter-settings"] floating enable
for_window [class="Lxappearance"] floating enable sticky enable border normal
for_window [class="Manjaro-hello"] floating enable
for_window [class="Manjaro Settings Manager"] floating enable border normal
for_window [title="MuseScore: Play Panel"] floating enable
for_window [class="Nitrogen"] floating enable sticky enable border normal
for_window [class="Oblogout"] fullscreen enable
for_window [class="octopi"] floating enable
for_window [title="About Pale Moon"] floating enable
for_window [class="Pamac-manager"] floating enable
for_window [class="Pavucontrol"] floating enable
for_window [class="qt5ct"] floating enable sticky enable border normal
for_window [class="Qtconfig-qt4"] floating enable sticky enable border normal
for_window [class="Simple-scan"] floating enable border normal
for_window [class="(?i)System-config-printer.py"] floating enable border normal
for_window [class="Skype"] floating enable border normal
for_window [class="Thus"] floating enable border normal
for_window [class="Timeset-gui"] floating enable border normal
for_window [class="(?i)virtualbox"] floating enable border normal
for_window [class="Xfburn"] floating enable
for_window [class="^VirtualBox Machine$" title="Running"] floating disable
for_window [class="^rdesktop" title="rdesktop"] floating disable
# firefox floating menus
for_window [window_role="pop-up"] floating enable
for_window [window_role="task_dialog"] floating enable
for_window [window_role="pop-up"] floating enable
for_window [window_role="bubble"] floating enable
for_window [window_role="task_dialog"] floating enable
for_window [window_role="Preferences"] floating enable
for_window [window_type="dialog"] floating enable
for_window [window_type="menu"] floating enable
for_window [title="About Mozilla Firefox"] floating enable
for_window [title="Password Required - Mozilla Firefox"] floating enable
for_window [title="Extension: (Open in Browser)*"] floating enable
# Technical media stuff happens on ws7
for_window [app_id="screen-recorder" title="Alacritty"] move to workspace $ws7, floating disable
no_focus [app_id="screen-recorder"]
for_window [title="Firefox — Sharing Indicator"] move to workspace $ws7, floating disable
no_focus [title="Firefox — Sharing Indicator"]
# qMasterPassword floating menu
for_window [title="qMasterPassword"] focus
for_window [title="qMasterPassword"] floating enable
# vimpc floating instance
for_window [app_id="mu_vimpc"] focus
for_window [app_id="mu_vimpc"] floating enable, border pixel 10, sticky enable

View File

@ -0,0 +1,19 @@
## Base16 Burn
# Author: Benjamin Bädorf
set $base00 #1a181a
set $base01 #2d2a2e
set $base02 #303030
set $base03 #949494
set $base04 #d3d1d4
set $base05 #e3e1e4
set $base06 #303030
set $base07 #ff5f5f
set $base08 #f85e84
set $base09 #df5923
set $base0A #e5c463
set $base0B #9ecd6f
set $base0C #ef9062
set $base0D #7accd7
set $base0E #ab9df2
set $base0F #d70000

View File

@ -0,0 +1,47 @@
# launch categorized menu
bindsym $mod+z exec --no-startup-id morc_menu
# switch keyboard input language
#bindsym $mod+tab exec toggle-kbd-layout
################################################################################################
## sound-section - ##
################################################################################################
bindsym $mod+Ctrl+m exec pavucontrol
################################################################################################
# Quickstart application shortcuts
bindsym $mod+F1 exec psos help
bindsym $mod+Shift+h exec psos help
bindsym $mod+F2 exec firefox
bindsym $mod+F4 exec nautilus -w
bindsym $mod+Shift+F4 exec signal-desktop --use-tray-icon
# Notifications with swaynotificationcenter
# Toggle control center
bindsym $mod+Shift+n exec swaync-client -t -sw
bindsym $mod+Shift+m exec qMasterPassword
# Screenshots and screen recordings
bindsym $mod+Ctrl+p exec grim -g "$(slurp -d -b \#ffffff11)" ~/Pictures/Screenshots/$(date +%Y%m%d_%Hh%Mm%Ss)_grim.png
bindsym $mod+Shift+p exec grim ~/Pictures/Screenshots/$(date +%Y%m%d_%Hh%Mm%Ss)_grim.png
bindsym $mod+Ctrl+f exec "( pkill flameshot || true && flameshot & ) && ( sleep 0.5s && flameshot gui )"
bindsym $mod+Ctrl+r exec record-screen
# Launcher
set $menu exec alacritty --class launcher -e env TERMINAL_COMMAND="alacritty -e" sway-launcher
bindsym $mod+Space exec $menu
set $mode_vncclient In VNCClient mode. Press $mod+Num_Lock or $mod+Shift+Escape to return.
bindsym $mod+Num_Lock mode "$mode_vncclient"
bindsym $mod+Shift+Escape mode "$mode_vncclient"
mode "$mode_vncclient" {
bindsym $mod+Num_Lock mode "default"
bindsym $mod+Shift+Escape mode "default"
}

View File

@ -0,0 +1,53 @@
# Set inner/outer gaps
gaps inner 10
gaps outer -5
# Additionally, you can issue commands with the following syntax. This is useful to bind keys to changing the gap size.
# gaps inner|outer current|all set|plus|minus <px>
# gaps inner all set 10
# gaps outer all plus 5
# Smart gaps (gaps used if only more than one container on the workspace)
smart_gaps on
# Smart borders (draw borders around container only if it is not the only container on this workspace)
# on|no_gaps (on=always activate and no_gaps=only activate if the gap size to the edge of the screen is 0)
smart_borders on
# Press $mod+Shift+g to enter the gap mode. Choose o or i for modifying outer/inner gaps. Press one of + / - (in-/decrement for current workspace) or 0 (remove gaps for current workspace). If you also press Shift with these keys, the change will be global for all workspaces.
set $mode_gaps Gaps: (o) outer, (i) inner
set $mode_gaps_outer Outer Gaps: +|-|0 (local), Shift + +|-|0 (global)
set $mode_gaps_inner Inner Gaps: +|-|0 (local), Shift + +|-|0 (global)
bindsym $mod+Shift+g mode "$mode_gaps"
mode "$mode_gaps" {
bindsym o mode "$mode_gaps_outer"
bindsym i mode "$mode_gaps_inner"
bindsym Return mode "default"
bindsym Escape mode "default"
}
mode "$mode_gaps_inner" {
bindsym plus gaps inner current plus 5
bindsym minus gaps inner current minus 5
bindsym 0 gaps inner current set 0
bindsym Shift+plus gaps inner all plus 5
bindsym Shift+minus gaps inner all minus 5
bindsym Shift+0 gaps inner all set 0
bindsym Return mode "default"
bindsym Escape mode "default"
}
mode "$mode_gaps_outer" {
bindsym plus gaps outer current plus 5
bindsym minus gaps outer current minus 5
bindsym 0 gaps outer current set 0
bindsym Shift+plus gaps outer all plus 5
bindsym Shift+minus gaps outer all minus 5
bindsym Shift+0 gaps outer all set 0
bindsym Return mode "default"
bindsym Escape mode "default"
}

View File

@ -0,0 +1,41 @@
{
pkgs,
psCfg,
...
}:
''
# Set shut down, restart and locking features
''
+ (
if psCfg.core.hibernation.enable
then ''
set $mode_system (e)xit, (h)ibernate, (l)ock, (s)uspend, (r)eboot, (Shift+s)hutdown
''
else ''
set $mode_system (e)xit, (l)ock, (s)uspend, (r)eboot, (Shift+s)hutdown
''
)
+ ''
bindsym $mod+0 mode "$mode_system"
mode "$mode_system" {
bindsym e exec swaymsg exit, mode "default"
''
+ (
if psCfg.core.hibernation.enable
then ''
bindsym h exec systemctl hibernate, mode "default"
''
else ""
)
+ ''
bindsym l exec ${pkgs.swaylock-bg}/bin/swaylock-bg, mode "default"
bindsym s exec systemctl suspend, mode "default"
bindsym r exec systemctl reboot, mode "default"
bindsym Shift+s exec systemctl poweroff, mode "default"
# exit system mode: "Enter" or "Escape"
bindsym Return mode "default"
bindsym Escape mode "default"
}
''

View File

@ -0,0 +1,8 @@
# Note that the systemctl commands must be run synchronously and can't be split into
# three exec statements, since otherwise the session target may be started before
# systemctl import-environment is complete, and services that require certain variables
# will fail to run.
# https://github.com/swaywm/sway/wiki/Systemd-integration
# Also, import the most important environment variables into the D-Bus and systemd
# user environments (e.g. required for screen sharing and Pinentry prompts):
exec "systemctl --user import-environment; systemctl --user start sway-session.target; exec dbus-update-activation-environment --systemd $IMPORT_ENVIRONMENT_ENV_LIST DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP; systemd-cat --identifier=sway sway"

View File

@ -0,0 +1,16 @@
# Border BG Text Ind Child Border
client.focused $base00 $base01 $base07 $base0D $base07
client.focused_inactive $base00 $base01 $base07 $base03 $base00
client.unfocused $base00 $base00 $base04 $base06 $base00
client.urgent $base00 $base0F $base00 $base08 $base00
client.background $base00
# Read the gtk settings from gtk setting.ini and pass them to gsettings
exec_always import-gtk-settings \
gtk-theme:gtk-theme-name \
icon-theme:gtk-icon-theme-name \
cursor-theme:gtk-cursor-theme-name
# Workaround to fix cursor scaling, see https://github.com/swaywm/sway/issues/4112
seat seat0 xcursor_theme Adwaita

View File

@ -0,0 +1,217 @@
{
config,
pkgs,
...
}: ''
# Default config for sway
#
# Copy this to ~/.config/sway/config and edit it to your liking.
#
# Read `man 5 sway` for a complete reference.
### Variables
#
# Logo key. Use Mod1 for Alt.
set $mod Mod4
# Home row direction keys, like vim
set $left j
set $down k
set $up i
set $right l
# Your preferred terminal emulator
set $term ${pkgs.alacritty}/bin/alacritty
# Your preferred application launcher
# Note: pass the final command to swaymsg so that the resulting window can be opened
# on the original workspace that the command was run on.
#set $menu dmenu_path | dmenu | xargs swaymsg exec bemenu-run --no-overlap
default_border pixel 1
### Output configuration
#
# Default wallpaper (more resolutions are available in @datadir@/backgrounds/sway/)
output * bg ~/.config/wallpaper.jpg fill
### Key bindings
#
# Basics:
#
# Start a terminal
bindsym $mod+Return exec $term
# Start a terminal
bindsym $mod+Shift+Return exec sh -c '$term --working-directory $(wcwd)'
# Kill focused window
bindsym $mod+Shift+q kill
# Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod.
# Despite the name, also works for non-floating windows.
# Change normal to inverse to use left mouse button for resizing and right
# mouse button for dragging.
floating_modifier $mod normal
# Reload the configuration file
bindsym $mod+F5 reload
#
# Moving around:
#
# Move your focus around
bindsym $mod+$left focus left
bindsym $mod+$down focus down
bindsym $mod+$up focus up
bindsym $mod+$right focus right
# Or use $mod+[up|down|left|right]
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
# Move the focused window with the same, but add Shift
bindsym $mod+Shift+$left move left
bindsym $mod+Shift+$down move down
bindsym $mod+Shift+$up move up
bindsym $mod+Shift+$right move right
# Ditto, with arrow keys
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
#
# Workspaces:
#
# Workspace names
# to display names or symbols instead of plain workspace numbers you can use
# something like: set $ws1 1:mail
# set $ws2 2:
set $ws1 1
set $ws2 2
set $ws3 3
set $ws4 4
set $ws5 5
set $ws6 6
set $ws7 7
set $ws8 8
set $ws9 9
# Switch to workspace
bindsym $mod+1 workspace 1
bindsym $mod+2 workspace 2
bindsym $mod+3 workspace 3
bindsym $mod+4 workspace 4
bindsym $mod+5 workspace 5
bindsym $mod+6 workspace 6
bindsym $mod+7 workspace 7
bindsym $mod+8 workspace 8
bindsym $mod+9 workspace 9
# Move focused container to workspace
bindsym $mod+Ctrl+1 move container to workspace $ws1
bindsym $mod+Ctrl+2 move container to workspace $ws2
bindsym $mod+Ctrl+3 move container to workspace $ws3
bindsym $mod+Ctrl+4 move container to workspace $ws4
bindsym $mod+Ctrl+5 move container to workspace $ws5
bindsym $mod+Ctrl+6 move container to workspace $ws6
bindsym $mod+Ctrl+7 move container to workspace $ws7
bindsym $mod+Ctrl+8 move container to workspace $ws8
bindsym $mod+Ctrl+9 move container to workspace $ws9
# Move focused container to workspace and move focus with it
bindsym $mod+Shift+1 move container to workspace 1; workspace $ws1
bindsym $mod+Shift+2 move container to workspace 2; workspace $ws2
bindsym $mod+Shift+3 move container to workspace 3; workspace $ws3
bindsym $mod+Shift+4 move container to workspace 4; workspace $ws4
bindsym $mod+Shift+5 move container to workspace 5; workspace $ws5
bindsym $mod+Shift+6 move container to workspace 6; workspace $ws6
bindsym $mod+Shift+7 move container to workspace 7; workspace $ws7
bindsym $mod+Shift+8 move container to workspace 8; workspace $ws8
bindsym $mod+Shift+9 move container to workspace 9; workspace $ws9
# Note: workspaces can have any name you want, not just numbers.
# We just use 1-10 as the default.
#navigate workspaces next / previous
bindsym $mod+Ctrl+Right workspace next
bindsym $mod+Ctrl+Left workspace prev
# workspace back and forth (with/without active container)
workspace_auto_back_and_forth yes
bindsym $mod+b workspace back_and_forth
bindsym $mod+Shift+b move container to workspace back_and_forth; workspace back_and_forth
#
# Layout stuff:
#
# Configure border style <normal|1pixel|pixel xx|none|pixel>
default_border pixel 1
default_floating_border normal
# Hide borders
hide_edge_borders none
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
font xft:Hack 16
# You can "split" the current object of your focus with
# $mod+b or $mod+v, for horizontal and vertical splits
# respectively.
bindsym $mod+h splith; exec notify-send 'tile horizontally'
bindsym $mod+v splitv; exec notify-send 'tile vertically'
# Switch the current container between different layout styles
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# Make the current focus fullscreen
bindsym $mod+f fullscreen
# Toggle the current focus between tiling and floating mode
bindsym $mod+Shift+space floating toggle
# Swap focus between the tiling area and the floating area
bindsym $mod+t focus mode_toggle
# Move focus to the parent container
bindsym $mod+a focus parent
bindsym $mod+d focus child
#
# Scratchpad:
#
# Sway has a "scratchpad", which is a bag of holding for windows.
# You can send windows there and get them back later.
# Move the currently focused window to the scratchpad
bindsym $mod+Shift+minus move scratchpad
# Show the next scratchpad window or hide the focused scratchpad window.
# If there are multiple scratchpad windows, this command cycles through them.
bindsym $mod+minus scratchpad show
#
# Resizing containers:
#
mode "resize" {
# left will shrink the containers width
# right will grow the containers width
# up will shrink the containers height
# down will grow the containers height
bindsym $left resize shrink width 10px
bindsym $down resize grow height 10px
bindsym $up resize shrink height 10px
bindsym $right resize grow width 10px
# Ditto, with arrow keys
bindsym Left resize shrink width 10px
bindsym Down resize grow height 10px
bindsym Up resize shrink height 10px
bindsym Right resize grow width 10px
# Return to default mode
bindsym Return mode "default"
bindsym Escape mode "default"
}
bindsym $mod+r mode "resize"
include ~/.config/sway/config.d/*''

View File

@ -0,0 +1,11 @@
{
psCfg,
pkgs,
}: "
address=0.0.0.0
enable_auth=true
username=${psCfg.user.name}
password=testtest
private_key_file=/run/agenix/vnc-key.pem
certificate_file=/run/agenix/vnc-cert.pem
"

View File

@ -0,0 +1,101 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
options.pub-solar.graphical = {
v4l2loopback.enable = mkOption {
type = types.bool;
default = false;
description = "WebCam streaming tool";
};
};
config = {
boot = mkIf psCfg.graphical.v4l2loopback.enable {
extraModulePackages = with config.boot.kernelPackages; [v4l2loopback];
kernelModules = ["v4l2loopback"];
extraModprobeConfig = ''
options v4l2loopback exclusive_caps=1 devices=3
'';
};
environment.systemPackages = with pkgs;
mkIf psCfg.graphical.v4l2loopback.enable [
linuxPackages.v4l2loopback
];
programs.sway.enable = true;
xdg.portal = {
enable = true;
wlr = {
enable = true;
settings = {
screencast = {
max_fps = 30;
chooser_type = "simple";
chooser_cmd = "${pkgs.slurp}/bin/slurp -f %o -or";
};
};
};
extraPortals = with pkgs; [xdg-desktop-portal-gtk];
};
services.pipewire.enable = true;
users.users."${psCfg.user.name}".packages = with pkgs; [
sway
grim
kanshi
slurp
swaybg
swayidle
swaynotificationcenter
xwayland
libappindicator-gtk3
wl-clipboard
wf-recorder
brightnessctl
gammastep
geoclue2
xsettingsd
ydotool
sway-launcher
record-screen
import-gtk-settings
# Unused on teutat3s hosts, see custom-keybindings.conf
#toggle-kbd-layout
s
wcwd
];
home-manager.users."${psCfg.user.name}" = {
programs.waybar.enable = true;
#programs.waybar.systemd.enable = true;
systemd.user.services.swaynotificationcenter = import ./swaynotificationcenter.service.nix pkgs;
systemd.user.services.sway = import ./sway.service.nix {inherit pkgs psCfg;};
systemd.user.services.swayidle = import ./swayidle.service.nix {inherit pkgs psCfg;};
systemd.user.services.xsettingsd = import ./xsettingsd.service.nix {inherit pkgs psCfg;};
systemd.user.services.waybar = import ./waybar.service.nix {inherit pkgs psCfg;};
systemd.user.targets.sway-session = import ./sway-session.target.nix {inherit pkgs psCfg;};
xdg.configFile."sway/config".text = import ./config/config.nix {inherit config pkgs;};
xdg.configFile."sway/config.d/colorscheme.conf".source = ./config/config.d/colorscheme.conf;
xdg.configFile."sway/config.d/theme.conf".source = ./config/config.d/theme.conf;
xdg.configFile."sway/config.d/gaps.conf".source = ./config/config.d/gaps.conf;
xdg.configFile."sway/config.d/custom-keybindings.conf".source = ./config/config.d/custom-keybindings.conf;
xdg.configFile."sway/config.d/mode_system.conf".text = import ./config/config.d/mode_system.conf.nix {inherit pkgs psCfg;};
xdg.configFile."sway/config.d/applications.conf".source = ./config/config.d/applications.conf;
xdg.configFile."sway/config.d/systemd.conf".source = ./config/config.d/systemd.conf;
};
};
}

View File

@ -0,0 +1,17 @@
{pkgs, ...}: {
Unit = {
Description = "set color temperature of display according to time of day";
Documentation = ["man:gammastep(1)"];
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
# ConditionEnvironment requires systemd v247 to work correctly
ConditionEnvironment = ["WAYLAND_DISPLAY"];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.gammastep}/bin/gammastep -l geoclue2 -m wayland -v";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,18 @@
{pkgs, ...}: {
Unit = {
Description = "Actions gestures on your touchpad using libinput";
Documentation = ["https://github.com/bulletmark/libinput-gestures"];
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.libinput-gestures}/bin/libinput-gestures";
Restart = "on-failure";
RestartSec = "1";
TimeoutStopSec = "10";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,18 @@
{pkgs, ...}: {
Unit = {
Description = "Lightweight Wayland notification daemon";
Documentation = ["man:mako(1)"];
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
ConditionEnvironment = ["WAYLAND_DISPLAY"];
};
Service = {
Type = "dbus";
BusName = "org.freedesktop.Notifications";
ExecStart = "${pkgs.mako}/bin/mako";
ExecReload = "${pkgs.mako}/bin/makoctl reload";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,9 @@
{pkgs, ...}: {
Unit = {
Description = "sway compositor session";
Documentation = ["man:systemd.special(7)"];
BindsTo = ["graphical-session.target"];
Wants = ["graphical-session-pre.target"];
After = ["graphical-session-pre.target"];
};
}

View File

@ -0,0 +1,17 @@
{pkgs, ...}: {
Unit = {
Description = "sway - SirCmpwn's Wayland window manager";
Documentation = ["man:sway(5)"];
BindsTo = ["graphical-session.target"];
Wants = ["graphical-session-pre.target"];
After = ["graphical-session-pre.target"];
};
Service = {
Type = "simple";
ExecStartPre = "${pkgs.systemd}/bin/systemctl --user unset-environment WAYLAND_DISPLAY DISPLAY";
ExecStart = "${pkgs.sway}/bin/sway";
Restart = "on-failure";
RestartSec = "1";
TimeoutStopSec = "10";
};
}

View File

@ -0,0 +1,26 @@
{
pkgs,
psCfg,
...
}: {
Unit = {
Description = "Idle manager for Wayland";
Documentation = ["man:swayidle(1)"];
BindsTo = ["graphical-session.target"];
Wants = ["graphical-session-pre.target"];
After = ["graphical-session-pre.target"];
};
Service = {
Type = "simple";
ExecStart = ''
${pkgs.swayidle}/bin/swayidle -w \
timeout 300 '${pkgs.swaylock-bg}/bin/swaylock-bg' \
timeout 600 '${pkgs.sway}/bin/swaymsg "output * dpms off"' \
resume '${pkgs.sway}/bin/swaymsg "output * dpms on"' \
before-sleep '${pkgs.swaylock-bg}/bin/swaylock-bg'
'';
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,21 @@
pkgs: {
Unit = {
Description = "Swaync notification daemon";
Documentation = "https://github.com/ErikReider/SwayNotificationCenter";
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
Requisite = ["graphical-session.target"];
# ConditionEnvironment requires systemd v247 to work correctly
ConditionEnvironment = ["WAYLAND_DISPLAY"];
};
Service = {
Type = "dbus";
BusName = "org.freedesktop.Notifications";
ExecStart = "${pkgs.swaynotificationcenter}/bin/swaync";
ExecReload = "${pkgs.swaynotificationcenter}/bin/swaync-client --reload-config ; ${pkgs.swaynotificationcenter}/bin/swaync-client --reload-css";
Restart = "on-failure";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,21 @@
{pkgs, ...}: {
Unit = {
Description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
Documentation = "https://github.com/Alexays/Waybar/wiki/";
BindsTo = ["sway-session.target"];
After = ["sway-session.target" "network-online.target"];
Wants = ["graphical-session-pre.target" "network-online.target" "blueman-applet.service"];
ConditionEnvironment = ["WAYLAND_DISPLAY"];
};
Service = {
Type = "dbus";
Environment = "PATH=${pkgs.bash}/bin:${pkgs.pavucontrol}/bin";
BusName = "fr.arouillard.waybar";
ExecStart = "${pkgs.waybar}/bin/waybar";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,18 @@
{pkgs, ...}: {
Unit = {
Description = "X Settings Daemon";
Documentation = ["https://github.com/derat/xsettingsd/wiki/Installation"];
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
# ConditionEnvironment requires systemd v247 to work correctly
ConditionEnvironment = ["WAYLAND_DISPLAY"];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.xsettingsd}/bin/xsettingsd";
ExecStop = "/run/current-system/sw/bin/env pkill xsettingsd";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,18 @@
{pkgs, ...}: {
Unit = {
Description = "ydotool - Generic command-line automation tool (no X!)";
Documentation = ["https://github.com/ReimuNotMoe/ydotool"];
BindsTo = ["sway-session.target"];
After = ["sway-session.target"];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.ydotool}/bin/ydotoold";
Restart = "on-failure";
RestartSec = "1";
TimeoutStopSec = "10";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

View File

@ -0,0 +1,11 @@
{config, ...}: {
home-manager.sharedModules = [
{
home.sessionVariables = {
inherit (config.environment.sessionVariables) NIX_PATH;
};
xdg.configFile."nix/registry.json".text =
config.environment.etc."nix/registry.json".text;
}
];
}

View File

@ -0,0 +1,377 @@
{
config,
pkgs,
lib,
...
}:
with lib; let
cfg = config.services.invoiceplane;
eachSite = cfg.sites;
user = "invoiceplane";
webserver = config.services.${cfg.webserver};
invoiceplane-config = hostName: cfg:
pkgs.writeText "ipconfig.php" ''
IP_URL=http://${hostName}
ENABLE_DEBUG=false
DISABLE_SETUP=false
REMOVE_INDEXPHP=false
DB_HOSTNAME=${cfg.database.host}
DB_USERNAME=${cfg.database.user}
# NOTE: file_get_contents adds newline at the end of returned string
DB_PASSWORD=${
if cfg.database.passwordFile == null
then ""
else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"
}
DB_DATABASE=${cfg.database.name}
DB_PORT=${toString cfg.database.port}
SESS_EXPIRATION=864000
ENABLE_INVOICE_DELETION=false
DISABLE_READ_ONLY=false
ENCRYPTION_KEY=
ENCRYPTION_CIPHER=AES-256
SETUP_COMPLETED=false
REMOVE_INDEXPHP=true
'';
extraConfig = hostName: cfg:
pkgs.writeText "extraConfig.php" ''
${toString cfg.extraConfig}
'';
pkg = hostName: cfg:
pkgs.stdenv.mkDerivation rec {
pname = "invoiceplane-${hostName}";
version = src.version;
src = pkgs.invoiceplane;
postPhase = ''
# Patch index.php file to load additional config file
substituteInPlace index.php \
--replace "require('vendor/autoload.php');" "require('vendor/autoload.php'); \$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, 'extraConfig.php'); \$dotenv->load();";
'';
installPhase = ''
mkdir -p $out
cp -r * $out/
# symlink uploads and log directories
rm -r $out/uploads $out/application/logs $out/vendor/mpdf/mpdf/tmp
ln -sf ${cfg.stateDir}/uploads $out/
ln -sf ${cfg.stateDir}/logs $out/application/
ln -sf ${cfg.stateDir}/tmp $out/vendor/mpdf/mpdf/
# symlink the InvoicePlane config
ln -s ${cfg.stateDir}/ipconfig.php $out/ipconfig.php
# symlink the extraConfig file
ln -s ${extraConfig hostName cfg} $out/extraConfig.php
# symlink additional templates
${concatMapStringsSep "\n" (template: "cp -r ${template}/. $out/application/views/invoice_templates/pdf/") cfg.invoiceTemplates}
'';
};
siteOpts = {
lib,
name,
...
}: {
options = {
enable = mkEnableOption (lib.mdDoc "InvoicePlane web application");
stateDir = mkOption {
type = types.path;
default = "/var/lib/invoiceplane/${name}";
description = lib.mdDoc ''
This directory is used for uploads of attachments and cache.
The directory passed here is automatically created and permissions
adjusted as required.
'';
};
database = {
host = mkOption {
type = types.str;
default = "localhost";
description = lib.mdDoc "Database host address.";
};
port = mkOption {
type = types.port;
default = 3306;
description = lib.mdDoc "Database host port.";
};
name = mkOption {
type = types.str;
default = "invoiceplane";
description = lib.mdDoc "Database name.";
};
user = mkOption {
type = types.str;
default = "invoiceplane";
description = lib.mdDoc "Database user.";
};
passwordFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/keys/invoiceplane-dbpassword";
description = lib.mdDoc ''
A file containing the password corresponding to
{option}`database.user`.
'';
};
createLocally = mkOption {
type = types.bool;
default = true;
description = lib.mdDoc "Create the database and database user locally.";
};
};
invoiceTemplates = mkOption {
type = types.listOf types.path;
default = [];
description = lib.mdDoc ''
List of path(s) to respective template(s) which are copied from the 'invoice_templates/pdf' directory.
::: {.note}
These templates need to be packaged before use, see example.
:::
'';
example = literalExpression ''
let
# Let's package an example template
template-vtdirektmarketing = pkgs.stdenv.mkDerivation {
name = "vtdirektmarketing";
# Download the template from a public repository
src = pkgs.fetchgit {
url = "https://git.project-insanity.org/onny/invoiceplane-vtdirektmarketing.git";
sha256 = "1hh0q7wzsh8v8x03i82p6qrgbxr4v5fb05xylyrpp975l8axyg2z";
};
sourceRoot = ".";
# Installing simply means copying template php file to the output directory
installPhase = ""
mkdir -p $out
cp invoiceplane-vtdirektmarketing/vtdirektmarketing.php $out/
"";
};
# And then pass this package to the template list like this:
in [ template-vtdirektmarketing ]
'';
};
poolConfig = mkOption {
type = with types; attrsOf (oneOf [str int bool]);
default = {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"pm.max_requests" = 500;
};
description = lib.mdDoc ''
Options for the InvoicePlane PHP pool. See the documentation on `php-fpm.conf`
for details on configuration directives.
'';
};
extraConfig = mkOption {
type = types.nullOr types.lines;
default = null;
example = ''
SETUP_COMPLETED=true
DISABLE_SETUP=true
IP_URL=https://invoice.example.com
'';
description = lib.mdDoc ''
InvoicePlane configuration. Refer to
<https://github.com/InvoicePlane/InvoicePlane/blob/master/ipconfig.php.example>
for details on supported values.
'';
};
cron = {
enable = mkOption {
type = types.bool;
default = false;
description = lib.mdDoc ''
Enable cron service which periodically runs Invoiceplane tasks.
Requires key taken from the administration page. Refer to
<https://wiki.invoiceplane.com/en/1.0/modules/recurring-invoices>
on how to configure it.
'';
};
key = mkOption {
type = types.str;
description = lib.mdDoc "Cron key taken from the administration page.";
};
};
};
};
in {
disabledModules = [
"services/web-apps/invoiceplane.nix"
];
# interface
options = {
services.invoiceplane = mkOption {
type = types.submodule {
options.sites = mkOption {
type = types.attrsOf (types.submodule siteOpts);
default = {};
description = lib.mdDoc "Specification of one or more WordPress sites to serve";
};
options.webserver = mkOption {
type = types.enum ["caddy"];
default = "caddy";
description = lib.mdDoc ''
Which webserver to use for virtual host management. Currently only
caddy is supported.
'';
};
};
default = {};
description = lib.mdDoc "InvoicePlane configuration.";
};
};
# implementation
config = mkIf (eachSite != {}) (mkMerge [
{
assertions = flatten (mapAttrsToList (hostName: cfg: [
{
assertion = cfg.database.createLocally -> cfg.database.user == user;
message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
}
{
assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
message = ''services.invoiceplane.sites."${hostName}".database.passwordFile cannot be specified if services.invoiceplane.sites."${hostName}".database.createLocally is set to true.'';
}
{
assertion = cfg.cron.enable -> cfg.cron.key != null;
message = ''services.invoiceplane.sites."${hostName}".cron.key must be set in order to use cron service.'';
}
])
eachSite);
services.mysql = mkIf (any (v: v.database.createLocally) (attrValues eachSite)) {
enable = true;
package = mkDefault pkgs.mariadb;
ensureDatabases = mapAttrsToList (hostName: cfg: cfg.database.name) eachSite;
ensureUsers =
mapAttrsToList (
hostName: cfg: {
name = cfg.database.user;
ensurePermissions = {"${cfg.database.name}.*" = "ALL PRIVILEGES";};
}
)
eachSite;
};
services.phpfpm = {
phpPackage = pkgs.php81;
pools =
mapAttrs' (hostName: cfg: (
nameValuePair "invoiceplane-${hostName}" {
inherit user;
group = webserver.group;
settings =
{
"listen.owner" = webserver.user;
"listen.group" = webserver.group;
}
// cfg.poolConfig;
}
))
eachSite;
};
}
{
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
"d ${cfg.stateDir} 0750 ${user} ${webserver.group} - -"
"f ${cfg.stateDir}/ipconfig.php 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/logs 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/uploads 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/uploads/archive 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/uploads/customer_files 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/uploads/temp 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/uploads/temp/mpdf 0750 ${user} ${webserver.group} - -"
"d ${cfg.stateDir}/tmp 0750 ${user} ${webserver.group} - -"
])
eachSite);
systemd.services.invoiceplane-config = {
serviceConfig.Type = "oneshot";
script = concatStrings (mapAttrsToList (hostName: cfg: ''
mkdir -p ${cfg.stateDir}/logs \
${cfg.stateDir}/uploads
if ! grep -q IP_URL "${cfg.stateDir}/ipconfig.php"; then
cp "${invoiceplane-config hostName cfg}" "${cfg.stateDir}/ipconfig.php"
fi
'')
eachSite);
wantedBy = ["multi-user.target"];
};
users.users.${user} = {
group = webserver.group;
isSystemUser = true;
};
}
{
# Cron service implementation
systemd.timers =
mapAttrs' (hostName: cfg: (
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "5m";
OnUnitActiveSec = "5m";
Unit = "invoiceplane-cron-${hostName}.service";
};
})
))
eachSite;
systemd.services =
mapAttrs' (hostName: cfg: (
nameValuePair "invoiceplane-cron-${hostName}" (mkIf cfg.cron.enable {
serviceConfig = {
Type = "oneshot";
User = user;
ExecStart = "${pkgs.curl}/bin/curl --header 'Host: ${hostName}' http://localhost/invoices/cron/recur/${cfg.cron.key}";
};
})
))
eachSite;
}
(mkIf (cfg.webserver == "caddy") {
services.caddy = {
enable = true;
virtualHosts =
mapAttrs' (hostName: cfg: (
nameValuePair "http://${hostName}" {
extraConfig = ''
root * ${pkg hostName cfg}
file_server
php_fastcgi unix/${config.services.phpfpm.pools."invoiceplane-${hostName}".socket}
'';
}
))
eachSite;
};
})
]);
}

View File

@ -0,0 +1,13 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
home-manager.users."${psCfg.user.name}" = {
systemd.user.services.nextcloud-client = import ./nextcloud.service.nix pkgs;
};
}

View File

@ -0,0 +1,20 @@
pkgs: {
Unit = {
Description = "Nextcloud Client";
BindsTo = ["sway-session.target"];
Wants = ["graphical-session-pre.target"];
After = ["graphical-session-pre.target"];
# ConditionEnvironment requires systemd v247 to work correctly
ConditionEnvironment = ["WAYLAND_DISPLAY"];
};
Service = {
Type = "simple";
ExecStart = "${pkgs.nextcloud-client}/bin/nextcloud --background";
ExecReload = "/run/current-system/sw/bin/kill -HUP $MAINPID";
KillMode = "process";
Restart = "on-failure";
};
Install = {
WantedBy = ["sway-session.target"];
};
}

65
modules/nix/default.nix Normal file
View File

@ -0,0 +1,65 @@
{
config,
pkgs,
lib,
flake,
...
}: {
nixpkgs.config.allowUnfreePredicate = pkg:
builtins.elem (lib.getName pkg) [
"1password"
"1password-cli"
"cups-brother-hl3140cw"
"facetimehd-firmware"
"slack"
"veracrypt"
"zoom"
];
nix = {
# Use default version alias for nix package
package = pkgs.nix;
gc.automatic = true;
optimise.automatic = true;
registry = {
nixpkgs.flake = flake.inputs.nixpkgs;
unstable.flake = flake.inputs.unstable;
system.flake = flake.self;
};
settings = {
# Improve nix store disk usage
auto-optimise-store = true;
# Prevents impurities in builds
sandbox = true;
# Give root and @wheel special privileges with nix
trusted-users = ["root" "@wheel"];
# Allow only group wheel to connect to the nix daemon
allowed-users = ["@wheel"];
substituters = [
"https://pub-solar.cachix.org/"
];
trusted-public-keys = [
"pub-solar.cachix.org-1:ZicXIxKgdxMtgSJECWR8iihZxHRvu8ObL4n2cuBmtos="
];
};
# Generally useful nix option defaults
extraOptions = lib.mkForce ''
experimental-features = flakes nix-command
min-free = 536870912
keep-outputs = true
keep-derivations = true
fallback = true
'';
nixPath = [
"nixpkgs=${flake.inputs.nixpkgs}"
"nixos-config=${../../lib/compat/nixos}"
"home-manager=${flake.inputs.home-manager}"
];
};
}

View File

@ -0,0 +1,20 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
in {
programs.evince.enable = true;
users.users."${psCfg.user.name}".packages = with pkgs; [
libreoffice-fresh
gnome.simple-scan
# Tools like pdfunite
poppler_utils
# tool for annotating PDFs
xournalpp
];
}

View File

@ -0,0 +1,40 @@
{
flake,
config,
pkgs,
lib,
...
}: {
services.avahi.enable = true;
services.avahi.ipv6 = true;
services.avahi.nssmdns = true;
services.avahi.publish.enable = true;
services.avahi.publish.userServices = true;
services.printing.enable = true;
services.printing.browsing = true;
services.printing.listenAddresses = ["localhost:631"];
services.printing.defaultShared = lib.mkDefault false;
services.printing.drivers =
[
pkgs.gutenprint
]
++ (
if (pkgs.system == "x86_64-linux")
then [pkgs.cups-brother-hl3140cw]
else []
);
networking.hosts = flake.self.lib.addLocalHostname ["cups.local"];
services.caddy = {
enable = true;
extraConfig = ''
cups.local {
request_header Host localhost:631
reverse_proxy unix//run/cups/cups.sock
}
'';
};
}

View File

@ -0,0 +1,47 @@
{
config,
pkgs,
...
}: let
user = config.pub-solar.user;
xdg = config.home-manager.users."${user.name}".xdg;
in '' [user]
${
if user.email != null
then "email = ${user.email}"
else ""
}
${
if user.fullName != null
then "name = ${user.fullName}"
else ""
}
${
if user.gpgKeyId != null
then "signingkey = ${user.gpgKeyId}"
else ""
}
[core]
editor = /etc/profiles/per-user/${config.pub-solar.user.name}/bin/nvim
excludesFile = /home/${config.pub-solar.user.name}/.config/git/global_gitignore
[alias]
pol = pull
ack = -c color.grep.linenumber=\"bold yellow\"\n -c color.grep.filename=\"bold green\"\n -c color.grep.match=\"reverse yellow\"\n grep --break --heading --line-number
# define command which will be used when "nvim"is set as a merge tool
[mergetool]
prompt = false
[merge]
tool = nvim
[mergetool "nvim"]
cmd = /etc/profiles/per-user/${config.pub-solar.user.name}/bin/nvim -f -c \"Gdiffsplit!\" \"$MERGED\"
[commit]
gpgsign = true
template = ${xdg.configHome}/git/gitmessage
[tag]
gpgsign = true
[init]
defaultBranch = main
[pull]
rebase = false''

View File

@ -0,0 +1,32 @@
{
config,
pkgs,
...
}: let
user = config.pub-solar.user;
xdg = config.home-manager.users."${user.name}".xdg;
in ''
# What happened?
#
# fix feat build chore ci docs style refactor perf test
#
# type!(optional scope): <summary> --------------#
#
# ^\n
# What exactly was done and why? --------------------------------------#
#
# ^\n
#
# Any issue numbers or links?
#
# Ref: #123
# ^\n
#
# Co-authored-by: Example Name <email@example.com>
''

View File

@ -0,0 +1,6 @@
{
config,
pkgs,
...
}: let
in ''tags''

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,126 @@
#!/bin/sh
# base16-shell (https://github.com/chriskempson/base16-shell)
# Base16 Shell template by Chris Kempson (http://chriskempson.com)
# Burn scheme by Benjamin Bädorf
color00="1a/18/1a" # Base 00 - Black
color01="f8/5e/84" # Base 08 - Red
color02="9e/cd/6f" # Base 0B - Green
color03="e5/c4/63" # Base 0A - Yellow
color04="7a/cc/d7" # Base 0D - Blue
color05="ab/9d/f2" # Base 0E - Magenta
color06="ef/90/62" # Base 0C - Cyan
color07="e3/e1/e4" # Base 05 - White
color08="94/94/94" # Base 03 - Bright Black
color09=$color01 # Base 08 - Bright Red
color10=$color02 # Base 0B - Bright Green
color11=$color03 # Base 0A - Bright Yellow
color12=$color04 # Base 0D - Bright Blue
color13=$color05 # Base 0E - Bright Magenta
color14=$color06 # Base 0C - Bright Cyan
color15="ff/5f/5f" # Base 07 - Bright White
color16="df/59/23" # Base 09
color17="d7/00/00" # Base 0F
color18="2d/2a/2e" # Base 01
color19="30/30/30" # Base 02
color20="d3/d1/d4" # Base 04
color21="30/30/30" # Base 06
color_foreground="e3/e1/e4" # Base 05
color_background="1a/18/1a" # Base 00
if [ -n "$TMUX" ]; then
# Tell tmux to pass the escape sequences through
# (Source: http://permalink.gmane.org/gmane.comp.terminal-emulators.tmux.user/1324)
put_template() { printf '\033Ptmux;\033\033]4;%d;rgb:%s\033\033\\\033\\' $@; }
put_template_var() { printf '\033Ptmux;\033\033]%d;rgb:%s\033\033\\\033\\' $@; }
put_template_custom() { printf '\033Ptmux;\033\033]%s%s\033\033\\\033\\' $@; }
elif [ "${TERM%%[-.]*}" = "screen" ]; then
# GNU screen (screen, screen-256color, screen-256color-bce)
put_template() { printf '\033P\033]4;%d;rgb:%s\007\033\\' $@; }
put_template_var() { printf '\033P\033]%d;rgb:%s\007\033\\' $@; }
put_template_custom() { printf '\033P\033]%s%s\007\033\\' $@; }
elif [ "${TERM%%-*}" = "linux" ]; then
put_template() { [ $1 -lt 16 ] && printf "\e]P%x%s" $1 $(echo $2 | sed 's/\///g'); }
put_template_var() { true; }
put_template_custom() { true; }
else
put_template() { printf '\033]4;%d;rgb:%s\033\\' $@; }
put_template_var() { printf '\033]%d;rgb:%s\033\\' $@; }
put_template_custom() { printf '\033]%s%s\033\\' $@; }
fi
# 16 color space
put_template 0 $color00
put_template 1 $color01
put_template 2 $color02
put_template 3 $color03
put_template 4 $color04
put_template 5 $color05
put_template 6 $color06
put_template 7 $color07
put_template 8 $color08
put_template 9 $color09
put_template 10 $color10
put_template 11 $color11
put_template 12 $color12
put_template 13 $color13
put_template 14 $color14
put_template 15 $color15
# 256 color space
put_template 16 $color16
put_template 17 $color17
put_template 18 $color18
put_template 19 $color19
put_template 20 $color20
put_template 21 $color21
# foreground / background / cursor color
if [ -n "$ITERM_SESSION_ID" ]; then
# iTerm2 proprietary escape codes
put_template_custom Pg e3e1e4 # foreground
put_template_custom Ph 1a181a # background
put_template_custom Pi e3e1e4 # bold color
put_template_custom Pj 303030 # selection color
put_template_custom Pk e3e1e4 # selected text color
put_template_custom Pl e3e1e4 # cursor
put_template_custom Pm 1a181a # cursor text
else
put_template_var 10 $color_foreground
if [ "$BASE16_SHELL_SET_BACKGROUND" != false ]; then
put_template_var 11 $color_background
if [ "${TERM%%-*}" = "rxvt" ]; then
put_template_var 708 $color_background # internal border (rxvt)
fi
fi
put_template_custom 12 ";7" # cursor (reverse video)
fi
# clean up
unset -f put_template
unset -f put_template_var
unset -f put_template_custom
unset color00
unset color01
unset color02
unset color03
unset color04
unset color05
unset color06
unset color07
unset color08
unset color09
unset color10
unset color11
unset color12
unset color13
unset color14
unset color15
unset color16
unset color17
unset color18
unset color19
unset color20
unset color21
unset color_foreground
unset color_background

View File

@ -0,0 +1,114 @@
{
config,
flake,
pkgs,
...
}: let
psCfg = config.pub-solar;
xdg = config.home-manager.users."${psCfg.user.name}".xdg;
in {
enable = true;
historyControl = ["ignorespace"];
# Run when initializing a login shell
profileExtra = ''
[ "$(tty)" = "/dev/tty1" ] && exec ${pkgs.sway-service}/bin/sway-service
'';
# Run when initializing an interactive shell
initExtra = ''
# Use fzf's CTRL-R history widget
source ${pkgs.fzf}/share/fzf/key-bindings.bash
# Show current directory at the top in Alacritty
PROMPT_COMMAND='echo -e -n "\e]2;$(basename "$PWD" | sed "s/${psCfg.user.name}/~/")\e\\"'
# If a command is not found, show me where it is
source ${pkgs.nix-index}/etc/profile.d/command-not-found.bash
# Helps you navigate directories faster
# https://github.com/gsamokovarov/jump
eval "$(${pkgs.jump}/bin/jump shell --bind=z)"
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
bind 'set show-all-if-ambiguous on'
# Syntax highlighting, auto suggestions, vim modes, etc.
# https://github.com/akinomyoga/ble.sh/wiki/Manual-A1-Installation#user-content-nixpkgs
source "$(blesh-share)"/ble.sh --attach=none
# ctrl + space to accept autocomplete suggestion
ble-bind -m 'auto_complete' -f 'C-@' 'auto_complete/insert-on-end'
# Meta (Alt) + Backspace to delete a word
ble-bind -m 'vi_imap' -f 'M-C-?' 'kill-backward-cword'
# Meta (Alt) + p to jump one word backwards
ble-bind -m 'vi_imap' -f M-p '@nomarked backward-uword'
ble-bind -m 'vi_imap' -f M-left '@nomarked backward-uword'
# Meta (Alt) + n to jump one word forwards
ble-bind -m 'vi_imap' -f M-n '@nomarked forward-uword'
ble-bind -m 'vi_imap' -f M-right '@nomarked forward-uword'
# Arrow up and Ctrl + p searches history for entered input
ble-bind -m 'vi_imap' -f up 'history-search-backward hide-status:immediate-accept:empty=emulate-readline:point=end'
ble-bind -m 'vi_imap' -f C-p 'history-search-backward hide-status:immediate-accept:empty=emulate-readline:point=end'
# Arrow down and Ctrl + n searches history for entered input
ble-bind -m 'vi_imap' -f down 'history-search-forward hide-status:immediate-accept:empty=emulate-readline:point=end'
ble-bind -m 'vi_imap' -f C-n 'history-search-forward hide-status:immediate-accept:empty=emulate-readline:point=end'
ble-face region_insert='fg=black,bg=navy'
function my/complete-load-hook {
bleopt complete_auto_delay=250
}
blehook/eval-after-load complete my/complete-load-hook
bleopt exec_elapsed_mark=
bleopt exec_errexit_mark=
bleopt filename_ls_colors="$LS_COLORS"
bleopt complete_menu_style=desc
# Bash vim mode keybindings
if [[ $- == *i* ]]; then # in interactive session
set -o vi
ble-bind -m vi_imap -f 'ENTER' 'vi_imap/complete'
ble-bind -m vi_imap -f 'TAB' 'vi_imap/complete'
ble-bind -m vi_imap -f 'j j' 'vi_imap/normal-mode'
ble-bind -m vi_imap -f 'ESC' 'vi_imap/normal-mode'
ble-bind -m vi_nmap -f 'h' 'vi_nmap/insert-mode'
ble-bind -m vi_nmap -f 'i' 'vi-command/backward-line'
ble-bind -m vi_nmap -f 'j' 'vi-command/backward-char'
ble-bind -m vi_nmap -f 'k' 'vi-command/forward-line'
ble-bind -m vi_nmap -f 'l' 'vi-command/forward-char'
ble-bind -m vi_imap -f 'C-c' discard-line
fi
# end of .bashrc
# Somehow we need to ensure starship starts later than ble.sh
# (possible packaging issue?)
# https://github.com/akinomyoga/ble.sh/issues/333
eval "$(${pkgs.starship}/bin/starship init bash)"
[[ ''${BLE_VERSION-} ]] && ble-attach
'';
shellAliases = {
nano = "nvim";
vi = "nvim";
vim = "nvim";
mutt = "neomutt";
ls = "eza";
la = "eza --group-directories-first -lag";
wget = "wget --hsts-file=$XDG_CACHE_HOME/wget-hsts";
irssi = "irssi --config=$XDG_CONFIG_HOME/irssi/config --home=$XDG_DATA_HOME/irssi";
drone = "DRONE_TOKEN=$(secret-tool lookup drone token) drone";
no = "manix \"\" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | fzf --preview=\"manix '{}'\" | xargs manix";
# fix nixos-option
nixos-option = "nixos-option -I nixpkgs=${flake.self}/lib/compat";
myip = "dig +short myip.opendns.com @208.67.222.222 2>&1";
nnn = "nnn -d -e -H -r";
};
}

View File

@ -0,0 +1,113 @@
{
lib,
config,
pkgs,
flake,
...
}:
with lib; let
psCfg = config.pub-solar;
cfg = config.pub-solar.terminal-life;
in {
options.pub-solar.terminal-life = {
full = mkOption {
description = ''
Enable a full version, which includes more nvim plugins and lsps.
'';
default = false;
type = types.bool;
};
};
config = {
programs.command-not-found.enable = false;
programs.nix-index.enable = true;
# We do this manually in modules/terminal-life/bash/default.nix
# until https://github.com/nix-community/nix-index/pull/227 is merged
programs.nix-index.enableBashIntegration = false;
users.users."${psCfg.user.name}".packages = with pkgs; [
ack
asciinema
bat
blesh
eza
fd
jump
(nnn.overrideAttrs (o: {
patches =
(o.patches or [])
++ [
./nnn/0001-feat-use-wasd-keybindings-for-jkli.patch
];
}))
powerline
screen
silver-searcher
watson
];
home-manager.users."${psCfg.user.name}" = {
xdg.dataFile."scripts/base16.sh".source = .local/share/scripts/base16.sh;
programs.less = {
enable = true;
keys = ''
k forw-line
i back-line
K forw-scroll
I back-scroll
'';
};
# Starship is a fast and featureful shell prompt
# starship.toml has sane defaults that can be changed there
programs.starship = {
enable = true;
settings = import ./starship.toml.nix;
};
programs.bash = import ./bash {
inherit config;
inherit pkgs;
inherit lib;
inherit flake;
};
programs.fzf = import ./fzf {
inherit config;
inherit pkgs;
};
programs.neovim = import ./nvim {
inherit config;
inherit pkgs;
inherit lib;
};
# Ensure nvim backup directory gets created
# Workaround for E510: Can't make backup file (add ! to override)
xdg.dataFile."nvim/backup/.keep".text = "";
xdg.dataFile."nvim/json-schemas/.keep".text = "";
# Generated with:
# docker run -it --name caddy-json-schema registry.greenbaum.cloud/gc/caddy-l4:2.5.2 caddy json-schema -output /srv/caddy_schema.json
xdg.dataFile."nvim/json-schemas/caddy_schema.json".source = .local/share/nvim/json-schemas/caddy_schema.json;
xdg.dataFile."nvim/templates/.keep".text = "";
programs.git = import ./git {};
xdg.configFile."git/config".text = import ./.config/git/config.nix {
inherit config;
inherit pkgs;
};
xdg.configFile."git/gitmessage".text = import ./.config/git/gitmessage.nix {
inherit config;
inherit pkgs;
};
xdg.configFile."git/global_gitignore".text = import ./.config/git/global_gitignore.nix {
inherit config;
inherit pkgs;
};
programs.direnv = import ./direnv {};
};
};
}

View File

@ -0,0 +1,6 @@
{...}: {
enable = true;
nix-direnv = {
enable = true;
};
}

View File

@ -0,0 +1,17 @@
{
config,
pkgs,
...
}: {
enable = true;
defaultCommand = "fd --hidden --type f --exclude .git";
defaultOptions = [
"--color=bg+:#2d2a2e,bg:#1a181a,spinner:#ef9062,hl:#7accd7"
"--color=fg:#d3d1d4,header:#7accd7,info:#e5c463,pointer:#ef9062"
"--color=marker:#ef9062,fg+:#303030,prompt:#e5c463,hl+:#7accd7"
];
# Use ble.sh for completions, see
# modules/terminal-life/bash/default.nix -> bleopt complete_menu_style=desc
# and https://github.com/akinomyoga/ble.sh/wiki/Manual-%C2%A77-Completion
enableBashIntegration = false;
}

View File

@ -0,0 +1,40 @@
{...}: {
enable = true;
extraConfig = {
pull.rebase = false;
};
aliases = {
a = "add -p";
co = "checkout";
cob = "checkout -b";
f = "fetch -p";
c = "commit";
p = "push";
ba = "branch -a";
bd = "branch -d";
bD = "branch -D";
d = "diff";
dc = "diff --cached";
ds = "diff --staged";
r = "restore";
rs = "restore --staged";
st = "status -sb";
# reset
soft = "reset --soft";
hard = "reset --hard";
s1ft = "soft HEAD~1";
h1rd = "hard HEAD~1";
# logging
lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog = "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog = "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
rank = "shortlog -sn --no-merges";
# delete merged branches
bdm = "!git branch --merged | grep -v '*' | xargs -n 1 git branch -d";
};
}

View File

@ -0,0 +1,38 @@
From a81ee68923412c0fb8fab46f2f918a7ec865b384 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Benjamin=20B=C3=A4dorf?= <hello@benjaminbaedorf.eu>
Date: Sun, 9 Jul 2023 04:19:51 +0200
Subject: [PATCH] feat: use wasd keybindings for jkli
---
src/nnn.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/nnn.h b/src/nnn.h
index d476ddd2..5f106987 100644
--- a/src/nnn.h
+++ b/src/nnn.h
@@ -131,7 +131,7 @@ struct key {
static struct key bindings[] = {
/* Back */
{ KEY_LEFT, SEL_BACK },
- { 'h', SEL_BACK },
+ { 'j', SEL_BACK },
/* Inside or select */
{ KEY_ENTER, SEL_OPEN },
{ '\r', SEL_OPEN },
@@ -139,10 +139,10 @@ static struct key bindings[] = {
{ KEY_RIGHT, SEL_NAV_IN },
{ 'l', SEL_NAV_IN },
/* Next */
- { 'j', SEL_NEXT },
+ { 'k', SEL_NEXT },
{ KEY_DOWN, SEL_NEXT },
/* Previous */
- { 'k', SEL_PREV },
+ { 'i', SEL_PREV },
{ KEY_UP, SEL_PREV },
/* Page down */
{ KEY_NPAGE, SEL_PGDN },
--
2.40.1

View File

@ -0,0 +1,20 @@
" Wayland clipboard provider that strips carriage returns (GTK3 issue).
" This is needed because currently there's an issue where GTK3 applications on
" Wayland contain carriage returns at the end of the lines (this is a root
" issue that needs to be fixed).
let g:clipboard = {
\ 'name': 'wayland-strip-carriage',
\ 'copy': {
\ '+': 'wl-copy --foreground --type text/plain --trim-newline',
\ '*': 'wl-copy --foreground --type text/plain --primary --trim-newline',
\ },
\ 'paste': {
\ '+': {-> systemlist('wl-paste --no-newline | tr -d "\r"')},
\ '*': {-> systemlist('wl-paste --no-newline --primary | tr -d "\r"')},
\ },
\ 'cache_enabled': 1,
\ }
" Copy filenames
nnor <leader>yfp :let @+=expand("%:p")<CR> " Mnemonic: Yank File path
nnor <leader>yfn :let @+=expand("%")<CR> " Mnemonic: Yank File name

View File

@ -0,0 +1,199 @@
{
config,
pkgs,
lib,
...
}: let
psCfg = config.pub-solar;
cfg = config.pub-solar.terminal-life;
xdg = config.home-manager.users."${psCfg.user.name}".xdg;
preview-file = pkgs.writeShellScriptBin "preview-file" (import ./preview-file.nix pkgs);
in {
enable = true;
viAlias = true;
vimAlias = true;
vimdiffAlias = true;
withNodeJs = true;
withRuby = true;
withPython3 = true;
extraPackages = with pkgs;
lib.mkIf (cfg.full) [
ansible-language-server
ccls
gopls
nixd
nodejs
nodePackages.bash-language-server
nodePackages.dockerfile-language-server-nodejs
nodePackages.svelte-language-server
nodePackages.typescript
nodePackages.typescript-language-server
nodePackages.vim-language-server
nodePackages.vue-language-server
nodePackages.vscode-langservers-extracted
nodePackages.yaml-language-server
python3Packages.python-lsp-server
python3Full
rust-analyzer
solargraph
terraform-ls
universal-ctags
];
plugins = with pkgs.vimPlugins;
lib.mkIf cfg.full [
(pkgs.vimPlugins.nvim-treesitter.withPlugins (p: [
p.ini
p.json
p.json5
p.markdown
p.nix
p.toml
p.yaml
p.css
p.graphql
p.html
p.javascript
p.scss
p.tsx
p.typescript
p.vue
p.c
p.cpp
p.go
p.gomod
p.gosum
p.haskell
p.lua
p.php
p.python
p.ruby
p.rust
p.vim
p.vimdoc
p.passwd
p.sql
p.diff
p.gitcommit
p.gitignore
p.git_config
p.gitattributes
p.git_rebase
p.bash
p.dockerfile
p.make
p.ninja
p.terraform
]))
# Dependencies for nvim-lspconfig
nvim-cmp
cmp-nvim-lsp
cmp_luasnip
luasnip
# Quickstart configs for neovim LSP
lsp_extensions-nvim
nvim-lspconfig
# Collaborative editing in Neovim using built-in capabilities
instant-nvim-nvfetcher
# Search functionality behind :Ack
ack-vim
# The status bar in the bottom of the screen with the mode indication and file location
vim-airline
# Automatically load editorconfig files in repos to configure nvim settings
editorconfig-vim
# File browser. Use <leader>n to access
nnn-vim
# Highlight characters when using f, F, t, and T
quick-scope
# Get sudo in vim; :SudaWrite <optional filename>
suda-vim
# Undo history etc. per project
vim-workspace-nvfetcher
# JSON schemas
SchemaStore-nvim
# Work with tags files
vim-gutentags
# Neovim colorschemes / themes
sonokai
vim-hybrid-material
vim-airline-themes
vim-apprentice-nvfetcher
# Git integrations
# A Git wrapper so awesome, it should be illegal
fugitive
# Shows git diff markers in the sign column
vim-gitgutter
# GitHub extension for fugitive
vim-rhubarb
# Ease your git workflow within Vim
vimagit-nvfetcher
# FZF fuzzy finder
fzf-vim
fzfWrapper
# Make the yanked region apparent
vim-highlightedyank
# :Beautify Code beautifier
vim-beautify-nvfetcher
# Unload, delete or wipe a buffer without closing the window
vim-bufkill
# Defaults everyone can agree on
vim-sensible
# emmet for vim: http://emmet.io/
emmet-vim
# Caddyfile syntax support for Vim
vim-caddyfile-nvfetcher
# Fix TOFU hashes when writing nix derivations without leaving neovim
vim-nixhash
];
extraConfig = builtins.concatStringsSep "\n" [
''
" Persistent undo
set undofile
set undodir=${xdg.cacheHome}/nvim/undo
set backupdir=${xdg.dataHome}/nvim/backup
set directory=${xdg.dataHome}/nvim/swap/
''
(builtins.readFile ./init.vim)
(builtins.readFile ./plugins.vim)
(builtins.readFile ./clipboard.vim)
(builtins.readFile ./ui.vim)
(builtins.readFile ./quickfixopenall.vim)
(builtins.readFile ./lsp.vim)
''
" fzf with file preview
command! -bang -nargs=? -complete=dir Files
\ call fzf#vim#files(<q-args>, { 'options': ['--keep-right', '--cycle', '--layout', 'reverse', '--preview', '${preview-file}/bin/preview-file {}'] }, <bang>0)
''
];
}

View File

@ -0,0 +1,108 @@
set nocompatible " be iMproved, required
filetype indent plugin on " required
set modeline
set modelines=1
set nowrap
set viminfo='100,<100,s20 " vim file history
set hidden
set expandtab
set shiftwidth=2
set number
set relativenumber
set mouse=
set autoindent
set smartindent
set undolevels=1000
set undoreload=10000
set updatetime=300
let mapleader = " "
nmap <c-s> :w<CR>
imap <c-s> <Esc>:w<CR>
vmap <c-s> <Esc><c-s>gv
noremap <leader>y "+y
noremap <leader>p "+p
noremap i <Up>
noremap j <Left>
noremap k <Down>
noremap h i
vnoremap K L
vnoremap I H
vnoremap H I
nnoremap K L
nnoremap I H
nnoremap H I
map <c-w>i :wincmd k<CR>
map <c-w>j :wincmd h<CR>
map <c-w>k :wincmd j<CR>
map <c-w>l :wincmd l<CR>
map <c-w>I :wincmd K<CR>
map <c-w>J :wincmd H<CR>
map <c-w>K :wincmd J<CR>
map <c-w>L :wincmd L<CR>
" replay macro for each line of a visual selection
xnoremap @q :normal @q<CR>
xnoremap @@ :normal @@<CR>
" reselect and re-yank any text that is pasted in visual mode
xnoremap p pgvy
" Escape overwrite
inoremap jj <Esc>
" Open new buffer
nmap <leader>T :enew<cr>
" Move to the next buffer
nmap <leader>l :bnext<CR>
" Move to the previous buffer
nmap <leader>j :bprevious<CR>
" Close the current buffer and move to the previous one
" This replicates the idea of closing a tab
nmap <leader>q :bp <BAR> bd #<CR>
" Show all open buffers and their status
nmap <leader>bl :ls<CR>
" Mapping selecting mappings
nmap <leader><tab> <plug>(fzf-maps-n)
xmap <leader><tab> <plug>(fzf-maps-x)
omap <leader><tab> <plug>(fzf-maps-o)
nmap <c-p> :Files<CR>
imap <c-p> <ESC>:Files<CR>
" Insert mode completion
imap <c-x><c-k> <plug>(fzf-complete-word)
imap <c-x><c-f> <plug>(fzf-complete-path)
imap <c-x><c-j> <plug>(fzf-complete-file)
imap <c-x><c-l> <plug>(fzf-complete-line)
" Clear quickfix shortcut
nmap <Leader>c :ccl<CR>
" Remember cursor position
" Vim jumps to the last position when reopening a file
if has("autocmd")
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif
nmap - :NnnPicker %<CR>
nmap <leader>n :NnnPicker %<CR>
nmap <leader>N :NnnPicker<CR>

View File

@ -0,0 +1,258 @@
" Set completeopt to have a better completion experience
" :help completeopt
" menuone: popup even when there's only one match
" noinsert: Do not insert text until a selection is made
" noselect: Do not select, force user to select one from the menu
set completeopt=menuone,noinsert,noselect
" Avoid showing extra messages when using completion
set shortmess+=c
function AddTemplate(tmpl_file)
exe "0read " . a:tmpl_file
set nomodified
6
endfunction
autocmd BufNewFile shell.nix call AddTemplate("$XDG_DATA_HOME/nvim/templates/shell.nix.tmpl")
" Configure neovim 0.6+ experimental LSPs
" https://github.com/neovim/nvim-lspconfig
" https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
" https://github.com/neovim/nvim-lspconfig/wiki/UI-Customization
" https://gitlab.com/Iron_E/dotfiles/-/blob/master/.config/nvim/lua/_config/plugin/nvim_lsp.lua
lua <<EOF
local nvim_lsp = require('lspconfig')
-- Mappings (global)
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
local opts = { noremap=true, silent=true }
vim.api.nvim_set_keymap('n', '<leader>e', '<cmd>lua vim.diagnostic.open_float()<CR>', opts)
vim.api.nvim_set_keymap('n', 'g[', '<cmd>lua vim.diagnostic.goto_prev()<CR>', opts)
vim.api.nvim_set_keymap('n', 'g]', '<cmd>lua vim.diagnostic.goto_next()<CR>', opts)
vim.api.nvim_set_keymap('n', '<leader>dq', '<cmd>lua vim.diagnostic.setloclist()<CR>', opts)
vim.api.nvim_set_keymap('n', '<leader>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)
-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
-- Enable completion triggered by <c-x><c-o>
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
-- Mappings (available if LSP is configured and attached to buffer)
-- See `:help vim.lsp.*` for documentation on any of the below functions
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<leader>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
-- Show diagnostic popup on cursor hold
vim.api.nvim_create_autocmd("CursorHold", {
buffer = bufnr,
callback = function()
local opts = {
focusable = false,
close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
border = 'rounded',
source = 'always',
prefix = ' ',
scope = 'cursor',
}
vim.diagnostic.open_float(nil, opts)
end
})
end
-- Add additional capabilities supported by nvim-cmp
local capabilities = require('cmp_nvim_lsp').default_capabilities()
-- vscode HTML lsp needs this https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#html
capabilities.textDocument.completion.completionItem.snippetSupport = true
-- vscode HTML lsp needs this https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#html
capabilities.textDocument.completion.completionItem.snippetSupport = true
local use_denols_for_typescript = not(os.getenv('NVIM_USE_DENOLS') == nil)
for lsp_key, lsp_settings in pairs({
'ansiblels', ---------------------------- Ansible
'bashls', ------------------------------- Bash
'ccls', --------------------------------- C / C++ / Objective-C
'cssls', -------------------------------- CSS / SCSS / LESS
'dockerls', ----------------------------- Docker
['gopls'] = { --------------------------- Go
['settings'] = {
['gopls'] = {
['analyses'] = {
['unusedparams'] = true,
},
['staticcheck'] = true
},
},
},
'html', --------------------------------- HTML
['jdtls'] = { --------------------------- Java
['root_dir'] = nvim_lsp.util.root_pattern('.git', 'pom.xml', 'build.xml'),
['init_options'] = {
['jvm_args'] = {['java.format.settings.url'] = vim.fn.stdpath('config')..'/eclipse-formatter.xml'},
['workspace'] = vim.fn.stdpath('cache')..'/java-workspaces'
}
},
['jsonls'] = { -------------------------- JSON
['settings'] = {
['json'] = {
['schemas' ] = vim.list_extend(
{
{
['description'] = 'JSON schema for Caddy v2',
['fileMatch'] = { '*caddy*.json' },
['name'] = 'caddy_schema.json',
['url'] = vim.fn.stdpath('data')..'/json-schemas/caddy_schema.json',
},
},
require('schemastore').json.schemas()
),
['validate'] = { ['enable'] = true }
}
}
},
'nixd', --------------------------------- Nix
'phpactor', ----------------------------- PHP
'pylsp', -------------------------------- Python
'solargraph', --------------------------- Ruby
'rust_analyzer', ------------------------ Rust
['sqlls'] = {
['cmd'] = {vim.fn.stdpath('data')..'/nvm/versions/node/v12.19.0/bin/sql-language-server', 'up', '--method', 'stdio'}
},
['terraformls'] = { --------------------- Terraform
['filetypes'] = { 'terraform', 'hcl', 'tf' }
},
-- The TS/JS server is chosen depending on an environment variable,
-- since denols is nicer for Deno based projects
------------------------ Deno TS/JS
------------------------------------ Typescript / JavaScript
(use_denols_for_typescript and 'denols' or 'tsserver'),
'vuels', -------------------------------- Vue
'svelte', ------------------------------- Svelte
['yamlls'] = { -------------------------- YAML
['settings'] = {
['yaml'] = {
['schemas'] = {
['https://json.schemastore.org/github-workflow'] = '.github/workflows/*.{yml,yaml}',
['https://json.schemastore.org/github-action'] = '.github/action.{yml,yaml}',
['https://json.schemastore.org/drone'] = '*.drone.{yml,yaml}',
['https://json.schemastore.org/swagger-2.0'] = 'swagger.{yml,yaml}',
}
}
}
}
}) do -- Setup all of the language servers. †
if type(lsp_key) == 'number' then -- Enable the LSP with defaults.
-- The `lsp` is an index in this case.
nvim_lsp[lsp_settings].setup{
on_attach = on_attach,
flags = {
debounce_text_changes = 150,
},
capabilities = capabilities,
}
else -- Use the LSP's configuration.
lsp_settings.on_attach = on_attach
lsp_settings.capabilities = capabilities
nvim_lsp[lsp_key].setup(lsp_settings)
end
end --
-- configure floating diagnostics appearance, symbols
local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " }
for type, icon in pairs(signs) do
local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
end
-- Set completeopt to have a better completion experience
vim.o.completeopt = 'menuone,noselect'
-- luasnip setup
local luasnip = require 'luasnip'
-- nvim-cmp setup
local cmp = require 'cmp'
cmp.setup {
snippet = {
expand = function(args)
require('luasnip').lsp_expand(args.body)
end,
},
mapping = {
['<C-p>'] = cmp.mapping.select_prev_item(),
['<C-n>'] = cmp.mapping.select_next_item(),
['<C-d>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.close(),
['<CR>'] = cmp.mapping.confirm {
behavior = cmp.ConfirmBehavior.Replace,
select = true,
},
['<Tab>'] = function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end,
['<S-Tab>'] = function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end,
},
sources = {
{ name = 'nvim_lsp' },
{ name = 'luasnip' },
},
}
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#denols
vim.g.markdown_fenced_languages = {
"ts=typescript"
}
-- Configure diagnostics
vim.diagnostic.config({
virtual_text = false,
signs = true,
underline = true,
update_in_insert = false,
severity_sort = false,
})
-- Change diagnostic symbols in the sign column (gutter)
local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " }
for type, icon in pairs(signs) do
local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
end
EOF
" have a fixed column for the diagnostics to appear in
" this removes the jitter when warnings/errors flow in
set signcolumn=yes:2

View File

@ -0,0 +1,87 @@
" Happy yaml configuration
au! BufNewFile,BufReadPost *.{yaml,yml} set filetype=yaml
autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab
let g:gutentags_file_list_command = 'git ls-files'
" quick-scope
" https://github.com/unblevable/quick-scope
let g:qs_highlight_on_keys = ['f', 'F', 't', 'T']
" Golang
" Go test, Def, Decls shortcut
nmap <Leader>got :GoTest<CR>:botright copen<CR>
autocmd FileType go nmap gd :GoDef<CR>
autocmd FileType go nmap gD :GoDecls<CR>
" Go formatting
autocmd FileType go setlocal noexpandtab shiftwidth=4 tabstop=4 softtabstop=4 nolist
" Caddyfile indentation
autocmd FileType caddyfile setlocal noexpandtab shiftwidth=8 tabstop=8 softtabstop=8 nolist
" vim-go disable text-objects
let g:go_textobj_enabled = 0
" disable vim-go :GoDef short cut (gd)
" this is handled by LanguageClient [LC]
let g:go_def_mapping_enabled = 0
" GitGutter and vim Magit
" inspired by: https://jakobgm.com/posts/vim/git-integration/
" Don't map gitgutter keys automatically, set them ourselves
let g:gitgutter_map_keys = 0
" Jump between hunks
nmap <Leader>gn <Plug>(GitGutterNextHunk) " git next
nmap <Leader>gp <Plug>(GitGutterPrevHunk) " git previous
" Hunk-add and hunk-revert for chunk staging
nmap <Leader>ga <Plug>(GitGutterStageHunk) " git add (chunk)
nmap <Leader>gu <Plug>(GitGutterUndoHunk) " git undo (chunk)
" Open vimagit pane
nnoremap <leader>gs :Magit<CR> " git status
" Push to remote
nnoremap <leader>gP :! git push<CR> " git Push
" Quick conflict resolution in git mergetool nvim
" http://vimcasts.org/episodes/fugitive-vim-resolving-merge-conflicts-with-vimdiff/
nmap <Leader>[ :diffget //2<CR>
nmap <Leader>] :diffget //3<CR>
" netrw
let g:netrw_fastbrowse=0
" Auto-FMT rust code on save
let g:rustfmt_autosave = 1
" Indenting in html template tags
let g:html_indent_style1 = "inc"
" yank highlight duration
let g:highlightedyank_highlight_duration = 200
" Markdown options
let g:vim_markdown_folding_disabled = 1
" Haskell options
let g:haskell_enable_quantification = 1 " to enable highlighting of `forall`
let g:haskell_enable_recursivedo = 1 " to enable highlighting of `mdo` and `rec`
let g:haskell_enable_arrowsyntax = 1 " to enable highlighting of `proc`
let g:haskell_enable_pattern_synonyms = 1 " to enable highlighting of `pattern`
let g:haskell_enable_typeroles = 1 " to enable highlighting of type roles
let g:haskell_enable_static_pointers = 1 " to enable highlighting of `static`
let g:haskell_backpack = 1 " to enable highlighting of backpack keywords
" Emmet
let g:user_emmet_leader_key='<c-n>'
" Ack
if executable('ag')
let g:ackprg = 'ag --vimgrep'
endif
" nnn
let g:nnn#command = 'nnn -d -e -H -r'

View File

@ -0,0 +1,36 @@
self:
with self; ''
IFS=':' read -r -a INPUT <<< "$1"
FILE=''${INPUT[0]}
CENTER=''${INPUT[1]}
if [[ "$1" =~ ^[A-Za-z]:\\ ]]; then
FILE=$FILE:''${INPUT[1]}
CENTER=''${INPUT[2]}
fi
if [[ -n "$CENTER" && ! "$CENTER" =~ ^[0-9] ]]; then
exit 1
fi
CENTER=''${CENTER/[^0-9]*/}
FILE="''${FILE/#\~\//$HOME/}"
if [ ! -r "$FILE" ]; then
echo "File not found ''${FILE}"
exit 1
fi
if [ -z "$CENTER" ]; then
CENTER=0
fi
exec cat "$FILE" \
| sed -e '/[#|\/\/ ?]-- copyright/,/[#\/\/]++/c\\' \
| ${pkgs.coreutils}/bin/tr -s '\n' \
| ${pkgs.bat}/bin/bat \
--style="''${BAT_STYLE:-numbers}" \
--color=always \
--pager=never \
--file-name="''$FILE" \
--highlight-line=$CENTER
''

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